11#include <config_buildconfig.h>
12#include <config_cairo_rgba.h>
13#include <config_features.h>
22#include <unicode/udata.h>
23#include <unicode/ucnv.h>
25#import <Foundation/Foundation.h>
26#import <CoreGraphics/CoreGraphics.h>
30#undef HAVE_MALLOC_TRIM
36# define HAVE_MALLOC_TRIM
41#include <osl/detail/android-bootstrap.h>
45#include <osl/detail/emscripten-bootstrap.h>
53#include <boost/property_tree/json_parser.hpp>
54#include <boost/algorithm/string.hpp>
56#include <LibreOfficeKit/LibreOfficeKit.h>
57#include <LibreOfficeKit/LibreOfficeKitEnums.h>
66#include <osl/file.hxx>
67#include <osl/process.h>
68#include <osl/thread.h>
69#include <rtl/bootstrap.hxx>
70#include <rtl/strbuf.hxx>
88#include <com/sun/star/document/MacroExecMode.hpp>
89#include <com/sun/star/beans/XPropertySet.hpp>
90#include <com/sun/star/container/XNameAccess.hpp>
91#include <com/sun/star/document/XDocumentLanguages.hpp>
92#include <com/sun/star/frame/Desktop.hpp>
93#include <com/sun/star/frame/DispatchResultEvent.hpp>
94#include <com/sun/star/frame/DispatchResultState.hpp>
95#include <com/sun/star/frame/XDispatchProvider.hpp>
96#include <com/sun/star/frame/XDispatchResultListener.hpp>
97#include <com/sun/star/frame/XSynchronousDispatch.hpp>
98#include <com/sun/star/frame/XStorable.hpp>
99#include <com/sun/star/lang/Locale.hpp>
100#include <com/sun/star/lang/XComponent.hpp>
101#include <com/sun/star/lang/XMultiServiceFactory.hpp>
102#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
103#include <com/sun/star/util/URLTransformer.hpp>
104#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
105#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
106#include <com/sun/star/datatransfer/XTransferable2.hpp>
107#include <com/sun/star/text/TextContentAnchorType.hpp>
108#include <com/sun/star/document/XRedlinesSupplier.hpp>
109#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
111#include <com/sun/star/xml/crypto/SEInitializer.hpp>
112#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
113#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
114#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
115#include <com/sun/star/security/XCertificate.hpp>
117#include <com/sun/star/linguistic2/LanguageGuessing.hpp>
118#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
119#include <com/sun/star/linguistic2/XSpellChecker.hpp>
120#include <com/sun/star/i18n/LocaleCalendar2.hpp>
121#include <com/sun/star/i18n/ScriptType.hpp>
122#include <com/sun/star/lang/DisposedException.hpp>
141#include <svx/strings.hrc>
143#include <svx/svxids.hrc>
164#include <unicode/uchar.h>
172#include <osl/module.hxx>
185#include <com/sun/star/document/XUndoManager.hpp>
186#include <com/sun/star/document/XUndoManagerSupplier.hpp>
187#include <com/sun/star/document/XLinkTargetSupplier.hpp>
194#include "../app/cmdlineargs.hxx"
196#include "../app/sofficemain.h"
197#include "../app/officeipcthread.hxx"
202#include <officecfg/Office/Common.hxx>
203#include <officecfg/Office/Impress.hxx>
204#include <officecfg/Office/Linguistic.hxx>
221#include <officecfg/Setup.hxx>
222#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
237 SAL_WARN_IF(!s.isEmpty(),
"lok",
"lok exception '" + s +
"'");
247 const char *filterName;
252 static const int dumpTimeoutMS = 5000;
255 TraceEventDumper() :
AutoTimer(
"Trace Event dumper" )
261 virtual void Invoke()
override
266 static void flushRecordings()
268 const css::uno::Sequence<OUString> aEvents =
270 OStringBuffer aOutput;
271 for (
const auto &s : aEvents)
276 if (aOutput.getLength() > 0)
278 OString aChunk = aOutput.makeStringAndClear();
291 {
"doc",
"MS Word 97" },
292 {
"docm",
"MS Word 2007 XML VBA" },
293 {
"docx",
"MS Word 2007 XML" },
294 {
"fodt",
"OpenDocument Text Flat XML" },
295 {
"html",
"HTML (StarWriter)" },
296 {
"odt",
"writer8" },
297 {
"ott",
"writer8_template" },
298 {
"pdf",
"writer_pdf_Export" },
300 {
"rtf",
"Rich Text Format" },
302 {
"xhtml",
"XHTML Writer File" },
303 {
"png",
"writer_png_Export" },
304 {
"xml",
"writer_indexing_export" },
310 {
"csv",
"Text - txt - csv (StarCalc)" },
311 {
"fods",
"OpenDocument Spreadsheet Flat XML" },
312 {
"html",
"HTML (StarCalc)" },
314 {
"ots",
"calc8_template" },
315 {
"pdf",
"calc_pdf_Export" },
316 {
"xhtml",
"XHTML Calc File" },
317 {
"xls",
"MS Excel 97" },
318 {
"xlsm",
"Calc MS Excel 2007 VBA XML" },
319 {
"xlsx",
"Calc MS Excel 2007 XML" },
320 {
"png",
"calc_png_Export" },
326 {
"fodp",
"OpenDocument Presentation Flat XML" },
327 {
"html",
"impress_html_Export" },
328 {
"odg",
"impress8_draw" },
329 {
"odp",
"impress8" },
330 {
"otp",
"impress8_template" },
331 {
"pdf",
"impress_pdf_Export" },
332 {
"potm",
"Impress MS PowerPoint 2007 XML Template" },
333 {
"pot",
"MS PowerPoint 97 Vorlage" },
334 {
"pptm",
"Impress MS PowerPoint 2007 XML VBA" },
335 {
"pptx",
"Impress MS PowerPoint 2007 XML" },
336 {
"pps",
"MS PowerPoint 97 Autoplay" },
337 {
"ppt",
"MS PowerPoint 97" },
338 {
"svg",
"impress_svg_Export" },
339 {
"xhtml",
"XHTML Impress File" },
340 {
"png",
"impress_png_Export"},
346 {
"fodg",
"draw_ODG_FlatXML" },
347 {
"html",
"draw_html_Export" },
349 {
"pdf",
"draw_pdf_Export" },
350 {
"svg",
"draw_svg_Export" },
351 {
"xhtml",
"XHTML Draw File" },
352 {
"png",
"draw_png_Export"},
358 if (pString ==
nullptr)
361 std::string_view sString(pString, strlen(pString));
362 return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
368 char* pMemory =
static_cast<char*
>(malloc(rStr.getLength() + 1));
370 memcpy(pMemory, rStr.getStr(), rStr.getLength() + 1);
387 OUString aWorkingDir;
388 osl_getProcessWorkingDir(&aWorkingDir.pData);
389 if (!aWorkingDir.endsWith(
"/"))
394 return rtl::Uri::convertRelToAbs(aWorkingDir,
aURL);
396 catch (
const rtl::MalformedUriException &)
406 if (pJSON && pJSON[0] !=
'\0')
417 const sal_uLong nLinks = aNames.getLength();
418 const OUString* pNames = aNames.getConstArray();
419 static constexpr OUStringLiteral aProp_LinkDisplayName(
u"LinkDisplayName" );
420 static constexpr OUStringLiteral aProp_LinkTarget(
u"com.sun.star.document.LinkTarget" );
421 bool bIsTarget =
false;
425 OUString aLink( *pNames++ );
430 aAny = xLinks->getByName( aLink );
432 catch(
const uno::Exception&)
447 aAny =
xTarget->getPropertyValue( aProp_LinkDisplayName );
448 OUString aDisplayName;
449 aAny >>= aDisplayName;
450 OUString aStrDisplayname ( aDisplayName );
454 aJson.
put(aStrDisplayname, aLink);
459 bIsTarget = xSI->supportsService( aProp_LinkTarget );
463 aJson.
put(aStrDisplayname, aLink);
479 SAL_WARN(
"lok",
"extractLinks: Exception");
488 OUString aType = anyItem.getValueTypeName();
489 rJson.
put(
"type", aType);
491 if (aType ==
"string")
492 rJson.
put(
"value", anyItem.get<OUString>());
493 else if (aType ==
"unsigned long")
494 rJson.
put(
"value", OString::number(anyItem.get<sal_uInt32>()));
495 else if (aType ==
"long")
496 rJson.
put(
"value", OString::number(anyItem.get<sal_Int32>()));
497 else if (aType ==
"[]any")
500 if (anyItem >>=
aSeq)
502 auto valueNode = rJson.
startNode(
"value");
504 for (
auto i = 0;
i <
aSeq.getLength(); ++
i)
519 if (rPayload.startsWith(
"EMPTY"))
524 int nSeparatorPos = rPayload.indexOf(
',', 6);
525 bool bHasMode = nSeparatorPos > 0;
529 assert(rPayload.getLength() > nSeparatorPos);
543 const char*
pos = rPayload.getStr();
544 const char*
end = rPayload.getStr() + rPayload.getLength();
569 nPart = rtl_str_toInt64_WithLength(
pos, 10,
end -
pos);
571 while( *
pos && *
pos !=
',' )
577 nMode = rtl_str_toInt64_WithLength(
pos, 10,
end -
pos);
589 if (nWidth <= 0 || nHeight <= 0)
606 if (nWidth > 0 && nHeight > 0)
631 PayloadObject = rRectAndPart;
632 PayloadString.clear();
639 if(PayloadObject.which() != 1)
641 return boost::get<RectangleAndPart>(PayloadObject);
646 boost::property_tree::ptree aTree;
647 std::stringstream aStream(payload);
648 boost::property_tree::read_json(aStream, aTree);
654 return boost::get<boost::property_tree::ptree>(PayloadObject);
659 std::stringstream aJSONStream;
660 constexpr bool bPretty =
false;
661 boost::property_tree::write_json(aJSONStream, rTree, bPretty);
662 PayloadString = OString(
o3tl::trim(aJSONStream.str()));
664 PayloadObject = rTree;
669 assert(PayloadObject.which() == 2);
670 return boost::get<boost::property_tree::ptree>(PayloadObject);
677 assert(PayloadObject.which() == 3);
678 return boost::get<int>(PayloadObject);
685 switch (PayloadObject.which())
693 return getRectangleAndPart().toString().getStr() == getPayload();
698 std::stringstream aJSONStream;
699 boost::property_tree::write_json(aJSONStream, getJson(),
false);
700 const std::string aExpected = boost::trim_copy(aJSONStream.str());
701 return getPayload() == std::string_view(aExpected);
709 assert(!
"Unknown variant type; please add an entry to validate.");
721 case LOK_CALLBACK_CELL_VIEW_CURSOR:
722 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
723 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
724 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
725 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
737 case LOK_CALLBACK_TEXT_SELECTION:
738 case LOK_CALLBACK_TEXT_SELECTION_START:
739 case LOK_CALLBACK_TEXT_SELECTION_END:
750 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
751 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
752 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
763 size_t viewIdPos = payload.find(
"viewId");
764 if (viewIdPos == std::string::npos)
767 size_t numberPos = payload.find(
":", viewIdPos + 6);
768 if (numberPos == std::string::npos)
771 for (++numberPos; numberPos < payload.length(); ++numberPos)
773 if (payload[numberPos] ==
',' || payload[numberPos] ==
'}' || (payload[numberPos] >=
'0' && payload[numberPos] <=
'9'))
777 if (numberPos < payload.length() && payload[numberPos] >=
'0' && payload[numberPos] <=
'9')
785std::string extractCertificate(
const std::string & certificate)
787 const std::string
header(
"-----BEGIN CERTIFICATE-----");
788 const std::string footer(
"-----END CERTIFICATE-----");
792 size_t pos1 = certificate.find(header);
793 if (pos1 == std::string::npos)
796 size_t pos2 = certificate.find(footer, pos1 + 1);
797 if (pos2 == std::string::npos)
800 pos1 = pos1 +
header.length();
803 return certificate.substr(pos1, pos2);
806std::string extractPrivateKey(
const std::string & privateKey)
808 const std::string
header(
"-----BEGIN PRIVATE KEY-----");
809 const std::string footer(
"-----END PRIVATE KEY-----");
813 size_t pos1 = privateKey.find(header);
814 if (pos1 == std::string::npos)
817 size_t pos2 = privateKey.find(footer, pos1 + 1);
818 if (pos2 == std::string::npos)
821 pos1 = pos1 +
header.length();
824 return privateKey.substr(pos1, pos2);
845 return pFilter->GetMimeType();
849css::uno::Reference< css::document::XUndoManager > getUndoManager(
const css::uno::Reference< css::frame::XFrame >& rxFrame )
851 const css::uno::Reference< css::frame::XController >&
xController = rxFrame->getController();
854 const css::uno::Reference< css::frame::XModel >&
xModel =
xController->getModel();
857 const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW );
858 return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW );
862 return css::uno::Reference< css::document::XUndoManager > ();
866void ExecuteMarginLRChange(
871 pPageLRMarginItem->
SetLeft( nPageLeftMargin );
872 pPageLRMarginItem->
SetRight( nPageRightMargin );
874 SfxCallMode::RECORD, { pPageLRMarginItem });
878void ExecuteMarginULChange(
883 pPageULMarginItem->
SetUpper( nPageTopMargin );
884 pPageULMarginItem->
SetLower( nPageBottomMargin );
886 SfxCallMode::RECORD, { pPageULMarginItem });
890void ExecuteOrientationChange()
896 std::unique_ptr<SvxPageItem> pPageItem(
new SvxPageItem(SID_ATTR_PAGE));
902 css::uno::Reference< css::document::XUndoManager > mxUndoManager(
905 if ( mxUndoManager.is() )
906 mxUndoManager->enterUndoContext(
"" );
911 std::unique_ptr<SvxSizeItem> pPageSizeItem(pSizeItem->
Clone());
915 std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(pLRSpaceItem->
Clone());
919 std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(pULSpaceItem->
Clone());
922 bool bIsLandscape =
false;
923 if ( pPageSizeItem->GetSize().Width() > pPageSizeItem->GetSize().Height())
927 pPageItem->SetLandscape(!bIsLandscape);
931 const tools::Long nRotatedWidth = pPageSizeItem->GetSize().Height();
932 const tools::Long nRotatedHeight = pPageSizeItem->GetSize().Width();
933 pPageSizeItem->SetSize(
Size(nRotatedWidth, nRotatedHeight));
940 SfxCallMode::RECORD, { pPageSizeItem.get(), pPageItem.get() });
952 const tools::Long nPW = pPageSizeItem->GetSize().Width();
958 ExecuteMarginLRChange( pPageLRMarginItem->
GetLeft(), nMR - (nTmpPW - nPW ), pPageLRMarginItem.get() );
962 ExecuteMarginLRChange( nML - (nTmpPW - nPW ), pPageLRMarginItem->
GetRight(), pPageLRMarginItem.get() );
970 const tools::Long nPH = pPageSizeItem->GetSize().Height();
976 ExecuteMarginULChange( pPageULMarginItem->
GetUpper(), nMB - ( nTmpPH - nPH ), pPageULMarginItem.get() );
980 ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), pPageULMarginItem->
GetLower(), pPageULMarginItem.get() );
985 if ( mxUndoManager.is() )
986 mxUndoManager->leaveUndoContext();
989void setupSidebar(std::u16string_view sidebarDeckId = u
"")
1012 = pDockingWin->GetOrCreateSidebarController();
1017 if (!sidebarDeckId.empty())
1026 pDockingWin->SyncUpdate();
1050 OUString aNameEquals(OUString::Concat(rName) +
"=");
1051 OUString aCommaNameEquals(OUString::Concat(
",") + rName +
"=");
1054 if (rOptions.startsWith(aNameEquals))
1056 size_t nLen = aNameEquals.getLength();
1057 int nComma = rOptions.indexOf(
",", nLen);
1060 aValue = rOptions.copy(nLen, nComma - nLen);
1061 rOptions = rOptions.copy(nComma + 1);
1065 aValue = rOptions.copy(nLen);
1069 else if ((
nIndex = rOptions.indexOf(aCommaNameEquals)) >= 0)
1071 size_t nLen = aCommaNameEquals.getLength();
1072 int nComma = rOptions.indexOf(
",",
nIndex + nLen);
1075 aValue = rOptions.copy(
nIndex + nLen, nComma -
nIndex - nLen);
1076 rOptions = OUString::Concat(rOptions.subView(0,
nIndex)) + rOptions.subView(nComma);
1080 aValue = rOptions.copy(
nIndex + nLen);
1081 rOptions = rOptions.copy(0,
nIndex);
1091static void doc_destroy(LibreOfficeKitDocument* pThis);
1092static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* pUrl,
const char* pFormat,
const char* pFilterOptions);
1096static int doc_getPart(LibreOfficeKitDocument* pThis);
1097static void doc_setPart(LibreOfficeKitDocument* pThis,
int nPart);
1098static void doc_selectPart(LibreOfficeKitDocument* pThis,
int nPart,
int nSelect);
1100static char*
doc_getPartName(LibreOfficeKitDocument* pThis,
int nPart);
1101static void doc_setPartMode(LibreOfficeKitDocument* pThis,
int nPartMode);
1104 unsigned char* pBuffer,
1105 const int nCanvasWidth,
const int nCanvasHeight,
1106 const int nTilePosX,
const int nTilePosY,
1107 const int nTileWidth,
const int nTileHeight);
1109 unsigned char* pBuffer,
1112 const int nCanvasWidth,
const int nCanvasHeight,
1113 const int nTilePosX,
const int nTilePosY,
1114 const int nTileWidth,
const int nTileHeight);
1124 const char* pArguments);
1127 LibreOfficeKitCallback pCallback,
1135 const char* blockedCommandList);
1142 unsigned nLOKWindowId,
1146 unsigned long long int nLOKWindowId,
1147 const char* pArguments);
1149 unsigned nLOKWindowId,
1161 unsigned nLOKWindowId,
1169 unsigned nLOKWindowId,
1175 const char* pCommand,
1176 const char* pArguments,
1177 bool bNotifyWhenFinished);
1179 unsigned nLOKWindowId,
1188 const char* pMimeType,
1189 char** pUsedMimeType);
1192 const char* pMimeType,
1194 char** pUsedMimeType);
1196 const char **pMimeTypes,
1198 char ***pOutMimeTypes,
1200 char ***pOutStreams);
1202 const size_t nInCount,
1203 const char **pInMimeTypes,
1204 const size_t *pInSizes,
1205 const char **pInStreams);
1206static bool doc_paste(LibreOfficeKitDocument* pThis,
1207 const char* pMimeType,
1217 int nTilePixelWidth,
1218 int nTilePixelHeight,
1220 int nTileTwipHeight);
1222static void doc_setOutlineState(LibreOfficeKitDocument* pThis,
bool bColumn,
int nLevel,
int nIndex,
bool bHidden);
1232 const char *pFontName,
1237static unsigned char*
doc_renderFont(LibreOfficeKitDocument* pThis,
1238 const char *pFontName,
1242static char*
doc_getPartHash(LibreOfficeKitDocument* pThis,
int nPart);
1244static void doc_paintWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1245 const int nX,
const int nY,
1246 const int nWidth,
const int nHeight);
1248static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1249 const int nX,
const int nY,
1250 const int nWidth,
const int nHeight,
1251 const double fDPIScale);
1253static void doc_paintWindowForView(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1254 const int nX,
const int nY,
1255 const int nWidth,
const int nHeight,
1256 const double fDPIScale,
int viewId);
1258static void doc_postWindow(LibreOfficeKitDocument* pThis,
unsigned
1259 nLOKWindowId,
int nAction,
const char* pData);
1261static char*
doc_getPartInfo(LibreOfficeKitDocument* pThis,
int nPart);
1264 const unsigned char* pCertificateBinary,
1265 const int nCertificateBinarySize,
1266 const unsigned char* pPrivateKeyBinary,
1267 const int nPrivateKeyBinarySize);
1270 const unsigned char* pCertificateBinary,
1271 const int nCertificateBinarySize);
1277static void doc_resizeWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
1278 const int nWidth,
const int nHeight);
1284 const char* pArguments);
1287 const char* pSearchResult,
unsigned char** pBitmapBuffer,
1288 int* pWidth,
int* pHeight,
size_t* pByteSize);
1302ITiledRenderable* getTiledRenderable(LibreOfficeKitDocument* pThis)
1305 return dynamic_cast<ITiledRenderable*
>(pDocument->
mxComponent.get());
1317 ITiledRenderable* pDoc = getTiledRenderable(pThis);
1320 SAL_INFO(
"lok",
"Set to clipboard for view " << xClip.get());
1329const vcl::Font* FindFont(std::u16string_view rFontName)
1337 if (pList && !rFontName.empty())
1343vcl::Font FindFont_FallbackToDefault(std::u16string_view rFontName)
1345 if (
auto pFound = FindFont(rFontName))
1349 GetDefaultFontFlags::NONE);
1352int getDocumentType (LibreOfficeKitDocument* pThis)
1362 if (xDocument->supportsService(
"com.sun.star.sheet.SpreadsheetDocument"))
1364 return LOK_DOCTYPE_SPREADSHEET;
1366 else if (xDocument->supportsService(
"com.sun.star.presentation.PresentationDocument"))
1368 return LOK_DOCTYPE_PRESENTATION;
1370 else if (xDocument->supportsService(
"com.sun.star.drawing.DrawingDocument"))
1372 return LOK_DOCTYPE_DRAWING;
1374 else if (xDocument->supportsService(
"com.sun.star.text.TextDocument") || xDocument->supportsService(
"com.sun.star.text.WebDocument"))
1376 return LOK_DOCTYPE_TEXT;
1383 catch (
const uno::Exception& exception)
1387 return LOK_DOCTYPE_OTHER;
1393 : mxComponent(
std::move(xComponent))
1394 , mnDocumentId(nDocumentId)
1396 assert(nDocumentId != -1 &&
"Cannot set mnDocumentId to -1");
1497 forceSetClipboardForCurrentView(
this);
1507 catch (
const css::lang::DisposedException&)
1515 OUString sGenerator(
1517 OUString os(
"$_OS");
1518 ::rtl::Bootstrap::expandMacros(os);
1519 return sGenerator.replaceFirst(
"%1", os);
1525 :
Timer(
"lokit timer callback" )
1526 , mHandler( handler )
1541 :
Idle(
"lokit idle callback" ),
1552 m_states.emplace(LOK_CALLBACK_TEXT_SELECTION,
"NIL");
1553 m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION,
"NIL");
1554 m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
"NIL");
1555 m_states.emplace(LOK_CALLBACK_STATE_CHANGED,
"NIL");
1556 m_states.emplace(LOK_CALLBACK_MOUSE_POINTER,
"NIL");
1557 m_states.emplace(LOK_CALLBACK_CELL_CURSOR,
"NIL");
1558 m_states.emplace(LOK_CALLBACK_CELL_FORMULA,
"NIL");
1559 m_states.emplace(LOK_CALLBACK_CELL_ADDRESS,
"NIL");
1560 m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE,
"NIL");
1561 m_states.emplace(LOK_CALLBACK_SET_PART,
"NIL");
1562 m_states.emplace(LOK_CALLBACK_TABLE_SELECTED,
"NIL");
1563 m_states.emplace(LOK_CALLBACK_TAB_STOP_LIST,
"NIL");
1564 m_states.emplace(LOK_CALLBACK_RULER_UPDATE,
"NIL");
1565 m_states.emplace(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE,
"NIL");
1575 int delta = std::distance(
m_queue1.begin(), pos);
1581 int delta = std::distance(
m_queue1.rbegin(), pos);
1605 types.resize(
nType + 1 );
1614 bool allViewIds =
false;
1625 std::vector<PerViewIdData>& types = it.second;
1627 types[
nType ].set =
false;
1646 queue(LOK_CALLBACK_INVALIDATE_TILES, callbackData);
1652 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1660 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1668 rState.append(
"\nView:\t");
1669 rState.append(
static_cast<sal_Int32
>(
m_viewId));
1670 rState.append(
"\n\tDisableCallbacks:\t");
1672 rState.append(
"\n\tStates:\n");
1675 rState.append(
"\n\t\t");
1676 rState.append(
static_cast<sal_Int32
>(
i.first));
1677 rState.append(
"\t");
1678 rState.append(
i.second);
1700 bool bIsChartActive =
false;
1701 bool bIsComment =
false;
1702 if (
type == LOK_CALLBACK_GRAPHIC_SELECTION)
1705 bIsChartActive = aChartHelper.
GetWindow() !=
nullptr;
1707 else if (
type == LOK_CALLBACK_COMMENT)
1721 if (
type != LOK_CALLBACK_STATE_CHANGED &&
1722 type != LOK_CALLBACK_INVALIDATE_TILES &&
1723 type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1724 type != LOK_CALLBACK_CURSOR_VISIBLE &&
1725 type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE &&
1726 type != LOK_CALLBACK_TEXT_SELECTION &&
1727 type != LOK_CALLBACK_TEXT_SELECTION_START &&
1728 type != LOK_CALLBACK_TEXT_SELECTION_END &&
1729 type != LOK_CALLBACK_MEDIA_SHAPE &&
1730 type != LOK_CALLBACK_REFERENCE_MARKS)
1742 if (
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1743 aCallbackData.
getPayload().indexOf(
", 0, 0, ") != -1 &&
1744 aCallbackData.
getPayload().indexOf(
"\"hyperlink\":\"\"") == -1 &&
1745 aCallbackData.
getPayload().indexOf(
"\"hyperlink\": {}") == -1)
1755 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1762 SAL_INFO(
"lok",
"Received event with updated type [" <<
type <<
"] as normal callback");
1767 SAL_INFO(
"lok",
"Received event with updated type [" <<
type <<
"] as normal callback");
1774 case LOK_CALLBACK_TEXT_SELECTION_START:
1775 case LOK_CALLBACK_TEXT_SELECTION_END:
1776 case LOK_CALLBACK_TEXT_SELECTION:
1777 case LOK_CALLBACK_GRAPHIC_SELECTION:
1778 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1779 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1780 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1781 case LOK_CALLBACK_STATE_CHANGED:
1782 case LOK_CALLBACK_MOUSE_POINTER:
1783 case LOK_CALLBACK_CELL_CURSOR:
1784 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1785 case LOK_CALLBACK_CELL_FORMULA:
1786 case LOK_CALLBACK_CELL_ADDRESS:
1787 case LOK_CALLBACK_CELL_SELECTION_AREA:
1788 case LOK_CALLBACK_CURSOR_VISIBLE:
1789 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1790 case LOK_CALLBACK_SET_PART:
1791 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1792 case LOK_CALLBACK_INVALIDATE_HEADER:
1793 case LOK_CALLBACK_WINDOW:
1794 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1795 case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
1796 case LOK_CALLBACK_REFERENCE_MARKS:
1797 case LOK_CALLBACK_CELL_AUTO_FILL_AREA:
1798 case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
1799 case LOK_CALLBACK_A11Y_CARET_CHANGED:
1800 case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
1801 case LOK_CALLBACK_COLOR_PALETTES:
1814 if (
type == LOK_CALLBACK_TEXT_SELECTION && aCallbackData.
isEmpty())
1816 const auto& posStart = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_TEXT_SELECTION_START);
1817 auto posStart2 =
toQueue2(posStart);
1821 const auto& posEnd = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_TEXT_SELECTION_END);
1832 case LOK_CALLBACK_TEXT_SELECTION_START:
1833 case LOK_CALLBACK_TEXT_SELECTION_END:
1834 case LOK_CALLBACK_TEXT_SELECTION:
1835 case LOK_CALLBACK_GRAPHIC_SELECTION:
1836 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1837 case LOK_CALLBACK_INVALIDATE_TILES:
1849 case LOK_CALLBACK_TEXT_SELECTION_START:
1850 case LOK_CALLBACK_TEXT_SELECTION_END:
1851 case LOK_CALLBACK_TEXT_SELECTION:
1852 case LOK_CALLBACK_MOUSE_POINTER:
1853 case LOK_CALLBACK_CELL_CURSOR:
1854 case LOK_CALLBACK_CELL_FORMULA:
1855 case LOK_CALLBACK_CELL_ADDRESS:
1856 case LOK_CALLBACK_CURSOR_VISIBLE:
1857 case LOK_CALLBACK_SET_PART:
1858 case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
1859 case LOK_CALLBACK_RULER_UPDATE:
1860 case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
1861 case LOK_CALLBACK_A11Y_CARET_CHANGED:
1862 case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
1863 case LOK_CALLBACK_COLOR_PALETTES:
1873 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1874 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1875 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1876 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1877 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1878 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1879 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1880 case LOK_CALLBACK_FORM_FIELD_BUTTON:
1884 const bool hyperLinkException =
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1885 aCallbackData.
getPayload().indexOf(
"\"hyperlink\":\"\"") == -1 &&
1886 aCallbackData.
getPayload().indexOf(
"\"hyperlink\": {}") == -1;
1887 if(!hyperLinkException)
1889 const int nViewId = aCallbackData.
getViewId();
1891 return (nViewId == elemData.
getViewId());
1898 case LOK_CALLBACK_INVALIDATE_TILES:
1905 case LOK_CALLBACK_STATE_CHANGED:
1914 if (
name !=
".uno:ModifiedStatus=")
1925 case LOK_CALLBACK_WINDOW:
1930 case LOK_CALLBACK_GRAPHIC_SELECTION:
1935 {
return (elemData.
getPayload().indexOf(
"INPLACE") == -1); });
1942 assert(aCallbackData.
validate() &&
"Cached callback payload object and string mismatch!");
1944 m_queue2.emplace_back(aCallbackData);
1952 std::ostringstream oss;
1956 oss <<
m_queue1.size() <<
" items\n";
1959 for (; it1 !=
m_queue1.end(); ++it1, ++it2)
1960 oss <<
i++ <<
": [" << *it1 <<
"] [" << it2->getPayload() <<
"].\n";
1961 SAL_INFO(
"lok",
"Current Queue: " << oss.str());
1985 = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_INVALIDATE_TILES);
1994 <<
"] since all tiles need to be invalidated.");
2004 <<
"] since overlaps existing all-parts.");
2013 <<
"] so removing all with part " << rcNew.
m_nPart <<
".");
2022 const auto rcOrig = rcNew;
2024 SAL_INFO(
"lok",
"Have [" <<
type <<
"]: [" << aCallbackData.
getPayload() <<
"] so merging overlapping.");
2030 SAL_INFO(
"lok",
"Nothing to merge between new: "
2031 << rcNew.toString() <<
", and old: " << rcOld.toString());
2038 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" has " << rcOld.toString()
2040 if (rcNew.m_aRectangle.Contains(rcOld.m_aRectangle) && rcOld.m_nMode == rcNew.m_nMode)
2042 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
2043 << rcOld.toString() <<
".");
2047 else if (rcOld.m_nPart == -1)
2050 SAL_INFO(
"lok",
"Old " << rcOld.toString() <<
" has " << rcNew.toString()
2052 if (rcOld.m_aRectangle.Contains(rcNew.m_aRectangle) && rcOld.m_nMode == rcNew.m_nMode)
2054 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
2055 << rcOld.toString() <<
".");
2063 const bool bOverlap = !rcOverlap.
IsEmpty() && rcOld.m_nMode == rcNew.
m_nMode;
2064 SAL_INFO(
"lok",
"Merging " << rcNew.
toString() <<
" & " << rcOld.toString()
2066 <<
" Overlap: " << bOverlap);
2079 if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
2081 SAL_INFO(
"lok",
"Replacing: " << rcOrig.toString() <<
" by " << rcNew.toString());
2082 if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth()
2083 || rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
2085 SAL_WARN(
"lok",
"Error: merged rect smaller.");
2090 aCallbackData.updateRectangleAndPart(rcNew);
2097 const OString& payload = aCallbackData.
getPayload();
2099 boost::property_tree::ptree& aTree = aCallbackData.
setJson(std::string(payload));
2100 const unsigned nLOKWindowId = aTree.get<
unsigned>(
"id", 0);
2101 const std::string aAction = aTree.get<std::string>(
"action",
"");
2102 if (aAction ==
"invalidate")
2104 std::string aRectStr = aTree.get<std::string>(
"rectangle",
"");
2107 if (aRectStr.empty())
2110 const boost::property_tree::ptree& aOldTree = elemData.
getJson();
2111 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
2112 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
2123 bool invAllExist =
false;
2126 for (;it1 !=
m_queue1.rend(); ++it1, ++it2)
2128 if (*it1 != LOK_CALLBACK_WINDOW)
2130 const boost::property_tree::ptree& aOldTree = it2->getJson();
2131 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
2132 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate"
2133 && aOldTree.get<std::string>(
"rectangle",
"").empty())
2143 SAL_INFO(
"lok.dialog",
"Skipping queue ["
2144 <<
type <<
"]: [" << payload
2145 <<
"] since whole window needs to be invalidated.");
2149 std::istringstream aRectStream(aRectStr);
2152 aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
2154 bool currentIsRedundant =
false;
2155 removeAll(LOK_CALLBACK_WINDOW, [&aNewRect, &nLOKWindowId,
2157 const boost::property_tree::ptree& aOldTree = elemData.
getJson();
2158 if (aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
2161 std::istringstream aOldRectStream(aOldTree.get<std::string>(
"rectangle",
""));
2162 tools::Long nOldLeft, nOldTop, nOldWidth, nOldHeight;
2164 aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
2165 >> nOldComma >> nOldHeight;
2166 const tools::Rectangle aOldRect = tools::Rectangle(
2167 nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
2169 if (nLOKWindowId == aOldTree.get<unsigned>(
"id", 0))
2171 if (aNewRect == aOldRect)
2173 SAL_INFO(
"lok.dialog",
"Duplicate rect [" << aNewRect.toString()
2174 <<
"]. Skipping new.");
2176 currentIsRedundant = true;
2180 else if (aNewRect.Contains(aOldRect))
2182 SAL_INFO(
"lok.dialog",
2183 "New rect [" << aNewRect.toString() <<
"] engulfs old ["
2184 << aOldRect.toString() <<
"]. Replacing old.");
2188 else if (aOldRect.Contains(aNewRect))
2190 SAL_INFO(
"lok.dialog",
2191 "Old rect [" << aOldRect.toString() <<
"] engulfs new ["
2192 << aNewRect.toString() <<
"]. Skipping new.");
2194 currentIsRedundant = true;
2200 const tools::Rectangle aPreMergeRect = aNewRect;
2201 aNewRect.Union(aOldRect);
2202 SAL_INFO(
"lok.dialog",
"Merging rects ["
2203 << aPreMergeRect.toString() <<
"] & ["
2204 << aOldRect.toString() <<
"] = ["
2205 << aNewRect.toString()
2206 <<
"]. Replacing old.");
2217 if (currentIsRedundant)
2220 aTree.put(
"rectangle", aNewRect.toString().getStr());
2222 assert(aCallbackData.
validate() &&
"Validation after setJson failed!");
2225 else if (aAction ==
"created")
2228 removeAll(LOK_CALLBACK_WINDOW,[&nLOKWindowId](
const CallbackData& elemData) {
2229 const boost::property_tree::ptree& aOldTree = elemData.getJson();
2230 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
2243 auto xClip = forceSetClipboardForCurrentView(m_pDocument);
2246 pWindow->SetClipboard(xClipboard);
2249 else if (aAction ==
"size_changed")
2253 removeAll(LOK_CALLBACK_WINDOW, [&nLOKWindowId](
const CallbackData& elemData) {
2254 const boost::property_tree::ptree& aOldTree = elemData.getJson();
2255 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
2257 const std::string aOldAction = aOldTree.get<std::string>(
"action",
"");
2258 if (aOldAction ==
"invalidate")
2276 assert(viewShell !=
nullptr);
2279 std::vector<bool> updatedTypes;
2281 boost::container::flat_map<int, std::vector<PerViewIdData>> updatedTypesPerViewId;
2288 static const int orderedUpdatedTypes[] = {
2289 LOK_CALLBACK_TEXT_SELECTION_START, LOK_CALLBACK_TEXT_SELECTION_END, LOK_CALLBACK_TEXT_SELECTION };
2292 static const int orderedUpdatedTypesPerViewId[] = {
2293 LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
2294 LOK_CALLBACK_INVALIDATE_VIEW_CURSOR,
2295 LOK_CALLBACK_TEXT_VIEW_SELECTION };
2297 for(
int type : orderedUpdatedTypes )
2304 for(
const auto& it : updatedTypesPerViewId )
2306 int viewId = it.first;
2307 const std::vector<PerViewIdData>& types = it.second;
2308 for(
int type : orderedUpdatedTypesPerViewId )
2313 const int sourceViewId = types[
type ].sourceViewId;
2316 assert(sourceViewId >= 0);
2320 if(sourceViewShell ==
nullptr)
2322 SAL_INFO(
"lok",
"View #" << sourceViewId <<
" no longer found for updated event [" <<
type <<
"]");
2333 if (
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR)
2336 viewShell = viewShell2;
2343 m_queue2.emplace_back(callbackData);
2345 <<
"] to have " <<
m_queue1.size() <<
" entries.");
2361 viewShell->flushPendingLOKInvalidateTiles();
2364 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
2372 for (; it1 !=
m_queue1.end(); ++it1, ++it2)
2374 const int type = *it1;
2375 const auto& payload = it2->getPayload();
2378 SAL_INFO(
"lok",
"processing event: [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2385 if (
type == LOK_CALLBACK_STATE_CHANGED &&
2386 (
idx = payload.indexOf(
'=')) != -1)
2388 OString key = payload.copy(0,
idx);
2389 OString
value = payload.copy(
idx+1);
2394 if (stateIt->second ==
value)
2396 SAL_INFO(
"lok",
"Skipping new state duplicate: [" <<
type <<
"]: [" << payload <<
"].");
2399 SAL_INFO(
"lok",
"Replacing a state element [" <<
type <<
"]: [" << payload <<
"].");
2400 stateIt->second =
value;
2404 SAL_INFO(
"lok",
"Inserted a new state element: [" <<
type <<
"]: [" << payload <<
"]");
2414 if (stateIt->second == payload)
2416 SAL_INFO(
"lok",
"Skipping duplicate [" <<
type <<
"]: [" << payload <<
"].");
2419 stateIt->second = payload;
2428 auto& states = statesIt->second;
2429 const auto stateIt = states.find(
type);
2430 if (stateIt != states.end())
2433 if (stateIt->second == payload)
2435 SAL_INFO(
"lok",
"Skipping view duplicate [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2439 SAL_INFO(
"lok",
"Replacing an element in view states [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2440 stateIt->second = payload;
2444 SAL_INFO(
"lok",
"Inserted a new element in view states: [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"]");
2445 states.emplace(
type, payload);
2470 bool bErased =
false;
2486 bool bErased =
false;
2494 if (rTestFunc(*it2))
2511 result.first->second.clear();
2535static void lo_destroy (LibreOfficeKit* pThis);
2536static int lo_initialize (LibreOfficeKit* pThis,
const char* pInstallPath,
const char* pUserProfilePath);
2537static LibreOfficeKitDocument*
lo_documentLoad (LibreOfficeKit* pThis,
const char* pURL);
2542 const char* pOptions);
2544 LibreOfficeKitCallback pCallback,
2550 const char* pPassword);
2552static int lo_runMacro (LibreOfficeKit* pThis,
const char* pURL);
2556 const unsigned char* pCertificateBinary,
2557 const int nCertificateBinarySize,
2558 const unsigned char* pPrivateKeyBinary,
2559 const int nPrivateKeyBinarySize);
2562 const char* pFilePath);
2564static void lo_trimMemory(LibreOfficeKit* pThis,
int nTarget);
2567 LibreOfficeKitPollCallback pPollCallback,
2568 LibreOfficeKitWakeCallback pWakeCallback,
2572 unsigned long long int nLOKWindowId,
2573 const char* pArguments);
2575static void lo_setOption(LibreOfficeKit* pThis,
const char* pOption,
const char* pValue);
2577static void lo_dumpState(LibreOfficeKit* pThis,
const char* pOptions,
char** pState);
2582 , mpCallback(nullptr)
2583 , mpCallbackData(nullptr)
2584 , mOptionalFeatures(0)
2622void setLanguageAndLocale(OUString
const & aLangISO)
2632 if (sFormat == u
"pdf")
2635 rFilterDataMap[
"ExportBookmarks"] <<=
true;
2657 static int nDocumentIdCounter = 0;
2660 pLib->maLastExceptionMsg.clear();
2665 pLib->maLastExceptionMsg =
"Filename to load was not provided.";
2666 SAL_INFO(
"lok",
"URL for load is empty");
2670 pLib->maLastExceptionMsg.clear();
2674 pLib->maLastExceptionMsg =
"ComponentContext is not available";
2675 SAL_INFO(
"lok",
"ComponentContext is not available");
2681 if (!xComponentLoader.is())
2683 pLib->maLastExceptionMsg =
"ComponentLoader is not available";
2684 SAL_INFO(
"lok",
"ComponentLoader is not available");
2696 if (!aLanguage.isEmpty() && isValidLangTag)
2698 static bool isLoading =
true;
2711 SAL_INFO(
"lok",
"Set document language to " << aLanguage);
2714 setLanguageAndLocale(aLanguage);
2721 if (!aTimezone.isEmpty())
2728 const char* tz = ::getenv(
"TZ");
2732 OStringToOUString(tz, RTL_TEXTENCODING_UTF8));
2740 const OUString aDeviceFormFactor =
extractParameter(aOptions,
u"DeviceFormFactor");
2744 if (!aBatch.isEmpty())
2749 const OUString sFilterOptions = aOptions;
2753 auto const pair(
pLib->mInteractionMap.insert(std::make_pair(
aURL.toUtf8(), pInteraction)));
2757 pLib->mInteractionMap.erase(aURL.toUtf8());
2762 int nMacroSecurityLevel = 1;
2763 const OUString aMacroSecurityLevel =
extractParameter(aOptions,
u"MacroSecurityLevel");
2764 if (!aMacroSecurityLevel.isEmpty())
2767 sal_uInt32 nFormat = 1;
2769 if (aFormatter.
IsNumberFormat(aMacroSecurityLevel, nFormat, nNumber))
2770 nMacroSecurityLevel =
static_cast<int>(nNumber);
2774#if defined(ANDROID) && HAVE_FEATURE_ANDROID_LOK
2775 sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG;
2777 const OUString aEnableMacrosExecution =
extractParameter(aOptions,
u"EnableMacrosExecution");
2778 sal_Int16 nMacroExecMode = aEnableMacrosExecution ==
"true" ? document::MacroExecMode::USE_CONFIG :
2779 document::MacroExecMode::NEVER_EXECUTE;
2801 const int nThisDocumentId = nDocumentIdCounter++;
2807 assert(!xComponent.is() || pair.second);
2809 if (!xComponent.is())
2811 pLib->maLastExceptionMsg =
"loadComponentFromURL returned an empty reference";
2812 SAL_INFO(
"lok",
"Document can't be loaded - " <<
pLib->maLastExceptionMsg);
2819 if (
pLib->mpCallback)
2822 pLib->mpCallback(LOK_CALLBACK_SIGNATURE_STATUS, OString::number(
nState).getStr(),
pLib->mpCallbackData);
2827 if (aFontMappingUseData.size() > 0)
2829 SAL_INFO(
"lok.fontsubst",
"================ Original substitutions:");
2830 for (
const auto &
i : aFontMappingUseData)
2832 SAL_INFO(
"lok.fontsubst",
i.mOriginalFont);
2833 for (
const auto &j :
i.mUsedFonts)
2834 SAL_INFO(
"lok.fontsubst",
" " << j);
2842 aFontMappingUseData.erase
2843 (std::remove_if(aFontMappingUseData.begin(), aFontMappingUseData.end(),
2855 if (x.mOriginalFont.indexOf(
'/') == -1)
2856 for (const auto &j : x.mUsedFonts)
2857 if (j == x.mOriginalFont ||
2858 j.startsWith(Concat2View(x.mOriginalFont +
"/")))
2863 aFontMappingUseData.end());
2869 aFontMappingUseData.erase
2870 (std::remove_if(aFontMappingUseData.begin(), aFontMappingUseData.end(),
2877 if (x.mOriginalFont.indexOf(
'/') == -1)
2878 for (const auto &j : x.mUsedFonts)
2879 if ((x.mOriginalFont ==
"Arial" &&
2880 j.startsWith(
"Liberation Sans/")) ||
2881 (x.mOriginalFont ==
"Times New Roman" &&
2882 j.startsWith(
"Liberation Serif/")) ||
2883 (x.mOriginalFont ==
"Courier New" &&
2884 j.startsWith(
"Liberation Mono/")) ||
2885 (x.mOriginalFont ==
"Arial Narrow" &&
2886 j.startsWith(
"Liberation Sans Narrow/")) ||
2887 (x.mOriginalFont ==
"Cambria" &&
2888 j.startsWith(
"Caladea/")) ||
2889 (x.mOriginalFont ==
"Calibri" &&
2890 j.startsWith(
"Carlito/")) ||
2891 (x.mOriginalFont ==
"Palatino Linotype" &&
2892 j.startsWith(
"P052/")) ||
2896 (x.mOriginalFont ==
"Symbol" &&
2897 j.startsWith(
"OpenSymbol/")))
2904 aFontMappingUseData.end());
2906 if (aFontMappingUseData.size() > 0)
2908 SAL_INFO(
"lok.fontsubst",
"================ Pruned substitutions:");
2909 for (
const auto &
i : aFontMappingUseData)
2911 SAL_INFO(
"lok.fontsubst",
i.mOriginalFont);
2912 for (
const auto &j :
i.mUsedFonts)
2913 SAL_INFO(
"lok.fontsubst",
" " << j);
2917 for (std::size_t
i = 0;
i < aFontMappingUseData.size(); ++
i)
2919 pDocument->
maFontsMissing.insert(aFontMappingUseData[
i].mOriginalFont);
2924 catch (
const uno::Exception& exception)
2926 pLib->maLastExceptionMsg = exception.Message;
2940 pLib->maLastExceptionMsg.clear();
2942 OUString sURL( pURL, strlen(pURL), RTL_TEXTENCODING_UTF8 );
2945 pLib->maLastExceptionMsg =
"Macro to run was not provided.";
2946 SAL_INFO(
"lok",
"Macro URL is empty");
2950 if (!sURL.startsWith(
"macro://"))
2952 pLib->maLastExceptionMsg =
"This doesn't look like macro URL";
2953 SAL_INFO(
"lok",
"Macro URL is invalid");
2957 pLib->maLastExceptionMsg.clear();
2961 pLib->maLastExceptionMsg =
"ComponentContext is not available";
2962 SAL_INFO(
"lok",
"ComponentContext is not available");
2967 aURL.Complete = sURL;
2972 xParser->parseStrict(
aURL );
2976 if (!xComponentLoader.is())
2978 pLib->maLastExceptionMsg =
"ComponentLoader is not available";
2979 SAL_INFO(
"lok",
"ComponentLoader is not available");
2990 xDP.set(
xSFactory->createInstance(
"com.sun.star.comp.sfx2.SfxMacroLoader"), uno::UNO_QUERY );
2995 pLib->maLastExceptionMsg =
"Macro loader is not available";
2996 SAL_INFO(
"lok",
"Macro loader is not available");
3002 css::beans::PropertyValue aErr;
3003 uno::Any aRet = xSyncDisp->dispatchWithReturnValue(
aURL, aEmpty );
3006 if (aErr.Name ==
"ErrorCode")
3008 sal_uInt32 nErrCode = 0;
3009 aErr.
Value >>= nErrCode;
3011 pLib->maLastExceptionMsg =
"An error occurred running macro (error code: " + OUString::number( nErrCode ) +
")";
3012 SAL_INFO(
"lok",
"Macro execution terminated with error code " << nErrCode);
3022 const unsigned char* pCertificateBinary,
3023 const int nCertificateBinarySize,
3024 const unsigned char* pPrivateKeyBinary,
3025 const int nPrivateKeyBinarySize)
3038 std::string aCertificateString(
reinterpret_cast<const char*
>(pCertificateBinary), nCertificateBinarySize);
3039 std::string aCertificateBase64String = extractCertificate(aCertificateString);
3040 if (!aCertificateBase64String.empty())
3042 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String);
3047 aCertificateSequence.realloc(nCertificateBinarySize);
3048 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.getArray());
3052 std::string aPrivateKeyString(
reinterpret_cast<const char*
>(pPrivateKeyBinary), nPrivateKeyBinarySize);
3053 std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
3054 if (!aPrivateKeyBase64String.empty())
3056 OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String);
3061 aPrivateKeySequence.realloc(nPrivateKeyBinarySize);
3062 std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeyBinarySize, aPrivateKeySequence.getArray());
3067 if (!xSecurityContext.is())
3073 if (!xCertificateCreator.is())
3078 if (!xCertificate.is())
3095 if (!
aURL.isEmpty())
3097 if (xComponentLoader.is())
3103 {
"Hidden", css::uno::Any(
true)},
3104 {
"ReadOnly", css::uno::Any(
true)}
3106 xComp = xComponentLoader->loadComponentFromURL(
aURL,
"_blank", 0, aFilterOptions );
3108 catch (
const lang::IllegalArgumentException&
ex )
3110 SAL_WARN(
"lok",
"lo_extractRequest: IllegalArgumentException: " <<
ex.Message);
3116 SAL_WARN(
"lok",
"lo_extractRequest: Exception on loadComponentFromURL, url= " <<
aURL);
3129 auto aNode = aJson.
startNode(
"Targets");
3153#ifdef HAVE_MALLOC_TRIM
3160 LibreOfficeKitCallback pCallback,
3169 pLib->maLastExceptionMsg.clear();
3175static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* sUrl,
const char* pFormat,
const char* pFilterOptions)
3192 SAL_INFO(
"lok",
"URL for save is empty");
3198 const ExtensionMap* pMap;
3202 case LOK_DOCTYPE_SPREADSHEET:
3205 case LOK_DOCTYPE_PRESENTATION:
3208 case LOK_DOCTYPE_DRAWING:
3211 case LOK_DOCTYPE_TEXT:
3214 case LOK_DOCTYPE_OTHER:
3216 SAL_INFO(
"lok",
"Can't save document - unsupported document type.");
3220 if (pFormat ==
nullptr)
3223 sal_Int32
idx =
aURL.lastIndexOf(
".");
3226 sFormat =
aURL.copy(
idx + 1 );
3235 OUString aFilterName;
3236 for (sal_Int32
i = 0; pMap[
i].extn; ++
i)
3238 if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[
i].extn))
3244 if (aFilterName.isEmpty())
3250 OUString aFilterOptions =
getUString(pFilterOptions);
3254 OUString watermarkText;
3255 std::u16string_view sFullSheetPreview;
3257 if ((
aIndex = aFilterOptions.indexOf(
",Watermark=")) >= 0)
3259 int bIndex = aFilterOptions.indexOf(
"WATERMARKEND");
3260 watermarkText = aFilterOptions.subView(
aIndex+11, bIndex-(
aIndex+11));
3261 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+12);
3264 if ((
aIndex = aFilterOptions.indexOf(
",FullSheetPreview=")) >= 0)
3266 int bIndex = aFilterOptions.indexOf(
"FULLSHEETPREVEND");
3267 sFullSheetPreview = aFilterOptions.subView(
aIndex+18, bIndex-(
aIndex+18));
3268 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+16);
3271 bool bFullSheetPreview = sFullSheetPreview ==
u"true";
3273 OUString filePassword;
3274 if ((
aIndex = aFilterOptions.indexOf(
",Password=")) >= 0)
3276 int bIndex = aFilterOptions.indexOf(
"PASSWORDEND");
3277 filePassword = aFilterOptions.subView(
aIndex + 10, bIndex - (
aIndex + 10));
3278 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex))
3279 + aFilterOptions.subView(bIndex + 11);
3281 OUString filePasswordToModify;
3282 if ((
aIndex = aFilterOptions.indexOf(
",PasswordToModify=")) >= 0)
3284 int bIndex = aFilterOptions.indexOf(
"PASSWORDTOMODIFYEND");
3285 filePassword = aFilterOptions.subView(
aIndex + 18, bIndex - (
aIndex + 18));
3286 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex))
3287 + aFilterOptions.subView(bIndex + 19);
3292 sal_Int32 pdfVer = 0;
3293 if ((
aIndex = aFilterOptions.indexOf(
",PDFVer=")) >= 0)
3295 int bIndex = aFilterOptions.indexOf(
"PDFVEREND");
3296 std::u16string_view sPdfVer = aFilterOptions.subView(
aIndex+8, bIndex-(
aIndex+8));
3297 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+9);
3322 std::vector<OUString> aFilteredOptionVec;
3323 bool bTakeOwnership =
false;
3325 for (
const auto& rOption : aOptionSeq)
3327 if (rOption ==
"TakeOwnership")
3328 bTakeOwnership =
true;
3329 else if (rOption ==
"NoFileSync")
3330 aSaveMediaDescriptor[
"NoFileSync"] <<=
true;
3332 aFilteredOptionVec.push_back(rOption);
3335 aSaveMediaDescriptor[
"Overwrite"] <<=
true;
3336 aSaveMediaDescriptor[
"FilterName"] <<= aFilterName;
3338 auto aFilteredOptionSeq = comphelper::containerToSequence<OUString>(aFilteredOptionVec);
3340 aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS] <<= aFilterOptions;
3346 if (!aFilterOptions.startsWith(
"{"))
3348 setFormatSpecificFilterData(sFormat, aFilterDataMap);
3351 if (!watermarkText.isEmpty())
3352 aFilterDataMap[
"TiledWatermark"] <<= watermarkText;
3354 if (bFullSheetPreview)
3355 aFilterDataMap[
"SinglePageSheets"] <<=
true;
3358 aFilterDataMap[
"SelectPdfVersion"] <<= pdfVer;
3360 if (!aFilterDataMap.
empty())
3364 if (!filePassword.isEmpty())
3365 aSaveMediaDescriptor[
"Password"] <<= filePassword;
3366 if (!filePasswordToModify.isEmpty())
3367 aSaveMediaDescriptor[
"PasswordToModify"] <<= filePasswordToModify;
3377 aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteraction;
3382 xStorable->storeAsURL(
aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
3384 xStorable->storeToURL(
aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
3388 catch (
const uno::Exception& exception)
3406 OUString sUnoCommands[] =
3408 OUString(
".uno:AlignLeft"),
3409 OUString(
".uno:AlignHorizontalCenter"),
3410 OUString(
".uno:AlignRight"),
3411 OUString(
".uno:BackColor"),
3412 OUString(
".uno:BackgroundColor"),
3413 OUString(
".uno:TableCellBackgroundColor"),
3414 OUString(
".uno:Bold"),
3415 OUString(
".uno:CenterPara"),
3416 OUString(
".uno:CharBackColor"),
3417 OUString(
".uno:CharBackgroundExt"),
3418 OUString(
".uno:CharFontName"),
3419 OUString(
".uno:Color"),
3420 OUString(
".uno:ControlCodes"),
3421 OUString(
".uno:DecrementIndent"),
3422 OUString(
".uno:DefaultBullet"),
3423 OUString(
".uno:DefaultNumbering"),
3424 OUString(
".uno:FontColor"),
3425 OUString(
".uno:FontHeight"),
3426 OUString(
".uno:IncrementIndent"),
3427 OUString(
".uno:Italic"),
3428 OUString(
".uno:JustifyPara"),
3429 OUString(
".uno:JumpToMark"),
3430 OUString(
".uno:OutlineFont"),
3431 OUString(
".uno:LeftPara"),
3432 OUString(
".uno:LanguageStatus"),
3433 OUString(
".uno:RightPara"),
3434 OUString(
".uno:Shadowed"),
3435 OUString(
".uno:SubScript"),
3436 OUString(
".uno:SuperScript"),
3437 OUString(
".uno:Strikeout"),
3438 OUString(
".uno:StyleApply"),
3439 OUString(
".uno:Underline"),
3440 OUString(
".uno:ModifiedStatus"),
3441 OUString(
".uno:Undo"),
3442 OUString(
".uno:Redo"),
3443 OUString(
".uno:InsertPage"),
3444 OUString(
".uno:DeletePage"),
3445 OUString(
".uno:DuplicatePage"),
3446 OUString(
".uno:InsertSlide"),
3447 OUString(
".uno:DeleteSlide"),
3448 OUString(
".uno:DuplicateSlide"),
3449 OUString(
".uno:ChangeTheme"),
3450 OUString(
".uno:Cut"),
3451 OUString(
".uno:Copy"),
3452 OUString(
".uno:Paste"),
3453 OUString(
".uno:SelectAll"),
3454 OUString(
".uno:ReplyComment"),
3455 OUString(
".uno:ResolveComment"),
3456 OUString(
".uno:ResolveCommentThread"),
3457 OUString(
".uno:InsertRowsBefore"),
3458 OUString(
".uno:InsertRowsAfter"),
3459 OUString(
".uno:InsertColumnsBefore"),
3460 OUString(
".uno:InsertColumnsAfter"),
3461 OUString(
".uno:DeleteRows"),
3462 OUString(
".uno:DeleteColumns"),
3463 OUString(
".uno:DeleteTable"),
3464 OUString(
".uno:SelectTable"),
3465 OUString(
".uno:EntireRow"),
3466 OUString(
".uno:EntireColumn"),
3467 OUString(
".uno:EntireCell"),
3468 OUString(
".uno:AssignLayout"),
3469 OUString(
".uno:StatusDocPos"),
3470 OUString(
".uno:RowColSelCount"),
3471 OUString(
".uno:StatusPageStyle"),
3472 OUString(
".uno:InsertMode"),
3473 OUString(
".uno:SpellOnline"),
3474 OUString(
".uno:StatusSelectionMode"),
3475 OUString(
".uno:StateTableCell"),
3476 OUString(
".uno:StatusBarFunc"),
3477 OUString(
".uno:StatePageNumber"),
3478 OUString(
".uno:StateWordCount"),
3479 OUString(
".uno:SelectionMode"),
3480 OUString(
".uno:PageStatus"),
3481 OUString(
".uno:LayoutStatus"),
3482 OUString(
".uno:Scale"),
3483 OUString(
".uno:Context"),
3484 OUString(
".uno:WrapText"),
3485 OUString(
".uno:ToggleMergeCells"),
3486 OUString(
".uno:NumberFormatCurrency"),
3487 OUString(
".uno:NumberFormatPercent"),
3488 OUString(
".uno:NumberFormatDecimal"),
3489 OUString(
".uno:NumberFormatIncDecimals"),
3490 OUString(
".uno:NumberFormatDecDecimals"),
3491 OUString(
".uno:NumberFormatDate"),
3492 OUString(
".uno:EditHeaderAndFooter"),
3493 OUString(
".uno:FrameLineColor"),
3494 OUString(
".uno:SortAscending"),
3495 OUString(
".uno:SortDescending"),
3496 OUString(
".uno:TrackChanges"),
3497 OUString(
".uno:ShowTrackedChanges"),
3498 OUString(
".uno:NextTrackedChange"),
3499 OUString(
".uno:PreviousTrackedChange"),
3500 OUString(
".uno:AcceptAllTrackedChanges"),
3501 OUString(
".uno:RejectAllTrackedChanges"),
3502 OUString(
".uno:TableDialog"),
3503 OUString(
".uno:FormatCellDialog"),
3504 OUString(
".uno:FontDialog"),
3505 OUString(
".uno:ParagraphDialog"),
3506 OUString(
".uno:OutlineBullet"),
3507 OUString(
".uno:InsertIndexesEntry"),
3508 OUString(
".uno:DocumentRepair"),
3509 OUString(
".uno:TransformDialog"),
3510 OUString(
".uno:InsertPageHeader"),
3511 OUString(
".uno:InsertPageFooter"),
3512 OUString(
".uno:OnlineAutoFormat"),
3513 OUString(
".uno:InsertObjectChart"),
3514 OUString(
".uno:InsertSection"),
3515 OUString(
".uno:InsertAnnotation"),
3516 OUString(
".uno:DeleteAnnotation"),
3517 OUString(
".uno:InsertPagebreak"),
3518 OUString(
".uno:InsertColumnBreak"),
3519 OUString(
".uno:HyperlinkDialog"),
3520 OUString(
".uno:InsertSymbol"),
3521 OUString(
".uno:EditRegion"),
3522 OUString(
".uno:ThesaurusDialog"),
3523 OUString(
".uno:FormatArea"),
3524 OUString(
".uno:FormatLine"),
3525 OUString(
".uno:FormatColumns"),
3526 OUString(
".uno:Watermark"),
3527 OUString(
".uno:ResetAttributes"),
3528 OUString(
".uno:Orientation"),
3529 OUString(
".uno:ObjectAlignLeft"),
3530 OUString(
".uno:ObjectAlignRight"),
3531 OUString(
".uno:AlignCenter"),
3532 OUString(
".uno:TransformPosX"),
3533 OUString(
".uno:TransformPosY"),
3534 OUString(
".uno:TransformWidth"),
3535 OUString(
".uno:TransformHeight"),
3536 OUString(
".uno:ObjectBackOne"),
3537 OUString(
".uno:SendToBack"),
3538 OUString(
".uno:ObjectForwardOne"),
3539 OUString(
".uno:BringToFront"),
3540 OUString(
".uno:WrapRight"),
3541 OUString(
".uno:WrapThrough"),
3542 OUString(
".uno:WrapLeft"),
3543 OUString(
".uno:WrapIdeal"),
3544 OUString(
".uno:WrapOn"),
3545 OUString(
".uno:WrapOff"),
3546 OUString(
".uno:UpdateCurIndex"),
3547 OUString(
".uno:InsertCaptionDialog"),
3548 OUString(
".uno:FormatGroup"),
3549 OUString(
".uno:SplitTable"),
3550 OUString(
".uno:SplitCell"),
3551 OUString(
".uno:MergeCells"),
3552 OUString(
".uno:DeleteNote"),
3553 OUString(
".uno:AcceptChanges"),
3554 OUString(
".uno:FormatPaintbrush"),
3555 OUString(
".uno:SetDefault"),
3556 OUString(
".uno:ParaLeftToRight"),
3557 OUString(
".uno:ParaRightToLeft"),
3558 OUString(
".uno:ParaspaceIncrease"),
3559 OUString(
".uno:ParaspaceDecrease"),
3560 OUString(
".uno:AcceptTrackedChange"),
3561 OUString(
".uno:RejectTrackedChange"),
3562 OUString(
".uno:ShowResolvedAnnotations"),
3563 OUString(
".uno:InsertBreak"),
3564 OUString(
".uno:InsertEndnote"),
3565 OUString(
".uno:InsertFootnote"),
3566 OUString(
".uno:InsertReferenceField"),
3567 OUString(
".uno:InsertBookmark"),
3568 OUString(
".uno:InsertAuthoritiesEntry"),
3569 OUString(
".uno:InsertMultiIndex"),
3570 OUString(
".uno:InsertField"),
3571 OUString(
".uno:PageNumberWizard"),
3572 OUString(
".uno:InsertPageNumberField"),
3573 OUString(
".uno:InsertPageCountField"),
3574 OUString(
".uno:InsertDateField"),
3575 OUString(
".uno:InsertTitleField"),
3576 OUString(
".uno:InsertFieldCtrl"),
3577 OUString(
".uno:CharmapControl"),
3578 OUString(
".uno:EnterGroup"),
3579 OUString(
".uno:LeaveGroup"),
3580 OUString(
".uno:AlignUp"),
3581 OUString(
".uno:AlignMiddle"),
3582 OUString(
".uno:AlignDown"),
3583 OUString(
".uno:TraceChangeMode"),
3584 OUString(
".uno:Combine"),
3585 OUString(
".uno:Merge"),
3586 OUString(
".uno:Dismantle"),
3587 OUString(
".uno:Substract"),
3588 OUString(
".uno:DistributeSelection"),
3589 OUString(
".uno:Intersect"),
3590 OUString(
".uno:BorderInner"),
3591 OUString(
".uno:BorderOuter"),
3592 OUString(
".uno:FreezePanes"),
3593 OUString(
".uno:FreezePanesColumn"),
3594 OUString(
".uno:FreezePanesRow"),
3595 OUString(
".uno:Sidebar"),
3596 OUString(
".uno:SheetRightToLeft"),
3597 OUString(
".uno:RunMacro"),
3598 OUString(
".uno:SpacePara1"),
3599 OUString(
".uno:SpacePara15"),
3600 OUString(
".uno:SpacePara2"),
3601 OUString(
".uno:InsertSparkline"),
3602 OUString(
".uno:DeleteSparkline"),
3603 OUString(
".uno:DeleteSparklineGroup"),
3604 OUString(
".uno:EditSparklineGroup"),
3605 OUString(
".uno:EditSparkline"),
3606 OUString(
".uno:GroupSparklines"),
3607 OUString(
".uno:UngroupSparklines"),
3608 OUString(
".uno:FormatSparklineMenu"),
3609 OUString(
".uno:Protect"),
3610 OUString(
".uno:UnsetCellsReadOnly"),
3611 OUString(
".uno:ContentControlProperties"),
3612 OUString(
".uno:InsertCheckboxContentControl"),
3613 OUString(
".uno:InsertContentControl"),
3614 OUString(
".uno:InsertDateContentControl"),
3615 OUString(
".uno:InsertDropdownContentControl"),
3616 OUString(
".uno:InsertPlainTextContentControl"),
3617 OUString(
".uno:InsertPictureContentControl"),
3618 OUString(
".uno:DataFilterAutoFilter")
3621 util::URL aCommandURL;
3628 SAL_WARN(
"lok",
"iniUnoCommands: No Frame-Controller created.");
3636 SAL_WARN(
"lok",
"iniUnoCommands: Component context is not available");
3640#if !defined IOS && !defined ANDROID && !defined __EMSCRIPTEN__
3642 if (!xSEInitializer.is())
3644 SAL_WARN(
"lok",
"iniUnoCommands: XSEInitializer is not available");
3649 xSEInitializer->createSecurityContext(OUString());
3650 if (!xSecurityContext.is())
3652 SAL_WARN(
"lok",
"iniUnoCommands: failed to create security context");
3659 for (
const auto & sUnoCommand : sUnoCommands)
3661 aCommandURL.Complete = sUnoCommand;
3662 xParser->parseStrict(aCommandURL);
3679 return getDocumentType(pThis);
3688 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3695 return pDoc->getParts();
3705 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3712 return pDoc->getPart();
3715static void doc_setPartImpl(LibreOfficeKitDocument* pThis,
int nPart,
bool bAllowChangeFocus =
true)
3722 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3729 pDoc->setPart( nPart, bAllowChangeFocus );
3742 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3758 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3765 pDoc->selectPart( nPart, nSelect );
3774 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3781 pDoc->moveSelectedParts(nPosition, bDuplicate);
3791 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3806 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3826 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3848 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3865 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3883 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3891 int nCurrentPart = pDoc->getPart();
3893 pDoc->setPartMode(nPartMode);
3904 if ( nCurrentPart < pDoc->getParts() )
3906 pDoc->setPart( nCurrentPart );
3921 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3928 return pDoc->getEditMode();
3932 unsigned char* pBuffer,
3933 const int nCanvasWidth,
const int nCanvasHeight,
3934 const int nTilePosX,
const int nTilePosY,
3935 const int nTileWidth,
const int nTileHeight)
3942 SAL_INFO(
"lok.tiledrendering",
"paintTile: painting [" << nTileWidth <<
"x" << nTileHeight <<
3943 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3944 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3946 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3953#if defined(UNX) && !defined(MACOSX) || defined(_WIN32)
3963 double fDPIScale = 1.0;
3967 CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
3968 nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
3969 kCGImageAlphaPremultipliedLast | kCGImageByteOrder32Big);
3971 CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
3972 CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
3974 SAL_INFO(
"lok.tiledrendering",
"doc_paintTile: painting [" << nTileWidth <<
"x" << nTileHeight <<
3975 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3976 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3978 Size aCanvasSize(nCanvasWidth, nCanvasHeight);
3981 aData.rCGContext =
reinterpret_cast<CGContextRef
>(pCGContext);
3985 pDevice->SetOutputSizePixel(aCanvasSize);
3986 pDoc->paintTile(*pDevice, aCanvasSize.
Width(), aCanvasSize.
Height(),
3987 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3989 CGContextRelease(pCGContext);
3996 pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(
4000 pDoc->paintTile(*pDevice, nCanvasWidth, nCanvasHeight,
4001 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
4003 static bool bDebug = getenv(
"LOK_DEBUG_TILES") !=
nullptr;
4008 aRect = pDevice->PixelToLogic(aRect);
4009 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
4011 pDevice->SetLineColor();
4012 pDevice->DrawRect(aRect);
4018 pDevice->EnableMapMode(
false);
4019 BitmapEx aBmpEx = pDevice->GetBitmapEx({ 0, 0 }, { nCanvasWidth, nCanvasHeight });
4025 assert(sraBmp->Height() == nCanvasHeight);
4026 assert(sraBmp->Width() == nCanvasWidth);
4027 assert(!sraAlpha || sraBmp->Height() == sraAlpha->Height());
4028 assert(!sraAlpha || sraBmp->Width() == sraAlpha->Width());
4032 Scanline dataBmp = sraBmp->GetScanline(
y);
4033 Scanline dataAlpha = sraAlpha ? sraAlpha->GetScanline(
y) :
nullptr;
4037 sal_uInt8 alpha = dataAlpha ? sraAlpha->GetPixelFromData(dataAlpha,
x).GetBlue() : 255;
4053 unsigned char* pBuffer,
4056 const int nCanvasWidth,
const int nCanvasHeight,
4057 const int nTilePosX,
const int nTilePosY,
4058 const int nTileWidth,
const int nTileHeight)
4065 SAL_INFO(
"lok.tiledrendering",
"paintPartTile: painting @ " << nPart <<
" : " << nMode <<
" ["
4066 << nTileWidth <<
"x" << nTileHeight <<
"]@("
4067 << nTilePosX <<
", " << nTilePosY <<
") to ["
4068 << nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
4073 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4080 if (nOrigViewId < 0)
4091 std::vector<int> viewIds(viewCount);
4094 nOrigViewId = viewIds[0];
4099 if (nOrigViewId >= 0)
4103 handlerIt->second->disableCallbacks();
4111 const bool isText = (aType == LOK_DOCTYPE_TEXT);
4112 const bool isCalc = (aType == LOK_DOCTYPE_SPREADSHEET);
4113 int nOrigEditMode = 0;
4114 bool bPaintTextEdit =
true;
4115 int nViewId = nOrigViewId;
4116 int nLastNonEditorView = -1;
4117 int nViewMatchingMode = -1;
4122 if (nPart !=
doc_getPart(pThis) || nMode != pDoc->getEditMode())
4132 if (pViewShell->
getPart() == nPart &&
4137 nViewMatchingMode = nViewId;
4138 nLastNonEditorView = nViewId;
4142 else if (pViewShell->
getEditMode() == nMode && !bIsInEdit)
4155 if (nViewMatchingMode >= 0 && nViewMatchingMode != nViewId)
4157 nViewId = nViewMatchingMode;
4160 else if (!isCalc && nLastNonEditorView >= 0 && nLastNonEditorView != nViewId &&
4161 pCurrentViewShell && pCurrentViewShell->
GetDrawView() &&
4164 nViewId = nLastNonEditorView;
4169 if (nViewId != nOrigViewId && nViewId >= 0)
4173 handlerIt->second->disableCallbacks();
4177 if (nPart != nOrigPart)
4182 nOrigEditMode = pDoc->getEditMode();
4183 if (nOrigEditMode != nMode)
4188 bPaintTextEdit = (nPart == nOrigPart && nMode == nOrigEditMode);
4189 pDoc->setPaintTextEdit(bPaintTextEdit);
4192 doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
4196 pDoc->setPaintTextEdit(
true);
4198 if (nMode != nOrigEditMode)
4203 if (nPart != nOrigPart)
4208 if (nViewId != nOrigViewId)
4214 handlerIt->second->enableCallbacks();
4221 catch (
const std::exception&)
4226 if (nOrigViewId >= 0)
4230 handlerIt->second->enableCallbacks();
4237#if ENABLE_CAIRO_RGBA || defined IOS
4238 return LOK_TILEMODE_RGBA;
4240 return LOK_TILEMODE_BGRA;
4253 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4256 Size aDocumentSize = pDoc->getDocumentSize();
4257 *pWidth = aDocumentSize.
Width();
4258 *pHeight = aDocumentSize.
Height();
4276 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4279 Size aDocumentSize = pDoc->getDataArea(nTab);
4280 *pCol = aDocumentSize.
Width();
4281 *pRow = aDocumentSize.
Height();
4290 const char* pArguments)
4297 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4301 pDoc->initializeForTiledRendering(
4307 LibreOfficeKitCallback pCallback,
4319 const size_t nId = nView;
4320 if (pCallback !=
nullptr)
4324 if (pair.first ==
nId)
4327 pair.second->addViewStates(nView);
4334 if (pair.first ==
nId)
4337 pair.second->removeViewStates(nView);
4343 if (pCallback !=
nullptr)
4347 if (pair.first ==
nId)
4361 std::string sPayload =
"{ \"fontsmissing\": [ ";
4369 sPayload +=
"\"" + std::string(f.toUtf8()) +
"\"";
4372 pCallback(LOK_CALLBACK_FONTS_MISSING, sPayload.c_str(),
pData);
4390 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4397 pDoc->getPostIts(aJsonWriter);
4405 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4412 pDoc->getPostItsPos(aJsonWriter);
4419 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4426 pDoc->getRulerState(aJsonWriter);
4430static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
int nType,
int nCharCode,
int nKeyCode)
4437 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4446 pDoc->postKeyEvent(
nType, nCharCode, nKeyCode);
4448 catch (
const uno::Exception& exception)
4451 SAL_INFO(
"lok",
"Failed to postKeyEvent " << exception.Message);
4469 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4475 pWindow = pDoc->getDocWindow();
4495 if (nLOKWindowId == 0)
4497 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4503 pWindow = pDoc->getDocWindow();
4519 if (nCharBefore > 0)
4522 if (nLOKWindowId == 0)
4525 for (
int i = 0;
i < nCharBefore; ++
i)
4526 pWindow->KeyInput(aEvt);
4535 if (nLOKWindowId == 0)
4538 for (
int i = 0;
i < nCharAfter; ++
i)
4539 pWindow->KeyInput(aEvt);
4564 case LOK_KEYEVENT_KEYINPUT:
4567 case LOK_KEYEVENT_KEYUP:
4600 case LOK_DOCTYPE_PRESENTATION:
4601 aMediaDescriptor[
"FilterName"] <<= OUString(
"impress_svg_Export");
4603 case LOK_DOCTYPE_DRAWING:
4604 aMediaDescriptor[
"FilterName"] <<= OUString(
"draw_svg_Export");
4606 case LOK_DOCTYPE_TEXT:
4607 aMediaDescriptor[
"FilterName"] <<= OUString(
"writer_svg_Export");
4609 case LOK_DOCTYPE_SPREADSHEET:
4610 aMediaDescriptor[
"FilterName"] <<= OUString(
"calc_svg_Export");
4613 SAL_WARN(
"lok",
"Failed to render shape selection: Document type is not supported");
4615 aMediaDescriptor[
"SelectionOnly"] <<=
true;
4616 aMediaDescriptor[
"OutputStream"] <<= xOut;
4617 aMediaDescriptor[
"IsPreview"] <<=
true;
4619 xStorable->storeToURL(
"private:stream", aMediaDescriptor.getAsConstPropertyValueList());
4624 *pOutput =
static_cast<char*
>(malloc(nOutputSize));
4627 std::memcpy(*pOutput, aOutStream.
GetData(), nOutputSize);
4632 catch (
const uno::Exception& exception)
4651class DispatchResultListener :
public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
4653 const OString maCommand;
4654 const std::shared_ptr<CallbackFlushHandler> mpCallback;
4655 const std::chrono::steady_clock::time_point mSaveTime;
4656 const bool mbWasModified;
4659 DispatchResultListener(
const char* pCommand, std::shared_ptr<CallbackFlushHandler> pCallback)
4660 : maCommand(pCommand)
4661 , mpCallback(
std::move(pCallback))
4662 , mSaveTime(
std::chrono::steady_clock::
now())
4668 virtual void SAL_CALL dispatchFinished(
const css::frame::DispatchResultEvent& rEvent)
override
4671 aJson.
put(
"commandName", maCommand);
4673 if (rEvent.State != frame::DispatchResultState::DONTKNOW)
4675 bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS);
4676 aJson.
put(
"success", bSuccess);
4680 aJson.
put(
"wasModified", mbWasModified);
4681 aJson.
put(
"startUnixTimeMics",
4682 std::chrono::time_point_cast<std::chrono::microseconds>(mSaveTime)
4685 aJson.
put(
"saveDurationMics", std::chrono::duration_cast<std::chrono::microseconds>(
4686 std::chrono::steady_clock::now() - mSaveTime)
4691 virtual void SAL_CALL disposing(
const css::lang::EventObject&)
override {}
4710 OUString sControlId =
aMap[
"id"];
4715 auto sCurrentShellId = OUString::number(nCurrentShellId);
4734static void doc_sendDialogEvent(LibreOfficeKitDocument* ,
unsigned long long int nWindowId,
const char* pArguments)
4739static void lo_sendDialogEvent(LibreOfficeKit* ,
unsigned long long int nWindowId,
const char* pArguments)
4744static void lo_setOption(LibreOfficeKit* ,
const char *pOption,
const char* pValue)
4746 static char* pCurrentSalLogOverride =
nullptr;
4748 if (strcmp(pOption,
"traceeventrecording") == 0)
4750 if (strcmp(pValue,
"start") == 0)
4757 else if (strcmp(pValue,
"stop") == 0)
4760 else if (strcmp(pOption,
"sallogoverride") == 0)
4762 if (pCurrentSalLogOverride !=
nullptr)
4763 free(pCurrentSalLogOverride);
4764 if (pValue ==
nullptr)
4765 pCurrentSalLogOverride =
nullptr;
4767 pCurrentSalLogOverride = strdup(pValue);
4769 if (pCurrentSalLogOverride ==
nullptr || pCurrentSalLogOverride[0] ==
'\0')
4770 sal_detail_set_log_selector(
nullptr);
4772 sal_detail_set_log_selector(pCurrentSalLogOverride);
4775 else if (strcmp(pOption,
"addfont") == 0)
4777 if (memcmp(pValue,
"file://", 7) == 0)
4780 int fd = open(pValue, O_RDONLY);
4783 std::cerr <<
"Could not open font file '" << pValue <<
"': " << strerror(errno) << std::endl;
4787 OUString sMagicFileName =
"file:///:FD:/" + OUString::number(fd);
4797static void lo_dumpState (LibreOfficeKit* pThis,
const char* ,
char** pState)
4806 OStringBuffer aState(4096*256);
4810 pLib->dumpState(aState);
4812 OString
aStr = aState.makeStringAndClear();
4813 *pState = strdup(
aStr.getStr());
4818 rState.append(
"LibreOfficeKit state:");
4819 rState.append(
"\n\tLastExceptionMsg:\t");
4821 rState.append(
"\n\tUnipoll:\t");
4823 rState.append(
"\n\tOptionalFeatures:\t0x");
4825 rState.append(
"\n\tCallbackData:\t0x");
4826 rState.append(
reinterpret_cast<sal_Int64
>(
mpCallback), 16);
4832static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand,
const char* pArguments,
bool bNotifyWhenFinished)
4840 OUString
aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
4847 beans::PropertyValue aSynchronMode;
4848 aSynchronMode.Name =
"SynchronMode";
4849 aSynchronMode.Value <<=
false;
4850 aPropertyValuesVector.push_back(aSynchronMode);
4859 ExecuteOrientationChange();
4867 OUString
aMimeType = lcl_getCurrentDocumentMimeType(pDocument);
4874 OUString
aURL = xStorable->getLocation();
4876 bool bResult =
doc_saveAs(pThis, aURLUtf8.getStr(),
"pdf",
nullptr);
4880 aJson.
put(
"commandName", pCommand);
4881 aJson.
put(
"success", bResult);
4891 beans::PropertyValue aValue;
4892 aValue.Name =
"InteractionHandler";
4893 aValue.Value <<= xInteraction;
4894 aPropertyValuesVector.push_back(aValue);
4896 bool bDontSaveIfUnmodified =
false;
4897 aPropertyValuesVector.erase(std::remove_if(aPropertyValuesVector.begin(),
4898 aPropertyValuesVector.end(),
4899 [&bDontSaveIfUnmodified](
const beans::PropertyValue& aItem){
4900 if (aItem.Name ==
"DontSaveIfUnmodified")
4902 bDontSaveIfUnmodified = aItem.Value.get<bool>();
4906 }), aPropertyValuesVector.end());
4909 if (bDontSaveIfUnmodified && (!pDocSh || !pDocSh->
IsModified()))
4912 aJson.
put(
"commandName", pCommand);
4913 aJson.
put(
"success",
false);
4916 auto resultNode = aJson.
startNode(
"result");
4917 aJson.
put(
"type",
"string");
4918 aJson.
put(
"value",
"unmodified");
4924 else if (
gImpl && aCommand ==
".uno:TransformDialog")
4926 bool bNeedConversion =
false;
4930 if (aChartHelper.GetWindow() )
4932 bNeedConversion =
true;
4936 if (
OutputDevice* pOutputDevice = pView->GetFirstOutputDevice())
4938 bNeedConversion = (pOutputDevice->GetMapMode().GetMapUnit() == MapUnit::Map100thMM);
4942 if (bNeedConversion)
4945 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
4947 if (rPropValue.Name ==
"TransformPosX"
4948 || rPropValue.Name ==
"TransformPosY"
4949 || rPropValue.Name ==
"TransformWidth"
4950 || rPropValue.Name ==
"TransformHeight"
4951 || rPropValue.Name ==
"TransformRotationX"
4952 || rPropValue.Name ==
"TransformRotationY")
4954 rPropValue.Value >>=
value;
4956 rPropValue.Value <<=
value;
4961 if (aChartHelper.GetWindow() && aPropertyValuesVector.size() > 0)
4963 if (aPropertyValuesVector[0].Name !=
"Action")
4970 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
4972 if (rPropValue.Name ==
"TransformPosX" || rPropValue.Name ==
"TransformRotationX")
4974 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
4975 rPropValue.Value <<=
value - nLeft;
4977 else if (rPropValue.Name ==
"TransformPosY" || rPropValue.Name ==
"TransformRotationY")
4979 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
4980 rPropValue.Value <<=
value - nTop;
4984 util::URL aCommandURL;
4985 aCommandURL.Path =
"LOKTransform";
4986 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
4991 else if (
gImpl && aCommand ==
".uno:LOKSidebarWriterPage")
4993 setupSidebar(u
"WriterPageDeck");
4996 else if (
gImpl && aCommand ==
".uno:SidebarShow")
5001 else if (
gImpl && aCommand ==
".uno:SidebarHide")
5007 bool bResult =
false;
5010 if (aChartHelper.GetWindow() && aCommand !=
".uno:Save" )
5012 util::URL aCommandURL;
5013 aCommandURL.Path =
aCommand.copy(5);
5014 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
5038static void doc_postMouseEvent(LibreOfficeKitDocument* pThis,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
5045 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5053 pDoc->postMouseEvent(
nType, nX, nY,
nCount, nButtons, nModifier);
5055 catch (
const uno::Exception& exception)
5058 SAL_INFO(
"lok",
"Failed to postMouseEvent " << exception.Message);
5062static void doc_postWindowMouseEvent(LibreOfficeKitDocument* ,
unsigned nLOKWindowId,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
5076 const Point aPos(nX, nY);
5084 case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
5087 case LOK_MOUSEEVENT_MOUSEBUTTONUP:
5090 case LOK_MOUSEEVENT_MOUSEMOVE:
5113 OString aType(pType);
5116 if (aType ==
"panBegin")
5117 eEventType = GestureEventPanType::Begin;
5118 else if (aType ==
"panEnd")
5119 eEventType = GestureEventPanType::End;
5126 PanningOrientation::Vertical,
5141 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5148 pDoc->setTextSelection(
nType, nX, nY);
5166 Size aOffset(pWindow->GetOutOffXPixel(), pWindow->GetOutOffYPixel());
5167 Point aCursorPos(nX, nY);
5168 aCursorPos.
Move(aOffset);
5171 MouseEvent aCursorEvent(aCursorPos, 1, MouseEventModifiers::SIMPLECLICK, 0, nModifier);
5177 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5178 const OString &aInMimeType, OString &aRet);
5181 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5182 const OString &aMimeType, OString &aRet)
5188 auto aSeq = Sequence<sal_Int8>(
reinterpret_cast<const sal_Int8*
>(aRet.getStr()),
5190 OStringBuffer aBase64Data;
5194 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
5196 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
5197 "name=\"generator\" content=\""
5200 "</head><body><img src=\"data:" +
aMimeType +
";base64,"
5201 + aBase64Data +
"\"/></body></html>";
5207 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5208 const OString &aMimeType, OString &aRet)
5214 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
5216 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
5217 "name=\"generator\" content=\""
5219 +
"\"/></head><body><pre>" + aRet +
"</pre></body></html>";
5225 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
5226 const OString &aInMimeType, OString &aRet)
5231 bool bConvert =
false;
5237 aMimeType =
"text/plain;charset=utf-16";
5242 datatransfer::DataFlavor aFlavor;
5243 aFlavor.MimeType = OUString::fromUtf8(
aMimeType);
5244 if (
aMimeType ==
"text/plain;charset=utf-16")
5249 if (!xTransferable->isDataFlavorSupported(aFlavor))
5252 if (aInMimeType ==
"text/html")
5269 aAny = xTransferable->getTransferData(aFlavor);
5271 catch (
const css::datatransfer::UnsupportedFlavorException& e)
5273 SetLastExceptionMsg(
"Unsupported flavor " + aFlavor.MimeType +
" exception " + e.Message);
5276 catch (
const css::uno::Exception& e)