mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
1794 lines
61 KiB
C++
1794 lines
61 KiB
C++
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2018
|
||
*
|
||
* This program is a free software product. You can redistribute it and/or
|
||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||
* version 3 as published by the Free Software Foundation. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
|
||
* EU, LV-1021.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
#ifndef DOC_BUILDER_PRIVATE
|
||
#define DOC_BUILDER_PRIVATE
|
||
|
||
#include "docbuilder.h"
|
||
#include "doctrenderer.h"
|
||
|
||
#include "../xml/include/xmlutils.h"
|
||
#include <iostream>
|
||
|
||
#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 <list>
|
||
|
||
#ifdef LINUX
|
||
#include <unistd.h>
|
||
#include <sys/wait.h>
|
||
#include <stdio.h>
|
||
#endif
|
||
|
||
#ifdef BUIDLER_OPEN_DOWNLOAD_ENABLED
|
||
#include "../../Common/FileDownloader/FileDownloader.h"
|
||
#endif
|
||
|
||
template <typename T>
|
||
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<v8::HandleScope>* m_handle_scope;
|
||
v8::Local<v8::Context> m_context;
|
||
|
||
int m_nFileType;
|
||
std::string m_sUtf8ArgumentJSON;
|
||
|
||
std::string m_sGlobalVariable;
|
||
|
||
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<v8::HandleScope>(m_isolate);
|
||
|
||
v8::Handle<v8::ObjectTemplate> 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<v8::String> source = v8::String::NewFromUtf8(m_isolate, commandA.c_str());
|
||
v8::Local<v8::Script> 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;
|
||
}
|
||
|
||
std::string GetGlobalVariable()
|
||
{
|
||
std::string commandA = "JSON.stringify(GlobalVariable);";
|
||
|
||
v8::Context::Scope context_scope(m_context);
|
||
|
||
v8::TryCatch try_catch;
|
||
|
||
v8::Local<v8::String> source = v8::String::NewFromUtf8(m_isolate, commandA.c_str());
|
||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||
|
||
std::string sReturn = "{}";
|
||
|
||
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 "";
|
||
}
|
||
else
|
||
{
|
||
v8::Local<v8::Value> _value = 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 "";
|
||
}
|
||
|
||
if (_value->IsString())
|
||
sReturn = to_cstringA(_value);
|
||
}
|
||
|
||
return sReturn;
|
||
}
|
||
|
||
bool OpenFile(const std::wstring& sBasePath, const std::wstring& path, const std::string& sString, const std::wstring& sCachePath)
|
||
{
|
||
LOGGER_SPEED_START
|
||
|
||
v8::Context::Scope context_scope(m_context);
|
||
|
||
v8::TryCatch try_catch;
|
||
|
||
v8::Local<v8::String> source = v8::String::NewFromUtf8(m_isolate, sString.c_str());
|
||
v8::Local<v8::Script> script;
|
||
|
||
CCacheDataScript oCachedScript(sCachePath);
|
||
if (sCachePath.empty())
|
||
script = v8::Script::Compile(source);
|
||
else
|
||
{
|
||
script = oCachedScript.Compile(m_context, 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")
|
||
|
||
if (true)
|
||
{
|
||
std::string sArg = m_sUtf8ArgumentJSON;
|
||
if (sArg.empty())
|
||
sArg = "{}";
|
||
NSCommon::string_replaceA(sArg, "\\", "\\\\");
|
||
NSCommon::string_replaceA(sArg, "\"", "\\\"");
|
||
std::string sArgument = "var Argument = JSON.parse(\"" + sArg + "\");";
|
||
|
||
v8::Local<v8::String> _sourceArg = v8::String::NewFromUtf8(m_isolate, sArgument.c_str());
|
||
v8::Local<v8::Script> _scriptArg = v8::Script::Compile(_sourceArg);
|
||
_scriptArg->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_argument_code", strCode);
|
||
_LOGGING_ERROR_(L"sdk_argument", strException);
|
||
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (true)
|
||
{
|
||
std::string sArg = m_sGlobalVariable;
|
||
if (sArg.empty())
|
||
sArg = "{}";
|
||
NSCommon::string_replaceA(sArg, "\\", "\\\\");
|
||
NSCommon::string_replaceA(sArg, "\"", "\\\"");
|
||
|
||
std::string sScriptVar = "var GlobalVariable = JSON.parse(\"" + sArg + "\");";
|
||
|
||
v8::Local<v8::String> _sourceArg = v8::String::NewFromUtf8(m_isolate, sScriptVar.c_str());
|
||
v8::Local<v8::Script> _scriptArg = v8::Script::Compile(_sourceArg);
|
||
_scriptArg->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_global_var_code", strCode);
|
||
_LOGGING_ERROR_(L"sdk_global_var", strException);
|
||
|
||
return false;
|
||
}
|
||
}
|
||
|
||
CNativeControl* pNative = NULL;
|
||
bool bIsBreak = false;
|
||
|
||
v8::Local<v8::Object> global_js = m_context->Global();
|
||
v8::Handle<v8::Value> args[1];
|
||
args[0] = v8::Int32::New(m_isolate, 0);
|
||
|
||
// GET_NATIVE_ENGINE
|
||
if (!bIsBreak)
|
||
{
|
||
v8::Handle<v8::Value> js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine"));
|
||
v8::Local<v8::Object> objNative;
|
||
if (js_func_get_native->IsFunction())
|
||
{
|
||
v8::Handle<v8::Function> func_get_native = v8::Handle<v8::Function>::Cast(js_func_get_native);
|
||
v8::Local<v8::Value> 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<v8::External> field = v8::Handle<v8::External>::Cast(objNative->GetInternalField(0));
|
||
|
||
pNative = static_cast<CNativeControl*>(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<v8::Value> js_func_open = global_js->Get(v8::String::NewFromUtf8(m_isolate, "NativeOpenFileData"));
|
||
if (js_func_open->IsFunction())
|
||
{
|
||
v8::Handle<v8::Function> func_open = v8::Handle<v8::Function>::Cast(js_func_open);
|
||
|
||
CChangesWorker oWorkerLoader;
|
||
int nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath());
|
||
|
||
v8::Handle<v8::Value> args_open[3];
|
||
args_open[0] = oWorkerLoader.GetDataFull();
|
||
args_open[1] = v8::Integer::New(m_isolate, nVersion);
|
||
|
||
std::wstring sXlsx = NSCommon::GetDirectoryName(pNative->GetFilePath()) + L"/Editor.xlsx";
|
||
if (NSFile::CFileBinary::Exists(sXlsx))
|
||
{
|
||
std::string sXlsxA = U_TO_UTF8(sXlsx);
|
||
args_open[2] = v8::String::NewFromUtf8(m_isolate, (char*)(sXlsxA.c_str()));
|
||
}
|
||
else
|
||
{
|
||
args_open[2] = v8::Undefined(m_isolate);
|
||
}
|
||
|
||
func_open->Call(global_js, 3, 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) || (type & AVS_OFFICESTUDIO_FILE_IMAGE))
|
||
_formatDst = NSDoctRenderer::DoctRendererFormat::PDF;
|
||
|
||
v8::Context::Scope context_scope(m_context);
|
||
v8::TryCatch try_catch;
|
||
|
||
CNativeControl* pNative = NULL;
|
||
|
||
v8::Local<v8::Object> global_js = m_context->Global();
|
||
v8::Handle<v8::Value> args[1];
|
||
args[0] = v8::Int32::New(m_isolate, 0);
|
||
|
||
// GET_NATIVE_ENGINE
|
||
if (true)
|
||
{
|
||
v8::Handle<v8::Value> js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine"));
|
||
v8::Local<v8::Object> objNative;
|
||
if (js_func_get_native->IsFunction())
|
||
{
|
||
v8::Handle<v8::Function> func_get_native = v8::Handle<v8::Function>::Cast(js_func_get_native);
|
||
v8::Local<v8::Value> 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<v8::External> field = v8::Handle<v8::External>::Cast(objNative->GetInternalField(0));
|
||
|
||
pNative = static_cast<CNativeControl*>(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;
|
||
m_sArgumentJSON = "";
|
||
}
|
||
|
||
public:
|
||
bool m_bCheckFonts;
|
||
std::wstring m_sWorkDir;
|
||
bool m_bSaveWithDoctrendererMode;
|
||
std::string m_sArgumentJSON;
|
||
};
|
||
|
||
class CDocBuilder_Private
|
||
{
|
||
public:
|
||
CArray<std::wstring> m_arrFiles;
|
||
|
||
std::vector<std::wstring> m_arDoctSDK;
|
||
std::vector<std::wstring> m_arPpttSDK;
|
||
std::vector<std::wstring> m_arXlstSDK;
|
||
|
||
std::wstring m_strEditorType;
|
||
std::wstring m_strFilePath;
|
||
|
||
std::wstring m_strAllFonts;
|
||
bool m_bIsNotUseConfigAllFontsDir;
|
||
|
||
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;
|
||
|
||
bool m_bIsCacheScript;
|
||
|
||
std::wstring m_sFolderForSaveOnlyUseNames;
|
||
|
||
std::string m_sGlobalVariable;
|
||
bool m_bIsGlobalVariableUse;
|
||
public:
|
||
CDocBuilder_Private()
|
||
{
|
||
m_pWorker = NULL;
|
||
|
||
m_nFileType = -1;
|
||
|
||
m_sTmpFolder = NSFile::CFileBinary::GetTempPath();
|
||
|
||
// под линуксом предыдущая функция создает файл!!!
|
||
if (NSFile::CFileBinary::Exists(m_sTmpFolder))
|
||
NSFile::CFileBinary::Remove(m_sTmpFolder);
|
||
|
||
m_pAdditionalData = NULL;
|
||
m_bIsInit = false;
|
||
m_bIsCacheScript = true;
|
||
|
||
m_sGlobalVariable = "";
|
||
m_bIsGlobalVariableUse = false;
|
||
|
||
m_bIsNotUseConfigAllFontsDir = 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"))
|
||
{
|
||
if (!m_bIsNotUseConfigAllFontsDir)
|
||
{
|
||
m_strAllFonts = strFilePath;
|
||
|
||
if (!NSFile::CFileBinary::Exists(m_strAllFonts) || NSFile::CFileBinary::Exists(sConfigDir + m_strAllFonts))
|
||
m_strAllFonts = sConfigDir + m_strAllFonts;
|
||
}
|
||
else
|
||
{
|
||
m_arrFiles.Add(m_strAllFonts);
|
||
continue;
|
||
}
|
||
}
|
||
|
||
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<std::wstring>& _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)
|
||
{
|
||
std::vector<std::string> 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.push_back(s);
|
||
}
|
||
nStart = nCur + 1;
|
||
}
|
||
}
|
||
|
||
delete[] pBuffer;
|
||
}
|
||
}
|
||
|
||
bool bIsEqual = NSFile::CFileBinary::Exists(strFontsSelectionBin);
|
||
|
||
if (!bIsEqual || bIsCheckSystemFonts)
|
||
{
|
||
NSFonts::IApplicationFonts* pApplicationF;
|
||
std::vector<std::wstring> strFontsW_Cur = pApplicationF->GetSetupFontFiles();
|
||
|
||
if (strFonts.size() != strFontsW_Cur.size())
|
||
bIsEqual = false;
|
||
|
||
if (bIsEqual)
|
||
{
|
||
int nCount = (int)strFonts.size();
|
||
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.size() != 0)
|
||
NSFile::CFileBinary::Remove(strDirectory + L"/fonts.log");
|
||
|
||
NSFile::CFileBinary oFile;
|
||
oFile.CreateFileW(strDirectory + L"/fonts.log");
|
||
int nCount = (int)strFontsW_Cur.size();
|
||
for (int i = 0; i < nCount; ++i)
|
||
{
|
||
oFile.WriteStringUTF8(strFontsW_Cur[i]);
|
||
oFile.WriteFile((BYTE*)"\n", 1);
|
||
}
|
||
oFile.CloseFile();
|
||
|
||
pApplicationF->InitializeFromArrayFiles(strFontsW_Cur, 2);
|
||
NSCommon::SaveAllFontsJS(pApplicationF, strAllFontsJSPath, L"", strFontsSelectionBin);
|
||
}
|
||
|
||
RELEASEOBJECT(pApplicationF);
|
||
}
|
||
}
|
||
|
||
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
|
||
}
|
||
|
||
void MoveFileOpen(const std::wstring& from, const std::wstring& to)
|
||
{
|
||
#ifdef BUIDLER_OPEN_DOWNLOAD_ENABLED
|
||
int n1 = (int)from.find (L"www");
|
||
int n2 = (int)from.find (L"http");
|
||
int n3 = (int)from.find (L"ftp");
|
||
int n4 = (int)from.find (L"https");
|
||
|
||
//если nI сранивать не с 0, то будут проблемы
|
||
//потому что в инсталяции мы кладем файлы в /var/www...
|
||
if (0 == n1 || 0 == n2 || 0 == n3 || 0 == n4)
|
||
{
|
||
CFileDownloader oDownloader(from, false);
|
||
oDownloader.SetFilePath(to);
|
||
if (oDownloader.DownloadSync())
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
#ifdef BUIDLER_OPEN_BASE64_ENABLED
|
||
if (0 == from.find(L"data:"))
|
||
{
|
||
std::wstring::size_type findBase64 = from.find(L"base64,");
|
||
if (std::wstring::npos != findBase64)
|
||
{
|
||
int nStartBase64 = (int)findBase64;
|
||
if (50 > nStartBase64)
|
||
{
|
||
nStartBase64 += 7;
|
||
const wchar_t* pStart = from.c_str() + nStartBase64;
|
||
int nDataLen = (int)from.length() - nStartBase64;
|
||
|
||
std::string sBase64 = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(pStart, (LONG)nDataLen, false);
|
||
|
||
BYTE* pDataDst = NULL;
|
||
int nDataDstLen = 0;
|
||
if (NSFile::CBase64Converter::Decode(sBase64.c_str(), (int)sBase64.length(), pDataDst, nDataLen))
|
||
{
|
||
NSFile::CFileBinary oFileDst;
|
||
if (oFileDst.CreateFileW(to))
|
||
{
|
||
oFileDst.WriteFile(pDataDst, (DWORD)nDataDstLen);
|
||
oFileDst.CloseFile();
|
||
|
||
RELEASEARRAYOBJECTS(pDataDst);
|
||
return;
|
||
}
|
||
|
||
RELEASEARRAYOBJECTS(pDataDst);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
NSFile::CFileBinary::Copy(from, to);
|
||
}
|
||
|
||
int 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);
|
||
MoveFileOpen(path, sFileCopy);
|
||
|
||
COfficeFileFormatChecker oChecker;
|
||
if (!oChecker.isOfficeFile(sFileCopy))
|
||
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"<?xml version=\"1.0\" encoding=\"utf-8\"?><TaskQueueDataConvert><m_sFileFrom>");
|
||
oBuilder.WriteEncodeXmlString(sFileCopy);
|
||
oBuilder.WriteString(L"</m_sFileFrom><m_sFileTo>");
|
||
oBuilder.WriteEncodeXmlString(m_sFileDir);
|
||
oBuilder.WriteString(L"/Editor.bin</m_sFileTo><m_nFormatTo>8192</m_nFormatTo>");
|
||
|
||
if (!m_bIsNotUseConfigAllFontsDir)
|
||
{
|
||
oBuilder.WriteString(L"<m_sFontDir>");
|
||
oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common");
|
||
oBuilder.WriteString(L"</m_sFontDir>");
|
||
}
|
||
else
|
||
{
|
||
oBuilder.WriteString(L"<m_sFontDir>");
|
||
oBuilder.WriteEncodeXmlString(NSCommon::GetDirectoryName(m_strAllFonts));
|
||
oBuilder.WriteString(L"</m_sFontDir>");
|
||
|
||
oBuilder.WriteString(L"<m_sAllFontsPath>");
|
||
oBuilder.WriteEncodeXmlString(m_strAllFonts);
|
||
oBuilder.WriteString(L"</m_sAllFontsPath>");
|
||
}
|
||
|
||
oBuilder.WriteString(L"<m_bIsNoBase64>true</m_bIsNoBase64>");
|
||
oBuilder.WriteString(L"<m_sThemeDir>./sdkjs/slide/themes</m_sThemeDir><m_bDontSaveAdditional>true</m_bDontSaveAdditional>");
|
||
oBuilder.WriteString(params);
|
||
oBuilder.WriteString(L"</TaskQueueDataConvert>");
|
||
|
||
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 0;
|
||
|
||
NSDirectory::DeleteDirectory(m_sFileDir);
|
||
m_sFileDir = L"";
|
||
m_nFileType = -1;
|
||
|
||
std::wstring sErrorLog = L"open file error (" + std::to_wstring(nReturnCode) + L")";
|
||
CV8RealTimeWorker::_LOGGING_ERROR_(L"error: ", sErrorLog);
|
||
return nReturnCode;
|
||
}
|
||
|
||
void CloseFile()
|
||
{
|
||
Init();
|
||
|
||
if (NSDirectory::Exists(m_sFileDir))
|
||
NSDirectory::DeleteDirectory(m_sFileDir);
|
||
|
||
m_sFileDir = L"";
|
||
m_nFileType = -1;
|
||
|
||
if (m_pWorker)
|
||
m_sGlobalVariable = m_pWorker->GetGlobalVariable();
|
||
RELEASEOBJECT(m_pWorker);
|
||
}
|
||
|
||
int SaveFile(const int& type, const std::wstring& path, const wchar_t* params = NULL)
|
||
{
|
||
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;
|
||
|
||
std::wstring _path = path;
|
||
if (!m_sFolderForSaveOnlyUseNames.empty())
|
||
{
|
||
_path = m_sFolderForSaveOnlyUseNames;
|
||
wchar_t last = m_sFolderForSaveOnlyUseNames.c_str()[m_sFolderForSaveOnlyUseNames.length() - 1];
|
||
if (last != '/' && last != '\\')
|
||
_path += L"/";
|
||
_path += NSCommon::GetFileName(path);
|
||
}
|
||
|
||
std::wstring sDstFileDir = NSCommon::GetDirectoryName(_path);
|
||
if ((sDstFileDir != _path) && !NSDirectory::Exists(sDstFileDir))
|
||
NSDirectory::CreateDirectories(sDstFileDir);
|
||
|
||
oBuilder.WriteString(L"<?xml version=\"1.0\" encoding=\"utf-8\"?><TaskQueueDataConvert><m_sFileFrom>");
|
||
oBuilder.WriteEncodeXmlString(m_sFileDir);
|
||
oBuilder.WriteString(sFileBin + L"</m_sFileFrom><m_sFileTo>");
|
||
oBuilder.WriteEncodeXmlString(_path);
|
||
oBuilder.WriteString(L"</m_sFileTo><m_nFormatTo>");
|
||
oBuilder.WriteString(std::to_wstring(type));
|
||
oBuilder.WriteString(L"</m_nFormatTo><m_sThemeDir>");
|
||
oBuilder.WriteEncodeXmlString(L"./sdkjs/slide/themes");
|
||
if (!m_oParams.m_bSaveWithDoctrendererMode)
|
||
oBuilder.WriteString(L"</m_sThemeDir><m_bDontSaveAdditional>true</m_bDontSaveAdditional>");
|
||
else
|
||
oBuilder.WriteString(L"</m_sThemeDir><m_bFromChanges>true</m_bFromChanges><m_bDontSaveAdditional>true</m_bDontSaveAdditional>");
|
||
oBuilder.WriteString(L"<m_nCsvTxtEncoding>46</m_nCsvTxtEncoding><m_nCsvDelimiter>4</m_nCsvDelimiter>");
|
||
|
||
if (!m_bIsNotUseConfigAllFontsDir)
|
||
{
|
||
oBuilder.WriteString(L"<m_sFontDir>");
|
||
oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common");
|
||
oBuilder.WriteString(L"</m_sFontDir>");
|
||
}
|
||
else
|
||
{
|
||
oBuilder.WriteString(L"<m_sFontDir>");
|
||
oBuilder.WriteEncodeXmlString(NSCommon::GetDirectoryName(m_strAllFonts));
|
||
oBuilder.WriteString(L"</m_sFontDir>");
|
||
|
||
oBuilder.WriteString(L"<m_sAllFontsPath>");
|
||
oBuilder.WriteEncodeXmlString(m_strAllFonts);
|
||
oBuilder.WriteString(L"</m_sAllFontsPath>");
|
||
}
|
||
|
||
int nDoctRendererParam = 0;
|
||
//if (true) // печать пдф (лист = страница)
|
||
// nDoctRendererParam |= 0x02;
|
||
|
||
oBuilder.WriteString(L"<m_nDoctParams>");
|
||
oBuilder.WriteString(std::to_wstring(nDoctRendererParam));
|
||
oBuilder.WriteString(L"</m_nDoctParams>");
|
||
|
||
if (NULL != params)
|
||
{
|
||
std::wstring sConvertionParams(params);
|
||
oBuilder.WriteString(sConvertionParams);
|
||
}
|
||
|
||
oBuilder.WriteString(L"</TaskQueueDataConvert>");
|
||
|
||
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 0;
|
||
|
||
std::wstring sErrorLog = L"save file error (" + std::to_wstring(nReturnCode) + L")";
|
||
CV8RealTimeWorker::_LOGGING_ERROR_(L"error: ", sErrorLog);
|
||
return nReturnCode;
|
||
}
|
||
|
||
bool ExecuteCommand(const std::wstring& command)
|
||
{
|
||
if (command.length() < 7) // minimum command (!!!)
|
||
return true;
|
||
|
||
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;
|
||
m_pWorker->m_sUtf8ArgumentJSON = m_oParams.m_sArgumentJSON;
|
||
m_pWorker->m_sGlobalVariable = m_sGlobalVariable;
|
||
|
||
std::wstring sCachePath = L"";
|
||
if (m_bIsCacheScript)
|
||
sCachePath = GetScriptCache();
|
||
|
||
bool bOpen = m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetScript(), sCachePath);
|
||
if (!bOpen)
|
||
return false;
|
||
}
|
||
|
||
return m_pWorker->ExecuteCommand(command);
|
||
}
|
||
|
||
std::string GetScript()
|
||
{
|
||
std::vector<std::wstring>* 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<std::wstring>::iterator i = arSdkFiles->begin(); i != arSdkFiles->end(); i++)
|
||
{
|
||
strScript += ReadScriptFile(*i);
|
||
strScript += "\n\n";
|
||
}
|
||
}
|
||
|
||
if (m_nFileType == 2)
|
||
strScript += "\n$.ready();";
|
||
|
||
return strScript;
|
||
}
|
||
|
||
std::wstring GetScriptCache()
|
||
{
|
||
std::vector<std::wstring>* arSdkFiles = NULL;
|
||
switch (m_nFileType)
|
||
{
|
||
case 0:
|
||
{
|
||
arSdkFiles = &m_arDoctSDK;
|
||
break;
|
||
}
|
||
case 1:
|
||
{
|
||
arSdkFiles = &m_arPpttSDK;
|
||
break;
|
||
}
|
||
case 2:
|
||
{
|
||
arSdkFiles = &m_arXlstSDK;
|
||
break;
|
||
}
|
||
default:
|
||
return L"";
|
||
}
|
||
|
||
if (0 < arSdkFiles->size())
|
||
{
|
||
return NSCommon::GetDirectoryName(*arSdkFiles->begin()) + L"/sdk-all.cache";
|
||
}
|
||
return L"";
|
||
}
|
||
|
||
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, int& nCount)
|
||
{
|
||
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;
|
||
}
|
||
|
||
nCount = nIndex;
|
||
}
|
||
|
||
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();
|
||
}
|
||
|
||
char* CDocBuilder::GetVersion()
|
||
{
|
||
m_pInternal->Init();
|
||
|
||
if (0 == m_pInternal->m_arDoctSDK.size())
|
||
return NULL;
|
||
|
||
std::wstring sFile;
|
||
for (std::vector<std::wstring>::iterator i = m_pInternal->m_arDoctSDK.begin(); i != m_pInternal->m_arDoctSDK.end(); i++)
|
||
{
|
||
if (std::wstring::npos != i->find(L"sdk-all-min.js"))
|
||
{
|
||
sFile = *i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (sFile.empty())
|
||
return NULL;
|
||
|
||
std::string sData;
|
||
if (!NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sData))
|
||
return NULL;
|
||
|
||
std::string::size_type startPos = sData.find("Version:");
|
||
if (std::string::npos == startPos)
|
||
return NULL;
|
||
|
||
startPos += 8;
|
||
|
||
std::string::size_type endPos = sData.find(')', startPos);
|
||
if (std::string::npos == endPos)
|
||
return NULL;
|
||
|
||
size_t sSrcLen = endPos - startPos + 1;
|
||
if (sSrcLen == 0)
|
||
return NULL;
|
||
|
||
char* sRet = new char[sSrcLen + 1];
|
||
memcpy(sRet, sData.c_str() + startPos, sSrcLen);
|
||
sRet[sSrcLen] = '\0';
|
||
return sRet;
|
||
}
|
||
|
||
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<std::string> _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<std::string>::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);
|
||
int nCountParameters = 0;
|
||
ParceParameters(command, _builder_params, nCountParameters);
|
||
|
||
if ("OpenFile" == sFuncNum)
|
||
bIsNoError = (0 == 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"odp" == _builder_params[0])
|
||
nFormat = AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP;
|
||
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;
|
||
else if (L"image" == _builder_params[0])
|
||
nFormat = AVS_OFFICESTUDIO_FILE_IMAGE;
|
||
else if (L"jpg" == _builder_params[0])
|
||
nFormat = AVS_OFFICESTUDIO_FILE_IMAGE;
|
||
else if (L"png" == _builder_params[0])
|
||
nFormat = AVS_OFFICESTUDIO_FILE_IMAGE;
|
||
|
||
if (m_pInternal->m_oParams.m_bSaveWithDoctrendererMode)
|
||
{
|
||
// перед сохранением в такой схеме нужно скинуть изменения
|
||
this->ExecuteCommand(L"_api.asc_Save();");
|
||
}
|
||
|
||
const wchar_t* sParams = NULL;
|
||
if (nCountParameters > 2)
|
||
sParams = _builder_params[2].c_str();
|
||
|
||
this->SaveFile(nFormat, _builder_params[1].c_str(), sParams);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//bIsNoError = this->m_pInternal->ExecuteCommand(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)_data, (LONG)_len));
|
||
sJsCommands += command;
|
||
sJsCommands += "\n";
|
||
}
|
||
|
||
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);
|
||
else if (sParam == "--cache-scripts")
|
||
m_pInternal->m_bIsCacheScript = (std::wstring(value) == L"true");
|
||
else if (sParam == "--save-use-only-names")
|
||
m_pInternal->m_sFolderForSaveOnlyUseNames = std::wstring(value);
|
||
else if (sParam == "--all-fonts-path")
|
||
{
|
||
m_pInternal->m_strAllFonts = std::wstring(value);
|
||
m_pInternal->m_bIsNotUseConfigAllFontsDir = true;
|
||
}
|
||
else if (sParam == "--argument")
|
||
{
|
||
std::wstring sArg(value);
|
||
m_pInternal->m_oParams.m_sArgumentJSON = U_TO_UTF8(sArg);
|
||
}
|
||
}
|
||
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
|