Merge branch 'bugfix/ai-agent' of git.onlyoffice.com:ONLYOFFICE/desktop-sdk into bugfix/ai-agent

This commit is contained in:
Timofey
2025-11-14 15:07:35 +08:00
13 changed files with 679 additions and 26 deletions

View File

@ -1614,6 +1614,9 @@ public:
// показывать ли консоль для дебага
bool m_bDebugInfoSupport;
// логгировать ли урлы
bool m_bLoggingBrowserUrls;
bool m_bSupportMultiplugins;
// экспериментальные возможности
@ -1749,6 +1752,7 @@ public:
m_bDebugInfoSupport = false;
m_bExperimentalFeatures = false;
m_bSupportMultiplugins = false;
m_bLoggingBrowserUrls = false;
m_bIsUseExternalMessageLoop = false;
m_pExternalMessageLoop = NULL;
@ -2009,6 +2013,10 @@ public:
if (pairComplexPlugins != _map->end() && "1" == pairComplexPlugins->second)
m_bSupportMultiplugins = true;
std::map<std::string, std::string>::iterator pairLogUrls = _map->find("log-browser-urls");
if (pairLogUrls != _map->end() && "1" == pairLogUrls->second)
m_bLoggingBrowserUrls = true;
if (!NSCommon::CSystemWindowScale::IsInit())
{
std::map<std::string, std::string>::iterator pairUseSystemScale = _map->find("system-scale");

View File

@ -1979,7 +1979,7 @@ public:
if (0 == sTest.find(L"regex:"))
{
std::wstring sTestRegex = sTest.substr(6);
boost::wregex oRegEx(sTestRegex);
boost::wregex oRegEx(sTestRegex, boost::regex::icase);
if (boost::regex_search(sUrl, oRegEx))
return true;
}
@ -2242,6 +2242,16 @@ public:
std::wstring sFrameUrl = L"";
if (frame)
sFrameUrl = frame->GetURL().ToWString();
if (m_pParent->m_pInternal->m_pManager->m_pInternal->m_bLoggingBrowserUrls)
{
CCefView* pMainView = m_pParent->m_pInternal->m_pManager->m_pInternal->GetViewForSystemMessages();
if (pMainView)
{
pMainView->ExecuteInAllFrames("console.log(\"" + target_url.ToString() + "\");", true);
}
}
CheckPopup(target_url.ToWString(), false, (WOD_NEW_BACKGROUND_TAB == target_disposition) ? true : false, false, sFrameUrl);
return true;
}
@ -2271,6 +2281,15 @@ public:
{
std::wstring sUrl = request->GetURL().ToWString();
if (m_pParent->m_pInternal->m_pManager->m_pInternal->m_bLoggingBrowserUrls)
{
CCefView* pMainView = m_pParent->m_pInternal->m_pManager->m_pInternal->GetViewForSystemMessages();
if (pMainView)
{
pMainView->ExecuteInAllFrames("console.log(\"" + U_TO_UTF8(sUrl) + "\");", true);
}
}
if (0 == sUrl.find(L"mailto"))
{
// disable navigation

View File

@ -4604,6 +4604,13 @@ window.AscDesktopEditor.CallInFrame(\"" +
}
else if (name == "_createProcess")
{
std::string sCurrentUrl = CefV8Context::GetCurrentContext()->GetFrame()->GetURL().ToString();
if (0 != sCurrentUrl.find("onlyoffice://"))
{
retval = CefV8Value::CreateInt(-1);
return true;
}
if (!m_external_processes)
m_external_processes = new NSProcesses::CProcessManager(this);
@ -5279,6 +5286,11 @@ window.AscDesktopEditor.CallInFrame(\"" +
return files;
}
virtual void ExecuteJS(const std::string& code)
{
CefV8Context::GetCurrentContext()->GetFrame()->ExecuteJavaScript(code, "", 0);
}
// Provide the reference counting implementation for this class.
IMPLEMENT_REFCOUNTING(CAscEditorNativeV8Handler);
};

View File

@ -6,6 +6,7 @@
#include <thread>
#include <atomic>
#include <vector>
#include <sstream>
#ifdef _WIN32
#include <windows.h>
@ -16,7 +17,6 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sstream>
#include <iomanip>
#endif
@ -32,6 +32,7 @@ extern char **environ;
#include "../../../../../core/DesktopEditor/common/File.h"
#include "../../../../../core/DesktopEditor/graphics/TemporaryCS.h"
#include "../../../../../core/DesktopEditor/graphics/BaseThread.h"
#include "../../../../../core/DesktopEditor/common/SystemUtils.h"
namespace NSProcesses
{
@ -188,7 +189,7 @@ namespace NSProcesses
{
std::string lineBuf;
char buf[4096];
#ifdef _WIN32
DWORD n;
#else
@ -239,22 +240,260 @@ namespace NSProcesses
m_callback->process_callback(m_id, type, lineBuf);
}
#ifdef _WIN32
std::wstring getPathVariable()
{
std::wstring pathEnv = NSSystemUtils::GetEnvVariable(L"PATH");
std::wstring systemEnv = L"";
std::wstring userEnv = L"";
if (true)
{
HKEY hKey;
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
DWORD size = 0;
RegQueryValueExW(hKey, L"PATH", nullptr, nullptr, nullptr, &size);
if (size > 0)
{
int charCount = (size / sizeof(wchar_t)) + 1;
wchar_t* buffer = new wchar_t[charCount];
if (RegQueryValueExW(hKey, L"PATH", nullptr, nullptr, (LPBYTE)buffer, &size) == ERROR_SUCCESS)
{
buffer[charCount - 1] = '\0';
userEnv = std::wstring(buffer);
}
delete [] buffer;
}
RegCloseKey(hKey);
}
}
if (true)
{
HKEY hKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
DWORD size = 0;
RegQueryValueExW(hKey, L"PATH", nullptr, nullptr, nullptr, &size);
if (size > 0)
{
int charCount = (size / sizeof(wchar_t)) + 1;
wchar_t* buffer = new wchar_t[charCount];
if (RegQueryValueExW(hKey, L"PATH", nullptr, nullptr, (LPBYTE)buffer, &size) == ERROR_SUCCESS)
{
buffer[charCount - 1] = '\0';
systemEnv = std::wstring(buffer);
}
delete [] buffer;
}
RegCloseKey(hKey);
}
}
std::wstring result;
if (!userEnv.empty())
result = userEnv;
if (!systemEnv.empty())
{
if (!result.empty())
result += L";";
result += systemEnv;
}
if (!pathEnv.empty())
{
if (!result.empty())
result += L";";
result += pathEnv;
}
return result;
}
std::map<std::wstring, std::wstring> getEnv()
{
std::map<std::wstring, std::wstring> env;
wchar_t* envStrings = GetEnvironmentStringsW();
if (!envStrings)
return env;
wchar_t* current = envStrings;
while (*current != L'\0')
{
size_t len = wcslen(current) + 1; // +1 for \0
std::wstring all(current, len - 1);
auto pos = all.find('=');
if (pos != std::wstring::npos)
{
std::wstring keyName = all.substr(0, pos);
std::wstring value = all.substr(pos + 1);
if (keyName == L"PATH" || keyName == L"Path")
{
std::wstring systemPath = getPathVariable();
if (!systemPath.empty())
{
if (!value.empty())
value += L";";
value += systemPath;
}
}
if (!keyName.empty())
env[keyName] = value;
}
current += len;
}
FreeEnvironmentStringsW(envStrings);
return env;
}
std::wstring findBinary(const std::wstring& cmd)
{
if (cmd.empty())
return cmd;
std::vector<std::wstring> extensions = {L"", L".exe", L".bat"};
if (true)
{
for (const auto& ext : extensions)
{
std::wstring test = cmd + ext;
DWORD attr = GetFileAttributesW(test.c_str());
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
return test;
}
}
std::wstring pathEnv = getPathVariable();
std::wistringstream iss(pathEnv);
std::wstring dir;
while (std::getline(iss, dir, L';'))
{
if (dir.empty())
continue;
if (!dir.empty() && dir.front() == '"')
dir = dir.substr(1);
if (!dir.empty() && dir.back() == '"')
dir.pop_back();
if (!dir.empty() && dir.back() != '\\' && dir.back() != '/')
dir += L"\\";
// Проверяем с разными расширениями
for (const auto& ext : extensions)
{
std::wstring test = dir + cmd + ext;
DWORD attr = GetFileAttributesW(test.c_str());
if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
return test;
}
}
return cmd;
}
#endif
#ifdef _LINUX
std::string getShellPath()
{
std::array<char, 1024> buffer;
std::string result;
const char* shell = getenv("SHELL");
if (!shell) {
#ifdef _MAC
shell = "/bin/zsh";
#else
shell = "/bin/bash";
#endif
}
std::string shellPath = shell;
std::string cmd;
// fish
if (shellPath.find("fish") != std::string::npos)
{
cmd = std::string(shell) + " -l -c 'echo $PATH' 2>/dev/null";
}
else
{
cmd = std::string(shell) + " -l -i -c 'echo $PATH' 2>/dev/null";
}
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe)
return "";
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr)
{
result += buffer.data();
}
pclose(pipe);
if (!result.empty() && result.back() == '\n')
{
result.pop_back();
}
return result;
}
std::string getPathVariable()
{
std::string pathEnv = "";
const char* pathEnvPtr = std::getenv("PATH");
if (pathEnvPtr)
pathEnv = std::string(pathEnvPtr);
std::string systemPath = getShellPath();
std::string pathValue = systemPath;
if (!pathEnv.empty())
{
if (!pathValue.empty())
pathValue += ":";
pathValue += pathEnv;
}
if (!pathValue.empty())
pathValue += ":";
pathValue += "/usr/bin:/bin:/usr/local/bin:/opt/homebrew/bin";
return pathValue;
}
std::string findBinary(const std::string& cmd)
{
if (!cmd.empty() && access(cmd.c_str(), X_OK) == 0)
return cmd;
const char* pathEnv = std::getenv("PATH");
if (!pathEnv)
return cmd;
std::string sPathEnv(pathEnv);
if (!sPathEnv.empty())
sPathEnv += ":";
sPathEnv += "/usr/bin:/bin:/usr/local/bin:/opt/homebrew/bin";
std::string sPathEnv = getPathVariable();
std::istringstream iss(sPathEnv);
std::string dir;
while (std::getline(iss, dir, ':'))
@ -289,21 +528,35 @@ namespace NSProcesses
si.hStdError = m_hStdErrWr;
si.dwFlags |= STARTF_USESTDHANDLES;
std::wstring envBlock;
std::map<std::wstring, std::wstring> env = getEnv();
for (auto& kv : m_env)
{
envBlock += (UTF8_TO_U((kv.first)) + L"=" + UTF8_TO_U((kv.second)));
env[UTF8_TO_U((kv.first))] = UTF8_TO_U((kv.second));
}
env[L"LANG"] = L"C.UTF-8";
std::wstring envBlock;
for (auto& kv : env)
{
envBlock += kv.first + L"=" + kv.second;
envBlock.push_back(L'\0');
}
envBlock += L"LANG=C.UTF-8\0";
envBlock.push_back(L'\0');
std::wstring commandW = UTF8_TO_U(m_command);
if (!CreateProcessW(nullptr, (LPWSTR)commandW.c_str(), nullptr, nullptr, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
std::wstring prog = commandW;
std::wstring::size_type posProg = commandW.find(L" ");
if (posProg != std::wstring::npos)
prog = commandW.substr(0, posProg);
prog = findBinary(prog);
if (prog == commandW)
prog = L"";
if (!CreateProcessW(prog.empty() ? nullptr : prog.c_str(), (LPWSTR)commandW.c_str(), nullptr, nullptr, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
(LPVOID)(envBlock.c_str()), nullptr, &si, &m_pi))
{
DWORD dwError = GetLastError();
m_callback->process_callback(m_id, StreamType::Terminate, "");
return;
}
@ -366,7 +619,9 @@ namespace NSProcesses
for (auto& s : args)
argv.push_back(const_cast<char*>(s.c_str()));
argv.push_back(nullptr);
std::string systemPath = getPathVariable();
std::map<std::string, std::string> mergedEnv;
for (char **env = environ; *env; ++env)
{
@ -374,7 +629,17 @@ namespace NSProcesses
auto pos = s.find('=');
if (pos != std::string::npos)
{
mergedEnv[s.substr(0, pos)] = s.substr(pos + 1);
std::string keyName = s.substr(0, pos);
std::string value = s.substr(pos + 1);
if (keyName == "PATH" && !systemPath.empty())
{
if (!value.empty())
value += ":";
value += systemPath;
}
mergedEnv[keyName] = value;
}
}
for (auto &kv : m_env)
@ -412,11 +677,11 @@ namespace NSProcesses
std::thread t_out = std::thread([this]()
{
readOutLoop(m_stdoutPipe[0], StreamType::StdOut);
readOutLoop(m_stdoutPipe[0], StreamType::StdOut);
});
std::thread t_err = std::thread([this]()
{
readOutLoop(m_stderrPipe[0], StreamType::StdErr);
readOutLoop(m_stderrPipe[0], StreamType::StdErr);
});
#endif

View File

@ -1,5 +1,10 @@
#include "./../internal/base.h"
#include "../../../src/x2t.h"
#include "../../../../../../core/DesktopEditor/common/Directory.h"
#include "../../../../../../core/Common/OfficeFileFormatChecker.h"
//#include "../../../../../../core/DesktopEditor/graphics/BaseThread.h"
namespace file_content_reader
{
std::string description()
@ -28,13 +33,153 @@ namespace file_content_reader
}";
}
class CConverter
{
public:
std::wstring m_sInputFile;
std::wstring m_sOutputFile;
std::wstring m_sTempDirectory;
int m_nOutputFormat;
CAIToolsHelper* m_pHelper;
public:
CConverter()
{
m_sTempDirectory = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSDirectory::GetTempPath(), L"CV");
if (NSFile::CFileBinary::Exists(m_sTempDirectory))
NSFile::CFileBinary::Remove(m_sTempDirectory);
NSDirectory::CreateDirectory(m_sTempDirectory);
m_sOutputFile = m_sTempDirectory + L"/output";
}
~CConverter()
{
NSDirectory::DeleteDirectory(m_sTempDirectory);
}
int Convert()
{
CAITools& tools = CAITools::getInstance();
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteString(L"<?xml version=\"1.0\" encoding=\"utf-8\"?><TaskQueueDataConvert><m_sFileFrom>");
oBuilder.WriteEncodeXmlString(m_sInputFile);
oBuilder.WriteString(L"</m_sFileFrom><m_sFileTo>");
oBuilder.WriteEncodeXmlString(m_sOutputFile);
oBuilder.WriteString(L"</m_sFileTo><m_nFormatTo>");
std::wstring sAdditionXml = L"";
if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA == m_nOutputFormat)
{
m_nOutputFormat = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF;
sAdditionXml = L"<m_bIsPDFA>true</m_bIsPDFA>";
}
oBuilder.WriteString(std::to_wstring(m_nOutputFormat));
oBuilder.WriteString(L"</m_nFormatTo><m_sFontDir>");
oBuilder.WriteEncodeXmlString(tools.getFontsDirectory());
oBuilder.WriteString(L"</m_sFontDir>");
oBuilder.WriteString(L"<m_bIsNoBase64>false</m_bIsNoBase64>");
oBuilder.WriteString(L"<m_sAllFontsPath>");
oBuilder.WriteEncodeXmlString(tools.getFontsDirectory());
oBuilder.WriteString(L"/AllFonts.js</m_sAllFontsPath>");
oBuilder.WriteString(L"<m_sTempDir>");
oBuilder.WriteEncodeXmlString(m_sTempDirectory);
oBuilder.WriteString(L"</m_sTempDir>");
oBuilder.WriteString(L"<m_nCsvTxtEncoding>46</m_nCsvTxtEncoding>");
if (!sAdditionXml.empty())
oBuilder.WriteString(sAdditionXml);
if (m_nOutputFormat & AVS_OFFICESTUDIO_FILE_IMAGE)
{
oBuilder.WriteString(L"<m_oThumbnail><first>false</first>");
if (m_nOutputFormat == AVS_OFFICESTUDIO_FILE_IMAGE_JPG)
oBuilder.WriteString(L"<format>3</format>");
oBuilder.WriteString(L"</m_oThumbnail>");
}
oBuilder.WriteString(L"</TaskQueueDataConvert>");
std::wstring sTempFileForParams = m_sTempDirectory + L"/params_simple_converter.xml";
NSFile::CFileBinary::SaveToFile(sTempFileForParams, oBuilder.GetData(), true);
CAscApplicationManager manager;
int nReturnCode = NSX2T::Convert(tools.getWorkDirectory() + L"/x2t", sTempFileForParams, &manager, false);
return nReturnCode;
}
};
std::string main(const std::string& arg, CAIToolsHelper* helper)
{
json returnValue = json::object();
returnValue["role"] = "tool";
returnValue["status"] = "error";
returnValue["error_message"] = "TODO: method no realized";
returnValue["content"] = "";
return returnValue.dump();
json param = json::parse(arg);
if (!param.contains("path") || !param["path"].is_string())
{
returnValue["status"] = "error";
returnValue["error_message"] = "The file was not opened.";
returnValue["content"] = "";
return returnValue.dump();
}
else
{
std::string path = param["path"];
std::wstring pathW = UTF8_TO_U(path);
COfficeFileFormatChecker checker;
if (!checker.isOfficeFile(pathW))
{
returnValue["status"] = "error";
returnValue["error_message"] = "The file was not opened.";
returnValue["content"] = "";
return returnValue.dump();
}
std::string content;
if (checker.nFileType == AVS_OFFICESTUDIO_FILE_DOCUMENT_MD ||
checker.nFileType == AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT ||
checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV)
{
NSFile::CFileBinary::ReadAllTextUtf8A(pathW, content);
}
else
{
CConverter converter;
converter.m_pHelper = helper;
converter.m_sInputFile = pathW;
converter.m_nOutputFormat = AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT;
if (checker.nFileType & AVS_OFFICESTUDIO_FILE_SPREADSHEET)
converter.m_nOutputFormat = AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV;
int nResult = converter.Convert();
if (0 != nResult)
{
returnValue["status"] = "error";
returnValue["error_message"] = "The file was not opened.";
returnValue["content"] = "";
return returnValue.dump();
}
returnValue["status"] = "success";
NSFile::CFileBinary::ReadAllTextUtf8A(converter.m_sOutputFile, content);
}
returnValue["content"] = content;
return returnValue.dump();
}
}
}

