11#include <config_buildconfig.h>
12#include <config_features.h>
21#include <unicode/udata.h>
22#include <unicode/ucnv.h>
24#import <Foundation/Foundation.h>
25#import <CoreGraphics/CoreGraphics.h>
29#undef HAVE_MALLOC_TRIM
35# define HAVE_MALLOC_TRIM
40#include <osl/detail/android-bootstrap.h>
44#include <osl/detail/emscripten-bootstrap.h>
52#include <boost/property_tree/json_parser.hpp>
53#include <boost/algorithm/string.hpp>
55#include <LibreOfficeKit/LibreOfficeKit.h>
56#include <LibreOfficeKit/LibreOfficeKitEnums.h>
65#include <osl/file.hxx>
66#include <osl/process.h>
67#include <osl/thread.h>
68#include <rtl/bootstrap.hxx>
69#include <rtl/strbuf.hxx>
87#include <com/sun/star/document/MacroExecMode.hpp>
88#include <com/sun/star/beans/XPropertySet.hpp>
89#include <com/sun/star/container/XNameAccess.hpp>
90#include <com/sun/star/document/XDocumentLanguages.hpp>
91#include <com/sun/star/frame/Desktop.hpp>
92#include <com/sun/star/frame/DispatchResultEvent.hpp>
93#include <com/sun/star/frame/DispatchResultState.hpp>
94#include <com/sun/star/frame/XDispatchProvider.hpp>
95#include <com/sun/star/frame/XDispatchResultListener.hpp>
96#include <com/sun/star/frame/XSynchronousDispatch.hpp>
97#include <com/sun/star/frame/XStorable.hpp>
98#include <com/sun/star/lang/Locale.hpp>
99#include <com/sun/star/lang/XComponent.hpp>
100#include <com/sun/star/lang/XMultiServiceFactory.hpp>
101#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
102#include <com/sun/star/util/URLTransformer.hpp>
103#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
104#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
105#include <com/sun/star/datatransfer/XTransferable2.hpp>
106#include <com/sun/star/text/TextContentAnchorType.hpp>
107#include <com/sun/star/document/XRedlinesSupplier.hpp>
108#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
110#include <com/sun/star/xml/crypto/SEInitializer.hpp>
111#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
112#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
113#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
114#include <com/sun/star/security/XCertificate.hpp>
116#include <com/sun/star/linguistic2/LanguageGuessing.hpp>
117#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
118#include <com/sun/star/linguistic2/XSpellChecker.hpp>
119#include <com/sun/star/i18n/LocaleCalendar2.hpp>
120#include <com/sun/star/i18n/ScriptType.hpp>
121#include <com/sun/star/lang/DisposedException.hpp>
140#include <svx/strings.hrc>
142#include <svx/svxids.hrc>
163#include <unicode/uchar.h>
171#include <osl/module.hxx>
184#include <com/sun/star/document/XUndoManager.hpp>
185#include <com/sun/star/document/XUndoManagerSupplier.hpp>
186#include <com/sun/star/document/XLinkTargetSupplier.hpp>
193#include "../app/cmdlineargs.hxx"
195#include "../app/sofficemain.h"
196#include "../app/officeipcthread.hxx"
201#include <officecfg/Office/Common.hxx>
202#include <officecfg/Office/Impress.hxx>
203#include <officecfg/Office/Linguistic.hxx>
220#include <officecfg/Setup.hxx>
221#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
236 SAL_WARN_IF(!s.isEmpty(),
"lok",
"lok exception '" + s +
"'");
246 const char *filterName;
251 static const int dumpTimeoutMS = 5000;
254 TraceEventDumper() :
AutoTimer(
"Trace Event dumper" )
260 virtual void Invoke()
override
265 static void flushRecordings()
267 const css::uno::Sequence<OUString> aEvents =
269 OStringBuffer aOutput;
270 for (
const auto &s : aEvents)
275 if (aOutput.getLength() > 0)
277 OString aChunk = aOutput.makeStringAndClear();
290 {
"doc",
"MS Word 97" },
291 {
"docm",
"MS Word 2007 XML VBA" },
292 {
"docx",
"MS Word 2007 XML" },
293 {
"fodt",
"OpenDocument Text Flat XML" },
294 {
"html",
"HTML (StarWriter)" },
295 {
"odt",
"writer8" },
296 {
"ott",
"writer8_template" },
297 {
"pdf",
"writer_pdf_Export" },
299 {
"rtf",
"Rich Text Format" },
301 {
"xhtml",
"XHTML Writer File" },
302 {
"png",
"writer_png_Export" },
303 {
"xml",
"writer_indexing_export" },
309 {
"csv",
"Text - txt - csv (StarCalc)" },
310 {
"fods",
"OpenDocument Spreadsheet Flat XML" },
311 {
"html",
"HTML (StarCalc)" },
313 {
"ots",
"calc8_template" },
314 {
"pdf",
"calc_pdf_Export" },
315 {
"xhtml",
"XHTML Calc File" },
316 {
"xls",
"MS Excel 97" },
317 {
"xlsm",
"Calc MS Excel 2007 VBA XML" },
318 {
"xlsx",
"Calc MS Excel 2007 XML" },
319 {
"png",
"calc_png_Export" },
325 {
"fodp",
"OpenDocument Presentation Flat XML" },
326 {
"html",
"impress_html_Export" },
327 {
"odg",
"impress8_draw" },
328 {
"odp",
"impress8" },
329 {
"otp",
"impress8_template" },
330 {
"pdf",
"impress_pdf_Export" },
331 {
"potm",
"Impress MS PowerPoint 2007 XML Template" },
332 {
"pot",
"MS PowerPoint 97 Vorlage" },
333 {
"pptm",
"Impress MS PowerPoint 2007 XML VBA" },
334 {
"pptx",
"Impress MS PowerPoint 2007 XML" },
335 {
"pps",
"MS PowerPoint 97 Autoplay" },
336 {
"ppt",
"MS PowerPoint 97" },
337 {
"svg",
"impress_svg_Export" },
338 {
"xhtml",
"XHTML Impress File" },
339 {
"png",
"impress_png_Export"},
345 {
"fodg",
"draw_ODG_FlatXML" },
346 {
"html",
"draw_html_Export" },
348 {
"pdf",
"draw_pdf_Export" },
349 {
"svg",
"draw_svg_Export" },
350 {
"xhtml",
"XHTML Draw File" },
351 {
"png",
"draw_png_Export"},
357 if (pString ==
nullptr)
360 std::string_view sString(pString, strlen(pString));
361 return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
367 char* pMemory =
static_cast<char*
>(malloc(rStr.getLength() + 1));
369 memcpy(pMemory, rStr.getStr(), rStr.getLength() + 1);
386 OUString aWorkingDir;
387 osl_getProcessWorkingDir(&aWorkingDir.pData);
388 if (!aWorkingDir.endsWith(
"/"))
393 return rtl::Uri::convertRelToAbs(aWorkingDir,
aURL);
395 catch (
const rtl::MalformedUriException &)
405 if (pJSON && pJSON[0] !=
'\0')
416 const sal_uLong nLinks = aNames.getLength();
417 const OUString* pNames = aNames.getConstArray();
418 const OUString aProp_LinkDisplayName(
"LinkDisplayName" );
419 const OUString aProp_LinkTarget(
"com.sun.star.document.LinkTarget" );
420 bool bIsTarget =
false;
424 OUString aLink( *pNames++ );
429 aAny = xLinks->getByName( aLink );
431 catch(
const uno::Exception&)
446 aAny =
xTarget->getPropertyValue( aProp_LinkDisplayName );
447 OUString aDisplayName;
448 aAny >>= aDisplayName;
449 OUString aStrDisplayname ( aDisplayName );
453 jsonText.append(
"\"");
454 jsonText.append(aStrDisplayname);
455 jsonText.append(
"\": \"");
456 jsonText.append(aLink);
457 jsonText.append(
"\"");
460 jsonText.append(
", ");
466 bIsTarget = xSI->supportsService( aProp_LinkTarget );
470 jsonText.append(
"}");
473 jsonText.append(
", ");
476 jsonText.append(
"\"");
477 jsonText.append(aStrDisplayname);
478 jsonText.append(
"\": ");
482 jsonText.append(
"true");
485 jsonText.append(
"{");
496 SAL_WARN(
"lok",
"extractLinks: Exception");
506 OUString aType = anyItem.getValueTypeName();
507 rJson.
put(
"type", aType);
509 if (aType ==
"string")
510 rJson.
put(
"value", anyItem.get<OUString>());
511 else if (aType ==
"unsigned long")
512 rJson.
put(
"value", OString::number(anyItem.get<sal_uInt32>()));
513 else if (aType ==
"long")
514 rJson.
put(
"value", OString::number(anyItem.get<sal_Int32>()));
515 else if (aType ==
"[]any")
518 if (anyItem >>=
aSeq)
520 auto valueNode = rJson.
startNode(
"value");
522 for (
auto i = 0;
i <
aSeq.getLength(); ++
i)
537 if (rPayload.startsWith(
"EMPTY"))
542 int nSeparatorPos = rPayload.indexOf(
',', 6);
543 bool bHasMode = nSeparatorPos > 0;
547 assert(rPayload.getLength() > nSeparatorPos);
561 const char*
pos = rPayload.getStr();
562 const char*
end = rPayload.getStr() + rPayload.getLength();
587 nPart = rtl_str_toInt64_WithLength(
pos, 10,
end -
pos);
589 while( *
pos && *
pos !=
',' )
595 nMode = rtl_str_toInt64_WithLength(
pos, 10,
end -
pos);
607 if (nWidth <= 0 || nHeight <= 0)
624 if (nWidth > 0 && nHeight > 0)
649 PayloadObject = rRectAndPart;
650 PayloadString.clear();
657 if(PayloadObject.which() != 1)
659 return boost::get<RectangleAndPart>(PayloadObject);
664 boost::property_tree::ptree aTree;
665 std::stringstream aStream(payload);
666 boost::property_tree::read_json(aStream, aTree);
672 return boost::get<boost::property_tree::ptree>(PayloadObject);
677 std::stringstream aJSONStream;
678 constexpr bool bPretty =
false;
679 boost::property_tree::write_json(aJSONStream, rTree, bPretty);
680 PayloadString = OString(
o3tl::trim(aJSONStream.str()));
682 PayloadObject = rTree;
687 assert(PayloadObject.which() == 2);
688 return boost::get<boost::property_tree::ptree>(PayloadObject);
695 assert(PayloadObject.which() == 3);
696 return boost::get<int>(PayloadObject);
703 switch (PayloadObject.which())
711 return getRectangleAndPart().toString().getStr() == getPayload();
716 std::stringstream aJSONStream;
717 boost::property_tree::write_json(aJSONStream, getJson(),
false);
718 const std::string aExpected = boost::trim_copy(aJSONStream.str());
719 return getPayload() == std::string_view(aExpected);
727 assert(!
"Unknown variant type; please add an entry to validate.");
739 case LOK_CALLBACK_CELL_VIEW_CURSOR:
740 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
741 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
742 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
743 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
755 case LOK_CALLBACK_TEXT_SELECTION:
756 case LOK_CALLBACK_TEXT_SELECTION_START:
757 case LOK_CALLBACK_TEXT_SELECTION_END:
768 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
769 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
770 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
781 size_t viewIdPos = payload.find(
"viewId");
782 if (viewIdPos == std::string::npos)
785 size_t numberPos = payload.find(
":", viewIdPos + 6);
786 if (numberPos == std::string::npos)
789 for (++numberPos; numberPos < payload.length(); ++numberPos)
791 if (payload[numberPos] ==
',' || payload[numberPos] ==
'}' || (payload[numberPos] >=
'0' && payload[numberPos] <=
'9'))
795 if (numberPos < payload.length() && payload[numberPos] >=
'0' && payload[numberPos] <=
'9')
803std::string extractCertificate(
const std::string & certificate)
805 const std::string
header(
"-----BEGIN CERTIFICATE-----");
806 const std::string footer(
"-----END CERTIFICATE-----");
810 size_t pos1 = certificate.find(header);
811 if (pos1 == std::string::npos)
814 size_t pos2 = certificate.find(footer, pos1 + 1);
815 if (pos2 == std::string::npos)
818 pos1 = pos1 +
header.length();
821 return certificate.substr(pos1, pos2);
824std::string extractPrivateKey(
const std::string & privateKey)
826 const std::string
header(
"-----BEGIN PRIVATE KEY-----");
827 const std::string footer(
"-----END PRIVATE KEY-----");
831 size_t pos1 = privateKey.find(header);
832 if (pos1 == std::string::npos)
835 size_t pos2 = privateKey.find(footer, pos1 + 1);
836 if (pos2 == std::string::npos)
839 pos1 = pos1 +
header.length();
842 return privateKey.substr(pos1, pos2);
863 return pFilter->GetMimeType();
867css::uno::Reference< css::document::XUndoManager > getUndoManager(
const css::uno::Reference< css::frame::XFrame >& rxFrame )
869 const css::uno::Reference< css::frame::XController >&
xController = rxFrame->getController();
872 const css::uno::Reference< css::frame::XModel >&
xModel =
xController->getModel();
875 const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW );
876 return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW );
880 return css::uno::Reference< css::document::XUndoManager > ();
884void ExecuteMarginLRChange(
889 pPageLRMarginItem->
SetLeft( nPageLeftMargin );
890 pPageLRMarginItem->
SetRight( nPageRightMargin );
892 SfxCallMode::RECORD, { pPageLRMarginItem });
896void ExecuteMarginULChange(
901 pPageULMarginItem->
SetUpper( nPageTopMargin );
902 pPageULMarginItem->
SetLower( nPageBottomMargin );
904 SfxCallMode::RECORD, { pPageULMarginItem });
908void ExecuteOrientationChange()
914 std::unique_ptr<SvxPageItem> pPageItem(
new SvxPageItem(SID_ATTR_PAGE));
920 css::uno::Reference< css::document::XUndoManager > mxUndoManager(
923 if ( mxUndoManager.is() )
924 mxUndoManager->enterUndoContext(
"" );
929 std::unique_ptr<SvxSizeItem> pPageSizeItem(pSizeItem->
Clone());
933 std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(pLRSpaceItem->
Clone());
937 std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(pULSpaceItem->
Clone());
940 bool bIsLandscape =
false;
941 if ( pPageSizeItem->GetSize().Width() > pPageSizeItem->GetSize().Height())
945 pPageItem->SetLandscape(!bIsLandscape);
949 const tools::Long nRotatedWidth = pPageSizeItem->GetSize().Height();
950 const tools::Long nRotatedHeight = pPageSizeItem->GetSize().Width();
951 pPageSizeItem->SetSize(
Size(nRotatedWidth, nRotatedHeight));
958 SfxCallMode::RECORD, { pPageSizeItem.get(), pPageItem.get() });
970 const tools::Long nPW = pPageSizeItem->GetSize().Width();
976 ExecuteMarginLRChange( pPageLRMarginItem->
GetLeft(), nMR - (nTmpPW - nPW ), pPageLRMarginItem.get() );
980 ExecuteMarginLRChange( nML - (nTmpPW - nPW ), pPageLRMarginItem->
GetRight(), pPageLRMarginItem.get() );
988 const tools::Long nPH = pPageSizeItem->GetSize().Height();
994 ExecuteMarginULChange( pPageULMarginItem->
GetUpper(), nMB - ( nTmpPH - nPH ), pPageULMarginItem.get() );
998 ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), pPageULMarginItem->
GetLower(), pPageULMarginItem.get() );
1003 if ( mxUndoManager.is() )
1004 mxUndoManager->leaveUndoContext();
1007void setupSidebar(std::u16string_view sidebarDeckId = u
"")
1030 = pDockingWin->GetOrCreateSidebarController();
1035 if (!sidebarDeckId.empty())
1044 pDockingWin->SyncUpdate();
1068 OUString aNameEquals(OUString::Concat(rName) +
"=");
1069 OUString aCommaNameEquals(OUString::Concat(
",") + rName +
"=");
1072 if (rOptions.startsWith(aNameEquals))
1074 size_t nLen = aNameEquals.getLength();
1075 int nComma = rOptions.indexOf(
",", nLen);
1078 aValue = rOptions.copy(nLen, nComma - nLen);
1079 rOptions = rOptions.copy(nComma + 1);
1083 aValue = rOptions.copy(nLen);
1087 else if ((
nIndex = rOptions.indexOf(aCommaNameEquals)) >= 0)
1089 size_t nLen = aCommaNameEquals.getLength();
1090 int nComma = rOptions.indexOf(
",",
nIndex + nLen);
1093 aValue = rOptions.copy(
nIndex + nLen, nComma -
nIndex - nLen);
1094 rOptions = OUString::Concat(rOptions.subView(0,
nIndex)) + rOptions.subView(nComma);
1098 aValue = rOptions.copy(
nIndex + nLen);
1099 rOptions = rOptions.copy(0,
nIndex);
1109static void doc_destroy(LibreOfficeKitDocument* pThis);
1110static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* pUrl,
const char* pFormat,
const char* pFilterOptions);
1114static int doc_getPart(LibreOfficeKitDocument* pThis);
1115static void doc_setPart(LibreOfficeKitDocument* pThis,
int nPart);
1116static void doc_selectPart(LibreOfficeKitDocument* pThis,
int nPart,
int nSelect);
1118static char*
doc_getPartName(LibreOfficeKitDocument* pThis,
int nPart);
1119static void doc_setPartMode(LibreOfficeKitDocument* pThis,
int nPartMode);
1122 unsigned char* pBuffer,
1123 const int nCanvasWidth,
const int nCanvasHeight,
1124 const int nTilePosX,
const int nTilePosY,
1125 const int nTileWidth,
const int nTileHeight);
1127 unsigned char* pBuffer,
1130 const int nCanvasWidth,
const int nCanvasHeight,
1131 const int nTilePosX,
const int nTilePosY,
1132 const int nTileWidth,
const int nTileHeight);
1142 const char* pArguments);
1145 LibreOfficeKitCallback pCallback,
1153 const char* blockedCommandList);
1160 unsigned nLOKWindowId,
1164 unsigned long long int nLOKWindowId,
1165 const char* pArguments);
1167 unsigned nLOKWindowId,
1179 unsigned nLOKWindowId,
1187 unsigned nLOKWindowId,
1193 const char* pCommand,
1194 const char* pArguments,
1195 bool bNotifyWhenFinished);
1197 unsigned nLOKWindowId,
1206 const char* pMimeType,
1207 char** pUsedMimeType);
1210 const char* pMimeType,
1212 char** pUsedMimeType);
1214 const char **pMimeTypes,
1216 char ***pOutMimeTypes,
1218 char ***pOutStreams);
1220 const size_t nInCount,
1221 const char **pInMimeTypes,
1222 const size_t *pInSizes,
1223 const char **pInStreams);
1224static bool doc_paste(LibreOfficeKitDocument* pThis,
1225 const char* pMimeType,
1235 int nTilePixelWidth,
1236 int nTilePixelHeight,
1238 int nTileTwipHeight);
1240static void doc_setOutlineState(LibreOfficeKitDocument* pThis,
bool bColumn,
int nLevel,
int nIndex,
bool bHidden);
1250 const char *pFontName,
1255static unsigned char*
doc_renderFont(LibreOfficeKitDocument* pThis,
1256 const char *pFontName,
1260static char*
doc_getPartHash(LibreOfficeKitDocument* pThis,
int nPart);
1262static void doc_paintWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1263 const int nX,
const int nY,
1264 const int nWidth,
const int nHeight);
1266static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1267 const int nX,
const int nY,
1268 const int nWidth,
const int nHeight,
1269 const double fDPIScale);
1271static void doc_paintWindowForView(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1272 const int nX,
const int nY,
1273 const int nWidth,
const int nHeight,
1274 const double fDPIScale,
int viewId);
1276static void doc_postWindow(LibreOfficeKitDocument* pThis,
unsigned
1277 nLOKWindowId,
int nAction,
const char* pData);
1279static char*
doc_getPartInfo(LibreOfficeKitDocument* pThis,
int nPart);
1282 const unsigned char* pCertificateBinary,
1283 const int nCertificateBinarySize,
1284 const unsigned char* pPrivateKeyBinary,
1285 const int nPrivateKeyBinarySize);
1288 const unsigned char* pCertificateBinary,
1289 const int nCertificateBinarySize);
1295static void doc_resizeWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
1296 const int nWidth,
const int nHeight);
1302 const char* pArguments);
1305 const char* pSearchResult,
unsigned char** pBitmapBuffer,
1306 int* pWidth,
int* pHeight,
size_t* pByteSize);
1320ITiledRenderable* getTiledRenderable(LibreOfficeKitDocument* pThis)
1323 return dynamic_cast<ITiledRenderable*
>(pDocument->
mxComponent.get());
1335 ITiledRenderable* pDoc = getTiledRenderable(pThis);
1338 SAL_INFO(
"lok",
"Set to clipboard for view " << xClip.get());
1347const vcl::Font* FindFont(std::u16string_view rFontName)
1355 if (pList && !rFontName.empty())
1361vcl::Font FindFont_FallbackToDefault(std::u16string_view rFontName)
1363 if (
auto pFound = FindFont(rFontName))
1367 GetDefaultFontFlags::NONE);
1370int getDocumentType (LibreOfficeKitDocument* pThis)
1380 if (xDocument->supportsService(
"com.sun.star.sheet.SpreadsheetDocument"))
1382 return LOK_DOCTYPE_SPREADSHEET;
1384 else if (xDocument->supportsService(
"com.sun.star.presentation.PresentationDocument"))
1386 return LOK_DOCTYPE_PRESENTATION;
1388 else if (xDocument->supportsService(
"com.sun.star.drawing.DrawingDocument"))
1390 return LOK_DOCTYPE_DRAWING;
1392 else if (xDocument->supportsService(
"com.sun.star.text.TextDocument") || xDocument->supportsService(
"com.sun.star.text.WebDocument"))
1394 return LOK_DOCTYPE_TEXT;
1401 catch (
const uno::Exception& exception)
1405 return LOK_DOCTYPE_OTHER;
1411 : mxComponent(
std::move(xComponent))
1412 , mnDocumentId(nDocumentId)
1414 assert(nDocumentId != -1 &&
"Cannot set mnDocumentId to -1");
1515 forceSetClipboardForCurrentView(
this);
1525 catch (
const css::lang::DisposedException&)
1533 OUString sGenerator(
1535 OUString os(
"$_OS");
1536 ::rtl::Bootstrap::expandMacros(os);
1537 return sGenerator.replaceFirst(
"%1", os);
1543 :
Timer(
"lokit timer callback" )
1544 , mHandler( handler )
1559 :
Idle(
"lokit idle callback" ),
1570 m_states.emplace(LOK_CALLBACK_TEXT_SELECTION,
"NIL");
1571 m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION,
"NIL");
1572 m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
"NIL");
1573 m_states.emplace(LOK_CALLBACK_STATE_CHANGED,
"NIL");
1574 m_states.emplace(LOK_CALLBACK_MOUSE_POINTER,
"NIL");
1575 m_states.emplace(LOK_CALLBACK_CELL_CURSOR,
"NIL");
1576 m_states.emplace(LOK_CALLBACK_CELL_FORMULA,
"NIL");
1577 m_states.emplace(LOK_CALLBACK_CELL_ADDRESS,
"NIL");
1578 m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE,
"NIL");
1579 m_states.emplace(LOK_CALLBACK_SET_PART,
"NIL");
1580 m_states.emplace(LOK_CALLBACK_TABLE_SELECTED,
"NIL");
1581 m_states.emplace(LOK_CALLBACK_TAB_STOP_LIST,
"NIL");
1582 m_states.emplace(LOK_CALLBACK_RULER_UPDATE,
"NIL");
1583 m_states.emplace(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE,
"NIL");
1593 int delta = std::distance(
m_queue1.begin(), pos);
1599 int delta = std::distance(
m_queue1.rbegin(), pos);
1623 types.resize(
nType + 1 );
1632 bool allViewIds =
false;
1643 std::vector<PerViewIdData>& types = it.second;
1645 types[
nType ].set =
false;
1664 queue(LOK_CALLBACK_INVALIDATE_TILES, callbackData);
1670 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1678 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1686 rState.append(
"\nView:\t");
1687 rState.append(
static_cast<sal_Int32
>(
m_viewId));
1688 rState.append(
"\n\tDisableCallbacks:\t");
1690 rState.append(
"\n\tStates:\n");
1693 rState.append(
"\n\t\t");
1694 rState.append(
static_cast<sal_Int32
>(
i.first));
1695 rState.append(
"\t");
1696 rState.append(
i.second);
1718 bool bIsChartActive =
false;
1719 bool bIsComment =
false;
1720 if (
type == LOK_CALLBACK_GRAPHIC_SELECTION)
1723 bIsChartActive = aChartHelper.
GetWindow() !=
nullptr;
1725 else if (
type == LOK_CALLBACK_COMMENT)
1739 if (
type != LOK_CALLBACK_STATE_CHANGED &&
1740 type != LOK_CALLBACK_INVALIDATE_TILES &&
1741 type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1742 type != LOK_CALLBACK_CURSOR_VISIBLE &&
1743 type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE &&
1744 type != LOK_CALLBACK_TEXT_SELECTION &&
1745 type != LOK_CALLBACK_TEXT_SELECTION_START &&
1746 type != LOK_CALLBACK_TEXT_SELECTION_END &&
1747 type != LOK_CALLBACK_MEDIA_SHAPE &&
1748 type != LOK_CALLBACK_REFERENCE_MARKS)
1760 if (
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1761 aCallbackData.
getPayload().indexOf(
", 0, 0, ") != -1 &&
1762 aCallbackData.
getPayload().indexOf(
"\"hyperlink\":\"\"") == -1 &&
1763 aCallbackData.
getPayload().indexOf(
"\"hyperlink\": {}") == -1)
1773 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1780 SAL_INFO(
"lok",
"Received event with updated type [" <<
type <<
"] as normal callback");
1785 SAL_INFO(
"lok",
"Received event with updated type [" <<
type <<
"] as normal callback");
1792 case LOK_CALLBACK_TEXT_SELECTION_START:
1793 case LOK_CALLBACK_TEXT_SELECTION_END:
1794 case LOK_CALLBACK_TEXT_SELECTION:
1795 case LOK_CALLBACK_GRAPHIC_SELECTION:
1796 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1797 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1798 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1799 case LOK_CALLBACK_STATE_CHANGED:
1800 case LOK_CALLBACK_MOUSE_POINTER:
1801 case LOK_CALLBACK_CELL_CURSOR:
1802 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1803 case LOK_CALLBACK_CELL_FORMULA:
1804 case LOK_CALLBACK_CELL_ADDRESS:
1805 case LOK_CALLBACK_CELL_SELECTION_AREA:
1806 case LOK_CALLBACK_CURSOR_VISIBLE:
1807 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1808 case LOK_CALLBACK_SET_PART:
1809 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1810 case LOK_CALLBACK_INVALIDATE_HEADER:
1811 case LOK_CALLBACK_WINDOW:
1812 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1813 case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
1814 case LOK_CALLBACK_REFERENCE_MARKS:
1815 case LOK_CALLBACK_CELL_AUTO_FILL_AREA:
1816 case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
1817 case LOK_CALLBACK_A11Y_CARET_CHANGED:
1818 case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
1831 if (
type == LOK_CALLBACK_TEXT_SELECTION && aCallbackData.
isEmpty())
1833 const auto& posStart = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_TEXT_SELECTION_START);
1834 auto posStart2 =
toQueue2(posStart);
1838 const auto& posEnd = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_TEXT_SELECTION_END);
1849 case LOK_CALLBACK_TEXT_SELECTION_START:
1850 case LOK_CALLBACK_TEXT_SELECTION_END:
1851 case LOK_CALLBACK_TEXT_SELECTION:
1852 case LOK_CALLBACK_GRAPHIC_SELECTION:
1853 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1854 case LOK_CALLBACK_INVALIDATE_TILES:
1866 case LOK_CALLBACK_TEXT_SELECTION_START:
1867 case LOK_CALLBACK_TEXT_SELECTION_END:
1868 case LOK_CALLBACK_TEXT_SELECTION:
1869 case LOK_CALLBACK_MOUSE_POINTER:
1870 case LOK_CALLBACK_CELL_CURSOR:
1871 case LOK_CALLBACK_CELL_FORMULA:
1872 case LOK_CALLBACK_CELL_ADDRESS:
1873 case LOK_CALLBACK_CURSOR_VISIBLE:
1874 case LOK_CALLBACK_SET_PART:
1875 case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
1876 case LOK_CALLBACK_RULER_UPDATE:
1877 case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
1878 case LOK_CALLBACK_A11Y_CARET_CHANGED:
1879 case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
1889 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1890 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1891 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1892 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1893 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1894 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1895 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1896 case LOK_CALLBACK_FORM_FIELD_BUTTON:
1900 const bool hyperLinkException =
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1901 aCallbackData.
getPayload().indexOf(
"\"hyperlink\":\"\"") == -1 &&
1902 aCallbackData.
getPayload().indexOf(
"\"hyperlink\": {}") == -1;
1903 if(!hyperLinkException)
1905 const int nViewId = aCallbackData.
getViewId();
1907 return (nViewId == elemData.
getViewId());
1914 case LOK_CALLBACK_INVALIDATE_TILES:
1921 case LOK_CALLBACK_STATE_CHANGED:
1930 if (
name !=
".uno:ModifiedStatus=")
1941 case LOK_CALLBACK_WINDOW:
1946 case LOK_CALLBACK_GRAPHIC_SELECTION:
1951 {
return (elemData.
getPayload().indexOf(
"INPLACE") == -1); });
1958 assert(aCallbackData.
validate() &&
"Cached callback payload object and string mismatch!");
1960 m_queue2.emplace_back(aCallbackData);
1968 std::ostringstream oss;
1972 oss <<
m_queue1.size() <<
" items\n";
1975 for (; it1 !=
m_queue1.end(); ++it1, ++it2)
1976 oss <<
i++ <<
": [" << *it1 <<
"] [" << it2->getPayload() <<
"].\n";
1977 SAL_INFO(
"lok",
"Current Queue: " << oss.str());
2001 = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_INVALIDATE_TILES);
2010 <<
"] since all tiles need to be invalidated.");
2020 <<
"] since overlaps existing all-parts.");
2029 <<
"] so removing all with part " << rcNew.
m_nPart <<
".");
2038 const auto rcOrig = rcNew;
2040 SAL_INFO(
"lok",
"Have [" <<
type <<
"]: [" << aCallbackData.
getPayload() <<
"] so merging overlapping.");
2046 SAL_INFO(
"lok",
"Nothing to merge between new: "
2047 << rcNew.toString() <<
", and old: " << rcOld.toString());
2054 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" has " << rcOld.toString()
2056 if (rcNew.m_aRectangle.Contains(rcOld.m_aRectangle) && rcOld.m_nMode == rcNew.m_nMode)
2058 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
2059 << rcOld.toString() <<
".");
2063 else if (rcOld.m_nPart == -1)
2066 SAL_INFO(
"lok",
"Old " << rcOld.toString() <<
" has " << rcNew.toString()
2068 if (rcOld.m_aRectangle.Contains(rcNew.m_aRectangle) && rcOld.m_nMode == rcNew.m_nMode)
2070 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
2071 << rcOld.toString() <<
".");
2079 const bool bOverlap = !rcOverlap.
IsEmpty() && rcOld.m_nMode == rcNew.
m_nMode;
2080 SAL_INFO(
"lok",
"Merging " << rcNew.
toString() <<
" & " << rcOld.toString()
2082 <<
" Overlap: " << bOverlap);
2095 if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
2097 SAL_INFO(
"lok",
"Replacing: " << rcOrig.toString() <<
" by " << rcNew.toString());
2098 if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth()
2099 || rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
2101 SAL_WARN(
"lok",
"Error: merged rect smaller.");
2106 aCallbackData.updateRectangleAndPart(rcNew);
2113 const OString& payload = aCallbackData.
getPayload();
2115 boost::property_tree::ptree& aTree = aCallbackData.
setJson(std::string(payload));
2116 const unsigned nLOKWindowId = aTree.get<
unsigned>(
"id", 0);
2117 const std::string aAction = aTree.get<std::string>(
"action",
"");
2118 if (aAction ==
"invalidate")
2120 std::string aRectStr = aTree.get<std::string>(
"rectangle",
"");
2123 if (aRectStr.empty())
2126 const boost::property_tree::ptree& aOldTree = elemData.
getJson();
2127 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
2128 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
2139 bool invAllExist =
false;
2142 for (;it1 !=
m_queue1.rend(); ++it1, ++it2)
2144 if (*it1 != LOK_CALLBACK_WINDOW)
2146 const boost::property_tree::ptree& aOldTree = it2->getJson();
2147 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
2148 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate"
2149 && aOldTree.get<std::string>(
"rectangle",
"").empty())
2159 SAL_INFO(
"lok.dialog",
"Skipping queue ["
2160 <<
type <<
"]: [" << payload
2161 <<
"] since whole window needs to be invalidated.");
2165 std::istringstream aRectStream(aRectStr);
2168 aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
2170 bool currentIsRedundant =
false;
2171 removeAll(LOK_CALLBACK_WINDOW, [&aNewRect, &nLOKWindowId,
2173 const boost::property_tree::ptree& aOldTree = elemData.
getJson();
2174 if (aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
2177 std::istringstream aOldRectStream(aOldTree.get<std::string>(
"rectangle",
""));
2178 tools::Long nOldLeft, nOldTop, nOldWidth, nOldHeight;
2180 aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
2181 >> nOldComma >> nOldHeight;
2182 const tools::Rectangle aOldRect = tools::Rectangle(
2183 nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
2185 if (nLOKWindowId == aOldTree.get<unsigned>(
"id", 0))
2187 if (aNewRect == aOldRect)
2189 SAL_INFO(
"lok.dialog",
"Duplicate rect [" << aNewRect.toString()
2190 <<
"]. Skipping new.");
2192 currentIsRedundant = true;
2196 else if (aNewRect.Contains(aOldRect))
2198 SAL_INFO(
"lok.dialog",
2199 "New rect [" << aNewRect.toString() <<
"] engulfs old ["
2200 << aOldRect.toString() <<
"]. Replacing old.");
2204 else if (aOldRect.Contains(aNewRect))
2206 SAL_INFO(
"lok.dialog",
2207 "Old rect [" << aOldRect.toString() <<
"] engulfs new ["
2208 << aNewRect.toString() <<
"]. Skipping new.");
2210 currentIsRedundant = true;
2216 const tools::Rectangle aPreMergeRect = aNewRect;
2217 aNewRect.Union(aOldRect);
2218 SAL_INFO(
"lok.dialog",
"Merging rects ["
2219 << aPreMergeRect.toString() <<
"] & ["
2220 << aOldRect.toString() <<
"] = ["
2221 << aNewRect.toString()
2222 <<
"]. Replacing old.");
2233 if (currentIsRedundant)
2236 aTree.put(
"rectangle", aNewRect.toString().getStr());
2238 assert(aCallbackData.
validate() &&
"Validation after setJson failed!");
2241 else if (aAction ==
"created")
2244 removeAll(LOK_CALLBACK_WINDOW,[&nLOKWindowId](
const CallbackData& elemData) {
2245 const boost::property_tree::ptree& aOldTree = elemData.getJson();
2246 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
2259 auto xClip = forceSetClipboardForCurrentView(m_pDocument);
2262 pWindow->SetClipboard(xClipboard);
2265 else if (aAction ==
"size_changed")
2269 removeAll(LOK_CALLBACK_WINDOW, [&nLOKWindowId](
const CallbackData& elemData) {
2270 const boost::property_tree::ptree& aOldTree = elemData.getJson();
2271 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
2273 const std::string aOldAction = aOldTree.get<std::string>(
"action",
"");
2274 if (aOldAction ==
"invalidate")
2292 assert(viewShell !=
nullptr);
2295 std::vector<bool> updatedTypes;
2297 boost::container::flat_map<int, std::vector<PerViewIdData>> updatedTypesPerViewId;
2304 static const int orderedUpdatedTypes[] = {
2305 LOK_CALLBACK_TEXT_SELECTION_START, LOK_CALLBACK_TEXT_SELECTION_END, LOK_CALLBACK_TEXT_SELECTION };
2308 static const int orderedUpdatedTypesPerViewId[] = {
2309 LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
2310 LOK_CALLBACK_INVALIDATE_VIEW_CURSOR,
2311 LOK_CALLBACK_TEXT_VIEW_SELECTION };
2313 for(
int type : orderedUpdatedTypes )
2320 for(
const auto& it : updatedTypesPerViewId )
2322 int viewId = it.first;
2323 const std::vector<PerViewIdData>& types = it.second;
2324 for(
int type : orderedUpdatedTypesPerViewId )
2329 const int sourceViewId = types[
type ].sourceViewId;
2332 assert(sourceViewId >= 0);
2336 if(sourceViewShell ==
nullptr)
2338 SAL_INFO(
"lok",
"View #" << sourceViewId <<
" no longer found for updated event [" <<
type <<
"]");
2349 if (
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR)
2352 viewShell = viewShell2;
2359 m_queue2.emplace_back(callbackData);
2361 <<
"] to have " <<
m_queue1.size() <<
" entries.");
2377 viewShell->flushPendingLOKInvalidateTiles();
2380 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
2388 for (; it1 !=
m_queue1.end(); ++it1, ++it2)
2390 const int type = *it1;
2391 const auto& payload = it2->getPayload();
2394 SAL_INFO(
"lok",
"processing event: [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2401 if (
type == LOK_CALLBACK_STATE_CHANGED &&
2402 (
idx = payload.indexOf(
'=')) != -1)
2404 OString key = payload.copy(0,
idx);
2405 OString
value = payload.copy(
idx+1);
2410 if (stateIt->second ==
value)
2412 SAL_INFO(
"lok",
"Skipping new state duplicate: [" <<
type <<
"]: [" << payload <<
"].");
2415 SAL_INFO(
"lok",
"Replacing a state element [" <<
type <<
"]: [" << payload <<
"].");
2416 stateIt->second =
value;
2420 SAL_INFO(
"lok",
"Inserted a new state element: [" <<
type <<
"]: [" << payload <<
"]");
2430 if (stateIt->second == payload)
2432 SAL_INFO(
"lok",
"Skipping duplicate [" <<
type <<
"]: [" << payload <<
"].");
2435 stateIt->second = payload;
2444 auto& states = statesIt->second;
2445 const auto stateIt = states.find(
type);
2446 if (stateIt != states.end())
2449 if (stateIt->second == payload)
2451 SAL_INFO(
"lok",
"Skipping view duplicate [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2455 SAL_INFO(
"lok",
"Replacing an element in view states [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2456 stateIt->second = payload;
2460 SAL_INFO(
"lok",
"Inserted a new element in view states: [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"]");
2461 states.emplace(
type, payload);
2486 bool bErased =
false;
2502 bool bErased =
false;
2510 if (rTestFunc(*it2))
2527 result.first->second.clear();
2551static void lo_destroy (LibreOfficeKit* pThis);
2552static int lo_initialize (LibreOfficeKit* pThis,
const char* pInstallPath,
const char* pUserProfilePath);
2553static LibreOfficeKitDocument*
lo_documentLoad (LibreOfficeKit* pThis,
const char* pURL);
2558 const char* pOptions);
2560 LibreOfficeKitCallback pCallback,
2566 const char* pPassword);
2568static int lo_runMacro (LibreOfficeKit* pThis,
const char* pURL);
2572 const unsigned char* pCertificateBinary,
2573 const int nCertificateBinarySize,
2574 const unsigned char* pPrivateKeyBinary,
2575 const int nPrivateKeyBinarySize);
2578 const char* pFilePath);
2580static void lo_trimMemory(LibreOfficeKit* pThis,
int nTarget);
2583 LibreOfficeKitPollCallback pPollCallback,
2584 LibreOfficeKitWakeCallback pWakeCallback,
2588 unsigned long long int nLOKWindowId,
2589 const char* pArguments);
2591static void lo_setOption(LibreOfficeKit* pThis,
const char* pOption,
const char* pValue);
2593static void lo_dumpState(LibreOfficeKit* pThis,
const char* pOptions,
char** pState);
2598 , mpCallback(nullptr)
2599 , mpCallbackData(nullptr)
2600 , mOptionalFeatures(0)
2638void setLanguageAndLocale(OUString
const & aLangISO)
2648 if (sFormat == u
"pdf")
2651 rFilterDataMap[
"ExportBookmarks"] <<=
true;
2673 static int nDocumentIdCounter = 0;
2676 pLib->maLastExceptionMsg.clear();
2681 pLib->maLastExceptionMsg =
"Filename to load was not provided.";
2682 SAL_INFO(
"lok",
"URL for load is empty");
2686 pLib->maLastExceptionMsg.clear();
2690 pLib->maLastExceptionMsg =
"ComponentContext is not available";
2691 SAL_INFO(
"lok",
"ComponentContext is not available");
2697 if (!xComponentLoader.is())
2699 pLib->maLastExceptionMsg =
"ComponentLoader is not available";
2700 SAL_INFO(
"lok",
"ComponentLoader is not available");
2712 if (!aLanguage.isEmpty() && isValidLangTag)
2714 static bool isLoading =
true;
2727 SAL_INFO(
"lok",
"Set document language to " << aLanguage);
2730 setLanguageAndLocale(aLanguage);
2737 if (!aTimezone.isEmpty())
2744 const char* tz = ::getenv(
"TZ");
2748 OStringToOUString(tz, RTL_TEXTENCODING_UTF8));
2756 const OUString aDeviceFormFactor =
extractParameter(aOptions,
u"DeviceFormFactor");
2760 if (!aBatch.isEmpty())
2765 const OUString sFilterOptions = aOptions;
2769 auto const pair(
pLib->mInteractionMap.insert(std::make_pair(
aURL.toUtf8(), pInteraction)));
2773 pLib->mInteractionMap.erase(aURL.toUtf8());
2778 int nMacroSecurityLevel = 1;
2779 const OUString aMacroSecurityLevel =
extractParameter(aOptions,
u"MacroSecurityLevel");
2780 if (!aMacroSecurityLevel.isEmpty())
2783 sal_uInt32 nFormat = 1;
2785 if (aFormatter.
IsNumberFormat(aMacroSecurityLevel, nFormat, nNumber))
2786 nMacroSecurityLevel =
static_cast<int>(nNumber);
2790#if defined(ANDROID) && HAVE_FEATURE_ANDROID_LOK
2791 sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG;
2793 const OUString aEnableMacrosExecution =
extractParameter(aOptions,
u"EnableMacrosExecution");
2794 sal_Int16 nMacroExecMode = aEnableMacrosExecution ==
"true" ? document::MacroExecMode::USE_CONFIG :
2795 document::MacroExecMode::NEVER_EXECUTE;
2817 const int nThisDocumentId = nDocumentIdCounter++;
2823 assert(!xComponent.is() || pair.second);
2825 if (!xComponent.is())
2827 pLib->maLastExceptionMsg =
"loadComponentFromURL returned an empty reference";
2828 SAL_INFO(
"lok",
"Document can't be loaded - " <<
pLib->maLastExceptionMsg);
2835 if (
pLib->mpCallback)
2838 pLib->mpCallback(LOK_CALLBACK_SIGNATURE_STATUS, OString::number(
nState).getStr(),
pLib->mpCallbackData);
2843 if (aFontMappingUseData.size() > 0)
2845 SAL_INFO(
"lok.fontsubst",
"================ Original substitutions:");
2846 for (
const auto &
i : aFontMappingUseData)
2848 SAL_INFO(
"lok.fontsubst",
i.mOriginalFont);
2849 for (
const auto &j :
i.mUsedFonts)
2850 SAL_INFO(
"lok.fontsubst",
" " << j);
2858 aFontMappingUseData.erase
2859 (std::remove_if(aFontMappingUseData.begin(), aFontMappingUseData.end(),
2871 if (x.mOriginalFont.indexOf(
'/') == -1)
2872 for (const auto &j : x.mUsedFonts)
2873 if (j == x.mOriginalFont ||
2874 j.startsWith(Concat2View(x.mOriginalFont +
"/")))
2879 aFontMappingUseData.end());
2885 aFontMappingUseData.erase
2886 (std::remove_if(aFontMappingUseData.begin(), aFontMappingUseData.end(),
2893 if (x.mOriginalFont.indexOf(
'/') == -1)
2894 for (const auto &j : x.mUsedFonts)
2895 if ((x.mOriginalFont ==
"Arial" &&
2896 j.startsWith(
"Liberation Sans/")) ||
2897 (x.mOriginalFont ==
"Times New Roman" &&
2898 j.startsWith(
"Liberation Serif/")) ||
2899 (x.mOriginalFont ==
"Courier New" &&
2900 j.startsWith(
"Liberation Mono/")) ||
2901 (x.mOriginalFont ==
"Arial Narrow" &&
2902 j.startsWith(
"Liberation Sans Narrow/")) ||
2903 (x.mOriginalFont ==
"Cambria" &&
2904 j.startsWith(
"Caladea/")) ||
2905 (x.mOriginalFont ==
"Calibri" &&
2906 j.startsWith(
"Carlito/")) ||
2907 (x.mOriginalFont ==
"Palatino Linotype" &&
2908 j.startsWith(
"P052/")) ||
2912 (x.mOriginalFont ==
"Symbol" &&
2913 j.startsWith(
"OpenSymbol/")))
2920 aFontMappingUseData.end());
2922 if (aFontMappingUseData.size() > 0)
2924 SAL_INFO(
"lok.fontsubst",
"================ Pruned substitutions:");
2925 for (
const auto &
i : aFontMappingUseData)
2927 SAL_INFO(
"lok.fontsubst",
i.mOriginalFont);
2928 for (
const auto &j :
i.mUsedFonts)
2929 SAL_INFO(
"lok.fontsubst",
" " << j);
2933 for (std::size_t
i = 0;
i < aFontMappingUseData.size(); ++
i)
2935 pDocument->
maFontsMissing.insert(aFontMappingUseData[
i].mOriginalFont);
2940 catch (
const uno::Exception& exception)
2942 pLib->maLastExceptionMsg = exception.Message;
2956 pLib->maLastExceptionMsg.clear();
2958 OUString sURL( pURL, strlen(pURL), RTL_TEXTENCODING_UTF8 );
2961 pLib->maLastExceptionMsg =
"Macro to run was not provided.";
2962 SAL_INFO(
"lok",
"Macro URL is empty");
2966 if (!sURL.startsWith(
"macro://"))
2968 pLib->maLastExceptionMsg =
"This doesn't look like macro URL";
2969 SAL_INFO(
"lok",
"Macro URL is invalid");
2973 pLib->maLastExceptionMsg.clear();
2977 pLib->maLastExceptionMsg =
"ComponentContext is not available";
2978 SAL_INFO(
"lok",
"ComponentContext is not available");
2983 aURL.Complete = sURL;
2988 xParser->parseStrict(
aURL );
2992 if (!xComponentLoader.is())
2994 pLib->maLastExceptionMsg =
"ComponentLoader is not available";
2995 SAL_INFO(
"lok",
"ComponentLoader is not available");
3006 xDP.set(
xSFactory->createInstance(
"com.sun.star.comp.sfx2.SfxMacroLoader"), uno::UNO_QUERY );
3011 pLib->maLastExceptionMsg =
"Macro loader is not available";
3012 SAL_INFO(
"lok",
"Macro loader is not available");
3018 css::beans::PropertyValue aErr;
3019 uno::Any aRet = xSyncDisp->dispatchWithReturnValue(
aURL, aEmpty );
3022 if (aErr.Name ==
"ErrorCode")
3024 sal_uInt32 nErrCode = 0;
3025 aErr.
Value >>= nErrCode;
3027 pLib->maLastExceptionMsg =
"An error occurred running macro (error code: " + OUString::number( nErrCode ) +
")";
3028 SAL_INFO(
"lok",
"Macro execution terminated with error code " << nErrCode);
3038 const unsigned char* pCertificateBinary,
3039 const int nCertificateBinarySize,
3040 const unsigned char* pPrivateKeyBinary,
3041 const int nPrivateKeyBinarySize)
3054 std::string aCertificateString(
reinterpret_cast<const char*
>(pCertificateBinary), nCertificateBinarySize);
3055 std::string aCertificateBase64String = extractCertificate(aCertificateString);
3056 if (!aCertificateBase64String.empty())
3058 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String);
3063 aCertificateSequence.realloc(nCertificateBinarySize);
3064 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.getArray());
3068 std::string aPrivateKeyString(
reinterpret_cast<const char*
>(pPrivateKeyBinary), nPrivateKeyBinarySize);
3069 std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
3070 if (!aPrivateKeyBase64String.empty())
3072 OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String);
3077 aPrivateKeySequence.realloc(nPrivateKeyBinarySize);
3078 std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeyBinarySize, aPrivateKeySequence.getArray());
3083 if (!xSecurityContext.is())
3089 if (!xCertificateCreator.is())
3094 if (!xCertificate.is())
3111 if (!
aURL.isEmpty())
3113 if (xComponentLoader.is())
3119 {
"Hidden", css::uno::Any(
true)},
3120 {
"ReadOnly", css::uno::Any(
true)}
3122 xComp = xComponentLoader->loadComponentFromURL(
aURL,
"_blank", 0, aFilterOptions );
3124 catch (
const lang::IllegalArgumentException&
ex )
3126 SAL_WARN(
"lok",
"lo_extractRequest: IllegalArgumentException: " <<
ex.Message);
3132 SAL_WARN(
"lok",
"lo_extractRequest: Exception on loadComponentFromURL, url= " <<
aURL);
3143 OUStringBuffer jsonText(
"{ \"Targets\": { ");
3144 bool lastParentheses =
extractLinks(xLTS->getLinks(),
false, jsonText);
3145 jsonText.append(
"} }");
3146 if (!lastParentheses)
3147 jsonText.append(
" }");
3149 OUString res(jsonText.makeStringAndClear());
3171#ifdef HAVE_MALLOC_TRIM
3178 LibreOfficeKitCallback pCallback,
3187 pLib->maLastExceptionMsg.clear();
3193static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* sUrl,
const char* pFormat,
const char* pFilterOptions)
3210 SAL_INFO(
"lok",
"URL for save is empty");
3216 const ExtensionMap* pMap;
3220 case LOK_DOCTYPE_SPREADSHEET:
3223 case LOK_DOCTYPE_PRESENTATION:
3226 case LOK_DOCTYPE_DRAWING:
3229 case LOK_DOCTYPE_TEXT:
3232 case LOK_DOCTYPE_OTHER:
3234 SAL_INFO(
"lok",
"Can't save document - unsupported document type.");
3238 if (pFormat ==
nullptr)
3241 sal_Int32
idx =
aURL.lastIndexOf(
".");
3244 sFormat =
aURL.copy(
idx + 1 );
3253 OUString aFilterName;
3254 for (sal_Int32
i = 0; pMap[
i].extn; ++
i)
3256 if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[
i].extn))
3262 if (aFilterName.isEmpty())
3268 OUString aFilterOptions =
getUString(pFilterOptions);
3272 OUString watermarkText;
3273 std::u16string_view sFullSheetPreview;
3275 if ((
aIndex = aFilterOptions.indexOf(
",Watermark=")) >= 0)
3277 int bIndex = aFilterOptions.indexOf(
"WATERMARKEND");
3278 watermarkText = aFilterOptions.subView(
aIndex+11, bIndex-(
aIndex+11));
3279 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+12);
3282 if ((
aIndex = aFilterOptions.indexOf(
",FullSheetPreview=")) >= 0)
3284 int bIndex = aFilterOptions.indexOf(
"FULLSHEETPREVEND");
3285 sFullSheetPreview = aFilterOptions.subView(
aIndex+18, bIndex-(
aIndex+18));
3286 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+16);
3289 bool bFullSheetPreview = sFullSheetPreview ==
u"true";
3293 sal_Int32 pdfVer = 0;
3294 if ((
aIndex = aFilterOptions.indexOf(
",PDFVer=")) >= 0)
3296 int bIndex = aFilterOptions.indexOf(
"PDFVEREND");
3297 std::u16string_view sPdfVer = aFilterOptions.subView(
aIndex+8, bIndex-(
aIndex+8));
3298 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+9);
3323 std::vector<OUString> aFilteredOptionVec;
3324 bool bTakeOwnership =
false;
3326 for (
const auto& rOption : aOptionSeq)
3328 if (rOption ==
"TakeOwnership")
3329 bTakeOwnership =
true;
3330 else if (rOption ==
"NoFileSync")
3331 aSaveMediaDescriptor[
"NoFileSync"] <<=
true;
3333 aFilteredOptionVec.push_back(rOption);
3336 aSaveMediaDescriptor[
"Overwrite"] <<=
true;
3337 aSaveMediaDescriptor[
"FilterName"] <<= aFilterName;
3339 auto aFilteredOptionSeq = comphelper::containerToSequence<OUString>(aFilteredOptionVec);
3341 aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS] <<= aFilterOptions;
3347 if (!aFilterOptions.startsWith(
"{"))
3349 setFormatSpecificFilterData(sFormat, aFilterDataMap);
3352 if (!watermarkText.isEmpty())
3353 aFilterDataMap[
"TiledWatermark"] <<= watermarkText;
3355 if (bFullSheetPreview)
3356 aFilterDataMap[
"SinglePageSheets"] <<=
true;
3359 aFilterDataMap[
"SelectPdfVersion"] <<= pdfVer;
3361 if (!aFilterDataMap.
empty())
3374 aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteraction;
3379 xStorable->storeAsURL(
aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
3381 xStorable->storeToURL(
aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
3385 catch (
const uno::Exception& exception)
3403 OUString sUnoCommands[] =
3405 OUString(
".uno:AlignLeft"),
3406 OUString(
".uno:AlignHorizontalCenter"),
3407 OUString(
".uno:AlignRight"),
3408 OUString(
".uno:BackColor"),
3409 OUString(
".uno:BackgroundColor"),
3410 OUString(
".uno:TableCellBackgroundColor"),
3411 OUString(
".uno:Bold"),
3412 OUString(
".uno:CenterPara"),
3413 OUString(
".uno:CharBackColor"),
3414 OUString(
".uno:CharBackgroundExt"),
3415 OUString(
".uno:CharFontName"),
3416 OUString(
".uno:Color"),
3417 OUString(
".uno:ControlCodes"),
3418 OUString(
".uno:DecrementIndent"),
3419 OUString(
".uno:DefaultBullet"),
3420 OUString(
".uno:DefaultNumbering"),
3421 OUString(
".uno:FontColor"),
3422 OUString(
".uno:FontHeight"),
3423 OUString(
".uno:IncrementIndent"),
3424 OUString(
".uno:Italic"),
3425 OUString(
".uno:JustifyPara"),
3426 OUString(
".uno:JumpToMark"),
3427 OUString(
".uno:OutlineFont"),
3428 OUString(
".uno:LeftPara"),
3429 OUString(
".uno:LanguageStatus"),
3430 OUString(
".uno:RightPara"),
3431 OUString(
".uno:Shadowed"),
3432 OUString(
".uno:SubScript"),
3433 OUString(
".uno:SuperScript"),
3434 OUString(
".uno:Strikeout"),
3435 OUString(
".uno:StyleApply"),
3436 OUString(
".uno:Underline"),
3437 OUString(
".uno:ModifiedStatus"),
3438 OUString(
".uno:Undo"),
3439 OUString(
".uno:Redo"),
3440 OUString(
".uno:InsertPage"),
3441 OUString(
".uno:DeletePage"),
3442 OUString(
".uno:DuplicatePage"),
3443 OUString(
".uno:InsertSlide"),
3444 OUString(
".uno:DeleteSlide"),
3445 OUString(
".uno:DuplicateSlide"),
3446 OUString(
".uno:ChangeTheme"),
3447 OUString(
".uno:Cut"),
3448 OUString(
".uno:Copy"),
3449 OUString(
".uno:Paste"),
3450 OUString(
".uno:SelectAll"),
3451 OUString(
".uno:ReplyComment"),
3452 OUString(
".uno:ResolveComment"),
3453 OUString(
".uno:ResolveCommentThread"),
3454 OUString(
".uno:InsertRowsBefore"),
3455 OUString(
".uno:InsertRowsAfter"),
3456 OUString(
".uno:InsertColumnsBefore"),
3457 OUString(
".uno:InsertColumnsAfter"),
3458 OUString(
".uno:DeleteRows"),
3459 OUString(
".uno:DeleteColumns"),
3460 OUString(
".uno:DeleteTable"),
3461 OUString(
".uno:SelectTable"),
3462 OUString(
".uno:EntireRow"),
3463 OUString(
".uno:EntireColumn"),
3464 OUString(
".uno:EntireCell"),
3465 OUString(
".uno:AssignLayout"),
3466 OUString(
".uno:StatusDocPos"),
3467 OUString(
".uno:RowColSelCount"),
3468 OUString(
".uno:StatusPageStyle"),
3469 OUString(
".uno:InsertMode"),
3470 OUString(
".uno:SpellOnline"),
3471 OUString(
".uno:StatusSelectionMode"),
3472 OUString(
".uno:StateTableCell"),
3473 OUString(
".uno:StatusBarFunc"),
3474 OUString(
".uno:StatePageNumber"),
3475 OUString(
".uno:StateWordCount"),
3476 OUString(
".uno:SelectionMode"),
3477 OUString(
".uno:PageStatus"),
3478 OUString(
".uno:LayoutStatus"),
3479 OUString(
".uno:Scale"),
3480 OUString(
".uno:Context"),
3481 OUString(
".uno:WrapText"),
3482 OUString(
".uno:ToggleMergeCells"),
3483 OUString(
".uno:NumberFormatCurrency"),
3484 OUString(
".uno:NumberFormatPercent"),
3485 OUString(
".uno:NumberFormatDecimal"),
3486 OUString(
".uno:NumberFormatDate"),
3487 OUString(
".uno:EditHeaderAndFooter"),
3488 OUString(
".uno:FrameLineColor"),
3489 OUString(
".uno:SortAscending"),
3490 OUString(
".uno:SortDescending"),
3491 OUString(
".uno:TrackChanges"),
3492 OUString(
".uno:ShowTrackedChanges"),
3493 OUString(
".uno:NextTrackedChange"),
3494 OUString(
".uno:PreviousTrackedChange"),
3495 OUString(
".uno:AcceptAllTrackedChanges"),
3496 OUString(
".uno:RejectAllTrackedChanges"),
3497 OUString(
".uno:TableDialog"),
3498 OUString(
".uno:FormatCellDialog"),
3499 OUString(
".uno:FontDialog"),
3500 OUString(
".uno:ParagraphDialog"),
3501 OUString(
".uno:OutlineBullet"),
3502 OUString(
".uno:InsertIndexesEntry"),
3503 OUString(
".uno:DocumentRepair"),
3504 OUString(
".uno:TransformDialog"),
3505 OUString(
".uno:InsertPageHeader"),
3506 OUString(
".uno:InsertPageFooter"),
3507 OUString(
".uno:OnlineAutoFormat"),
3508 OUString(
".uno:InsertObjectChart"),
3509 OUString(
".uno:InsertSection"),
3510 OUString(
".uno:InsertAnnotation"),
3511 OUString(
".uno:DeleteAnnotation"),
3512 OUString(
".uno:InsertPagebreak"),
3513 OUString(
".uno:InsertColumnBreak"),
3514 OUString(
".uno:HyperlinkDialog"),
3515 OUString(
".uno:InsertSymbol"),
3516 OUString(
".uno:EditRegion"),
3517 OUString(
".uno:ThesaurusDialog"),
3518 OUString(
".uno:FormatArea"),
3519 OUString(
".uno:FormatLine"),
3520 OUString(
".uno:FormatColumns"),
3521 OUString(
".uno:Watermark"),
3522 OUString(
".uno:ResetAttributes"),
3523 OUString(
".uno:Orientation"),
3524 OUString(
".uno:ObjectAlignLeft"),
3525 OUString(
".uno:ObjectAlignRight"),
3526 OUString(
".uno:AlignCenter"),
3527 OUString(
".uno:TransformPosX"),
3528 OUString(
".uno:TransformPosY"),
3529 OUString(
".uno:TransformWidth"),
3530 OUString(
".uno:TransformHeight"),
3531 OUString(
".uno:ObjectBackOne"),
3532 OUString(
".uno:SendToBack"),
3533 OUString(
".uno:ObjectForwardOne"),
3534 OUString(
".uno:BringToFront"),
3535 OUString(
".uno:WrapRight"),
3536 OUString(
".uno:WrapThrough"),
3537 OUString(
".uno:WrapLeft"),
3538 OUString(
".uno:WrapIdeal"),
3539 OUString(
".uno:WrapOn"),
3540 OUString(
".uno:WrapOff"),
3541 OUString(
".uno:UpdateCurIndex"),
3542 OUString(
".uno:InsertCaptionDialog"),
3543 OUString(
".uno:FormatGroup"),
3544 OUString(
".uno:SplitTable"),
3545 OUString(
".uno:SplitCell"),
3546 OUString(
".uno:MergeCells"),
3547 OUString(
".uno:DeleteNote"),
3548 OUString(
".uno:AcceptChanges"),
3549 OUString(
".uno:FormatPaintbrush"),
3550 OUString(
".uno:SetDefault"),
3551 OUString(
".uno:ParaLeftToRight"),
3552 OUString(
".uno:ParaRightToLeft"),
3553 OUString(
".uno:ParaspaceIncrease"),
3554 OUString(
".uno:ParaspaceDecrease"),
3555 OUString(
".uno:AcceptTrackedChange"),
3556 OUString(
".uno:RejectTrackedChange"),
3557 OUString(
".uno:ShowResolvedAnnotations"),
3558 OUString(
".uno:InsertBreak"),
3559 OUString(
".uno:InsertEndnote"),
3560 OUString(
".uno:InsertFootnote"),
3561 OUString(
".uno:InsertReferenceField"),
3562 OUString(
".uno:InsertBookmark"),
3563 OUString(
".uno:InsertAuthoritiesEntry"),
3564 OUString(
".uno:InsertMultiIndex"),
3565 OUString(
".uno:InsertField"),
3566 OUString(
".uno:PageNumberWizard"),
3567 OUString(
".uno:InsertPageNumberField"),
3568 OUString(
".uno:InsertPageCountField"),
3569 OUString(
".uno:InsertDateField"),
3570 OUString(
".uno:InsertTitleField"),
3571 OUString(
".uno:InsertFieldCtrl"),
3572 OUString(
".uno:CharmapControl"),
3573 OUString(
".uno:EnterGroup"),
3574 OUString(
".uno:LeaveGroup"),
3575 OUString(
".uno:AlignUp"),
3576 OUString(
".uno:AlignMiddle"),
3577 OUString(
".uno:AlignDown"),
3578 OUString(
".uno:TraceChangeMode"),
3579 OUString(
".uno:Combine"),
3580 OUString(
".uno:Merge"),
3581 OUString(
".uno:Dismantle"),
3582 OUString(
".uno:Substract"),
3583 OUString(
".uno:DistributeSelection"),
3584 OUString(
".uno:Intersect"),
3585 OUString(
".uno:BorderInner"),
3586 OUString(
".uno:BorderOuter"),
3587 OUString(
".uno:FreezePanes"),
3588 OUString(
".uno:FreezePanesColumn"),
3589 OUString(
".uno:FreezePanesRow"),
3590 OUString(
".uno:Sidebar"),
3591 OUString(
".uno:SheetRightToLeft"),
3592 OUString(
".uno:RunMacro"),
3593 OUString(
".uno:SpacePara1"),
3594 OUString(
".uno:SpacePara15"),
3595 OUString(
".uno:SpacePara2"),
3596 OUString(
".uno:InsertSparkline"),
3597 OUString(
".uno:DeleteSparkline"),
3598 OUString(
".uno:DeleteSparklineGroup"),
3599 OUString(
".uno:EditSparklineGroup"),
3600 OUString(
".uno:EditSparkline"),
3601 OUString(
".uno:GroupSparklines"),
3602 OUString(
".uno:UngroupSparklines"),
3603 OUString(
".uno:FormatSparklineMenu"),
3604 OUString(
".uno:Protect"),
3605 OUString(
".uno:UnsetCellsReadOnly"),
3606 OUString(
".uno:ContentControlProperties"),
3607 OUString(
".uno:InsertCheckboxContentControl"),
3608 OUString(
".uno:InsertContentControl"),
3609 OUString(
".uno:InsertDateContentControl"),
3610 OUString(
".uno:InsertDropdownContentControl"),
3611 OUString(
".uno:InsertPlainTextContentControl"),
3612 OUString(
".uno:InsertPictureContentControl")
3615 util::URL aCommandURL;
3622 SAL_WARN(
"lok",
"iniUnoCommands: No Frame-Controller created.");
3630 SAL_WARN(
"lok",
"iniUnoCommands: Component context is not available");
3634#if !defined IOS && !defined ANDROID && !defined __EMSCRIPTEN__
3636 if (!xSEInitializer.is())
3638 SAL_WARN(
"lok",
"iniUnoCommands: XSEInitializer is not available");
3643 xSEInitializer->createSecurityContext(OUString());
3644 if (!xSecurityContext.is())
3646 SAL_WARN(
"lok",
"iniUnoCommands: failed to create security context");
3653 for (
const auto & sUnoCommand : sUnoCommands)
3655 aCommandURL.Complete = sUnoCommand;
3656 xParser->parseStrict(aCommandURL);
3673 return getDocumentType(pThis);
3682 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3689 return pDoc->getParts();
3699 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3706 return pDoc->getPart();
3709static void doc_setPartImpl(LibreOfficeKitDocument* pThis,
int nPart,
bool bAllowChangeFocus =
true)
3716 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3723 pDoc->setPart( nPart, bAllowChangeFocus );
3736 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3752 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3759 pDoc->selectPart( nPart, nSelect );
3768 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3775 pDoc->moveSelectedParts(nPosition, bDuplicate);
3785 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3800 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3820 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3842 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3859 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3877 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3885 int nCurrentPart = pDoc->getPart();
3887 pDoc->setPartMode(nPartMode);
3898 if ( nCurrentPart < pDoc->getParts() )
3900 pDoc->setPart( nCurrentPart );
3915 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3922 return pDoc->getEditMode();
3926 unsigned char* pBuffer,
3927 const int nCanvasWidth,
const int nCanvasHeight,
3928 const int nTilePosX,
const int nTilePosY,
3929 const int nTileWidth,
const int nTileHeight)
3936 SAL_INFO(
"lok.tiledrendering",
"paintTile: painting [" << nTileWidth <<
"x" << nTileHeight <<
3937 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3938 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3940 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3947#if defined(UNX) && !defined(MACOSX) || defined(_WIN32)
3957 double fDPIScale = 1.0;
3959 CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
3960 nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
3961 kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little);
3963 CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
3964 CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
3966 SAL_INFO(
"lok.tiledrendering",
"doc_paintTile: painting [" << nTileWidth <<
"x" << nTileHeight <<
3967 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3968 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3970 Size aCanvasSize(nCanvasWidth, nCanvasHeight);
3973 aData.rCGContext =
reinterpret_cast<CGContextRef
>(pCGContext);
3977 pDevice->SetOutputSizePixel(aCanvasSize);
3978 pDoc->paintTile(*pDevice, aCanvasSize.
Width(), aCanvasSize.
Height(),
3979 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3981 CGContextRelease(pCGContext);
3988 pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(
3992 pDoc->paintTile(*pDevice, nCanvasWidth, nCanvasHeight,
3993 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3995 static bool bDebug = getenv(
"LOK_DEBUG_TILES") !=
nullptr;
4000 aRect = pDevice->PixelToLogic(aRect);
4001 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
4003 pDevice->SetLineColor();
4004 pDevice->DrawRect(aRect);
4010 pDevice->EnableMapMode(
false);
4011 BitmapEx aBmpEx = pDevice->GetBitmapEx({ 0, 0 }, { nCanvasWidth, nCanvasHeight });
4017 assert(sraBmp->Height() == nCanvasHeight);
4018 assert(sraBmp->Width() == nCanvasWidth);
4019 assert(!sraAlpha || sraBmp->Height() == sraAlpha->Height());
4020 assert(!sraAlpha || sraBmp->Width() == sraAlpha->Width());
4024 Scanline dataBmp = sraBmp->GetScanline(
y);
4025 Scanline dataAlpha = sraAlpha ? sraAlpha->GetScanline(
y) :
nullptr;
4029 sal_uInt8 alpha = dataAlpha ? sraAlpha->GetPixelFromData(dataAlpha,
x).GetBlue() : 255;
4045 unsigned char* pBuffer,
4048 const int nCanvasWidth,
const int nCanvasHeight,
4049 const int nTilePosX,
const int nTilePosY,
4050 const int nTileWidth,
const int nTileHeight)
4057 SAL_INFO(
"lok.tiledrendering",
"paintPartTile: painting @ " << nPart <<
" : " << nMode <<
" ["
4058 << nTileWidth <<
"x" << nTileHeight <<
"]@("
4059 << nTilePosX <<
", " << nTilePosY <<
") to ["
4060 << nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
4065 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4072 if (nOrigViewId < 0)
4083 std::vector<int> viewIds(viewCount);
4086 nOrigViewId = viewIds[0];
4091 if (nOrigViewId >= 0)
4095 handlerIt->second->disableCallbacks();
4103 const bool isText = (aType == LOK_DOCTYPE_TEXT);
4104 const bool isCalc = (aType == LOK_DOCTYPE_SPREADSHEET);
4105 int nOrigEditMode = 0;
4106 bool bPaintTextEdit =
true;
4107 int nViewId = nOrigViewId;
4108 int nLastNonEditorView = -1;
4109 int nViewMatchingMode = -1;
4114 if (nPart !=
doc_getPart(pThis) || nMode != pDoc->getEditMode())
4124 if (pViewShell->
getPart() == nPart &&
4129 nViewMatchingMode = nViewId;
4130 nLastNonEditorView = nViewId;
4134 else if (pViewShell->
getEditMode() == nMode && !bIsInEdit)
4147 if (nViewMatchingMode >= 0 && nViewMatchingMode != nViewId)
4149 nViewId = nViewMatchingMode;
4152 else if (!isCalc && nLastNonEditorView >= 0 && nLastNonEditorView != nViewId &&
4153 pCurrentViewShell && pCurrentViewShell->
GetDrawView() &&
4156 nViewId = nLastNonEditorView;
4161 if (nViewId != nOrigViewId && nViewId >= 0)
4165 handlerIt->second->disableCallbacks();
4169 if (nPart != nOrigPart)
4174 nOrigEditMode = pDoc->getEditMode();
4175 if (nOrigEditMode != nMode)
4180 bPaintTextEdit = (nPart == nOrigPart && nMode == nOrigEditMode);
4181 pDoc->setPaintTextEdit(bPaintTextEdit);
4184 doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
4188 pDoc->setPaintTextEdit(
true);
4190 if (nMode != nOrigEditMode)
4195 if (nPart != nOrigPart)
4200 if (nViewId != nOrigViewId)
4206 handlerIt->second->enableCallbacks();
4213 catch (
const std::exception&)
4218 if (nOrigViewId >= 0)
4222 handlerIt->second->enableCallbacks();
4229 return LOK_TILEMODE_BGRA;
4241 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4244 Size aDocumentSize = pDoc->getDocumentSize();
4245 *pWidth = aDocumentSize.
Width();
4246 *pHeight = aDocumentSize.
Height();
4264 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4267 Size aDocumentSize = pDoc->getDataArea(nTab);
4268 *pCol = aDocumentSize.
Width();
4269 *pRow = aDocumentSize.
Height();
4278 const char* pArguments)
4285 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4289 pDoc->initializeForTiledRendering(
4295 LibreOfficeKitCallback pCallback,
4307 const size_t nId = nView;
4308 if (pCallback !=
nullptr)
4312 if (pair.first ==
nId)
4315 pair.second->addViewStates(nView);
4322 if (pair.first ==
nId)
4325 pair.second->removeViewStates(nView);
4331 if (pCallback !=
nullptr)
4335 if (pair.first ==
nId)
4349 std::string sPayload =
"{ \"fontsmissing\": [ ";
4357 sPayload +=
"\"" + std::string(f.toUtf8()) +
"\"";
4360 pCallback(LOK_CALLBACK_FONTS_MISSING, sPayload.c_str(),
pData);
4378 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4385 pDoc->getPostIts(aJsonWriter);
4393 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4400 pDoc->getPostItsPos(aJsonWriter);
4407 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4414 pDoc->getRulerState(aJsonWriter);
4418static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
int nType,
int nCharCode,
int nKeyCode)
4425 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4434 pDoc->postKeyEvent(
nType, nCharCode, nKeyCode);
4436 catch (
const uno::Exception& exception)
4439 SAL_INFO(
"lok",
"Failed to postKeyEvent " << exception.Message);
4457 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4463 pWindow = pDoc->getDocWindow();
4483 if (nLOKWindowId == 0)
4485 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4491 pWindow = pDoc->getDocWindow();
4507 if (nCharBefore > 0)
4510 if (nLOKWindowId == 0)
4513 for (
int i = 0;
i < nCharBefore; ++
i)
4514 pWindow->KeyInput(aEvt);
4523 if (nLOKWindowId == 0)
4526 for (
int i = 0;
i < nCharAfter; ++
i)
4527 pWindow->KeyInput(aEvt);
4552 case LOK_KEYEVENT_KEYINPUT:
4555 case LOK_KEYEVENT_KEYUP:
4588 case LOK_DOCTYPE_PRESENTATION:
4589 aMediaDescriptor[
"FilterName"] <<= OUString(
"impress_svg_Export");
4591 case LOK_DOCTYPE_DRAWING:
4592 aMediaDescriptor[
"FilterName"] <<= OUString(
"draw_svg_Export");
4594 case LOK_DOCTYPE_TEXT:
4595 aMediaDescriptor[
"FilterName"] <<= OUString(
"writer_svg_Export");
4597 case LOK_DOCTYPE_SPREADSHEET:
4598 aMediaDescriptor[
"FilterName"] <<= OUString(
"calc_svg_Export");
4601 SAL_WARN(
"lok",
"Failed to render shape selection: Document type is not supported");
4603 aMediaDescriptor[
"SelectionOnly"] <<=
true;
4604 aMediaDescriptor[
"OutputStream"] <<= xOut;
4605 aMediaDescriptor[
"IsPreview"] <<=
true;
4607 xStorable->storeToURL(
"private:stream", aMediaDescriptor.getAsConstPropertyValueList());
4612 *pOutput =
static_cast<char*
>(malloc(nOutputSize));
4615 std::memcpy(*pOutput, aOutStream.
GetData(), nOutputSize);
4620 catch (
const uno::Exception& exception)
4639class DispatchResultListener :
public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
4641 const OString maCommand;
4642 const std::shared_ptr<CallbackFlushHandler> mpCallback;
4643 const std::chrono::steady_clock::time_point mSaveTime;
4644 const bool mbWasModified;
4647 DispatchResultListener(
const char* pCommand, std::shared_ptr<CallbackFlushHandler> pCallback)
4648 : maCommand(pCommand)
4649 , mpCallback(
std::move(pCallback))
4650 , mSaveTime(
std::chrono::steady_clock::
now())
4656 virtual void SAL_CALL dispatchFinished(
const css::frame::DispatchResultEvent& rEvent)
override
4659 aJson.
put(
"commandName", maCommand);
4661 if (rEvent.State != frame::DispatchResultState::DONTKNOW)
4663 bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS);
4664 aJson.
put(
"success", bSuccess);
4668 aJson.
put(
"wasModified", mbWasModified);
4669 aJson.
put(
"startUnixTimeMics",
4670 std::chrono::time_point_cast<std::chrono::microseconds>(mSaveTime)
4673 aJson.
put(
"saveDurationMics", std::chrono::duration_cast<std::chrono::microseconds>(
4674 std::chrono::steady_clock::now() - mSaveTime)
4679 virtual void SAL_CALL disposing(
const css::lang::EventObject&)
override {}
4698 OUString sControlId =
aMap[
"id"];
4703 auto sCurrentShellId = OUString::number(nCurrentShellId);
4722static void doc_sendDialogEvent(LibreOfficeKitDocument* ,
unsigned long long int nWindowId,
const char* pArguments)
4727static void lo_sendDialogEvent(LibreOfficeKit* ,
unsigned long long int nWindowId,
const char* pArguments)
4732static void lo_setOption(LibreOfficeKit* ,
const char *pOption,
const char* pValue)
4734 static char* pCurrentSalLogOverride =
nullptr;
4736 if (strcmp(pOption,
"traceeventrecording") == 0)
4738 if (strcmp(pValue,
"start") == 0)
4745 else if (strcmp(pValue,
"stop") == 0)
4748 else if (strcmp(pOption,
"sallogoverride") == 0)
4750 if (pCurrentSalLogOverride !=
nullptr)
4751 free(pCurrentSalLogOverride);
4752 if (pValue ==
nullptr)
4753 pCurrentSalLogOverride =
nullptr;
4755 pCurrentSalLogOverride = strdup(pValue);
4757 if (pCurrentSalLogOverride ==
nullptr || pCurrentSalLogOverride[0] ==
'\0')
4758 sal_detail_set_log_selector(
nullptr);
4760 sal_detail_set_log_selector(pCurrentSalLogOverride);
4763 else if (strcmp(pOption,
"addfont") == 0)
4765 if (memcmp(pValue,
"file://", 7) == 0)
4768 int fd = open(pValue, O_RDONLY);
4771 std::cerr <<
"Could not open font file '" << pValue <<
"': " << strerror(errno) << std::endl;
4775 OUString sMagicFileName =
"file:///:FD:/" + OUString::number(fd);
4785static void lo_dumpState (LibreOfficeKit* pThis,
const char* ,
char** pState)
4794 OStringBuffer aState(4096*256);
4798 pLib->dumpState(aState);
4800 OString
aStr = aState.makeStringAndClear();
4801 *pState = strdup(
aStr.getStr());
4806 rState.append(
"LibreOfficeKit state:");
4807 rState.append(
"\n\tLastExceptionMsg:\t");
4809 rState.append(
"\n\tUnipoll:\t");
4811 rState.append(
"\n\tOptionalFeatures:\t0x");
4813 rState.append(
"\n\tCallbackData:\t0x");
4814 rState.append(
reinterpret_cast<sal_Int64
>(
mpCallback), 16);
4820static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand,
const char* pArguments,
bool bNotifyWhenFinished)
4828 OUString
aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
4835 beans::PropertyValue aSynchronMode;
4836 aSynchronMode.Name =
"SynchronMode";
4837 aSynchronMode.Value <<=
false;
4838 aPropertyValuesVector.push_back(aSynchronMode);
4847 ExecuteOrientationChange();
4855 OUString
aMimeType = lcl_getCurrentDocumentMimeType(pDocument);
4862 OUString
aURL = xStorable->getLocation();
4864 bool bResult =
doc_saveAs(pThis, aURLUtf8.getStr(),
"pdf",
nullptr);
4868 aJson.
put(
"commandName", pCommand);
4869 aJson.
put(
"success", bResult);
4879 beans::PropertyValue aValue;
4880 aValue.Name =
"InteractionHandler";
4881 aValue.Value <<= xInteraction;
4882 aPropertyValuesVector.push_back(aValue);
4884 bool bDontSaveIfUnmodified =
false;
4885 aPropertyValuesVector.erase(std::remove_if(aPropertyValuesVector.begin(),
4886 aPropertyValuesVector.end(),
4887 [&bDontSaveIfUnmodified](
const beans::PropertyValue& aItem){
4888 if (aItem.Name ==
"DontSaveIfUnmodified")
4890 bDontSaveIfUnmodified = aItem.Value.get<bool>();
4894 }), aPropertyValuesVector.end());
4897 if (bDontSaveIfUnmodified && (!pDocSh || !pDocSh->
IsModified()))
4900 aJson.
put(
"commandName", pCommand);
4901 aJson.
put(
"success",
false);
4904 auto resultNode = aJson.
startNode(
"result");
4905 aJson.
put(
"type",
"string");
4906 aJson.
put(
"value",
"unmodified");
4912 else if (
gImpl && aCommand ==
".uno:TransformDialog")
4914 bool bNeedConversion =
false;
4918 if (aChartHelper.GetWindow() )
4920 bNeedConversion =
true;
4924 if (
OutputDevice* pOutputDevice = pView->GetFirstOutputDevice())
4926 bNeedConversion = (pOutputDevice->GetMapMode().GetMapUnit() == MapUnit::Map100thMM);
4930 if (bNeedConversion)
4933 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
4935 if (rPropValue.Name ==
"TransformPosX"
4936 || rPropValue.Name ==
"TransformPosY"
4937 || rPropValue.Name ==
"TransformWidth"
4938 || rPropValue.Name ==
"TransformHeight"
4939 || rPropValue.Name ==
"TransformRotationX"
4940 || rPropValue.Name ==
"TransformRotationY")
4942 rPropValue.Value >>=
value;
4944 rPropValue.Value <<=
value;
4949 if (aChartHelper.GetWindow() && aPropertyValuesVector.size() > 0)
4951 if (aPropertyValuesVector[0].Name !=
"Action")
4958 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
4960 if (rPropValue.Name ==
"TransformPosX" || rPropValue.Name ==
"TransformRotationX")
4962 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
4963 rPropValue.Value <<=
value - nLeft;
4965 else if (rPropValue.Name ==
"TransformPosY" || rPropValue.Name ==
"TransformRotationY")
4967 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
4968 rPropValue.Value <<=
value - nTop;
4972 util::URL aCommandURL;
4973 aCommandURL.Path =
"LOKTransform";
4974 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
4979 else if (
gImpl && aCommand ==
".uno:LOKSidebarWriterPage")
4981 setupSidebar(u
"WriterPageDeck");
4984 else if (
gImpl && aCommand ==
".uno:SidebarShow")
4989 else if (
gImpl && aCommand ==
".uno:SidebarHide")
4995 bool bResult =
false;
4998 if (aChartHelper.GetWindow() && aCommand !=
".uno:Save" )
5000 util::URL aCommandURL;
5001 aCommandURL.Path =
aCommand.copy(5);
5002 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
5026static void doc_postMouseEvent(LibreOfficeKitDocument* pThis,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
5033 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5041 pDoc->postMouseEvent(
nType, nX, nY,
nCount, nButtons, nModifier);
5043 catch (
const uno::Exception& exception)
5046 SAL_INFO(
"lok",
"Failed to postMouseEvent " << exception.Message);
5050static void doc_postWindowMouseEvent(LibreOfficeKitDocument* ,
unsigned nLOKWindowId,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
5064 const Point aPos(nX, nY);
5072 case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
5075 case LOK_MOUSEEVENT_MOUSEBUTTONUP:
5078 case LOK_MOUSEEVENT_MOUSEMOVE:
5101 OString aType(pType);
5104 if (aType ==
"panBegin")
5105 eEventType = GestureEventPanType::Begin;
5106 else if (aType ==
"panEnd")
5107 eEventType = GestureEventPanType::End;
5114 PanningOrientation::Vertical,
5129 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5136 pDoc->setTextSelection(
nType, nX, nY);
5154 Size aOffset(pWindow->GetOutOffXPixel(), pWindow->GetOutOffYPixel());
5155 Point aCursorPos(nX, nY);
5156 aCursorPos.Move(aOffset);
5159 MouseEvent aCursorEvent(aCursorPos, 1, MouseEventModifiers::SIMPLECLICK, 0, nModifier);
5165 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5166 const OString &aInMimeType, OString &aRet);
5169 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5170 const OString &aMimeType, OString &aRet)
5176 auto aSeq = Sequence<sal_Int8>(
reinterpret_cast<const sal_Int8*
>(aRet.getStr()),
5178 OStringBuffer aBase64Data;
5182 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
5184 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
5185 "name=\"generator\" content=\""
5188 "</head><body><img src=\"data:" +
aMimeType +
";base64,"
5189 + aBase64Data +
"\"/></body></html>";
5195 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5196 const OString &aMimeType, OString &aRet)
5202 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
5204 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
5205 "name=\"generator\" content=\""
5207 +
"\"/></head><body><pre>" + aRet +
"</pre></body></html>";
5213 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5214 const OString &aInMimeType, OString &aRet)
5219 bool bConvert =
false;
5225 aMimeType =
"text/plain;charset=utf-16";
5230 datatransfer::DataFlavor aFlavor;
5231 aFlavor.MimeType = OUString::fromUtf8(
aMimeType);
5232 if (
aMimeType ==
"text/plain;charset=utf-16")
5237 if (!xTransferable->isDataFlavorSupported(aFlavor))
5240 if (aInMimeType ==
"text/html")
5257 aAny = xTransferable->getTransferData(aFlavor);
5259 catch (
const css::datatransfer::UnsupportedFlavorException& e)
5261 SetLastExceptionMsg(
"Unsupported flavor " + aFlavor.MimeType +
" exception " + e.Message);
5264 catch (
const css::uno::Exception& e)
5277 aRet = OString(
reinterpret_cast<const char *
>(aString.getStr()), aString.getLength() *
sizeof(
sal_Unicode));
5283 aRet = OString(
reinterpret_cast<const char*
>(aSequence.getConstArray()), aSequence.getLength());
5296 ITiledRenderable* pDoc = getTiledRenderable(pThis);