Merge branch hotfix/v9.0.4 into master

This commit is contained in:
papacarlo
2025-08-05 14:09:05 +00:00
18 changed files with 26871 additions and 24 deletions

View File

@ -126,6 +126,18 @@ SOURCES += \
$$CORE_ROOT_DIR/Common/3dParty/pole/pole.cpp \
$$CORE_ROOT_DIR/OOXML/Base/unicode_util.cpp
AI_TOOLS_PATH = $$PWD/tools
HEADERS += \
$$AI_TOOLS_PATH/tools.h
SOURCES += \
$$AI_TOOLS_PATH/tools.cpp
AI_TOOLS_FUNCS_PATH = $$/AI_TOOLS_PATH/functions
HEADERS += \
AI_TOOLS_FUNCS_PATH/internal/base.h \
AI_TOOLS_FUNCS_PATH/internal/funcs.h
# crypto ----------------------------------
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCompoundFileLib
@ -177,4 +189,4 @@ core_linux {
LIBS += -lX11 -lX11-xcb -lxkbcommon-x11 -lxkbcommon
}
ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network, PdfFile, XpsFile, DjVuFile, hunspell, ooxmlsignature)
ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network, PdfFile, XpsFile, DjVuFile, hunspell, ooxmlsignature, doctrenderer)

View File