View File

@ -0,0 +1,15 @@
{
"type": "function",
"name": "generate_docx",
"description": "Use this function if you are asked to generate a textual document (report, article, letter, etc.) based on a description. Input: a detailed description of what needs to be generated.",
"parameters": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "Detailed description of the document to generate, including its topic, structure, tone, and format."
}
},
"required": ["description"]
}
}

View File

@ -0,0 +1,45 @@
#include "./../internal/base.h"
namespace generate_docx
{
std::string description()
{
return "\
{\
\"type\": \"function\",\
\"name\": \"generate_docx\",\
\"description\": \"Use this function if you are asked to generate a textual document (report, article, letter, etc.) based on a description. Input: a detailed description of what needs to be generated.\",\
\"parameters\": {\
\"type\": \"object\",\
\"properties\": {\
\"description\": {\
\"type\": \"string\",\
\"description\": \"Detailed description of the document to generate, including its topic, structure, tone, and format.\"\
}\
},\
\"required\": [\"description\"]\
}\
}";
}
std::string main(const std::string& arg, CAIToolsHelper* helper)
{
json returnValue = json::object();
json param = json::parse(arg);
if (!param.contains("description") || !param["description"].is_string())
{
returnValue["status"] = "error";
}
else
{
std::string description = param["description"];
std::string code = "window.AscDesktopEditor.generateNew(\"docx\", \"ai-gen-docx\", " + json(description).dump() + ");";
helper->ExecuteJS(code);
returnValue["status"] = "success";
}
return returnValue.dump();
}
}

