X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.excel%2Fnative%2FInterface.cpp;h=9e67f4aa8258bb2ea627b0d5d971e512116fc073;hp=910df78bd982b946d553b04b0f2fb01e59fd4c2e;hb=0c128e8f1ce1dd42d4375b0f91e4e93f02214ccf;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.excel/native/Interface.cpp b/bundles/org.simantics.excel/native/Interface.cpp index 910df78bd..9e67f4aa8 100644 --- a/bundles/org.simantics.excel/native/Interface.cpp +++ b/bundles/org.simantics.excel/native/Interface.cpp @@ -1,528 +1,518 @@ - -//#include "stdafx.h" - -//#ifndef _UNICODE -//#define _UNICODE -//#endif - -#include -#include -//#include -//#include - -using namespace std; - -#import "c:/program files (x86)/common files/microsoft shared/office12/mso.dll" \ - rename( "RGB", "MSORGB" ) - -using namespace Office; - -#import "c:/program files (x86)/common files/microsoft shared/vba/vba6/vbe6ext.olb" \ - -using namespace VBIDE; - -#import "c:/program files (x86)/microsoft office/office12/excel.exe" \ - rename( "DialogBox", "ExcelDialogBox" ) \ - rename( "RGB", "ExcelRGB" ) \ - rename( "CopyFile", "ExcelCopyFile" ) \ - rename( "ReplaceText", "ExcelReplaceText" ) - -#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 Excel; - -map 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;iWorkbooks->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;iSheets->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;iSheets->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::iterator it = handles.find(handle); - if(it != handles.end()) return (*it).second; - else return 0; -} -*/ - -Excel::_WorksheetPtr getWorksheet(int handle) { - map::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::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) { - - //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; - - variant_t val = 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; - 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); - - // this code returns "??" for all cells. - //BSTR bstr = val.bstrVal; - //const char *text = _com_util::ConvertBSTRToString(bstr); - - jstring ret = env->NewStringUTF((const char*)text); - delete[] text; - return ret; - } catch (...) { - return NULL; - } - } - SIMANTICS_DEBUG("%d\r\n",val.vt); - return NULL; - -} -*/ \ No newline at end of file + +#include +#include +#include +#include +#include +#include + +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 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;iWorkbooks->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;iSheets->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;iSheets->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::iterator it = handles.find(handle); + if(it != handles.end()) return (*it).second; + else return 0; +} +*/ + +Excel::_WorksheetPtr getWorksheet(int handle) { + map::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::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; + +}