From cb1bfddc8905b63909a9321bde0d388fbc42396e Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 2 Jun 2016 18:14:43 +0300 Subject: [PATCH] docbuilder new scheme (extension in core-ext) --- .../doctrenderer/docbuilder.com/docbuilder.h | 10 +- DesktopEditor/doctrenderer/docbuilder.cpp | 1307 +--------------- DesktopEditor/doctrenderer/docbuilder.h | 5 +- .../docbuilder.net/docbuilder.net.cpp | 13 +- .../docbuilder.net/docbuilder.net.h | 3 +- DesktopEditor/doctrenderer/docbuilder_p.h | 1388 +++++++++++++++++ DesktopEditor/doctrenderer/doctrenderer.pro | 1 + .../doctrenderer/test_builder/docbuilder.pro | 2 +- .../doctrenderer/test_builder/main.cpp | 7 +- 9 files changed, 1417 insertions(+), 1319 deletions(-) create mode 100644 DesktopEditor/doctrenderer/docbuilder_p.h diff --git a/DesktopEditor/doctrenderer/docbuilder.com/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.com/docbuilder.h index 47c8f9c8cb..90c3676815 100644 --- a/DesktopEditor/doctrenderer/docbuilder.com/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.com/docbuilder.h @@ -33,7 +33,7 @@ __interface IASCDocBuilder : IDispatch [id(105)] HRESULT ExecuteCommand([in] BSTR command, [out, retval] VARIANT_BOOL* result); [id(106)] HRESULT Run([in] BSTR path, [out, retval] VARIANT_BOOL* result); [id(107)] HRESULT RunText([in] BSTR commands, [out, retval] VARIANT_BOOL* result); - [id(108)] HRESULT SetProperty([in] BSTR sproperty); + [id(108)] HRESULT SetProperty([in] BSTR key, [in] BSTR value); [id(201)] HRESULT Initialize(void); [id(202)] HRESULT Dispose(void); @@ -66,7 +66,7 @@ public: if (NULL != m_pBuilder) delete m_pBuilder; - m_pBuilder = new NSDoctRenderer::CDocBuilder((VARIANT_TRUE == checkFonts) ? true : false); + m_pBuilder = new NSDoctRenderer::CDocBuilder(); return S_OK; } STDMETHOD(OpenFile)(BSTR path, BSTR params, VARIANT_BOOL* result) @@ -138,14 +138,12 @@ public: *result = bRet ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; } - STDMETHOD(SetProperty)(BSTR sproperty) + STDMETHOD(SetProperty)(BSTR key, BSTR value) { if (NULL == m_pBuilder) return S_FALSE; - std::wstring sData(sproperty); - std::string sDataA = U_TO_UTF8(sData); - m_pBuilder->SetProperty(sDataA.c_str()); + m_pBuilder->SetPropertyW(key, value); return S_OK; } diff --git a/DesktopEditor/doctrenderer/docbuilder.cpp b/DesktopEditor/doctrenderer/docbuilder.cpp index 5d42c26461..4fe58bce0e 100644 --- a/DesktopEditor/doctrenderer/docbuilder.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.cpp @@ -1,1112 +1,10 @@ -#include "docbuilder.h" -#include "doctrenderer.h" - -#include "../xml/include/xmlutils.h" -#include - -#define ASC_APPLICATION_FONTS_NO_THUMBNAILS -#include "../fontengine/application_generate_fonts.h" - -#include "../common/File.h" -#include "../common/Directory.h" - -#include "../../Common/OfficeFileFormats.h" -#include "../../Common/OfficeFileFormatChecker.h" - -#include "nativecontrol.h" -#include - -#ifdef LINUX -#include -#include -#include -#endif - -template -class CScopeWrapper -{ -private: - T m_handler; - -private: - CScopeWrapper(const CScopeWrapper&) {} - void operator=(const CScopeWrapper&) {} - -public: - - CScopeWrapper(v8::Isolate* isolate) : m_handler(isolate) {} -}; - -class CV8RealTimeWorker -{ -public: - v8::Isolate* m_isolate; - - v8::Isolate::Scope* m_isolate_scope; - v8::Locker* m_isolate_locker; - - CScopeWrapper* m_handle_scope; - v8::Local m_context; - - int m_nFileType; - -public: - - CV8RealTimeWorker() - { - m_nFileType = -1; - - m_isolate = CV8Worker::getInitializer()->CreateNew(); - - m_isolate_scope = new v8::Isolate::Scope(m_isolate); - m_isolate_locker = new v8::Locker(m_isolate); - m_handle_scope = new CScopeWrapper(m_isolate); - - v8::Handle global = v8::ObjectTemplate::New(); - global->Set(v8::String::NewFromUtf8(m_isolate, "CreateNativeEngine"), v8::FunctionTemplate::New(m_isolate, CreateNativeObjectBuilder)); - global->Set(v8::String::NewFromUtf8(m_isolate, "CreateNativeMemoryStream"), v8::FunctionTemplate::New(m_isolate, CreateNativeMemoryStream)); - - m_context = v8::Context::New(m_isolate, NULL, global); - } - ~CV8RealTimeWorker() - { - RELEASEOBJECT(m_handle_scope); - m_context.Clear(); - - RELEASEOBJECT(m_isolate_locker); - RELEASEOBJECT(m_isolate_scope); - - m_isolate->Dispose(); - m_isolate = NULL; - } - -public: - - static void _LOGGING_ERROR_(const std::wstring& strType, const std::wstring& strError) - { - std::string sT = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strType); - std::string sE = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strError); - - std::cerr << sT << ": " << sE << std::endl; - } - - bool ExecuteCommand(const std::wstring& command) - { - LOGGER_SPEED_START - - std::string commandA = U_TO_UTF8(command); - //commandA = "_api." + commandA; - - v8::Context::Scope context_scope(m_context); - - v8::TryCatch try_catch; - - v8::Local source = v8::String::NewFromUtf8(m_isolate, commandA.c_str()); - v8::Local script = v8::Script::Compile(source); - - LOGGER_SPEED_LAP("compile_command") - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"execute_compile_code", strCode); - _LOGGING_ERROR_(L"execute_compile", strException); - - return false; - } - else - { - script->Run(); - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"execute_run_code", strCode); - _LOGGING_ERROR_(L"execute_run", strException); - - return false; - } - } - - LOGGER_SPEED_LAP("run_command") - - return true; - } - - bool OpenFile(const std::wstring& path, const std::string& sString) - { - LOGGER_SPEED_START - - v8::Context::Scope context_scope(m_context); - - v8::TryCatch try_catch; - - v8::Local source = v8::String::NewFromUtf8(m_isolate, sString.c_str()); - v8::Local script = v8::Script::Compile(source); - - LOGGER_SPEED_LAP("compile") - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"sdk_compile_code", strCode); - _LOGGING_ERROR_(L"sdk_compile", strException); - - return false; - } - else - { - script->Run(); - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"sdk_run_code", strCode); - _LOGGING_ERROR_(L"sdk_run", strException); - - return false; - } - } - LOGGER_SPEED_LAP("run") - - CNativeControl* pNative = NULL; - bool bIsBreak = false; - - v8::Local global_js = m_context->Global(); - v8::Handle args[1]; - args[0] = v8::Int32::New(m_isolate, 0); - - // GET_NATIVE_ENGINE - if (!bIsBreak) - { - v8::Handle js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine")); - v8::Local objNative; - if (js_func_get_native->IsFunction()) - { - v8::Handle func_get_native = v8::Handle::Cast(js_func_get_native); - v8::Local js_result2 = func_get_native->Call(global_js, 1, args); - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"run_code", strCode); - _LOGGING_ERROR_(L"run", strException); - - bIsBreak = true; - } - else - { - objNative = js_result2->ToObject(); - v8::Handle field = v8::Handle::Cast(objNative->GetInternalField(0)); - - pNative = static_cast(field->Value()); - } - } - } - - if (pNative != NULL) - { - pNative->m_strFontsDirectory = NSFile::GetProcessDirectory() + L"/sdkjs/common"; - pNative->m_strImagesDirectory = path + L"/media"; - - pNative->CheckFonts(); - - if (0 == m_nFileType) - pNative->m_strEditorType = L"document"; - else if (1 == m_nFileType) - pNative->m_strEditorType = L"presentation"; - else - pNative->m_strEditorType = L"spreadsheet"; - - pNative->SetFilePath(path + L"/Editor.bin"); - - pNative->m_sChangesBuilderPath = path + L"/changes/changes0.json"; - - pNative->m_nMaxChangesNumber = -1; - } - - // OPEN - if (!bIsBreak) - { - v8::Handle js_func_open = global_js->Get(v8::String::NewFromUtf8(m_isolate, "NativeOpenFileData")); - if (js_func_open->IsFunction()) - { - v8::Handle func_open = v8::Handle::Cast(js_func_open); - - CChangesWorker oWorkerLoader; - int nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath()); - - v8::Handle args_open[2]; - args_open[0] = oWorkerLoader.GetDataFull(); - args_open[1] = v8::Integer::New(m_isolate, nVersion); - - func_open->Call(global_js, 2, args_open); - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"open_code", strCode); - _LOGGING_ERROR_(L"open", strException); - - bIsBreak = true; - } - } - } - - if (!bIsBreak) - bIsBreak = !this->ExecuteCommand(L"_api.asc_nativeInitBuilder();"); - if (!bIsBreak) - bIsBreak = !this->ExecuteCommand(L"_api.asc_SetSilentMode(true);"); - - LOGGER_SPEED_LAP("open") - - return !bIsBreak; - } - - bool SaveFileWithChanges(int type, const std::wstring& _path) - { - NSDoctRenderer::DoctRendererFormat::FormatFile _formatDst = NSDoctRenderer::DoctRendererFormat::DOCT; - if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) - _formatDst = NSDoctRenderer::DoctRendererFormat::PPTT; - else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) - _formatDst = NSDoctRenderer::DoctRendererFormat::XLST; - else if (type & AVS_OFFICESTUDIO_FILE_CROSSPLATFORM) - _formatDst = NSDoctRenderer::DoctRendererFormat::PDF; - - v8::Context::Scope context_scope(m_context); - v8::TryCatch try_catch; - - CNativeControl* pNative = NULL; - - v8::Local global_js = m_context->Global(); - v8::Handle args[1]; - args[0] = v8::Int32::New(m_isolate, 0); - - // GET_NATIVE_ENGINE - if (true) - { - v8::Handle js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine")); - v8::Local objNative; - if (js_func_get_native->IsFunction()) - { - v8::Handle func_get_native = v8::Handle::Cast(js_func_get_native); - v8::Local js_result2 = func_get_native->Call(global_js, 1, args); - - if (try_catch.HasCaught()) - { - std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); - std::wstring strException = to_cstring(try_catch.Message()->Get()); - - _LOGGING_ERROR_(L"run_code", strCode); - _LOGGING_ERROR_(L"run", strException); - } - else - { - objNative = js_result2->ToObject(); - v8::Handle field = v8::Handle::Cast(objNative->GetInternalField(0)); - - pNative = static_cast(field->Value()); - } - } - } - - if (pNative == NULL) - return false; - - if (_formatDst == NSDoctRenderer::DoctRendererFormat::PDF) - this->ExecuteCommand(L"_api.asc_SetSilentMode(false);"); - - std::wstring strError; - bool bIsError = Doct_renderer_SaveFile_ForBuilder(_formatDst, - _path, - pNative, - m_isolate, - global_js, - args, - try_catch, - strError); - - if (_formatDst == NSDoctRenderer::DoctRendererFormat::PDF) - this->ExecuteCommand(L"_api.asc_SetSilentMode(true);"); - - return bIsError; - } -}; - -#ifdef CreateFile -#undef CreateFile -#endif +#include "docbuilder_p.h" namespace NSDoctRenderer { - class CDocBuilder_Private + CDocBuilder::CDocBuilder() { - public: - CArray m_arrFiles; - - std::vector m_arDoctSDK; - std::vector m_arPpttSDK; - std::vector m_arXlstSDK; - - std::wstring m_strEditorType; - std::wstring m_strFilePath; - - std::wstring m_strAllFonts; - - std::wstring m_sTmpFolder; - std::wstring m_sFileDir; - int m_nFileType; - - std::wstring m_sX2tPath; - - CV8RealTimeWorker* m_pWorker; - - bool m_bIsSaveWithDoctrendererMode; - public: - CDocBuilder_Private(bool bIsCheckSystemFonts) - { - m_bIsSaveWithDoctrendererMode = false; - - m_sX2tPath = NSFile::GetProcessDirectory(); - m_pWorker = NULL; - - m_nFileType = -1; - -#if 0 - m_sX2tPath += L"/converter"; -#endif - - std::wstring sConfigDir = NSFile::GetProcessDirectory() + L"/"; - std::wstring sConfigPath = sConfigDir + L"DoctRenderer.config"; - - XmlUtils::CXmlNode oNode; - if (oNode.FromXmlFile(sConfigPath)) - { - XmlUtils::CXmlNodes oNodes; - if (oNode.GetNodes(L"file", oNodes)) - { - int nCount = oNodes.GetCount(); - XmlUtils::CXmlNode _node; - for (int i = 0; i < nCount; ++i) - { - oNodes.GetAt(i, _node); - std::wstring strFilePath = _node.GetText(); - - if (std::wstring::npos != strFilePath.find(L"AllFonts.js")) - { - m_strAllFonts = strFilePath; - - if (!NSFile::CFileBinary::Exists(m_strAllFonts) || NSFile::CFileBinary::Exists(sConfigDir + m_strAllFonts)) - m_strAllFonts = sConfigDir + m_strAllFonts; - } - - if (NSFile::CFileBinary::Exists(strFilePath) && !NSFile::CFileBinary::Exists(sConfigDir + strFilePath)) - m_arrFiles.Add(strFilePath); - else - m_arrFiles.Add(sConfigDir + strFilePath); - } - } - } - - XmlUtils::CXmlNode oNodeSdk = oNode.ReadNode(L"DoctSdk"); - if (oNodeSdk.IsValid()) - LoadSDK_scripts(oNodeSdk, m_arDoctSDK, sConfigDir); - - oNodeSdk = oNode.ReadNode(L"PpttSdk"); - if (oNodeSdk.IsValid()) - LoadSDK_scripts(oNodeSdk, m_arPpttSDK, sConfigDir); - - oNodeSdk = oNode.ReadNode(L"XlstSdk"); - if (oNodeSdk.IsValid()) - LoadSDK_scripts(oNodeSdk, m_arXlstSDK, sConfigDir); - - CheckFonts(bIsCheckSystemFonts); - - m_sTmpFolder = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"DTB"); - - // под линуксом предыдущая функция создает файл!!! - if (NSFile::CFileBinary::Exists(m_sTmpFolder)) - NSFile::CFileBinary::Remove(m_sTmpFolder); - } - - ~CDocBuilder_Private() - { - CloseFile(); - } - - void LoadSDK_scripts(XmlUtils::CXmlNode& oNode, std::vector& _files, const std::wstring& strConfigDir) - { - XmlUtils::CXmlNodes oNodes; - if (oNode.GetNodes(L"file", oNodes)) - { - int nCount = oNodes.GetCount(); - XmlUtils::CXmlNode _node; - for (int i = 0; i < nCount; ++i) - { - oNodes.GetAt(i, _node); - std::wstring strFilePath = _node.GetText(); - - if (NSFile::CFileBinary::Exists(strFilePath) && - !NSFile::CFileBinary::Exists(strConfigDir + strFilePath)) - _files.push_back(strFilePath); - else - _files.push_back(strConfigDir + strFilePath); - } - } - else - { - std::wstring strFilePath = oNode.GetText(); - - if (NSFile::CFileBinary::Exists(strFilePath) && - !NSFile::CFileBinary::Exists(strConfigDir + strFilePath)) - _files.push_back(strFilePath); - else - _files.push_back(strConfigDir + strFilePath); - } - } - - void CheckFonts(bool bIsCheckSystemFonts) - { - CArray strFonts; - std::wstring strDirectory = NSCommon::GetDirectoryName(m_strAllFonts); - - std::wstring strAllFontsJSPath = strDirectory + L"/AllFonts.js"; - std::wstring strFontsSelectionBin = strDirectory + L"/font_selection.bin"; - - if (true) - { - NSFile::CFileBinary oFile; - if (oFile.OpenFile(strDirectory + L"/fonts.log")) - { - int nSize = oFile.GetFileSize(); - char* pBuffer = new char[nSize]; - DWORD dwReaden = 0; - oFile.ReadFile((BYTE*)pBuffer, nSize, dwReaden); - oFile.CloseFile(); - - int nStart = 0; - int nCur = nStart; - for (; nCur < nSize; ++nCur) - { - if (pBuffer[nCur] == '\n') - { - int nEnd = nCur - 1; - if (nEnd > nStart) - { - std::string s(pBuffer + nStart, nEnd - nStart + 1); - strFonts.Add(s); - } - nStart = nCur + 1; - } - } - - delete[] pBuffer; - } - } - - bool bIsEqual = NSFile::CFileBinary::Exists(strFontsSelectionBin); - - if (!bIsEqual || bIsCheckSystemFonts) - { - CApplicationFonts oApplicationF; - CArray strFontsW_Cur = oApplicationF.GetSetupFontFiles(); - - if (strFonts.GetCount() != strFontsW_Cur.GetCount()) - bIsEqual = false; - - if (bIsEqual) - { - int nCount = strFonts.GetCount(); - for (int i = 0; i < nCount; ++i) - { - if (strFonts[i] != NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(strFontsW_Cur[i].c_str(), strFontsW_Cur[i].length())) - { - bIsEqual = false; - break; - } - } - } - - if (!bIsEqual) - { - if (NSFile::CFileBinary::Exists(strAllFontsJSPath)) - NSFile::CFileBinary::Remove(strAllFontsJSPath); - if (NSFile::CFileBinary::Exists(strFontsSelectionBin)) - NSFile::CFileBinary::Remove(strFontsSelectionBin); - - if (strFonts.GetCount() != 0) - NSFile::CFileBinary::Remove(strDirectory + L"/fonts.log"); - - NSFile::CFileBinary oFile; - oFile.CreateFileW(strDirectory + L"/fonts.log"); - int nCount = strFontsW_Cur.GetCount(); - for (int i = 0; i < nCount; ++i) - { - oFile.WriteStringUTF8(strFontsW_Cur[i]); - oFile.WriteFile((BYTE*)"\n", 1); - } - oFile.CloseFile(); - - oApplicationF.InitializeFromArrayFiles(strFontsW_Cur, 2); - NSCommon::SaveAllFontsJS(oApplicationF, strAllFontsJSPath, L"", strFontsSelectionBin); - } - } - } - - void CheckFileDir() - { - m_sFileDir = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_sTmpFolder, L"DE_"); - if (NSFile::CFileBinary::Exists(m_sFileDir)) - NSFile::CFileBinary::Remove(m_sFileDir); - - NSCommon::string_replace(m_sFileDir, L"\\", L"/"); - - std::wstring::size_type nPosPoint = m_sFileDir.rfind('.'); - if (nPosPoint != std::wstring::npos && nPosPoint > m_sTmpFolder.length()) - { - m_sFileDir = m_sFileDir.substr(0, nPosPoint); - } - - m_nFileType = -1; - - NSDirectory::CreateDirectory(m_sFileDir); - } - - bool CreateFile(int type) - { -#if 1 - CheckFileDir(); - - std::wstring sEmptyPath = NSFile::GetProcessDirectory() + L"/empty/"; - if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) - { - sEmptyPath = sEmptyPath + L"docx.bin"; - m_nFileType = 0; - } - else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) - { - sEmptyPath = sEmptyPath + L"pptx.bin"; - m_nFileType = 1; - } - else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) - { - sEmptyPath = sEmptyPath + L"xlsx.bin"; - m_nFileType = 2; - } - else - return false; - - bool bRet = NSFile::CFileBinary::Copy(sEmptyPath, m_sFileDir + L"/Editor.bin"); - if (bRet) - { - NSDirectory::CreateDirectory(m_sFileDir + L"/media"); - NSDirectory::CreateDirectory(m_sFileDir + L"/changes"); - } - - return bRet; -#else - std::wstring sPath = NSFile::GetProcessDirectory() + L"/empty/new."; - if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) - sPath += L"docx"; - else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) - sPath += L"pptx"; - else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) - sPath += L"xlsx"; - return this->OpenFile(sPath, L""); -#endif - } - - bool OpenFile(const std::wstring& path, const std::wstring& params) - { - LOGGER_SPEED_START - - CheckFileDir(); - NSDirectory::CreateDirectory(m_sFileDir + L"/changes"); - - std::wstring sFileCopy = m_sFileDir + L"/origin." + NSCommon::GetFileExtention(path); - NSFile::CFileBinary::Copy(path, sFileCopy); - - COfficeFileFormatChecker oChecker; - if (!oChecker.isOfficeFile(path)) - return false; - - if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_DOCUMENT) - m_nFileType = 0; - if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_PRESENTATION) - m_nFileType = 1; - if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_SPREADSHEET) - m_nFileType = 2; - - NSStringUtils::CStringBuilder oBuilder; - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(sFileCopy); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(m_sFileDir); - oBuilder.WriteString(L"/Editor.bin8192"); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(NSFile::GetProcessDirectory() + L"/sdkjs/common"); - oBuilder.WriteString(L""); - oBuilder.WriteString(L"./sdkjs/slide/themestrue"); - oBuilder.WriteString(params); - oBuilder.WriteString(L""); - - std::wstring sXmlConvert = oBuilder.GetData(); - - std::wstring sConverterExe = m_sX2tPath + L"/x2t"; - - int nReturnCode = 0; - - std::wstring sTempFileForParams = m_sFileDir + L"/params_from.xml"; - NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); - - #ifdef WIN32 - std::wstring sApp = L"x2t32 "; - - if (NSFile::CFileBinary::Exists(sConverterExe + L".exe")) - { - sApp = L"x2t "; - sConverterExe += L".exe"; - } - else - sConverterExe += L"32.exe"; - - STARTUPINFO sturtupinfo; - ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); - sturtupinfo.cb = sizeof(STARTUPINFO); - - sApp += (L"\"" + sTempFileForParams + L"\""); - wchar_t* pCommandLine = NULL; - if (true) - { - pCommandLine = new wchar_t[sApp.length() + 1]; - memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t)); - pCommandLine[sApp.length()] = (wchar_t)'\0'; - } - - PROCESS_INFORMATION processinfo; - ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION)); - BOOL bResult = CreateProcessW(sConverterExe.c_str(), pCommandLine, - NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo); - - ::WaitForSingleObject(processinfo.hProcess, INFINITE); - - RELEASEARRAYOBJECTS(pCommandLine); - - //get exit code - DWORD dwExitCode = 0; - if (GetExitCodeProcess(processinfo.hProcess, &dwExitCode)) - { - nReturnCode = (int)dwExitCode; - } - - CloseHandle(processinfo.hProcess); - CloseHandle(processinfo.hThread); - - #endif - - #ifdef LINUX - pid_t pid = fork(); // create child process - int status; - - std::string sProgramm = U_TO_UTF8(sConverterExe); - std::string sXmlA = U_TO_UTF8(sTempFileForParams); - - switch (pid) - { - case -1: // error - break; - - case 0: // child process - { - std::string sLibraryDir = sProgramm; - std::string sPATH = sProgramm; - if (std::string::npos != sProgramm.find_last_of('/')) - { - sLibraryDir = "LD_LIBRARY_PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); - sPATH = "PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); - } - - #ifdef _MAC - sLibraryDir = "DY" + sLibraryDir; - #endif - - const char* nargs[3]; - nargs[0] = sProgramm.c_str(); - nargs[1] = sXmlA.c_str(); - nargs[2] = NULL; - - #ifndef _MAC - const char* nenv[2]; - nenv[0] = sLibraryDir.c_str(); - nenv[1] = NULL; - #else - const char* nenv[3]; - nenv[0] = sLibraryDir.c_str(); - nenv[1] = sPATH.c_str(); - nenv[2] = NULL; - #endif - - execve(sProgramm.c_str(), - (char * const *)nargs, - (char * const *)nenv); - exit(EXIT_SUCCESS); - break; - } - default: // parent process, pid now contains the child pid - while (-1 == waitpid(pid, &status, 0)); // wait for child to complete - if (WIFEXITED(status)) - { - nReturnCode = WEXITSTATUS(status); - } - break; - } - #endif - - NSFile::CFileBinary::Remove(sTempFileForParams); - - LOGGER_SPEED_LAP("open_convert") - - if (0 == nReturnCode) - return true; - - NSDirectory::DeleteDirectory(m_sFileDir); - m_sFileDir = L""; - m_nFileType = -1; - - CV8RealTimeWorker::_LOGGING_ERROR_(L"error: ", L"open file error"); - return false; - } - - void CloseFile() - { - if (NSDirectory::Exists(m_sFileDir)) - NSDirectory::DeleteDirectory(m_sFileDir); - - m_sFileDir = L""; - m_nFileType = -1; - - RELEASEOBJECT(m_pWorker); - } - - bool SaveFile(const int& type, const std::wstring& path) - { - if (-1 == m_nFileType) - { - CV8RealTimeWorker::_LOGGING_ERROR_(L"error (save)", L"file not opened!"); - return false; - } - - LOGGER_SPEED_START - - std::wstring sFileBin = L"/Editor.bin"; - - if (!m_bIsSaveWithDoctrendererMode && m_pWorker) - { - this->m_pWorker->SaveFileWithChanges(type, m_sFileDir + L"/Editor2.bin"); - sFileBin = L"/Editor2.bin"; - } - - NSStringUtils::CStringBuilder oBuilder; - - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(m_sFileDir); - oBuilder.WriteString(sFileBin + L""); - oBuilder.WriteEncodeXmlString(path); - oBuilder.WriteString(L""); - oBuilder.WriteString(std::to_wstring(type)); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(L"./sdkjs/slide/themes"); - if (!m_bIsSaveWithDoctrendererMode) - oBuilder.WriteString(L"true"); - else - oBuilder.WriteString(L"truetrue"); - oBuilder.WriteString(L"464"); - oBuilder.WriteString(L""); - oBuilder.WriteEncodeXmlString(NSFile::GetProcessDirectory() + L"/sdkjs/common"); - oBuilder.WriteString(L""); - - int nDoctRendererParam = 0; - //if (true) // печать пдф (лист = страница) - // nDoctRendererParam |= 0x02; - - oBuilder.WriteString(L""); - oBuilder.WriteString(std::to_wstring(nDoctRendererParam)); - oBuilder.WriteString(L""); - - oBuilder.WriteString(L""); - - std::wstring sXmlConvert = oBuilder.GetData(); - - std::wstring sConverterExe = m_sX2tPath + L"/x2t"; - - int nReturnCode = 0; - - std::wstring sTempFileForParams = m_sFileDir + L"/params_to.xml"; - NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); - - #ifdef WIN32 - std::wstring sApp = L"x2t32 "; - - if (NSFile::CFileBinary::Exists(sConverterExe + L".exe")) - { - sApp = L"x2t "; - sConverterExe += L".exe"; - } - else - sConverterExe += L"32.exe"; - - STARTUPINFO sturtupinfo; - ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); - sturtupinfo.cb = sizeof(STARTUPINFO); - - sApp += (L"\"" + sTempFileForParams + L"\""); - wchar_t* pCommandLine = NULL; - if (true) - { - pCommandLine = new wchar_t[sApp.length() + 1]; - memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t)); - pCommandLine[sApp.length()] = (wchar_t)'\0'; - } - - PROCESS_INFORMATION processinfo; - ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION)); - BOOL bResult = CreateProcessW(sConverterExe.c_str(), pCommandLine, - NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo); - - ::WaitForSingleObject(processinfo.hProcess, INFINITE); - - RELEASEARRAYOBJECTS(pCommandLine); - - //get exit code - DWORD dwExitCode = 0; - if (GetExitCodeProcess(processinfo.hProcess, &dwExitCode)) - { - nReturnCode = (int)dwExitCode; - } - - CloseHandle(processinfo.hProcess); - CloseHandle(processinfo.hThread); - - #endif - - #ifdef LINUX - pid_t pid = fork(); // create child process - int status; - - std::string sProgramm = U_TO_UTF8(sConverterExe); - std::string sXmlA = U_TO_UTF8(sTempFileForParams); - - switch (pid) - { - case -1: // error - break; - - case 0: // child process - { - std::string sLibraryDir = sProgramm; - std::string sPATH = sProgramm; - if (std::string::npos != sProgramm.find_last_of('/')) - { - sLibraryDir = "LD_LIBRARY_PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); - sPATH = "PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); - } - - #ifdef _MAC - sLibraryDir = "DY" + sLibraryDir; - #endif - - const char* nargs[3]; - nargs[0] = sProgramm.c_str(); - nargs[1] = sXmlA.c_str(); - nargs[2] = NULL; - - #ifndef _MAC - const char* nenv[2]; - nenv[0] = sLibraryDir.c_str(); - nenv[1] = NULL; - #else - const char* nenv[3]; - nenv[0] = sLibraryDir.c_str(); - nenv[1] = sPATH.c_str(); - nenv[2] = NULL; - #endif - - execve(sProgramm.c_str(), - (char * const *)nargs, - (char * const *)nenv); - exit(EXIT_SUCCESS); - break; - } - default: // parent process, pid now contains the child pid - while (-1 == waitpid(pid, &status, 0)); // wait for child to complete - if (WIFEXITED(status)) - { - nReturnCode = WEXITSTATUS(status); - } - break; - } - #endif - - NSFile::CFileBinary::Remove(sTempFileForParams); - - LOGGER_SPEED_LAP("save_convert") - - if (0 == nReturnCode) - return true; - - CV8RealTimeWorker::_LOGGING_ERROR_(L"error: ", L"save file error"); - return false; - } - - bool ExecuteCommand(const std::wstring& command) - { - if (-1 == m_nFileType) - { - CV8RealTimeWorker::_LOGGING_ERROR_(L"error (command)", L"file not opened!"); - return false; - } - - if (NULL == m_pWorker) - { - m_pWorker = new CV8RealTimeWorker(); - m_pWorker->m_nFileType = m_nFileType; - - bool bOpen = m_pWorker->OpenFile(m_sFileDir, GetScript()); - if (!bOpen) - return false; - } - - return m_pWorker->ExecuteCommand(command); - } - - std::string GetScript() - { - std::vector* arSdkFiles = NULL; - - std::wstring sResourceFile; - switch (m_nFileType) - { - case 0: - { - arSdkFiles = &m_arDoctSDK; - break; - } - case 1: - { - arSdkFiles = &m_arPpttSDK; - break; - } - case 2: - { - arSdkFiles = &m_arXlstSDK; - break; - } - default: - return ""; - } - - std::string strScript = ""; - for (size_t i = 0; i < m_arrFiles.GetCount(); ++i) - { - strScript += ReadScriptFile(m_arrFiles[i]); - strScript += "\n\n"; - } - - if (NULL != arSdkFiles) - { - for (std::vector::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++) - { - strScript += ReadScriptFile(*i); - strScript += "\n\n"; - } - } - - if (m_nFileType == 2) - strScript += "\n$.ready();"; - - return strScript; - } - - std::string ReadScriptFile(const std::wstring& strFile) - { - NSFile::CFileBinary oFile; - - if (!oFile.OpenFile(strFile)) - return ""; - - int nSize = (int)oFile.GetFileSize(); - if (nSize < 3) - return ""; - - BYTE* pData = new BYTE[nSize]; - DWORD dwReadSize = 0; - oFile.ReadFile(pData, (DWORD)nSize, dwReadSize); - - int nOffset = 0; - if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF) - { - nOffset = 3; - } - - std::string sReturn((char*)(pData + nOffset), nSize - nOffset); - - RELEASEARRAYOBJECTS(pData); - return sReturn; - } - }; -} - -namespace NSDoctRenderer -{ - void ParceParameters(const std::string& command, std::wstring* params) - { - const char* _commandsPtr = command.c_str(); - size_t _commandsLen = command.length(); - size_t _currentPos = 0; - - int nIndex = 0; - - while (true) - { - while (_currentPos < _commandsLen && !(_commandsPtr[_currentPos] == '\"' && _commandsPtr[_currentPos - 1] != '\\')) - ++_currentPos; - - ++_currentPos; - size_t _start = _currentPos; - - while (_currentPos < _commandsLen && !(_commandsPtr[_currentPos] == '\"' && _commandsPtr[_currentPos - 1] != '\\')) - ++_currentPos; - - if (_currentPos > _start) - { - if (_currentPos == (_start + 1)) - params[nIndex++] = L""; - else - params[nIndex++] = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)(_commandsPtr + _start), (LONG)(_currentPos - _start)); - } - - ++_currentPos; - - if (_currentPos >= _commandsLen) - break; - } - } - - CDocBuilder::CDocBuilder(bool bIsCheckSystemFonts) - { - m_pInternal = new CDocBuilder_Private(bIsCheckSystemFonts); + m_pInternal = new CDocBuilder_Private(); } CDocBuilder::~CDocBuilder() { @@ -1119,211 +17,14 @@ namespace NSDoctRenderer if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder)) NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder); - return m_pInternal->OpenFile(path, params); - } - bool CDocBuilder::CreateFile(const int& type) - { - m_pInternal->m_nFileType = -1; - if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder)) - NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder); - - return m_pInternal->CreateFile(type); - } - void CDocBuilder::SetTmpFolder(const wchar_t* folder) - { - m_pInternal->m_sTmpFolder = std::wstring(folder); + return m_pInternal->OpenFile(path, params); } bool CDocBuilder::SaveFile(const int& type, const wchar_t* path) { return m_pInternal->SaveFile(type, path); } - void CDocBuilder::CloseFile() - { - m_pInternal->CloseFile(); - } - bool CDocBuilder::ExecuteCommand(const wchar_t* command) { return m_pInternal->ExecuteCommand(command); } - - bool CDocBuilder::Run(const wchar_t* path) - { - std::wstring sPath(path); - if (!NSFile::CFileBinary::Exists(sPath)) - sPath = NSFile::GetProcessDirectory() + L"/" + sPath; - - std::string sCommands; - bool bRet = NSFile::CFileBinary::ReadAllTextUtf8A(sPath, sCommands); - - if (!bRet) - { - CV8RealTimeWorker::_LOGGING_ERROR_(L"error", L"cannot read run file"); - return bRet; - } - - return this->RunTextA(sCommands.c_str()); - } - - bool CDocBuilder::RunTextW(const wchar_t* commands) - { - std::wstring sCommandsW(commands); - std::string sCommands = U_TO_UTF8(sCommandsW); - return this->RunTextA(sCommands.c_str()); - } - - bool CDocBuilder::RunTextA(const char* commands) - { - std::list _commands; - size_t _commandsLen = strlen(commands); - size_t _currentPos = 0; - - while (true) - { - while (_currentPos < _commandsLen && (commands[_currentPos] == 0x0d || commands[_currentPos] == 0x0a)) - ++_currentPos; - - size_t _start = _currentPos; - - while (_currentPos < _commandsLen && (commands[_currentPos] != 0x0d && commands[_currentPos] != 0x0a)) - ++_currentPos; - - if (_currentPos > _start) - { - size_t _start2 = _start; - while (_start2 < _currentPos && (commands[_start2] == '\t' || commands[_start2] == ' ')) - ++_start2; - - if (_currentPos > _start2 && (commands[_start2] != '#' && commands[_start2] != '/')) - { - _commands.push_back(std::string(commands + _start2, _currentPos - _start2)); - // DEBUG - //std::cout << std::string(commands + _start2, _currentPos - _start2) << std::endl; - } - } - - if (_currentPos >= _commandsLen) - break; - } - - std::string sJsCommands = ""; - std::wstring _builder_params[4]; // с запасом - for (std::list::iterator i = _commands.begin(); i != _commands.end(); i++) - { - const std::string& command = *i; - const char* _data = command.c_str(); - size_t _len = command.length(); - - bool bIsBuilder = false; - if (_len > 8) - { - if (_data[0] == 'b' && - _data[1] == 'u' && - _data[2] == 'i' && - _data[3] == 'l' && - _data[4] == 'd' && - _data[5] == 'e' && - _data[6] == 'r' && - _data[7] == '.') - bIsBuilder = true; - } - - bool bIsNoError = true; - if (bIsBuilder) - { - if (!sJsCommands.empty()) - { - bIsNoError = this->m_pInternal->ExecuteCommand(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sJsCommands.c_str(), (LONG)sJsCommands.length())); - sJsCommands = ""; - if (!bIsNoError) - return false; - } - - size_t _pos = 8; - while (_data[_pos] != '(') - ++_pos; - - std::string sFuncNum(_data + 8, _pos - 8); - ParceParameters(command, _builder_params); - - if ("OpenFile" == sFuncNum) - bIsNoError = this->OpenFile(_builder_params[0].c_str(), _builder_params[1].c_str()); - else if ("CreateFile" == sFuncNum) - { - if (L"docx" == _builder_params[0]) - bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); - else if (L"pptx" == _builder_params[0]) - bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX); - else if (L"xlsx" == _builder_params[0]) - bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); - } - else if ("SetTmpFolder" == sFuncNum) - this->SetTmpFolder(_builder_params[0].c_str()); - else if ("CloseFile" == sFuncNum) - this->CloseFile(); - else if ("SaveFile" == sFuncNum) - { - int nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; - - if (L"docx" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; - else if (L"doc" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC; - else if (L"odt" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; - else if (L"rtf" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF; - else if (L"txt" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT; - else if (L"pptx" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX; - else if (L"xlsx" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; - else if (L"xls" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS; - else if (L"ods" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; - else if (L"csv" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; - else if (L"pdf" == _builder_params[0]) - nFormat = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF; - - if (m_pInternal->m_bIsSaveWithDoctrendererMode) - { - // перед сохранением в такой схеме нужно скинуть изменения - this->ExecuteCommand(L"_api.asc_Save();"); - } - - this->SaveFile(nFormat, _builder_params[1].c_str()); - } - } - else - { - //bIsNoError = this->m_pInternal->ExecuteCommand(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)_data, (LONG)_len)); - sJsCommands += command; - } - - if (!bIsNoError) - return false; - } - - return true; - } - - void CDocBuilder::SetProperty(const char* param) - { - std::string sParam = std::string(param); - if (sParam == "--use-doctrenderer-scheme") - m_pInternal->m_bIsSaveWithDoctrendererMode = true; - } - - void CDocBuilder::Initialize() - { - CV8Worker::Initialize(); - } - - void CDocBuilder::Dispose() - { - CV8Worker::Dispose(); - } } diff --git a/DesktopEditor/doctrenderer/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h index 28d680f60c..c395b61ca8 100644 --- a/DesktopEditor/doctrenderer/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -9,7 +9,7 @@ namespace NSDoctRenderer class Q_DECL_EXPORT CDocBuilder { public: - CDocBuilder(bool bIsCheckSystemFonts); + CDocBuilder(); ~CDocBuilder(); public: @@ -25,7 +25,8 @@ namespace NSDoctRenderer bool RunTextW(const wchar_t* commands); bool RunTextA(const char* commands); - void SetProperty(const char* param); + void SetProperty(const char* param, const wchar_t* value); + void SetPropertyW(const wchar_t* param, const wchar_t* value); public: static void Initialize(); diff --git a/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.cpp b/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.cpp index 2826a7905c..7217764546 100644 --- a/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.cpp +++ b/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.cpp @@ -23,9 +23,9 @@ namespace docbuilder_net public: NSDoctRenderer::CDocBuilder* m_pBuilder; - CDocBuilder_Private(bool bIsCheckSystemFonts) + CDocBuilder_Private() { - m_pBuilder = new NSDoctRenderer::CDocBuilder(bIsCheckSystemFonts); + m_pBuilder = new NSDoctRenderer::CDocBuilder(); } ~CDocBuilder_Private() { @@ -34,9 +34,9 @@ namespace docbuilder_net }; - CDocBuilder::CDocBuilder(bool bIsCheckSystemFonts) + CDocBuilder::CDocBuilder() { - m_pInternal = gcnew CDocBuilder_Private(bIsCheckSystemFonts); + m_pInternal = gcnew CDocBuilder_Private(); } CDocBuilder::~CDocBuilder() { @@ -78,6 +78,11 @@ namespace docbuilder_net return m_pInternal->m_pBuilder->RunTextW(StringToStdString(text)); } + void CDocBuilder::SetProperty(String^ key, String^ value) + { + m_pInternal->m_pBuilder->SetPropertyW(StringToStdString(key), StringToStdString(value)); + } + void CDocBuilder::Initialize() { NSDoctRenderer::CDocBuilder::Initialize(); diff --git a/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.h b/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.h index cab3082eb1..d60a337af9 100644 --- a/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.h +++ b/DesktopEditor/doctrenderer/docbuilder.net/docbuilder.net.h @@ -10,7 +10,7 @@ namespace docbuilder_net public ref class CDocBuilder { public: - CDocBuilder(bool bIsCheckSystemFonts); + CDocBuilder(); ~CDocBuilder(); bool OpenFile(String^ path, String^ params); @@ -19,6 +19,7 @@ namespace docbuilder_net bool SaveFile(int type, String^ path); void CloseFile(); bool ExecuteCommand(String^ command); + void SetProperty(String^ key, String^ value); bool Run(String^ path); bool RunText(String^ text_commands); diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h new file mode 100644 index 0000000000..6803d1ad42 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -0,0 +1,1388 @@ +#ifndef DOC_BUILDER_PRIVATE +#define DOC_BUILDER_PRIVATE + +#include "docbuilder.h" +#include "doctrenderer.h" + +#include "../xml/include/xmlutils.h" +#include + +#define ASC_APPLICATION_FONTS_NO_THUMBNAILS +#include "../fontengine/application_generate_fonts.h" + +#include "../common/File.h" +#include "../common/Directory.h" + +#include "../../Common/OfficeFileFormats.h" +#include "../../Common/OfficeFileFormatChecker.h" + +#include "nativecontrol.h" +#include + +#ifdef LINUX +#include +#include +#include +#endif + +template +class CScopeWrapper +{ +private: + T m_handler; + +private: + CScopeWrapper(const CScopeWrapper&) {} + void operator=(const CScopeWrapper&) {} + +public: + + CScopeWrapper(v8::Isolate* isolate) : m_handler(isolate) {} +}; + +class CV8RealTimeWorker +{ +public: + v8::Isolate* m_isolate; + + v8::Isolate::Scope* m_isolate_scope; + v8::Locker* m_isolate_locker; + + CScopeWrapper* m_handle_scope; + v8::Local m_context; + + int m_nFileType; + +public: + + CV8RealTimeWorker() + { + m_nFileType = -1; + + m_isolate = CV8Worker::getInitializer()->CreateNew(); + + m_isolate_scope = new v8::Isolate::Scope(m_isolate); + m_isolate_locker = new v8::Locker(m_isolate); + m_handle_scope = new CScopeWrapper(m_isolate); + + v8::Handle global = v8::ObjectTemplate::New(); + global->Set(v8::String::NewFromUtf8(m_isolate, "CreateNativeEngine"), v8::FunctionTemplate::New(m_isolate, CreateNativeObjectBuilder)); + global->Set(v8::String::NewFromUtf8(m_isolate, "CreateNativeMemoryStream"), v8::FunctionTemplate::New(m_isolate, CreateNativeMemoryStream)); + + m_context = v8::Context::New(m_isolate, NULL, global); + } + ~CV8RealTimeWorker() + { + RELEASEOBJECT(m_handle_scope); + m_context.Clear(); + + RELEASEOBJECT(m_isolate_locker); + RELEASEOBJECT(m_isolate_scope); + + m_isolate->Dispose(); + m_isolate = NULL; + } + +public: + + static void _LOGGING_ERROR_(const std::wstring& strType, const std::wstring& strError) + { + std::string sT = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strType); + std::string sE = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strError); + + std::cerr << sT << ": " << sE << std::endl; + } + + bool ExecuteCommand(const std::wstring& command) + { + LOGGER_SPEED_START + + std::string commandA = U_TO_UTF8(command); + //commandA = "_api." + commandA; + + v8::Context::Scope context_scope(m_context); + + v8::TryCatch try_catch; + + v8::Local source = v8::String::NewFromUtf8(m_isolate, commandA.c_str()); + v8::Local script = v8::Script::Compile(source); + + LOGGER_SPEED_LAP("compile_command") + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"execute_compile_code", strCode); + _LOGGING_ERROR_(L"execute_compile", strException); + + return false; + } + else + { + script->Run(); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"execute_run_code", strCode); + _LOGGING_ERROR_(L"execute_run", strException); + + return false; + } + } + + LOGGER_SPEED_LAP("run_command") + + return true; + } + + bool OpenFile(const std::wstring& sBasePath, const std::wstring& path, const std::string& sString) + { + LOGGER_SPEED_START + + v8::Context::Scope context_scope(m_context); + + v8::TryCatch try_catch; + + v8::Local source = v8::String::NewFromUtf8(m_isolate, sString.c_str()); + v8::Local script = v8::Script::Compile(source); + + LOGGER_SPEED_LAP("compile") + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"sdk_compile_code", strCode); + _LOGGING_ERROR_(L"sdk_compile", strException); + + return false; + } + else + { + script->Run(); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"sdk_run_code", strCode); + _LOGGING_ERROR_(L"sdk_run", strException); + + return false; + } + } + LOGGER_SPEED_LAP("run") + + CNativeControl* pNative = NULL; + bool bIsBreak = false; + + v8::Local global_js = m_context->Global(); + v8::Handle args[1]; + args[0] = v8::Int32::New(m_isolate, 0); + + // GET_NATIVE_ENGINE + if (!bIsBreak) + { + v8::Handle js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine")); + v8::Local objNative; + if (js_func_get_native->IsFunction()) + { + v8::Handle func_get_native = v8::Handle::Cast(js_func_get_native); + v8::Local js_result2 = func_get_native->Call(global_js, 1, args); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"run_code", strCode); + _LOGGING_ERROR_(L"run", strException); + + bIsBreak = true; + } + else + { + objNative = js_result2->ToObject(); + v8::Handle field = v8::Handle::Cast(objNative->GetInternalField(0)); + + pNative = static_cast(field->Value()); + } + } + } + + if (pNative != NULL) + { + pNative->m_strFontsDirectory = sBasePath + L"/sdkjs/common"; + pNative->m_strImagesDirectory = path + L"/media"; + + pNative->CheckFonts(); + + if (0 == m_nFileType) + pNative->m_strEditorType = L"document"; + else if (1 == m_nFileType) + pNative->m_strEditorType = L"presentation"; + else + pNative->m_strEditorType = L"spreadsheet"; + + pNative->SetFilePath(path + L"/Editor.bin"); + + pNative->m_sChangesBuilderPath = path + L"/changes/changes0.json"; + + pNative->m_nMaxChangesNumber = -1; + } + + // OPEN + if (!bIsBreak) + { + v8::Handle js_func_open = global_js->Get(v8::String::NewFromUtf8(m_isolate, "NativeOpenFileData")); + if (js_func_open->IsFunction()) + { + v8::Handle func_open = v8::Handle::Cast(js_func_open); + + CChangesWorker oWorkerLoader; + int nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath()); + + v8::Handle args_open[2]; + args_open[0] = oWorkerLoader.GetDataFull(); + args_open[1] = v8::Integer::New(m_isolate, nVersion); + + func_open->Call(global_js, 2, args_open); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"open_code", strCode); + _LOGGING_ERROR_(L"open", strException); + + bIsBreak = true; + } + } + } + + if (!bIsBreak) + bIsBreak = !this->ExecuteCommand(L"_api.asc_nativeInitBuilder();"); + if (!bIsBreak) + bIsBreak = !this->ExecuteCommand(L"_api.asc_SetSilentMode(true);"); + + LOGGER_SPEED_LAP("open") + + return !bIsBreak; + } + + bool SaveFileWithChanges(int type, const std::wstring& _path) + { + NSDoctRenderer::DoctRendererFormat::FormatFile _formatDst = NSDoctRenderer::DoctRendererFormat::DOCT; + if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) + _formatDst = NSDoctRenderer::DoctRendererFormat::PPTT; + else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) + _formatDst = NSDoctRenderer::DoctRendererFormat::XLST; + else if (type & AVS_OFFICESTUDIO_FILE_CROSSPLATFORM) + _formatDst = NSDoctRenderer::DoctRendererFormat::PDF; + + v8::Context::Scope context_scope(m_context); + v8::TryCatch try_catch; + + CNativeControl* pNative = NULL; + + v8::Local global_js = m_context->Global(); + v8::Handle args[1]; + args[0] = v8::Int32::New(m_isolate, 0); + + // GET_NATIVE_ENGINE + if (true) + { + v8::Handle js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine")); + v8::Local objNative; + if (js_func_get_native->IsFunction()) + { + v8::Handle func_get_native = v8::Handle::Cast(js_func_get_native); + v8::Local js_result2 = func_get_native->Call(global_js, 1, args); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"run_code", strCode); + _LOGGING_ERROR_(L"run", strException); + } + else + { + objNative = js_result2->ToObject(); + v8::Handle field = v8::Handle::Cast(objNative->GetInternalField(0)); + + pNative = static_cast(field->Value()); + } + } + } + + if (pNative == NULL) + return false; + + if (_formatDst == NSDoctRenderer::DoctRendererFormat::PDF) + this->ExecuteCommand(L"_api.asc_SetSilentMode(false);"); + + std::wstring strError; + bool bIsError = Doct_renderer_SaveFile_ForBuilder(_formatDst, + _path, + pNative, + m_isolate, + global_js, + args, + try_catch, + strError); + + if (_formatDst == NSDoctRenderer::DoctRendererFormat::PDF) + this->ExecuteCommand(L"_api.asc_SetSilentMode(true);"); + + return bIsError; + } +}; + +#ifdef CreateFile +#undef CreateFile +#endif + +namespace NSDoctRenderer +{ + class CAdditionalData + { + public: + CAdditionalData() {} + virtual ~CAdditionalData() {} + virtual std::string getParam(const std::wstring& name) { return ""; } + }; + + class CDocBuilderParams + { + public: + CDocBuilderParams() + { + m_bCheckFonts = false; + m_sWorkDir = L""; + m_bSaveWithDoctrendererMode = false; + } + + public: + bool m_bCheckFonts; + std::wstring m_sWorkDir; + bool m_bSaveWithDoctrendererMode; + }; + + class CDocBuilder_Private + { + public: + CArray m_arrFiles; + + std::vector m_arDoctSDK; + std::vector m_arPpttSDK; + std::vector m_arXlstSDK; + + std::wstring m_strEditorType; + std::wstring m_strFilePath; + + std::wstring m_strAllFonts; + + std::wstring m_sTmpFolder; + std::wstring m_sFileDir; + int m_nFileType; + + std::wstring m_sX2tPath; + + CV8RealTimeWorker* m_pWorker; + + CAdditionalData* m_pAdditionalData; + + CDocBuilderParams m_oParams; + bool m_bIsInit; + public: + CDocBuilder_Private() + { + m_pWorker = NULL; + + m_nFileType = -1; + + m_sTmpFolder = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"DTB"); + + // под линуксом предыдущая функция создает файл!!! + if (NSFile::CFileBinary::Exists(m_sTmpFolder)) + NSFile::CFileBinary::Remove(m_sTmpFolder); + + m_pAdditionalData = NULL; + m_bIsInit = false; + } + + void Init() + { + if (m_bIsInit) + return; + + std::wstring sWorkDir = m_oParams.m_sWorkDir; + if (sWorkDir.empty() || !NSDirectory::Exists(sWorkDir)) + { + sWorkDir = NSFile::GetProcessDirectory(); + if (!m_oParams.m_sWorkDir.empty()) + { + std::wstring sCheck = sWorkDir; + if (0 != m_oParams.m_sWorkDir.find('/')) + sCheck += L"/"; + sCheck += m_oParams.m_sWorkDir; + if (NSDirectory::Exists(sCheck)) + sWorkDir = sCheck; + } + } + else + { + std::wstring sNatural = NSFile::GetProcessDirectory(); + if (0 != sWorkDir.find('/')) + sNatural += L"/"; + sNatural += sWorkDir; + if (NSDirectory::Exists(sNatural)) + sWorkDir = sNatural; + } + + m_sX2tPath = sWorkDir; + + std::wstring sConfigDir = sWorkDir + L"/"; + std::wstring sConfigPath = sConfigDir + L"DoctRenderer.config"; + + XmlUtils::CXmlNode oNode; + if (oNode.FromXmlFile(sConfigPath)) + { + XmlUtils::CXmlNodes oNodes; + if (oNode.GetNodes(L"file", oNodes)) + { + int nCount = oNodes.GetCount(); + XmlUtils::CXmlNode _node; + for (int i = 0; i < nCount; ++i) + { + oNodes.GetAt(i, _node); + std::wstring strFilePath = _node.GetText(); + + if (std::wstring::npos != strFilePath.find(L"AllFonts.js")) + { + m_strAllFonts = strFilePath; + + if (!NSFile::CFileBinary::Exists(m_strAllFonts) || NSFile::CFileBinary::Exists(sConfigDir + m_strAllFonts)) + m_strAllFonts = sConfigDir + m_strAllFonts; + } + + if (NSFile::CFileBinary::Exists(strFilePath) && !NSFile::CFileBinary::Exists(sConfigDir + strFilePath)) + m_arrFiles.Add(strFilePath); + else + m_arrFiles.Add(sConfigDir + strFilePath); + } + } + } + + XmlUtils::CXmlNode oNodeSdk = oNode.ReadNode(L"DoctSdk"); + if (oNodeSdk.IsValid()) + LoadSDK_scripts(oNodeSdk, m_arDoctSDK, sConfigDir); + + oNodeSdk = oNode.ReadNode(L"PpttSdk"); + if (oNodeSdk.IsValid()) + LoadSDK_scripts(oNodeSdk, m_arPpttSDK, sConfigDir); + + oNodeSdk = oNode.ReadNode(L"XlstSdk"); + if (oNodeSdk.IsValid()) + LoadSDK_scripts(oNodeSdk, m_arXlstSDK, sConfigDir); + + CheckFonts(m_oParams.m_bCheckFonts); + + m_bIsInit = true; + } + + ~CDocBuilder_Private() + { + CloseFile(); + + RELEASEOBJECT(m_pAdditionalData); + } + + void LoadSDK_scripts(XmlUtils::CXmlNode& oNode, std::vector& _files, const std::wstring& strConfigDir) + { + XmlUtils::CXmlNodes oNodes; + if (oNode.GetNodes(L"file", oNodes)) + { + int nCount = oNodes.GetCount(); + XmlUtils::CXmlNode _node; + for (int i = 0; i < nCount; ++i) + { + oNodes.GetAt(i, _node); + std::wstring strFilePath = _node.GetText(); + + if (NSFile::CFileBinary::Exists(strFilePath) && + !NSFile::CFileBinary::Exists(strConfigDir + strFilePath)) + _files.push_back(strFilePath); + else + _files.push_back(strConfigDir + strFilePath); + } + } + else + { + std::wstring strFilePath = oNode.GetText(); + + if (NSFile::CFileBinary::Exists(strFilePath) && + !NSFile::CFileBinary::Exists(strConfigDir + strFilePath)) + _files.push_back(strFilePath); + else + _files.push_back(strConfigDir + strFilePath); + } + } + + void CheckFonts(bool bIsCheckSystemFonts) + { + CArray strFonts; + std::wstring strDirectory = NSCommon::GetDirectoryName(m_strAllFonts); + + std::wstring strAllFontsJSPath = strDirectory + L"/AllFonts.js"; + std::wstring strFontsSelectionBin = strDirectory + L"/font_selection.bin"; + + if (true) + { + NSFile::CFileBinary oFile; + if (oFile.OpenFile(strDirectory + L"/fonts.log")) + { + int nSize = oFile.GetFileSize(); + char* pBuffer = new char[nSize]; + DWORD dwReaden = 0; + oFile.ReadFile((BYTE*)pBuffer, nSize, dwReaden); + oFile.CloseFile(); + + int nStart = 0; + int nCur = nStart; + for (; nCur < nSize; ++nCur) + { + if (pBuffer[nCur] == '\n') + { + int nEnd = nCur - 1; + if (nEnd > nStart) + { + std::string s(pBuffer + nStart, nEnd - nStart + 1); + strFonts.Add(s); + } + nStart = nCur + 1; + } + } + + delete[] pBuffer; + } + } + + bool bIsEqual = NSFile::CFileBinary::Exists(strFontsSelectionBin); + + if (!bIsEqual || bIsCheckSystemFonts) + { + CApplicationFonts oApplicationF; + CArray strFontsW_Cur = oApplicationF.GetSetupFontFiles(); + + if (strFonts.GetCount() != strFontsW_Cur.GetCount()) + bIsEqual = false; + + if (bIsEqual) + { + int nCount = strFonts.GetCount(); + for (int i = 0; i < nCount; ++i) + { + if (strFonts[i] != NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(strFontsW_Cur[i].c_str(), strFontsW_Cur[i].length())) + { + bIsEqual = false; + break; + } + } + } + + if (!bIsEqual) + { + if (NSFile::CFileBinary::Exists(strAllFontsJSPath)) + NSFile::CFileBinary::Remove(strAllFontsJSPath); + if (NSFile::CFileBinary::Exists(strFontsSelectionBin)) + NSFile::CFileBinary::Remove(strFontsSelectionBin); + + if (strFonts.GetCount() != 0) + NSFile::CFileBinary::Remove(strDirectory + L"/fonts.log"); + + NSFile::CFileBinary oFile; + oFile.CreateFileW(strDirectory + L"/fonts.log"); + int nCount = strFontsW_Cur.GetCount(); + for (int i = 0; i < nCount; ++i) + { + oFile.WriteStringUTF8(strFontsW_Cur[i]); + oFile.WriteFile((BYTE*)"\n", 1); + } + oFile.CloseFile(); + + oApplicationF.InitializeFromArrayFiles(strFontsW_Cur, 2); + NSCommon::SaveAllFontsJS(oApplicationF, strAllFontsJSPath, L"", strFontsSelectionBin); + } + } + } + + void CheckFileDir() + { + m_sFileDir = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_sTmpFolder, L"DE_"); + if (NSFile::CFileBinary::Exists(m_sFileDir)) + NSFile::CFileBinary::Remove(m_sFileDir); + + NSCommon::string_replace(m_sFileDir, L"\\", L"/"); + + std::wstring::size_type nPosPoint = m_sFileDir.rfind('.'); + if (nPosPoint != std::wstring::npos && nPosPoint > m_sTmpFolder.length()) + { + m_sFileDir = m_sFileDir.substr(0, nPosPoint); + } + + m_nFileType = -1; + + NSDirectory::CreateDirectory(m_sFileDir); + } + + bool CreateFile(int type) + { + Init(); +#if 1 + CheckFileDir(); + + std::wstring sEmptyPath = m_sX2tPath + L"/empty/"; + if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) + { + sEmptyPath = sEmptyPath + L"docx.bin"; + m_nFileType = 0; + } + else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) + { + sEmptyPath = sEmptyPath + L"pptx.bin"; + m_nFileType = 1; + } + else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) + { + sEmptyPath = sEmptyPath + L"xlsx.bin"; + m_nFileType = 2; + } + else + return false; + + bool bRet = NSFile::CFileBinary::Copy(sEmptyPath, m_sFileDir + L"/Editor.bin"); + if (bRet) + { + NSDirectory::CreateDirectory(m_sFileDir + L"/media"); + NSDirectory::CreateDirectory(m_sFileDir + L"/changes"); + } + + return bRet; +#else + std::wstring sPath = m_sX2tPath + L"/empty/new."; + if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) + sPath += L"docx"; + else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) + sPath += L"pptx"; + else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) + sPath += L"xlsx"; + return this->OpenFile(sPath, L""); +#endif + } + + bool OpenFile(const std::wstring& path, const std::wstring& params) + { + Init(); + + LOGGER_SPEED_START + + CheckFileDir(); + NSDirectory::CreateDirectory(m_sFileDir + L"/changes"); + + std::wstring sFileCopy = m_sFileDir + L"/origin." + NSCommon::GetFileExtention(path); + NSFile::CFileBinary::Copy(path, sFileCopy); + + COfficeFileFormatChecker oChecker; + if (!oChecker.isOfficeFile(path)) + return false; + + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_DOCUMENT) + m_nFileType = 0; + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_PRESENTATION) + m_nFileType = 1; + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_SPREADSHEET) + m_nFileType = 2; + + NSStringUtils::CStringBuilder oBuilder; + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(sFileCopy); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_sFileDir); + oBuilder.WriteString(L"/Editor.bin8192"); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common"); + oBuilder.WriteString(L""); + oBuilder.WriteString(L"./sdkjs/slide/themestrue"); + oBuilder.WriteString(params); + oBuilder.WriteString(L""); + + std::wstring sXmlConvert = oBuilder.GetData(); + + std::wstring sConverterExe = m_sX2tPath + L"/x2t"; + + int nReturnCode = 0; + + std::wstring sTempFileForParams = m_sFileDir + L"/params_from.xml"; + NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); + + #ifdef WIN32 + std::wstring sApp = L"x2t32 "; + + if (NSFile::CFileBinary::Exists(sConverterExe + L".exe")) + { + sApp = L"x2t "; + sConverterExe += L".exe"; + } + else + sConverterExe += L"32.exe"; + + STARTUPINFO sturtupinfo; + ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); + sturtupinfo.cb = sizeof(STARTUPINFO); + + sApp += (L"\"" + sTempFileForParams + L"\""); + wchar_t* pCommandLine = NULL; + if (true) + { + pCommandLine = new wchar_t[sApp.length() + 1]; + memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t)); + pCommandLine[sApp.length()] = (wchar_t)'\0'; + } + + PROCESS_INFORMATION processinfo; + ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION)); + BOOL bResult = CreateProcessW(sConverterExe.c_str(), pCommandLine, + NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo); + + ::WaitForSingleObject(processinfo.hProcess, INFINITE); + + RELEASEARRAYOBJECTS(pCommandLine); + + //get exit code + DWORD dwExitCode = 0; + if (GetExitCodeProcess(processinfo.hProcess, &dwExitCode)) + { + nReturnCode = (int)dwExitCode; + } + + CloseHandle(processinfo.hProcess); + CloseHandle(processinfo.hThread); + + #endif + + #ifdef LINUX + pid_t pid = fork(); // create child process + int status; + + std::string sProgramm = U_TO_UTF8(sConverterExe); + std::string sXmlA = U_TO_UTF8(sTempFileForParams); + + switch (pid) + { + case -1: // error + break; + + case 0: // child process + { + std::string sLibraryDir = sProgramm; + std::string sPATH = sProgramm; + if (std::string::npos != sProgramm.find_last_of('/')) + { + sLibraryDir = "LD_LIBRARY_PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); + sPATH = "PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); + } + + #ifdef _MAC + sLibraryDir = "DY" + sLibraryDir; + #endif + + const char* nargs[3]; + nargs[0] = sProgramm.c_str(); + nargs[1] = sXmlA.c_str(); + nargs[2] = NULL; + + #ifndef _MAC + const char* nenv[2]; + nenv[0] = sLibraryDir.c_str(); + nenv[1] = NULL; + #else + const char* nenv[3]; + nenv[0] = sLibraryDir.c_str(); + nenv[1] = sPATH.c_str(); + nenv[2] = NULL; + #endif + + execve(sProgramm.c_str(), + (char * const *)nargs, + (char * const *)nenv); + exit(EXIT_SUCCESS); + break; + } + default: // parent process, pid now contains the child pid + while (-1 == waitpid(pid, &status, 0)); // wait for child to complete + if (WIFEXITED(status)) + { + nReturnCode = WEXITSTATUS(status); + } + break; + } + #endif + + NSFile::CFileBinary::Remove(sTempFileForParams); + + LOGGER_SPEED_LAP("open_convert") + + if (0 == nReturnCode) + return true; + + NSDirectory::DeleteDirectory(m_sFileDir); + m_sFileDir = L""; + m_nFileType = -1; + + CV8RealTimeWorker::_LOGGING_ERROR_(L"error: ", L"open file error"); + return false; + } + + void CloseFile() + { + Init(); + + if (NSDirectory::Exists(m_sFileDir)) + NSDirectory::DeleteDirectory(m_sFileDir); + + m_sFileDir = L""; + m_nFileType = -1; + + RELEASEOBJECT(m_pWorker); + } + + bool SaveFile(const int& type, const std::wstring& path) + { + Init(); + + if (-1 == m_nFileType) + { + CV8RealTimeWorker::_LOGGING_ERROR_(L"error (save)", L"file not opened!"); + return false; + } + + LOGGER_SPEED_START + + std::wstring sFileBin = L"/Editor.bin"; + + if (!m_oParams.m_bSaveWithDoctrendererMode && m_pWorker) + { + this->m_pWorker->SaveFileWithChanges(type, m_sFileDir + L"/Editor2.bin"); + sFileBin = L"/Editor2.bin"; + } + + NSStringUtils::CStringBuilder oBuilder; + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_sFileDir); + oBuilder.WriteString(sFileBin + L""); + oBuilder.WriteEncodeXmlString(path); + oBuilder.WriteString(L""); + oBuilder.WriteString(std::to_wstring(type)); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"./sdkjs/slide/themes"); + if (!m_oParams.m_bSaveWithDoctrendererMode) + oBuilder.WriteString(L"true"); + else + oBuilder.WriteString(L"truetrue"); + oBuilder.WriteString(L"464"); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common"); + oBuilder.WriteString(L""); + + int nDoctRendererParam = 0; + //if (true) // печать пдф (лист = страница) + // nDoctRendererParam |= 0x02; + + oBuilder.WriteString(L""); + oBuilder.WriteString(std::to_wstring(nDoctRendererParam)); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + std::wstring sXmlConvert = oBuilder.GetData(); + + std::wstring sConverterExe = m_sX2tPath + L"/x2t"; + + int nReturnCode = 0; + + std::wstring sTempFileForParams = m_sFileDir + L"/params_to.xml"; + NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); + + #ifdef WIN32 + std::wstring sApp = L"x2t32 "; + + if (NSFile::CFileBinary::Exists(sConverterExe + L".exe")) + { + sApp = L"x2t "; + sConverterExe += L".exe"; + } + else + sConverterExe += L"32.exe"; + + STARTUPINFO sturtupinfo; + ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); + sturtupinfo.cb = sizeof(STARTUPINFO); + + sApp += (L"\"" + sTempFileForParams + L"\""); + wchar_t* pCommandLine = NULL; + if (true) + { + pCommandLine = new wchar_t[sApp.length() + 1]; + memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t)); + pCommandLine[sApp.length()] = (wchar_t)'\0'; + } + + PROCESS_INFORMATION processinfo; + ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION)); + BOOL bResult = CreateProcessW(sConverterExe.c_str(), pCommandLine, + NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo); + + ::WaitForSingleObject(processinfo.hProcess, INFINITE); + + RELEASEARRAYOBJECTS(pCommandLine); + + //get exit code + DWORD dwExitCode = 0; + if (GetExitCodeProcess(processinfo.hProcess, &dwExitCode)) + { + nReturnCode = (int)dwExitCode; + } + + CloseHandle(processinfo.hProcess); + CloseHandle(processinfo.hThread); + + #endif + + #ifdef LINUX + pid_t pid = fork(); // create child process + int status; + + std::string sProgramm = U_TO_UTF8(sConverterExe); + std::string sXmlA = U_TO_UTF8(sTempFileForParams); + + switch (pid) + { + case -1: // error + break; + + case 0: // child process + { + std::string sLibraryDir = sProgramm; + std::string sPATH = sProgramm; + if (std::string::npos != sProgramm.find_last_of('/')) + { + sLibraryDir = "LD_LIBRARY_PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); + sPATH = "PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); + } + + #ifdef _MAC + sLibraryDir = "DY" + sLibraryDir; + #endif + + const char* nargs[3]; + nargs[0] = sProgramm.c_str(); + nargs[1] = sXmlA.c_str(); + nargs[2] = NULL; + + #ifndef _MAC + const char* nenv[2]; + nenv[0] = sLibraryDir.c_str(); + nenv[1] = NULL; + #else + const char* nenv[3]; + nenv[0] = sLibraryDir.c_str(); + nenv[1] = sPATH.c_str(); + nenv[2] = NULL; + #endif + + execve(sProgramm.c_str(), + (char * const *)nargs, + (char * const *)nenv); + exit(EXIT_SUCCESS); + break; + } + default: // parent process, pid now contains the child pid + while (-1 == waitpid(pid, &status, 0)); // wait for child to complete + if (WIFEXITED(status)) + { + nReturnCode = WEXITSTATUS(status); + } + break; + } + #endif + + NSFile::CFileBinary::Remove(sTempFileForParams); + + LOGGER_SPEED_LAP("save_convert") + + if (0 == nReturnCode) + return true; + + CV8RealTimeWorker::_LOGGING_ERROR_(L"error: ", L"save file error"); + return false; + } + + bool ExecuteCommand(const std::wstring& command) + { + Init(); + + if (-1 == m_nFileType) + { + CV8RealTimeWorker::_LOGGING_ERROR_(L"error (command)", L"file not opened!"); + return false; + } + + if (NULL == m_pWorker) + { + m_pWorker = new CV8RealTimeWorker(); + m_pWorker->m_nFileType = m_nFileType; + + bool bOpen = m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetScript()); + if (!bOpen) + return false; + } + + return m_pWorker->ExecuteCommand(command); + } + + std::string GetScript() + { + std::vector* arSdkFiles = NULL; + + std::wstring sResourceFile; + switch (m_nFileType) + { + case 0: + { + arSdkFiles = &m_arDoctSDK; + break; + } + case 1: + { + arSdkFiles = &m_arPpttSDK; + break; + } + case 2: + { + arSdkFiles = &m_arXlstSDK; + break; + } + default: + return ""; + } + + std::string strScript = ""; + for (size_t i = 0; i < m_arrFiles.GetCount(); ++i) + { + strScript += ReadScriptFile(m_arrFiles[i]); + strScript += "\n\n"; + } + + if (NULL != arSdkFiles) + { + for (std::vector::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++) + { + strScript += ReadScriptFile(*i); + strScript += "\n\n"; + } + } + + if (m_nFileType == 2) + strScript += "\n$.ready();"; + + return strScript; + } + + std::string ReadScriptFile(const std::wstring& strFile) + { + NSFile::CFileBinary oFile; + + if (!oFile.OpenFile(strFile)) + return ""; + + int nSize = (int)oFile.GetFileSize(); + if (nSize < 3) + return ""; + + BYTE* pData = new BYTE[nSize]; + DWORD dwReadSize = 0; + oFile.ReadFile(pData, (DWORD)nSize, dwReadSize); + + int nOffset = 0; + if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF) + { + nOffset = 3; + } + + std::string sReturn((char*)(pData + nOffset), nSize - nOffset); + + RELEASEARRAYOBJECTS(pData); + return sReturn; + } + }; +} + +namespace NSDoctRenderer +{ + void ParceParameters(const std::string& command, std::wstring* params) + { + const char* _commandsPtr = command.c_str(); + size_t _commandsLen = command.length(); + size_t _currentPos = 0; + + int nIndex = 0; + + while (true) + { + while (_currentPos < _commandsLen && !(_commandsPtr[_currentPos] == '\"' && _commandsPtr[_currentPos - 1] != '\\')) + ++_currentPos; + + ++_currentPos; + size_t _start = _currentPos; + + while (_currentPos < _commandsLen && !(_commandsPtr[_currentPos] == '\"' && _commandsPtr[_currentPos - 1] != '\\')) + ++_currentPos; + + if (_currentPos > _start) + { + if (_currentPos == (_start + 1)) + params[nIndex++] = L""; + else + params[nIndex++] = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)(_commandsPtr + _start), (LONG)(_currentPos - _start)); + } + + ++_currentPos; + + if (_currentPos >= _commandsLen) + break; + } + } + + bool CDocBuilder::CreateFile(const int& type) + { + m_pInternal->m_nFileType = -1; + if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder)) + NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder); + + return m_pInternal->CreateFile(type); + } + void CDocBuilder::SetTmpFolder(const wchar_t* folder) + { + m_pInternal->m_sTmpFolder = std::wstring(folder); + } + void CDocBuilder::CloseFile() + { + m_pInternal->CloseFile(); + } + + bool CDocBuilder::Run(const wchar_t* path) + { + std::wstring sPath(path); + if (!NSFile::CFileBinary::Exists(sPath)) + sPath = NSFile::GetProcessDirectory() + L"/" + sPath; + + std::string sCommands; + bool bRet = NSFile::CFileBinary::ReadAllTextUtf8A(sPath, sCommands); + + if (!bRet) + { + CV8RealTimeWorker::_LOGGING_ERROR_(L"error", L"cannot read run file"); + return bRet; + } + + return this->RunTextA(sCommands.c_str()); + } + + bool CDocBuilder::RunTextW(const wchar_t* commands) + { + std::wstring sCommandsW(commands); + std::string sCommands = U_TO_UTF8(sCommandsW); + return this->RunTextA(sCommands.c_str()); + } + + bool CDocBuilder::RunTextA(const char* commands) + { + m_pInternal->Init(); + std::list _commands; + size_t _commandsLen = strlen(commands); + size_t _currentPos = 0; + + while (true) + { + while (_currentPos < _commandsLen && (commands[_currentPos] == 0x0d || commands[_currentPos] == 0x0a)) + ++_currentPos; + + size_t _start = _currentPos; + + while (_currentPos < _commandsLen && (commands[_currentPos] != 0x0d && commands[_currentPos] != 0x0a)) + ++_currentPos; + + if (_currentPos > _start) + { + size_t _start2 = _start; + while (_start2 < _currentPos && (commands[_start2] == '\t' || commands[_start2] == ' ')) + ++_start2; + + if (_currentPos > _start2 && (commands[_start2] != '#' && commands[_start2] != '/')) + { + _commands.push_back(std::string(commands + _start2, _currentPos - _start2)); + // DEBUG + //std::cout << std::string(commands + _start2, _currentPos - _start2) << std::endl; + } + } + + if (_currentPos >= _commandsLen) + break; + } + + std::string sJsCommands = ""; + std::wstring _builder_params[4]; // с запасом + for (std::list::iterator i = _commands.begin(); i != _commands.end(); i++) + { + const std::string& command = *i; + const char* _data = command.c_str(); + size_t _len = command.length(); + + bool bIsBuilder = false; + if (_len > 8) + { + if (_data[0] == 'b' && + _data[1] == 'u' && + _data[2] == 'i' && + _data[3] == 'l' && + _data[4] == 'd' && + _data[5] == 'e' && + _data[6] == 'r' && + _data[7] == '.') + bIsBuilder = true; + } + + bool bIsNoError = true; + if (bIsBuilder) + { + if (!sJsCommands.empty()) + { + std::wstring sUnicodeCommand = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sJsCommands.c_str(), (LONG)sJsCommands.length()); + bIsNoError = this->ExecuteCommand(sUnicodeCommand.c_str()); + sJsCommands = ""; + if (!bIsNoError) + return false; + } + + size_t _pos = 8; + while (_data[_pos] != '(') + ++_pos; + + std::string sFuncNum(_data + 8, _pos - 8); + ParceParameters(command, _builder_params); + + if ("OpenFile" == sFuncNum) + bIsNoError = this->OpenFile(_builder_params[0].c_str(), _builder_params[1].c_str()); + else if ("CreateFile" == sFuncNum) + { + if (L"docx" == _builder_params[0]) + bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); + else if (L"pptx" == _builder_params[0]) + bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX); + else if (L"xlsx" == _builder_params[0]) + bIsNoError = this->CreateFile(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); + } + else if ("SetTmpFolder" == sFuncNum) + this->SetTmpFolder(_builder_params[0].c_str()); + else if ("CloseFile" == sFuncNum) + this->CloseFile(); + else if ("SaveFile" == sFuncNum) + { + int nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; + + if (L"docx" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX; + else if (L"doc" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC; + else if (L"odt" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT; + else if (L"rtf" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF; + else if (L"txt" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT; + else if (L"pptx" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX; + else if (L"xlsx" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; + else if (L"xls" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS; + else if (L"ods" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS; + else if (L"csv" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV; + else if (L"pdf" == _builder_params[0]) + nFormat = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF; + + if (m_pInternal->m_oParams.m_bSaveWithDoctrendererMode) + { + // перед сохранением в такой схеме нужно скинуть изменения + this->ExecuteCommand(L"_api.asc_Save();"); + } + + this->SaveFile(nFormat, _builder_params[1].c_str()); + } + } + else + { + //bIsNoError = this->m_pInternal->ExecuteCommand(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)_data, (LONG)_len)); + sJsCommands += command; + } + + if (!bIsNoError) + return false; + } + + return true; + } + + void CDocBuilder::SetProperty(const char* param, const wchar_t* value) + { + std::string sParam = std::string(param); + if (sParam == "--use-doctrenderer-scheme") + m_pInternal->m_oParams.m_bSaveWithDoctrendererMode = true; + else if (sParam == "--check-fonts") + m_pInternal->m_oParams.m_bCheckFonts = true; + else if (sParam == "--work-directory") + m_pInternal->m_oParams.m_sWorkDir = std::wstring(value); + } + void CDocBuilder::SetPropertyW(const wchar_t* param, const wchar_t* value) + { + std::wstring sW(param); + std::string sA = U_TO_UTF8(sW); + return this->SetProperty(sA.c_str(), value); + } + + void CDocBuilder::Initialize() + { + CV8Worker::Initialize(); + } + + void CDocBuilder::Dispose() + { + CV8Worker::Dispose(); + } +} + +#endif // DOC_BUILDER_PRIVATE diff --git a/DesktopEditor/doctrenderer/doctrenderer.pro b/DesktopEditor/doctrenderer/doctrenderer.pro index 01f530f0a8..9880f16c73 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.pro +++ b/DesktopEditor/doctrenderer/doctrenderer.pro @@ -185,6 +185,7 @@ SOURCES += \ HEADERS += doctrenderer.h \ docbuilder.h \ + docbuilder_p.h \ memorystream.h \ nativecontrol.h diff --git a/DesktopEditor/doctrenderer/test_builder/docbuilder.pro b/DesktopEditor/doctrenderer/test_builder/docbuilder.pro index 2e8e0f31e2..73f4e35b97 100644 --- a/DesktopEditor/doctrenderer/test_builder/docbuilder.pro +++ b/DesktopEditor/doctrenderer/test_builder/docbuilder.pro @@ -77,7 +77,7 @@ TARGET = docbuilder$$TARGET_PLATFORM ################################################ -LIBS += -L$$DESTINATION_SDK_PATH_DOCTRENDERER -ldoctrenderer +LIBS += -L$$DESTINATION_SDK_PATH_DOCTRENDERER/docbuilder -ldoctrenderer linux-g++ { LIBS += -ldl diff --git a/DesktopEditor/doctrenderer/test_builder/main.cpp b/DesktopEditor/doctrenderer/test_builder/main.cpp index aaceaeb53e..ab94bacfc7 100644 --- a/DesktopEditor/doctrenderer/test_builder/main.cpp +++ b/DesktopEditor/doctrenderer/test_builder/main.cpp @@ -55,7 +55,10 @@ int main(int argc, char *argv[]) if (true) { - NSDoctRenderer::CDocBuilder oBuilder(true); + NSDoctRenderer::CDocBuilder oBuilder; + oBuilder.SetProperty("--check-fonts", L""); + //oBuilder.SetProperty("--use-doctrenderer-scheme", L""); + //oBuilder.SetProperty("--work-directory", L"builder"); for (int i = 0; i < (argc - 1); ++i) { @@ -65,7 +68,7 @@ int main(int argc, char *argv[]) #else std::string sParam(argv[i]); #endif - oBuilder.SetProperty(sParam.c_str()); + oBuilder.SetProperty(sParam.c_str(), L""); } oBuilder.Run(sBuildFile.c_str());