@ -293,12 +293,14 @@ namespace NSRequest
CefRefPtr<CefRequest> m_request;
int m_requestId;
int_64_type m_frameId;
bool m_isProgress;
CCefView_Private* m_view;
public:
CSimpleRequestClient(CefRefPtr<CefListValue>& args)
{
m_isProgress = false;
m_request = CefRequest::Create();
m_frameId = NSArgumentList::GetInt64(args, 0);
m_requestId = args->GetInt(1);
@ -307,6 +309,18 @@ namespace NSRequest
std::string sMethod = args->GetString(3).ToString();
m_request->SetMethod(sMethod);
std::string::size_type posMethodParams = sMethod.find(":");
std::string sParams = "";
if (posMethodParams != std::string::npos)
{
sParams = sMethod.substr(posMethodParams + 1);
sMethod = sMethod.substr(0, posMethodParams);
if (std::string::npos != sParams.find("stream"))
m_isProgress = true;
}
if ("POST" == sMethod)
{
std::string sPostData = args->GetString(4).ToString();
@ -422,6 +436,28 @@ namespace NSRequest
size_t data_length) override
{
m_download_data += std::string(static_cast<const char*>(data), data_length);
if (m_isProgress)
{
CefURLRequest::Status status = request->GetRequestStatus();
CefURLRequest::ErrorCode error_code = request->GetRequestError();
std::string sReturnObject = "{ status: " + std::to_string((int)status) + ", statusCode: " + std::to_string((int)error_code) + ", responseText : \"";
char* base64 = NULL;
int base64Len = 0;
NSFile::CBase64Converter::Encode(static_cast<const BYTE*>(data), (int)data_length, base64, base64Len, NSBase64::B64_BASE64_FLAG_NOCRLF);
sReturnObject += std::string(base64, base64Len);
RELEASEARRAYOBJECTS(base64);
sReturnObject += "\"}";
std::string sCode = "try { window.AscSimpleRequest._onProgress(" + std::to_string(m_requestId) + ", " +
sReturnObject + "); } catch (err) { window.AscSimpleRequest._onError(" +
std::to_string(m_requestId) + ", { status : \"error\", statusCode : 404, responseText : \"\" }); }";
this->SendToRenderer(m_frameId, sCode);
}
}
bool GetAuthCredentials(bool isProxy,
@ -558,6 +594,7 @@ namespace NSSystem
bool bRes = true;
m_pLocker->StartWrite();
m_pLocker->SeekFile(0);
DWORD dwRead = 0;
@ -1510,6 +1547,8 @@ public:
// показывать ли консоль для дебага
bool m_bDebugInfoSupport;
bool m_bSupportMultiplugins;
// экспериментальные возможности
bool m_bExperimentalFeatures;
@ -1642,6 +1681,7 @@ public:
m_sLogFile = "";
m_bDebugInfoSupport = false;
m_bExperimentalFeatures = false;
m_bSupportMultiplugins = false;
m_bIsUseExternalMessageLoop = false;
m_pExternalMessageLoop = NULL;
@ -1898,6 +1938,10 @@ public:
if (pairDEBUG != _map->end() && "1" == pairDEBUG->second)
m_bDebugInfoSupport = true;
std::map<std::string, std::string>::iterator pairComplexPlugins = _map->find("support-complex-plugins");
if (pairComplexPlugins != _map->end() && "1" == pairComplexPlugins->second)
m_bSupportMultiplugins = true;
if (!NSCommon::CSystemWindowScale::IsInit())
{
std::map<std::string, std::string>::iterator pairUseSystemScale = _map->find("system-scale");

View File

@ -501,6 +501,8 @@ int CApplicationCEF::Init_CEF(CAscApplicationManager* pManager, int argc, char*
CPluginsManager oPlugins;
oPlugins.m_strDirectory = pManager->m_oSettings.system_plugins_path;
oPlugins.m_strUserDirectory = pManager->m_oSettings.user_plugins_path;
oPlugins.m_bIsSupportMultiplugins = pManager->m_pInternal->m_bSupportMultiplugins;
oPlugins.GetInstalledPlugins();
bool bIsCurrentCryptoPresent = false;

View File

@ -4689,8 +4689,10 @@ virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
sGuidA = sGuidA.substr(4);
std::wstring sGuid = UTF8_TO_U(sGuidA);
std::wstring sSrc = (iterExt->isUser ? sUserPluginsPath : sSystemPluginsPath) + L"/" + sGuid + L"/index.html" + m_pParent->m_pInternal->m_pManager->m_pInternal->m_mainPostFix;
std::wstring sSrc = (iterExt->isUser ? sUserPluginsPath : sSystemPluginsPath) + L"/" + sGuid + L"/" + UTF8_TO_U(iterExt->sUrl) + m_pParent->m_pInternal->m_pManager->m_pInternal->m_mainPostFix;
NSCommon::url_correct(sSrc);
if (iterExt->isOnlyofficeScheme)
sSrc = L"onlyoffice://plugin/" + sSrc;
std::wstring sNameG = UTF8_TO_U((iterExt->sName));
std::wstring sNameLocal = UTF8_TO_U((iterExt->sNameObject));

View File

@ -60,6 +60,8 @@
#include <boost/filesystem.hpp>
#include "../../tools/tools.h"
std::wstring GetTmpFileFromBase64(const std::string& sData, const std::wstring& sTmpFolder)
{
if (sData.empty())
@ -2394,11 +2396,13 @@ window.AscDesktopEditor._convertFile(path, format);\n\
window.AscDesktopEditor.getPortalsList = function() { var ret = []; try { var portals = JSON.parse(localStorage.getItem(\"portals\")); for (var i = 0, len = portals.length; i < len; i++) { ret.push(portals[i].portal); ret.push(portals[i].provider); } } catch(err) { ret = []; } console.log(ret);window.AscDesktopEditor.setPortalsList(ret); };\n\
";
#ifdef CEF_VERSION_ABOVE_102
sCodeInitJS += "!function(){window.AscSimpleRequest=window.AscSimpleRequest||{};var r=0,o={};window.AscSimpleRequest.createRequest=function(e){var "
"t;o[++r]={id:r,complete:e.complete,error:e.error},e.timeout&&(o[t=r].timer=setTimeout(function(){o[t]&&(o[t].error&&o[t].error({status:\"error\",statusCode:404},"
"\"error\"),delete o[t])},e.timeout)),window.AscDesktopEditor.sendSimpleRequest(r,e)},window.AscSimpleRequest._onSuccess=function(e,t){let "
"r=o[e];r&&(r.timer&&clearTimeout(r.timer),r.complete&&r.complete(t,t.status),delete o[e])},window.AscSimpleRequest._onError=function(e,t){let "
"r=o[e];r&&(r.timer&&clearTimeout(r.timer),r.error&&r.error(t,t.status),delete o[e])}}();\n";
sCodeInitJS += "!function(){window.AscSimpleRequest=window.AscSimpleRequest||{};var r=0,o={};window.AscSimpleRequest.createRequest=function(e)"
"{var t;o[++r]={id:r,complete:e.complete,error:e.error,progress:e.progress},e.timeout&&(o[t=r].timer=setTimeout(function()"
"{o[t]&&(o[t].error&&o[t].error({status:\"error\",statusCode:404},\"error\"),delete o[t])},e.timeout)),"
"window.AscDesktopEditor.sendSimpleRequest(r,e)},window.AscSimpleRequest._onSuccess=function(e,t){"
"let r=o[e];r&&(r.timer&&clearTimeout(r.timer),r.complete&&r.complete(t,t.status),delete o[e])},"
"window.AscSimpleRequest._onError=function(e,t){let r=o[e];r&&(r.timer&&clearTimeout(r.timer),r.error&&r.error(t,t.status),delete o[e])},"
"window.AscSimpleRequest._onProgress=function(e,t){let r=o[e];r&&(r.timer&&clearTimeout(r.timer),r.progress&&r.progress(t,t.status))}}();";
#endif
sCodeInitJS += "\
window.AscDesktopEditor.getViewportSettings=function(){return JSON.parse(window.AscDesktopEditor._getViewportSettings());};\
@ -4408,6 +4412,32 @@ window.AscDesktopEditor.CallInFrame(\"" +
retval = CefV8Value::CreateInt(nVersion);
return true;
}
else if (name == "getToolFunctions")
{
CAITools& tools = CAITools::getInstance();
if (tools.getWorkDirectory().empty())
{
tools.setFontsDirectory(m_sFontsData);
tools.setWorkDirectory(m_sSystemPlugins + L"/../../converter");
}
retval = CefV8Value::CreateString(tools.getFunctions());
return true;
}
else if (name == "callToolFunction")
{
CAITools& tools = CAITools::getInstance();
if (tools.getWorkDirectory().empty())
{
tools.setFontsDirectory(m_sFontsData);
tools.setWorkDirectory(m_sSystemPlugins + L"/../../converter");
}
std::string name = arguments[0]->GetStringValue().ToString();
std::string param = arguments[1]->GetStringValue().ToString();
retval = CefV8Value::CreateString(tools.callFunc(name, param));
return true;
}
// Function does not exist.
return false;
@ -4983,7 +5013,7 @@ if (targetElem) { targetElem.dispatchEvent(event); }})();";
CefRefPtr<CefV8Handler> handler = pWrapper;
#define EXTEND_METHODS_COUNT 186
#define EXTEND_METHODS_COUNT 188
const char* methods[EXTEND_METHODS_COUNT] = {
"Copy",
"Paste",
@ -5242,6 +5272,9 @@ if (targetElem) { targetElem.dispatchEvent(event); }})();";
"getEngineVersion",
"getToolFunctions",
"callToolFunction",
NULL};
ExtendObject(obj, handler, methods);

View File

@ -299,8 +299,7 @@ public:
virtual bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback)
OVERRIDE
CefRefPtr<CefCallback> callback) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
@ -374,9 +373,163 @@ private:
IMPLEMENT_REFCOUNTING(ClientSchemeHandler);
};
class ClientSchemeHandlerOO : public CefResourceHandler
{
public:
ClientSchemeHandlerOO(CAscApplicationManager* pManager) : offset_(0)
{
offset_ = 0;
data_binary_ = NULL;
data_binary_len_ = 0;
m_pManager = pManager;
}
virtual ~ClientSchemeHandlerOO()
{
if (NULL != data_binary_)
delete [] data_binary_;
}
virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
std::string url = request->GetURL().ToString();
std::string::size_type posFind = url.find("onlyoffice://plugin/");
if (posFind != std::string::npos)
{
std::wstring sFile = read_file_path(request).substr(20);
if (!m_pManager->IsResolveLocalFile(sFile))
return false;
std::wstring::size_type posSearch = sFile.find(L"?lang=");
if (std::wstring::npos == posSearch)
{
posSearch = sFile.find(L".html?");
if (std::wstring::npos != posSearch)
posSearch += 5;
}
if (std::wstring::npos != posSearch)
sFile = sFile.substr(0, posSearch);
if (0 == sFile.find(L"file:///"))
{
sFile = sFile.substr(7);
if (!NSFile::CFileBinary::Exists(sFile))
sFile = sFile.substr(1);
}
read_binary_file(sFile, true);
callback->Continue();
return true;
}
return false;
}
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
int64& response_length,
CefString& redirectUrl) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
DCHECK(!data_.empty() || !data_binary_);
response->SetMimeType(mime_type_);
response->SetStatus(200);
CefResponse::HeaderMap headers;
response->GetHeaderMap(headers);
headers.insert(std::make_pair("Access-Control-Allow-Origin", "*"));
response->SetHeaderMap(headers);
// Set the resulting response length
response_length = (NULL == data_binary_) ? data_.length() : data_binary_len_;
}
virtual void Cancel() OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
}
virtual bool ReadResponse(void* data_out,
int bytes_to_read,
int& bytes_read,
CefRefPtr<CefCallback> callback) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
bytes_read = 0;
BYTE* read_data = (BYTE*)data_binary_;
size_t read_data_len = data_binary_len_;
if (!read_data)
{
read_data = (BYTE*)data_.c_str();
read_data_len = data_.length();
}
if (offset_ < read_data_len)
{
// Copy the next block of data into the buffer.
int transfer_size = std::min(bytes_to_read, static_cast<int>(read_data_len - offset_));
memcpy(data_out, read_data + offset_, transfer_size);
offset_ += transfer_size;
bytes_read = transfer_size;
return true;
}
return false;
}
private:
std::wstring read_file_path(CefRefPtr<CefRequest>& request)
{
int nFlag = UU_SPACES | UU_REPLACE_PLUS_WITH_SPACE;
#if defined (_LINUX) && !defined(_MAC)
nFlag |= UU_URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS;
#else
#ifndef CEF_2623
nFlag |= UU_URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS;
#endif
#endif
CefString cefUrl = request->GetURL();
CefString cefFile = CefURIDecode(cefUrl, false, static_cast<cef_uri_unescape_rule_t>(nFlag));
return cefFile.ToWString();
}
void read_binary_file(std::wstring& sFile, const bool& isCheckExt = false)
{
data_binary_len_ = (size_t)asc_scheme::read_file_with_urls(sFile, data_binary_);
if (isCheckExt)
mime_type_ = asc_scheme::GetMimeTypeFromExt(sFile);
if (mime_type_.empty())
mime_type_ = "*/*";
}
private:
std::string data_;
std::string mime_type_;
size_t offset_;
BYTE* data_binary_;
size_t data_binary_len_;
CAscApplicationManager* m_pManager;
IMPLEMENT_REFCOUNTING(ClientSchemeHandlerOO);
};
namespace asc_scheme
{
// Implementation of the factory for for creating schema handlers.
class ClientSchemeHandlerFactory : public CefSchemeHandlerFactory
{
@ -394,13 +547,18 @@ namespace asc_scheme
virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& scheme_name,
CefRefPtr<CefRequest> request)
OVERRIDE
CefRefPtr<CefRequest> request) OVERRIDE
{
CEF_REQUIRE_IO_THREAD();
std::string schemeName = scheme_name.ToString();
if (schemeName == "onlyoffice")
return new ClientSchemeHandlerOO(m_pManager);
std::wstring sMainUrl = L"";
if (browser && browser->GetMainFrame())
sMainUrl = browser->GetMainFrame()->GetURL().ToWString();
return new ClientSchemeHandler(m_pManager, sMainUrl);
}
@ -420,13 +578,17 @@ namespace asc_scheme
#endif
)
{
registrar->AddCustomScheme("ascdesktop", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_SECURE | CEF_SCHEME_OPTION_CORS_ENABLED/* | CEF_SCHEME_OPTION_FETCH_ENABLED*/);
registrar->AddCustomScheme("ascdesktop", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_SECURE | CEF_SCHEME_OPTION_CORS_ENABLED | CEF_SCHEME_OPTION_FETCH_ENABLED);
registrar->AddCustomScheme("onlyoffice", CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_SECURE | CEF_SCHEME_OPTION_CORS_ENABLED | CEF_SCHEME_OPTION_FETCH_ENABLED);
}
#endif
bool InitScheme(CAscApplicationManager* pManager)
{
return CefRegisterSchemeHandlerFactory("ascdesktop", "", new ClientSchemeHandlerFactory(pManager));
bool res = true;
res = res && CefRegisterSchemeHandlerFactory("ascdesktop", "", new ClientSchemeHandlerFactory(pManager));
res = res && CefRegisterSchemeHandlerFactory("onlyoffice", "", new ClientSchemeHandlerFactory(pManager));
return res;
}
} // namespace asc_scheme

