]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.excel/native/Interface.cpp
SimanticsExcel interface refresh
[simantics/platform.git] / bundles / org.simantics.excel / native / Interface.cpp
index 910df78bd982b946d553b04b0f2fb01e59fd4c2e..9e67f4aa8258bb2ea627b0d5d971e512116fc073 100644 (file)
-\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
+
+#include <sstream>
+#include <map>
+#include <stdio.h>
+#include <tchar.h>
+#include <cstring>
+#include <atlstr.h>
+
+using namespace std;
+
+// mso.dll
+#import "libid:{2df8d04c-5bfa-101b-bde5-00aa0044de52}"  auto_rename
+// vb6ext.olb
+#import "libid:{0002e157-0000-0000-c000-000000000046}"  auto_rename
+// excel.exe
+#import "libid:{00020813-0000-0000-c000-000000000046}"  auto_rename
+
+using namespace Excel;
+
+#include "jni2.h"
+
+//#define SIMANTICS_DEBUG(...) \
+//{ FILE *fp = fopen("d:/excel.log", "ab"); fprintf(fp, __VA_ARGS__); fflush(fp); fclose(fp);  }
+
+#define SIMANTICS_DEBUG(...)
+
+//using namespace std;
+//using namespace Office;
+
+map<int, _WorksheetPtr> handles;
+static int handleCounter = 1;
+
+void replace(std::string &s, const std::string &s1, const std::string &s2) {
+
+       int index = 0;
+
+       index = s.find(s1, index);
+       while(index != std::string::npos) {
+               s.replace(index, s1.length(), s2.c_str(), s2.length());
+               index = s.find(s1, index + 1);
+       }
+
+}
+
+boolean getString(JNIEnv *env, jstring str, char *target) {
+
+    jboolean iscopy;
+    const char *chars = env->GetStringUTFChars(str, &iscopy);
+       if(!chars) return false;
+
+       strcpy(target, chars);
+
+    env->ReleaseStringUTFChars(str, chars);
+
+       return true;
+
+}
+
+string getString(JNIEnv *env, jstring str) {
+
+    jboolean iscopy;
+    const char *chars = env->GetStringUTFChars(str, &iscopy);
+       if(!chars) return 0;
+       string result = chars;
+    env->ReleaseStringUTFChars(str, chars);
+       return result;
+
+}
+
+Excel::_ApplicationPtr getApplication(bool create) {
+       
+       Excel::_ApplicationPtr application;
+
+       CLSID clsid;
+       HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);
+       if(FAILED(hr)) {
+               return 0;
+       }
+
+       if (!SUCCEEDED(application.GetActiveObject(clsid)))
+       {
+               if(create) {
+                       hr = application.CreateInstance(clsid);
+                       if(FAILED(hr)) {
+                               return 0;
+                       }
+               } else {
+                       return 0;
+               }
+       }
+
+       application->EnableEvents = VARIANT_FALSE;
+
+       return application;
+
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_init(JNIEnv *env, jobject) {
+
+       SIMANTICS_DEBUG("Excel init\r\n");
+
+       HRESULT hr = ::OleInitialize(NULL);
+       if(FAILED(hr)) {
+               return hr;
+       }
+
+       /*
+       Excel::_ApplicationPtr application = getApplication(true);
+       if(!application) return -1;
+       bstr_t version = application->GetVersion(0);
+       ostringstream os;
+       os << version << endl;
+       SIMANTICS_DEBUG("Init successful with version %s\r\n",  os.str().c_str());
+
+       application->put_Interactive( 0, VARIANT_FALSE );
+       application->put_Visible( 0, VARIANT_FALSE );
+       */
+
+       return 0;
+
+}
+
+Excel::_WorkbookPtr getWorkbook(const Excel::_ApplicationPtr &application, const string &fileName) {
+
+       SIMANTICS_DEBUG("getWorkbook(%s)\r\n", fileName.c_str());
+
+       for(int i=0;i<application->Workbooks->Count;i++) {
+               _bstr_t fullName;
+               Excel::_WorkbookPtr workbook = application->Workbooks->GetItem( _variant_t(i+1) );
+               workbook->get_FullName(0, &fullName.GetBSTR());
+               std::string fullNameStr = fullName;
+               SIMANTICS_DEBUG("'%s'\r\n", fullNameStr.c_str());
+               if(fullNameStr == fileName) return workbook;
+       }
+
+       return 0;
+
+}
+
+Excel::_WorksheetPtr getWorksheet(const Excel::_WorkbookPtr workbook, const string &sheetName) {
+
+       SIMANTICS_DEBUG("getWorksheet(%s)\r\n", sheetName.c_str());
+
+       for(int i=0;i<workbook->Sheets->Count;i++) {
+               Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));
+               std:string name = sheet->Name;
+               SIMANTICS_DEBUG("'%s'\r\n", name.c_str());
+               if(name == sheetName) return sheet;
+       }
+
+       return 0;
+
+}
+
+char message[1024];
+
+JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_open(JNIEnv *env, jobject, jstring fileName, jstring sheetName_) {
+
+       string name = getString(env, fileName);
+       string sheetName = getString(env, sheetName_);
+
+       _variant_t varOption( (long) DISP_E_PARAMNOTFOUND, VT_ERROR );
+
+       Excel::_ApplicationPtr application = getApplication(true);
+       if(!application) return env->NewStringUTF("Excel application could not be started.");
+
+       Excel::_WorkbookPtr workbook = getWorkbook(application, name);
+       if(!workbook) {
+
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Opening.\r\n", name.c_str());
+
+               FILE *fp = fopen(name.c_str(), "r");
+               if(fp) {
+
+               SIMANTICS_DEBUG("getWorkbook(%s) book was found. Opening file.\r\n", name.c_str());
+
+                       fclose(fp);
+                       workbook = application->Workbooks->OpenXML(_bstr_t(name.c_str()), 
+                               varOption, varOption);
+                       if(!workbook) return env->NewStringUTF("File could not be opened.");
+
+               } else {
+
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creating file.\r\n", name.c_str());
+
+                       workbook = application->Workbooks->Add(varOption);
+
+                       if(!workbook) return env->NewStringUTF("New workbook could not be created.");
+
+                       try {
+
+                               Excel::_WorksheetPtr sheet = workbook->Sheets->Add();
+                               sheet->Name = _bstr_t(sheetName.c_str());
+
+                               /*
+                               // Does not work for some unknown reason
+                               for(int i=0;i<workbook->Sheets->Count;i++) {
+                                       Excel::_WorksheetPtr sheet = workbook->Sheets->GetItem(_variant_t(i+1));
+                                       if(name != sheetName)
+                                               sheet->PutVisible(0, Excel::XlSheetVisibility::xlSheetVeryHidden);
+                               }
+                               */
+
+                               workbook->SaveAs(_bstr_t(name.c_str()), varOption, varOption, varOption, varOption,
+                                       varOption, Excel::xlExclusive, varOption, varOption, varOption, varOption, 0);
+
+                       } catch (_com_error& e) {
+                               _bstr_t bstr = _bstr_t(e.ErrorMessage());
+                               string s(bstr);
+                               _bstr_t bstr2 = _bstr_t(e.Description());
+                               string s2(bstr2);
+                               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 1 '%s' '%s'\r\n", name.c_str(), s.c_str(), s2.c_str());
+                               strcpy(message, s2.c_str());
+                               return env->NewStringUTF(message);
+                       } catch (exception& e) {
+                               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());
+                               return env->NewStringUTF(e.what());
+                       } catch (...) {
+                               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 3 \r\n", name.c_str());
+                               return env->NewStringUTF("Undefined error");
+                       }
+               
+
+               }
+
+       }
+
+       application->put_Interactive( 0, VARIANT_TRUE );
+       application->put_Visible( 0, VARIANT_TRUE );
+
+       workbook->Activate();
+
+       SIMANTICS_DEBUG("getWorkbook(%s) searches for sheet '%s'\r\n", name.c_str(), sheetName.c_str());
+
+       try {
+               Excel::_WorksheetPtr sheet = getWorksheet(workbook, sheetName);
+               if(!sheet) {
+                       SIMANTICS_DEBUG("creating sheet %s for '%s'\r\n", sheetName.c_str(), name.c_str());
+                       sheet = workbook->Sheets->Add();
+                       sheet->Name = _bstr_t(sheetName.c_str());
+               }
+           int handle = handleCounter++;
+       SIMANTICS_DEBUG("opened handle %d for '%s'\r\n", handle, name.c_str());
+       handles[handle] = sheet;
+               ostringstream os;
+               os << handle;
+               return env->NewStringUTF(os.str().c_str());
+
+       } catch (_com_error& e) {
+               _bstr_t bstr = _bstr_t(e.ErrorMessage());
+               string s(bstr);
+               _bstr_t bstr2 = _bstr_t(e.Description());
+               string s2(bstr2);
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 1 '%s' '%s'\r\n", name.c_str(), s.c_str(), s2.c_str());
+               return env->NewStringUTF(s2.c_str());
+       } catch (exception& e) {
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error 2 '%s'\r\n", name.c_str(), e.what());
+               return env->NewStringUTF(e.what());
+       } catch (...) {
+               SIMANTICS_DEBUG("getWorkbook(%s) book was not found. Creation error\r\n", name.c_str());
+               return env->NewStringUTF("Unhandled exception.");
+       }
+
+
+       //Excel::_WorksheetPtr sheet = workbook->ActiveSheet;
+       //if(!sheet) return -4;
+
+
+}
+
+string cellName(int row, int column) {
+
+       string result;
+
+       SIMANTICS_DEBUG("cellName(%d, %d) -> ", row, column);
+
+       do {
+               char rem = column % 26;
+               char c = 'A' + rem;
+               result += c;
+               column -= rem;
+               column /= 26;
+       } while(column);
+
+       ostringstream os;
+       os << (row + 1);
+       result += os.str();
+
+       SIMANTICS_DEBUG("%s\r\n", result.c_str());
+
+       return result;
+
+}
+
+/*
+Excel::_WorkbookPtr getWorkbook(int handle) {
+       map<int, Excel::_WorkbookPtr>::iterator it = handles.find(handle);
+       if(it != handles.end()) return (*it).second;
+       else return 0;
+}
+*/
+
+Excel::_WorksheetPtr getWorksheet(int handle) {
+       map<int, Excel::_WorksheetPtr>::iterator it = handles.find(handle);
+       if(it != handles.end()) return (*it).second;
+       else return 0;
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setDouble(JNIEnv *env, jobject, jint handle, jint row, jint column, jdouble value) {
+
+       SIMANTICS_DEBUG("setDouble(%d, %d, %f)\r\n", row, column, value);
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return -1;
+       Excel::RangePtr range = sheet->Cells;
+       if(!range) return -2;
+       range->Item[row+1][column+1] = value;
+
+       return 0;
+
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setString(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {
+
+       string val = getString(env, value);
+
+       SIMANTICS_DEBUG("setString(%d, %d, %s)\r\n", row, column, val.c_str());
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return -1;
+       Excel::RangePtr range = sheet->Cells;
+       if(!range) return -2;
+
+       const char *text = val.c_str();
+
+       range->Item[row+1][column+1] = text;
+       //range->Name[row+1][column+1] = text;
+
+       return 0;
+
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setName(JNIEnv *env, jobject, jint handle, jint row, jint column, jstring value) {
+
+       string val = getString(env, value);
+
+       SIMANTICS_DEBUG("setName(%d, %d, %s)\r\n", row, column, val.c_str());
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return -1;
+       //sheet->c
+       Excel::RangePtr range = sheet->GetRange(_variant_t(cellName(row, column).c_str()));
+       if(!range) return -2;
+       range->Name = _variant_t(val.c_str());
+
+
+       //range->Item[row+1][column+1] = text;
+       //range->Name[row+1][column+1] = text;
+
+       return 0;
+
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_setVisible(JNIEnv *env, jobject, jint handle, jboolean value) {
+
+       SIMANTICS_DEBUG("setVisible(%d)\r\n", value);
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return -1;
+       Excel::_ApplicationPtr application = sheet->Application;
+       if(!application) return -2;
+
+       if(value) {
+               application->put_Interactive( 0, VARIANT_TRUE );
+               application->put_Visible( 0, VARIANT_TRUE );
+       } else {
+               application->put_Interactive( 0, VARIANT_FALSE );
+               application->put_Visible( 0, VARIANT_FALSE );
+       }
+
+       return 0;
+
+}
+
+JNIEXPORT jint JNICALL Java_org_simantics_excel_Excel_close(JNIEnv *env, jobject, jint handle) {
+
+       SIMANTICS_DEBUG("closing handle %d\r\n", handle);
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return -1;
+       Excel::_ApplicationPtr application = sheet->Application;
+       if(!application) return -2;
+
+       Excel::_WorkbookPtr workbook = (Excel::_WorkbookPtr)sheet->Parent;
+       if(!workbook) return -3;
+
+//     SIMANTICS_DEBUG("About to save\r\n");
+       HRESULT hr = workbook->Save();
+//     workbook->put_Saved(0, VARIANT_TRUE);
+       if(FAILED(hr)) {
+               SIMANTICS_DEBUG("Save failed with %d\r\n", hr);
+               return hr;
+       }
+//     SIMANTICS_DEBUG("About to AcceptAllChanges\r\n");
+//     HRESULT hr = workbook->AcceptAllChanges();
+//     if(FAILED(hr)) {
+
+       //SIMANTICS_DEBUG("Close failed with %d\r\n", hr);
+       //      return hr;
+       //}
+
+       // Release this reference for Close
+       handles.erase(handle);
+
+       map<int, Excel::_WorksheetPtr>::iterator it = handles.begin();
+       for(;it != handles.end();++it) {
+               Excel::_WorksheetPtr sheet2 = (*it).second;
+               Excel::_WorkbookPtr book = (Excel::_WorkbookPtr)sheet2->Parent;
+               // The book remains open
+               if(book->Name == workbook->Name) return 0;
+       }
+
+       //SIMANTICS_DEBUG("About to PutUserControl\r\n");
+       //workbook->PutUserControl(VARIANT_FALSE);
+       SIMANTICS_DEBUG("About to Close\r\n");
+       hr = workbook->Close(VARIANT_FALSE);
+       if(FAILED(hr)) {
+               SIMANTICS_DEBUG("Close failed with %d\r\n", hr);
+               return hr;
+       }
+
+       long remaining = 0;
+
+       application->Workbooks->get_Count(&remaining);
+       if(!remaining) {
+               application->put_Interactive( 0, VARIANT_FALSE );
+               application->put_Visible( 0, VARIANT_FALSE );
+               hr = application->Quit();
+               if(FAILED(hr)) {
+                       SIMANTICS_DEBUG("Close failed with %d\r\n", hr);
+                       return hr;
+               }
+       }
+
+//     SIMANTICS_DEBUG("About to hide");
+
+//     application->put_Interactive( 0, VARIANT_FALSE );
+//     application->put_Visible( 0, VARIANT_FALSE );
+
+//     if(handles.empty())
+//             application->Quit();
+
+       return 0;
+
+}
+
+
+JNIEXPORT jdouble JNICALL Java_org_simantics_excel_Excel_getDouble(JNIEnv *env, jobject, jint handle, jint row, jint column) {
+
+       SIMANTICS_DEBUG("getDouble(%d, %d)\r\n", row, column);
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return 0.0; // TODO: NAN
+       Excel::RangePtr range = sheet->Cells;
+       if(!range) return 0.0; // TODO: NAN
+
+       variant_t val = range->Item[row+1][column+1];
+       if (val.vt != VT_NULL) {
+               try {
+                       double d = val;
+                       SIMANTICS_DEBUG("%f\r\n",d);
+                       return d;
+               } catch (...) {
+                       return 0.0; // TODO: NAN
+               }
+       }
+       return 0.0; // TODO: NAN
+
+}
+
+JNIEXPORT jstring JNICALL Java_org_simantics_excel_Excel_getString(JNIEnv *env, jobject, jint handle, jint row, jint column) {
+       USES_CONVERSION;
+       //string val = getString(env, value);
+
+       SIMANTICS_DEBUG("getString(%d, %d)\r\n", row, column);
+
+       Excel::_WorksheetPtr sheet = getWorksheet(handle);
+       if(!sheet) return NULL;
+       Excel::RangePtr range = sheet->Cells;
+       if(!range) return NULL;
+
+       _bstr_t val = _bstr_t(range->Item[row + 1][column + 1]);
+       //if (val.vt != VT_NULL) {  // val.vt seems to be always VT_DISPATCH.
+               //try {
+                       //this call will crash the application, if the cell is empty!
+                       //_bstr_t bstrt = val;
+                       //std::string text(val);
+                       //CString text(val);
+                       //text.
+                       //TCHAR text[1024];
+                       // 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.
+                       //_stprintf(text, _T("%s"), (LPCTSTR)bstrt);
+                       //const char *text = bstrt;
+                       SIMANTICS_DEBUG("%s\r\n",text);
+
+                       string text(val);
+
+
+                       return env->NewStringUTF(text.c_str());
+
+               //} catch (...) {
+               //      return NULL; 
+               //}
+       //} 
+       //SIMANTICS_DEBUG("%d\r\n",val.vt);
+       //return NULL; 
+
+}