View File

@ -0,0 +1,15 @@
{
"type": "function",
"name": "generate_form",
"description": "Use this function if you are asked to generate a form or document template (contract, any document for filling) based on a description. Input: a detailed description of the desired form or template.",
"parameters": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "Detailed description of the form or template to generate, including purpose, structure."
}
},
"required": ["description"]
}
}

View File

@ -0,0 +1,45 @@
#include "./../internal/base.h"
namespace generate_form
{
std::string description()
{
return "\
{\
\"type\": \"function\",\
\"name\": \"generate_form\",\
\"description\": \"Use this function if you are asked to generate a form or document template (contract, any document for filling) based on a description. Input: a detailed description of the desired form or template.\",\
\"parameters\": {\
\"type\": \"object\",\
\"properties\": {\
\"description\": {\
\"type\": \"string\",\
\"description\": \"Detailed description of the form or template to generate, including purpose, structure.\"\
}\
},\
\"required\": [\"description\"]\
}\
}";
}
std::string main(const std::string& arg, CAIToolsHelper* helper)
{
json returnValue = json::object();
json param = json::parse(arg);
if (!param.contains("description") || !param["description"].is_string())
{
returnValue["status"] = "error";
}
else
{
std::string description = param["description"];
std::string code = "window.AscDesktopEditor.generateNew(\"pdf\", \"ai-gen-form\", " + json(description).dump() + ");";
helper->ExecuteJS(code);
returnValue["status"] = "success";
}
return returnValue.dump();
}
}

