]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.excel/native/SimanticsExcel2008/SimanticsExcel2008/Interface.cpp
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.excel / native / SimanticsExcel2008 / SimanticsExcel2008 / Interface.cpp
1 \r
2 #include "stdafx.h"\r
3 \r
4 #include <sstream>\r
5 #include <map>\r
6 \r
7 using namespace std;\r
8 \r
9 #import "c:/program files (x86)/common files/microsoft shared/office12/mso.dll" \\r
10         rename( "RGB", "MSORGB" )\r
11 \r
12 using namespace Office;\r
13 \r
14 #import "c:/program files (x86)/common files/microsoft shared/vba/vba6/vbe6ext.olb" \\r
15 \r
16 using namespace VBIDE;\r
17 \r
18 #import "c:/program files (x86)/microsoft office/office12/excel.exe" \\r
19         rename( "DialogBox", "ExcelDialogBox" ) \\r
20         rename( "RGB", "ExcelRGB" ) \\r
21         rename( "CopyFile", "ExcelCopyFile" ) \\r
22         rename( "ReplaceText", "ExcelReplaceText" )\r
23 \r
24 #include "jni2.h"\r
25 \r
26 //#define SIMANTICS_DEBUG(...) \\r
27 //{ FILE *fp = fopen("d:/excel.log", "ab"); fprintf(fp, __VA_ARGS__); fflush(fp); fclose(fp);  }\r
28 \r
29 #define SIMANTICS_DEBUG(...)\r
30 \r
31 using namespace std;\r
32 using namespace Excel;\r
33 \r
34 map<int, Excel::_WorksheetPtr> handles;\r
35 static int handleCounter = 1;\r
36 \r
37 void replace(std::string &s, const std::string &s1, const std::string &s2) {\r
38 \r
39         int index = 0;\r
40 \r
41         index = s.find(s1, index);\r
42         while(index != std::string::npos) {\r
43                 s.replace(index, s1.length(), s2.c_str(), s2.length());\r
44                 index = s.find(s1, index + 1);\r
45         }\r
46 \r
47 }\r
48 \r
49 boolean getString(JNIEnv *env, jstring str, char *target) {\r
50 \r
51     jboolean iscopy;\r
52     const char *chars = env->GetStringUTFChars(str, &iscopy);\r
53         if(!chars) return false;\r
54 \r
55         strcpy(target, chars);\r
56 \r
57     env->ReleaseStringUTFChars(str, chars);\r
58 \r
59         return true;\r
60 \r
61 }\r
62 \r
63 string getString(JNIEnv *env, jstring str) {\r
64 \r
65     jboolean iscopy;\r
66     const char *chars = env->GetStringUTFChars(str, &iscopy);\r
67         if(!chars) return 0;\r
68         string result = chars;\r
69     env->ReleaseStringUTFChars(str, chars);\r
70         return result;\r
71 \r
72 }\r
73 \r
74 Excel::_ApplicationPtr getApplication(bool create) {\r
75         \r
76         Excel::_ApplicationPtr application;\r
77 \r
78         CLSID clsid;\r
79         HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);\r
80         if(FAILED(hr)) {\r
81                 return 0;\r
82         }\r
83 \r
84         if (!SUCCEEDED(application.GetActiveObject(clsid)))\r
85         {\r
86                 if(create) {\r
87                         hr = application.CreateInstance(clsid);\r
88                         if(FAILED(hr)) {\r
89                                 return 0;\r
90                         }\r
91                 } else {\r
92                         return 0;\r
93                 }\r
94         }\r
95 \r
96         application->EnableEvents = VARIANT_FALSE;\r
97 \r
98         return application;\r
99 \r
100 }\r
101 \r
102 JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_init(JNIEnv *env, jobject) {\r
103 \r
104         SIMANTICS_DEBUG("Excel init\r\n");\r
105 \r
106         HRESULT hr = ::OleInitialize(NULL);\r
107         if(FAILED(hr)) {\r
108                 return hr;\r
109         }\r
110 \r
111         /*\r
112         Excel::_ApplicationPtr application = getApplication(true);\r
113         if(!application) return -1;\r
114         bstr_t version = application->GetVersion(0);\r
115         ostringstream os;\r
116         os << version << endl;\r
117         SIMANTICS_DEBUG("Init successful with version %s\r\n",  os.str().c_str());\r
118 \r
119         application->put_Interactive( 0, VARIANT_FALSE );\r
120         application->put_Visible( 0, VARIANT_FALSE );\r
121         */\r
122 \r
123         return 0;\r
124 \r
125 }\r
126 \r
127 Excel::_WorkbookPtr getWorkbook(const Excel::_ApplicationPtr &application, const string &fileName) {\r
128 \r
129         SIMANTICS_DEBUG("getWorkbook(%s)\r\n", fileName.c_str());\r
130 \r
131         for(int i=0;i<application->Workbooks->Count;i++) {\r
132                 _bstr_t fullName;\r
133                 Excel::_WorkbookPtr workbook = application->Workbooks->GetItem( _variant_t(i+1) );\r
134                 workbook->get_FullName(0, &fullName.GetBSTR());\r
135                 std::string fullNameStr = fullName;\r
136                 SIMANTICS_DEBUG("'%s'\r\n", fullNameStr.c_str());\r
137                 if(fullNameStr == fileName) return workbook;\r
138         }\r
139 \r
140         return 0;\r
141 \r
142 }\r
143 \r
144 Excel::_WorksheetPtr getWorksheet(const Excel::_WorkbookPtr workbook, const string &sheetName) {\r
145 \r
146         SIMANTICS_DEBUG("getWorksheet(%s)\r\n", sheetName.c_str());\r
147 \r
148         for(int i=0;i<workbook->Sheets->Count;i++) {\r
149                 Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));\r
150                 std:string name = sheet->Name;\r
151                 SIMANTICS_DEBUG("'%s'\r\n", name.c_str());\r
152                 if(name == sheetName) return sheet;\r
153         }\r
154 \r
155         return 0;\r
156 \r
157 }\r
158 \r
159 char message[1024];\r
160 \r
161 JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_open(JNIEnv *env, jobject, jstring fileName, jstring sheetName_) {\r
162 \r
163         string name = getString(env, fileName);\r
164         string sheetName = getString(env, sheetName_);\r
165 \r
166         _variant_t varOption( (long) DISP_E_PARAMNOTFOUND, VT_ERROR );\r
167 \r
168         Excel::_ApplicationPtr application = getApplication(true);\r
169         if(!application) return env->NewStringUTF("Excel application could not be started.");\r
170 \r
171         Excel::_WorkbookPtr workbook = getWorkbook(application, name);\r
172         if(!workbook) {\r
173 \r
174                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Opening.\r\n", name.c_str());\r
175 \r
176                 FILE *fp = fopen(name.c_str(), "r");\r
177                 if(fp) {\r
178 \r
179                 SIMANTICS_DEBUG("getWorkbook(%s) book was found. Opening file.\r\n", name.c_str());\r
180 \r
181                         fclose(fp);\r
182                         workbook = application->Workbooks->OpenXML(_bstr_t(name.c_str()), \r
183                                 varOption, varOption);\r
184                         if(!workbook) return env->NewStringUTF("File could not be opened.");\r
185 \r
186                 } else {\r
187 \r
188                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creating file.\r\n", name.c_str());\r
189 \r
190                         workbook = application->Workbooks->Add(varOption);\r
191 \r
192                         if(!workbook) return env->NewStringUTF("New workbook could not be created.");\r
193 \r
194                         try {\r
195 \r
196                                 Excel::_WorksheetPtr sheet = workbook->Sheets->Add();\r
197                                 sheet->Name = _bstr_t(sheetName.c_str());\r
198 \r
199                                 /*\r
200                                 // Does not work for some unknown reason\r
201                                 for(int i=0;i<workbook->Sheets->Count;i++) {\r
202                                         Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));\r
203                                         if(name != sheetName)\r
204                                                 sheet->PutVisible(0, Excel::XlSheetVisibility::xlSheetVeryHidden);\r
205                                 }\r
206                                 */\r
207 \r
208                                 workbook->SaveAs(_bstr_t(name.c_str()), varOption, varOption, varOption, varOption,\r
209                                         varOption, Excel::xlExclusive, varOption, varOption, varOption, varOption, 0);\r
210 \r
211                         } catch (_com_error& e) {\r
212                                 _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
213                                 string s(bstr);\r
214                                 _bstr_t bstr2 = _bstr_t(e.Description());\r
215                                 string s2(bstr2);\r
216                                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 1 '%s' '%s'\r\n", name.c_str(), s.c_str(), s2.c_str());\r
217                                 strcpy(message, s2.c_str());\r
218                                 return env->NewStringUTF(message);\r
219                         } catch (exception& e) {\r
220                                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());\r
221                                 return env->NewStringUTF(e.what());\r
222                         } catch (...) {\r
223                                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 3 \r\n", name.c_str());\r
224                                 return env->NewStringUTF("Undefined error");\r
225                         }\r
226                 \r
227 \r
228                 }\r
229 \r
230         }\r
231 \r
232         application->put_Interactive( 0, VARIANT_TRUE );\r
233         application->put_Visible( 0, VARIANT_TRUE );\r
234 \r
235         workbook->Activate();\r
236 \r
237         SIMANTICS_DEBUG("getWorkbook(%s) searches for sheet '%s'\r\n", name.c_str(), sheetName.c_str());\r
238 \r
239         try {\r
240                 Excel::_WorksheetPtr sheet = getWorksheet(workbook, sheetName);\r
241                 if(!sheet) {\r
242                         SIMANTICS_DEBUG("creating sheet %s for '%s'\r\n", sheetName.c_str(), name.c_str());\r
243                         sheet = workbook->Sheets->Add();\r
244                         sheet->Name = _bstr_t(sheetName.c_str());\r
245                 }\r
246             int handle = handleCounter++;\r
247         SIMANTICS_DEBUG("opened handle %d for '%s'\r\n", handle, name.c_str());\r
248         handles[handle] = sheet;\r
249                 ostringstream os;\r
250                 os << handle;\r
251                 return env->NewStringUTF(os.str().c_str());\r
252 \r
253         } catch (_com_error& e) {\r
254                 _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
255                 string s(bstr);\r
256                 _bstr_t bstr2 = _bstr_t(e.Description());\r
257                 string s2(bstr2);\r
258                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 1 '%s' '%s'\r\n", name.c_str(), s.c_str(), s2.c_str());\r
259                 return env->NewStringUTF(s2.c_str());\r
260         } catch (exception& e) {\r
261                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());\r
262                 return env->NewStringUTF(e.what());\r
263         } catch (...) {\r
264                 SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error\r\n", name.c_str());\r
265                 return env->NewStringUTF("Unhandled exception.");\r
266         }\r
267 \r
268 \r
269         //Excel::_WorksheetPtr sheet = workbook->ActiveSheet;\r
270         //if(!sheet) return -4;\r
271 \r
272 \r
273 }\r
274 \r
275 string cellName(int row, int column) {\r
276 \r
277         string result;\r
278 \r
279         SIMANTICS_DEBUG("cellName(%d, %d) -> ", row, column);\r
280 \r
281         do {\r
282                 char rem = column % 26;\r
283                 char c = 'A' + rem;\r
284                 result += c;\r
285                 column -= rem;\r
286                 column /= 26;\r
287         } while(column);\r
288 \r
289         ostringstream os;\r
290         os << (row + 1);\r
291         result += os.str();\r
292 \r
293         SIMANTICS_DEBUG("%s\r\n", result.c_str());\r
294 \r
295         return result;\r
296 \r
297 }\r
298 \r
299 /*\r
300 Excel::_WorkbookPtr getWorkbook(int handle) {\r
301         map<int, Excel::_WorkbookPtr>::iterator it = handles.find(handle);\r
302         if(it != handles.end()) return (*it).second;\r
303         else return 0;\r
304 }\r
305 */\r
306 \r
307 Excel::_WorksheetPtr getWorksheet(int handle) {\r
308         map<int, Excel::_WorksheetPtr>::iterator it = handles.find(handle);\r
309         if(it != handles.end()) return (*it).second;\r
310         else return 0;\r
311 }\r
312 \r
313 JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setDouble(JNIEnv *env, jobject, jint handle, jint row, jint column, jdouble value) {\r
314 \r
315         SIMANTICS_DEBUG("setDouble(%d, %d, %f)\r\n", row, column, value);\r
316 \r
317         Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
318         if(!sheet) return -1;\r
319         Excel::RangePtr range = sheet->Cells;\r
320         if(!range) return -2;\r
321         range->Item[row+1][column+1] = value;\r
322 \r
323         return 0;\r
324 \r
325 }\r
326 \r
327 JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setString(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {\r
328 \r
329         try {\r
330 \r
331                 string val = getString(env, value);\r
332 \r
333                 SIMANTICS_DEBUG("setString(%d, %d, %s)\r\n", row, column, val.c_str());\r
334 \r
335                 Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
336 \r
337                 SIMANTICS_DEBUG("setString2(%d, %d, %s)\r\n", row, column, val.c_str());\r
338 \r
339                 if(!sheet) return -1;\r
340 \r
341                 struct Range *_range = 0;\r
342                 HRESULT _hr = sheet->get_Cells(&_range);\r
343                 if (FAILED(_hr)) return -1;\r
344                 Excel::RangePtr range = RangePtr(_range, false);\r
345 \r
346                 SIMANTICS_DEBUG("setString3(%d, %d, %s)\r\n", row, column, val.c_str());\r
347 \r
348                 if(!range) return -2;\r
349 \r
350                 const char *text = val.c_str();\r
351 \r
352                 SIMANTICS_DEBUG("setString4(%d, %d, %s)\r\n", row, column, val.c_str());\r
353 \r
354                 Excel::RangePtr cell = range->Item[row+1][column+1];\r
355                 if(!cell) return -4;\r
356 \r
357                 SIMANTICS_DEBUG("setString5(%d, %d, %s)\r\n", row, column, val.c_str());\r
358 \r
359                 cell->Item[1][1] = text;\r
360 \r
361 //              cell = text;\r
362 \r
363                 return 0;\r
364 \r
365         } catch (_com_error& e) {\r
366 \r
367                 _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
368                 string s(bstr);\r
369                 _bstr_t bstr2 = _bstr_t(e.Description());\r
370                 string s2(bstr2);\r
371                 SIMANTICS_DEBUG("SetString error 1 '%s' '%s'\r\n", s.c_str(), s2.c_str());\r
372                 return -5;\r
373 \r
374         } catch (exception& e) {\r
375 \r
376                 SIMANTICS_DEBUG("SetString error 2 '%s'\r\n", e.what());\r
377                 return -5;\r
378 \r
379         } catch (...) {\r
380 \r
381                 SIMANTICS_DEBUG("SetString error\r\n");\r
382                 return -5;\r
383 \r
384         }\r
385 \r
386 }\r
387 \r
388 JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setName(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {\r
389 \r
390         string val = getString(env, value);\r
391 \r
392         SIMANTICS_DEBUG("setName(%d, %d, %s)\r\n", row, column, val.c_str());\r
393 \r
394         Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
395         if(!sheet) return -1;\r
396         //sheet->c\r
397         Excel::RangePtr range = sheet->GetRange(_variant_t(cellName(row, column).c_str()));\r
398         if(!range) return -2;\r
399         range->Name = _variant_t(val.c_str());\r
400 \r
401 \r
402         //range->Item[row+1][column+1] = text;\r
403         //range->Name[row+1][column+1] = text;\r
404 \r
405         return 0;\r
406 \r
407 }\r
408 \r
409 JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setVisible(JNIEnv *env, jobject, jint handle, jboolean value) {\r
410 \r
411         SIMANTICS_DEBUG("setVisible(%d)\r\n", value);\r
412 \r
413         Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
414         if(!sheet) return -1;\r
415         Excel::_ApplicationPtr application = sheet->Application;\r
416         if(!application) return -2;\r
417 \r
418         if(value) {\r
419                 application->put_Interactive( 0, VARIANT_TRUE );\r
420                 application->put_Visible( 0, VARIANT_TRUE );\r
421         } else {\r
422                 application->put_Interactive( 0, VARIANT_FALSE );\r
423                 application->put_Visible( 0, VARIANT_FALSE );\r
424         }\r
425 \r
426         return 0;\r
427 \r
428 }\r
429 \r
430 JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_close(JNIEnv *env, jobject, jint handle) {\r
431 \r
432         SIMANTICS_DEBUG("closing handle %d\r\n", handle);\r
433 \r
434         try {\r
435 \r
436                 Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
437                 if(!sheet) return -1;\r
438                 \r
439                 // Release this reference for Close\r
440                 handles.erase(handle);\r
441 \r
442                                         SIMANTICS_DEBUG("closing 1\r\n");\r
443 \r
444                 struct Range *_range = 0;\r
445                 HRESULT _hr = sheet->get_Cells(&_range);\r
446                 if (FAILED(_hr)) return -1;\r
447 \r
448                                         SIMANTICS_DEBUG("closing 2\r\n");\r
449 \r
450                 Excel::_ApplicationPtr application = sheet->Application;\r
451                 if(!application) return -2;\r
452 \r
453                 Excel::_WorkbookPtr workbook = (Excel::_WorkbookPtr)sheet->Parent;\r
454                 if(!workbook) return -3;\r
455 \r
456         //      SIMANTICS_DEBUG("About to save\r\n");\r
457                 HRESULT hr = workbook->Save();\r
458         //      workbook->put_Saved(0, VARIANT_TRUE);\r
459                 if(FAILED(hr)) {\r
460                         SIMANTICS_DEBUG("Save failed with %d\r\n", hr);\r
461                         return hr;\r
462                 }\r
463 \r
464                 map<int, Excel::_WorksheetPtr>::iterator it = handles.begin();\r
465                 for(;it != handles.end();++it) {\r
466                         Excel::_WorksheetPtr sheet2 = (*it).second;\r
467                         Excel::_WorkbookPtr book = (Excel::_WorkbookPtr)sheet2->Parent;\r
468                         // The book remains open\r
469                         if(book->Name == workbook->Name) return 0;\r
470                 }\r
471 \r
472                 SIMANTICS_DEBUG("About to Close\r\n");\r
473                 hr = workbook->Close(VARIANT_FALSE);\r
474                 if(FAILED(hr)) {\r
475                         SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
476                         return hr;\r
477                 }\r
478 \r
479                 long remaining = 0;\r
480 \r
481                 application->Workbooks->get_Count(&remaining);\r
482                 if(!remaining) {\r
483                         application->put_Interactive( 0, VARIANT_FALSE );\r
484                         application->put_Visible( 0, VARIANT_FALSE );\r
485                         hr = application->Quit();\r
486                         if(FAILED(hr)) {\r
487                                 SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
488                                 return hr;\r
489                         }\r
490                 }\r
491 \r
492         } catch (_com_error& e) {\r
493                 _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
494                 string s(bstr);\r
495                 _bstr_t bstr2 = _bstr_t(e.Description());\r
496                 string s2(bstr2);\r
497                 SIMANTICS_DEBUG("Close error 1 '%s' '%s'\r\n", s.c_str(), s2.c_str());\r
498                 return -5;\r
499         } catch (exception& e) {\r
500                 SIMANTICS_DEBUG("Close error 2 '%s'\r\n", e.what());\r
501                 return -5;\r
502         } catch (...) {\r
503                 SIMANTICS_DEBUG("Close error\r\n");\r
504                 return -5;\r
505         }\r
506 \r
507 \r
508 \r
509 //      SIMANTICS_DEBUG("About to hide");\r
510 \r
511 //      application->put_Interactive( 0, VARIANT_FALSE );\r
512 //      application->put_Visible( 0, VARIANT_FALSE );\r
513 \r
514 //      if(handles.empty())\r
515 //              application->Quit();\r
516 \r
517         return 0;\r
518 \r
519 }\r