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>
34 #include <string_view>
36 #include <boost/property_tree/json_parser.hpp>
37 #include <boost/algorithm/string.hpp>
39 #include <LibreOfficeKit/LibreOfficeKit.h>
40 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
46 #include <osl/file.hxx>
47 #include <osl/process.h>
48 #include <osl/thread.h>
49 #include <rtl/bootstrap.hxx>
50 #include <rtl/strbuf.hxx>
51 #include <rtl/uri.hxx>
65 #include <com/sun/star/document/MacroExecMode.hpp>
66 #include <com/sun/star/beans/XPropertySet.hpp>
67 #include <com/sun/star/container/XNameAccess.hpp>
68 #include <com/sun/star/frame/Desktop.hpp>
69 #include <com/sun/star/frame/DispatchResultEvent.hpp>
70 #include <com/sun/star/frame/DispatchResultState.hpp>
71 #include <com/sun/star/frame/XDispatchProvider.hpp>
72 #include <com/sun/star/frame/XDispatchResultListener.hpp>
73 #include <com/sun/star/frame/XSynchronousDispatch.hpp>
74 #include <com/sun/star/frame/XStorable.hpp>
75 #include <com/sun/star/lang/Locale.hpp>
76 #include <com/sun/star/lang/XComponent.hpp>
77 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
78 #include <com/sun/star/reflection/theCoreReflection.hpp>
79 #include <com/sun/star/reflection/XIdlClass.hpp>
80 #include <com/sun/star/reflection/XIdlReflection.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>
118 #include <svx/strings.hrc>
120 #include <svx/svxids.hrc>
139 #include <unicode/uchar.h>
146 #include <osl/module.hxx>
159 #include <com/sun/star/document/XUndoManager.hpp>
160 #include <com/sun/star/document/XUndoManagerSupplier.hpp>
167 #include "../app/cmdlineargs.hxx"
169 #include "../app/sofficemain.h"
170 #include "../app/officeipcthread.hxx"
175 #include <officecfg/Office/Impress.hxx>
188 SAL_WARN_IF(!s.isEmpty(),
"lok",
"lok exception '" + s +
"'");
198 const char *filterName;
205 {
"doc",
"MS Word 97" },
206 {
"docm",
"MS Word 2007 XML VBA" },
207 {
"docx",
"MS Word 2007 XML" },
208 {
"fodt",
"OpenDocument Text Flat XML" },
209 {
"html",
"HTML (StarWriter)" },
210 {
"odt",
"writer8" },
211 {
"ott",
"writer8_template" },
212 {
"pdf",
"writer_pdf_Export" },
214 {
"rtf",
"Rich Text Format" },
216 {
"xhtml",
"XHTML Writer File" },
217 {
"png",
"writer_png_Export" },
223 {
"csv",
"Text - txt - csv (StarCalc)" },
224 {
"fods",
"OpenDocument Spreadsheet Flat XML" },
225 {
"html",
"HTML (StarCalc)" },
227 {
"ots",
"calc8_template" },
228 {
"pdf",
"calc_pdf_Export" },
229 {
"xhtml",
"XHTML Calc File" },
230 {
"xls",
"MS Excel 97" },
231 {
"xlsm",
"Calc MS Excel 2007 VBA XML" },
232 {
"xlsx",
"Calc MS Excel 2007 XML" },
233 {
"png",
"calc_png_Export" },
239 {
"fodp",
"OpenDocument Presentation Flat XML" },
240 {
"html",
"impress_html_Export" },
241 {
"odg",
"impress8_draw" },
242 {
"odp",
"impress8" },
243 {
"otp",
"impress8_template" },
244 {
"pdf",
"impress_pdf_Export" },
245 {
"potm",
"Impress MS PowerPoint 2007 XML Template" },
246 {
"pot",
"MS PowerPoint 97 Vorlage" },
247 {
"pptm",
"Impress MS PowerPoint 2007 XML VBA" },
248 {
"pptx",
"Impress MS PowerPoint 2007 XML" },
249 {
"pps",
"MS PowerPoint 97 Autoplay" },
250 {
"ppt",
"MS PowerPoint 97" },
251 {
"svg",
"impress_svg_Export" },
252 {
"xhtml",
"XHTML Impress File" },
253 {
"png",
"impress_png_Export"},
259 {
"fodg",
"draw_ODG_FlatXML" },
260 {
"html",
"draw_html_Export" },
262 {
"pdf",
"draw_pdf_Export" },
263 {
"svg",
"draw_svg_Export" },
264 {
"xhtml",
"XHTML Draw File" },
265 {
"png",
"draw_png_Export"},
271 if (pString ==
nullptr)
274 OString sString(pString, strlen(pString));
275 return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
281 char* pMemory =
static_cast<char*
>(malloc(rStr.getLength() + 1));
283 memcpy(pMemory, rStr.getStr(), rStr.getLength() + 1);
300 OUString aWorkingDir;
301 osl_getProcessWorkingDir(&aWorkingDir.pData);
302 if (!aWorkingDir.endsWith(
"/"))
307 return rtl::Uri::convertRelToAbs(aWorkingDir, aURL);
309 catch (
const rtl::MalformedUriException &)
321 uno::Reference< reflection::XIdlField > aField;
322 boost::property_tree::ptree aNodeNull, aNodeValue, aNodeField;
323 const std::string& rType = aTree.get<std::string>(
"type",
"");
324 const std::string&
rValue = aTree.get<std::string>(
"value",
"");
325 uno::Sequence< uno::Reference< reflection::XIdlField > > aFields;
326 uno::Reference< reflection:: XIdlClass > xIdlClass =
330 uno::TypeClass aTypeClass = xIdlClass->getTypeClass();
331 xIdlClass->createObject(aAny);
332 aFields = xIdlClass->getFields();
333 nFields = aFields.getLength();
334 aNodeValue = aTree.get_child(
"value", aNodeNull);
335 if (nFields > 0 && aNodeValue != aNodeNull)
337 for (sal_Int32 itField = 0; itField < nFields; ++itField)
339 aField = aFields[itField];
340 aNodeField = aNodeValue.get_child(aField->getName().toUtf8().getStr(), aNodeNull);
341 if (aNodeField != aNodeNull)
344 aField->set(aAny, aValue);
348 else if (!rValue.empty())
350 if (aTypeClass == uno::TypeClass_VOID)
352 else if (aTypeClass == uno::TypeClass_BYTE)
353 aAny <<= static_cast<sal_Int8>(OString(rValue.c_str()).
toInt32());
354 else if (aTypeClass == uno::TypeClass_BOOLEAN)
355 aAny <<= OString(rValue.c_str()).toBoolean();
356 else if (aTypeClass == uno::TypeClass_SHORT)
357 aAny <<= static_cast<sal_Int16>(OString(rValue.c_str()).
toInt32());
358 else if (aTypeClass == uno::TypeClass_UNSIGNED_SHORT)
359 aAny <<= static_cast<sal_uInt16>(OString(rValue.c_str()).toUInt32());
360 else if (aTypeClass == uno::TypeClass_LONG)
361 aAny <<= OString(rValue.c_str()).
toInt32();
362 else if (aTypeClass == uno::TypeClass_UNSIGNED_LONG)
363 aAny <<= static_cast<sal_uInt32>(OString(rValue.c_str()).
toInt32());
364 else if (aTypeClass == uno::TypeClass_FLOAT)
365 aAny <<= OString(rValue.c_str()).toFloat();
366 else if (aTypeClass == uno::TypeClass_DOUBLE)
367 aAny <<= OString(rValue.c_str()).
toDouble();
368 else if (aTypeClass == uno::TypeClass_STRING)
369 aAny <<= OUString::fromUtf8(rValue.c_str());
378 if (pJSON && pJSON[0] !=
'\0')
380 boost::property_tree::ptree aTree, aNodeNull, aNodeValue;
381 std::stringstream aStream(pJSON);
382 boost::property_tree::read_json(aStream, aTree);
384 for (
const auto& rPair : aTree)
386 const std::string& rType = rPair.second.get<std::string>(
"type",
"");
387 const std::string&
rValue = rPair.second.get<std::string>(
"value",
"");
389 beans::PropertyValue aValue;
390 aValue.Name = OUString::fromUtf8(rPair.first.c_str());
391 if (rType ==
"string")
392 aValue.Value <<= OUString::fromUtf8(rValue.c_str());
393 else if (rType ==
"boolean")
394 aValue.Value <<= OString(rValue.c_str()).toBoolean();
395 else if (rType ==
"float")
396 aValue.Value <<= OString(rValue.c_str()).toFloat();
397 else if (rType ==
"long")
398 aValue.Value <<= OString(rValue.c_str()).
toInt32();
399 else if (rType ==
"short")
400 aValue.Value <<= sal_Int16(OString(rValue.c_str()).
toInt32());
401 else if (rType ==
"unsigned short")
402 aValue.Value <<= sal_uInt16(OString(rValue.c_str()).toUInt32());
403 else if (rType ==
"int64")
404 aValue.Value <<= OString(rValue.c_str()).toInt64();
405 else if (rType ==
"int32")
406 aValue.Value <<= OString(rValue.c_str()).
toInt32();
407 else if (rType ==
"int16")
408 aValue.Value <<= sal_Int16(OString(rValue.c_str()).
toInt32());
409 else if (rType ==
"uint64")
410 aValue.Value <<= OString(rValue.c_str()).toUInt64();
411 else if (rType ==
"uint32")
412 aValue.Value <<= OString(rValue.c_str()).toUInt32();
413 else if (rType ==
"uint16")
414 aValue.Value <<= sal_uInt16(OString(rValue.c_str()).toUInt32());
415 else if (rType ==
"[]byte")
417 aNodeValue = rPair.second.get_child(
"value", aNodeNull);
418 if (aNodeValue != aNodeNull && aNodeValue.size() == 0)
420 uno::Sequence< sal_Int8 > aSeqByte(reinterpret_cast<const sal_Int8*>(rValue.c_str()), rValue.size());
421 aValue.Value <<= aSeqByte;
424 else if (rType ==
"[]any")
426 aNodeValue = rPair.second.get_child(
"value", aNodeNull);
427 if (aNodeValue != aNodeNull && !aNodeValue.empty())
430 uno::Sequence< uno::Any >
aSeq(aNodeValue.size());
431 for (
const auto& rSeqPair : aNodeValue)
433 aValue.Value <<=
aSeq;
437 SAL_WARN(
"desktop.lib",
"jsonToPropertyValuesVector: unhandled type '"<<rType<<
"'");
438 aArguments.push_back(aValue);
447 boost::property_tree::ptree aTree;
448 OUString aType = anyItem.getValueTypeName();
449 aTree.put(
"type", aType.toUtf8().getStr());
451 if (aType ==
"string")
452 aTree.put(
"value", anyItem.get<OUString>().toUtf8().getStr());
453 else if (aType ==
"unsigned long")
454 aTree.put(
"value", OString::number(anyItem.get<sal_uInt32>()).getStr());
455 else if (aType ==
"long")
456 aTree.put(
"value", OString::number(anyItem.get<sal_Int32>()).getStr());
457 else if (aType ==
"[]any")
459 uno::Sequence<uno::Any>
aSeq;
460 if (anyItem >>= aSeq)
462 boost::property_tree::ptree aSubTree;
464 for (
auto i = 0;
i < aSeq.getLength(); ++
i)
468 aTree.add_child(
"value", aSubTree);
482 if (rPayload.compare(0, 5,
"EMPTY") == 0)
486 aRet.
m_nPart = std::stol(rPayload.substr(6));
491 std::istringstream aStream(rPayload);
497 aStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight >> nComma >> nPart;
501 aStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
504 if (nWidth > 0 && nHeight > 0)
520 if (nWidth > 0 && nHeight > 0)
531 RectangleAndPart& CallbackFlushHandler::CallbackData::setRectangleAndPart(
const std::string& payload)
533 setRectangleAndPart(RectangleAndPart::Create(payload));
536 return boost::get<RectangleAndPart>(PayloadObject);
539 void CallbackFlushHandler::CallbackData::setRectangleAndPart(
const RectangleAndPart& rRectAndPart)
541 PayloadString = rRectAndPart.
toString().getStr();
542 PayloadObject = rRectAndPart;
547 assert(PayloadObject.which() == 1);
548 return boost::get<RectangleAndPart>(PayloadObject);
551 boost::property_tree::ptree& CallbackFlushHandler::CallbackData::setJson(
const std::string& payload)
553 boost::property_tree::ptree aTree;
554 std::stringstream aStream(payload);
555 boost::property_tree::read_json(aStream, aTree);
561 return boost::get<boost::property_tree::ptree>(PayloadObject);
564 void CallbackFlushHandler::CallbackData::setJson(
const boost::property_tree::ptree& rTree)
566 std::stringstream aJSONStream;
567 constexpr
bool bPretty =
false;
568 boost::property_tree::write_json(aJSONStream, rTree, bPretty);
569 PayloadString = boost::trim_copy(aJSONStream.str());
571 PayloadObject = rTree;
574 const boost::property_tree::ptree& CallbackFlushHandler::CallbackData::getJson()
const
576 assert(PayloadObject.which() == 2);
577 return boost::get<boost::property_tree::ptree>(PayloadObject);
580 bool CallbackFlushHandler::CallbackData::validate()
const
582 switch (PayloadObject.which())
590 return getRectangleAndPart().toString().getStr() == PayloadString;
595 std::stringstream aJSONStream;
596 boost::property_tree::write_json(aJSONStream, getJson(),
false);
597 const std::string aExpected = boost::trim_copy(aJSONStream.str());
598 return aExpected == PayloadString;
602 assert(!
"Unknown variant type; please add an entry to validate.");
612 bool lcl_isViewCallbackType(
const int type)
616 case LOK_CALLBACK_CELL_VIEW_CURSOR:
617 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
618 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
619 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
620 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
628 int lcl_getViewId(
const std::string& payload)
632 size_t viewIdPos = payload.find(
"viewId");
633 if (viewIdPos == std::string::npos)
636 size_t numberPos = payload.find(
":", viewIdPos + 6);
637 if (numberPos == std::string::npos)
640 for (++numberPos; numberPos < payload.length(); ++numberPos)
642 if (payload[numberPos] ==
',' || payload[numberPos] ==
'}' || (payload[numberPos] >=
'0' && payload[numberPos] <=
'9'))
646 if (numberPos < payload.length() && payload[numberPos] >=
'0' && payload[numberPos] <=
'9')
647 return strtol(payload.substr(numberPos).c_str(),
nullptr, 10);
655 return rCallbackData.
getJson().get<
int>(
"viewId");
659 std::string extractCertificate(
const std::string & certificate)
661 const std::string
header(
"-----BEGIN CERTIFICATE-----");
662 const std::string footer(
"-----END CERTIFICATE-----");
666 size_t pos1 = certificate.find(header);
667 if (pos1 == std::string::npos)
670 size_t pos2 = certificate.find(footer, pos1 + 1);
671 if (pos2 == std::string::npos)
674 pos1 = pos1 +
header.length();
677 return certificate.substr(pos1, pos2);
680 std::string extractPrivateKey(
const std::string & privateKey)
682 const std::string
header(
"-----BEGIN PRIVATE KEY-----");
683 const std::string footer(
"-----END PRIVATE KEY-----");
687 size_t pos1 = privateKey.find(header);
688 if (pos1 == std::string::npos)
691 size_t pos2 = privateKey.find(footer, pos1 + 1);
692 if (pos2 == std::string::npos)
695 pos1 = pos1 +
header.length();
698 return privateKey.substr(pos1, pos2);
719 return pFilter->GetMimeType();
723 css::uno::Reference< css::document::XUndoManager > getUndoManager(
const css::uno::Reference< css::frame::XFrame >& rxFrame )
725 const css::uno::Reference< css::frame::XController >&
xController = rxFrame->getController();
726 if ( xController.is() )
728 const css::uno::Reference< css::frame::XModel >&
xModel = xController->getModel();
731 const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW );
732 return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW );
736 return css::uno::Reference< css::document::XUndoManager > ();
740 void ExecuteMarginLRChange(
745 pPageLRMarginItem->
SetLeft( nPageLeftMargin );
746 pPageLRMarginItem->
SetRight( nPageRightMargin );
748 SfxCallMode::RECORD, { pPageLRMarginItem });
752 void ExecuteMarginULChange(
757 pPageULMarginItem->
SetUpper( nPageTopMargin );
758 pPageULMarginItem->
SetLower( nPageBottomMargin );
760 SfxCallMode::RECORD, { pPageULMarginItem });
764 void ExecuteOrientationChange()
766 std::unique_ptr<SvxPageItem> pPageItem(
new SvxPageItem(SID_ATTR_PAGE));
767 std::unique_ptr<SvxSizeItem> pPageSizeItem(
new SvxSizeItem(SID_ATTR_PAGE_SIZE));
768 std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(
new SvxLongLRSpaceItem( 0, 0, SID_ATTR_PAGE_LRSPACE ));
769 std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(
new SvxLongULSpaceItem( 0, 0, SID_ATTR_PAGE_ULSPACE ));
774 css::uno::Reference< css::document::XUndoManager > mxUndoManager(
777 if ( mxUndoManager.is() )
778 mxUndoManager->enterUndoContext(
"" );
785 pPageSizeItem.reset( static_cast<SvxSizeItem*>(pItem->
Clone()) );
790 pPageLRMarginItem.reset( static_cast<SvxLongLRSpaceItem*>(pItem->
Clone()) );
795 pPageULMarginItem.reset( static_cast<SvxLongULSpaceItem*>(pItem->
Clone()) );
799 bool bIsLandscape =
false;
800 if ( pPageSizeItem->GetSize().Width() > pPageSizeItem->GetSize().Height())
804 pPageItem->SetLandscape(!bIsLandscape);
808 const tools::Long nRotatedWidth = pPageSizeItem->GetSize().Height();
809 const tools::Long nRotatedHeight = pPageSizeItem->GetSize().Width();
810 pPageSizeItem->SetSize(
Size(nRotatedWidth, nRotatedHeight));
817 SfxCallMode::RECORD, { pPageSizeItem.get(), pPageItem.get() });
829 const tools::Long nPW = pPageSizeItem->GetSize().Width();
835 ExecuteMarginLRChange( pPageLRMarginItem->
GetLeft(), nMR - (nTmpPW - nPW ), pPageLRMarginItem.get() );
839 ExecuteMarginLRChange( nML - (nTmpPW - nPW ), pPageLRMarginItem->
GetRight(), pPageLRMarginItem.get() );
847 const tools::Long nPH = pPageSizeItem->GetSize().Height();
853 ExecuteMarginULChange( pPageULMarginItem->
GetUpper(), nMB - ( nTmpPH - nPH ), pPageULMarginItem.get() );
857 ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), pPageULMarginItem->
GetLower(), pPageULMarginItem.get() );
862 if ( mxUndoManager.is() )
863 mxUndoManager->leaveUndoContext();
866 void setupSidebar(std::u16string_view sidebarDeckId = u
"")
889 bool switchToDefault =
true;
891 if (currentDeckId ==
"ChartDeck")
892 switchToDefault =
false;
894 if (!sidebarDeckId.empty())
896 pDockingWin->GetSidebarController()->SwitchToDeck(sidebarDeckId);
901 pDockingWin->GetSidebarController()->SwitchToDefaultDeck();
904 pDockingWin->SyncUpdate();
951 OUString aNameEquals(OUString::Concat(rName) +
"=");
952 OUString aCommaNameEquals(OUString::Concat(
",") + rName +
"=");
955 if (rOptions.startsWith(aNameEquals))
957 size_t nLen = aNameEquals.getLength();
958 int nComma = rOptions.indexOf(
",", nLen);
961 aValue = rOptions.copy(nLen, nComma - nLen);
962 rOptions = rOptions.copy(nComma + 1);
966 aValue = rOptions.copy(nLen);
970 else if ((nIndex = rOptions.indexOf(aCommaNameEquals)) >= 0)
972 size_t nLen = aCommaNameEquals.getLength();
973 int nComma = rOptions.indexOf(
",", nIndex + nLen);
976 aValue = rOptions.copy(nIndex + nLen, nComma - nIndex - nLen);
977 rOptions = OUString::Concat(rOptions.subView(0, nIndex)) + rOptions.subView(nComma);
981 aValue = rOptions.copy(nIndex + nLen);
982 rOptions = rOptions.copy(0, nIndex);
992 static void doc_destroy(LibreOfficeKitDocument* pThis);
993 static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* pUrl,
const char* pFormat,
const char* pFilterOptions);
997 static int doc_getPart(LibreOfficeKitDocument* pThis);
998 static void doc_setPart(LibreOfficeKitDocument* pThis,
int nPart);
999 static void doc_selectPart(LibreOfficeKitDocument* pThis,
int nPart,
int nSelect);
1001 static char*
doc_getPartName(LibreOfficeKitDocument* pThis,
int nPart);
1002 static void doc_setPartMode(LibreOfficeKitDocument* pThis,
int nPartMode);
1004 unsigned char* pBuffer,
1005 const int nCanvasWidth,
const int nCanvasHeight,
1006 const int nTilePosX,
const int nTilePosY,
1007 const int nTileWidth,
const int nTileHeight);
1009 static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
1011 const int nCanvasWidth,
const int nCanvasHeight,
1012 const int nTilePosX,
const int nTilePosY,
1013 const int nTileWidth,
const int nTileHeight);
1016 unsigned char* pBuffer,
1018 const int nCanvasWidth,
const int nCanvasHeight,
1019 const int nTilePosX,
const int nTilePosY,
1020 const int nTileWidth,
const int nTileHeight);
1026 const char* pArguments);
1029 LibreOfficeKitCallback pCallback,
1040 unsigned nLOKWindowId,
1044 unsigned long long int nLOKWindowId,
1045 const char* pArguments);
1047 unsigned nLOKWindowId,
1059 unsigned nLOKWindowId,
1067 unsigned nLOKWindowId,
1073 const char* pCommand,
1074 const char* pArguments,
1075 bool bNotifyWhenFinished);
1077 unsigned nLOKWindowId,
1086 const char* pMimeType,
1087 char** pUsedMimeType);
1090 const char **pMimeTypes,
1092 char ***pOutMimeTypes,
1094 char ***pOutStreams);
1096 const size_t nInCount,
1097 const char **pInMimeTypes,
1098 const size_t *pInSizes,
1099 const char **pInStreams);
1100 static bool doc_paste(LibreOfficeKitDocument* pThis,
1101 const char* pMimeType,
1111 int nTilePixelWidth,
1112 int nTilePixelHeight,
1114 int nTileTwipHeight);
1116 static void doc_setOutlineState(LibreOfficeKitDocument* pThis,
bool bColumn,
int nLevel,
int nIndex,
bool bHidden);
1120 static void doc_setView(LibreOfficeKitDocument* pThis,
int nId);
1121 static int doc_getView(LibreOfficeKitDocument* pThis);
1123 static bool doc_getViewIds(LibreOfficeKitDocument* pThis,
int* pArray,
size_t nSize);
1124 static void doc_setViewLanguage(LibreOfficeKitDocument* pThis,
int nId,
const char* language);
1126 const char *pFontName,
1131 static unsigned char*
doc_renderFont(LibreOfficeKitDocument* pThis,
1132 const char *pFontName,
1136 static char*
doc_getPartHash(LibreOfficeKitDocument* pThis,
int nPart);
1138 static void doc_paintWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1139 const int nX,
const int nY,
1140 const int nWidth,
const int nHeight);
1142 static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1143 const int nX,
const int nY,
1144 const int nWidth,
const int nHeight,
1145 const double fDPIScale);
1147 static void doc_paintWindowForView(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
unsigned char* pBuffer,
1148 const int nX,
const int nY,
1149 const int nWidth,
const int nHeight,
1150 const double fDPIScale,
int viewId);
1152 static void doc_postWindow(LibreOfficeKitDocument* pThis,
unsigned
1153 nLOKWindowId,
int nAction,
const char* pData);
1155 static char*
doc_getPartInfo(LibreOfficeKitDocument* pThis,
int nPart);
1158 const unsigned char* pCertificateBinary,
1159 const int nCertificateBinarySize,
1160 const unsigned char* pPrivateKeyBinary,
1161 const int nPrivateKeyBinarySize);
1164 const unsigned char* pCertificateBinary,
1165 const int nCertificateBinarySize);
1171 static void doc_resizeWindow(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
1172 const int nWidth,
const int nHeight);
1178 const char* pArguments);
1200 SAL_INFO(
"lok",
"Set to clipboard for view " << xClip.get());
1202 pDoc->
setClipboard(uno::Reference<datatransfer::clipboard::XClipboard>(xClip->getXI(), UNO_QUERY));
1211 LibLODocument_Impl::LibLODocument_Impl(
const uno::Reference <css::lang::XComponent> &xComponent,
int nDocumentId)
1212 : mxComponent(xComponent)
1213 , mnDocumentId(nDocumentId)
1215 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 :
Idle(
"lokit timer callback" ),
1333 m_pDocument(pDocument),
1334 m_pCallback(pCallback),
1336 m_nDisableCallbacks(0)
1342 m_states.emplace(LOK_CALLBACK_TEXT_SELECTION,
"NIL");
1343 m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION,
"NIL");
1344 m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
"NIL");
1345 m_states.emplace(LOK_CALLBACK_STATE_CHANGED,
"NIL");
1346 m_states.emplace(LOK_CALLBACK_MOUSE_POINTER,
"NIL");
1347 m_states.emplace(LOK_CALLBACK_CELL_CURSOR,
"NIL");
1348 m_states.emplace(LOK_CALLBACK_CELL_FORMULA,
"NIL");
1349 m_states.emplace(LOK_CALLBACK_CELL_ADDRESS,
"NIL");
1350 m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE,
"NIL");
1351 m_states.emplace(LOK_CALLBACK_SET_PART,
"NIL");
1366 self->
queue(type, payload);
1374 CallbackData aCallbackData(type, (data ? data :
"(nil)"));
1376 SAL_INFO(
"lok",
"Queue: [" << type <<
"]: [" << payload <<
"] on " <<
m_queue.size() <<
" entries.");
1378 bool bIsChartActive =
false;
1379 if (type == LOK_CALLBACK_GRAPHIC_SELECTION)
1382 bIsChartActive = aChartHelper.
GetWindow() !=
nullptr;
1394 if (type != LOK_CALLBACK_STATE_CHANGED &&
1395 type != LOK_CALLBACK_INVALIDATE_TILES &&
1396 type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1397 type != LOK_CALLBACK_CURSOR_VISIBLE &&
1398 type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE &&
1399 type != LOK_CALLBACK_TEXT_SELECTION &&
1400 type != LOK_CALLBACK_TEXT_SELECTION_START &&
1401 type != LOK_CALLBACK_TEXT_SELECTION_END &&
1402 type != LOK_CALLBACK_REFERENCE_MARKS)
1404 SAL_INFO(
"lok",
"Skipping while painting [" << type <<
"]: [" << payload <<
"].");
1414 if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1415 payload.find(
", 0, 0, ") != std::string::npos &&
1416 payload.find(
"\"hyperlink\":\"\"") == std::string::npos &&
1417 payload.find(
"\"hyperlink\": {}") == std::string::npos)
1423 SAL_INFO(
"lok",
"Skipping invalid event [" << type <<
"]: [" << payload <<
"].");
1432 case LOK_CALLBACK_TEXT_SELECTION_START:
1433 case LOK_CALLBACK_TEXT_SELECTION_END:
1434 case LOK_CALLBACK_TEXT_SELECTION:
1435 case LOK_CALLBACK_GRAPHIC_SELECTION:
1436 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1437 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1438 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1439 case LOK_CALLBACK_STATE_CHANGED:
1440 case LOK_CALLBACK_MOUSE_POINTER:
1441 case LOK_CALLBACK_CELL_CURSOR:
1442 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1443 case LOK_CALLBACK_CELL_FORMULA:
1444 case LOK_CALLBACK_CELL_ADDRESS:
1445 case LOK_CALLBACK_CURSOR_VISIBLE:
1446 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1447 case LOK_CALLBACK_SET_PART:
1448 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1449 case LOK_CALLBACK_INVALIDATE_HEADER:
1450 case LOK_CALLBACK_WINDOW:
1451 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1452 case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
1455 [type] (
const queue_type::value_type& elem) {
return (elem.Type == type); });
1459 SAL_INFO(
"lok",
"Skipping queue duplicate [" << type << +
"]: [" << payload <<
"].");
1466 if (type == LOK_CALLBACK_TEXT_SELECTION && payload.empty())
1468 const auto& posStart = std::find_if(
m_queue.rbegin(),
m_queue.rend(),
1469 [] (
const queue_type::value_type& elem) {
return (elem.Type == LOK_CALLBACK_TEXT_SELECTION_START); });
1470 if (posStart !=
m_queue.rend())
1471 posStart->PayloadString.clear();
1473 const auto& posEnd = std::find_if(
m_queue.rbegin(),
m_queue.rend(),
1474 [] (
const queue_type::value_type& elem) {
return (elem.Type == LOK_CALLBACK_TEXT_SELECTION_END); });
1476 posEnd->PayloadString.clear();
1480 if (payload.empty())
1484 case LOK_CALLBACK_TEXT_SELECTION_START:
1485 case LOK_CALLBACK_TEXT_SELECTION_END:
1486 case LOK_CALLBACK_TEXT_SELECTION:
1487 case LOK_CALLBACK_GRAPHIC_SELECTION:
1488 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1489 case LOK_CALLBACK_INVALIDATE_TILES:
1491 [type](
const queue_type::value_type& elem) {
return (elem.Type == type); }))
1492 SAL_INFO(
"lok",
"Removed dups of [" << type <<
"]: [" << payload <<
"].");
1502 case LOK_CALLBACK_TEXT_SELECTION_START:
1503 case LOK_CALLBACK_TEXT_SELECTION_END:
1504 case LOK_CALLBACK_TEXT_SELECTION:
1505 case LOK_CALLBACK_MOUSE_POINTER:
1506 case LOK_CALLBACK_CELL_CURSOR:
1507 case LOK_CALLBACK_CELL_FORMULA:
1508 case LOK_CALLBACK_CELL_ADDRESS:
1509 case LOK_CALLBACK_CURSOR_VISIBLE:
1510 case LOK_CALLBACK_SET_PART:
1511 case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
1512 case LOK_CALLBACK_RULER_UPDATE:
1515 [type](
const queue_type::value_type& elem) {
return (elem.Type == type); }))
1516 SAL_INFO(
"lok",
"Removed dups of [" << type <<
"]: [" << payload <<
"].");
1523 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1524 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1525 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1526 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1527 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1528 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1529 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1530 case LOK_CALLBACK_FORM_FIELD_BUTTON:
1534 const bool hyperLinkException = type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1535 payload.find(
"\"hyperlink\":\"\"") == std::string::npos &&
1536 payload.find(
"\"hyperlink\": {}") == std::string::npos;
1537 const int nViewId = lcl_getViewId(payload);
1539 [type, nViewId, hyperLinkException] (
const queue_type::value_type& elem) {
1540 return (elem.Type == type && nViewId == lcl_getViewId(elem) && !hyperLinkException);
1546 case LOK_CALLBACK_INVALIDATE_TILES:
1553 case LOK_CALLBACK_STATE_CHANGED:
1556 const auto pos = payload.find(
'=');
1557 if (
pos != std::string::npos)
1559 const std::string
name = payload.substr(0,
pos + 1);
1562 if (name !=
".uno:ModifiedStatus=")
1565 [type, &name] (
const queue_type::value_type& elem) {
1566 return (elem.Type == type) && (elem.PayloadString.compare(0, name.size(), name) == 0);
1574 case LOK_CALLBACK_WINDOW:
1579 case LOK_CALLBACK_GRAPHIC_SELECTION:
1583 removeAll([type, payload] (
const queue_type::value_type& elem)
1584 {
return (elem.Type == type && elem.PayloadString[0] !=
'I'); });
1591 assert(aCallbackData.
validate() &&
"Cached callback payload object and string mismatch!");
1592 m_queue.emplace_back(aCallbackData);
1594 " [" << type <<
"]: [" << payload <<
"] to have " <<
m_queue.size() <<
" entries.");
1600 std::ostringstream oss;
1604 oss <<
m_queue.size() <<
" items\n";
1606 oss << i++ <<
": [" << c.Type <<
"] [" << c.PayloadString <<
"].\n";
1607 SAL_INFO(
"lok",
"Current Queue: " << oss.str());
1610 m_queue.begin(), m_queue.end(),
1625 const int type = aCallbackData.
Type;
1630 SAL_INFO(
"lok",
"Skipping invalid event [" << type <<
"]: [" << payload <<
"].");
1637 = std::find_if(
m_queue.rbegin(),
m_queue.rend(), [](
const queue_type::value_type& elem) {
1638 return (elem.Type == LOK_CALLBACK_INVALIDATE_TILES);
1645 SAL_INFO(
"lok",
"Skipping queue [" << type <<
"]: [" << payload
1646 <<
"] since all tiles need to be invalidated.");
1655 SAL_INFO(
"lok",
"Skipping queue [" << type <<
"]: [" << payload
1656 <<
"] since overlaps existing all-parts.");
1664 SAL_INFO(
"lok",
"Have Empty [" << type <<
"]: [" << payload
1665 <<
"] so removing all with part " << rcNew.
m_nPart <<
".");
1666 removeAll([&rcNew](
const queue_type::value_type& elem) {
1667 if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
1670 const RectangleAndPart rcOld = RectangleAndPart::Create(elem.PayloadString);
1671 return (rcNew.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart);
1680 const auto rcOrig = rcNew;
1682 SAL_INFO(
"lok",
"Have [" << type <<
"]: [" << payload <<
"] so merging overlapping.");
1683 removeAll([&rcNew](
const queue_type::value_type& elem) {
1684 if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
1686 const RectangleAndPart& rcOld = elem.getRectangleAndPart();
1687 if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && rcOld.m_nPart != rcNew.m_nPart)
1689 SAL_INFO(
"lok",
"Nothing to merge between new: "
1690 << rcNew.toString() <<
", and old: " << rcOld.toString());
1697 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" has " << rcOld.toString()
1699 if (rcNew.m_aRectangle.IsInside(rcOld.m_aRectangle))
1701 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
1702 << rcOld.toString() <<
".");
1706 else if (rcOld.m_nPart == -1)
1709 SAL_INFO(
"lok",
"Old " << rcOld.toString() <<
" has " << rcNew.toString()
1711 if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
1713 SAL_INFO(
"lok",
"New " << rcNew.toString() <<
" engulfs old "
1714 << rcOld.toString() <<
".");
1722 const bool bOverlap = !rcOverlap.
IsEmpty();
1723 SAL_INFO(
"lok",
"Merging " << rcNew.
toString() <<
" & " << rcOld.toString()
1725 <<
" Overlap: " << bOverlap);
1739 if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
1741 SAL_INFO(
"lok",
"Replacing: " << rcOrig.toString() <<
" by " << rcNew.toString());
1742 if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth()
1743 || rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
1745 SAL_WARN(
"lok",
"Error: merged rect smaller.");
1750 aCallbackData.setRectangleAndPart(rcNew);
1758 const int type = aCallbackData.
Type;
1760 boost::property_tree::ptree& aTree = aCallbackData.
setJson(payload);
1761 const unsigned nLOKWindowId = aTree.get<
unsigned>(
"id", 0);
1762 const std::string aAction = aTree.get<std::string>(
"action",
"");
1763 if (aAction ==
"invalidate")
1765 std::string aRectStr = aTree.get<std::string>(
"rectangle",
"");
1768 if (aRectStr.empty())
1770 removeAll([&nLOKWindowId](
const queue_type::value_type& elem) {
1771 if (elem.Type == LOK_CALLBACK_WINDOW)
1773 const boost::property_tree::ptree& aOldTree = elem.getJson();
1774 if (nLOKWindowId == aOldTree.get<unsigned>(
"id", 0)
1775 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
1787 const auto invAllExist = std::any_of(
m_queue.rbegin(),
m_queue.rend(),
1788 [&nLOKWindowId] (
const queue_type::value_type& elem)
1790 if (elem.Type != LOK_CALLBACK_WINDOW)
1793 const boost::property_tree::ptree& aOldTree = elem.getJson();
1794 return nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0)
1795 && aOldTree.get<std::string>(
"action",
"") ==
"invalidate"
1796 && aOldTree.get<std::string>(
"rectangle",
"").empty();
1802 SAL_INFO(
"lok.dialog",
"Skipping queue ["
1803 << type <<
"]: [" << payload
1804 <<
"] since whole window needs to be invalidated.");
1808 std::istringstream aRectStream(aRectStr);
1811 aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
1813 bool currentIsRedundant =
false;
1815 ¤tIsRedundant](
const queue_type::value_type& elem) {
1816 if (elem.Type != LOK_CALLBACK_WINDOW)
1819 const boost::property_tree::ptree& aOldTree = elem.getJson();
1820 if (aOldTree.get<std::string>(
"action",
"") ==
"invalidate")
1823 std::istringstream aOldRectStream(aOldTree.get<std::string>(
"rectangle",
""));
1824 tools::Long nOldLeft, nOldTop, nOldWidth, nOldHeight;
1826 aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
1827 >> nOldComma >> nOldHeight;
1829 nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
1831 if (nLOKWindowId == aOldTree.get<
unsigned>(
"id", 0))
1833 if (aNewRect == aOldRect)
1836 <<
"]. Skipping new.");
1838 currentIsRedundant =
true;
1842 else if (aNewRect.
IsInside(aOldRect))
1845 "New rect [" << aNewRect.
toString() <<
"] engulfs old ["
1846 << aOldRect.
toString() <<
"]. Replacing old.");
1850 else if (aOldRect.
IsInside(aNewRect))
1853 "Old rect [" << aOldRect.
toString() <<
"] engulfs new ["
1854 << aNewRect.
toString() <<
"]. Skipping new.");
1856 currentIsRedundant =
true;
1863 aNewRect.
Union(aOldRect);
1864 SAL_INFO(
"lok.dialog",
"Merging rects ["
1865 << aPreMergeRect.
toString() <<
"] & ["
1868 <<
"]. Replacing old.");
1879 if (currentIsRedundant)
1882 aTree.put(
"rectangle", aNewRect.
toString().getStr());
1884 assert(aCallbackData.
validate() &&
"Validation after setJson failed!");
1887 else if (aAction ==
"created")
1890 removeAll([&nLOKWindowId](
const queue_type::value_type& elem) {
1891 if (elem.Type == LOK_CALLBACK_WINDOW)
1893 const boost::property_tree::ptree& aOldTree = elem.getJson();
1894 if (nLOKWindowId == aOldTree.get<unsigned>(
"id", 0))
1903 gImpl->
maLastExceptionMsg =
"Document doesn't support dialog rendering, or window not found.";
1908 auto xClip = forceSetClipboardForCurrentView(m_pDocument);
1910 uno::Reference<datatransfer::clipboard::XClipboard> xClipboard(xClip);
1911 pWindow->SetClipboard(xClipboard);
1914 else if (aAction ==
"size_changed")
1918 removeAll([&nLOKWindowId](
const queue_type::value_type& elem) {
1919 if (elem.Type == LOK_CALLBACK_WINDOW)
1921 const boost::property_tree::ptree& aOldTree = elem.getJson();
1922 if (nLOKWindowId == aOldTree.get<unsigned>(
"id", 0))
1924 const std::string aOldAction = aOldTree.get<std::string>(
"action",
"");
1925 if (aOldAction ==
"invalidate")
1937 void CallbackFlushHandler::Invoke()
1947 for (
const auto& rCallbackData :
m_queue)
1949 const int type = rCallbackData.
Type;
1951 const int viewId = lcl_isViewCallbackType(type) ? lcl_getViewId(rCallbackData) : -1;
1955 const auto stateIt =
m_states.find(type);
1959 if (stateIt->second == payload)
1961 SAL_INFO(
"lok",
"Skipping duplicate [" << type <<
"]: [" << payload <<
"].");
1965 stateIt->second = payload;
1973 auto& states = statesIt->second;
1974 const auto stateIt = states.find(type);
1975 if (stateIt != states.end())
1978 if (stateIt->second == payload)
1980 SAL_INFO(
"lok",
"Skipping view duplicate [" << type <<
',' << viewId <<
"]: [" << payload <<
"].");
1984 SAL_INFO(
"lok",
"Replacing an element in view states [" << type <<
',' << viewId <<
"]: [" << payload <<
"].");
1985 stateIt->second = payload;
1989 SAL_INFO(
"lok",
"Inserted a new element in view states: [" << type <<
',' << viewId <<
"]: [" << payload <<
"]");
1990 states.emplace(type, payload);
2004 auto newEnd = std::remove_if(
m_queue.begin(),
m_queue.end(), rTestFunc);
2017 if (!result.second && result.first !=
m_viewStates.end())
2019 result.first->second.clear();
2041 static void lo_destroy (LibreOfficeKit* pThis);
2042 static int lo_initialize (LibreOfficeKit* pThis,
const char* pInstallPath,
const char* pUserProfilePath);
2043 static LibreOfficeKitDocument*
lo_documentLoad (LibreOfficeKit* pThis,
const char* pURL);
2044 static char *
lo_getError (LibreOfficeKit* pThis);
2048 const char* pOptions);
2050 LibreOfficeKitCallback pCallback,
2056 const char* pPassword);
2058 static int lo_runMacro (LibreOfficeKit* pThis,
const char* pURL);
2062 const unsigned char* pCertificateBinary,
2063 const int nCertificateBinarySize,
2064 const unsigned char* pPrivateKeyBinary,
2065 const int nPrivateKeyBinarySize);
2067 static void lo_runLoop(LibreOfficeKit* pThis,
2068 LibreOfficeKitPollCallback pPollCallback,
2069 LibreOfficeKitWakeCallback pWakeCallback,
2073 unsigned long long int nLOKWindowId,
2074 const char* pArguments);
2079 , mpCallback(nullptr)
2080 , mpCallbackData(nullptr)
2081 , mOptionalFeatures(0)
2117 void* rCGContext,
const Size nCanvasSize,
2118 const int nTilePosX,
const int nTilePosY,
2119 const int nTileWidth,
const int nTileHeight)
2122 aData.rCGContext =
reinterpret_cast<CGContextRef
>(rCGContext);
2125 pDevice->SetBackground(
Wallpaper(COL_TRANSPARENT));
2126 pDevice->SetOutputSizePixel(nCanvasSize);
2128 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2131 void paintTileIOS(LibreOfficeKitDocument* pThis,
2132 unsigned char* pBuffer,
2133 const int nCanvasWidth,
const int nCanvasHeight,
const double fDPIScale,
2134 const int nTilePosX,
const int nTilePosY,
2135 const int nTileWidth,
const int nTileHeight)
2137 CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
2138 nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
2139 kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little);
2141 CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
2142 CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
2144 doc_paintTileToCGContext(pThis, (
void*) pCGContext, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2146 CGContextRelease(pCGContext);
2150 void setLanguageAndLocale(OUString
const & aLangISO)
2160 if (sFormat == u
"pdf")
2163 rFilterDataMap[
"ExportBookmarks"] <<=
true;
2170 static uno::Reference<css::uno::XComponentContext>
xContext;
2171 static uno::Reference<css::lang::XMultiServiceFactory>
xSFactory;
2172 static uno::Reference<css::lang::XMultiComponentFactory>
xFactory;
2185 static int nDocumentIdCounter = 0;
2194 SAL_INFO(
"lok",
"URL for load is empty");
2203 SAL_INFO(
"lok",
"ComponentContext is not available");
2209 if (!xComponentLoader.is())
2212 SAL_INFO(
"lok",
"ComponentLoader is not available");
2224 if (!aLanguage.isEmpty() && isValidLangTag)
2231 SAL_INFO(
"lok",
"Set document language to " << aLanguage);
2234 setLanguageAndLocale(aLanguage);
2239 const OUString aDeviceFormFactor =
extractParameter(aOptions,
u"DeviceFormFactor");
2242 uno::Sequence<css::beans::PropertyValue> aFilterOptions(3);
2243 aFilterOptions[0] = css::beans::PropertyValue(
"FilterOptions",
2245 uno::makeAny(aOptions),
2246 beans::PropertyState_DIRECT_VALUE);
2250 auto const pair(pLib->
mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction)));
2254 pLib->mInteractionMap.erase(aURL.toUtf8());
2257 uno::Reference<task::XInteractionHandler2>
const xInteraction(pInteraction);
2258 aFilterOptions[1].Name =
"InteractionHandler";
2259 aFilterOptions[1].Value <<= xInteraction;
2261 sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG;
2262 aFilterOptions[2].Name =
"MacroExecutionMode";
2263 aFilterOptions[2].Value <<= nMacroExecMode;
2271 const int nThisDocumentId = nDocumentIdCounter++;
2273 uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL(
2277 assert(!xComponent.is() || pair.second);
2279 if (!xComponent.is())
2296 catch (
const uno::Exception& exception)
2314 OUString sURL( pURL, strlen(pURL), RTL_TEXTENCODING_UTF8 );
2318 SAL_INFO(
"lok",
"Macro URL is empty");
2322 if (!sURL.startsWith(
"macro://"))
2325 SAL_INFO(
"lok",
"Macro URL is invalid");
2334 SAL_INFO(
"lok",
"ComponentContext is not available");
2339 aURL.Complete = sURL;
2344 xParser->parseStrict( aURL );
2348 if (!xComponentLoader.is())
2351 SAL_INFO(
"lok",
"ComponentLoader is not available");
2355 xFactory = xContext->getServiceManager();
2359 uno::Reference<frame::XDispatchProvider> xDP;
2360 xSFactory.set(xFactory, uno::UNO_QUERY_THROW);
2361 xDP.set( xSFactory->createInstance(
"com.sun.star.comp.sfx2.SfxMacroLoader"), uno::UNO_QUERY );
2362 uno::Reference<frame::XDispatch> xD = xDP->queryDispatch( aURL, OUString(), 0);
2367 SAL_INFO(
"lok",
"Macro loader is not available");
2371 uno::Reference < frame::XSynchronousDispatch > xSyncDisp( xD, uno::UNO_QUERY_THROW );
2372 uno::Sequence<css::beans::PropertyValue> aEmpty;
2373 css::beans::PropertyValue aErr;
2374 uno::Any aRet = xSyncDisp->dispatchWithReturnValue( aURL, aEmpty );
2377 if (aErr.Name ==
"ErrorCode")
2379 sal_uInt32 nErrCode = 0;
2380 aErr.
Value >>= nErrCode;
2382 pLib->
maLastExceptionMsg =
"An error occurred running macro (error code: " + OUString::number( nErrCode ) +
")";
2383 SAL_INFO(
"lok",
"Macro execution terminated with error code " << nErrCode);
2396 const unsigned char* pCertificateBinary,
2397 const int nCertificateBinarySize,
2398 const unsigned char* pPrivateKeyBinary,
2399 const int nPrivateKeyBinarySize)
2410 uno::Sequence<sal_Int8> aCertificateSequence;
2412 std::string aCertificateString(reinterpret_cast<const char*>(pCertificateBinary), nCertificateBinarySize);
2413 std::string aCertificateBase64String = extractCertificate(aCertificateString);
2414 if (!aCertificateBase64String.empty())
2416 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
2421 aCertificateSequence.realloc(nCertificateBinarySize);
2422 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.begin());
2425 uno::Sequence<sal_Int8> aPrivateKeySequence;
2426 std::string aPrivateKeyString(reinterpret_cast<const char*>(pPrivateKeyBinary), nPrivateKeyBinarySize);
2427 std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
2428 if (!aPrivateKeyBase64String.empty())
2430 OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String.c_str());
2435 aPrivateKeySequence.realloc(nPrivateKeyBinarySize);
2436 std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeyBinarySize, aPrivateKeySequence.begin());
2440 uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString());
2441 if (!xSecurityContext.is())
2444 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = xSecurityContext->getSecurityEnvironment();
2445 uno::Reference<xml::crypto::XCertificateCreator> xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
2447 if (!xCertificateCreator.is())
2450 uno::Reference<security::XCertificate> xCertificate = xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, aPrivateKeySequence);
2452 if (!xCertificate.is())
2463 LibreOfficeKitCallback pCallback,
2478 static int doc_saveAs(LibreOfficeKitDocument* pThis,
const char* sUrl,
const char* pFormat,
const char* pFilterOptions)
2490 uno::Reference<frame::XStorable> xStorable(pDocument->
mxComponent, uno::UNO_QUERY_THROW);
2495 SAL_INFO(
"lok",
"URL for save is empty");
2501 const ExtensionMap* pMap;
2505 case LOK_DOCTYPE_SPREADSHEET:
2508 case LOK_DOCTYPE_PRESENTATION:
2511 case LOK_DOCTYPE_DRAWING:
2514 case LOK_DOCTYPE_TEXT:
2517 case LOK_DOCTYPE_OTHER:
2519 SAL_INFO(
"lok",
"Can't save document - unsupported document type.");
2523 if (pFormat ==
nullptr)
2526 sal_Int32
idx = aURL.lastIndexOf(
".");
2529 sFormat = aURL.copy( idx + 1 );
2538 OUString aFilterName;
2539 for (sal_Int32
i = 0; pMap[
i].extn; ++
i)
2541 if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[
i].extn))
2543 aFilterName =
getUString(pMap[i].filterName);
2547 if (aFilterName.isEmpty())
2553 OUString aFilterOptions =
getUString(pFilterOptions);
2557 OUString watermarkText, sFullSheetPreview;
2559 if ((aIndex = aFilterOptions.indexOf(
",Watermark=")) >= 0)
2561 int bIndex = aFilterOptions.indexOf(
"WATERMARKEND");
2562 watermarkText = aFilterOptions.subView(aIndex+11, bIndex-(aIndex+11));
2563 aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+12);
2566 if ((aIndex = aFilterOptions.indexOf(
",FullSheetPreview=")) >= 0)
2568 int bIndex = aFilterOptions.indexOf(
"FULLSHEETPREVEND");
2569 sFullSheetPreview = aFilterOptions.subView(aIndex+18, bIndex-(aIndex+18));
2570 aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+16);
2573 bool bFullSheetPreview = sFullSheetPreview ==
"true";
2581 std::vector<OUString> aFilteredOptionVec;
2582 bool bTakeOwnership =
false;
2584 for (
const auto& rOption : aOptionSeq)
2586 if (rOption ==
"TakeOwnership")
2587 bTakeOwnership =
true;
2588 else if (rOption ==
"NoFileSync")
2589 aSaveMediaDescriptor[
"NoFileSync"] <<=
true;
2591 aFilteredOptionVec.push_back(rOption);
2594 aSaveMediaDescriptor[
"Overwrite"] <<=
true;
2595 aSaveMediaDescriptor[
"FilterName"] <<= aFilterName;
2597 auto aFilteredOptionSeq = comphelper::containerToSequence<OUString>(aFilteredOptionVec);
2599 aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS()] <<= aFilterOptions;
2603 setFormatSpecificFilterData(sFormat, aFilterDataMap);
2605 if (!watermarkText.isEmpty())
2606 aFilterDataMap[
"TiledWatermark"] <<= watermarkText;
2608 if (bFullSheetPreview)
2609 aFilterDataMap[
"SinglePageSheets"] <<=
true;
2611 if (!aFilterDataMap.
empty())
2622 uno::Reference<task::XInteractionHandler2>
const xInteraction(pInteraction);
2624 aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteraction;
2629 xStorable->storeAsURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
2631 xStorable->storeToURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
2635 catch (
const uno::Exception& exception)
2653 OUString sUnoCommands[] =
2655 OUString(
".uno:AlignLeft"),
2656 OUString(
".uno:AlignHorizontalCenter"),
2657 OUString(
".uno:AlignRight"),
2658 OUString(
".uno:BackColor"),
2659 OUString(
".uno:BackgroundColor"),
2660 OUString(
".uno:TableCellBackgroundColor"),
2661 OUString(
".uno:Bold"),
2662 OUString(
".uno:CenterPara"),
2663 OUString(
".uno:CharBackColor"),
2664 OUString(
".uno:CharBackgroundExt"),
2665 OUString(
".uno:CharFontName"),
2666 OUString(
".uno:Color"),
2667 OUString(
".uno:ControlCodes"),
2668 OUString(
".uno:DecrementIndent"),
2669 OUString(
".uno:DefaultBullet"),
2670 OUString(
".uno:DefaultNumbering"),
2671 OUString(
".uno:FontColor"),
2672 OUString(
".uno:FontHeight"),
2673 OUString(
".uno:IncrementIndent"),
2674 OUString(
".uno:Italic"),
2675 OUString(
".uno:JustifyPara"),
2676 OUString(
".uno:OutlineFont"),
2677 OUString(
".uno:LeftPara"),
2678 OUString(
".uno:LanguageStatus"),
2679 OUString(
".uno:RightPara"),
2680 OUString(
".uno:Shadowed"),
2681 OUString(
".uno:SubScript"),
2682 OUString(
".uno:SuperScript"),
2683 OUString(
".uno:Strikeout"),
2684 OUString(
".uno:StyleApply"),
2685 OUString(
".uno:Underline"),
2686 OUString(
".uno:ModifiedStatus"),
2687 OUString(
".uno:Undo"),
2688 OUString(
".uno:Redo"),
2689 OUString(
".uno:InsertPage"),
2690 OUString(
".uno:DeletePage"),
2691 OUString(
".uno:DuplicatePage"),
2692 OUString(
".uno:Cut"),
2693 OUString(
".uno:Copy"),
2694 OUString(
".uno:Paste"),
2695 OUString(
".uno:SelectAll"),
2696 OUString(
".uno:InsertAnnotation"),
2697 OUString(
".uno:DeleteAnnotation"),
2698 OUString(
".uno:ReplyComment"),
2699 OUString(
".uno:ResolveComment"),
2700 OUString(
".uno:ResolveCommentThread"),
2701 OUString(
".uno:InsertRowsBefore"),
2702 OUString(
".uno:InsertRowsAfter"),
2703 OUString(
".uno:InsertColumnsBefore"),
2704 OUString(
".uno:InsertColumnsAfter"),
2705 OUString(
".uno:MergeCells"),
2706 OUString(
".uno:DeleteRows"),
2707 OUString(
".uno:DeleteColumns"),
2708 OUString(
".uno:DeleteTable"),
2709 OUString(
".uno:SelectTable"),
2710 OUString(
".uno:EntireRow"),
2711 OUString(
".uno:EntireColumn"),
2712 OUString(
".uno:EntireCell"),
2713 OUString(
".uno:AssignLayout"),
2714 OUString(
".uno:StatusDocPos"),
2715 OUString(
".uno:RowColSelCount"),
2716 OUString(
".uno:StatusPageStyle"),
2717 OUString(
".uno:InsertMode"),
2718 OUString(
".uno:SpellOnline"),
2719 OUString(
".uno:StatusSelectionMode"),
2720 OUString(
".uno:StateTableCell"),
2721 OUString(
".uno:StatusBarFunc"),
2722 OUString(
".uno:StatePageNumber"),
2723 OUString(
".uno:StateWordCount"),
2724 OUString(
".uno:SelectionMode"),
2725 OUString(
".uno:PageStatus"),
2726 OUString(
".uno:LayoutStatus"),
2727 OUString(
".uno:Context"),
2728 OUString(
".uno:WrapText"),
2729 OUString(
".uno:ToggleMergeCells"),
2730 OUString(
".uno:NumberFormatCurrency"),
2731 OUString(
".uno:NumberFormatPercent"),
2732 OUString(
".uno:NumberFormatDecimal"),
2733 OUString(
".uno:NumberFormatDate"),
2734 OUString(
".uno:FrameLineColor"),
2735 OUString(
".uno:SortAscending"),
2736 OUString(
".uno:SortDescending"),
2737 OUString(
".uno:TrackChanges"),
2738 OUString(
".uno:ShowTrackedChanges"),
2739 OUString(
".uno:NextTrackedChange"),
2740 OUString(
".uno:PreviousTrackedChange"),
2741 OUString(
".uno:AcceptAllTrackedChanges"),
2742 OUString(
".uno:RejectAllTrackedChanges"),
2743 OUString(
".uno:TableDialog"),
2744 OUString(
".uno:FormatCellDialog"),
2745 OUString(
".uno:FontDialog"),
2746 OUString(
".uno:ParagraphDialog"),
2747 OUString(
".uno:OutlineBullet"),
2748 OUString(
".uno:InsertIndexesEntry"),
2749 OUString(
".uno:DocumentRepair"),
2750 OUString(
".uno:TransformDialog"),
2751 OUString(
".uno:InsertPageHeader"),
2752 OUString(
".uno:InsertPageFooter"),
2753 OUString(
".uno:OnlineAutoFormat"),
2754 OUString(
".uno:InsertObjectChart"),
2755 OUString(
".uno:InsertSection"),
2756 OUString(
".uno:InsertAnnotation"),
2757 OUString(
".uno:InsertPagebreak"),
2758 OUString(
".uno:InsertColumnBreak"),
2759 OUString(
".uno:HyperlinkDialog"),
2760 OUString(
".uno:InsertSymbol"),
2761 OUString(
".uno:EditRegion"),
2762 OUString(
".uno:ThesaurusDialog"),
2763 OUString(
".uno:FormatArea"),
2764 OUString(
".uno:FormatLine"),
2765 OUString(
".uno:FormatColumns"),
2766 OUString(
".uno:Watermark"),
2767 OUString(
".uno:ResetAttributes"),
2768 OUString(
".uno:Orientation"),
2769 OUString(
".uno:ObjectAlignLeft"),
2770 OUString(
".uno:ObjectAlignRight"),
2771 OUString(
".uno:AlignCenter"),
2772 OUString(
".uno:TransformPosX"),
2773 OUString(
".uno:TransformPosY"),
2774 OUString(
".uno:TransformWidth"),
2775 OUString(
".uno:TransformHeight"),
2776 OUString(
".uno:ObjectBackOne"),
2777 OUString(
".uno:SendToBack"),
2778 OUString(
".uno:ObjectForwardOne"),
2779 OUString(
".uno:BringToFront"),
2780 OUString(
".uno:WrapRight"),
2781 OUString(
".uno:WrapThrough"),
2782 OUString(
".uno:WrapLeft"),
2783 OUString(
".uno:WrapIdeal"),
2784 OUString(
".uno:WrapOn"),
2785 OUString(
".uno:WrapOff"),
2786 OUString(
".uno:UpdateCurIndex"),
2787 OUString(
".uno:InsertCaptionDialog"),
2788 OUString(
".uno:FormatGroup"),
2789 OUString(
".uno:SplitTable"),
2790 OUString(
".uno:MergeCells"),
2791 OUString(
".uno:DeleteNote"),
2792 OUString(
".uno:AcceptChanges"),
2793 OUString(
".uno:FormatPaintbrush"),
2794 OUString(
".uno:SetDefault"),
2795 OUString(
".uno:ParaLeftToRight"),
2796 OUString(
".uno:ParaRightToLeft"),
2797 OUString(
".uno:ParaspaceIncrease"),
2798 OUString(
".uno:ParaspaceDecrease"),
2799 OUString(
".uno:AcceptTrackedChange"),
2800 OUString(
".uno:RejectTrackedChange"),
2801 OUString(
".uno:ShowResolvedAnnotations"),
2802 OUString(
".uno:InsertBreak"),
2803 OUString(
".uno:InsertEndnote"),
2804 OUString(
".uno:InsertFootnote"),
2805 OUString(
".uno:InsertReferenceField"),
2806 OUString(
".uno:InsertBookmark"),
2807 OUString(
".uno:InsertAuthoritiesEntry"),
2808 OUString(
".uno:InsertMultiIndex"),
2809 OUString(
".uno:InsertField"),
2810 OUString(
".uno:InsertPageNumberField"),
2811 OUString(
".uno:InsertPageCountField"),
2812 OUString(
".uno:InsertDateField"),
2813 OUString(
".uno:InsertTitleField"),
2814 OUString(
".uno:InsertFieldCtrl"),
2815 OUString(
".uno:CharmapControl"),
2816 OUString(
".uno:EnterGroup"),
2817 OUString(
".uno:LeaveGroup"),
2818 OUString(
".uno:AlignUp"),
2819 OUString(
".uno:AlignMiddle"),
2820 OUString(
".uno:AlignDown"),
2821 OUString(
".uno:TraceChangeMode"),
2822 OUString(
".uno:Combine"),
2823 OUString(
".uno:Merge"),
2824 OUString(
".uno:Dismantle"),
2825 OUString(
".uno:Substract"),
2826 OUString(
".uno:DistributeSelection"),
2827 OUString(
".uno:Intersect"),
2828 OUString(
".uno:BorderInner"),
2829 OUString(
".uno:BorderOuter"),
2830 OUString(
".uno:FreezePanes"),
2831 OUString(
".uno:FreezePanesColumn"),
2832 OUString(
".uno:FreezePanesRow"),
2833 OUString(
".uno:Sidebar"),
2834 OUString(
".uno:SheetRightToLeft"),
2835 OUString(
".uno:RunMacro")
2838 util::URL aCommandURL;
2845 SAL_WARN(
"lok",
"iniUnoCommands: No Frame-Controller created.");
2853 SAL_WARN(
"lok",
"iniUnoCommands: Component context is not available");
2860 for (
const auto & sUnoCommand : sUnoCommands)
2862 aCommandURL.Complete = sUnoCommand;
2863 xParser->parseStrict(aCommandURL);
2886 uno::Reference<lang::XServiceInfo> xDocument(pDocument->
mxComponent, uno::UNO_QUERY_THROW);
2888 if (xDocument->supportsService(
"com.sun.star.sheet.SpreadsheetDocument"))
2890 return LOK_DOCTYPE_SPREADSHEET;
2892 else if (xDocument->supportsService(
"com.sun.star.presentation.PresentationDocument"))
2894 return LOK_DOCTYPE_PRESENTATION;
2896 else if (xDocument->supportsService(
"com.sun.star.drawing.DrawingDocument"))
2898 return LOK_DOCTYPE_DRAWING;
2900 else if (xDocument->supportsService(
"com.sun.star.text.TextDocument") || xDocument->supportsService(
"com.sun.star.text.WebDocument"))
2902 return LOK_DOCTYPE_TEXT;
2909 catch (
const uno::Exception& exception)
2913 return LOK_DOCTYPE_OTHER;
3080 int nCurrentPart = pDoc->
getPart();
3093 if ( nCurrentPart < pDoc->getParts() )
3095 pDoc->
setPart( nCurrentPart );
3104 unsigned char* pBuffer,
3105 const int nCanvasWidth,
const int nCanvasHeight,
3106 const int nTilePosX,
const int nTilePosY,
3107 const int nTileWidth,
const int nTileHeight)
3114 SAL_INFO(
"lok.tiledrendering",
"paintTile: painting [" << nTileWidth <<
"x" << nTileHeight <<
3115 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3116 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3125 #if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS)
3135 double fDPIScaleX = 1.0;
3136 paintTileIOS(pThis, pBuffer, nCanvasWidth, nCanvasHeight, fDPIScaleX, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3140 #if !defined(ANDROID) || HAVE_FEATURE_ANDROID_LOK
3147 pDevice->SetOutputSizePixelScaleOffsetAndBuffer(
3151 pDoc->
paintTile(*pDevice, nCanvasWidth, nCanvasHeight,
3152 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3154 static bool bDebug = getenv(
"LOK_DEBUG_TILES") !=
nullptr;
3159 aRect = pDevice->PixelToLogic(aRect);
3160 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
3162 pDevice->SetLineColor();
3163 pDevice->DrawRect(aRect);
3177 static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
3179 const int nCanvasWidth,
const int nCanvasHeight,
3180 const int nTilePosX,
const int nTilePosY,
3181 const int nTileWidth,
const int nTileHeight)
3186 SAL_INFO(
"lok.tiledrendering",
"paintTileToCGContext: painting [" << nTileWidth <<
"x" << nTileHeight <<
3187 "]@(" << nTilePosX <<
", " << nTilePosY <<
") to [" <<
3188 nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3197 Size aCanvasSize(nCanvasWidth, nCanvasHeight);
3198 paintTileToCGContext(pDoc, rCGContext, aCanvasSize, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3204 unsigned char* pBuffer,
3206 const int nCanvasWidth,
const int nCanvasHeight,
3207 const int nTilePosX,
const int nTilePosY,
3208 const int nTileWidth,
const int nTileHeight)
3215 SAL_INFO(
"lok.tiledrendering",
"paintPartTile: painting @ " << nPart <<
" ["
3216 << nTileWidth <<
"x" << nTileHeight <<
"]@("
3217 << nTilePosX <<
", " << nTilePosY <<
") to ["
3218 << nCanvasWidth <<
"x" << nCanvasHeight <<
"]px" );
3223 if (nOrigViewId < 0)
3234 std::vector<int> viewIds(viewCount);
3237 nOrigViewId = viewIds[0];
3242 if (nOrigViewId >= 0)
3246 handlerIt->second->disableCallbacks();
3254 int nViewId = nOrigViewId;
3264 if (pViewShell->
getPart() == nPart)
3275 if (nPart != nOrigPart)
3281 doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3283 if (!isText && nPart != nOrigPart)
3287 if (!isText && nViewId != nOrigViewId)
3292 catch (
const std::exception&)
3297 if (nOrigViewId >= 0)
3301 handlerIt->second->enableCallbacks();
3308 return LOK_TILEMODE_BGRA;
3324 *pWidth = aDocumentSize.
Width();
3325 *pHeight = aDocumentSize.
Height();
3334 const char* pArguments)
3351 LibreOfficeKitCallback pCallback,
3363 const size_t nId = nView;
3364 if (pCallback !=
nullptr)
3368 if (pair.first == nId)
3371 pair.second->addViewStates(nView);
3378 if (pair.first == nId)
3381 pair.second->removeViewStates(nView);
3387 if (pCallback !=
nullptr)
3391 if (pair.first == nId)
3456 static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
int nType,
int nCharCode,
int nKeyCode)
3474 catch (
const uno::Exception& exception)
3477 SAL_INFO(
"lok",
"Failed to postKeyEvent " << exception.Message);
3511 static void doc_removeTextContext(LibreOfficeKitDocument* pThis,
unsigned nLOKWindowId,
int nCharBefore,
int nCharAfter)
3515 if (nLOKWindowId == 0)
3532 gImpl->
maLastExceptionMsg =
"No window found for window id: " + OUString::number(nLOKWindowId);
3539 if (nCharBefore > 0)
3542 if (nLOKWindowId == 0)
3545 for (
int i = 0;
i < nCharBefore; ++
i)
3555 if (nLOKWindowId == 0)
3558 for (
int i = 0;
i < nCharAfter; ++
i)
3584 case LOK_KEYEVENT_KEYINPUT:
3587 case LOK_KEYEVENT_KEYUP:
3612 uno::Reference<frame::XStorable> xStorable(pDocument->
mxComponent, uno::UNO_QUERY_THROW);
3620 case LOK_DOCTYPE_PRESENTATION:
3621 aMediaDescriptor[
"FilterName"] <<= OUString(
"impress_svg_Export");
3623 case LOK_DOCTYPE_DRAWING:
3624 aMediaDescriptor[
"FilterName"] <<= OUString(
"draw_svg_Export");
3626 case LOK_DOCTYPE_TEXT:
3627 aMediaDescriptor[
"FilterName"] <<= OUString(
"writer_svg_Export");
3629 case LOK_DOCTYPE_SPREADSHEET:
3630 aMediaDescriptor[
"FilterName"] <<= OUString(
"calc_svg_Export");
3633 SAL_WARN(
"lok",
"Failed to render shape selection: Document type is not supported");
3635 aMediaDescriptor[
"SelectionOnly"] <<=
true;
3636 aMediaDescriptor[
"OutputStream"] <<= xOut;
3638 xStorable->storeToURL(
"private:stream", aMediaDescriptor.getAsConstPropertyValueList());
3643 *pOutput =
static_cast<char*
>(malloc(nOutputSize));
3646 std::memcpy(*pOutput, aOutStream.
GetData(), nOutputSize);
3651 catch (
const uno::Exception& exception)
3670 class DispatchResultListener :
public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
3673 std::shared_ptr<CallbackFlushHandler> mpCallback;
3676 DispatchResultListener(
const char* pCommand, std::shared_ptr<CallbackFlushHandler>
const & pCallback)
3677 : maCommand(pCommand)
3678 , mpCallback(pCallback)
3683 virtual void SAL_CALL dispatchFinished(
const css::frame::DispatchResultEvent& rEvent)
override
3685 boost::property_tree::ptree aTree;
3686 aTree.put(
"commandName", maCommand.getStr());
3688 if (rEvent.State != frame::DispatchResultState::DONTKNOW)
3690 bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS);
3691 aTree.put(
"success", bSuccess);
3696 std::stringstream aStream;
3697 boost::property_tree::write_json(aStream, aTree);
3698 OString aPayload = aStream.str().c_str();
3699 mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aPayload.getStr());
3702 virtual void SAL_CALL disposing(
const css::lang::EventObject&)
override {}
3715 if (!pWindow && nWindowId >= 1000000000 )
3716 pWindow = getSidebarWindow();
3718 if (aMap.find(
"id") == aMap.end())
3721 static constexpr OUStringLiteral sClickAction(
u"CLICK");
3722 static constexpr OUStringLiteral sSelectAction(
u"SELECT");
3723 static constexpr OUStringLiteral sClearAction(
u"CLEAR");
3724 static constexpr OUStringLiteral sTypeAction(
u"TYPE");
3725 static constexpr OUStringLiteral sUpAction(
u"UP");
3726 static constexpr OUStringLiteral sDownAction(
u"DOWN");
3727 static constexpr OUStringLiteral sValue(
u"VALUE");
3729 bool bIsWeldedDialog =
false;
3736 if (!bIsWeldedDialog)
3746 if (!bIsWeldedDialog)
3751 OUString sAction((aMap.find(
"cmd") != aMap.end())? aMap[
"cmd"]:
"");
3753 if (sAction ==
"selected")
3755 aMap[
"POS"] = aMap[
"data"];
3756 aMap[
"TEXT"] = aMap[
"data"];
3758 pUIWindow->execute(sSelectAction, aMap);
3760 else if (sAction ==
"plus")
3762 pUIWindow->execute(sUpAction, aMap);
3764 else if (sAction ==
"minus")
3766 pUIWindow->execute(sDownAction, aMap);
3768 else if (sAction ==
"set")
3770 aMap[
"TEXT"] = aMap[
"data"];
3772 pUIWindow->execute(sClearAction, aMap);
3773 pUIWindow->execute(sTypeAction, aMap);
3775 else if (sAction ==
"value")
3777 aMap[
"VALUE"] = aMap[
"data"];
3778 pUIWindow->execute(sValue, aMap);
3781 pUIWindow->execute(sClickAction, aMap);
3787 if (!bIsWeldedDialog)
3792 static void doc_sendDialogEvent(LibreOfficeKitDocument* ,
unsigned long long int nWindowId,
const char* pArguments)
3797 static void lo_sendDialogEvent(LibreOfficeKit* ,
unsigned long long int nWindowId,
const char* pArguments)
3802 static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand,
const char* pArguments,
bool bNotifyWhenFinished)
3810 OUString
aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
3817 beans::PropertyValue aSynchronMode;
3818 aSynchronMode.Name =
"SynchronMode";
3819 aSynchronMode.Value <<=
false;
3820 aPropertyValuesVector.push_back(aSynchronMode);
3827 if (gImpl && aCommand ==
".uno:ToggleOrientation")
3829 ExecuteOrientationChange();
3834 if (gImpl && aCommand ==
".uno:Save")
3837 OUString
aMimeType = lcl_getCurrentDocumentMimeType(pDocument);
3838 if (pDocSh->
IsModified() && aMimeType ==
"application/pdf")
3843 uno::Reference<frame::XStorable> xStorable(pDocument->
mxComponent, uno::UNO_QUERY_THROW);
3844 OUString
aURL = xStorable->getLocation();
3846 bool bResult =
doc_saveAs(pThis, aURLUtf8.getStr(),
"pdf",
nullptr);
3849 boost::property_tree::ptree aTree;
3850 aTree.put(
"commandName", pCommand);
3851 aTree.put(
"success", bResult);
3852 std::stringstream aStream;
3853 boost::property_tree::write_json(aStream, aTree);
3854 OString aPayload = aStream.str().c_str();
3862 uno::Reference<task::XInteractionHandler2>
const xInteraction(pInteraction);
3864 beans::PropertyValue aValue;
3865 aValue.Name =
"InteractionHandler";
3866 aValue.Value <<= xInteraction;
3867 aPropertyValuesVector.push_back(aValue);
3869 bool bDontSaveIfUnmodified =
false;
3870 aPropertyValuesVector.erase(std::remove_if(aPropertyValuesVector.begin(),
3871 aPropertyValuesVector.end(),
3872 [&bDontSaveIfUnmodified](
const beans::PropertyValue& aItem){
3873 if (aItem.Name ==
"DontSaveIfUnmodified")
3875 bDontSaveIfUnmodified = aItem.Value.get<
bool>();
3879 }), aPropertyValuesVector.end());
3882 if (bDontSaveIfUnmodified && !pDocSh->
IsModified())
3884 boost::property_tree::ptree aTree;
3885 aTree.put(
"commandName", pCommand);
3886 aTree.put(
"success",
false);
3889 const uno::Any aResultValue = uno::makeAny(OUString(
"unmodified"));
3892 std::stringstream aStream;
3893 boost::property_tree::write_json(aStream, aTree);
3894 OString aPayload = aStream.str().c_str();
3899 else if (gImpl && aCommand ==
".uno:TransformDialog")
3901 bool bNeedConversion =
false;
3907 bNeedConversion =
true;
3911 if (
OutputDevice* pOutputDevice = pView->GetFirstOutputDevice())
3913 bNeedConversion = (pOutputDevice->GetMapMode().GetMapUnit() == MapUnit::Map100thMM);
3917 if (bNeedConversion)
3920 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
3922 if (rPropValue.Name ==
"TransformPosX"
3923 || rPropValue.Name ==
"TransformPosY"
3924 || rPropValue.Name ==
"TransformWidth"
3925 || rPropValue.Name ==
"TransformHeight"
3926 || rPropValue.Name ==
"TransformRotationX"
3927 || rPropValue.Name ==
"TransformRotationY")
3929 rPropValue.Value >>= value;
3931 rPropValue.Value <<= value;
3936 if (aChartHelper.
GetWindow() && aPropertyValuesVector.size() > 0)
3938 if (aPropertyValuesVector[0].
Name !=
"Action")
3944 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
3946 if (rPropValue.Name ==
"TransformPosX" || rPropValue.Name ==
"TransformRotationX")
3948 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3949 rPropValue.Value <<=
value - nLeft;
3951 else if (rPropValue.Name ==
"TransformPosY" || rPropValue.Name ==
"TransformRotationY")
3953 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3954 rPropValue.Value <<=
value - nTop;
3958 util::URL aCommandURL;
3959 aCommandURL.Path =
"LOKTransform";
3960 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.
GetXDispatcher();
3965 else if (gImpl && aCommand ==
".uno:LOKSidebarWriterPage")
3967 setupSidebar(
u"WriterPageDeck");
3970 else if (gImpl && aCommand ==
".uno:SidebarShow")
3975 else if (gImpl && aCommand ==
".uno:SidebarHide")
3981 bool bResult =
false;
3984 if (aChartHelper.
GetWindow() && aCommand !=
".uno:Save" )
3986 util::URL aCommandURL;
3987 aCommandURL.Path = aCommand.copy(5);
3988 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.
GetXDispatcher();
4006 static void doc_postMouseEvent(LibreOfficeKitDocument* pThis,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
4021 pDoc->
postMouseEvent(nType, nX, nY, nCount, nButtons, nModifier);
4023 catch (
const uno::Exception& exception)
4026 SAL_INFO(
"lok",
"Failed to postMouseEvent " << exception.Message);
4030 static void doc_postWindowMouseEvent(LibreOfficeKitDocument* ,
unsigned nLOKWindowId,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier)
4044 const Point aPos(nX, nY);
4046 MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
4052 case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
4055 case LOK_MOUSEEVENT_MOUSEBUTTONUP:
4058 case LOK_MOUSEEVENT_MOUSEMOVE:
4081 OString aType(pType);
4084 if (aType ==
"panBegin")
4085 eEventType = GestureEventType::PanningBegin;
4086 else if (aType ==
"panEnd")
4087 eEventType = GestureEventType::PanningEnd;
4094 PanningOrientation::Vertical,
4135 Point aCursorPos(nX, nY);
4136 aCursorPos.Move(aOffset);
4139 MouseEvent aCursorEvent(aCursorPos, 1, MouseEventModifiers::SIMPLECLICK, 0, nModifier);
4145 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4146 const OString &aInMimeType, OString &aRet);
4149 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4150 const OString &aMimeType, OString &aRet)
4156 auto aSeq = Sequence<sal_Int8>(
reinterpret_cast<const sal_Int8*
>(aRet.getStr()),
4158 OUStringBuffer aBase64Data;
4162 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
4164 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
4165 "name=\"generator\" content=\""
4168 "</head><body><img src=\"data:" + aMimeType +
";base64,"
4169 + aBase64Data.makeStringAndClear().toUtf8() +
"\"/></body></html>";
4175 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4176 const OString &aMimeType, OString &aRet)
4182 aRet =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
4184 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
4185 "name=\"generator\" content=\""
4187 +
"\"/></head><body><pre>" + aRet +
"</pre></body></html>";
4193 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4194 const OString &aInMimeType, OString &aRet)
4199 bool bConvert =
false;
4201 if (aMimeType.getToken(0,
';', nIndex) ==
"text/plain")
4203 if (aMimeType.getToken(0,
';', nIndex) ==
"charset=utf-8")
4205 aMimeType =
"text/plain;charset=utf-16";
4210 datatransfer::DataFlavor aFlavor;
4211 aFlavor.MimeType = OUString::fromUtf8(aMimeType.getStr());
4212 if (aMimeType ==
"text/plain;charset=utf-16")
4217 if (!xTransferable->isDataFlavorSupported(aFlavor))
4220 if (aInMimeType ==
"text/html")
4237 aAny = xTransferable->getTransferData(aFlavor);
4239 catch (
const css::datatransfer::UnsupportedFlavorException& e)
4241 SetLastExceptionMsg(
"Unsupported flavor " + aFlavor.MimeType +
" exception " + e.Message);
4244 catch (
const css::uno::Exception& e)
4257 aRet = OString(reinterpret_cast<const char *>(aString.getStr()), aString.getLength() *
sizeof(
sal_Unicode));
4261 uno::Sequence<sal_Int8> aSequence;
4263 aRet = OString(reinterpret_cast<char*>(aSequence.getArray()), aSequence.getLength());
4283 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->
getSelection();
4290 const char *pType = pMimeType;
4291 if (!pType || pType[0] ==
'\0')
4292 pType =
"text/plain;charset=utf-8";
4302 *pUsedMimeType = strdup(pMimeType);
4304 *pUsedMimeType =
nullptr;
4321 return LOK_SELTYPE_NONE;
4324 css::uno::Reference<css::datatransfer::XTransferable2> xTransferable(pDoc->
getSelection(), css::uno::UNO_QUERY);
4328 return LOK_SELTYPE_NONE;
4331 if (xTransferable->isComplex())
4332 return LOK_SELTYPE_COMPLEX;
4337 return LOK_SELTYPE_NONE;
4339 if (aRet.getLength() > 10000)
4340 return LOK_SELTYPE_COMPLEX;
4342 return aRet.getLength() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE;
4346 const char **pMimeTypes,
4348 char ***pOutMimeTypes,
4350 char ***pOutStreams)
4363 *pOutMimeTypes =
nullptr;
4364 *pOutSizes =
nullptr;
4365 *pOutStreams =
nullptr;
4376 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = xClip->getContents();
4377 SAL_INFO(
"lok",
"Got from clip: " << xClip.get() <<
" transferrable: " << xTransferable);
4384 std::vector<OString> aMimeTypes;
4387 const uno::Sequence< css::datatransfer::DataFlavor > flavors = xTransferable->getTransferDataFlavors();
4388 if (!flavors.getLength())
4393 for (
const auto &it : flavors)
4398 for (
size_t i = 0; pMimeTypes[
i]; ++
i)
4399 aMimeTypes.push_back(OString(pMimeTypes[
i]));
4402 *pOutCount = aMimeTypes.size();
4403 *pOutSizes =
static_cast<size_t *
>(malloc(*pOutCount *
sizeof(
size_t)));
4404 *pOutMimeTypes =
static_cast<char **
>(malloc(*pOutCount *
sizeof(
char *)));
4405 *pOutStreams =
static_cast<char **
>(malloc(*pOutCount *
sizeof(
char *)));
4406 for (
size_t i = 0;
i < aMimeTypes.size(); ++
i)
4408 if (aMimeTypes[
i] ==
"text/plain;charset=utf-16")
4409 (*pOutMimeTypes)[
i] = strdup(
"text/plain;charset=utf-8");
4411 (*pOutMimeTypes)[
i] = strdup(aMimeTypes[
i].getStr());
4415 if (!bSuccess || aRet.getLength() < 1)
4417 (*pOutSizes)[i] = 0;
4418 (*pOutStreams)[i] =
nullptr;
4422 (*pOutSizes)[i] = aRet.getLength();
4431 const size_t nInCount,
4432 const char **pInMimeTypes,
4433 const size_t *pInSizes,
4434 const char **pInStreams)
4439 (
void) pInMimeTypes;
4455 uno::Reference<datatransfer::XTransferable> xTransferable(
new LOKTransferable(nInCount, pInMimeTypes, pInSizes, pInStreams));
4457 auto xClip = forceSetClipboardForCurrentView(pThis);
4458 xClip->setContents(xTransferable, uno::Reference<datatransfer::clipboard::XClipboardOwner>());
4460 SAL_INFO(
"lok",
"Set clip: " << xClip.get() <<
" to: " << xTransferable);
4471 static bool doc_paste(LibreOfficeKitDocument* pThis,
const char* pMimeType,
const char* pData,
size_t nSize)
4477 const char *pInMimeTypes[1];
4478 const char *pInStreams[1];
4480 pInMimeTypes[0] = pMimeType;
4481 pInSizes[0] = nSize;
4482 pInStreams[0] = pData;
4489 {
"AnchorType", uno::makeAny(static_cast<sal_uInt16>(text::TextContentAnchorType_AS_CHARACTER))},
4490 {
"IgnoreComments", uno::makeAny(
true)},
4537 css::uno::Sequence< css::lang::Locale > aLocales;
4544 css::uno::Reference<css::linguistic2::XSpellChecker> xSpell = xLangSrv->getSpellChecker();
4546 aLocales = xSpell->getLocales();
4550 boost::property_tree::ptree aTree;
4551 aTree.put(
"commandName", pCommand);
4552 boost::property_tree::ptree aValues;
4553 boost::property_tree::ptree aChild;
4555 for ( css::lang::Locale
const & locale : std::as_const(aLocales) )
4559 if (sLanguage.startsWith(
"{") && sLanguage.endsWith(
"}"))
4562 sLanguage +=
";" + aLanguageTag.
getBcp47(
false);
4563 aChild.put(
"", sLanguage.toUtf8());
4564 aValues.push_back(std::make_pair(
"", aChild));
4566 aTree.add_child(
"commandValues", aValues);
4567 std::stringstream aStream;
4568 boost::property_tree::write_json(aStream, aTree);
4569 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
4571 strcpy(pJson, aStream.str().c_str());
4572 pJson[aStream.str().size()] =
'\0';
4580 pDocSh->
GetItem(SID_ATTR_CHAR_FONTLIST));
4583 boost::property_tree::ptree aTree;
4584 aTree.put(
"commandName", pCommand);
4585 boost::property_tree::ptree aValues;
4589 for (sal_uInt16
i = 0;
i < nFontCount; ++
i)
4591 boost::property_tree::ptree aChildren;
4593 const int* pAry = pList->
GetSizeAry(rFontMetric);
4594 sal_uInt16 nSizeCount = 0;
4595 while (pAry[nSizeCount])
4597 boost::property_tree::ptree aChild;
4598 aChild.put(
"", static_cast<float>(pAry[nSizeCount]) / 10);
4599 aChildren.push_back(std::make_pair(
"", aChild));
4602 aValues.add_child(rFontMetric.
GetFamilyName().toUtf8().getStr(), aChildren);
4605 aTree.add_child(
"commandValues", aValues);
4606 std::stringstream aStream;
4607 boost::property_tree::write_json(aStream, aTree);
4608 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
4610 strcpy(pJson, aStream.str().c_str());
4611 pJson[aStream.str().size()] =
'\0';
4617 OUString aFoundFont(::rtl::Uri::decode(OStringToOUString(aFontName, RTL_TEXTENCODING_UTF8), rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8));
4620 pDocSh->
GetItem(SID_ATTR_CHAR_FONTLIST));
4623 boost::property_tree::ptree aTree;
4624 aTree.put(
"commandName",
".uno:FontSubset");
4625 boost::property_tree::ptree aValues;
4627 if ( pList && !aFoundFont.isEmpty() )
4630 sal_uInt16 nItFont = 0;
4631 for (; nItFont < nFontCount; ++nItFont)
4639 if ( nItFont < nFontCount )
4645 aDevice->SetFont(aFont);
4646 aDevice->GetFontCharMap(xFontCharMap);
4651 boost::property_tree::ptree aChild;
4652 aChild.put(
"", static_cast<int>(ublock_getCode(subset.GetRangeMin())));
4653 aValues.push_back(std::make_pair(
"", aChild));
4658 aTree.add_child(
"commandValues", aValues);
4659 std::stringstream aStream;
4660 boost::property_tree::write_json(aStream, aTree);
4661 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
4663 strcpy(pJson, aStream.str().c_str());
4664 pJson[aStream.str().size()] =
'\0';
4668 static char*
getStyles(LibreOfficeKitDocument* pThis,
const char* pCommand)
4672 boost::property_tree::ptree aTree;
4673 aTree.put(
"commandName", pCommand);
4674 uno::Reference<css::style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(pDocument->
mxComponent, uno::UNO_QUERY);
4675 const uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
4676 const uno::Sequence<OUString> aStyleFamilies = xStyleFamilies->getElementNames();
4678 static const std::vector<OUString> aWriterStyles =
4692 std::set<OUString> aDefaultStyleNames;
4694 boost::property_tree::ptree aValues;
4695 for (OUString
const & sStyleFam : aStyleFamilies)
4697 boost::property_tree::ptree aChildren;
4698 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(sStyleFam), uno::UNO_QUERY);
4703 if (sStyleFam ==
"ParagraphStyles"
4706 for (
const OUString& rStyle: aWriterStyles)
4708 aDefaultStyleNames.insert( rStyle );
4710 boost::property_tree::ptree aChild;
4711 aChild.put(
"", rStyle.toUtf8());
4712 aChildren.push_back(std::make_pair(
"", aChild));
4716 const uno::Sequence<OUString> aStyles = xStyleFamily->getElementNames();
4717 for (
const OUString& rStyle: aStyles )
4721 if (aDefaultStyleNames.find(rStyle) == aDefaultStyleNames.end() ||
4724 boost::property_tree::ptree aChild;
4725 aChild.put(
"", rStyle.toUtf8());
4726 aChildren.push_back(std::make_pair(
"", aChild));
4729 aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren);
4734 boost::property_tree::ptree aChild;
4735 boost::property_tree::ptree aChildren;
4736 const OUString sPageStyles(
"PageStyles");
4737 uno::Reference<beans::XPropertySet> xProperty;
4738 uno::Reference<container::XNameContainer> xContainer;
4740 if (xStyleFamilies->hasByName(sPageStyles) && (xStyleFamilies->getByName(sPageStyles) >>= xContainer))
4742 const uno::Sequence<OUString> aSeqNames = xContainer->getElementNames();
4743 for (OUString
const &
sName : aSeqNames)
4746 xProperty.set(xContainer->getByName(
sName), uno::UNO_QUERY);
4747 if (xProperty.is() && (xProperty->getPropertyValue(
"IsPhysical") >>= bIsPhysical) && bIsPhysical)
4749 OUString displayName;
4750 xProperty->getPropertyValue(
"DisplayName") >>= displayName;
4751 aChild.put(
"", displayName.toUtf8());
4752 aChildren.push_back(std::make_pair(
"", aChild));
4755 aValues.add_child(
"HeaderFooter", aChildren);
4760 boost::property_tree::ptree aCommandList;
4763 boost::property_tree::ptree aChild;
4765 OUString sClearFormat =
SvxResId(RID_SVXSTR_CLEARFORM);
4767 boost::property_tree::ptree
aName;
4768 aName.put(
"", sClearFormat.toUtf8());
4769 aChild.push_back(std::make_pair(
"text", aName));
4771 boost::property_tree::ptree
aCommand;
4772 aCommand.put(
"",
".uno:ResetAttributes");
4773 aChild.push_back(std::make_pair(
"id", aCommand));
4775 aCommandList.push_back(std::make_pair(
"", aChild));
4778 aValues.add_child(
"Commands", aCommandList);
4781 aTree.add_child(
"commandValues", aValues);
4782 std::stringstream aStream;
4783 boost::property_tree::write_json(aStream, aTree);
4784 char* pJson =
static_cast<char*
>(malloc(aStream.str().size() + 1));
4786 strcpy(pJson, aStream.str().c_str());
4787 pJson[aStream.str().size()] =
'\0';
4819 if (eCommand == UndoOrRedo::UNDO)
4823 char* pJson = strdup(aString.toUtf8().getStr());
4832 uno::Reference<document::XRedlinesSupplier> xRedlinesSupplier(pDocument->
mxComponent, uno::UNO_QUERY);
4839 auto redlinesNode = aJson.
startArray(
"redlines");
4840 uno::Reference<container::XEnumeration> xRedlines = xRedlinesSupplier->getRedlines()->createEnumeration();
4841 for (
size_t nIndex = 0; xRedlines->hasMoreElements(); ++
nIndex)
4843 uno::Reference<beans::XPropertySet> xRedline(xRedlines->nextElement(), uno::UNO_QUERY);
4845 aJson.
put(
"index", static_cast<sal_Int32>(
nIndex));
4848 xRedline->getPropertyValue(
"RedlineAuthor") >>= sAuthor;
4849 aJson.
put(
"author", sAuthor);
4852 xRedline->getPropertyValue(
"RedlineType") >>= sType;
4853 aJson.
put(
"type", sType);
4856 xRedline->getPropertyValue(
"RedlineComment") >>= sComment;
4857 aJson.
put(
"comment", sComment);
4859 OUString sDescription;
4860 xRedline->getPropertyValue(
"RedlineDescription") >>= sDescription;
4861 aJson.
put(
"description", sDescription);
4863 util::DateTime aDateTime;
4864 xRedline->getPropertyValue(
"RedlineDateTime") >>= aDateTime;
4866 aJson.
put(
"dateTime", sDateTime);
4906 static constexpr OStringLiteral aViewRowColumnHeaders(
".uno:ViewRowColumnHeaders");
4907 static constexpr OStringLiteral aSheetGeometryData(
".uno:SheetGeometryData");
4908 static constexpr OStringLiteral aCellCursor(
".uno:CellCursor");
4909 static constexpr OStringLiteral aFontSubset(
".uno:FontSubset&name=");
4911 if (!strcmp(pCommand,
".uno:LanguageStatus"))
4915 else if (!strcmp(pCommand,
".uno:CharFontName"))
4919 else if (!strcmp(pCommand,
".uno:StyleApply"))
4923 else if (aCommand ==
".uno:Undo")
4927 else if (aCommand ==
".uno:Redo")
4931 else if (aCommand ==
".uno:AcceptTrackedChanges")
4935 else if (aCommand ==
".uno:TrackedChangeAuthors")
4939 else if (aCommand ==
".uno:ViewAnnotations")
4943 else if (aCommand ==
".uno:ViewAnnotationsPosition")
4947 else if (aCommand ==
".uno:RulerState")
4951 else if (aCommand.startsWith(aViewRowColumnHeaders))
4961 if (aCommand.getLength() > aViewRowColumnHeaders.getLength())
4968 OString
aArguments = aCommand.copy(aViewRowColumnHeaders.getLength() + 1);
4969 sal_Int32 nParamIndex = 0;
4972 OString aParamToken = aArguments.getToken(0,
'&', nParamIndex);
4978 OString aToken = aParamToken.getToken(0,
'=', nIndex);
4979 if (!aKey.getLength())
4984 while (nIndex >= 0);
4986 nX = aValue.toInt32();
4987 else if (aKey ==
"y")
4988 nY = aValue.toInt32();
4989 else if (aKey ==
"width")
4990 nWidth = aValue.toInt32();
4991 else if (aKey ==
"height")
4992 nHeight = aValue.toInt32();
4994 while (nParamIndex >= 0);
5003 else if (aCommand.startsWith(aSheetGeometryData))
5012 bool bColumns =
true;
5015 bool bHidden =
true;
5016 bool bFiltered =
true;
5017 bool bGroups =
true;
5018 if (aCommand.getLength() > aSheetGeometryData.getLength())
5020 bColumns = bRows = bSizes = bHidden = bFiltered = bGroups =
false;
5022 OString
aArguments = aCommand.copy(aSheetGeometryData.getLength() + 1);
5023 sal_Int32 nParamIndex = 0;
5026 OString aParamToken = aArguments.getToken(0,
'&', nParamIndex);
5032 OString aToken = aParamToken.getToken(0,
'=', nIndex);
5033 if (!aKey.getLength())
5038 }
while (nIndex >= 0);
5040 bool bEnableFlag = aValue.isEmpty() ||
5041 aValue.equalsIgnoreAsciiCase(
"true") || aValue.toInt32() > 0;
5045 if (aKey ==
"columns")
5047 else if (aKey ==
"rows")
5049 else if (aKey ==
"sizes")
5051 else if (aKey ==
"hidden")
5053 else if (aKey ==
"filtered")
5055 else if (aKey ==
"groups")
5058 }
while (nParamIndex >= 0);
5061 OString aGeomDataStr
5064 if (aGeomDataStr.isEmpty())
5069 else if (aCommand.startsWith(aCellCursor))
5082 else if (aCommand.startsWith(aFontSubset))
5084 return getFontSubset(std::string_view(pCommand + aFontSubset.getLength()));
5093 static void doc_setClientZoom(LibreOfficeKitDocument* pThis,
int nTilePixelWidth,
int nTilePixelHeight,
5094 int nTileTwipWidth,
int nTileTwipHeight)
5108 pDoc->
setClientZoom(nTilePixelWidth, nTilePixelHeight, nTileTwipWidth, nTileTwipHeight);
5129 static void doc_setOutlineState(LibreOfficeKitDocument* pThis,
bool bColumn,
int nLevel,
int nIndex,
bool bHidden)
5147 const char* pOptions)
5157 if (!aLanguage.isEmpty())
5164 const OUString aDeviceFormFactor =
extractParameter(aOptions,
u"DeviceFormFactor");
5173 forceSetClipboardForCurrentView(pThis);
5196 static void doc_setView(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* ,
int nId)
5227 static bool doc_getViewIds(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* pThis,
int* pArray,
size_t nSize)
5245 OUString sLanguage = OStringToOUString(language, RTL_TEXTENCODING_UTF8);
5253 const char* pFontName,
5262 const char* pFontName,
5273 OString aSearchedFontName(pFontName);
5274 OUString aText(OStringToOUString(pChar, RTL_TEXTENCODING_UTF8));
5277 pDocSh->
GetItem(SID_ATTR_CHAR_FONTLIST));
5280 const int nDefaultFontSize = 25;
5285 for (sal_uInt16
i = 0;
i < nFontCount; ++
i)
5289 if (aSearchedFontName != aFontName.toUtf8())
5292 if (aText.isEmpty())
5300 aDevice->SetFont(aFont);
5301 aDevice->GetTextBoundRect(aRect, aText);
5305 int nFontWidth = aRect.
Right() + 1;
5306 int nFontHeight = aRect.
Bottom() + 1;
5308 if (nFontWidth <= 0 || nFontHeight <= 0)
5311 if (*pFontWidth > 0 && *pFontHeight > 0)
5313 double fScaleX = *pFontWidth /
static_cast<double>(nFontWidth) / 1.5;
5314 double fScaleY = *pFontHeight /
static_cast<double>(nFontHeight) / 1.5;
5316 double fScale = std::min(fScaleX, fScaleY);
5320 int nFontSize = fScale * nDefaultFontSize;
5322 aDevice->SetFont(aFont);
5327 nFontWidth = *pFontWidth;
5328 nFontHeight = *pFontHeight;
5332 unsigned char* pBuffer =
static_cast<unsigned char*
>(malloc(4 * nFontWidth * nFontHeight));
5336 memset(pBuffer, 0, nFontWidth * nFontHeight * 4);
5338 aDevice->SetOutputSizePixelScaleOffsetAndBuffer(
5342 if (*pFontWidth > 0 && *pFontHeight > 0)
5345 DrawTextFlags::Center
5346 | DrawTextFlags::VCenter
5347 | DrawTextFlags::MultiLine
5348 | DrawTextFlags::WordBreak;
5350 aDevice->DrawText(aRect, aText, nStyle);
5354 *pFontWidth = nFontWidth;
5355 *pFontHeight = nFontHeight;
5357 aDevice->DrawText(
Point(0,0), aText);
5369 unsigned char* pBuffer,
5370 const int nX,
const int nY,
5371 const int nWidth,
const int nHeight)
5377 unsigned char* pBuffer,
5378 const int nX,
const int nY,
5379 const int nWidth,
const int nHeight,
5380 const double fDPIScale)
5386 unsigned char* pBuffer,
const int nX,
const int nY,
5387 const int nWidth,
const int nHeight,
5388 const double fDPIScale,
int viewId)
5415 CGContextRef cgc = CGBitmapContextCreate(pBuffer, nWidth, nHeight, 8, nWidth*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little);
5417 CGContextTranslateCTM(cgc, 0, nHeight);
5418 CGContextScaleCTM(cgc, fDPIScale, -fDPIScale);
5421 aData.rCGContext = cgc;