View File

@ -0,0 +1,23 @@
{
"type": "function",
"name": "generate_pptx",
"description": "Use this function if you are asked to generate a complete presentation with a custom theme, fonts, and streaming content. Input: a detailed description of the presentation to create, including topic, number of slides, and style.",
"parameters": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"description": "Presentation topic."
},
"slideCount": {
"type": "string",
"description": "Number of slides to generate."
},
"style": {
"type": "string",
"description": "Visual style of the presentation: modern, classic, minimal, or corporate."
}
},
"required": []
}
}

View File

@ -0,0 +1,53 @@
#include "./../internal/base.h"
namespace generate_pptx
{
std::string description()
{
return "\
{\
\"type\": \"function\",\
\"name\": \"generate_pptx\",\
\"description\": \"Use this function if you are asked to generate a complete presentation with a custom theme, fonts, and streaming content. Input: a detailed description of the presentation to create, including topic, number of slides, and style.\",\
\"parameters\": {\
\"type\": \"object\",\
\"properties\": {\
\"topic\": {\
\"type\": \"string\",\
\"description\": \"Presentation topic.\"\
},\
\"slideCount\": {\
\"type\": \"string\",\
\"description\": \"Number of slides to generate.\"\
},\
\"style\": {\
\"type\": \"string\",\
\"description\": \"Visual style of the presentation: modern, classic, minimal, or corporate.\"\
}\
},\
\"required\": []\
}\
}";
}
std::string main(const std::string& arg, CAIToolsHelper* helper)
{
json returnValue = json::object();
json param = json::parse(arg);
if (!param.is_object())
{
returnValue["status"] = "error";
}
else
{
std::string value = json(param).dump();
std::string code = "window.AscDesktopEditor.generateNew(\"pptx\", \"ai-gen-pptx\", " + json(value).dump() + ");";
helper->ExecuteJS(code);
returnValue["status"] = "success";
}
return returnValue.dump();
}
}