View File

@ -26,7 +26,8 @@
simpleRequestCallback[simpleRequestCounter] = {
id : simpleRequestCounter,
complete : obj.complete,
error : obj.error
error : obj.error,
progress : obj.progress
};
if (obj.timeout)
@ -82,4 +83,17 @@
}
};
window.AscSimpleRequest._onProgress = function(counter, e)
{
let obj = simpleRequestCallback[counter];
if (obj)
{
if (obj.timer)
clearTimeout(obj.timer);
if (obj.progress)
obj.progress(e, e.status);
}
};
})();

View File

@ -32,6 +32,264 @@
#include "./filelocker.h"
#include <set>
#include <chrono>
#include <sstream>
#include <iomanip>
#ifdef _WIN32
#include <windows.h>
#if defined(CreateFile)
#undef CreateFile
#endif
#if defined(CopyFile)
#undef CopyFile
#endif
#if defined(DeleteFile)
#undef DeleteFile
#endif
#else
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <limits.h>
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 1000
#endif
#endif
#include "../../../../core/DesktopEditor/common/SystemUtils.h"
#include "../../../../core/DesktopEditor/common/StringBuilder.h"
#if defined(_LINUX) && !defined(_MAC)
#include <gio/gio.h>
#define LOCKER_USE_GIO
#endif
namespace NSSystem
{
CLockFileTemp::CLockFileTemp(const std::wstring& file)
{
m_file = file;
}
CLockFileTemp::~CLockFileTemp()
{
}
CLockFileTemp::CLockFileTemp(const CLockFileTemp& src)
{
m_file = src.m_file;
m_user = src.m_user;
m_host = src.m_host;
m_date = src.m_date;
m_user_dir = src.m_user_dir;
}
CLockFileTemp& CLockFileTemp::operator=(const CLockFileTemp& src)
{
m_file = src.m_file;
m_user = src.m_user;
m_host = src.m_host;
m_date = src.m_date;
m_user_dir = src.m_user_dir;
return *this;
}
void CLockFileTemp::Generate()
{
if (true)
{
#ifdef _WIN32
wchar_t user_name[1000];
DWORD user_name_len = 1000 + 1;
GetUserNameW(user_name, &user_name_len);
m_user = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(user_name, user_name_len - 1);
#else
m_user = NSSystemUtils::GetEnvVariableA(L"USER");
#endif
}
if (true)
{
#ifdef _WIN32
wchar_t hostname[MAX_COMPUTERNAME_LENGTH + 1];
DWORD hostname_len = MAX_COMPUTERNAME_LENGTH + 1;
if (GetComputerNameExW(ComputerNamePhysicalDnsFullyQualified, hostname, &hostname_len))
{
m_host = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(hostname, hostname_len);
}
else if (GetComputerNameW(hostname, &hostname_len))
{
m_host = NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(hostname, hostname_len);
}
else
{
m_host = "Unknown";
}
#else
char hostname[HOST_NAME_MAX + 1];
if (gethostname(hostname, sizeof(hostname)) == 0)
{
hostname[HOST_NAME_MAX] = '\0';
m_host = std::string(hostname);
}
else
{
m_host = "Unknown";
}
#endif
}
if (true)
{
auto now = std::chrono::system_clock::now();
std::time_t time_t = std::chrono::system_clock::to_time_t(now);
std::tm utc_tm = {};
#ifdef _WIN32
gmtime_s(&utc_tm, &time_t);
#else
gmtime_r(&time_t, &utc_tm);
#endif
std::ostringstream stream;
stream << std::setfill('0')
<< std::setw(2) << utc_tm.tm_mday << "."
<< std::setw(2) << (utc_tm.tm_mon + 1) << "."
<< (utc_tm.tm_year + 1900) << " "
<< std::setw(2) << utc_tm.tm_hour << ":"
<< std::setw(2) << utc_tm.tm_min;
m_date = stream.str();
}
if (true)
{
std::wstring user_dir = NSSystemUtils::GetAppDataDir();
m_user_dir = U_TO_UTF8(user_dir);
#ifdef _WIN32
NSStringUtils::string_replaceA(m_user_dir, "\\", "/");
#endif
}
NSStringUtils::string_replaceA(m_user, ",", "&#39;");
NSStringUtils::string_replaceA(m_host, ",", "&#39;");
NSStringUtils::string_replaceA(m_date, ",", "&#39;");
NSStringUtils::string_replaceA(m_user_dir, ",", "&#39;");
}
void CLockFileTemp::Save(int type)
{
std::string content = "," + m_user + "," + m_host + "," + m_date + "," + m_user_dir + ";";
switch (type)
{
case 0:
{
NSFile::CFileBinary oFile;
if (oFile.CreateFile(m_file))
{
oFile.WriteFile((BYTE*)content.c_str(), (DWORD)content.length());
oFile.CloseFile();
}
break;
}
case 1:
{
#ifdef LOCKER_USE_GIO
GError* error = NULL;
std::string sFileA = U_TO_UTF8(m_file);
GFile* file = g_file_new_for_commandline_arg(sFileA.c_str());
GFileOutputStream* outputStream = g_file_create(file, G_FILE_CREATE_NONE, NULL, &error);
if (!outputStream)
{
g_error_free(error);
g_object_unref(file);
return;
}
gsize bytesWritten = 0;
gboolean writeResult = g_output_stream_write_all(G_OUTPUT_STREAM(outputStream), content.c_str(), content.length(), &bytesWritten, NULL, &error);
if (!writeResult)
{
g_error_free(error);
}
g_output_stream_close(G_OUTPUT_STREAM(outputStream), NULL, NULL);
g_object_unref(outputStream);
g_object_unref(file);
#endif
break;
}
default:
break;
}
}
void CLockFileTemp::Load()
{
std::string content;
if (NSFile::CFileBinary::ReadAllTextUtf8A(m_file, content))
{
std::string::size_type pos1 = 1;
std::string::size_type pos2 = content.find(',', pos1);
if (std::string::npos != pos2)
{
m_user = content.substr(pos1, pos2 - pos1);
pos1 = pos2 + 1;
}
pos2 = content.find(',', pos1);
if (std::string::npos != pos2)
{
m_host = content.substr(pos1, pos2 - pos1);
pos1 = pos2 + 1;
}
pos2 = content.find(',', pos1);
if (std::string::npos != pos2)
{
m_date = content.substr(pos1, pos2 - pos1);
pos1 = pos2 + 1;
}
pos2 = content.find(';', pos1);
if (std::string::npos != pos2)
{
m_user_dir = content.substr(pos1);
}
}
}
bool CLockFileTemp::IsEqual(const CLockFileTemp& lock)
{
if (m_user != lock.m_user)
return false;
if (m_host != lock.m_host)
return false;
if (m_user_dir != lock.m_user_dir)
return false;
return true;
}
std::wstring CLockFileTemp::GetPath()
{
return m_file;
}
}
class CHandlesMonitor
{
@ -91,6 +349,14 @@ namespace NSSystem
virtual bool Lock()
{
CLockFileTemp lockFile(L"");
if (IsUseLockFile())
{
lockFile = CheckLockFilePath(m_sFile);
if (lockFile.GetPath().empty())
return false;
}
bool bResult = true;
std::wstring sFileFull = CorrectPathW(m_sFile);
DWORD dwFileAttributes = 0; //GetFileAttributesW(sFileFull.c_str());
@ -107,6 +373,12 @@ namespace NSSystem
m_nDescriptor = INVALID_HANDLE_VALUE;
bResult = false;
}
if (bResult && !lockFile.GetPath().empty())
{
m_sLockFilePath = lockFile.GetPath();
lockFile.Save();
}
return bResult;
}
@ -125,6 +397,7 @@ namespace NSSystem
bResult = true;
}
DeleteLockFile();
return bResult;
}
@ -153,6 +426,11 @@ namespace NSSystem
}
public:
static bool IsUseLockFile()
{
return true;
}
static LockType IsLockedInternal(const std::wstring& file)
{
LockType lockType = LockType::ltNone;
@ -175,6 +453,14 @@ namespace NSSystem
}
}
CloseHandle(hFile);
if (lockType == LockType::ltNone && IsUseLockFile())
{
CLockFileTemp tmp = CheckLockFilePath(file);
if (tmp.GetPath().empty())
return LockType::ltLocked;
}
return lockType;
}
};
@ -207,15 +493,31 @@ namespace NSSystem
virtual bool Lock()
{
CLockFileTemp lockFile(L"");
if (IsUseLockFile())
{
lockFile = CheckLockFilePath(m_sFile);
if (lockFile.GetPath().empty())
return false;
}
if (!lockFile.GetPath().empty())
{
m_sLockFilePath = lockFile.GetPath();
lockFile.Save();
}
std::string sFileA = U_TO_UTF8(m_sFile);
m_nDescriptor = open(sFileA.c_str(), O_RDWR | O_EXCL);
if (-1 == m_nDescriptor)
return true;
return true;
}
virtual bool Unlock()
{
DeleteLockFile();
if (-1 == m_nDescriptor)
return true;
close(m_nDescriptor);
@ -266,6 +568,25 @@ namespace NSSystem
{
return true;
}
static bool IsUseLockFile()
{
return true;
}
static LockType IsLockedInternal(const std::wstring& file)
{
LockType lockType = LockType::ltNone;
if (lockType == LockType::ltNone && IsUseLockFile())
{
CLockFileTemp tmp = CheckLockFilePath(file);
if (tmp.GetPath().empty())
return LockType::ltLocked;
}
return lockType;
}
};
class CFileLockerFCNTL : public CFileLockerEmpty
@ -281,6 +602,14 @@ namespace NSSystem
virtual bool Lock()
{
CLockFileTemp lockFile(L"");
if (IsUseLockFile())
{
lockFile = CheckLockFilePath(m_sFile);
if (lockFile.GetPath().empty())
return false;
}
bool bResult = true;
std::string sFileA = U_TO_UTF8(m_sFile);
@ -298,12 +627,19 @@ namespace NSSystem
bResult = (0 == fcntl(m_nDescriptor, F_SETLKW, &_lock));
if (bResult && !lockFile.GetPath().empty())
{
m_sLockFilePath = lockFile.GetPath();
lockFile.Save();
}
CHandlesMonitor::Instance().Add(m_sFile);
return bResult;
}
virtual bool Unlock()
{
DeleteLockFile();
if (-1 == m_nDescriptor)
return true;
@ -324,6 +660,11 @@ namespace NSSystem
}
public:
static bool IsUseLockFile()
{
return true;
}
static LockType IsLockedInternal(const std::wstring& file)
{
LockType lockType = LockType::ltNone;
@ -345,12 +686,20 @@ namespace NSSystem
if (F_WRLCK == (_lock.l_type & F_WRLCK))
lockType = LockType::ltLocked;
close(nDescriptor);
if (lockType == LockType::ltNone && IsUseLockFile())
{
CLockFileTemp tmp = CheckLockFilePath(file);
if (tmp.GetPath().empty())
return LockType::ltLocked;
}
return lockType;
}
};
}
#if defined(_LINUX) && !defined(_MAC)
#ifdef LOCKER_USE_GIO
#include <gio/gio.h>
@ -361,6 +710,7 @@ namespace NSSystem
GFile* m_pFile;
char* m_pFileUri;
GOutputStream* m_pOutputStream;
bool m_bIsReplace;
public:
CFileLockerGIO(const std::wstring& file) : CFileLocker(file)
@ -368,6 +718,7 @@ namespace NSSystem
m_pFile = NULL;
m_pFileUri = NULL;
m_pOutputStream = NULL;
m_bIsReplace = false;
}
virtual ~CFileLockerGIO()
{
@ -376,6 +727,14 @@ namespace NSSystem
virtual bool Lock()
{
CLockFileTemp lockFile(L"");
if (IsUseLockFile())
{
lockFile = CheckLockFilePath(m_sFile, 1);
if (lockFile.GetPath().empty())
return false;
}
bool bResult = true;
std::string sFileA = U_TO_UTF8(m_sFile);
@ -385,12 +744,31 @@ namespace NSSystem
m_pFileUri = g_file_get_uri(m_pFile);
GError* err = NULL;
m_pOutputStream = G_OUTPUT_STREAM(g_file_append_to(m_pFile, G_FILE_CREATE_PRIVATE, NULL, &err));
if (err && err->code == G_IO_ERROR_NOT_SUPPORTED)
{
g_error_free(err);
err = NULL;
if (m_pOutputStream)
{
g_output_stream_close(m_pOutputStream, NULL, NULL);
g_object_unref(m_pOutputStream);
m_pOutputStream = NULL;
}
m_bIsReplace = true;
}
bResult = !err;
if (err)
g_error_free (err);
}
if (bResult && !lockFile.GetPath().empty())
{
m_sLockFilePath = lockFile.GetPath();
lockFile.Save(1);
}
return bResult;
}
@ -405,6 +783,7 @@ namespace NSSystem
GError* err = NULL;
g_output_stream_close(m_pOutputStream, NULL, &err);
g_object_unref(m_pOutputStream);
m_pOutputStream = NULL;
if (err)
g_error_free (err);
@ -422,6 +801,7 @@ namespace NSSystem
bResult = true;
}
DeleteLockFile();
return bResult;
}
@ -448,19 +828,50 @@ namespace NSSystem
bool bResult = false;
if (m_pFile && m_pOutputStream)
{
if (g_seekable_can_truncate((GSeekable*)m_pOutputStream))
if (!m_bIsReplace)
{
GError* err = NULL;
if (g_seekable_truncate((GSeekable*)m_pOutputStream, dwPosition, NULL, &err))
bResult = !err;
if (g_seekable_can_truncate((GSeekable*)m_pOutputStream))
{
GError* err = NULL;
if (g_seekable_truncate((GSeekable*)m_pOutputStream, dwPosition, NULL, &err))
bResult = !err;
if (err)
g_error_free (err);
if (err)
g_error_free (err);
}
}
else
{
g_output_stream_close(m_pOutputStream, NULL, NULL);
g_object_unref(m_pOutputStream);
m_pOutputStream = NULL;
}
}
return bResult;
}
virtual bool StartWrite()
{
if (!m_pOutputStream && m_bIsReplace)
{
GError* err = NULL;
m_pOutputStream = G_OUTPUT_STREAM(g_file_replace(m_pFile, nullptr, false, G_FILE_CREATE_PRIVATE, nullptr, &err));
if (err)
{
if (m_pOutputStream)
{
g_output_stream_close(m_pOutputStream, NULL, NULL);
g_object_unref(m_pOutputStream);
m_pOutputStream = NULL;
}
g_error_free(err);
return false;
}
}
return true;
}
virtual bool WriteFile(const void* pData, DWORD dwBytesToWrite, DWORD& dwSizeWrite)
{
bool bResult = false;
@ -474,6 +885,11 @@ namespace NSSystem
return bResult;
}
static bool IsUseLockFile()
{
return true;
}
static LockType IsLockedInternal(const std::wstring& file)
{
LockType lockType = LockType::ltNone;
@ -481,6 +897,14 @@ namespace NSSystem
if (!pLocker->Lock())
lockType = LockType::ltReadOnly; // ltLocked
delete pLocker;
if (lockType == LockType::ltNone && IsUseLockFile())
{
CLockFileTemp tmp = CheckLockFilePath(file, 1);
if (tmp.GetPath().empty())
return LockType::ltLocked;
}
return lockType;
}
};
@ -530,6 +954,8 @@ namespace NSSystem
lockType = NSSystem::CFileLockerFCNTL::IsLockedInternal(file);
else
lockType = NSSystem::CFileLockerGIO::IsLockedInternal(file);
#else
lockType = NSSystem::CFileLockerEmpty::IsLockedInternal(file);
#endif
#endif
return lockType;
@ -559,11 +985,72 @@ namespace NSSystem
CFileLocker::CFileLocker(const std::wstring& file)
{
m_sFile = file;
m_sLockFilePath = L"";
}
CFileLocker::~CFileLocker()
{
}
CLockFileTemp CFileLocker::CheckLockFilePath(const std::wstring& file, const int& flags)
{
std::wstring sDirectory = NSFile::GetDirectoryName(file);
std::wstring sFilename = NSFile::GetFileName(file);
#ifdef LOCKER_USE_GIO
if (flags == 1)
{
std::string fileA = U_TO_UTF8(file);
GFile* file = g_file_new_for_path(fileA.c_str());
if (file)
{
GError* error = NULL;
GFileInfo* info = g_file_query_info(file,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
G_FILE_ATTRIBUTE_STANDARD_NAME,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
if (info && !error)
{
const char* displayName = g_file_info_get_display_name(info);
if (displayName)
{
std::string result = displayName;
sFilename = UTF8_TO_U(result);
}
g_object_unref(info);
}
if (error)
g_error_free(error);
g_object_unref(file);
}
}
#endif
std::wstring sLockFile = sDirectory + L"/.~lock." + sFilename + L"#";
CLockFileTemp tempCur(sLockFile);
tempCur.Generate();
if (NSFile::CFileBinary::Exists(sLockFile))
{
CLockFileTemp tempSaved(sLockFile);
tempSaved.Load();
if (!tempCur.IsEqual(tempSaved))
return CLockFileTemp(L"");
}
return tempCur;
}
void CFileLocker::DeleteLockFile()
{
if (!m_sLockFilePath.empty())
NSFile::CFileBinary::Remove(m_sLockFilePath);
m_sLockFilePath = L"";
}
bool CFileLocker::IsEmpty()
{
return false;
@ -611,4 +1098,9 @@ namespace NSSystem
#endif
}
bool CFileLocker::StartWrite()
{
return true;
}
}

