]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.excel/native/Interface.cpp
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.excel / native / Interface.cpp
diff --git a/bundles/org.simantics.excel/native/Interface.cpp b/bundles/org.simantics.excel/native/Interface.cpp
new file mode 100644 (file)
index 0000000..910df78
--- /dev/null
@@ -0,0 +1,528 @@
+\r
+//#include "stdafx.h"\r
+\r
+//#ifndef _UNICODE\r
+//#define _UNICODE\r
+//#endif\r
+\r
+#include <sstream>\r
+#include <map>\r
+//#include <cmath>\r
+//#include <TCHAR.H>\r
+\r
+using namespace std;\r
+\r
+#import "c:/program files (x86)/common files/microsoft shared/office12/mso.dll" \\r
+       rename( "RGB", "MSORGB" )\r
+\r
+using namespace Office;\r
+\r
+#import "c:/program files (x86)/common files/microsoft shared/vba/vba6/vbe6ext.olb" \\r
+\r
+using namespace VBIDE;\r
+\r
+#import "c:/program files (x86)/microsoft office/office12/excel.exe" \\r
+       rename( "DialogBox", "ExcelDialogBox" ) \\r
+       rename( "RGB", "ExcelRGB" ) \\r
+       rename( "CopyFile", "ExcelCopyFile" ) \\r
+       rename( "ReplaceText", "ExcelReplaceText" )\r
+\r
+#include "jni2.h"\r
+\r
+//#define SIMANTICS_DEBUG(...) \\r
+//{ FILE *fp = fopen("d:/excel.log", "ab"); fprintf(fp, __VA_ARGS__); fflush(fp); fclose(fp);  }\r
+\r
+#define SIMANTICS_DEBUG(...)\r
+\r
+using namespace std;\r
+using namespace Excel;\r
+\r
+map<int, Excel::_WorksheetPtr> handles;\r
+static int handleCounter = 1;\r
+\r
+void replace(std::string &s, const std::string &s1, const std::string &s2) {\r
+\r
+       int index = 0;\r
+\r
+       index = s.find(s1, index);\r
+       while(index != std::string::npos) {\r
+               s.replace(index, s1.length(), s2.c_str(), s2.length());\r
+               index = s.find(s1, index + 1);\r
+       }\r
+\r
+}\r
+\r
+boolean getString(JNIEnv *env, jstring str, char *target) {\r
+\r
+    jboolean iscopy;\r
+    const char *chars = env->GetStringUTFChars(str, &iscopy);\r
+       if(!chars) return false;\r
+\r
+       strcpy(target, chars);\r
+\r
+    env->ReleaseStringUTFChars(str, chars);\r
+\r
+       return true;\r
+\r
+}\r
+\r
+string getString(JNIEnv *env, jstring str) {\r
+\r
+    jboolean iscopy;\r
+    const char *chars = env->GetStringUTFChars(str, &iscopy);\r
+       if(!chars) return 0;\r
+       string result = chars;\r
+    env->ReleaseStringUTFChars(str, chars);\r
+       return result;\r
+\r
+}\r
+\r
+Excel::_ApplicationPtr getApplication(bool create) {\r
+       \r
+       Excel::_ApplicationPtr application;\r
+\r
+       CLSID clsid;\r
+       HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);\r
+       if(FAILED(hr)) {\r
+               return 0;\r
+       }\r
+\r
+       if (!SUCCEEDED(application.GetActiveObject(clsid)))\r
+       {\r
+               if(create) {\r
+                       hr = application.CreateInstance(clsid);\r
+                       if(FAILED(hr)) {\r
+                               return 0;\r
+                       }\r
+               } else {\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       application->EnableEvents = VARIANT_FALSE;\r
+\r
+       return application;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_init(JNIEnv *env, jobject) {\r
+\r
+       SIMANTICS_DEBUG("Excel init\r\n");\r
+\r
+       HRESULT hr = ::OleInitialize(NULL);\r
+       if(FAILED(hr)) {\r
+               return hr;\r
+       }\r
+\r
+       /*\r
+       Excel::_ApplicationPtr application = getApplication(true);\r
+       if(!application) return -1;\r
+       bstr_t version = application->GetVersion(0);\r
+       ostringstream os;\r
+       os << version << endl;\r
+       SIMANTICS_DEBUG("Init successful with version %s\r\n",  os.str().c_str());\r
+\r
+       application->put_Interactive( 0, VARIANT_FALSE );\r
+       application->put_Visible( 0, VARIANT_FALSE );\r
+       */\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+Excel::_WorkbookPtr getWorkbook(const Excel::_ApplicationPtr &application, const string &fileName) {\r
+\r
+       SIMANTICS_DEBUG("getWorkbook(%s)\r\n", fileName.c_str());\r
+\r
+       for(int i=0;i<application->Workbooks->Count;i++) {\r
+               _bstr_t fullName;\r
+               Excel::_WorkbookPtr workbook = application->Workbooks->GetItem( _variant_t(i+1) );\r
+               workbook->get_FullName(0, &fullName.GetBSTR());\r
+               std::string fullNameStr = fullName;\r
+               SIMANTICS_DEBUG("'%s'\r\n", fullNameStr.c_str());\r
+               if(fullNameStr == fileName) return workbook;\r
+       }\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+Excel::_WorksheetPtr getWorksheet(const Excel::_WorkbookPtr workbook, const string &sheetName) {\r
+\r
+       SIMANTICS_DEBUG("getWorksheet(%s)\r\n", sheetName.c_str());\r
+\r
+       for(int i=0;i<workbook->Sheets->Count;i++) {\r
+               Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));\r
+               std:string name = sheet->Name;\r
+               SIMANTICS_DEBUG("'%s'\r\n", name.c_str());\r
+               if(name == sheetName) return sheet;\r
+       }\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+char message[1024];\r
+\r
+JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_open(JNIEnv *env, jobject, jstring fileName, jstring sheetName_) {\r
+\r
+       string name = getString(env, fileName);\r
+       string sheetName = getString(env, sheetName_);\r
+\r
+       _variant_t varOption( (long) DISP_E_PARAMNOTFOUND, VT_ERROR );\r
+\r
+       Excel::_ApplicationPtr application = getApplication(true);\r
+       if(!application) return env->NewStringUTF("Excel application could not be started.");\r
+\r
+       Excel::_WorkbookPtr workbook = getWorkbook(application, name);\r
+       if(!workbook) {\r
+\r
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Opening.\r\n", name.c_str());\r
+\r
+               FILE *fp = fopen(name.c_str(), "r");\r
+               if(fp) {\r
+\r
+               SIMANTICS_DEBUG("getWorkbook(%s) book was found. Opening file.\r\n", name.c_str());\r
+\r
+                       fclose(fp);\r
+                       workbook = application->Workbooks->OpenXML(_bstr_t(name.c_str()), \r
+                               varOption, varOption);\r
+                       if(!workbook) return env->NewStringUTF("File could not be opened.");\r
+\r
+               } else {\r
+\r
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creating file.\r\n", name.c_str());\r
+\r
+                       workbook = application->Workbooks->Add(varOption);\r
+\r
+                       if(!workbook) return env->NewStringUTF("New workbook could not be created.");\r
+\r
+                       try {\r
+\r
+                               Excel::_WorksheetPtr sheet = workbook->Sheets->Add();\r
+                               sheet->Name = _bstr_t(sheetName.c_str());\r
+\r
+                               /*\r
+                               // Does not work for some unknown reason\r
+                               for(int i=0;i<workbook->Sheets->Count;i++) {\r
+                                       Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));\r
+                                       if(name != sheetName)\r
+                                               sheet->PutVisible(0, Excel::XlSheetVisibility::xlSheetVeryHidden);\r
+                               }\r
+                               */\r
+\r
+                               workbook->SaveAs(_bstr_t(name.c_str()), varOption, varOption, varOption, varOption,\r
+                                       varOption, Excel::xlExclusive, varOption, varOption, varOption, varOption, 0);\r
+\r
+                       } catch (_com_error& e) {\r
+                               _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
+                               string s(bstr);\r
+                               _bstr_t bstr2 = _bstr_t(e.Description());\r
+                               string s2(bstr2);\r
+                               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
+                               strcpy(message, s2.c_str());\r
+                               return env->NewStringUTF(message);\r
+                       } catch (exception& e) {\r
+                               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());\r
+                               return env->NewStringUTF(e.what());\r
+                       } catch (...) {\r
+                               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 3 \r\n", name.c_str());\r
+                               return env->NewStringUTF("Undefined error");\r
+                       }\r
+               \r
+\r
+               }\r
+\r
+       }\r
+\r
+       application->put_Interactive( 0, VARIANT_TRUE );\r
+       application->put_Visible( 0, VARIANT_TRUE );\r
+\r
+       workbook->Activate();\r
+\r
+       SIMANTICS_DEBUG("getWorkbook(%s) searches for sheet '%s'\r\n", name.c_str(), sheetName.c_str());\r
+\r
+       try {\r
+               Excel::_WorksheetPtr sheet = getWorksheet(workbook, sheetName);\r
+               if(!sheet) {\r
+                       SIMANTICS_DEBUG("creating sheet %s for '%s'\r\n", sheetName.c_str(), name.c_str());\r
+                       sheet = workbook->Sheets->Add();\r
+                       sheet->Name = _bstr_t(sheetName.c_str());\r
+               }\r
+           int handle = handleCounter++;\r
+       SIMANTICS_DEBUG("opened handle %d for '%s'\r\n", handle, name.c_str());\r
+       handles[handle] = sheet;\r
+               ostringstream os;\r
+               os << handle;\r
+               return env->NewStringUTF(os.str().c_str());\r
+\r
+       } catch (_com_error& e) {\r
+               _bstr_t bstr = _bstr_t(e.ErrorMessage());\r
+               string s(bstr);\r
+               _bstr_t bstr2 = _bstr_t(e.Description());\r
+               string s2(bstr2);\r
+               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
+               return env->NewStringUTF(s2.c_str());\r
+       } catch (exception& e) {\r
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());\r
+               return env->NewStringUTF(e.what());\r
+       } catch (...) {\r
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error\r\n", name.c_str());\r
+               return env->NewStringUTF("Unhandled exception.");\r
+       }\r
+\r
+\r
+       //Excel::_WorksheetPtr sheet = workbook->ActiveSheet;\r
+       //if(!sheet) return -4;\r
+\r
+\r
+}\r
+\r
+string cellName(int row, int column) {\r
+\r
+       string result;\r
+\r
+       SIMANTICS_DEBUG("cellName(%d, %d) -> ", row, column);\r
+\r
+       do {\r
+               char rem = column % 26;\r
+               char c = 'A' + rem;\r
+               result += c;\r
+               column -= rem;\r
+               column /= 26;\r
+       } while(column);\r
+\r
+       ostringstream os;\r
+       os << (row + 1);\r
+       result += os.str();\r
+\r
+       SIMANTICS_DEBUG("%s\r\n", result.c_str());\r
+\r
+       return result;\r
+\r
+}\r
+\r
+/*\r
+Excel::_WorkbookPtr getWorkbook(int handle) {\r
+       map<int, Excel::_WorkbookPtr>::iterator it = handles.find(handle);\r
+       if(it != handles.end()) return (*it).second;\r
+       else return 0;\r
+}\r
+*/\r
+\r
+Excel::_WorksheetPtr getWorksheet(int handle) {\r
+       map<int, Excel::_WorksheetPtr>::iterator it = handles.find(handle);\r
+       if(it != handles.end()) return (*it).second;\r
+       else return 0;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setDouble(JNIEnv *env, jobject, jint handle, jint row, jint column, jdouble value) {\r
+\r
+       SIMANTICS_DEBUG("setDouble(%d, %d, %f)\r\n", row, column, value);\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return -1;\r
+       Excel::RangePtr range = sheet->Cells;\r
+       if(!range) return -2;\r
+       range->Item[row+1][column+1] = value;\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setString(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {\r
+\r
+       string val = getString(env, value);\r
+\r
+       SIMANTICS_DEBUG("setString(%d, %d, %s)\r\n", row, column, val.c_str());\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return -1;\r
+       Excel::RangePtr range = sheet->Cells;\r
+       if(!range) return -2;\r
+\r
+       const char *text = val.c_str();\r
+\r
+       range->Item[row+1][column+1] = text;\r
+       //range->Name[row+1][column+1] = text;\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setName(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {\r
+\r
+       string val = getString(env, value);\r
+\r
+       SIMANTICS_DEBUG("setName(%d, %d, %s)\r\n", row, column, val.c_str());\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return -1;\r
+       //sheet->c\r
+       Excel::RangePtr range = sheet->GetRange(_variant_t(cellName(row, column).c_str()));\r
+       if(!range) return -2;\r
+       range->Name = _variant_t(val.c_str());\r
+\r
+\r
+       //range->Item[row+1][column+1] = text;\r
+       //range->Name[row+1][column+1] = text;\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setVisible(JNIEnv *env, jobject, jint handle, jboolean value) {\r
+\r
+       SIMANTICS_DEBUG("setVisible(%d)\r\n", value);\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return -1;\r
+       Excel::_ApplicationPtr application = sheet->Application;\r
+       if(!application) return -2;\r
+\r
+       if(value) {\r
+               application->put_Interactive( 0, VARIANT_TRUE );\r
+               application->put_Visible( 0, VARIANT_TRUE );\r
+       } else {\r
+               application->put_Interactive( 0, VARIANT_FALSE );\r
+               application->put_Visible( 0, VARIANT_FALSE );\r
+       }\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_close(JNIEnv *env, jobject, jint handle) {\r
+\r
+       SIMANTICS_DEBUG("closing handle %d\r\n", handle);\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return -1;\r
+       Excel::_ApplicationPtr application = sheet->Application;\r
+       if(!application) return -2;\r
+\r
+       Excel::_WorkbookPtr workbook = (Excel::_WorkbookPtr)sheet->Parent;\r
+       if(!workbook) return -3;\r
+\r
+//     SIMANTICS_DEBUG("About to save\r\n");\r
+       HRESULT hr = workbook->Save();\r
+//     workbook->put_Saved(0, VARIANT_TRUE);\r
+       if(FAILED(hr)) {\r
+               SIMANTICS_DEBUG("Save failed with %d\r\n", hr);\r
+               return hr;\r
+       }\r
+//     SIMANTICS_DEBUG("About to AcceptAllChanges\r\n");\r
+//     HRESULT hr = workbook->AcceptAllChanges();\r
+//     if(FAILED(hr)) {\r
+\r
+       //SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
+       //      return hr;\r
+       //}\r
+\r
+       // Release this reference for Close\r
+       handles.erase(handle);\r
+\r
+       map<int, Excel::_WorksheetPtr>::iterator it = handles.begin();\r
+       for(;it != handles.end();++it) {\r
+               Excel::_WorksheetPtr sheet2 = (*it).second;\r
+               Excel::_WorkbookPtr book = (Excel::_WorkbookPtr)sheet2->Parent;\r
+               // The book remains open\r
+               if(book->Name == workbook->Name) return 0;\r
+       }\r
+\r
+       //SIMANTICS_DEBUG("About to PutUserControl\r\n");\r
+       //workbook->PutUserControl(VARIANT_FALSE);\r
+       SIMANTICS_DEBUG("About to Close\r\n");\r
+       hr = workbook->Close(VARIANT_FALSE);\r
+       if(FAILED(hr)) {\r
+               SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
+               return hr;\r
+       }\r
+\r
+       long remaining = 0;\r
+\r
+       application->Workbooks->get_Count(&remaining);\r
+       if(!remaining) {\r
+               application->put_Interactive( 0, VARIANT_FALSE );\r
+               application->put_Visible( 0, VARIANT_FALSE );\r
+               hr = application->Quit();\r
+               if(FAILED(hr)) {\r
+                       SIMANTICS_DEBUG("Close failed with %d\r\n", hr);\r
+                       return hr;\r
+               }\r
+       }\r
+\r
+//     SIMANTICS_DEBUG("About to hide");\r
+\r
+//     application->put_Interactive( 0, VARIANT_FALSE );\r
+//     application->put_Visible( 0, VARIANT_FALSE );\r
+\r
+//     if(handles.empty())\r
+//             application->Quit();\r
+\r
+       return 0;\r
+\r
+}\r
+\r
+/**\r
+JNIEXPORT jdouble JNICALL Java_org_simantics_excel_Excel_getDouble(JNIEnv *env, jobject, jint handle, jint row, jint column) {\r
+\r
+       SIMANTICS_DEBUG("getDouble(%d, %d)\r\n", row, column);\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return 0.0; // TODO: NAN\r
+       Excel::RangePtr range = sheet->Cells;\r
+       if(!range) return 0.0; // TODO: NAN\r
+\r
+       variant_t val = range->Item[row+1][column+1];\r
+       if (val.vt != VT_NULL) {\r
+               try {\r
+                       double d = val;\r
+                       SIMANTICS_DEBUG("%f\r\n",d);\r
+                       return d;\r
+               } catch (...) {\r
+                       return 0.0; // TODO: NAN\r
+               }\r
+       }\r
+       return 0.0; // TODO: NAN\r
+\r
+}\r
+\r
+JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_getString(JNIEnv *env, jobject, jint handle, jint row, jint column) {\r
+\r
+       //string val = getString(env, value);\r
+\r
+       SIMANTICS_DEBUG("getString(%d, %d)\r\n", row, column);\r
+\r
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);\r
+       if(!sheet) return NULL;\r
+       Excel::RangePtr range = sheet->Cells;\r
+       if(!range) return NULL;\r
+\r
+       variant_t val = range->Item[row+1][column+1];\r
+       if (val.vt != VT_NULL) {  // val.vt seems to be always VT_DISPATCH.\r
+               try {\r
+                       //this call will crash the application, if the cell is empty!\r
+                       _bstr_t bstrt = val;\r
+                       TCHAR text[1024];\r
+                       // TODO: this uses wide character (16-bit) while NewStringUTF expext regular character (8-bit), hence Java gets only the fisrt charater of the whole string.\r
+                       _stprintf(text, _T("%s"), (LPCTSTR)bstrt);\r
+                       //const char *text = bstrt;\r
+                       SIMANTICS_DEBUG("%s\r\n",text);\r
+       \r
+                       // this code returns "??" for all cells.\r
+                       //BSTR bstr = val.bstrVal;\r
+                       //const char *text = _com_util::ConvertBSTRToString(bstr);\r
+\r
+                       jstring ret = env->NewStringUTF((const char*)text);\r
+                       delete[] text;\r
+                       return ret;\r
+               } catch (...) {\r
+                       return NULL; \r
+               }\r
+       } \r
+       SIMANTICS_DEBUG("%d\r\n",val.vt);\r
+       return NULL; \r
+\r
+}\r
+*/
\ No newline at end of file