X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.excel%2Fnative%2FSimanticsExcel2008%2FSimanticsExcel2008%2FInterface.cpp;fp=bundles%2Forg.simantics.excel%2Fnative%2FSimanticsExcel2008%2FSimanticsExcel2008%2FInterface.cpp;h=582eafd7d0a29c20849a4a71b1d7b0f7eec38669;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.excel/native/SimanticsExcel2008/SimanticsExcel2008/Interface.cpp b/bundles/org.simantics.excel/native/SimanticsExcel2008/SimanticsExcel2008/Interface.cpp new file mode 100644 index 000000000..582eafd7d --- /dev/null +++ b/bundles/org.simantics.excel/native/SimanticsExcel2008/SimanticsExcel2008/Interface.cpp @@ -0,0 +1,519 @@ + +#include "stdafx.h" + +#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) { + + try { + + string val = getString(env, value); + + SIMANTICS_DEBUG("setString(%d, %d, %s)\r\n", row, column, val.c_str()); + + Excel::_WorksheetPtr sheet = getWorksheet(handle); + + SIMANTICS_DEBUG("setString2(%d, %d, %s)\r\n", row, column, val.c_str()); + + if(!sheet) return -1; + + struct Range *_range = 0; + HRESULT _hr = sheet->get_Cells(&_range); + if (FAILED(_hr)) return -1; + Excel::RangePtr range = RangePtr(_range, false); + + SIMANTICS_DEBUG("setString3(%d, %d, %s)\r\n", row, column, val.c_str()); + + if(!range) return -2; + + const char *text = val.c_str(); + + SIMANTICS_DEBUG("setString4(%d, %d, %s)\r\n", row, column, val.c_str()); + + Excel::RangePtr cell = range->Item[row+1][column+1]; + if(!cell) return -4; + + SIMANTICS_DEBUG("setString5(%d, %d, %s)\r\n", row, column, val.c_str()); + + cell->Item[1][1] = text; + +// cell = text; + + return 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("SetString error 1 '%s' '%s'\r\n", s.c_str(), s2.c_str()); + return -5; + + } catch (exception& e) { + + SIMANTICS_DEBUG("SetString error 2 '%s'\r\n", e.what()); + return -5; + + } catch (...) { + + SIMANTICS_DEBUG("SetString error\r\n"); + return -5; + + } + +} + +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); + + try { + + Excel::_WorksheetPtr sheet = getWorksheet(handle); + if(!sheet) return -1; + + // Release this reference for Close + handles.erase(handle); + + SIMANTICS_DEBUG("closing 1\r\n"); + + struct Range *_range = 0; + HRESULT _hr = sheet->get_Cells(&_range); + if (FAILED(_hr)) return -1; + + SIMANTICS_DEBUG("closing 2\r\n"); + + 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; + } + + 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 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; + } + } + + } 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("Close error 1 '%s' '%s'\r\n", s.c_str(), s2.c_str()); + return -5; + } catch (exception& e) { + SIMANTICS_DEBUG("Close error 2 '%s'\r\n", e.what()); + return -5; + } catch (...) { + SIMANTICS_DEBUG("Close error\r\n"); + return -5; + } + + + +// SIMANTICS_DEBUG("About to hide"); + +// application->put_Interactive( 0, VARIANT_FALSE ); +// application->put_Visible( 0, VARIANT_FALSE ); + +// if(handles.empty()) +// application->Quit(); + + return 0; + +}