View File

@ -47,17 +47,47 @@ namespace NSSystem
ltNosafe = 0x04
};
class CLockFileTemp
{
private:
std::string m_user;
std::string m_host;
std::string m_date;
std::string m_user_dir;
std::wstring m_file;
public:
CLockFileTemp(const std::wstring& file);
~CLockFileTemp();
CLockFileTemp(const CLockFileTemp& file);
CLockFileTemp& operator=(const CLockFileTemp& file);
public:
void Generate();
void Save(int type = 0);
void Load();
bool IsEqual(const CLockFileTemp& lock);
std::wstring GetPath();
};
class CFileLocker
{
public:
std::wstring m_sFile;
std::wstring m_sLockFilePath;
CFileLocker(const std::wstring& file);
virtual ~CFileLocker();
static CLockFileTemp CheckLockFilePath(const std::wstring& file, const int& flags = 0);
virtual void DeleteLockFile();
virtual bool Lock() = 0;
virtual bool Unlock() = 0;
virtual bool StartWrite();
virtual bool SeekFile(DWORD dwPosition) = 0;
virtual bool Truncate(DWORD dwPosition) = 0;
virtual bool WriteFile(const void* pData, DWORD dwBytesToWrite, DWORD& dwSizeWrite) = 0;

View File

@ -51,6 +51,9 @@ public:
std::string sGuid;
std::string sName;
std::string sNameObject;
std::string sConfigName;
std::string sUrl;
bool isOnlyofficeScheme;
bool isUser;
};
@ -74,6 +77,7 @@ public:
// плагин не для редактора, а для главной страницы (для системных сообщенией)
std::vector<CExternalPluginInfo> m_arExternals;
bool m_bIsSupportMultiplugins;
public:
CPluginsManager()
@ -88,6 +92,8 @@ public:
// Возможность псевдо-обновления системных плагинов
// По факту подмена системного на более новый из папки пользователя
m_isSupportSystemUpdate = true;
m_bIsSupportMultiplugins = false;
}
std::string GetPluginsJson(const bool& bActivePlugins = true, const bool& bCheckCrypto = false,
@ -142,12 +148,13 @@ public:
for (size_t j = 0; j < _arPlugins.size(); j++)
{
std::string sJson;
bool bIsExternal = false;
if (NSFile::CFileBinary::ReadAllTextUtf8A(_arPlugins[j] + L"/config.json", sJson))
{
CheckEncryption(sJson, false);
// !!! это надо обсудить, т.к. возможны такие плагины в папке пользователя
CheckExternal(sJson, i == 0);
bIsExternal = CheckExternal(sJson, i == 0);
std::string::size_type pos1 = sJson.find("asc.{");
std::string::size_type pos2 = sJson.find('}', pos1);
@ -164,6 +171,12 @@ public:
}
}
}
// check for desktop
if (m_bIsSupportMultiplugins && !bIsExternal && NSFile::CFileBinary::ReadAllTextUtf8A(_arPlugins[j] + L"/configDesktop.json", sJson))
{
CheckExternal(sJson, i == 0);
}
}
}
@ -555,6 +568,8 @@ private:
info.sName = GetStringValue(sJson, "name");
info.sNameObject = GetObjectValue(sJson, "nameLocale");
info.isUser = isSystem ? false : true;
info.sUrl = GetStringValue(sJson, "url");
info.isOnlyofficeScheme = (std::string::npos != sJson.find("onlyofficeScheme")) ? true : false;
m_arExternals.push_back(info);
}