View File

@ -5,6 +5,9 @@
#include "../folder_content_reader/main.cpp"
#include "../form_field_analyser/main.cpp"
#include "../form_field_filler/main.cpp"
#include "../generate_docx/main.cpp"
#include "../generate_form/main.cpp"
#include "../generate_pptx/main.cpp"
#include "../recent_files_reader/main.cpp"
struct TFuncInstance
@ -26,6 +29,9 @@ public:
m_funcs.insert(std::make_pair("folder_content_reader", TFuncInstance(folder_content_reader::description(), folder_content_reader::main)));
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)));
m_funcs.insert(std::make_pair("generate_docx", TFuncInstance(generate_docx::description(), generate_docx::main)));
m_funcs.insert(std::make_pair("generate_form", TFuncInstance(generate_form::description(), generate_form::main)));
m_funcs.insert(std::make_pair("generate_pptx", TFuncInstance(generate_pptx::description(), generate_pptx::main)));
m_funcs.insert(std::make_pair("recent_files_reader", TFuncInstance(recent_files_reader::description(), recent_files_reader::main)));
}
};

View File

@ -65,6 +65,8 @@ public:
virtual void OpenTemplate(const std::wstring& path, const std::wstring& name = L"") = 0;
virtual void OpenFile(const std::wstring& path) = 0;
virtual std::vector<CRecentFileInfo> GetRecents() = 0;
virtual void ExecuteJS(const std::string& code) = 0;
};
class CFunctions;