10#include <config_features.h>
19#include <unicode/udata.h>
20#include <unicode/ucnv.h>
22#import <Foundation/Foundation.h>
23#import <CoreGraphics/CoreGraphics.h>
28#include <osl/detail/android-bootstrap.h>
36#include <boost/property_tree/json_parser.hpp>
37#include <boost/algorithm/string.hpp>
39#include <LibreOfficeKit/LibreOfficeKit.h>
40#include <LibreOfficeKit/LibreOfficeKitEnums.h>
49#include <osl/file.hxx>
50#include <osl/process.h>
51#include <osl/thread.h>
52#include <rtl/bootstrap.hxx>
53#include <rtl/strbuf.hxx>
68#include <com/sun/star/document/MacroExecMode.hpp>
69#include <com/sun/star/beans/XPropertySet.hpp>
70#include <com/sun/star/container/XNameAccess.hpp>
71#include <com/sun/star/frame/Desktop.hpp>
72#include <com/sun/star/frame/DispatchResultEvent.hpp>
73#include <com/sun/star/frame/DispatchResultState.hpp>
74#include <com/sun/star/frame/XDispatchProvider.hpp>
75#include <com/sun/star/frame/XDispatchResultListener.hpp>
76#include <com/sun/star/frame/XSynchronousDispatch.hpp>
77#include <com/sun/star/frame/XStorable.hpp>
78#include <com/sun/star/lang/Locale.hpp>
79#include <com/sun/star/lang/XComponent.hpp>
80#include <com/sun/star/lang/XMultiServiceFactory.hpp>
81#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
82#include <com/sun/star/util/URLTransformer.hpp>
83#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
84#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
85#include <com/sun/star/datatransfer/XTransferable2.hpp>
86#include <com/sun/star/text/TextContentAnchorType.hpp>
87#include <com/sun/star/document/XRedlinesSupplier.hpp>
88#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
90#include <com/sun/star/xml/crypto/SEInitializer.hpp>
91#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
92#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
93#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
94#include <com/sun/star/security/XCertificate.hpp>
96#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
97#include <com/sun/star/linguistic2/XSpellChecker.hpp>
98#include <com/sun/star/i18n/LocaleCalendar2.hpp>
99#include <com/sun/star/i18n/ScriptType.hpp>
100#include <com/sun/star/lang/DisposedException.hpp>
119#include <svx/strings.hrc>
121#include <svx/svxids.hrc>
139#include <unicode/uchar.h>
147#include <osl/module.hxx>
160#include <com/sun/star/document/XUndoManager.hpp>
161#include <com/sun/star/document/XUndoManagerSupplier.hpp>
168#include "../app/cmdlineargs.hxx"
170#include "../app/sofficemain.h"
171#include "../app/officeipcthread.hxx"
176#include <officecfg/Office/Common.hxx>
177#include <officecfg/Office/Impress.hxx>
206 SAL_WARN_IF(!s.isEmpty(),
"lok",
"lok exception '" + s +
"'");
216 const char *filterName;
221 static const int dumpTimeoutMS = 5000;
224 TraceEventDumper() :
AutoTimer(
"Trace Event dumper" )
230 virtual void Invoke()
override
235 static void flushRecordings()
237 const css::uno::Sequence<OUString> aEvents =
239 OStringBuffer aOutput;
240 for (
const auto &s : aEvents)
243 aOutput.append(
"\n");
245 if (aOutput.getLength() > 0)
247 OString aChunk = aOutput.makeStringAndClear();
260 {
"doc",
"MS Word 97" },
261 {
"docm",
"MS Word 2007 XML VBA" },
262 {
"docx",
"MS Word 2007 XML" },
263 {
"fodt",
"OpenDocument Text Flat XML" },
264 {
"html",
"HTML (StarWriter)" },
265 {
"odt",
"writer8" },
266 {
"ott",
"writer8_template" },
267 {
"pdf",
"writer_pdf_Export" },
269 {
"rtf",
"Rich Text Format" },
271 {
"xhtml",
"XHTML Writer File" },
272 {
"png",
"writer_png_Export" },
273 {
"xml",
"writer_indexing_export" },
279 {
"csv",
"Text - txt - csv (StarCalc)" },
280 {
"fods",
"OpenDocument Spreadsheet Flat XML" },
281 {
"html",
"HTML (StarCalc)" },
283 {
"ots",
"calc8_template" },
284 {
"pdf",
"calc_pdf_Export" },
285 {
"xhtml",
"XHTML Calc File" },
286 {
"xls",
"MS Excel 97" },
287 {
"xlsm",
"Calc MS Excel 2007 VBA XML" },
288 {
"xlsx",
"Calc MS Excel 2007 XML" },
289 {
"png",
"calc_png_Export" },
295 {
"fodp",
"OpenDocument Presentation Flat XML" },
296 {
"html",
"impress_html_Export" },
297 {
"odg",
"impress8_draw" },
298 {
"odp",
"impress8" },
299 {
"otp",
"impress8_template" },
300 {
"pdf",
"impress_pdf_Export" },
301 {
"potm",
"Impress MS PowerPoint 2007 XML Template" },
302 {
"pot",
"MS PowerPoint 97 Vorlage" },
303 {
"pptm",
"Impress MS PowerPoint 2007 XML VBA" },
304 {
"pptx",
"Impress MS PowerPoint 2007 XML" },
305 {
"pps",
"MS PowerPoint 97 Autoplay" },
306 {
"ppt",
"MS PowerPoint 97" },
307 {
"svg",
"impress_svg_Export" },
308 {
"xhtml",
"XHTML Impress File" },
309 {
"png",
"impress_png_Export"},
315 {
"fodg",
"draw_ODG_FlatXML" },
316 {
"html",
"draw_html_Export" },
318 {
"pdf",
"draw_pdf_Export" },
319 {
"svg",
"draw_svg_Export" },
320 {
"xhtml",
"XHTML Draw File" },
321 {
"png",
"draw_png_Export"},
327 if (pString ==
nullptr)
330 OString sString(pString, strlen(pString));
331 return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
337 char* pMemory =
static_cast<char*
>(malloc(rStr.getLength() + 1));
339 memcpy(pMemory, rStr.getStr(), rStr.getLength() + 1);
356 OUString aWorkingDir;
357 osl_getProcessWorkingDir(&aWorkingDir.pData);
358 if (!aWorkingDir.endsWith(
"/"))
363 return rtl::Uri::convertRelToAbs(aWorkingDir,
aURL);
365 catch (
const rtl::MalformedUriException &)
375 if (pJSON && pJSON[0] !=
'\0')
385 OUString aType = anyItem.getValueTypeName();
386 rJson.
put(
"type", aType.toUtf8().getStr());
388 if (aType ==
"string")
389 rJson.
put(
"value", anyItem.get<OUString>().toUtf8().getStr());
390 else if (aType ==
"unsigned long")
391 rJson.
put(
"value", OString::number(anyItem.get<sal_uInt32>()).getStr());
392 else if (aType ==
"long")
393 rJson.
put(
"value", OString::number(anyItem.get<sal_Int32>()).getStr());
394 else if (aType ==
"[]any")
397 if (anyItem >>=
aSeq)
399 auto valueNode = rJson.
startNode(
"value");
401 for (
auto i = 0;
i <
aSeq.getLength(); ++
i)
416 if (rPayload.compare(0, 5,
"EMPTY") == 0)
420 aRet.
m_nPart = std::stol(rPayload.substr(6));
426 const char*
pos = rPayload.c_str();
427 const char*
end = rPayload.c_str() + rPayload.size();
451 nPart = rtl_str_toInt64_WithLength(
pos, 10,
end -
pos);
461 if (nWidth <= 0 || nHeight <= 0)
478 if (nWidth > 0 && nHeight > 0)
503 PayloadObject = rRectAndPart;
504 PayloadString.clear();
511 if(PayloadObject.which() != 1)
513 return boost::get<RectangleAndPart>(PayloadObject);
518 boost::property_tree::ptree aTree;
519 std::stringstream aStream(payload);
520 boost::property_tree::read_json(aStream, aTree);
526 return boost::get<boost::property_tree::ptree>(PayloadObject);
531 std::stringstream aJSONStream;
532 constexpr bool bPretty =
false;
533 boost::property_tree::write_json(aJSONStream, rTree, bPretty);
534 PayloadString = boost::trim_copy(aJSONStream.str());
536 PayloadObject = rTree;
541 assert(PayloadObject.which() == 2);
542 return boost::get<boost::property_tree::ptree>(PayloadObject);
549 assert(PayloadObject.which() == 3);
550 return boost::get<int>(PayloadObject);
557 switch (PayloadObject.which())
565 return getRectangleAndPart().toString().getStr() == getPayload();
570 std::stringstream aJSONStream;
571 boost::property_tree::write_json(aJSONStream, getJson(),
false);
572 const std::string aExpected = boost::trim_copy(aJSONStream.str());
573 return aExpected == getPayload();
581 assert(!
"Unknown variant type; please add an entry to validate.");
593 case LOK_CALLBACK_CELL_VIEW_CURSOR:
594 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
595 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
596 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
597 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
609 case LOK_CALLBACK_TEXT_SELECTION:
610 case LOK_CALLBACK_TEXT_SELECTION_START:
611 case LOK_CALLBACK_TEXT_SELECTION_END:
622 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
623 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
624 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
635 size_t viewIdPos = payload.find(
"viewId");
636 if (viewIdPos == std::string::npos)
639 size_t numberPos = payload.find(
":", viewIdPos + 6);
640 if (numberPos == std::string::npos)
643 for (++numberPos; numberPos < payload.length(); ++numberPos)
645 if (payload[numberPos] ==
',' || payload[numberPos] ==
'}' || (payload[numberPos] >=
'0' && payload[numberPos] <=
'9'))
649 if (numberPos < payload.length() && payload[numberPos] >=
'0' && payload[numberPos] <=
'9')
650 return strtol(payload.substr(numberPos).c_str(),
nullptr, 10);
657std::string extractCertificate(
const std::string & certificate)
659 const std::string
header(
"-----BEGIN CERTIFICATE-----");
660 const std::string footer(
"-----END CERTIFICATE-----");
664 size_t pos1 = certificate.find(header);
665 if (pos1 == std::string::npos)
668 size_t pos2 = certificate.find(footer, pos1 + 1);
669 if (pos2 == std::string::npos)
672 pos1 = pos1 +
header.length();
675 return certificate.substr(pos1, pos2);
678std::string extractPrivateKey(
const std::string & privateKey)
680 const std::string
header(
"-----BEGIN PRIVATE KEY-----");
681 const std::string footer(
"-----END PRIVATE KEY-----");
685 size_t pos1 = privateKey.find(header);
686 if (pos1 == std::string::npos)
689 size_t pos2 = privateKey.find(footer, pos1 + 1);
690 if (pos2 == std::string::npos)
693 pos1 = pos1 +
header.length();
696 return privateKey.substr(pos1, pos2);
717 return pFilter->GetMimeType();
721css::uno::Reference< css::document::XUndoManager > getUndoManager(
const css::uno::Reference< css::frame::XFrame >& rxFrame )
723 const css::uno::Reference< css::frame::XController >&
xController = rxFrame->getController();
726 const css::uno::Reference< css::frame::XModel >&
xModel =
xController->getModel();
729 const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW );
730 return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW );
734 return css::uno::Reference< css::document::XUndoManager > ();
738void ExecuteMarginLRChange(
743 pPageLRMarginItem->
SetLeft( nPageLeftMargin );
744 pPageLRMarginItem->
SetRight( nPageRightMargin );
746 SfxCallMode::RECORD, { pPageLRMarginItem });
750void ExecuteMarginULChange(
755 pPageULMarginItem->
SetUpper( nPageTopMargin );
756 pPageULMarginItem->
SetLower( nPageBottomMargin );
758 SfxCallMode::RECORD, { pPageULMarginItem });
762void ExecuteOrientationChange()
764 std::unique_ptr<SvxPageItem> pPageItem(
new SvxPageItem(SID_ATTR_PAGE));
770 css::uno::Reference< css::document::XUndoManager > mxUndoManager(
773 if ( mxUndoManager.is() )
774 mxUndoManager->enterUndoContext(
"" );
779 std::unique_ptr<SvxSizeItem> pPageSizeItem(pSizeItem->
Clone());
783 std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(pLRSpaceItem->
Clone());
787 std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(pULSpaceItem->
Clone());
790 bool bIsLandscape =
false;
791 if ( pPageSizeItem->GetSize().Width() > pPageSizeItem->GetSize().Height())
795 pPageItem->SetLandscape(!bIsLandscape);
799 const tools::Long nRotatedWidth = pPageSizeItem->GetSize().Height();
800 const tools::Long nRotatedHeight = pPageSizeItem->GetSize().Width();
801 pPageSizeItem->SetSize(
Size(nRotatedWidth, nRotatedHeight));
808 SfxCallMode::RECORD, { pPageSizeItem.get(), pPageItem.get() });
820 const tools::Long nPW = pPageSizeItem->GetSize().Width();
826 ExecuteMarginLRChange( pPageLRMarginItem->
GetLeft(), nMR - (nTmpPW - nPW ), pPageLRMarginItem.get() );
830 ExecuteMarginLRChange( nML - (nTmpPW - nPW ), pPageLRMarginItem->
GetRight(), pPageLRMarginItem.get() );
838 const tools::Long nPH = pPageSizeItem->GetSize().Height();
844 ExecuteMarginULChange( pPageULMarginItem->
GetUpper(), nMB - ( nTmpPH - nPH ), pPageULMarginItem.get() );
848 ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), pPageULMarginItem->
GetLower(), pPageULMarginItem.get() );
853 if ( mxUndoManager.is() )
854 mxUndoManager->leaveUndoContext();
857void setupSidebar(std::u16string_view sidebarDeckId = u
"")
877 if (!sidebarDeckId.empty())
883 pDockingWin->GetSidebarController()->SwitchToDefaultDeck();
886 pDockingWin->SyncUpdate();
910 OUString aNameEquals(OUString::Concat(rName) +
"=");
911 OUString aCommaNameEquals(OUString::Concat(
",") + rName +
"=");
914 if (rOptions.startsWith(aNameEquals))
916 size_t nLen = aNameEquals.getLength();
917 int nComma = rOptions.indexOf(
",", nLen);
920 aValue = rOptions.copy(nLen, nComma - nLen);
921 rOptions = rOptions.copy(nComma + 1);
925 aValue = rOptions.copy(nLen);
929 else if ((
nIndex = rOptions.indexOf(aCommaNameEquals)) >= 0)
931 size_t nLen = aCommaNameEquals.getLength();
932 int nComma = rOptions.indexOf(
",",
nIndex + nLen);
935 aValue = rOptions.copy(
nIndex + nLen, nComma -
nIndex - nLen);
936 rOptions = OUString::Concat(rOptions.subView(0,
nIndex)) + rOptions.subView(nComma);
940 aValue = rOptions.copy(
nIndex + nLen);
941 rOptions = rOptions.copy(0,
nIndex);
951static void doc_destroy(LibreOfficeKitDocument* pThis);
952static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* pUrl,
const char* pFormat,
const char* pFilterOptions);
956static int doc_getPart(LibreOfficeKitDocument* pThis);
957static void doc_setPart(LibreOfficeKitDocument* pThis,
int nPart);
958static void doc_selectPart(LibreOfficeKitDocument* pThis,
int nPart,
int nSelect);
961static void doc_setPartMode(LibreOfficeKitDocument* pThis,
int nPartMode);
963 unsigned char* pBuffer,
964 const int nCanvasWidth,
const int nCanvasHeight,
965 const int nTilePosX,
const int nTilePosY,
966 const int nTileWidth,
const int nTileHeight);
968static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
970 const int nCanvasWidth,
const int nCanvasHeight,
971 const int nTilePosX,
const int nTilePosY,
972 const int nTileWidth,
const int nTileHeight);
975 unsigned char* pBuffer,
977 const int nCanvasWidth,
const int nCanvasHeight,
978 const int nTilePosX,
const int nTilePosY,
979 const int nTileWidth,
const int nTileHeight);
985 const char* pArguments);
988 LibreOfficeKitCallback pCallback,
996 const char* blockedCommandList);
1003 unsigned nLOKWindowId,
1007 unsigned long long int nLOKWindowId,
1008 const char* pArguments);
1010 unsigned nLOKWindowId,
1022 unsigned nLOKWindowId,
1030 unsigned nLOKWindowId,
1036 const char* pCommand,
1037 const char* pArguments,
1038 bool bNotifyWhenFinished);
1040 unsigned nLOKWindowId,
1049 const char* pMimeType,
1050 char** pUsedMimeType);
1053 const char* pMimeType,
1055 char** pUsedMimeType);
1057 const char **pMimeTypes,
1059 char ***pOutMimeTypes,
1061 char ***pOutStreams);
1063 const size_t nInCount,
1064 const char **pInMimeTypes,
1065 const size_t *pInSizes,
1066 const char **pInStreams);
1067static bool doc_paste(LibreOfficeKitDocument* pThis,
1068 const char* pMimeType,
1078 int nTilePixelWidth,
1079 int nTilePixelHeight,
1081 int nTileTwipHeight);
1083static void doc_setOutlineState(LibreOfficeKitDocument* pThis,
bool bColumn,
int nLevel,
int nIndex,
bool bHidden);
1093 const char *pFontName,
1098static unsigned char*
doc_renderFont(LibreOfficeKitDocument* pThis,
1099 const char *pFontName,
1103static char*
doc_getPartHash(LibreOfficeKitDocument* pThis,
int nPart);
1105static void doc_paintWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1106 const int nX,
const int nY,
1107 const int nWidth,
const int nHeight);
1109static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1110 const int nX,
const int nY,
1111 const int nWidth,
const int nHeight,
1112 const double fDPIScale);
1114static void doc_paintWindowForView(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1115 const int nX,
const int nY,
1116 const int nWidth,
const int nHeight,
1117 const double fDPIScale,
int viewId);
1119static void doc_postWindow(LibreOfficeKitDocument* pThis,
unsigned
1120 nLOKWindowId,
int nAction,
const char* pData);
1122static char*
doc_getPartInfo(LibreOfficeKitDocument* pThis,
int nPart);
1125 const unsigned char* pCertificateBinary,
1126 const int nCertificateBinarySize,
1127 const unsigned char* pPrivateKeyBinary,
1128 const int nPrivateKeyBinarySize);
1131 const unsigned char* pCertificateBinary,
1132 const int nCertificateBinarySize);
1138static void doc_resizeWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
1139 const int nWidth,
const int nHeight);
1145 const char* pArguments);
1148 const char* pSearchResult,
unsigned char** pBitmapBuffer,
1149 int* pWidth,
int* pHeight,
size_t* pByteSize);
1174 SAL_INFO(
"lok",
"Set to clipboard for view " << xClip.get());
1183const vcl::Font* FindFont(std::u16string_view rFontName)
1189 if (pList && !rFontName.empty())
1195vcl::Font FindFont_FallbackToDefault(std::u16string_view rFontName)
1197 if (
auto pFound = FindFont(rFontName))
1201 GetDefaultFontFlags::NONE);
1206 : mxComponent(
std::move(xComponent))
1207 , mnDocumentId(nDocumentId)
1209 assert(nDocumentId != -1 &&
"Cannot set mnDocumentId to -1");
1304 forceSetClipboardForCurrentView(
this);
1314 catch (
const css::lang::DisposedException&)
1322 OUString sGenerator(
1324 OUString os(
"$_OS");
1325 ::rtl::Bootstrap::expandMacros(os);
1326 return sGenerator.replaceFirst(
"%1", os);
1332 :
Timer(
"lokit timer callback" )
1333 , mHandler( handler )
1348 :
Idle(
"lokit idle callback" ),
1359 m_states.emplace(LOK_CALLBACK_TEXT_SELECTION,
"NIL");
1360 m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION,
"NIL");
1361 m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
"NIL");
1362 m_states.emplace(LOK_CALLBACK_STATE_CHANGED,
"NIL");
1363 m_states.emplace(LOK_CALLBACK_MOUSE_POINTER,
"NIL");
1364 m_states.emplace(LOK_CALLBACK_CELL_CURSOR,
"NIL");
1365 m_states.emplace(LOK_CALLBACK_CELL_FORMULA,
"NIL");
1366 m_states.emplace(LOK_CALLBACK_CELL_ADDRESS,
"NIL");
1367 m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE,
"NIL");
1368 m_states.emplace(LOK_CALLBACK_SET_PART,
"NIL");
1369 m_states.emplace(LOK_CALLBACK_TABLE_SELECTED,
"NIL");
1370 m_states.emplace(LOK_CALLBACK_TAB_STOP_LIST,
"NIL");
1371 m_states.emplace(LOK_CALLBACK_RULER_UPDATE,
"NIL");
1372 m_states.emplace(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE,
"NIL");
1382 int delta = std::distance(
m_queue1.begin(), pos);
1388 int delta = std::distance(
m_queue1.rbegin(), pos);
1412 types.resize(
nType + 1 );
1421 bool allViewIds =
false;
1432 std::vector<PerViewIdData>& types = it.second;
1434 types[
nType ].set =
false;
1453 queue(LOK_CALLBACK_INVALIDATE_TILES, callbackData);
1459 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1467 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1484 bool bIsChartActive =
false;
1485 bool bIsComment =
false;
1486 if (
type == LOK_CALLBACK_GRAPHIC_SELECTION)
1489 bIsChartActive = aChartHelper.
GetWindow() !=
nullptr;
1491 else if (
type == LOK_CALLBACK_COMMENT)
1505 if (
type != LOK_CALLBACK_STATE_CHANGED &&
1506 type != LOK_CALLBACK_INVALIDATE_TILES &&
1507 type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1508 type != LOK_CALLBACK_CURSOR_VISIBLE &&
1509 type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE &&
1510 type != LOK_CALLBACK_TEXT_SELECTION &&
1511 type != LOK_CALLBACK_TEXT_SELECTION_START &&
1512 type != LOK_CALLBACK_TEXT_SELECTION_END &&
1513 type != LOK_CALLBACK_REFERENCE_MARKS)
1525 if (
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1526 aCallbackData.
getPayload().find(
", 0, 0, ") != std::string::npos &&
1527 aCallbackData.
getPayload().find(
"\"hyperlink\":\"\"") == std::string::npos &&
1528 aCallbackData.
getPayload().find(
"\"hyperlink\": {}") == std::string::npos)
1538 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
1545 SAL_INFO(
"lok",
"Received event with updated type [" <<
type <<
"] as normal callback");
1550 SAL_INFO(
"lok",
"Received event with updated type [" <<
type <<
"] as normal callback");
1557 case LOK_CALLBACK_TEXT_SELECTION_START:
1558 case LOK_CALLBACK_TEXT_SELECTION_END:
1559 case LOK_CALLBACK_TEXT_SELECTION:
1560 case LOK_CALLBACK_GRAPHIC_SELECTION:
1561 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1562 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1563 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1564 case LOK_CALLBACK_STATE_CHANGED:
1565 case LOK_CALLBACK_MOUSE_POINTER:
1566 case LOK_CALLBACK_CELL_CURSOR:
1567 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1568 case LOK_CALLBACK_CELL_FORMULA:
1569 case LOK_CALLBACK_CELL_ADDRESS:
1570 case LOK_CALLBACK_CELL_SELECTION_AREA:
1571 case LOK_CALLBACK_CURSOR_VISIBLE:
1572 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1573 case LOK_CALLBACK_SET_PART:
1574 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1575 case LOK_CALLBACK_INVALIDATE_HEADER:
1576 case LOK_CALLBACK_WINDOW:
1577 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1578 case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
1579 case LOK_CALLBACK_REFERENCE_MARKS:
1580 case LOK_CALLBACK_CELL_AUTO_FILL_AREA:
1593 if (
type == LOK_CALLBACK_TEXT_SELECTION && aCallbackData.
isEmpty())
1595 const auto& posStart = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_TEXT_SELECTION_START);
1596 auto posStart2 =
toQueue2(posStart);
1600 const auto& posEnd = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_TEXT_SELECTION_END);
1611 case LOK_CALLBACK_TEXT_SELECTION_START:
1612 case LOK_CALLBACK_TEXT_SELECTION_END:
1613 case LOK_CALLBACK_TEXT_SELECTION:
1614 case LOK_CALLBACK_GRAPHIC_SELECTION:
1615 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1616 case LOK_CALLBACK_INVALIDATE_TILES:
1628 case LOK_CALLBACK_TEXT_SELECTION_START:
1629 case LOK_CALLBACK_TEXT_SELECTION_END:
1630 case LOK_CALLBACK_TEXT_SELECTION:
1631 case LOK_CALLBACK_MOUSE_POINTER:
1632 case LOK_CALLBACK_CELL_CURSOR:
1633 case LOK_CALLBACK_CELL_FORMULA:
1634 case LOK_CALLBACK_CELL_ADDRESS:
1635 case LOK_CALLBACK_CURSOR_VISIBLE:
1636 case LOK_CALLBACK_SET_PART:
1637 case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
1638 case LOK_CALLBACK_RULER_UPDATE:
1648 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1649 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1650 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1651 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1652 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1653 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1654 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1655 case LOK_CALLBACK_FORM_FIELD_BUTTON:
1659 const bool hyperLinkException =
type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1660 aCallbackData.
getPayload().find(
"\"hyperlink\":\"\"") == std::string::npos &&
1661 aCallbackData.
getPayload().find(
"\"hyperlink\": {}") == std::string::npos;
1662 if(!hyperLinkException)
1664 const int nViewId = aCallbackData.
getViewId();
1666 return (nViewId == elemData.
getViewId());
1673 case LOK_CALLBACK_INVALIDATE_TILES:
1680 case LOK_CALLBACK_STATE_CHANGED:
1684 if (
pos != std::string::npos)
1689 if (
name !=
".uno:ModifiedStatus=")
1700 case LOK_CALLBACK_WINDOW:
1705 case LOK_CALLBACK_GRAPHIC_SELECTION:
1710 {
return (elemData.
getPayload().find(
"INPLACE") == std::string::npos); });
1717 assert(aCallbackData.
validate() &&
"Cached callback payload object and string mismatch!");
1719 m_queue2.emplace_back(aCallbackData);
1727 std::ostringstream oss;
1731 oss <<
m_queue1.size() <<
" items\n";
1734 for (; it1 !=
m_queue1.end(); ++it1, ++it2)
1735 oss <<
i++ <<
": [" << *it1 <<
"] [" << it2->getPayload() <<
"].\n";
1736 SAL_INFO(
"lok",
"Current Queue: " << oss.str());
1760 = std::find(
m_queue1.rbegin(),
m_queue1.rend(), LOK_CALLBACK_INVALIDATE_TILES);
1768 <<
"] since all tiles need to be invalidated.");
1778 <<
"] since overlaps existing all-parts.");
1787 <<
"] so removing all with part " << rcNew.
m_nPart <<
".");
1795 const auto rcOrig = rcNew;
1797 SAL_INFO(
"lok",
"Have [" <<
type <<
"]: [" << aCallbackData.
getPayload() <<
"] so merging overlapping.");
1802 SAL_INFO(
"lok",
"Nothing to merge between new: "
1803 << rcNew.toString() <<
", and old: " << rcOld.toString());
1810 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" has " << rcOld.toString()
1812 if (rcNew.m_aRectangle.Contains(rcOld.m_aRectangle))
1814 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
1815 << rcOld.toString() <<
".");
1819 else if (rcOld.m_nPart == -1)
1822 SAL_INFO(
"lok",
"Old " << rcOld.toString() <<
" has " << rcNew.toString()
1824 if (rcOld.m_aRectangle.Contains(rcNew.m_aRectangle))
1826 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
1827 << rcOld.toString() <<
".");
1835 const bool bOverlap = !rcOverlap.
IsEmpty();
1836 SAL_INFO(
"lok",
"Merging " << rcNew.
toString() <<
" & " << rcOld.toString()
1838 <<
" Overlap: " << bOverlap);
1851 if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
1853 SAL_INFO(
"lok",
"Replacing: " << rcOrig.toString() <<
" by " << rcNew.toString());
1854 if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth()
1855 || rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
1857 SAL_WARN(
"lok",
"Error: merged rect smaller.");
1862 aCallbackData.updateRectangleAndPart(rcNew);
1869 const std::string& payload = aCallbackData.
getPayload();
1871 boost::property_tree::ptree& aTree = aCallbackData.
setJson(payload);
1872 const unsigned nLOKWindowId = aTree.get<
unsigned>(
"id", 0);
1873 const std::string aAction = aTree.get<std::string>(
"action",
"");
1874 if (aAction ==
"invalidate")
1876 std::string aRectStr = aTree.get<std::string>(
"rectangle",
"");
1879 if (aRectStr.empty())
1882 const boost::property_tree::ptree& aOldTree = elemData.
getJson();
1883 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
1884 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
1895 bool invAllExist =
false;
1898 for (;it1 !=
m_queue1.rend(); ++it1, ++it2)
1900 if (*it1 != LOK_CALLBACK_WINDOW)
1902 const boost::property_tree::ptree& aOldTree = it2->getJson();
1903 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
1904 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate"
1905 && aOldTree.get<std::string>(
"rectangle",
"").empty())
1915 SAL_INFO(
"lok.dialog",
"Skipping queue ["
1916 <<
type <<
"]: [" << payload
1917 <<
"] since whole window needs to be invalidated.");
1921 std::istringstream aRectStream(aRectStr);
1924 aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
1926 bool currentIsRedundant =
false;
1927 removeAll(LOK_CALLBACK_WINDOW, [&aNewRect, &nLOKWindowId,
1929 const boost::property_tree::ptree& aOldTree = elemData.
getJson();
1930 if (aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
1933 std::istringstream aOldRectStream(aOldTree.get<std::string>(
"rectangle",
""));
1934 tools::Long nOldLeft, nOldTop, nOldWidth, nOldHeight;
1936 aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
1937 >> nOldComma >> nOldHeight;
1938 const tools::Rectangle aOldRect = tools::Rectangle(
1939 nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
1941 if (nLOKWindowId == aOldTree.get<unsigned>(
"id", 0))
1943 if (aNewRect == aOldRect)
1945 SAL_INFO(
"lok.dialog",
"Duplicate rect [" << aNewRect.toString()
1946 <<
"]. Skipping new.");
1948 currentIsRedundant = true;
1952 else if (aNewRect.Contains(aOldRect))
1954 SAL_INFO(
"lok.dialog",
1955 "New rect [" << aNewRect.toString() <<
"] engulfs old ["
1956 << aOldRect.toString() <<
"]. Replacing old.");
1960 else if (aOldRect.Contains(aNewRect))
1962 SAL_INFO(
"lok.dialog",
1963 "Old rect [" << aOldRect.toString() <<
"] engulfs new ["
1964 << aNewRect.toString() <<
"]. Skipping new.");
1966 currentIsRedundant = true;
1972 const tools::Rectangle aPreMergeRect = aNewRect;
1973 aNewRect.Union(aOldRect);
1974 SAL_INFO(
"lok.dialog",
"Merging rects ["
1975 << aPreMergeRect.toString() <<
"] & ["
1976 << aOldRect.toString() <<
"] = ["
1977 << aNewRect.toString()
1978 <<
"]. Replacing old.");
1989 if (currentIsRedundant)
1992 aTree.put(
"rectangle", aNewRect.toString().getStr());
1994 assert(aCallbackData.
validate() &&
"Validation after setJson failed!");
1997 else if (aAction ==
"created")
2000 removeAll(LOK_CALLBACK_WINDOW,[&nLOKWindowId](
const CallbackData& elemData) {
2001 const boost::property_tree::ptree& aOldTree = elemData.getJson();
2002 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
2015 auto xClip = forceSetClipboardForCurrentView(m_pDocument);
2018 pWindow->SetClipboard(xClipboard);
2021 else if (aAction ==
"size_changed")
2025 removeAll(LOK_CALLBACK_WINDOW, [&nLOKWindowId](
const CallbackData& elemData) {
2026 const boost::property_tree::ptree& aOldTree = elemData.getJson();
2027 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
2029 const std::string aOldAction = aOldTree.get<std::string>(
"action",
"");
2030 if (aOldAction ==
"invalidate")
2048 assert(viewShell !=
nullptr);
2051 std::vector<bool> updatedTypes;
2053 boost::container::flat_map<int, std::vector<PerViewIdData>> updatedTypesPerViewId;
2060 static const int orderedUpdatedTypes[] = {
2061 LOK_CALLBACK_TEXT_SELECTION_START, LOK_CALLBACK_TEXT_SELECTION_END, LOK_CALLBACK_TEXT_SELECTION };
2064 static const int orderedUpdatedTypesPerViewId[] = {
2065 LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
2066 LOK_CALLBACK_INVALIDATE_VIEW_CURSOR,
2067 LOK_CALLBACK_TEXT_VIEW_SELECTION };
2069 for(
int type : orderedUpdatedTypes )
2076 for(
const auto& it : updatedTypesPerViewId )
2078 int viewId = it.first;
2079 const std::vector<PerViewIdData>& types = it.second;
2080 for(
int type : orderedUpdatedTypesPerViewId )
2085 const int sourceViewId = types[
type ].sourceViewId;
2088 assert(sourceViewId >= 0);
2092 if(sourceViewShell ==
nullptr)
2094 SAL_INFO(
"lok",
"View #" << sourceViewId <<
" no longer found for updated event [" <<
type <<
"]");
2111 m_queue2.emplace_back(callbackData);
2113 <<
"] to have " <<
m_queue1.size() <<
" entries.");
2129 viewShell->flushPendingLOKInvalidateTiles();
2132 std::unique_lock<std::recursive_mutex>
lock(
m_mutex);
2140 for (; it1 !=
m_queue1.end(); ++it1, ++it2)
2142 const int type = *it1;
2143 const auto& payload = it2->getPayload();
2146 SAL_INFO(
"lok",
"processing event: [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2153 if (
type == LOK_CALLBACK_STATE_CHANGED &&
2154 (
idx = payload.find(
'=')) != std::string::npos)
2156 std::string key = payload.substr(0,
idx);
2157 std::string
value = payload.substr(
idx+1);
2162 if (stateIt->second ==
value)
2164 SAL_INFO(
"lok",
"Skipping new state duplicate: [" <<
type <<
"]: [" << payload <<
"].");
2167 SAL_INFO(
"lok",
"Replacing a state element [" <<
type <<
"]: [" << payload <<
"].");
2168 stateIt->second =
value;
2172 SAL_INFO(
"lok",
"Inserted a new state element: [" <<
type <<
"]: [" << payload <<
"]");
2182 if (stateIt->second == payload)
2184 SAL_INFO(
"lok",
"Skipping duplicate [" <<
type <<
"]: [" << payload <<
"].");
2187 stateIt->second = payload;
2196 auto& states = statesIt->second;
2197 const auto stateIt = states.find(
type);
2198 if (stateIt != states.end())
2201 if (stateIt->second == payload)
2203 SAL_INFO(
"lok",
"Skipping view duplicate [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2207 SAL_INFO(
"lok",
"Replacing an element in view states [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"].");
2208 stateIt->second = payload;
2212 SAL_INFO(
"lok",
"Inserted a new element in view states: [" <<
type <<
',' << viewId <<
"]: [" << payload <<
"]");
2213 states.emplace(
type, payload);
2238 bool bErased =
false;
2254 bool bErased =
false;
2262 if (rTestFunc(*it2))
2279 result.first->second.clear();
2303static void lo_destroy (LibreOfficeKit* pThis);
2304static int lo_initialize (LibreOfficeKit* pThis,
const char* pInstallPath,
const char* pUserProfilePath);
2305static LibreOfficeKitDocument*
lo_documentLoad (LibreOfficeKit* pThis,
const char* pURL);
2310 const char* pOptions);
2312 LibreOfficeKitCallback pCallback,
2318 const char* pPassword);
2320static int lo_runMacro (LibreOfficeKit* pThis,
const char* pURL);
2324 const unsigned char* pCertificateBinary,
2325 const int nCertificateBinarySize,
2326 const unsigned char* pPrivateKeyBinary,
2327 const int nPrivateKeyBinarySize);
2330 LibreOfficeKitPollCallback pPollCallback,
2331 LibreOfficeKitWakeCallback pWakeCallback,
2335 unsigned long long int nLOKWindowId,
2336 const char* pArguments);
2338static void lo_setOption(LibreOfficeKit* pThis,
const char* pOption,
const char* pValue);
2343 , mpCallback(nullptr)
2344 , mpCallbackData(nullptr)
2345 , mOptionalFeatures(0)
2382 void* rCGContext,
const Size nCanvasSize,
2383 const int nTilePosX,
const int nTilePosY,
2384 const int nTileWidth,
const int nTileHeight)
2387 aData.rCGContext =
reinterpret_cast<CGContextRef
>(rCGContext);
2390 pDevice->SetBackground(
Wallpaper(COL_TRANSPARENT));
2391 pDevice->SetOutputSizePixel(nCanvasSize);
2393 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2396void paintTileIOS(LibreOfficeKitDocument* pThis,
2397 unsigned char* pBuffer,
2398 const int nCanvasWidth,
const int nCanvasHeight,
const double fDPIScale,
2399 const int nTilePosX,
const int nTilePosY,
2400 const int nTileWidth,
const int nTileHeight)
2402 CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
2403 nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
2404 kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little);
2406 CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
2407 CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
2409 doc_paintTileToCGContext(pThis, (
void*) pCGContext, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2411 CGContextRelease(pCGContext);
2415void setLanguageAndLocale(OUString
const & aLangISO)
2425 if (sFormat == u
"pdf")
2428 rFilterDataMap[
"ExportBookmarks"] <<=
true;
2450 static int nDocumentIdCounter = 0;
2453 pLib->maLastExceptionMsg.clear();
2458 pLib->maLastExceptionMsg =
"Filename to load was not provided.";
2459 SAL_INFO(
"lok",
"URL for load is empty");
2463 pLib->maLastExceptionMsg.clear();
2467 pLib->maLastExceptionMsg =
"ComponentContext is not available";
2468 SAL_INFO(
"lok",
"ComponentContext is not available");
2474 if (!xComponentLoader.is())
2476 pLib->maLastExceptionMsg =
"ComponentLoader is not available";
2477 SAL_INFO(
"lok",
"ComponentLoader is not available");
2489 if (!aLanguage.isEmpty() && isValidLangTag)
2496 SAL_INFO(
"lok",
"Set document language to " << aLanguage);
2499 setLanguageAndLocale(aLanguage);
2504 const OUString aDeviceFormFactor =
extractParameter(aOptions,
u"DeviceFormFactor");
2508 if (!aBatch.isEmpty())
2513 const OUString sFilterOptions = aOptions;
2517 auto const pair(
pLib->mInteractionMap.insert(std::make_pair(
aURL.toUtf8(), pInteraction)));
2521 pLib->mInteractionMap.erase(aURL.toUtf8());
2526 int nMacroSecurityLevel = 1;
2527 const OUString aMacroSecurityLevel =
extractParameter(aOptions,
u"MacroSecurityLevel");
2528 if (!aMacroSecurityLevel.isEmpty())
2531 sal_uInt32 nFormat = 1;
2533 if (aFormatter.
IsNumberFormat(aMacroSecurityLevel, nFormat, nNumber))
2534 nMacroSecurityLevel =
static_cast<int>(nNumber);
2538#if defined(ANDROID) && HAVE_FEATURE_ANDROID_LOK
2539 sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG;
2541 const OUString aEnableMacrosExecution =
extractParameter(aOptions,
u"EnableMacrosExecution");
2542 sal_Int16 nMacroExecMode = aEnableMacrosExecution ==
"true" ? document::MacroExecMode::USE_CONFIG :
2543 document::MacroExecMode::NEVER_EXECUTE;
2558 const int nThisDocumentId = nDocumentIdCounter++;
2564 assert(!xComponent.is() || pair.second);
2566 if (!xComponent.is())
2568 pLib->maLastExceptionMsg =
"loadComponentFromURL returned an empty reference";
2569 SAL_INFO(
"lok",
"Document can't be loaded - " <<
pLib->maLastExceptionMsg);
2576 if (
pLib->mpCallback)
2579 pLib->mpCallback(LOK_CALLBACK_SIGNATURE_STATUS, OString::number(
nState).getStr(),
pLib->mpCallbackData);
2583 catch (
const uno::Exception& exception)
2585 pLib->maLastExceptionMsg = exception.Message;
2599 pLib->maLastExceptionMsg.clear();
2601 OUString sURL( pURL, strlen(pURL), RTL_TEXTENCODING_UTF8 );
2604 pLib->maLastExceptionMsg =
"Macro to run was not provided.";
2605 SAL_INFO(
"lok",
"Macro URL is empty");
2609 if (!sURL.startsWith(
"macro://"))
2611 pLib->maLastExceptionMsg =
"This doesn't look like macro URL";
2612 SAL_INFO(
"lok",
"Macro URL is invalid");
2616 pLib->maLastExceptionMsg.clear();
2620 pLib->maLastExceptionMsg =
"ComponentContext is not available";
2621 SAL_INFO(
"lok",
"ComponentContext is not available");
2626 aURL.Complete = sURL;
2631 xParser->parseStrict(
aURL );
2635 if (!xComponentLoader.is())
2637 pLib->maLastExceptionMsg =
"ComponentLoader is not available";
2638 SAL_INFO(
"lok",
"ComponentLoader is not available");
2649 xDP.set(
xSFactory->createInstance(
"com.sun.star.comp.sfx2.SfxMacroLoader"), uno::UNO_QUERY );
2654 pLib->maLastExceptionMsg =
"Macro loader is not available";
2655 SAL_INFO(
"lok",
"Macro loader is not available");
2661 css::beans::PropertyValue aErr;
2662 uno::Any aRet = xSyncDisp->dispatchWithReturnValue(
aURL, aEmpty );
2665 if (aErr.Name ==
"ErrorCode")
2667 sal_uInt32 nErrCode = 0;
2668 aErr.
Value >>= nErrCode;
2670 pLib->maLastExceptionMsg =
"An error occurred running macro (error code: " + OUString::number( nErrCode ) +
")";
2671 SAL_INFO(
"lok",
"Macro execution terminated with error code " << nErrCode);
2681 const unsigned char* pCertificateBinary,
2682 const int nCertificateBinarySize,
2683 const unsigned char* pPrivateKeyBinary,
2684 const int nPrivateKeyBinarySize)
2697 std::string aCertificateString(
reinterpret_cast<const char*
>(pCertificateBinary), nCertificateBinarySize);
2698 std::string aCertificateBase64String = extractCertificate(aCertificateString);
2699 if (!aCertificateBase64String.empty())
2701 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
2706 aCertificateSequence.realloc(nCertificateBinarySize);
2707 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.getArray());
2711 std::string aPrivateKeyString(
reinterpret_cast<const char*
>(pPrivateKeyBinary), nPrivateKeyBinarySize);
2712 std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
2713 if (!aPrivateKeyBase64String.empty())
2715 OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String.c_str());
2720 aPrivateKeySequence.realloc(nPrivateKeyBinarySize);
2721 std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeyBinarySize, aPrivateKeySequence.getArray());
2726 if (!xSecurityContext.is())
2732 if (!xCertificateCreator.is())
2737 if (!xCertificate.is())
2748 LibreOfficeKitCallback pCallback,
2757 pLib->maLastExceptionMsg.clear();
2763static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* sUrl,
const char* pFormat,
const char* pFilterOptions)
2780 SAL_INFO(
"lok",
"URL for save is empty");
2786 const ExtensionMap* pMap;
2790 case LOK_DOCTYPE_SPREADSHEET:
2793 case LOK_DOCTYPE_PRESENTATION:
2796 case LOK_DOCTYPE_DRAWING:
2799 case LOK_DOCTYPE_TEXT:
2802 case LOK_DOCTYPE_OTHER:
2804 SAL_INFO(
"lok",
"Can't save document - unsupported document type.");
2808 if (pFormat ==
nullptr)
2811 sal_Int32
idx =
aURL.lastIndexOf(
".");
2814 sFormat =
aURL.copy(
idx + 1 );
2823 OUString aFilterName;
2824 for (sal_Int32
i = 0; pMap[
i].extn; ++
i)
2826 if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[
i].extn))
2832 if (aFilterName.isEmpty())
2838 OUString aFilterOptions =
getUString(pFilterOptions);
2842 OUString watermarkText;
2843 std::u16string_view sFullSheetPreview;
2845 if ((
aIndex = aFilterOptions.indexOf(
",Watermark=")) >= 0)
2847 int bIndex = aFilterOptions.indexOf(
"WATERMARKEND");
2848 watermarkText = aFilterOptions.subView(
aIndex+11, bIndex-(
aIndex+11));
2849 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+12);
2852 if ((
aIndex = aFilterOptions.indexOf(
",FullSheetPreview=")) >= 0)
2854 int bIndex = aFilterOptions.indexOf(
"FULLSHEETPREVEND");
2855 sFullSheetPreview = aFilterOptions.subView(
aIndex+18, bIndex-(
aIndex+18));
2856 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+16);
2859 bool bFullSheetPreview = sFullSheetPreview ==
u"true";
2863 sal_Int32 pdfVer = 0;
2864 if ((
aIndex = aFilterOptions.indexOf(
",PDFVer=")) >= 0)
2866 int bIndex = aFilterOptions.indexOf(
"PDFVEREND");
2867 std::u16string_view sPdfVer = aFilterOptions.subView(
aIndex+8, bIndex-(
aIndex+8));
2868 aFilterOptions = OUString::Concat(aFilterOptions.subView(0,
aIndex)) + aFilterOptions.subView(bIndex+9);
2893 std::vector<OUString> aFilteredOptionVec;
2894 bool bTakeOwnership =
false;
2896 for (
const auto& rOption : aOptionSeq)
2898 if (rOption ==
"TakeOwnership")
2899 bTakeOwnership =
true;
2900 else if (rOption ==
"NoFileSync")
2901 aSaveMediaDescriptor[
"NoFileSync"] <<=
true;
2903 aFilteredOptionVec.push_back(rOption);
2906 aSaveMediaDescriptor[
"Overwrite"] <<=
true;
2907 aSaveMediaDescriptor[
"FilterName"] <<= aFilterName;
2909 auto aFilteredOptionSeq = comphelper::containerToSequence<OUString>(aFilteredOptionVec);
2911 aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS] <<= aFilterOptions;
2917 if (!aFilterOptions.startsWith(
"{"))
2919 setFormatSpecificFilterData(sFormat, aFilterDataMap);
2922 if (!watermarkText.isEmpty())
2923 aFilterDataMap[
"TiledWatermark"] <<= watermarkText;
2925 if (bFullSheetPreview)
2926 aFilterDataMap[
"SinglePageSheets"] <<=
true;
2929 aFilterDataMap[
"SelectPdfVersion"] <<= pdfVer;
2931 if (!aFilterDataMap.
empty())
2944 aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteraction;
2949 xStorable->storeAsURL(
aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
2951 xStorable->storeToURL(
aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
2955 catch (
const uno::Exception& exception)
2973 OUString sUnoCommands[] =
2975 OUString(
".uno:AlignLeft"),
2976 OUString(
".uno:AlignHorizontalCenter"),
2977 OUString(
".uno:AlignRight"),
2978 OUString(
".uno:BackColor"),
2979 OUString(
".uno:BackgroundColor"),
2980 OUString(
".uno:TableCellBackgroundColor"),
2981 OUString(
".uno:Bold"),
2982 OUString(
".uno:CenterPara"),
2983 OUString(
".uno:CharBackColor"),
2984 OUString(
".uno:CharBackgroundExt"),
2985 OUString(
".uno:CharFontName"),
2986 OUString(
".uno:Color"),
2987 OUString(
".uno:ControlCodes"),
2988 OUString(
".uno:DecrementIndent"),
2989 OUString(
".uno:DefaultBullet"),
2990 OUString(
".uno:DefaultNumbering"),
2991 OUString(
".uno:FontColor"),
2992 OUString(
".uno:FontHeight"),
2993 OUString(
".uno:IncrementIndent"),
2994 OUString(
".uno:Italic"),
2995 OUString(
".uno:JustifyPara"),
2996 OUString(
".uno:JumpToMark"),
2997 OUString(
".uno:OutlineFont"),
2998 OUString(
".uno:LeftPara"),
2999 OUString(
".uno:LanguageStatus"),
3000 OUString(
".uno:RightPara"),
3001 OUString(
".uno:Shadowed"),
3002 OUString(
".uno:SubScript"),
3003 OUString(
".uno:SuperScript"),
3004 OUString(
".uno:Strikeout"),
3005 OUString(
".uno:StyleApply"),
3006 OUString(
".uno:Underline"),
3007 OUString(
".uno:ModifiedStatus"),
3008 OUString(
".uno:Undo"),
3009 OUString(
".uno:Redo"),
3010 OUString(
".uno:InsertPage"),
3011 OUString(
".uno:DeletePage"),
3012 OUString(
".uno:DuplicatePage"),
3013 OUString(
".uno:InsertSlide"),
3014 OUString(
".uno:DeleteSlide"),
3015 OUString(
".uno:DuplicateSlide"),
3016 OUString(
".uno:Cut"),
3017 OUString(
".uno:Copy"),
3018 OUString(
".uno:Paste"),
3019 OUString(
".uno:SelectAll"),
3020 OUString(
".uno:ReplyComment"),
3021 OUString(
".uno:ResolveComment"),
3022 OUString(
".uno:ResolveCommentThread"),
3023 OUString(
".uno:InsertRowsBefore"),
3024 OUString(
".uno:InsertRowsAfter"),
3025 OUString(
".uno:InsertColumnsBefore"),
3026 OUString(
".uno:InsertColumnsAfter"),
3027 OUString(
".uno:DeleteRows"),
3028 OUString(
".uno:DeleteColumns"),
3029 OUString(
".uno:DeleteTable"),
3030 OUString(
".uno:SelectTable"),
3031 OUString(
".uno:EntireRow"),
3032 OUString(
".uno:EntireColumn"),
3033 OUString(
".uno:EntireCell"),
3034 OUString(
".uno:AssignLayout"),
3035 OUString(
".uno:StatusDocPos"),
3036 OUString(
".uno:RowColSelCount"),
3037 OUString(
".uno:StatusPageStyle"),
3038 OUString(
".uno:InsertMode"),
3039 OUString(
".uno:SpellOnline"),
3040 OUString(
".uno:StatusSelectionMode"),
3041 OUString(
".uno:StateTableCell"),
3042 OUString(
".uno:StatusBarFunc"),
3043 OUString(
".uno:StatePageNumber"),
3044 OUString(
".uno:StateWordCount"),
3045 OUString(
".uno:SelectionMode"),
3046 OUString(
".uno:PageStatus"),
3047 OUString(
".uno:LayoutStatus"),
3048 OUString(
".uno:Scale"),
3049 OUString(
".uno:Context"),
3050 OUString(
".uno:WrapText"),
3051 OUString(
".uno:ToggleMergeCells"),
3052 OUString(
".uno:NumberFormatCurrency"),
3053 OUString(
".uno:NumberFormatPercent"),
3054 OUString(
".uno:NumberFormatDecimal"),
3055 OUString(
".uno:NumberFormatDate"),
3056 OUString(
".uno:EditHeaderAndFooter"),
3057 OUString(
".uno:FrameLineColor"),
3058 OUString(
".uno:SortAscending"),
3059 OUString(
".uno:SortDescending"),
3060 OUString(
".uno:TrackChanges"),
3061 OUString(
".uno:ShowTrackedChanges"),
3062 OUString(
".uno:NextTrackedChange"),
3063 OUString(
".uno:PreviousTrackedChange"),
3064 OUString(
".uno:AcceptAllTrackedChanges"),
3065 OUString(
".uno:RejectAllTrackedChanges"),
3066 OUString(
".uno:TableDialog"),
3067 OUString(
".uno:FormatCellDialog"),
3068 OUString(
".uno:FontDialog"),
3069 OUString(
".uno:ParagraphDialog"),
3070 OUString(
".uno:OutlineBullet"),
3071 OUString(
".uno:InsertIndexesEntry"),
3072 OUString(
".uno:DocumentRepair"),
3073 OUString(
".uno:TransformDialog"),
3074 OUString(
".uno:InsertPageHeader"),
3075 OUString(
".uno:InsertPageFooter"),
3076 OUString(
".uno:OnlineAutoFormat"),
3077 OUString(
".uno:InsertObjectChart"),
3078 OUString(
".uno:InsertSection"),
3079 OUString(
".uno:InsertAnnotation"),
3080 OUString(
".uno:DeleteAnnotation"),
3081 OUString(
".uno:InsertPagebreak"),
3082 OUString(
".uno:InsertColumnBreak"),
3083 OUString(
".uno:HyperlinkDialog"),
3084 OUString(
".uno:InsertSymbol"),
3085 OUString(
".uno:EditRegion"),
3086 OUString(
".uno:ThesaurusDialog"),
3087 OUString(
".uno:FormatArea"),
3088 OUString(
".uno:FormatLine"),
3089 OUString(
".uno:FormatColumns"),
3090 OUString(
".uno:Watermark"),
3091 OUString(
".uno:ResetAttributes"),
3092 OUString(
".uno:Orientation"),
3093 OUString(
".uno:ObjectAlignLeft"),
3094 OUString(
".uno:ObjectAlignRight"),
3095 OUString(
".uno:AlignCenter"),
3096 OUString(
".uno:TransformPosX"),
3097 OUString(
".uno:TransformPosY"),
3098 OUString(
".uno:TransformWidth"),
3099 OUString(
".uno:TransformHeight"),
3100 OUString(
".uno:ObjectBackOne"),
3101 OUString(
".uno:SendToBack"),
3102 OUString(
".uno:ObjectForwardOne"),
3103 OUString(
".uno:BringToFront"),
3104 OUString(
".uno:WrapRight"),
3105 OUString(
".uno:WrapThrough"),
3106 OUString(
".uno:WrapLeft"),
3107 OUString(
".uno:WrapIdeal"),
3108 OUString(
".uno:WrapOn"),
3109 OUString(
".uno:WrapOff"),
3110 OUString(
".uno:UpdateCurIndex"),
3111 OUString(
".uno:InsertCaptionDialog"),
3112 OUString(
".uno:FormatGroup"),
3113 OUString(
".uno:SplitTable"),
3114 OUString(
".uno:SplitCell"),
3115 OUString(
".uno:MergeCells"),
3116 OUString(
".uno:DeleteNote"),
3117 OUString(
".uno:AcceptChanges"),
3118 OUString(
".uno:FormatPaintbrush"),
3119 OUString(
".uno:SetDefault"),
3120 OUString(
".uno:ParaLeftToRight"),
3121 OUString(
".uno:ParaRightToLeft"),
3122 OUString(
".uno:ParaspaceIncrease"),
3123 OUString(
".uno:ParaspaceDecrease"),
3124 OUString(
".uno:AcceptTrackedChange"),
3125 OUString(
".uno:RejectTrackedChange"),
3126 OUString(
".uno:ShowResolvedAnnotations"),
3127 OUString(
".uno:InsertBreak"),
3128 OUString(
".uno:InsertEndnote"),
3129 OUString(
".uno:InsertFootnote"),
3130 OUString(
".uno:InsertReferenceField"),
3131 OUString(
".uno:InsertBookmark"),
3132 OUString(
".uno:InsertAuthoritiesEntry"),
3133 OUString(
".uno:InsertMultiIndex"),
3134 OUString(
".uno:InsertField"),
3135 OUString(
".uno:InsertPageNumberField"),
3136 OUString(
".uno:InsertPageCountField"),
3137 OUString(
".uno:InsertDateField"),
3138 OUString(
".uno:InsertTitleField"),
3139 OUString(
".uno:InsertFieldCtrl"),
3140 OUString(
".uno:CharmapControl"),
3141 OUString(
".uno:EnterGroup"),
3142 OUString(
".uno:LeaveGroup"),
3143 OUString(
".uno:AlignUp"),
3144 OUString(
".uno:AlignMiddle"),
3145 OUString(
".uno:AlignDown"),
3146 OUString(
".uno:TraceChangeMode"),
3147 OUString(
".uno:Combine"),
3148 OUString(
".uno:Merge"),
3149 OUString(
".uno:Dismantle"),
3150 OUString(
".uno:Substract"),
3151 OUString(
".uno:DistributeSelection"),
3152 OUString(
".uno:Intersect"),
3153 OUString(
".uno:BorderInner"),
3154 OUString(
".uno:BorderOuter"),
3155 OUString(
".uno:FreezePanes"),
3156 OUString(
".uno:FreezePanesColumn"),
3157 OUString(
".uno:FreezePanesRow"),
3158 OUString(
".uno:Sidebar"),
3159 OUString(
".uno:SheetRightToLeft"),
3160 OUString(
".uno:RunMacro"),
3161 OUString(
".uno:SpacePara1"),
3162 OUString(
".uno:SpacePara15"),
3163 OUString(
".uno:SpacePara2"),
3164 OUString(
".uno:InsertSparkline"),
3165 OUString(
".uno:DeleteSparkline"),
3166 OUString(
".uno:DeleteSparklineGroup"),
3167 OUString(
".uno:EditSparklineGroup"),
3168 OUString(
".uno:EditSparkline"),
3169 OUString(
".uno:GroupSparklines"),
3170 OUString(
".uno:UngroupSparklines"),
3171 OUString(
".uno:FormatSparklineMenu"),
3172 OUString(
".uno:Protect"),
3173 OUString(
".uno:UnsetCellsReadOnly")
3176 util::URL aCommandURL;
3183 SAL_WARN(
"lok",
"iniUnoCommands: No Frame-Controller created.");
3191 SAL_WARN(
"lok",
"iniUnoCommands: Component context is not available");
3198 for (
const auto & sUnoCommand : sUnoCommands)
3200 aCommandURL.Complete = sUnoCommand;
3201 xParser->parseStrict(aCommandURL);
3226 if (xDocument->supportsService(
"com.sun.star.sheet.SpreadsheetDocument"))
3228 return LOK_DOCTYPE_SPREADSHEET;
3230 else if (xDocument->supportsService(
"com.sun.star.presentation.PresentationDocument"))
3232 return LOK_DOCTYPE_PRESENTATION;
3234 else if (xDocument->supportsService(
"com.sun.star.drawing.DrawingDocument"))
3236 return LOK_DOCTYPE_DRAWING;
3238 else if (xDocument->supportsService(
"com.sun.star.text.TextDocument") || xDocument->supportsService(
"com.sun.star.text.WebDocument"))
3240 return LOK_DOCTYPE_TEXT;
3247 catch (
const uno::Exception& exception)
3251 return LOK_DOCTYPE_OTHER;
3287static void doc_setPartImpl(LibreOfficeKitDocument* pThis,
int nPart,
bool bAllowChangeFocus =
true)
3301 pDoc->
setPart( nPart, bAllowChangeFocus );
3423 int nCurrentPart = pDoc->
getPart();
3436 if ( nCurrentPart < pDoc->getParts() )
3438 pDoc->
setPart( nCurrentPart );
3447 unsigned char* pBuffer,
3448 const int nCanvasWidth,
const int nCanvasHeight,
3449 const int nTilePosX,
const int nTilePosY,
3450 const int nTileWidth,
const int nTileHeight)
3457 SAL_INFO(
"lok.tiledrendering",
"paintTile: painting [" << nTileWidth <<
"x" << nTileHeight <<
3458 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3459 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3468#if defined(UNX) && !defined(MACOSX)
3478 double fDPIScaleX = 1.0;
3479 paintTileIOS(pThis, pBuffer, nCanvasWidth, nCanvasHeight, fDPIScaleX, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3486 pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(
3490 pDoc->
paintTile(*pDevice, nCanvasWidth, nCanvasHeight,
3491 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3493 static bool bDebug = getenv(
"LOK_DEBUG_TILES") !=
nullptr;
3498 aRect = pDevice->PixelToLogic(aRect);
3499 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
3501 pDevice->SetLineColor();
3502 pDevice->DrawRect(aRect);
3516static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
3518 const int nCanvasWidth,
const int nCanvasHeight,
3519 const int nTilePosX,
const int nTilePosY,
3520 const int nTileWidth,
const int nTileHeight)
3525 SAL_INFO(
"lok.tiledrendering",
"paintTileToCGContext: painting [" << nTileWidth <<
"x" << nTileHeight <<
3526 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3527 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3536 Size aCanvasSize(nCanvasWidth, nCanvasHeight);
3537 paintTileToCGContext(pDoc, rCGContext, aCanvasSize, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3543 unsigned char* pBuffer,
3545 const int nCanvasWidth,
const int nCanvasHeight,
3546 const int nTilePosX,
const int nTilePosY,
3547 const int nTileWidth,
const int nTileHeight)
3554 SAL_INFO(
"lok.tiledrendering",
"paintPartTile: painting @ " << nPart <<
" ["
3555 << nTileWidth <<
"x" << nTileHeight <<
"]@("
3556 << nTilePosX <<
", " << nTilePosY <<
") to ["
3557 << nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3562 if (nOrigViewId < 0)
3573 std::vector<int> viewIds(viewCount);
3576 nOrigViewId = viewIds[0];
3581 if (nOrigViewId >= 0)
3585 handlerIt->second->disableCallbacks();
3593 int nViewId = nOrigViewId;
3594 int nLastNonEditorView = nViewId;
3609 if (pViewShell->
getPart() == nPart && !bIsInEdit)
3612 nLastNonEditorView = nViewId;
3622 if (pCurrentViewShell && pCurrentViewShell->
GetDrawView() &&
3629 if (nPart != nOrigPart)
3635 doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3637 if (!isText && nPart != nOrigPart)
3641 if (!isText && nViewId != nOrigViewId)
3646 catch (
const std::exception&)
3651 if (nOrigViewId >= 0)
3655 handlerIt->second->enableCallbacks();
3662 return LOK_TILEMODE_BGRA;
3678 *pWidth = aDocumentSize.
Width();
3679 *pHeight = aDocumentSize.
Height();
3688 const char* pArguments)
3705 LibreOfficeKitCallback pCallback,
3717 const size_t nId = nView;
3718 if (pCallback !=
nullptr)
3722 if (pair.first ==
nId)
3725 pair.second->addViewStates(nView);
3732 if (pair.first ==
nId)
3735 pair.second->removeViewStates(nView);
3741 if (pCallback !=
nullptr)
3745 if (pair.first ==
nId)
3811static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
int nType,
int nCharCode,
int nKeyCode)
3829 catch (
const uno::Exception& exception)
3832 SAL_INFO(
"lok",
"Failed to postKeyEvent " << exception.Message);
3876 if (nLOKWindowId == 0)
3900 if (nCharBefore > 0)
3903 if (nLOKWindowId == 0)
3906 for (
int i = 0;
i < nCharBefore; ++
i)
3907 pWindow->KeyInput(aEvt);
3916 if (nLOKWindowId == 0)
3919 for (
int i = 0;
i < nCharAfter; ++
i)
3920 pWindow->KeyInput(aEvt);
3945 case LOK_KEYEVENT_KEYINPUT:
3948 case LOK_KEYEVENT_KEYUP:
3981 case LOK_DOCTYPE_PRESENTATION:
3982 aMediaDescriptor[
"FilterName"] <<= OUString(
"impress_svg_Export");
3984 case LOK_DOCTYPE_DRAWING:
3985 aMediaDescriptor[
"FilterName"] <<= OUString(
"draw_svg_Export");
3987 case LOK_DOCTYPE_TEXT:
3988 aMediaDescriptor[
"FilterName"] <<= OUString(
"writer_svg_Export");
3990 case LOK_DOCTYPE_SPREADSHEET:
3991 aMediaDescriptor[
"FilterName"] <<= OUString(
"calc_svg_Export");
3994 SAL_WARN(
"lok",
"Failed to render shape selection: Document type is not supported");
3996 aMediaDescriptor[
"SelectionOnly"] <<=
true;
3997 aMediaDescriptor[
"OutputStream"] <<= xOut;
3998 aMediaDescriptor[
"IsPreview"] <<=
true;
4000 xStorable->storeToURL(
"private:stream", aMediaDescriptor.getAsConstPropertyValueList());
4005 *pOutput =
static_cast<char*
>(malloc(nOutputSize));
4008 std::memcpy(*pOutput, aOutStream.
GetData(), nOutputSize);
4013 catch (
const uno::Exception& exception)
4032class DispatchResultListener :
public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
4035 std::shared_ptr<CallbackFlushHandler> mpCallback;
4038 DispatchResultListener(
const char* pCommand, std::shared_ptr<CallbackFlushHandler> pCallback)
4039 : maCommand(pCommand)
4040 , mpCallback(
std::move(pCallback))
4045 virtual void SAL_CALL dispatchFinished(
const css::frame::DispatchResultEvent& rEvent)
override
4048 aJson.
put(
"commandName", maCommand);
4050 if (rEvent.State != frame::DispatchResultState::DONTKNOW)
4052 bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS);
4053 aJson.
put(
"success", bSuccess);
4057 mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.
extractData());
4060 virtual void SAL_CALL disposing(
const css::lang::EventObject&)
override {}
4083 if (!bFoundWeldedControl)
4085 if (!bFoundWeldedControl)
4087 if (!bFoundWeldedControl)
4096 if (bFoundWeldedControl)
4106static void doc_sendDialogEvent(LibreOfficeKitDocument* ,
unsigned long long int nWindowId,
const char* pArguments)
4111static void lo_sendDialogEvent(LibreOfficeKit* ,
unsigned long long int nWindowId,
const char* pArguments)
4116static void lo_setOption(LibreOfficeKit* ,
const char *pOption,
const char* pValue)
4118 static char* pCurrentSalLogOverride =
nullptr;
4120 if (strcmp(pOption,
"traceeventrecording") == 0)
4122 if (strcmp(pValue,
"start") == 0)
4129 else if (strcmp(pValue,
"stop") == 0)
4132 else if (strcmp(pOption,
"sallogoverride") == 0)
4134 if (pCurrentSalLogOverride !=
nullptr)
4135 free(pCurrentSalLogOverride);
4136 if (pValue ==
nullptr)
4137 pCurrentSalLogOverride =
nullptr;
4139 pCurrentSalLogOverride = strdup(pValue);
4141 if (pCurrentSalLogOverride ==
nullptr || pCurrentSalLogOverride[0] ==
'\0')
4142 sal_detail_set_log_selector(
nullptr);
4144 sal_detail_set_log_selector(pCurrentSalLogOverride);
4146 else if (strcmp(pOption,
"addfont") == 0)
4155static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand,
const char* pArguments,
bool bNotifyWhenFinished)
4163 OUString
aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
4170 beans::PropertyValue aSynchronMode;
4171 aSynchronMode.Name =
"SynchronMode";
4172 aSynchronMode.Value <<=
false;
4173 aPropertyValuesVector.push_back(aSynchronMode);
4182 ExecuteOrientationChange();
4190 OUString
aMimeType = lcl_getCurrentDocumentMimeType(pDocument);
4197 OUString
aURL = xStorable->getLocation();
4199 bool bResult =
doc_saveAs(pThis, aURLUtf8.getStr(),
"pdf",
nullptr);
4203 aJson.
put(
"commandName", pCommand);
4204 aJson.
put(
"success", bResult);
4214 beans::PropertyValue aValue;
4215 aValue.Name =
"InteractionHandler";
4216 aValue.Value <<= xInteraction;
4217 aPropertyValuesVector.push_back(aValue);
4219 bool bDontSaveIfUnmodified =
false;
4220 aPropertyValuesVector.erase(std::remove_if(aPropertyValuesVector.begin(),
4221 aPropertyValuesVector.end(),
4222 [&bDontSaveIfUnmodified](
const beans::PropertyValue& aItem){
4223 if (aItem.Name ==
"DontSaveIfUnmodified")
4225 bDontSaveIfUnmodified = aItem.Value.get<bool>();
4229 }), aPropertyValuesVector.end());
4232 if (bDontSaveIfUnmodified && !pDocSh->
IsModified())
4235 aJson.
put(
"commandName", pCommand);
4236 aJson.
put(
"success",
false);
4239 auto resultNode = aJson.
startNode(
"result");
4240 aJson.
put(
"type",
"string");
4241 aJson.
put(
"value",
"unmodified");
4247 else if (
gImpl && aCommand ==
".uno:TransformDialog")
4249 bool bNeedConversion =
false;
4253 if (aChartHelper.GetWindow() )
4255 bNeedConversion =
true;
4259 if (
OutputDevice* pOutputDevice = pView->GetFirstOutputDevice())
4261 bNeedConversion = (pOutputDevice->GetMapMode().GetMapUnit() == MapUnit::Map100thMM);
4265 if (bNeedConversion)
4268 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
4270 if (rPropValue.Name ==
"TransformPosX"
4271 || rPropValue.Name ==
"TransformPosY"
4272 || rPropValue.Name ==
"TransformWidth"
4273 || rPropValue.Name ==
"TransformHeight"
4274 || rPropValue.Name ==
"TransformRotationX"
4275 || rPropValue.Name ==
"TransformRotationY")
4277 rPropValue.Value >>=
value;
4279 rPropValue.Value <<=
value;
4284 if (aChartHelper.GetWindow() && aPropertyValuesVector.size() > 0)
4286 if (aPropertyValuesVector[0].Name !=
"Action")
4293 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
4295 if (rPropValue.Name ==
"TransformPosX" || rPropValue.Name ==
"TransformRotationX")
4297 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
4298 rPropValue.Value <<=
value - nLeft;
4300 else if (rPropValue.Name ==
"TransformPosY" || rPropValue.Name ==
"TransformRotationY")
4302 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
4303 rPropValue.Value <<=
value - nTop;
4307 util::URL aCommandURL;
4308 aCommandURL.Path =
"LOKTransform";
4309 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
4314 else if (
gImpl && aCommand ==
".uno:LOKSidebarWriterPage")
4316 setupSidebar(u
"WriterPageDeck");
4319 else if (
gImpl && aCommand ==
".uno:SidebarShow")
4324 else if (
gImpl && aCommand ==
".uno:SidebarHide")
4330 bool bResult =
false;
4333 if (aChartHelper.GetWindow() && aCommand !=
".uno:Save" )
4335 util::URL aCommandURL;
4336 aCommandURL.Path =
aCommand.copy(5);
4337 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
4341 else if (bNotifyWhenFinished && pDocument->mpCallbackFlushHandlers.count(nView))
4344 new DispatchResultListener(pCommand, pDocument->mpCallbackFlushHandlers[nView]));
4355static void doc_postMouseEvent(LibreOfficeKitDocument* pThis,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
4372 catch (
const uno::Exception& exception)
4375 SAL_INFO(
"lok",
"Failed to postMouseEvent " << exception.Message);
4379static void doc_postWindowMouseEvent(LibreOfficeKitDocument* ,
unsigned nLOKWindowId,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
4393 const Point aPos(nX, nY);
4401 case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
4404 case LOK_MOUSEEVENT_MOUSEBUTTONUP:
4407 case LOK_MOUSEEVENT_MOUSEMOVE:
4430 OString aType(pType);
4433 if (aType ==
"panBegin")
4434 eEventType = GestureEventType::PanningBegin;
4435 else if (aType ==
"panEnd")
4436 eEventType = GestureEventType::PanningEnd;
4443 PanningOrientation::Vertical,
4483 Size aOffset(pWindow->GetOutOffXPixel(), pWindow->GetOutOffYPixel());
4484 Point aCursorPos(nX, nY);
4485 aCursorPos.Move(aOffset);
4488 MouseEvent aCursorEvent(aCursorPos, 1, MouseEventModifiers::SIMPLECLICK, 0, nModifier);
4494 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4495 const OString &aInMimeType, OString &aRet);
4498 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4499 const OString &aMimeType, OString &aRet)
4505 auto aSeq = Sequence<sal_Int8>(
reinterpret_cast<const sal_Int8*
>(aRet.getStr()),
4507 OUStringBuffer aBase64Data;
4511 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
4513 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
4514 "name=\"generator\" content=\""
4517 "</head><body><img src=\"data:" +
aMimeType +
";base64,"
4518 + aBase64Data.makeStringAndClear().toUtf8() +
"\"/></body></html>";
4524 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4525 const OString &aMimeType, OString &aRet)
4531 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
4533 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
4534 "name=\"generator\" content=\""
4536 +
"\"/></head><body><pre>" + aRet +
"</pre></body></html>";
4542 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4543 const OString &aInMimeType, OString &aRet)
4548 bool bConvert =
false;
4554 aMimeType =
"text/plain;charset=utf-16";
4559 datatransfer::DataFlavor aFlavor;
4560 aFlavor.MimeType = OUString::fromUtf8(
aMimeType.getStr());
4561 if (
aMimeType ==
"text/plain;charset=utf-16")
4566 if (!xTransferable->isDataFlavorSupported(aFlavor))
4569 if (aInMimeType ==
"text/html")
4586 aAny = xTransferable->getTransferData(aFlavor);
4588 catch (
const css::datatransfer::UnsupportedFlavorException& e)
4590 SetLastExceptionMsg(
"Unsupported flavor " + aFlavor.MimeType +
" exception " + e.Message);
4593 catch (
const css::uno::Exception& e)
4606 aRet = OString(
reinterpret_cast<const char *
>(aString.getStr()), aString.getLength() *
sizeof(
sal_Unicode));
4612 aRet = OString(
reinterpret_cast<const char*
>(aSequence.getConstArray()), aSequence.getLength());
4632 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->
getSelection();
4639 const char *pType = pMimeType;
4640 if (!pType || pType[0] ==
'\0')
4641 pType =
"text/plain;charset=utf-8";
4651 *pUsedMimeType = strdup(pMimeType);
4653 *pUsedMimeType =
nullptr;
4670 return LOK_SELTYPE_NONE;
4673 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->
getSelection();
4677 return LOK_SELTYPE_NONE;
4680 css::uno::Reference<css::datatransfer::XTransferable2> xTransferable2(xTransferable, css::uno::UNO_QUERY);
4681 if (xTransferable2.is() && xTransferable2->isComplex())
4682 return LOK_SELTYPE_COMPLEX;
4687 return LOK_SELTYPE_NONE;
4689 if (aRet.getLength() > 10000)
4690 return LOK_SELTYPE_COMPLEX;
4692 return !aRet.isEmpty() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE;
4708 return LOK_SELTYPE_NONE;
4711 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->
getSelection();
4715 return LOK_SELTYPE_NONE;
4718 css::uno::Reference<css::datatransfer::XTransferable2> xTransferable2(xTransferable, css::uno::UNO_QUERY);
4719 if (xTransferable2.is() && xTransferable2->isComplex())
4720 return LOK_SELTYPE_COMPLEX;
4722 const char *pType = pMimeType;
4723 if (!pType || pType[0] ==
'\0')
4724 pType =
"text/plain;charset=utf-8";
4729 return LOK_SELTYPE_NONE;
4731 if (aRet.getLength() > 10000)
4732 return LOK_SELTYPE_COMPLEX;
4735 return LOK_SELTYPE_NONE;
4743 *pUsedMimeType = strdup(pMimeType);
4745 *pUsedMimeType =
nullptr;
4748 return LOK_SELTYPE_TEXT;
4752 const char **pMimeTypes,
4754 char ***pOutMimeTypes,
4756 char ***pOutStreams)
4762 (void) pOutMimeTypes;
4766 assert(!
"doc_getClipboard should not be called on iOS");
4776 assert (pOutMimeTypes);
4778 assert (pOutStreams);
4781 *pOutMimeTypes =
nullptr;
4782 *pOutSizes =
nullptr;
4783 *pOutStreams =
nullptr;
4794 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = xClip->getContents();
4795 SAL_INFO(
"lok",
"Got from clip: " << xClip.get() <<
" transferrable: " << xTransferable);
4802 std::vector<OString> aMimeTypes;
4806 if (!flavors.getLength())
4811 for (
const auto &it : flavors)
4816 for (
size_t i = 0; pMimeTypes[
i]; ++
i)
4817 aMimeTypes.push_back(OString(pMimeTypes[
i]));
4820 *pOutCount = aMimeTypes.size();
4821 *pOutSizes =
static_cast<size_t *
>(malloc(*pOutCount *
sizeof(
size_t)));
4822 *pOutMimeTypes =
static_cast<char **
>(malloc(*pOutCount *
sizeof(
char *)));
4823 *pOutStreams =
static_cast<char **
>(malloc(*pOutCount *
sizeof(
char *)));
4824 for (
size_t i = 0;
i < aMimeTypes.size(); ++
i)
4826 if (aMimeTypes[
i] ==
"text/plain;charset=utf-16")
4827 (*pOutMimeTypes)[
i] = strdup(
"text/plain;charset=utf-8");
4829 (*pOutMimeTypes)[
i] = strdup(aMimeTypes[
i].getStr());
4833 if (!bSuccess || aRet.getLength() < 1)
4835 (*pOutSizes)[
i] = 0;
4836 (*pOutStreams)[
i] =
nullptr;
4840 (*pOutSizes)[
i] = aRet.getLength();
4850 const size_t nInCount,
4851 const char **pInMimeTypes,
4852 const size_t *pInSizes,
4853 const char **pInStreams)
4858 (void) pInMimeTypes;
4876 auto xClip = forceSetClipboardForCurrentView(pThis);
4879 SAL_INFO(
"lok",
"Set clip: " << xClip.get() <<
" to: " << xTransferable);
4890static bool doc_paste(LibreOfficeKitDocument* pThis,
const char* pMimeType,
const char* pData,
size_t nSize)
4896 const char *pInMimeTypes[1];
4897 const char *pInStreams[1];
4899 pInMimeTypes[0] = pMimeType;
4900 pInSizes[0] = nSize;
4901 pInStreams[0] =
pData;
4908 {
"AnchorType",
uno::Any(
static_cast<sal_uInt16
>(css::text::TextContentAnchorType_AS_CHARACTER))},
4909 {
"IgnoreComments",
uno::Any(
true)},
4956 css::uno::Sequence< css::lang::Locale > aLocales;
4963 css::uno::Reference<css::linguistic2::XSpellChecker> xSpell = xLangSrv->getSpellChecker();
4965 aLocales = xSpell->getLocales();
4969 boost::property_tree::ptree aTree;
4970 aTree.put(
"commandName", pCommand);
4971 boost::property_tree::ptree aValues;
4972 boost::property_tree::ptree aChild;
4974 for ( css::lang::Locale
const & locale : std::as_const(aLocales) )
4978 if (sLanguage.startsWith(
"{") && sLanguage.endsWith(
"}"))
4981 sLanguage +=
";" + aLanguageTag.
getBcp47(
false);
4982 aChild.put(
"", sLanguage.toUtf8());
4983 aValues.push_back(std::make_pair(
"", aChild));
4985 aTree.add_child(
"commandValues", aValues);
4986 std::stringstream aStream;
4987 boost::property_tree::write_json(aStream, aTree);
4988 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
4990 strcpy(pJson, aStream.str().c_str());
4991 pJson[aStream.str().size()] =
'\0';
4999 pDocSh->
GetItem(SID_ATTR_CHAR_FONTLIST));
5002 boost::property_tree::ptree aTree;
5003 aTree.put(
"commandName", pCommand);
5004 boost::property_tree::ptree aValues;
5008 for (sal_uInt16
i = 0;
i < nFontCount; ++
i)
5010 boost::property_tree::ptree aChildren;
5013 sal_uInt16 nSizeCount = 0;
5014 while (pAry[nSizeCount])
5016 boost::property_tree::ptree aChild;
5017 aChild.put(
"",
static_cast<float>(pAry[nSizeCount]) / 10);
5018 aChildren.push_back(std::make_pair(
"", aChild));
5021 aValues.add_child(rFontMetric.
GetFamilyName().toUtf8().getStr(), aChildren);
5024 aTree.add_child(
"commandValues", aValues);
5025 std::stringstream aStream;
5026 boost::property_tree::write_json(aStream, aTree);
5027 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
5029 strcpy(pJson, aStream.str().c_str());
5030 pJson[aStream.str().size()] =
'\0';
5036 OUString aFoundFont(::rtl::Uri::decode(OStringToOUString(aFontName, RTL_TEXTENCODING_UTF8), rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8));
5038 boost::property_tree::ptree aTree;
5039 aTree.put(
"commandName",
".uno:FontSubset");
5040 boost::property_tree::ptree aValues;
5042 if (
const vcl::Font* pFont = FindFont(aFoundFont))
5047 aDevice->SetFont(*pFont);
5048 aDevice->GetFontCharMap(xFontCharMap);
5053 boost::property_tree::ptree aChild;
5054 aChild.put(
"",
static_cast<int>(ublock_getCode(subset.GetRangeMin())));
5055 aValues.push_back(std::make_pair(
"", aChild));
5059 aTree.add_child(
"commandValues", aValues);
5060 std::stringstream aStream;
5061 boost::property_tree::write_json(aStream, aTree);
5062 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
5064 strcpy(pJson, aStream.str().c_str());
5065 pJson[aStream.str().size()] =
'\0';
5069static char*
getStyles(LibreOfficeKitDocument* pThis,
const char* pCommand)
5073 boost::property_tree::ptree aTree;
5074 aTree.put(
"commandName", pCommand);
5079 static const std::vector<OUString> aWriterStyles =
5093 std::set<OUString> aDefaultStyleNames;
5095 boost::property_tree::ptree aValues;
5096 for (OUString
const & sStyleFam : aStyleFamilies)
5098 boost::property_tree::ptree aChildren;
5104 if (sStyleFam ==
"ParagraphStyles"
5107 for (
const OUString& rStyle: aWriterStyles)
5109 aDefaultStyleNames.insert( rStyle );
5111 boost::property_tree::ptree aChild;
5112 aChild.put(
"", rStyle.toUtf8());
5113 aChildren.push_back(std::make_pair(
"", aChild));
5118 for (
const OUString& rStyle: aStyles )
5122 if (aDefaultStyleNames.find(rStyle) == aDefaultStyleNames.end() ||
5125 boost::property_tree::ptree aChild;
5126 aChild.put(
"", rStyle.toUtf8());
5127 aChildren.push_back(std::make_pair(
"", aChild));
5130 aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren);
5135 boost::property_tree::ptree aChild;
5136 boost::property_tree::ptree aChildren;
5137 static const OUStringLiteral sPageStyles(
u"PageStyles");
5141 if (xStyleFamilies->hasByName(sPageStyles) && (xStyleFamilies->getByName(sPageStyles) >>= xContainer))
5144 for (OUString
const &
sName : aSeqNames)
5147 xProperty.set(xContainer->getByName(
sName), uno::UNO_QUERY);
5148 if (xProperty.is() && (xProperty->getPropertyValue(
"IsPhysical") >>= bIsPhysical) && bIsPhysical)
5150 OUString displayName;
5151 xProperty->getPropertyValue(
"DisplayName") >>= displayName;
5152 aChild.put(
"", displayName.toUtf8());
5153 aChildren.push_back(std::make_pair(
"", aChild));
5156 aValues.add_child(
"HeaderFooter", aChildren);
5161 boost::property_tree::ptree aCommandList;
5164 boost::property_tree::ptree aChild;
5166 OUString sClearFormat =
SvxResId(RID_SVXSTR_CLEARFORM);
5168 boost::property_tree::ptree
aName;
5169 aName.put(
"", sClearFormat.toUtf8());
5170 aChild.push_back(std::make_pair(
"text",
aName));
5172 boost::property_tree::ptree
aCommand;
5173 aCommand.put(
"",
".uno:ResetAttributes");
5174 aChild.push_back(std::make_pair(
"id",
aCommand));
5176 aCommandList.push_back(std::make_pair(
"", aChild));
5179 aValues.add_child(
"Commands", aCommandList);
5182 aTree.add_child(
"commandValues", aValues);
5183 std::stringstream aStream;
5184 boost::property_tree::write_json(aStream, aTree);
5185 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
5187 strcpy(pJson, aStream.str().c_str());
5188 pJson[aStream.str().size()] =
'\0';
5194enum class UndoOrRedo
5220 if (eCommand == UndoOrRedo::UNDO)
5224 char* pJson = strdup(aString.toUtf8().getStr());
5240 auto redlinesNode = aJson.
startArray(
"redlines");
5242 for (
size_t nIndex = 0; xRedlines->hasMoreElements(); ++
nIndex)
5246 aJson.
put(
"index",
static_cast<sal_Int32
>(
nIndex));
5249 xRedline->getPropertyValue(
"RedlineAuthor") >>= sAuthor;
5250 aJson.
put(
"author", sAuthor);
5253 xRedline->getPropertyValue(
"RedlineType") >>=
sType;
5257 xRedline->getPropertyValue(
"RedlineComment") >>= sComment;
5258 aJson.
put(
"comment", sComment);
5260 OUString sDescription;
5261 xRedline->getPropertyValue(
"RedlineDescription") >>= sDescription;
5262 aJson.
put(
"description", sDescription);
5264 util::DateTime aDateTime;
5265 xRedline->getPropertyValue(
"RedlineDateTime") >>= aDateTime;
5267 aJson.
put(
"dateTime", sDateTime);
5306 const std::string_view
aCommand(pCommand);
5307 static constexpr OStringLiteral aViewRowColumnHeaders(
".uno:ViewRowColumnHeaders");
5308 static constexpr OStringLiteral aSheetGeometryData(
".uno:SheetGeometryData");
5309 static constexpr OStringLiteral aCellCursor(
".uno:CellCursor");
5310 static constexpr OStringLiteral aFontSubset(
".uno:FontSubset&name=");
5312 if (!strcmp(pCommand,
".uno:LanguageStatus"))
5316 else if (!strcmp(pCommand,
".uno:CharFontName"))
5320 else if (!strcmp(pCommand,
".uno:StyleApply"))