View File

@ -0,0 +1,61 @@
#include "./internal/base.h"
namespace form_field_analyser
{
std::string description()
{
return "\n\
- form_field_analyser\n\
Description: \n\
Use this function if you are asked to analyze document or forms.\n\
Parameters:\n\
- document (string): path or link value to the document you were asked to analyze\n\
Examples:\n\
If you need to analyze document /home/user/document.docx, respond with: \
[functionCalling (form_field_analyser)]: { \"document\" : \"/home/user/document.docx\" }\n";
}
std::string main(const std::string& arg)
{
json param = json::parse(arg);
if (!param.contains("document") || !param["document"].is_string())
return "";
std::string pathA = param["document"];
std::wstring path = UTF8_TO_U(pathA);
CDocBuilder builder;
initBuilder(&builder);
int res = builder.OpenFile(path.c_str(), L"");
if (0 != res)
return "";
CContext context = builder.GetContext();
CValue global = context.GetGlobal();
CValue api = global["Api"];
CValue document = api.Call("GetDocument");
json keys = json::array();
CValue allForms = document.Call("GetAllForms");
int count = allForms.GetLength();
for (int i = 0; i < count; i++)
{
CValue field = allForms.Get(i);
std::wstring keyW(field.Call("GetFormKey").ToString().c_str());
std::string key = U_TO_UTF8(keyW);
keys.push_back(key);
}
std::string result = keys.dump();
builder.CloseFile();
std::string prompt = "[prompt]Match the document fields by meaning with the values in the array in javascript format. \
And when you are asked to fill out a form, send not invented field values to the function, but only those that are in the passed list: " + result;
return prompt;
}
}

View File

@ -0,0 +1,114 @@
#include "./internal/base.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <ctime>
#ifdef _WIN32
#define timegm _mkgmtime
#endif
namespace form_field_filler
{
long long parseDateToUTCMilliseconds(const std::string& date)
{
long long default_value = 946684800000;
std::tm tm = {};
std::istringstream ss(date);
ss >> std::get_time(&tm, "%d.%m.%Y");
if (ss.fail())
return default_value;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
time_t timeUtc = timegm(&tm);
if (timeUtc == -1) {
return default_value;
}
return static_cast<long long>(timeUtc) * 1000;
}
std::string description()
{
return "\n\
- form_field_filler\n\
Description: \n\
Use this function if you are asked to fill out a document or form.\n\
Use only those keys that were obtained during the analysis of the document or form, unless a specific key was specified in the request.\n\
Parameters:\n\
- document (string): path or link value to the document you were asked to fill\n\
- fields (object): path or link value to the document you were asked to fill (\
If you are asked for a date, then give it in the format dd.mm.yyyy. \
Convert any given date range or time period (e.g. \"summer 2025\", \"fall 2024\", \"January 2023\", \"second half 2026\", \"first quarter 2022\") to two dates: \
start and end, represented as timestamp in format dd.mm.yyyy. Use exact calendar dates to define period boundaries (taking into account leap years, number of days in months, etc.)).\n\
Examples:\n\
[functionCalling (form_field_filler)] { \"document\" : \"/home/user/document.docx\", \"fields\" : { \"key1\" : \"value1\", \"key2\" : \"value2\" } }\n";
}
std::string main(const std::string& arg)
{
json param = json::parse(arg);
if (!param.contains("document") || !param["document"].is_string())
return "";
if (!param.contains("fields") || !param["fields"].is_object())
return "";
std::string pathA = param["document"];
std::wstring path = UTF8_TO_U(pathA);
CDocBuilder builder;
initBuilder(&builder);
int res = builder.OpenFile(path.c_str(), L"");
if (0 != res)
return "";
json inputFields = param["fields"];
CContext context = builder.GetContext();
CValue global = context.GetGlobal();
CValue api = global["Api"];
CValue document = api.Call("GetDocument");
CValue allForms = document.Call("GetAllForms");
int count = allForms.GetLength();
for (int i = 0; i < count; i++)
{
CValue field = allForms.Get(i);
std::wstring keyW(field.Call("GetFormKey").ToString().c_str());
std::string key = U_TO_UTF8(keyW);
if (!inputFields.contains(key))
continue;
std::wstring typeW(field.Call("GetFormType").ToString().c_str());
std::string type = U_TO_UTF8(typeW);
if ("textForm" == type && inputFields[key].is_string())
{
std::string fieldValue = inputFields[key];
field.Call("SetText", fieldValue.c_str());
}
if ("dateForm" == type && inputFields[key].is_string())
{
std::string fieldValue = inputFields[key];
field.Call("SetTime", (double)parseDateToUTCMilliseconds(fieldValue));
}
}
std::wstring filePath = CAITools::getInstance().getTempFile() + L".pdf";
builder.SaveFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF, filePath.c_str());
builder.CloseFile();
return "[file]" + U_TO_UTF8(filePath);
}
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "../../tools.h"
#ifndef JSON_HAS_CPP_11
#define JSON_HAS_CPP_11
#endif
#include "./json.hpp"
using namespace nlohmann;
#include "../../../../../../core/DesktopEditor/doctrenderer/docbuilder.h"
using namespace NSDoctRenderer;
#include "../../../../../../core/DesktopEditor/common/File.h"
#include "../../../../../../core/Common/OfficeFileFormats.h"
static void initBuilder(CDocBuilder* builder)
{
std::wstring allFontsJS = CAITools::getInstance().getFontsDirectory() + L"/AllFonts.js";
builder->SetProperty("--all-fonts-path", allFontsJS.c_str());
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "./base.h"
#include "../form_field_analyser.cpp"
#include "../form_field_filler.cpp"
struct TFuncInstance
{
std::string name;
std::function<std::string(std::string)> func;
TFuncInstance(const std::string& n, std::function<std::string(const std::string&)> f)
: name(n), func(f) {}
};
class CFunctions
{
public:
std::map<std::string, TFuncInstance> m_funcs;
CFunctions()
{
m_funcs.insert(std::make_pair("form_field_analyser", TFuncInstance(form_field_analyser::description(), form_field_analyser::main)));
m_funcs.insert(std::make_pair("form_field_filler", TFuncInstance(form_field_filler::description(), form_field_filler::main)));
}
};

View File

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
import os
import sys
from pathlib import Path
def generate_header_file(folder_path, output_path="./funcs.h"):
if not os.path.exists(folder_path):
return False
cpp_files = []
for file in os.listdir(folder_path):
if file.endswith('.cpp'):
filename_without_ext = os.path.splitext(file)[0]
cpp_files.append(filename_without_ext)
header_content = generate_header_content(cpp_files)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(header_content)
return
def generate_header_content(cpp_files):
content = "#pragma once\n"
content += "#include \"./base.h\"\n"
for cpp_file in cpp_files:
content += f"#include \"../{cpp_file}.cpp\"\n"
content += """
struct TFuncInstance
{
\tstd::string name;
\tstd::function<std::string(std::string)> func;
\tTFuncInstance(const std::string& n, std::function<std::string(const std::string&)> f)
\t\t: name(n), func(f) {}
};
class CFunctions
{
public:
\tstd::map<std::string, TFuncInstance> m_funcs;
\tCFunctions()
\t{
"""
for cpp_file in cpp_files:
content += f'\t\tm_funcs.insert(std::make_pair("{cpp_file}", TFuncInstance({cpp_file}::description(), {cpp_file}::main)));\n'
content += "\t}\n};\n"
return content
def main():
generate_header_file("./..", "./funcs.h")
return
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* 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
*
*/
#include "./tools.h"
#include "../../../../core/DesktopEditor/doctrenderer/docbuilder.h"
#include "../../../../core/DesktopEditor/common/File.h"
#include "./functions/internal/funcs.h"
CAITools::CAITools()
{
m_funcs = new CFunctions();
}
CAITools::~CAITools()
{
delete m_funcs;
}
CAITools& CAITools::getInstance()
{
static CAITools tools;
return tools;
}
void CAITools::setWorkDirectory(const std::wstring& dir)
{
m_workDirectory = dir;
NSDoctRenderer::CDocBuilder::Initialize(m_workDirectory.c_str());
}
std::wstring CAITools::getWorkDirectory()
{
return m_workDirectory;
}
void CAITools::setFontsDirectory(const std::wstring& dir)
{
m_fontsDirectory = dir;
}
std::wstring CAITools::getFontsDirectory()
{
return m_fontsDirectory;
}
std::wstring CAITools::getTempFile()
{
std::wstring sDirTmp = NSFile::CFileBinary::GetTempPath();
std::wstring sFileTmp = NSFile::CFileBinary::CreateTempFileWithUniqueName(sDirTmp, L"IMG");
if (NSFile::CFileBinary::Exists(sFileTmp))
NSFile::CFileBinary::Remove(sFileTmp);
return sFileTmp;
}
std::string CAITools::getFunctions()
{
std::string sResult = "";
for (std::map<std::string, TFuncInstance>::iterator iter = m_funcs->m_funcs.begin(); iter != m_funcs->m_funcs.end(); iter++)
{
sResult += iter->second.name;
sResult += "\n";
}
return sResult;
}
std::string CAITools::callFunc(const std::string& name, const std::string& arg)
{
auto find = m_funcs->m_funcs.find(name);
if (find !=m_funcs->m_funcs.end())
return find->second.func(arg);
return "";
}

View File

@ -0,0 +1,63 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* 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
*
*/
#pragma once
#include <string>
#include <string.h>
#include <map>
#include <functional>
class CFunctions;
class CAITools
{
private:
CAITools();
~CAITools();
std::wstring m_workDirectory;
std::wstring m_fontsDirectory;
CFunctions* m_funcs;
public:
static CAITools& getInstance();
void setWorkDirectory(const std::wstring& dir);
std::wstring getWorkDirectory();
void setFontsDirectory(const std::wstring& dir);
std::wstring getFontsDirectory();
std::wstring getTempFile();
std::string callFunc(const std::string& name, const std::string& arg);
std::string getFunctions();
};