Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name init.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D DESKTOP_DLLIMPLEMENTATION -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/curl/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/desktop/inc -I /home/maarten/src/libreoffice/core/desktop/source/inc -I /home/maarten/src/libreoffice/core/desktop/source/deployment/inc -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx

/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <config_features.h>
11
12#include <stdio.h>
13#include <string.h>
14#include <stdlib.h>
15
16#ifdef IOS
17#include <sys/mman.h>
18#include <sys/stat.h>
19#include <unicode/udata.h>
20#include <unicode/ucnv.h>
21#include <premac.h>
22#import <Foundation/Foundation.h>
23#import <CoreGraphics/CoreGraphics.h>
24#include <postmac.h>
25#endif
26
27#ifdef ANDROID
28#include <osl/detail/android-bootstrap.h>
29#endif
30
31#include <algorithm>
32#include <memory>
33#include <iostream>
34#include <boost/property_tree/json_parser.hpp>
35#include <boost/algorithm/string.hpp>
36
37#include <LibreOfficeKit/LibreOfficeKit.h>
38#include <LibreOfficeKit/LibreOfficeKitEnums.h>
39
40#include <sal/log.hxx>
41#include <vcl/errinf.hxx>
42#include <vcl/lok.hxx>
43#include <o3tl/any.hxx>
44#include <osl/file.hxx>
45#include <osl/process.h>
46#include <osl/thread.h>
47#include <rtl/bootstrap.hxx>
48#include <rtl/strbuf.hxx>
49#include <rtl/uri.hxx>
50#include <svl/zforlist.hxx>
51#include <cppuhelper/bootstrap.hxx>
52#include <comphelper/base64.hxx>
53#include <comphelper/dispatchcommand.hxx>
54#include <comphelper/lok.hxx>
55#include <comphelper/processfactory.hxx>
56#include <comphelper/string.hxx>
57#include <comphelper/profilezone.hxx>
58#include <comphelper/propertysequence.hxx>
59#include <comphelper/scopeguard.hxx>
60#include <comphelper/threadpool.hxx>
61#include <comphelper/sequenceashashmap.hxx>
62
63#include <com/sun/star/beans/XPropertySet.hpp>
64#include <com/sun/star/container/XNameAccess.hpp>
65#include <com/sun/star/frame/Desktop.hpp>
66#include <com/sun/star/frame/DispatchResultEvent.hpp>
67#include <com/sun/star/frame/DispatchResultState.hpp>
68#include <com/sun/star/frame/XDispatchProvider.hpp>
69#include <com/sun/star/frame/XDispatchResultListener.hpp>
70#include <com/sun/star/frame/XSynchronousDispatch.hpp>
71#include <com/sun/star/frame/XStorable.hpp>
72#include <com/sun/star/lang/Locale.hpp>
73#include <com/sun/star/lang/XComponent.hpp>
74#include <com/sun/star/lang/XMultiServiceFactory.hpp>
75#include <com/sun/star/reflection/theCoreReflection.hpp>
76#include <com/sun/star/reflection/XIdlClass.hpp>
77#include <com/sun/star/reflection/XIdlReflection.hpp>
78#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
79#include <com/sun/star/util/URLTransformer.hpp>
80#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
81#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
82#include <com/sun/star/datatransfer/XTransferable2.hpp>
83#include <com/sun/star/text/TextContentAnchorType.hpp>
84#include <com/sun/star/document/XRedlinesSupplier.hpp>
85#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
86
87#include <com/sun/star/xml/crypto/SEInitializer.hpp>
88#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
89#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
90#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
91#include <com/sun/star/security/XCertificate.hpp>
92
93#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
94#include <com/sun/star/linguistic2/XSpellChecker.hpp>
95#include <com/sun/star/i18n/LocaleCalendar2.hpp>
96#include <com/sun/star/i18n/ScriptType.hpp>
97#include <com/sun/star/lang/DisposedException.hpp>
98
99#include <editeng/flstitem.hxx>
100#ifdef IOS
101#include <sfx2/app.hxx>
102#endif
103#include <sfx2/objsh.hxx>
104#include <sfx2/docfilt.hxx>
105#include <sfx2/docfile.hxx>
106#include <sfx2/viewsh.hxx>
107#include <sfx2/viewfrm.hxx>
108#include <sfx2/msgpool.hxx>
109#include <sfx2/dispatch.hxx>
110#include <sfx2/lokcharthelper.hxx>
111#include <sfx2/DocumentSigner.hxx>
112#include <sfx2/sidebar/SidebarDockingWindow.hxx>
113#include <sfx2/sidebar/SidebarController.hxx>
114#include <svx/dialmgr.hxx>
115#include <svx/strings.hrc>
116#include <svx/svdview.hxx>
117#include <svx/svxids.hrc>
118#include <svx/ucsubset.hxx>
119#include <vcl/vclevent.hxx>
120#include <vcl/GestureEvent.hxx>
121#include <vcl/svapp.hxx>
122#include <unotools/resmgr.hxx>
123#include <tools/fract.hxx>
124#include <tools/json_writer.hxx>
125#include <svtools/ctrltool.hxx>
126#include <svtools/langtab.hxx>
127#include <vcl/floatwin.hxx>
128#include <vcl/fontcharmap.hxx>
129#include <vcl/graphicfilter.hxx>
130#ifdef IOS
131#include <vcl/sysdata.hxx>
132#endif
133#include <vcl/virdev.hxx>
134#include <vcl/ImageTree.hxx>
135#include <vcl/ITiledRenderable.hxx>
136#include <vcl/dialoghelper.hxx>
137#include <unicode/uchar.h>
138#include <unotools/confignode.hxx>
139#include <unotools/syslocaleoptions.hxx>
140#include <unotools/mediadescriptor.hxx>
141#include <unotools/pathoptions.hxx>
142#include <unotools/tempfile.hxx>
143#include <unotools/streamwrap.hxx>
144#include <osl/module.hxx>
145#include <comphelper/sequence.hxx>
146#include <sfx2/sfxbasemodel.hxx>
147#include <svl/undo.hxx>
148#include <unotools/datetime.hxx>
149#include <i18nlangtag/mslangid.hxx>
150#include <i18nlangtag/languagetag.hxx>
151#include <vcl/builder.hxx>
152#include <vcl/abstdlg.hxx>
153#include <tools/diagnose_ex.h>
154#include <vcl/uitest/uiobject.hxx>
155#include <vcl/jsdialog/executor.hxx>
156
157// Needed for getUndoManager()
158#include <com/sun/star/document/XUndoManager.hpp>
159#include <com/sun/star/document/XUndoManagerSupplier.hpp>
160#include <editeng/sizeitem.hxx>
161#include <svx/rulritem.hxx>
162#include <svx/pageitem.hxx>
163
164#include <app.hxx>
165
166#include "../app/cmdlineargs.hxx"
167// We also need to hackily be able to start the main libreoffice thread:
168#include "../app/sofficemain.h"
169#include "../app/officeipcthread.hxx"
170#include <lib/init.hxx>
171
172#include "lokinteractionhandler.hxx"
173#include "lokclipboard.hxx"
174#include <officecfg/Office/Impress.hxx>
175
176using namespace css;
177using namespace vcl;
178using namespace desktop;
179using namespace utl;
180
181static LibLibreOffice_Impl *gImpl = nullptr;
182static std::weak_ptr< LibreOfficeKitClass > gOfficeClass;
183static std::weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass;
184
185static void SetLastExceptionMsg(const OUString& s = OUString())
186{
187 SAL_WARN_IF(!s.isEmpty(), "lok", "lok exception '" + s + "'")do { if (true && (!s.isEmpty())) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "lok exception '"
+ s + "'") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "187" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "lok exception '" + s + "'"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"lok exception '" + s + "'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "187" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "lok exception '" + s + "'") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "187" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "lok exception '" + s + "'"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"lok exception '" + s + "'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "187" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
188 if (gImpl)
189 gImpl->maLastExceptionMsg = s;
190}
191
192namespace {
193
194struct ExtensionMap
195{
196 const char *extn;
197 const char *filterName;
198};
199
200}
201
202const ExtensionMap aWriterExtensionMap[] =
203{
204 { "doc", "MS Word 97" },
205 { "docm", "MS Word 2007 XML VBA" },
206 { "docx", "MS Word 2007 XML" },
207 { "fodt", "OpenDocument Text Flat XML" },
208 { "html", "HTML (StarWriter)" },
209 { "odt", "writer8" },
210 { "ott", "writer8_template" },
211 { "pdf", "writer_pdf_Export" },
212 { "epub", "EPUB" },
213 { "rtf", "Rich Text Format" },
214 { "txt", "Text" },
215 { "xhtml", "XHTML Writer File" },
216 { "png", "writer_png_Export" },
217 { nullptr, nullptr }
218};
219
220const ExtensionMap aCalcExtensionMap[] =
221{
222 { "csv", "Text - txt - csv (StarCalc)" },
223 { "fods", "OpenDocument Spreadsheet Flat XML" },
224 { "html", "HTML (StarCalc)" },
225 { "ods", "calc8" },
226 { "ots", "calc8_template" },
227 { "pdf", "calc_pdf_Export" },
228 { "xhtml", "XHTML Calc File" },
229 { "xls", "MS Excel 97" },
230 { "xlsm", "Calc MS Excel 2007 VBA XML" },
231 { "xlsx", "Calc MS Excel 2007 XML" },
232 { "png", "calc_png_Export" },
233 { nullptr, nullptr }
234};
235
236const ExtensionMap aImpressExtensionMap[] =
237{
238 { "fodp", "OpenDocument Presentation Flat XML" },
239 { "html", "impress_html_Export" },
240 { "odg", "impress8_draw" },
241 { "odp", "impress8" },
242 { "otp", "impress8_template" },
243 { "pdf", "impress_pdf_Export" },
244 { "potm", "Impress MS PowerPoint 2007 XML Template" },
245 { "pot", "MS PowerPoint 97 Vorlage" },
246 { "pptm", "Impress MS PowerPoint 2007 XML VBA" },
247 { "pptx", "Impress MS PowerPoint 2007 XML" },
248 { "pps", "MS PowerPoint 97 Autoplay" },
249 { "ppt", "MS PowerPoint 97" },
250 { "svg", "impress_svg_Export" },
251 { "xhtml", "XHTML Impress File" },
252 { "png", "impress_png_Export"},
253 { nullptr, nullptr }
254};
255
256const ExtensionMap aDrawExtensionMap[] =
257{
258 { "fodg", "draw_ODG_FlatXML" },
259 { "html", "draw_html_Export" },
260 { "odg", "draw8" },
261 { "pdf", "draw_pdf_Export" },
262 { "svg", "draw_svg_Export" },
263 { "xhtml", "XHTML Draw File" },
264 { "png", "draw_png_Export"},
265 { nullptr, nullptr }
266};
267
268static OUString getUString(const char* pString)
269{
270 if (pString == nullptr)
271 return OUString();
272
273 OString sString(pString, strlen(pString));
274 return OStringToOUString(sString, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
275}
276
277// Tolerate embedded \0s etc.
278static char *convertOString(const OString &rStr)
279{
280 char* pMemory = static_cast<char*>(malloc(rStr.getLength() + 1));
281 assert(pMemory)(static_cast <bool> (pMemory) ? void (0) : __assert_fail
("pMemory", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 281, __extension__ __PRETTY_FUNCTION__))
; // don't tolerate failed allocations.
282 memcpy(pMemory, rStr.getStr(), rStr.getLength() + 1);
283 return pMemory;
284}
285
286static char *convertOUString(const OUString &aStr)
287{
288 return convertOString(OUStringToOString(aStr, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
289}
290
291/// Try to convert a relative URL to an absolute one, unless it already looks like a URL.
292static OUString getAbsoluteURL(const char* pURL)
293{
294 OUString aURL(getUString(pURL));
295 if (aURL.isEmpty())
296 return aURL;
297
298 // convert relative paths to absolute ones
299 OUString aWorkingDir;
300 osl_getProcessWorkingDir(&aWorkingDir.pData);
301 if (!aWorkingDir.endsWith("/"))
302 aWorkingDir += "/";
303
304 try
305 {
306 return rtl::Uri::convertRelToAbs(aWorkingDir, aURL);
307 }
308 catch (const rtl::MalformedUriException &)
309 {
310 }
311
312 return OUString();
313}
314
315static uno::Any jsonToUnoAny(const boost::property_tree::ptree& aTree)
316{
317 uno::Any aAny;
318 uno::Any aValue;
319 sal_Int32 nFields;
320 uno::Reference< reflection::XIdlField > aField;
321 boost::property_tree::ptree aNodeNull, aNodeValue, aNodeField;
322 const std::string& rType = aTree.get<std::string>("type", "");
323 const std::string& rValue = aTree.get<std::string>("value", "");
324 uno::Sequence< uno::Reference< reflection::XIdlField > > aFields;
325 uno::Reference< reflection:: XIdlClass > xIdlClass =
326 css::reflection::theCoreReflection::get(comphelper::getProcessComponentContext())->forName(OUString::fromUtf8(rType.c_str()));
327 if (xIdlClass.is())
328 {
329 uno::TypeClass aTypeClass = xIdlClass->getTypeClass();
330 xIdlClass->createObject(aAny);
331 aFields = xIdlClass->getFields();
332 nFields = aFields.getLength();
333 aNodeValue = aTree.get_child("value", aNodeNull);
334 if (nFields > 0 && aNodeValue != aNodeNull)
335 {
336 for (sal_Int32 itField = 0; itField < nFields; ++itField)
337 {
338 aField = aFields[itField];
339 aNodeField = aNodeValue.get_child(aField->getName().toUtf8().getStr(), aNodeNull);
340 if (aNodeField != aNodeNull)
341 {
342 aValue = jsonToUnoAny(aNodeField);
343 aField->set(aAny, aValue);
344 }
345 }
346 }
347 else if (!rValue.empty())
348 {
349 if (aTypeClass == uno::TypeClass_VOID)
350 aAny.clear();
351 else if (aTypeClass == uno::TypeClass_BYTE)
352 aAny <<= static_cast<sal_Int8>(OString(rValue.c_str()).toInt32());
353 else if (aTypeClass == uno::TypeClass_BOOLEAN)
354 aAny <<= OString(rValue.c_str()).toBoolean();
355 else if (aTypeClass == uno::TypeClass_SHORT)
356 aAny <<= static_cast<sal_Int16>(OString(rValue.c_str()).toInt32());
357 else if (aTypeClass == uno::TypeClass_UNSIGNED_SHORT)
358 aAny <<= static_cast<sal_uInt16>(OString(rValue.c_str()).toUInt32());
359 else if (aTypeClass == uno::TypeClass_LONG)
360 aAny <<= OString(rValue.c_str()).toInt32();
361 else if (aTypeClass == uno::TypeClass_UNSIGNED_LONG)
362 aAny <<= static_cast<sal_uInt32>(OString(rValue.c_str()).toInt32());
363 else if (aTypeClass == uno::TypeClass_FLOAT)
364 aAny <<= OString(rValue.c_str()).toFloat();
365 else if (aTypeClass == uno::TypeClass_DOUBLE)
366 aAny <<= OString(rValue.c_str()).toDouble();
367 else if (aTypeClass == uno::TypeClass_STRING)
368 aAny <<= OUString::fromUtf8(rValue.c_str());
369 }
370 }
371 return aAny;
372}
373
374std::vector<beans::PropertyValue> desktop::jsonToPropertyValuesVector(const char* pJSON)
375{
376 std::vector<beans::PropertyValue> aArguments;
377 if (pJSON && pJSON[0] != '\0')
378 {
379 boost::property_tree::ptree aTree, aNodeNull, aNodeValue;
380 std::stringstream aStream(pJSON);
381 boost::property_tree::read_json(aStream, aTree);
382
383 for (const auto& rPair : aTree)
384 {
385 const std::string& rType = rPair.second.get<std::string>("type", "");
386 const std::string& rValue = rPair.second.get<std::string>("value", "");
387
388 beans::PropertyValue aValue;
389 aValue.Name = OUString::fromUtf8(rPair.first.c_str());
390 if (rType == "string")
391 aValue.Value <<= OUString::fromUtf8(rValue.c_str());
392 else if (rType == "boolean")
393 aValue.Value <<= OString(rValue.c_str()).toBoolean();
394 else if (rType == "float")
395 aValue.Value <<= OString(rValue.c_str()).toFloat();
396 else if (rType == "long")
397 aValue.Value <<= OString(rValue.c_str()).toInt32();
398 else if (rType == "short")
399 aValue.Value <<= sal_Int16(OString(rValue.c_str()).toInt32());
400 else if (rType == "unsigned short")
401 aValue.Value <<= sal_uInt16(OString(rValue.c_str()).toUInt32());
402 else if (rType == "int64")
403 aValue.Value <<= OString(rValue.c_str()).toInt64();
404 else if (rType == "int32")
405 aValue.Value <<= OString(rValue.c_str()).toInt32();
406 else if (rType == "int16")
407 aValue.Value <<= sal_Int16(OString(rValue.c_str()).toInt32());
408 else if (rType == "uint64")
409 aValue.Value <<= OString(rValue.c_str()).toUInt64();
410 else if (rType == "uint32")
411 aValue.Value <<= OString(rValue.c_str()).toUInt32();
412 else if (rType == "uint16")
413 aValue.Value <<= sal_uInt16(OString(rValue.c_str()).toUInt32());
414 else if (rType == "[]byte")
415 {
416 aNodeValue = rPair.second.get_child("value", aNodeNull);
417 if (aNodeValue != aNodeNull && aNodeValue.size() == 0)
418 {
419 uno::Sequence< sal_Int8 > aSeqByte(reinterpret_cast<const sal_Int8*>(rValue.c_str()), rValue.size());
420 aValue.Value <<= aSeqByte;
421 }
422 }
423 else if (rType == "[]any")
424 {
425 aNodeValue = rPair.second.get_child("value", aNodeNull);
426 if (aNodeValue != aNodeNull && !aNodeValue.empty())
427 {
428 sal_Int32 itSeq = 0;
429 uno::Sequence< uno::Any > aSeq(aNodeValue.size());
430 for (const auto& rSeqPair : aNodeValue)
431 aSeq[itSeq++] = jsonToUnoAny(rSeqPair.second);
432 aValue.Value <<= aSeq;
433 }
434 }
435 else
436 SAL_WARN("desktop.lib", "jsonToPropertyValuesVector: unhandled type '"<<rType<<"'")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "desktop.lib")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break;
case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "jsonToPropertyValuesVector: unhandled type '"
<<rType<<"'") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("desktop.lib"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "436" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "jsonToPropertyValuesVector: unhandled type '"
<<rType<<"'"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "jsonToPropertyValuesVector: unhandled type '"
<<rType<<"'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("desktop.lib"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "436" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "jsonToPropertyValuesVector: unhandled type '"<<
rType<<"'") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("desktop.lib"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "436" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "jsonToPropertyValuesVector: unhandled type '"
<<rType<<"'"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "jsonToPropertyValuesVector: unhandled type '"
<<rType<<"'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("desktop.lib"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "436" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
437 aArguments.push_back(aValue);
438 }
439 }
440 return aArguments;
441}
442
443
444static StringMap jsonToStringMap(const char* pJSON)
445{
446 StringMap aArgs;
447 if (pJSON && pJSON[0] != '\0')
448 {
449 std::stringstream aStream(pJSON);
450 boost::property_tree::ptree aTree;
451 boost::property_tree::read_json(aStream, aTree);
452
453 for (const auto& rPair : aTree)
454 {
455 aArgs[OUString::fromUtf8(rPair.first.c_str())] = OUString::fromUtf8(rPair.second.get_value<std::string>(".").c_str());
456 }
457 }
458 return aArgs;
459}
460
461
462static boost::property_tree::ptree unoAnyToPropertyTree(const uno::Any& anyItem)
463{
464 boost::property_tree::ptree aTree;
465 OUString aType = anyItem.getValueTypeName();
466 aTree.put("type", aType.toUtf8().getStr());
467
468 if (aType == "string")
469 aTree.put("value", anyItem.get<OUString>().toUtf8().getStr());
470 else if (aType == "unsigned long")
471 aTree.put("value", OString::number(anyItem.get<sal_uInt32>()).getStr());
472 else if (aType == "long")
473 aTree.put("value", OString::number(anyItem.get<sal_Int32>()).getStr());
474 else if (aType == "[]any")
475 {
476 uno::Sequence<uno::Any> aSeq;
477 if (anyItem >>= aSeq)
478 {
479 boost::property_tree::ptree aSubTree;
480
481 for (auto i = 0; i < aSeq.getLength(); ++i)
482 {
483 aSubTree.add_child(OString::number(i).getStr(), unoAnyToPropertyTree(aSeq[i]));
484 }
485 aTree.add_child("value", aSubTree);
486 }
487 }
488
489 // TODO: Add more as required
490
491 return aTree;
492}
493
494namespace desktop {
495
496RectangleAndPart RectangleAndPart::Create(const std::string& rPayload)
497{
498 RectangleAndPart aRet;
499 if (rPayload.compare(0, 5, "EMPTY") == 0) // payload starts with "EMPTY"
500 {
501 aRet.m_aRectangle = tools::Rectangle(0, 0, SfxLokHelper::MaxTwips, SfxLokHelper::MaxTwips);
502 if (comphelper::LibreOfficeKit::isPartInInvalidation())
503 aRet.m_nPart = std::stol(rPayload.substr(6));
504
505 return aRet;
506 }
507
508 std::istringstream aStream(rPayload);
509 long nLeft, nTop, nWidth, nHeight;
510 long nPart = INT_MIN(-2147483647 -1);
511 char nComma;
512 if (comphelper::LibreOfficeKit::isPartInInvalidation())
513 {
514 aStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight >> nComma >> nPart;
515 }
516 else
517 {
518 aStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
519 }
520
521 if (nWidth > 0 && nHeight > 0)
522 {
523 // The top-left corner starts at (0, 0).
524 // Anything negative is invalid.
525 if (nLeft < 0)
526 {
527 nWidth += nLeft;
528 nLeft = 0;
529 }
530
531 if (nTop < 0)
532 {
533 nHeight += nTop;
534 nTop = 0;
535 }
536
537 if (nWidth > 0 && nHeight > 0)
538 {
539 aRet.m_aRectangle = tools::Rectangle(nLeft, nTop, nLeft + nWidth, nTop + nHeight);
540 }
541 }
542 // else leave empty rect.
543
544 aRet.m_nPart = nPart;
545 return aRet;
546}
547
548RectangleAndPart& CallbackFlushHandler::CallbackData::setRectangleAndPart(const std::string& payload)
549{
550 setRectangleAndPart(RectangleAndPart::Create(payload));
551
552 // Return reference to the cached object.
553 return boost::get<RectangleAndPart>(PayloadObject);
554}
555
556void CallbackFlushHandler::CallbackData::setRectangleAndPart(const RectangleAndPart& rRectAndPart)
557{
558 PayloadString = rRectAndPart.toString().getStr();
559 PayloadObject = rRectAndPart;
560}
561
562const RectangleAndPart& CallbackFlushHandler::CallbackData::getRectangleAndPart() const
563{
564 assert(PayloadObject.which() == 1)(static_cast <bool> (PayloadObject.which() == 1) ? void
(0) : __assert_fail ("PayloadObject.which() == 1", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 564, __extension__ __PRETTY_FUNCTION__))
;
565 return boost::get<RectangleAndPart>(PayloadObject);
566}
567
568boost::property_tree::ptree& CallbackFlushHandler::CallbackData::setJson(const std::string& payload)
569{
570 boost::property_tree::ptree aTree;
571 std::stringstream aStream(payload);
572 boost::property_tree::read_json(aStream, aTree);
573
574 // Let boost normalize the payload so it always matches the cache.
575 setJson(aTree);
576
577 // Return reference to the cached object.
578 return boost::get<boost::property_tree::ptree>(PayloadObject);
579}
580
581void CallbackFlushHandler::CallbackData::setJson(const boost::property_tree::ptree& rTree)
582{
583 std::stringstream aJSONStream;
584 constexpr bool bPretty = false; // Don't waste time and bloat logs.
585 boost::property_tree::write_json(aJSONStream, rTree, bPretty);
586 PayloadString = boost::trim_copy(aJSONStream.str());
587
588 PayloadObject = rTree;
589}
590
591const boost::property_tree::ptree& CallbackFlushHandler::CallbackData::getJson() const
592{
593 assert(PayloadObject.which() == 2)(static_cast <bool> (PayloadObject.which() == 2) ? void
(0) : __assert_fail ("PayloadObject.which() == 2", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 593, __extension__ __PRETTY_FUNCTION__))
;
594 return boost::get<boost::property_tree::ptree>(PayloadObject);
595}
596
597bool CallbackFlushHandler::CallbackData::validate() const
598{
599 switch (PayloadObject.which())
600 {
601 // Not cached.
602 case 0:
603 return true;
604
605 // RectangleAndPart.
606 case 1:
607 return getRectangleAndPart().toString().getStr() == PayloadString;
608
609 // Json.
610 case 2:
611 {
612 std::stringstream aJSONStream;
613 boost::property_tree::write_json(aJSONStream, getJson(), false);
614 const std::string aExpected = boost::trim_copy(aJSONStream.str());
615 return aExpected == PayloadString;
616 }
617
618 default:
619 assert(!"Unknown variant type; please add an entry to validate.")(static_cast <bool> (!"Unknown variant type; please add an entry to validate."
) ? void (0) : __assert_fail ("!\"Unknown variant type; please add an entry to validate.\""
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 619, __extension__ __PRETTY_FUNCTION__))
;
620 }
621
622 return false;
623}
624
625}
626
627namespace {
628
629bool lcl_isViewCallbackType(const int type)
630{
631 switch (type)
632 {
633 case LOK_CALLBACK_CELL_VIEW_CURSOR:
634 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
635 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
636 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
637 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
638 return true;
639
640 default:
641 return false;
642 }
643}
644
645int lcl_getViewId(const std::string& payload)
646{
647 // this is a cheap way how to get the viewId from a JSON message; proper
648 // parsing is terribly expensive, and we just need the viewId here
649 size_t viewIdPos = payload.find("viewId");
650 if (viewIdPos == std::string::npos)
651 return 0;
652
653 size_t numberPos = payload.find(":", viewIdPos + 6);
654 if (numberPos == std::string::npos)
655 return 0;
656
657 for (++numberPos; numberPos < payload.length(); ++numberPos)
658 {
659 if (payload[numberPos] == ',' || payload[numberPos] == '}' || (payload[numberPos] >= '0' && payload[numberPos] <= '9'))
660 break;
661 }
662
663 if (numberPos < payload.length() && payload[numberPos] >= '0' && payload[numberPos] <= '9')
664 return strtol(payload.substr(numberPos).c_str(), nullptr, 10);
665
666 return 0;
667}
668
669int lcl_getViewId(const desktop::CallbackFlushHandler::CallbackData& rCallbackData)
670{
671 if (rCallbackData.isCached())
672 return rCallbackData.getJson().get<int>("viewId");
673 return lcl_getViewId(rCallbackData.PayloadString);
674}
675
676std::string extractCertificate(const std::string & certificate)
677{
678 const std::string header("-----BEGIN CERTIFICATE-----");
679 const std::string footer("-----END CERTIFICATE-----");
680
681 std::string result;
682
683 size_t pos1 = certificate.find(header);
684 if (pos1 == std::string::npos)
685 return result;
686
687 size_t pos2 = certificate.find(footer, pos1 + 1);
688 if (pos2 == std::string::npos)
689 return result;
690
691 pos1 = pos1 + header.length();
692 pos2 = pos2 - pos1;
693
694 return certificate.substr(pos1, pos2);
695}
696
697std::string extractPrivateKey(const std::string & privateKey)
698{
699 const std::string header("-----BEGIN PRIVATE KEY-----");
700 const std::string footer("-----END PRIVATE KEY-----");
701
702 std::string result;
703
704 size_t pos1 = privateKey.find(header);
705 if (pos1 == std::string::npos)
706 return result;
707
708 size_t pos2 = privateKey.find(footer, pos1 + 1);
709 if (pos2 == std::string::npos)
710 return result;
711
712 pos1 = pos1 + header.length();
713 pos2 = pos2 - pos1;
714
715 return privateKey.substr(pos1, pos2);
716}
717
718OUString lcl_getCurrentDocumentMimeType(const LibLODocument_Impl* pDocument)
719{
720 SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
721 if (!pBaseModel)
722 return "";
723
724 SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
725 if (!pObjectShell)
726 return "";
727
728 SfxMedium* pMedium = pObjectShell->GetMedium();
729 if (!pMedium)
730 return "";
731
732 auto pFilter = pMedium->GetFilter();
733 if (!pFilter)
734 return "";
735
736 return pFilter->GetMimeType();
737}
738
739// Gets an undo manager to enter and exit undo context. Needed by ToggleOrientation
740css::uno::Reference< css::document::XUndoManager > getUndoManager( const css::uno::Reference< css::frame::XFrame >& rxFrame )
741{
742 const css::uno::Reference< css::frame::XController >& xController = rxFrame->getController();
743 if ( xController.is() )
744 {
745 const css::uno::Reference< css::frame::XModel >& xModel = xController->getModel();
746 if ( xModel.is() )
747 {
748 const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW );
749 return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW );
750 }
751 }
752
753 return css::uno::Reference< css::document::XUndoManager > ();
754}
755
756// Adjusts page margins for Writer doc. Needed by ToggleOrientation
757void ExecuteMarginLRChange(
758 const long nPageLeftMargin,
759 const long nPageRightMargin,
760 SvxLongLRSpaceItem* pPageLRMarginItem)
761{
762 pPageLRMarginItem->SetLeft( nPageLeftMargin );
763 pPageLRMarginItem->SetRight( nPageRightMargin );
764 SfxViewShell::Current()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_LRSPACETypedWhichId<SvxLongLRSpaceItem>( 10000 + 62 ),
765 SfxCallMode::RECORD, { pPageLRMarginItem });
766}
767
768// Adjusts page margins for Writer doc. Needed by ToggleOrientation
769void ExecuteMarginULChange(
770 const long nPageTopMargin,
771 const long nPageBottomMargin,
772 SvxLongULSpaceItem* pPageULMarginItem)
773{
774 pPageULMarginItem->SetUpper( nPageTopMargin );
775 pPageULMarginItem->SetLower( nPageBottomMargin );
776 SfxViewShell::Current()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_ULSPACETypedWhichId<SvxLongULSpaceItem>( 10000 + 63 ),
777 SfxCallMode::RECORD, { pPageULMarginItem });
778}
779
780// Main function which toggles page orientation of the Writer doc. Needed by ToggleOrientation
781void ExecuteOrientationChange()
782{
783 std::unique_ptr<SvxPageItem> pPageItem(new SvxPageItem(SID_ATTR_PAGETypedWhichId<SvxPageItem>( 10000 + 50 )));
784 std::unique_ptr<SvxSizeItem> pPageSizeItem(new SvxSizeItem(SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 )));
785 std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(new SvxLongLRSpaceItem( 0, 0, SID_ATTR_PAGE_LRSPACETypedWhichId<SvxLongLRSpaceItem>( 10000 + 62 ) ));
786 std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(new SvxLongULSpaceItem( 0, 0, SID_ATTR_PAGE_ULSPACETypedWhichId<SvxLongULSpaceItem>( 10000 + 63 ) ));
787 // 1mm in twips rounded
788 // This should be in sync with MINBODY in sw/source/uibase/sidebar/PageMarginControl.hxx
789 constexpr long MINBODY = 56;
790
791 css::uno::Reference< css::document::XUndoManager > mxUndoManager(
792 getUndoManager( SfxViewFrame::Current()->GetFrame().GetFrameInterface() ) );
793
794 if ( mxUndoManager.is() )
795 mxUndoManager->enterUndoContext( "" );
796
797
798 const SfxPoolItem* pItem;
799
800
801 SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ), pItem);
802 pPageSizeItem.reset( static_cast<SvxSizeItem*>(pItem->Clone()) );
803
804
805
806 SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_LRSPACETypedWhichId<SvxLongLRSpaceItem>( 10000 + 62 ), pItem);
807 pPageLRMarginItem.reset( static_cast<SvxLongLRSpaceItem*>(pItem->Clone()) );
808
809
810
811 SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_ULSPACETypedWhichId<SvxLongULSpaceItem>( 10000 + 63 ), pItem);
812 pPageULMarginItem.reset( static_cast<SvxLongULSpaceItem*>(pItem->Clone()) );
813
814
815 {
816 bool bIsLandscape = false;
817 if ( pPageSizeItem->GetSize().Width() > pPageSizeItem->GetSize().Height())
818 bIsLandscape = true;
819
820 // toggle page orientation
821 pPageItem->SetLandscape(!bIsLandscape);
822
823
824 // swap the width and height of the page size
825 const long nRotatedWidth = pPageSizeItem->GetSize().Height();
826 const long nRotatedHeight = pPageSizeItem->GetSize().Width();
827 pPageSizeItem->SetSize(Size(nRotatedWidth, nRotatedHeight));
828
829
830 // apply changed attributes
831 if (SfxViewShell::Current())
832 {
833 SfxViewShell::Current()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_SIZETypedWhichId<SvxSizeItem>( 10000 + 51 ),
834 SfxCallMode::RECORD, { pPageSizeItem.get(), pPageItem.get() });
835 }
836 }
837
838
839 // check, if margin values still fit to the changed page size.
840 // if not, adjust margin values
841 {
842 const long nML = pPageLRMarginItem->GetLeft();
843 const long nMR = pPageLRMarginItem->GetRight();
844 const long nTmpPW = nML + nMR + MINBODY;
845
846 const long nPW = pPageSizeItem->GetSize().Width();
847
848 if ( nTmpPW > nPW )
849 {
850 if ( nML <= nMR )
851 {
852 ExecuteMarginLRChange( pPageLRMarginItem->GetLeft(), nMR - (nTmpPW - nPW ), pPageLRMarginItem.get() );
853 }
854 else
855 {
856 ExecuteMarginLRChange( nML - (nTmpPW - nPW ), pPageLRMarginItem->GetRight(), pPageLRMarginItem.get() );
857 }
858 }
859
860 const long nMT = pPageULMarginItem->GetUpper();
861 const long nMB = pPageULMarginItem->GetLower();
862 const long nTmpPH = nMT + nMB + MINBODY;
863
864 const long nPH = pPageSizeItem->GetSize().Height();
865
866 if ( nTmpPH > nPH )
867 {
868 if ( nMT <= nMB )
869 {
870 ExecuteMarginULChange( pPageULMarginItem->GetUpper(), nMB - ( nTmpPH - nPH ), pPageULMarginItem.get() );
871 }
872 else
873 {
874 ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), pPageULMarginItem->GetLower(), pPageULMarginItem.get() );
875 }
876 }
877 }
878
879 if ( mxUndoManager.is() )
880 mxUndoManager->leaveUndoContext();
881}
882
883void setupSidebar(const OUString& sidebarDeckId = "")
884{
885 SfxViewShell* pViewShell = SfxViewShell::Current();
886 SfxViewFrame* pViewFrame = pViewShell ? pViewShell->GetViewFrame() : nullptr;
887 if (pViewFrame)
888 {
889 if (!pViewFrame->GetChildWindow(SID_SIDEBAR(10000 + 336)))
890 pViewFrame->SetChildWindow(SID_SIDEBAR(10000 + 336), false /* create it */, true /* focus */);
891
892 pViewFrame->ShowChildWindow(SID_SIDEBAR(10000 + 336), true);
893
894 // Force synchronous population of panels
895 SfxChildWindow *pChild = pViewFrame->GetChildWindow(SID_SIDEBAR(10000 + 336));
896 if (!pChild)
897 return;
898
899 auto pDockingWin = dynamic_cast<sfx2::sidebar::SidebarDockingWindow *>(pChild->GetWindow());
900 if (!pDockingWin)
901 return;
902
903 OUString currentDeckId = pDockingWin->GetSidebarController()->GetCurrentDeckId();
904
905 // check if it is the chart deck id, if it is, don't switch to default deck
906 bool switchToDefault = true;
907
908 if (currentDeckId == "ChartDeck")
909 switchToDefault = false;
910
911 if (!sidebarDeckId.isEmpty())
912 {
913 pDockingWin->GetSidebarController()->SwitchToDeck(sidebarDeckId);
914 }
915 else
916 {
917 if (switchToDefault)
918 pDockingWin->GetSidebarController()->SwitchToDefaultDeck();
919 }
920
921 pDockingWin->SyncUpdate();
922 }
923 else
924 SetLastExceptionMsg("No view shell or sidebar");
925}
926
927void hideSidebar()
928{
929 SfxViewShell* pViewShell = SfxViewShell::Current();
930 SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr;
931 if (pViewFrame)
932 pViewFrame->SetChildWindow(SID_SIDEBAR(10000 + 336), false , false );
933 else
934 SetLastExceptionMsg("No view shell or sidebar");
935}
936
937VclPtr<Window> getSidebarWindow()
938{
939 VclPtr<Window> xRet;
940
941 setupSidebar();
942 SfxViewShell* pViewShell = SfxViewShell::Current();
943 SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr;
944 if (!pViewFrame)
945 return xRet;
946
947 // really a SidebarChildWindow
948 SfxChildWindow *pChild = pViewFrame->GetChildWindow(SID_SIDEBAR(10000 + 336));
949 if (!pChild)
950 return xRet;
951
952 // really a SidebarDockingWindow
953 vcl::Window *pWin = pChild->GetWindow();
954 if (!pWin)
955 return xRet;
956 xRet = pWin;
957 return xRet;
958}
959
960} // end anonymous namespace
961
962// Could be anonymous in principle, but for the unit testing purposes, we
963// declare it in init.hxx.
964OUString desktop::extractParameter(OUString& rOptions, const OUString& rName)
965{
966 OUString aValue;
967
968 OUString aNameEquals(rName + "=");
969 OUString aCommaNameEquals("," + rName + "=");
970
971 int nIndex = -1;
972 if (rOptions.startsWith(aNameEquals))
973 {
974 size_t nLen = aNameEquals.getLength();
975 int nComma = rOptions.indexOf(",", nLen);
976 if (nComma >= 0)
977 {
978 aValue = rOptions.copy(nLen, nComma - nLen);
979 rOptions = rOptions.copy(nComma + 1);
980 }
981 else
982 {
983 aValue = rOptions.copy(nLen);
984 rOptions.clear();
985 }
986 }
987 else if ((nIndex = rOptions.indexOf(aCommaNameEquals)) >= 0)
988 {
989 size_t nLen = aCommaNameEquals.getLength();
990 int nComma = rOptions.indexOf(",", nIndex + nLen);
991 if (nComma >= 0)
992 {
993 aValue = rOptions.copy(nIndex + nLen, nComma - nIndex - nLen);
994 rOptions = rOptions.copy(0, nIndex) + rOptions.copy(nComma);
995 }
996 else
997 {
998 aValue = rOptions.copy(nIndex + nLen);
999 rOptions = rOptions.copy(0, nIndex);
1000 }
1001 }
1002
1003 return aValue;
1004}
1005
1006extern "C"
1007{
1008
1009static void doc_destroy(LibreOfficeKitDocument* pThis);
1010static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* pUrl, const char* pFormat, const char* pFilterOptions);
1011static int doc_getDocumentType(LibreOfficeKitDocument* pThis);
1012static int doc_getParts(LibreOfficeKitDocument* pThis);
1013static char* doc_getPartPageRectangles(LibreOfficeKitDocument* pThis);
1014static int doc_getPart(LibreOfficeKitDocument* pThis);
1015static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart);
1016static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect);
1017static void doc_moveSelectedParts(LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate);
1018static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart);
1019static void doc_setPartMode(LibreOfficeKitDocument* pThis, int nPartMode);
1020static void doc_paintTile(LibreOfficeKitDocument* pThis,
1021 unsigned char* pBuffer,
1022 const int nCanvasWidth, const int nCanvasHeight,
1023 const int nTilePosX, const int nTilePosY,
1024 const int nTileWidth, const int nTileHeight);
1025#ifdef IOS
1026static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
1027 void* rCGContext,
1028 const int nCanvasWidth, const int nCanvasHeight,
1029 const int nTilePosX, const int nTilePosY,
1030 const int nTileWidth, const int nTileHeight);
1031#endif
1032static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
1033 unsigned char* pBuffer,
1034 const int nPart,
1035 const int nCanvasWidth, const int nCanvasHeight,
1036 const int nTilePosX, const int nTilePosY,
1037 const int nTileWidth, const int nTileHeight);
1038static int doc_getTileMode(LibreOfficeKitDocument* pThis);
1039static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
1040 long* pWidth,
1041 long* pHeight);
1042static void doc_initializeForRendering(LibreOfficeKitDocument* pThis,
1043 const char* pArguments);
1044
1045static void doc_registerCallback(LibreOfficeKitDocument* pThis,
1046 LibreOfficeKitCallback pCallback,
1047 void* pData);
1048static void doc_postKeyEvent(LibreOfficeKitDocument* pThis,
1049 int nType,
1050 int nCharCode,
1051 int nKeyCode);
1052static void doc_postWindowExtTextInputEvent(LibreOfficeKitDocument* pThis,
1053 unsigned nWindowId,
1054 int nType,
1055 const char* pText);
1056static void doc_removeTextContext(LibreOfficeKitDocument* pThis,
1057 unsigned nLOKWindowId,
1058 int nCharBefore,
1059 int nCharAfter);
1060static void doc_sendDialogEvent(LibreOfficeKitDocument* pThis,
1061 unsigned long long int nLOKWindowId,
1062 const char* pArguments);
1063static void doc_postWindowKeyEvent(LibreOfficeKitDocument* pThis,
1064 unsigned nLOKWindowId,
1065 int nType,
1066 int nCharCode,
1067 int nKeyCode);
1068static void doc_postMouseEvent (LibreOfficeKitDocument* pThis,
1069 int nType,
1070 int nX,
1071 int nY,
1072 int nCount,
1073 int nButtons,
1074 int nModifier);
1075static void doc_postWindowMouseEvent (LibreOfficeKitDocument* pThis,
1076 unsigned nLOKWindowId,
1077 int nType,
1078 int nX,
1079 int nY,
1080 int nCount,
1081 int nButtons,
1082 int nModifier);
1083static void doc_postWindowGestureEvent(LibreOfficeKitDocument* pThis,
1084 unsigned nLOKWindowId,
1085 const char* pType,
1086 int nX,
1087 int nY,
1088 int nOffset);
1089static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
1090 const char* pCommand,
1091 const char* pArguments,
1092 bool bNotifyWhenFinished);
1093static void doc_setWindowTextSelection(LibreOfficeKitDocument* pThis,
1094 unsigned nLOKWindowId,
1095 bool swap,
1096 int nX,
1097 int nY);
1098static void doc_setTextSelection (LibreOfficeKitDocument* pThis,
1099 int nType,
1100 int nX,
1101 int nY);
1102static char* doc_getTextSelection(LibreOfficeKitDocument* pThis,
1103 const char* pMimeType,
1104 char** pUsedMimeType);
1105static int doc_getSelectionType(LibreOfficeKitDocument* pThis);
1106static int doc_getClipboard (LibreOfficeKitDocument* pThis,
1107 const char **pMimeTypes,
1108 size_t *pOutCount,
1109 char ***pOutMimeTypes,
1110 size_t **pOutSizes,
1111 char ***pOutStreams);
1112static int doc_setClipboard (LibreOfficeKitDocument* pThis,
1113 const size_t nInCount,
1114 const char **pInMimeTypes,
1115 const size_t *pInSizes,
1116 const char **pInStreams);
1117static bool doc_paste(LibreOfficeKitDocument* pThis,
1118 const char* pMimeType,
1119 const char* pData,
1120 size_t nSize);
1121static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis,
1122 int nType,
1123 int nX,
1124 int nY);
1125static void doc_resetSelection (LibreOfficeKitDocument* pThis);
1126static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand);
1127static void doc_setClientZoom(LibreOfficeKitDocument* pThis,
1128 int nTilePixelWidth,
1129 int nTilePixelHeight,
1130 int nTileTwipWidth,
1131 int nTileTwipHeight);
1132static void doc_setClientVisibleArea(LibreOfficeKitDocument* pThis, int nX, int nY, int nWidth, int nHeight);
1133static void doc_setOutlineState(LibreOfficeKitDocument* pThis, bool bColumn, int nLevel, int nIndex, bool bHidden);
1134static int doc_createView(LibreOfficeKitDocument* pThis);
1135static int doc_createViewWithOptions(LibreOfficeKitDocument* pThis, const char* pOptions);
1136static void doc_destroyView(LibreOfficeKitDocument* pThis, int nId);
1137static void doc_setView(LibreOfficeKitDocument* pThis, int nId);
1138static int doc_getView(LibreOfficeKitDocument* pThis);
1139static int doc_getViewsCount(LibreOfficeKitDocument* pThis);
1140static bool doc_getViewIds(LibreOfficeKitDocument* pThis, int* pArray, size_t nSize);
1141static void doc_setViewLanguage(LibreOfficeKitDocument* pThis, int nId, const char* language);
1142static unsigned char* doc_renderFontOrientation(LibreOfficeKitDocument* pThis,
1143 const char *pFontName,
1144 const char *pChar,
1145 int* pFontWidth,
1146 int* pFontHeight,
1147 int pOrientation);
1148static unsigned char* doc_renderFont(LibreOfficeKitDocument* pThis,
1149 const char *pFontName,
1150 const char *pChar,
1151 int* pFontWidth,
1152 int* pFontHeight);
1153static char* doc_getPartHash(LibreOfficeKitDocument* pThis, int nPart);
1154
1155static void doc_paintWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, unsigned char* pBuffer,
1156 const int nX, const int nY,
1157 const int nWidth, const int nHeight);
1158
1159static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, unsigned char* pBuffer,
1160 const int nX, const int nY,
1161 const int nWidth, const int nHeight,
1162 const double fDPIScale);
1163
1164static void doc_paintWindowForView(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, unsigned char* pBuffer,
1165 const int nX, const int nY,
1166 const int nWidth, const int nHeight,
1167 const double fDPIScale, int viewId);
1168
1169static void doc_postWindow(LibreOfficeKitDocument* pThis, unsigned
1170 nLOKWindowId, int nAction, const char* pData);
1171
1172static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart);
1173
1174static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
1175 const unsigned char* pCertificateBinary,
1176 const int nCertificateBinarySize,
1177 const unsigned char* pPrivateKeyBinary,
1178 const int nPrivateKeyBinarySize);
1179
1180static bool doc_addCertificate(LibreOfficeKitDocument* pThis,
1181 const unsigned char* pCertificateBinary,
1182 const int nCertificateBinarySize);
1183
1184static int doc_getSignatureState(LibreOfficeKitDocument* pThis);
1185
1186static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput);
1187
1188static void doc_resizeWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId,
1189 const int nWidth, const int nHeight);
1190
1191static void doc_completeFunction(LibreOfficeKitDocument* pThis, const char*);
1192
1193
1194static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis,
1195 const char* pArguments);
1196} // extern "C"
1197
1198namespace {
1199ITiledRenderable* getTiledRenderable(LibreOfficeKitDocument* pThis)
1200{
1201 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
1202 return dynamic_cast<ITiledRenderable*>(pDocument->mxComponent.get());
1203}
1204
1205#ifndef IOS
1206
1207/*
1208 * Unfortunately clipboard creation using UNO is insanely baroque.
1209 * we also need to ensure that this works for the first view which
1210 * has no clear 'createView' called for it (unfortunately).
1211 */
1212rtl::Reference<LOKClipboard> forceSetClipboardForCurrentView(LibreOfficeKitDocument *pThis)
1213{
1214 ITiledRenderable* pDoc = getTiledRenderable(pThis);
1215 rtl::Reference<LOKClipboard> xClip(LOKClipboardFactory::getClipboardForCurView());
1216
1217 SAL_INFO("lok", "Set to clipboard for view " << xClip.get())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Set to clipboard for view " << xClip.get()
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1217" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Set to clipboard for view " <<
xClip.get()), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Set to clipboard for view " <<
xClip.get(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1217" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Set to clipboard for view " << xClip.get()
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1217" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Set to clipboard for view " <<
xClip.get()), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Set to clipboard for view " <<
xClip.get(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1217" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1218 // FIXME: using a hammer here - should not be necessary if all tests used createView.
1219 pDoc->setClipboard(uno::Reference<datatransfer::clipboard::XClipboard>(xClip->getXI(), UNO_QUERY));
1220
1221 return xClip;
1222}
1223
1224#endif
1225
1226} // anonymous namespace
1227
1228LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent, int nDocumentId)
1229 : mxComponent(xComponent)
1230 , mnDocumentId(nDocumentId)
1231{
1232 m_pDocumentClass = gDocumentClass.lock();
1233 if (!m_pDocumentClass)
1234 {
1235 m_pDocumentClass = std::make_shared<LibreOfficeKitDocumentClass>();
1236
1237 m_pDocumentClass->nSize = sizeof(LibreOfficeKitDocumentClass);
1238
1239 m_pDocumentClass->destroy = doc_destroy;
1240 m_pDocumentClass->saveAs = doc_saveAs;
1241 m_pDocumentClass->getDocumentType = doc_getDocumentType;
1242 m_pDocumentClass->getParts = doc_getParts;
1243 m_pDocumentClass->getPartPageRectangles = doc_getPartPageRectangles;
1244 m_pDocumentClass->getPart = doc_getPart;
1245 m_pDocumentClass->setPart = doc_setPart;
1246 m_pDocumentClass->selectPart = doc_selectPart;
1247 m_pDocumentClass->moveSelectedParts = doc_moveSelectedParts;
1248 m_pDocumentClass->getPartName = doc_getPartName;
1249 m_pDocumentClass->setPartMode = doc_setPartMode;
1250 m_pDocumentClass->paintTile = doc_paintTile;
1251#ifdef IOS
1252 m_pDocumentClass->paintTileToCGContext = doc_paintTileToCGContext;
1253#endif
1254 m_pDocumentClass->paintPartTile = doc_paintPartTile;
1255 m_pDocumentClass->getTileMode = doc_getTileMode;
1256 m_pDocumentClass->getDocumentSize = doc_getDocumentSize;
1257 m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
1258 m_pDocumentClass->registerCallback = doc_registerCallback;
1259 m_pDocumentClass->postKeyEvent = doc_postKeyEvent;
1260 m_pDocumentClass->postWindowExtTextInputEvent = doc_postWindowExtTextInputEvent;
1261 m_pDocumentClass->removeTextContext = doc_removeTextContext;
1262 m_pDocumentClass->postWindowKeyEvent = doc_postWindowKeyEvent;
1263 m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
1264 m_pDocumentClass->postWindowMouseEvent = doc_postWindowMouseEvent;
1265 m_pDocumentClass->sendDialogEvent = doc_sendDialogEvent;
1266 m_pDocumentClass->postUnoCommand = doc_postUnoCommand;
1267 m_pDocumentClass->setTextSelection = doc_setTextSelection;
1268 m_pDocumentClass->setWindowTextSelection = doc_setWindowTextSelection;
1269 m_pDocumentClass->getTextSelection = doc_getTextSelection;
1270 m_pDocumentClass->getSelectionType = doc_getSelectionType;
1271 m_pDocumentClass->getClipboard = doc_getClipboard;
1272 m_pDocumentClass->setClipboard = doc_setClipboard;
1273 m_pDocumentClass->paste = doc_paste;
1274 m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection;
1275 m_pDocumentClass->resetSelection = doc_resetSelection;
1276 m_pDocumentClass->getCommandValues = doc_getCommandValues;
1277 m_pDocumentClass->setClientZoom = doc_setClientZoom;
1278 m_pDocumentClass->setClientVisibleArea = doc_setClientVisibleArea;
1279 m_pDocumentClass->setOutlineState = doc_setOutlineState;
1280
1281 m_pDocumentClass->createView = doc_createView;
1282 m_pDocumentClass->destroyView = doc_destroyView;
1283 m_pDocumentClass->setView = doc_setView;
1284 m_pDocumentClass->getView = doc_getView;
1285 m_pDocumentClass->getViewsCount = doc_getViewsCount;
1286 m_pDocumentClass->getViewIds = doc_getViewIds;
1287
1288 m_pDocumentClass->renderFont = doc_renderFont;
1289 m_pDocumentClass->renderFontOrientation = doc_renderFontOrientation;
1290 m_pDocumentClass->getPartHash = doc_getPartHash;
1291
1292 m_pDocumentClass->paintWindow = doc_paintWindow;
1293 m_pDocumentClass->paintWindowDPI = doc_paintWindowDPI;
1294 m_pDocumentClass->paintWindowForView = doc_paintWindowForView;
1295 m_pDocumentClass->postWindow = doc_postWindow;
1296 m_pDocumentClass->resizeWindow = doc_resizeWindow;
1297
1298 m_pDocumentClass->setViewLanguage = doc_setViewLanguage;
1299
1300 m_pDocumentClass->getPartInfo = doc_getPartInfo;
1301
1302 m_pDocumentClass->insertCertificate = doc_insertCertificate;
1303 m_pDocumentClass->addCertificate = doc_addCertificate;
1304 m_pDocumentClass->getSignatureState = doc_getSignatureState;
1305
1306 m_pDocumentClass->renderShapeSelection = doc_renderShapeSelection;
1307 m_pDocumentClass->postWindowGestureEvent = doc_postWindowGestureEvent;
1308
1309 m_pDocumentClass->createViewWithOptions = doc_createViewWithOptions;
1310 m_pDocumentClass->completeFunction = doc_completeFunction;
1311
1312 m_pDocumentClass->sendFormFieldEvent = doc_sendFormFieldEvent;
1313
1314 gDocumentClass = m_pDocumentClass;
1315 }
1316 pClass = m_pDocumentClass.get();
1317
1318#ifndef IOS
1319 forceSetClipboardForCurrentView(this);
1320#endif
1321}
1322
1323LibLODocument_Impl::~LibLODocument_Impl()
1324{
1325 try
1326 {
1327 mxComponent->dispose();
1328 }
1329 catch (const css::lang::DisposedException&)
1330 {
1331 TOOLS_WARN_EXCEPTION("lok", "failed to dispose document")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "failed to dispose document" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1331" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "failed to dispose document" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "failed to dispose document" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1331" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "failed to dispose document" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1331" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "failed to dispose document" <<
" " << exceptionToString(tools_warn_exception)), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "failed to dispose document" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1331" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1332 }
1333}
1334
1335static OUString getGenerator()
1336{
1337 OUString sGenerator(
1338 Translate::ExpandVariables("%PRODUCTNAME %PRODUCTVERSION%PRODUCTEXTENSION (%1)"));
1339 OUString os("$_OS");
1340 ::rtl::Bootstrap::expandMacros(os);
1341 return sGenerator.replaceFirst("%1", os);
1342}
1343
1344extern "C" {
1345
1346CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, LibreOfficeKitCallback pCallback, void* pData)
1347 : Idle( "lokit timer callback" ),
1348 m_pDocument(pDocument),
1349 m_pCallback(pCallback),
1350 m_pData(pData),
1351 m_nDisableCallbacks(0)
1352{
1353 SetPriority(TaskPriority::POST_PAINT);
1354
1355 // Add the states that are safe to skip duplicates on, even when
1356 // not consequent (i.e. do no emit them if unchanged from last).
1357 m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL");
1358 m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL");
1359 m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL");
1360 m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL");
1361 m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL");
1362 m_states.emplace(LOK_CALLBACK_CELL_CURSOR, "NIL");
1363 m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL");
1364 m_states.emplace(LOK_CALLBACK_CELL_ADDRESS, "NIL");
1365 m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL");
1366 m_states.emplace(LOK_CALLBACK_SET_PART, "NIL");
1367
1368 Start();
1369}
1370
1371CallbackFlushHandler::~CallbackFlushHandler()
1372{
1373 Stop();
1374}
1375
1376void CallbackFlushHandler::callback(const int type, const char* payload, void* data)
1377{
1378 CallbackFlushHandler* self = static_cast<CallbackFlushHandler*>(data);
1379 if (self)
1380 {
1381 self->queue(type, payload);
1382 }
1383}
1384
1385void CallbackFlushHandler::queue(const int type, const char* data)
1386{
1387 comphelper::ProfileZone aZone("CallbackFlushHandler::queue");
1388
1389 CallbackData aCallbackData(type, (data ? data : "(nil)"));
1390 const std::string& payload = aCallbackData.PayloadString;
1391 SAL_INFO("lok", "Queue: [" << type << "]: [" << payload << "] on " << m_queue.size() << " entries.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Queue: [" << type << "]: [" <<
payload << "] on " << m_queue.size() << " entries."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1391" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Queue: [" << type << "]: ["
<< payload << "] on " << m_queue.size() <<
" entries."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Queue: [" << type <<
"]: [" << payload << "] on " << m_queue.size
() << " entries."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1391" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Queue: [" << type << "]: [" <<
payload << "] on " << m_queue.size() << " entries."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1391" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Queue: [" << type << "]: ["
<< payload << "] on " << m_queue.size() <<
" entries."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Queue: [" << type <<
"]: [" << payload << "] on " << m_queue.size
() << " entries."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1391" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1392
1393 bool bIsChartActive = false;
1394 if (type == LOK_CALLBACK_GRAPHIC_SELECTION)
1395 {
1396 LokChartHelper aChartHelper(SfxViewShell::Current());
1397 bIsChartActive = aChartHelper.GetWindow() != nullptr;
1398 }
1399
1400 if (callbacksDisabled() && !bIsChartActive)
1401 {
1402 // We drop notifications when this is set, except for important ones.
1403 // When we issue a complex command (such as .uno:InsertAnnotation)
1404 // there will be multiple notifications. On the first invalidation
1405 // we will start painting, but other events will get fired
1406 // while the complex command in question executes.
1407 // We don't want to suppress everything here on the wrong assumption
1408 // that no new events are fired during painting.
1409 if (type != LOK_CALLBACK_STATE_CHANGED &&
1410 type != LOK_CALLBACK_INVALIDATE_TILES &&
1411 type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1412 type != LOK_CALLBACK_CURSOR_VISIBLE &&
1413 type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE &&
1414 type != LOK_CALLBACK_TEXT_SELECTION &&
1415 type != LOK_CALLBACK_TEXT_SELECTION_START &&
1416 type != LOK_CALLBACK_TEXT_SELECTION_END &&
1417 type != LOK_CALLBACK_REFERENCE_MARKS)
1418 {
1419 SAL_INFO("lok", "Skipping while painting [" << type << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping while painting [" << type <<
"]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1419" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping while painting [" <<
type << "]: [" << payload << "]."), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping while painting [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1419" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping while painting [" << type <<
"]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1419" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping while painting [" <<
type << "]: [" << payload << "]."), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping while painting [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1419" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1420 return;
1421 }
1422
1423 // In Writer we drop all notifications during painting.
1424 if (doc_getDocumentType(m_pDocument) == LOK_DOCTYPE_TEXT)
1425 return;
1426 }
1427
1428 // Suppress invalid payloads.
1429 if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1430 payload.find(", 0, 0, ") != std::string::npos)
1431 {
1432 // The cursor position is often the relative coordinates of the widget
1433 // issuing it, instead of the absolute one that we expect.
1434 // This is temporary however, and, once the control is created and initialized
1435 // correctly, it eventually emits the correct absolute coordinates.
1436 SAL_INFO("lok", "Skipping invalid event [" << type << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping invalid event [" << type <<
"]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1436" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping invalid event [" << type
<< "]: [" << payload << "]."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping invalid event [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1436" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping invalid event [" << type <<
"]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1436" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping invalid event [" << type
<< "]: [" << payload << "]."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping invalid event [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1436" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1437 return;
1438 }
1439
1440 std::unique_lock<std::mutex> lock(m_mutex);
1441
1442 // drop duplicate callbacks for the listed types
1443 switch (type)
1444 {
1445 case LOK_CALLBACK_TEXT_SELECTION_START:
1446 case LOK_CALLBACK_TEXT_SELECTION_END:
1447 case LOK_CALLBACK_TEXT_SELECTION:
1448 case LOK_CALLBACK_GRAPHIC_SELECTION:
1449 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1450 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1451 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1452 case LOK_CALLBACK_STATE_CHANGED:
1453 case LOK_CALLBACK_MOUSE_POINTER:
1454 case LOK_CALLBACK_CELL_CURSOR:
1455 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1456 case LOK_CALLBACK_CELL_FORMULA:
1457 case LOK_CALLBACK_CELL_ADDRESS:
1458 case LOK_CALLBACK_CURSOR_VISIBLE:
1459 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1460 case LOK_CALLBACK_SET_PART:
1461 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1462 case LOK_CALLBACK_INVALIDATE_HEADER:
1463 case LOK_CALLBACK_WINDOW:
1464 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1465 case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
1466 {
1467 const auto& pos = std::find_if(m_queue.rbegin(), m_queue.rend(),
1468 [type] (const queue_type::value_type& elem) { return (elem.Type == type); });
1469
1470 if (pos != m_queue.rend() && pos->PayloadString == payload)
1471 {
1472 SAL_INFO("lok", "Skipping queue duplicate [" << type << + "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue duplicate [" << type <<
+ "]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1472" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue duplicate [" <<
type << + "]: [" << payload << "]."), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue duplicate [" << type <<
+ "]: [" << payload << "]."; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1472" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue duplicate [" << type <<
+ "]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1472" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue duplicate [" <<
type << + "]: [" << payload << "]."), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue duplicate [" << type <<
+ "]: [" << payload << "]."; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1472" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1473 return;
1474 }
1475 }
1476 break;
1477 }
1478
1479 if (type == LOK_CALLBACK_TEXT_SELECTION && payload.empty())
1480 {
1481 const auto& posStart = std::find_if(m_queue.rbegin(), m_queue.rend(),
1482 [] (const queue_type::value_type& elem) { return (elem.Type == LOK_CALLBACK_TEXT_SELECTION_START); });
1483 if (posStart != m_queue.rend())
1484 posStart->PayloadString.clear();
1485
1486 const auto& posEnd = std::find_if(m_queue.rbegin(), m_queue.rend(),
1487 [] (const queue_type::value_type& elem) { return (elem.Type == LOK_CALLBACK_TEXT_SELECTION_END); });
1488 if (posEnd != m_queue.rend())
1489 posEnd->PayloadString.clear();
1490 }
1491
1492 // When payload is empty discards any previous state.
1493 if (payload.empty())
1494 {
1495 switch (type)
1496 {
1497 case LOK_CALLBACK_TEXT_SELECTION_START:
1498 case LOK_CALLBACK_TEXT_SELECTION_END:
1499 case LOK_CALLBACK_TEXT_SELECTION:
1500 case LOK_CALLBACK_GRAPHIC_SELECTION:
1501 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1502 case LOK_CALLBACK_INVALIDATE_TILES:
1503 if (removeAll(
1504 [type](const queue_type::value_type& elem) { return (elem.Type == type); }))
1505 SAL_INFO("lok", "Removed dups of [" << type << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Removed dups of [" << type << "]: ["
<< payload << "].") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1505" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Removed dups of [" << type <<
"]: [" << payload << "]."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Removed dups of ["
<< type << "]: [" << payload << "]."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1505" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Removed dups of [" << type << "]: ["
<< payload << "].") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1505" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Removed dups of [" << type <<
"]: [" << payload << "]."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Removed dups of ["
<< type << "]: [" << payload << "]."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1505" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1506 break;
1507 }
1508 }
1509 else
1510 {
1511 switch (type)
1512 {
1513 // These are safe to use the latest state and ignore previous
1514 // ones (if any) since the last overrides previous ones.
1515 case LOK_CALLBACK_TEXT_SELECTION_START:
1516 case LOK_CALLBACK_TEXT_SELECTION_END:
1517 case LOK_CALLBACK_TEXT_SELECTION:
1518 case LOK_CALLBACK_MOUSE_POINTER:
1519 case LOK_CALLBACK_CELL_CURSOR:
1520 case LOK_CALLBACK_CELL_FORMULA:
1521 case LOK_CALLBACK_CELL_ADDRESS:
1522 case LOK_CALLBACK_CURSOR_VISIBLE:
1523 case LOK_CALLBACK_SET_PART:
1524 case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
1525 case LOK_CALLBACK_RULER_UPDATE:
1526 {
1527 if (removeAll(
1528 [type](const queue_type::value_type& elem) { return (elem.Type == type); }))
1529 SAL_INFO("lok", "Removed dups of [" << type << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Removed dups of [" << type << "]: ["
<< payload << "].") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1529" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Removed dups of [" << type <<
"]: [" << payload << "]."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Removed dups of ["
<< type << "]: [" << payload << "]."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1529" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Removed dups of [" << type << "]: ["
<< payload << "].") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1529" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Removed dups of [" << type <<
"]: [" << payload << "]."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Removed dups of ["
<< type << "]: [" << payload << "]."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1529" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1530 }
1531 break;
1532
1533 // These are safe to use the latest state and ignore previous
1534 // ones (if any) since the last overrides previous ones,
1535 // but only if the view is the same.
1536 case LOK_CALLBACK_CELL_VIEW_CURSOR:
1537 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
1538 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
1539 case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
1540 case LOK_CALLBACK_TEXT_VIEW_SELECTION:
1541 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
1542 case LOK_CALLBACK_CALC_FUNCTION_LIST:
1543 case LOK_CALLBACK_JSDIALOG:
1544 {
1545 // deleting the duplicate of visible cursor message can cause hyperlink popup not to show up on second/or more click on the same place.
1546 // If the hyperlink is not empty we can bypass that to show the popup
1547 const bool hyperLinkException = type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
1548 payload.find("\"hyperlink\":\"\"") == std::string::npos &&
1549 payload.find("\"hyperlink\": {}") == std::string::npos;
1550 const int nViewId = lcl_getViewId(payload);
1551 removeAll(
1552 [type, nViewId, hyperLinkException] (const queue_type::value_type& elem) {
1553 return (elem.Type == type && nViewId == lcl_getViewId(elem) && !hyperLinkException);
1554 }
1555 );
1556 }
1557 break;
1558
1559 case LOK_CALLBACK_INVALIDATE_TILES:
1560 if (processInvalidateTilesEvent(aCallbackData))
1561 return;
1562 break;
1563
1564 // State changes with same name override previous ones with a different value.
1565 // Ex. ".uno:PageStatus=Slide 20 of 83" overwrites any previous PageStatus.
1566 case LOK_CALLBACK_STATE_CHANGED:
1567 {
1568 // Compare the state name=value and overwrite earlier entries with same name.
1569 const auto pos = payload.find('=');
1570 if (pos != std::string::npos)
1571 {
1572 const std::string name = payload.substr(0, pos + 1);
1573 // This is needed because otherwise it creates some problems when
1574 // a save occurs while a cell is still edited in Calc.
1575 if (name != ".uno:ModifiedStatus=")
1576 {
1577 removeAll(
1578 [type, &name] (const queue_type::value_type& elem) {
1579 return (elem.Type == type) && (elem.PayloadString.compare(0, name.size(), name) == 0);
1580 }
1581 );
1582 }
1583 }
1584 }
1585 break;
1586
1587 case LOK_CALLBACK_WINDOW:
1588 if (processWindowEvent(aCallbackData))
1589 return;
1590 break;
1591
1592 case LOK_CALLBACK_GRAPHIC_SELECTION:
1593 {
1594 // remove only selection ranges and 'EMPTY' messages
1595 // always send 'INPLACE' and 'INPLACE EXIT' messages
1596 removeAll([type, payload] (const queue_type::value_type& elem)
1597 { return (elem.Type == type && elem.PayloadString[0] != 'I'); });
1598 }
1599 break;
1600 }
1601 }
1602
1603 // Validate that the cached data and the payload string are identical.
1604 assert(aCallbackData.validate() && "Cached callback payload object and string mismatch!")(static_cast <bool> (aCallbackData.validate() &&
"Cached callback payload object and string mismatch!") ? void
(0) : __assert_fail ("aCallbackData.validate() && \"Cached callback payload object and string mismatch!\""
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 1604, __extension__ __PRETTY_FUNCTION__))
;
1605 m_queue.emplace_back(aCallbackData);
1606 SAL_INFO("lok", "Queued #" << (m_queue.size() - 1) <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Queued #" << (m_queue.size() - 1) <<
" [" << type << "]: [" << payload <<
"] to have " << m_queue.size() << " entries.") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Queued #" << (m_queue.size() -
1) << " [" << type << "]: [" << payload
<< "] to have " << m_queue.size() << " entries."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Queued #" << (m_queue.size() - 1) << " ["
<< type << "]: [" << payload << "] to have "
<< m_queue.size() << " entries."; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Queued #" << (m_queue.size() - 1) <<
" [" << type << "]: [" << payload <<
"] to have " << m_queue.size() << " entries.") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Queued #" << (m_queue.size() -
1) << " [" << type << "]: [" << payload
<< "] to have " << m_queue.size() << " entries."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Queued #" << (m_queue.size() - 1) << " ["
<< type << "]: [" << payload << "] to have "
<< m_queue.size() << " entries."; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1607 " [" << type << "]: [" << payload << "] to have " << m_queue.size() << " entries.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Queued #" << (m_queue.size() - 1) <<
" [" << type << "]: [" << payload <<
"] to have " << m_queue.size() << " entries.") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Queued #" << (m_queue.size() -
1) << " [" << type << "]: [" << payload
<< "] to have " << m_queue.size() << " entries."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Queued #" << (m_queue.size() - 1) << " ["
<< type << "]: [" << payload << "] to have "
<< m_queue.size() << " entries."; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Queued #" << (m_queue.size() - 1) <<
" [" << type << "]: [" << payload <<
"] to have " << m_queue.size() << " entries.") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Queued #" << (m_queue.size() -
1) << " [" << type << "]: [" << payload
<< "] to have " << m_queue.size() << " entries."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Queued #" << (m_queue.size() - 1) << " ["
<< type << "]: [" << payload << "] to have "
<< m_queue.size() << " entries."; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1607" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1608
1609#ifdef DBG_UTIL
1610 {
1611 // Dump the queue state and validate cached data.
1612 int i = 1;
1613 std::ostringstream oss;
1614 if (m_queue.empty())
1615 oss << "Empty";
1616 else
1617 oss << m_queue.size() << " items\n";
1618 for (const CallbackData& c : m_queue)
1619 oss << i++ << ": [" << c.Type << "] [" << c.PayloadString << "].\n";
1620 SAL_INFO("lok", "Current Queue: " << oss.str())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Current Queue: " << oss.str()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1620" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Current Queue: " << oss.str()
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Current Queue: " << oss.str(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1620" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Current Queue: " << oss.str()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1620" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Current Queue: " << oss.str()
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Current Queue: " << oss.str(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1620" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1621 assert((static_cast <bool> (std::all_of( m_queue.begin(), m_queue
.end(), [](const CallbackData& c) { return c.validate(); }
)) ? void (0) : __assert_fail ("std::all_of( m_queue.begin(), m_queue.end(), [](const CallbackData& c) { return c.validate(); })"
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 1624, __extension__ __PRETTY_FUNCTION__))
1622 std::all_of((static_cast <bool> (std::all_of( m_queue.begin(), m_queue
.end(), [](const CallbackData& c) { return c.validate(); }
)) ? void (0) : __assert_fail ("std::all_of( m_queue.begin(), m_queue.end(), [](const CallbackData& c) { return c.validate(); })"
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 1624, __extension__ __PRETTY_FUNCTION__))
1623 m_queue.begin(), m_queue.end(),(static_cast <bool> (std::all_of( m_queue.begin(), m_queue
.end(), [](const CallbackData& c) { return c.validate(); }
)) ? void (0) : __assert_fail ("std::all_of( m_queue.begin(), m_queue.end(), [](const CallbackData& c) { return c.validate(); })"
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 1624, __extension__ __PRETTY_FUNCTION__))
1624 [](const CallbackData& c) { return c.validate(); }))(static_cast <bool> (std::all_of( m_queue.begin(), m_queue
.end(), [](const CallbackData& c) { return c.validate(); }
)) ? void (0) : __assert_fail ("std::all_of( m_queue.begin(), m_queue.end(), [](const CallbackData& c) { return c.validate(); })"
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 1624, __extension__ __PRETTY_FUNCTION__))
;
1625 }
1626#endif
1627
1628 lock.unlock();
1629 if (!IsActive())
1630 {
1631 Start();
1632 }
1633}
1634
1635bool CallbackFlushHandler::processInvalidateTilesEvent(CallbackData& aCallbackData)
1636{
1637 const std::string& payload = aCallbackData.PayloadString;
1638 const int type = aCallbackData.Type;
1639
1640 RectangleAndPart& rcNew = aCallbackData.setRectangleAndPart(payload);
1641 if (rcNew.isEmpty())
1642 {
1643 SAL_INFO("lok", "Skipping invalid event [" << type << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping invalid event [" << type <<
"]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1643" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping invalid event [" << type
<< "]: [" << payload << "]."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping invalid event [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1643" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping invalid event [" << type <<
"]: [" << payload << "].") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1643" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping invalid event [" << type
<< "]: [" << payload << "]."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping invalid event [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1643" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1644 return true;
1645 }
1646
1647 // If we have to invalidate all tiles, we can skip any new tile invalidation.
1648 // Find the last INVALIDATE_TILES entry, if any to see if it's invalidate-all.
1649 const auto& pos
1650 = std::find_if(m_queue.rbegin(), m_queue.rend(), [](const queue_type::value_type& elem) {
1651 return (elem.Type == LOK_CALLBACK_INVALIDATE_TILES);
1652 });
1653 if (pos != m_queue.rend())
1654 {
1655 const RectangleAndPart& rcOld = pos->getRectangleAndPart();
1656 if (rcOld.isInfinite() && (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart))
1657 {
1658 SAL_INFO("lok", "Skipping queue [" << type << "]: [" << payloaddo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since all tiles need to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since all tiles need to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1659 << "] since all tiles need to be invalidated.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since all tiles need to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since all tiles need to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since all tiles need to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1659" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1660 return true;
1661 }
1662
1663 if (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart)
1664 {
1665 // If fully overlapping.
1666 if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
1667 {
1668 SAL_INFO("lok", "Skipping queue [" << type << "]: [" << payloaddo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts.") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since overlaps existing all-parts."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts."; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts.") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since overlaps existing all-parts."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts."; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1669 << "] since overlaps existing all-parts.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts.") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since overlaps existing all-parts."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts."; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts.") == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since overlaps existing all-parts."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since overlaps existing all-parts."; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1669" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1670 return true;
1671 }
1672 }
1673 }
1674
1675 if (rcNew.isInfinite())
1676 {
1677 SAL_INFO("lok", "Have Empty [" << type << "]: [" << payloaddo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Have Empty [" << type << "]: [" <<
payload << "] so removing all with part " << rcNew
.m_nPart << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Have Empty [" << type <<
"]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Have Empty ["
<< type << "]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Have Empty [" << type << "]: [" <<
payload << "] so removing all with part " << rcNew
.m_nPart << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Have Empty [" << type <<
"]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Have Empty ["
<< type << "]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1678 << "] so removing all with part " << rcNew.m_nPart << ".")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Have Empty [" << type << "]: [" <<
payload << "] so removing all with part " << rcNew
.m_nPart << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Have Empty [" << type <<
"]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Have Empty ["
<< type << "]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Have Empty [" << type << "]: [" <<
payload << "] so removing all with part " << rcNew
.m_nPart << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Have Empty [" << type <<
"]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Have Empty ["
<< type << "]: [" << payload << "] so removing all with part "
<< rcNew.m_nPart << "."; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1678" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1679 removeAll([&rcNew](const queue_type::value_type& elem) {
1680 if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
1681 {
1682 // Remove exiting if new is all-encompassing, or if of the same part.
1683 const RectangleAndPart rcOld = RectangleAndPart::Create(elem.PayloadString);
1684 return (rcNew.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart);
1685 }
1686
1687 // Keep others.
1688 return false;
1689 });
1690 }
1691 else
1692 {
1693 const auto rcOrig = rcNew;
1694
1695 SAL_INFO("lok", "Have [" << type << "]: [" << payload << "] so merging overlapping.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Have [" << type << "]: [" << payload
<< "] so merging overlapping.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1695" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Have [" << type << "]: ["
<< payload << "] so merging overlapping."), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Have [" << type << "]: [" << payload
<< "] so merging overlapping."; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1695" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Have [" << type << "]: [" << payload
<< "] so merging overlapping.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1695" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Have [" << type << "]: ["
<< payload << "] so merging overlapping."), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Have [" << type << "]: [" << payload
<< "] so merging overlapping."; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1695" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1696 removeAll([&rcNew](const queue_type::value_type& elem) {
1697 if (elem.Type == LOK_CALLBACK_INVALIDATE_TILES)
1698 {
1699 const RectangleAndPart& rcOld = elem.getRectangleAndPart();
1700 if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && rcOld.m_nPart != rcNew.m_nPart)
1701 {
1702 SAL_INFO("lok", "Nothing to merge between new: "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString()) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Nothing to merge between new: " <<
rcNew.toString() << ", and old: " << rcOld.toString
()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString()) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Nothing to merge between new: " <<
rcNew.toString() << ", and old: " << rcOld.toString
()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1703 << rcNew.toString() << ", and old: " << rcOld.toString())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString()) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Nothing to merge between new: " <<
rcNew.toString() << ", and old: " << rcOld.toString
()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString()) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Nothing to merge between new: " <<
rcNew.toString() << ", and old: " << rcOld.toString
()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Nothing to merge between new: " << rcNew.toString
() << ", and old: " << rcOld.toString(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1703" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1704 return false;
1705 }
1706
1707 if (rcNew.m_nPart == -1)
1708 {
1709 // Don't merge unless fully overlapped.
1710 SAL_INFO("lok", "New " << rcNew.toString() << " has " << rcOld.toString()do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " has "
<< rcOld.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" has " << rcOld.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"New " << rcNew.toString() << " has " << rcOld
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " has "
<< rcOld.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" has " << rcOld.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"New " << rcNew.toString() << " has " << rcOld
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1711 << "?")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " has "
<< rcOld.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" has " << rcOld.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"New " << rcNew.toString() << " has " << rcOld
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " has "
<< rcOld.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" has " << rcOld.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"New " << rcNew.toString() << " has " << rcOld
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1711" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1712 if (rcNew.m_aRectangle.IsInside(rcOld.m_aRectangle))
1713 {
1714 SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1715 << rcOld.toString() << ".")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1715" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1716 return true;
1717 }
1718 }
1719 else if (rcOld.m_nPart == -1)
1720 {
1721 // Don't merge unless fully overlapped.
1722 SAL_INFO("lok", "Old " << rcOld.toString() << " has " << rcNew.toString()do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old " << rcOld.toString() << " has "
<< rcNew.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old " << rcOld.toString() <<
" has " << rcNew.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Old " << rcOld.toString() << " has " << rcNew
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old " << rcOld.toString() << " has "
<< rcNew.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old " << rcOld.toString() <<
" has " << rcNew.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Old " << rcOld.toString() << " has " << rcNew
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1723 << "?")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old " << rcOld.toString() << " has "
<< rcNew.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old " << rcOld.toString() <<
" has " << rcNew.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Old " << rcOld.toString() << " has " << rcNew
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old " << rcOld.toString() << " has "
<< rcNew.toString() << "?") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old " << rcOld.toString() <<
" has " << rcNew.toString() << "?"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Old " << rcOld.toString() << " has " << rcNew
.toString() << "?"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1723" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1724 if (rcOld.m_aRectangle.IsInside(rcNew.m_aRectangle))
1725 {
1726 SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1727 << rcOld.toString() << ".")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New " << rcNew.toString() <<
" engulfs old " << rcOld.toString() << "."), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << "."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1727" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1728 return true;
1729 }
1730 }
1731 else
1732 {
1733 const tools::Rectangle rcOverlap
1734 = rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle);
1735 const bool bOverlap = !rcOverlap.IsEmpty();
1736 SAL_INFO("lok", "Merging " << rcNew.toString() << " & " << rcOld.toString()do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging " << rcNew.toString() << " & "
<< rcOld.toString() << " => " << rcOverlap
.toString() << " Overlap: " << bOverlap) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging " << rcNew.toString()
<< " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Merging " << rcNew.toString
() << " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO),
("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging " << rcNew.toString() << " & "
<< rcOld.toString() << " => " << rcOverlap
.toString() << " Overlap: " << bOverlap) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging " << rcNew.toString()
<< " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Merging " << rcNew.toString
() << " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO),
("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1737 << " => " << rcOverlap.toString()do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging " << rcNew.toString() << " & "
<< rcOld.toString() << " => " << rcOverlap
.toString() << " Overlap: " << bOverlap) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging " << rcNew.toString()
<< " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Merging " << rcNew.toString
() << " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO),
("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging " << rcNew.toString() << " & "
<< rcOld.toString() << " => " << rcOverlap
.toString() << " Overlap: " << bOverlap) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging " << rcNew.toString()
<< " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Merging " << rcNew.toString
() << " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO),
("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1738 << " Overlap: " << bOverlap)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging " << rcNew.toString() << " & "
<< rcOld.toString() << " => " << rcOverlap
.toString() << " Overlap: " << bOverlap) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging " << rcNew.toString()
<< " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Merging " << rcNew.toString
() << " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO),
("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging " << rcNew.toString() << " & "
<< rcOld.toString() << " => " << rcOverlap
.toString() << " Overlap: " << bOverlap) == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging " << rcNew.toString()
<< " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Merging " << rcNew.toString
() << " & " << rcOld.toString() << " => "
<< rcOverlap.toString() << " Overlap: " <<
bOverlap; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO),
("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1738" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1739 if (bOverlap)
1740 {
1741 rcNew.m_aRectangle.Union(rcOld.m_aRectangle);
1742 SAL_INFO("lok", "Merged: " << rcNew.toString())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merged: " << rcNew.toString()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1742" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merged: " << rcNew.toString()
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merged: " << rcNew.toString(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1742" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merged: " << rcNew.toString()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1742" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merged: " << rcNew.toString()
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merged: " << rcNew.toString(); ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1742" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1743 return true;
1744 }
1745 }
1746 }
1747
1748 // Keep others.
1749 return false;
1750 });
1751
1752 if (rcNew.m_aRectangle != rcOrig.m_aRectangle)
1753 {
1754 SAL_INFO("lok", "Replacing: " << rcOrig.toString() << " by " << rcNew.toString())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Replacing: " << rcOrig.toString() <<
" by " << rcNew.toString()) == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1754" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Replacing: " << rcOrig.toString
() << " by " << rcNew.toString()), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"Replacing: " << rcOrig.toString() << " by " <<
rcNew.toString(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1754" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Replacing: " << rcOrig.toString() <<
" by " << rcNew.toString()) == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1754" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Replacing: " << rcOrig.toString
() << " by " << rcNew.toString()), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"Replacing: " << rcOrig.toString() << " by " <<
rcNew.toString(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1754" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1755 if (rcNew.m_aRectangle.GetWidth() < rcOrig.m_aRectangle.GetWidth()
1756 || rcNew.m_aRectangle.GetHeight() < rcOrig.m_aRectangle.GetHeight())
1757 {
1758 SAL_WARN("lok", "Error: merged rect smaller.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Error: merged rect smaller.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1758" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Error: merged rect smaller."), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Error: merged rect smaller."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1758" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Error: merged rect smaller.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1758" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Error: merged rect smaller."), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Error: merged rect smaller."; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1758" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1759 }
1760 }
1761 }
1762
1763 aCallbackData.setRectangleAndPart(rcNew);
1764 // Queue this one.
1765 return false;
1766}
1767
1768bool CallbackFlushHandler::processWindowEvent(CallbackData& aCallbackData)
1769{
1770 const std::string& payload = aCallbackData.PayloadString;
1771 const int type = aCallbackData.Type;
1772
1773 boost::property_tree::ptree& aTree = aCallbackData.setJson(payload);
1774 const unsigned nLOKWindowId = aTree.get<unsigned>("id", 0);
1775 const std::string aAction = aTree.get<std::string>("action", "");
1776 if (aAction == "invalidate")
1777 {
1778 std::string aRectStr = aTree.get<std::string>("rectangle", "");
1779 // no 'rectangle' field => invalidate all of the window =>
1780 // remove all previous window part invalidations
1781 if (aRectStr.empty())
1782 {
1783 removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
1784 if (elem.Type == LOK_CALLBACK_WINDOW)
1785 {
1786 const boost::property_tree::ptree& aOldTree = elem.getJson();
1787 if (nLOKWindowId == aOldTree.get<unsigned>("id", 0)
1788 && aOldTree.get<std::string>("action", "") == "invalidate")
1789 {
1790 return true;
1791 }
1792 }
1793 return false;
1794 });
1795 }
1796 else
1797 {
1798 // if we have to invalidate all of the window, ignore
1799 // any part invalidation message
1800 const auto invAllExist = std::any_of(m_queue.rbegin(), m_queue.rend(),
1801 [&nLOKWindowId] (const queue_type::value_type& elem)
1802 {
1803 if (elem.Type != LOK_CALLBACK_WINDOW)
1804 return false;
1805
1806 const boost::property_tree::ptree& aOldTree = elem.getJson();
1807 return nLOKWindowId == aOldTree.get<unsigned>("id", 0)
1808 && aOldTree.get<std::string>("action", "") == "invalidate"
1809 && aOldTree.get<std::string>("rectangle", "").empty();
1810 });
1811
1812 // we found a invalidate-all window callback
1813 if (invAllExist)
1814 {
1815 SAL_INFO("lok.dialog", "Skipping queue ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Skipping queue [" <<
type << "]: [" << payload << "] since whole window needs to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since whole window needs to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since whole window needs to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1816 << type << "]: [" << payloaddo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Skipping queue [" <<
type << "]: [" << payload << "] since whole window needs to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since whole window needs to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since whole window needs to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1817 << "] since whole window needs to be invalidated.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Skipping queue [" <<
type << "]: [" << payload << "] since whole window needs to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since whole window needs to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping queue [" << type <<
"]: [" << payload << "] since whole window needs to be invalidated."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Skipping queue [" << type << "]: [" <<
payload << "] since whole window needs to be invalidated."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1817" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1818 return true;
1819 }
1820
1821 std::istringstream aRectStream(aRectStr);
1822 long nLeft, nTop, nWidth, nHeight;
1823 char nComma;
1824 aRectStream >> nLeft >> nComma >> nTop >> nComma >> nWidth >> nComma >> nHeight;
1825 tools::Rectangle aNewRect(nLeft, nTop, nLeft + nWidth, nTop + nHeight);
1826 bool currentIsRedundant = false;
1827 removeAll([&aNewRect, &nLOKWindowId,
1828 &currentIsRedundant](const queue_type::value_type& elem) {
1829 if (elem.Type != LOK_CALLBACK_WINDOW)
1830 return false;
1831
1832 const boost::property_tree::ptree& aOldTree = elem.getJson();
1833 if (aOldTree.get<std::string>("action", "") == "invalidate")
1834 {
1835 // Not possible that we encounter an empty rectangle here; we already handled this case above.
1836 std::istringstream aOldRectStream(aOldTree.get<std::string>("rectangle", ""));
1837 long nOldLeft, nOldTop, nOldWidth, nOldHeight;
1838 char nOldComma;
1839 aOldRectStream >> nOldLeft >> nOldComma >> nOldTop >> nOldComma >> nOldWidth
1840 >> nOldComma >> nOldHeight;
1841 const tools::Rectangle aOldRect = tools::Rectangle(
1842 nOldLeft, nOldTop, nOldLeft + nOldWidth, nOldTop + nOldHeight);
1843
1844 if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
1845 {
1846 if (aNewRect == aOldRect)
1847 {
1848 SAL_INFO("lok.dialog", "Duplicate rect [" << aNewRect.toString()do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Duplicate rect [" <<
aNewRect.toString() << "]. Skipping new.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Duplicate rect [" << aNewRect
.toString() << "]. Skipping new."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Duplicate rect ["
<< aNewRect.toString() << "]. Skipping new."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Duplicate rect [" << aNewRect.toString() <<
"]. Skipping new.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Duplicate rect [" << aNewRect
.toString() << "]. Skipping new."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Duplicate rect ["
<< aNewRect.toString() << "]. Skipping new."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1849 << "]. Skipping new.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Duplicate rect [" <<
aNewRect.toString() << "]. Skipping new.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Duplicate rect [" << aNewRect
.toString() << "]. Skipping new."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Duplicate rect ["
<< aNewRect.toString() << "]. Skipping new."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Duplicate rect [" << aNewRect.toString() <<
"]. Skipping new.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Duplicate rect [" << aNewRect
.toString() << "]. Skipping new."), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "Duplicate rect ["
<< aNewRect.toString() << "]. Skipping new."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1849" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1850 // We have a rectangle in the queue already that makes the current Callback useless.
1851 currentIsRedundant = true;
1852 return false;
1853 }
1854 // new one engulfs the old one?
1855 else if (aNewRect.IsInside(aOldRect))
1856 {
1857 SAL_INFO("lok.dialog",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "New rect [" <<
aNewRect.toString() << "] engulfs old [" << aOldRect
.toString() << "]. Replacing old.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New rect [" << aNewRect.toString() <<
"] engulfs old [" << aOldRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1858 "New rect [" << aNewRect.toString() << "] engulfs old ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "New rect [" <<
aNewRect.toString() << "] engulfs old [" << aOldRect
.toString() << "]. Replacing old.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New rect [" << aNewRect.toString() <<
"] engulfs old [" << aOldRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1859 << aOldRect.toString() << "]. Replacing old.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "New rect [" <<
aNewRect.toString() << "] engulfs old [" << aOldRect
.toString() << "]. Replacing old.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "New rect [" << aNewRect.toString() <<
"] engulfs old [" << aOldRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "New rect [" << aNewRect.toString
() << "] engulfs old [" << aOldRect.toString() <<
"]. Replacing old."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1859" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1860 return true;
1861 }
1862 // old one engulfs the new one?
1863 else if (aOldRect.IsInside(aNewRect))
1864 {
1865 SAL_INFO("lok.dialog",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Old rect [" <<
aOldRect.toString() << "] engulfs new [" << aNewRect
.toString() << "]. Skipping new.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old rect [" << aOldRect.toString() <<
"] engulfs new [" << aNewRect.toString() << "]. Skipping new."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1866 "Old rect [" << aOldRect.toString() << "] engulfs new ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Old rect [" <<
aOldRect.toString() << "] engulfs new [" << aNewRect
.toString() << "]. Skipping new.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old rect [" << aOldRect.toString() <<
"] engulfs new [" << aNewRect.toString() << "]. Skipping new."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1867 << aNewRect.toString() << "]. Skipping new.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Old rect [" <<
aOldRect.toString() << "] engulfs new [" << aNewRect
.toString() << "]. Skipping new.") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Old rect [" << aOldRect.toString() <<
"] engulfs new [" << aNewRect.toString() << "]. Skipping new."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Old rect [" << aOldRect.toString
() << "] engulfs new [" << aNewRect.toString() <<
"]. Skipping new."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1867" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1868 // We have a rectangle in the queue already that makes the current Callback useless.
1869 currentIsRedundant = true;
1870 return false;
1871 }
1872 else
1873 {
1874 // Overlapping rects.
1875 const tools::Rectangle aPreMergeRect = aNewRect;
1876 aNewRect.Union(aOldRect);
1877 SAL_INFO("lok.dialog", "Merging rects ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Merging rects [" <<
aPreMergeRect.toString() << "] & [" << aOldRect
.toString() << "] = [" << aNewRect.toString() <<
"]. Replacing old.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging rects [" << aPreMergeRect.toString
() << "] & [" << aOldRect.toString() <<
"] = [" << aNewRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1878 << aPreMergeRect.toString() << "] & ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Merging rects [" <<
aPreMergeRect.toString() << "] & [" << aOldRect
.toString() << "] = [" << aNewRect.toString() <<
"]. Replacing old.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging rects [" << aPreMergeRect.toString
() << "] & [" << aOldRect.toString() <<
"] = [" << aNewRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1879 << aOldRect.toString() << "] = ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Merging rects [" <<
aPreMergeRect.toString() << "] & [" << aOldRect
.toString() << "] = [" << aNewRect.toString() <<
"]. Replacing old.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging rects [" << aPreMergeRect.toString
() << "] & [" << aOldRect.toString() <<
"] = [" << aNewRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1880 << aNewRect.toString()do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Merging rects [" <<
aPreMergeRect.toString() << "] & [" << aOldRect
.toString() << "] = [" << aNewRect.toString() <<
"]. Replacing old.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging rects [" << aPreMergeRect.toString
() << "] & [" << aOldRect.toString() <<
"] = [" << aNewRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
1881 << "]. Replacing old.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Merging rects [" <<
aPreMergeRect.toString() << "] & [" << aOldRect
.toString() << "] = [" << aNewRect.toString() <<
"]. Replacing old.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.dialog"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Merging rects [" << aPreMergeRect.toString
() << "] & [" << aOldRect.toString() <<
"] = [" << aNewRect.toString() << "]. Replacing old."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Merging rects [" << aPreMergeRect
.toString() << "] & [" << aOldRect.toString()
<< "] = [" << aNewRect.toString() << "]. Replacing old."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Merging rects [" << aPreMergeRect.toString()
<< "] & [" << aOldRect.toString() << "] = ["
<< aNewRect.toString() << "]. Replacing old."; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.dialog"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1881" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1882 return true;
1883 }
1884 }
1885 }
1886
1887 // keep rest
1888 return false;
1889 });
1890
1891 // Do not enqueue if redundant.
1892 if (currentIsRedundant)
1893 return true;
1894
1895 aTree.put("rectangle", aNewRect.toString().getStr());
1896 aCallbackData.setJson(aTree);
1897 assert(aCallbackData.validate() && "Validation after setJson failed!")(static_cast <bool> (aCallbackData.validate() &&
"Validation after setJson failed!") ? void (0) : __assert_fail
("aCallbackData.validate() && \"Validation after setJson failed!\""
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 1897, __extension__ __PRETTY_FUNCTION__))
;
1898 }
1899 }
1900 else if (aAction == "created")
1901 {
1902 // Remove all previous actions on same dialog, if we are creating it anew.
1903 removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
1904 if (elem.Type == LOK_CALLBACK_WINDOW)
1905 {
1906 const boost::property_tree::ptree& aOldTree = elem.getJson();
1907 if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
1908 return true;
1909 }
1910 return false;
1911 });
1912
1913 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
1914 if (!pWindow)
1915 {
1916 gImpl->maLastExceptionMsg = "Document doesn't support dialog rendering, or window not found.";
1917 return false;
1918 }
1919
1920#ifndef IOS
1921 auto xClip = forceSetClipboardForCurrentView(m_pDocument);
1922
1923 uno::Reference<datatransfer::clipboard::XClipboard> xClipboard(xClip.get());
1924 pWindow->SetClipboard(xClipboard);
1925#endif
1926 }
1927 else if (aAction == "size_changed")
1928 {
1929 // A size change is practically re-creation of the window.
1930 // But at a minimum it's a full invalidation.
1931 removeAll([&nLOKWindowId](const queue_type::value_type& elem) {
1932 if (elem.Type == LOK_CALLBACK_WINDOW)
1933 {
1934 const boost::property_tree::ptree& aOldTree = elem.getJson();
1935 if (nLOKWindowId == aOldTree.get<unsigned>("id", 0))
1936 {
1937 const std::string aOldAction = aOldTree.get<std::string>("action", "");
1938 if (aOldAction == "invalidate")
1939 return true;
1940 }
1941 }
1942 return false;
1943 });
1944 }
1945
1946 // Queue this one.
1947 return false;
1948}
1949
1950void CallbackFlushHandler::Invoke()
1951{
1952 comphelper::ProfileZone aZone("CallbackFlushHandler::Invoke");
1953
1954 if (!m_pCallback)
1955 return;
1956
1957 std::scoped_lock<std::mutex> lock(m_mutex);
1958
1959 SAL_INFO("lok", "Flushing " << m_queue.size() << " elements.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Flushing " << m_queue.size() << " elements."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1959" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Flushing " << m_queue.size() <<
" elements."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Flushing " << m_queue.size
() << " elements."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1959" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Flushing " << m_queue.size() << " elements."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1959" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Flushing " << m_queue.size() <<
" elements."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Flushing " << m_queue.size
() << " elements."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1959" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1960 for (const auto& rCallbackData : m_queue)
1961 {
1962 const int type = rCallbackData.Type;
1963 const auto& payload = rCallbackData.PayloadString;
1964 const int viewId = lcl_isViewCallbackType(type) ? lcl_getViewId(rCallbackData) : -1;
1965
1966 if (viewId == -1)
1967 {
1968 const auto stateIt = m_states.find(type);
1969 if (stateIt != m_states.end())
1970 {
1971 // If the state didn't change, it's safe to ignore.
1972 if (stateIt->second == payload)
1973 {
1974 SAL_INFO("lok", "Skipping duplicate [" << type << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping duplicate [" << type << "]: ["
<< payload << "].") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1974" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping duplicate [" << type
<< "]: [" << payload << "]."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping duplicate [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1974" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping duplicate [" << type << "]: ["
<< payload << "].") == 1) { ::sal_detail_log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1974" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping duplicate [" << type
<< "]: [" << payload << "]."), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Skipping duplicate [" << type << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1974" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1975 continue;
1976 }
1977
1978 stateIt->second = payload;
1979 }
1980 }
1981 else
1982 {
1983 const auto statesIt = m_viewStates.find(viewId);
1984 if (statesIt != m_viewStates.end())
1985 {
1986 auto& states = statesIt->second;
1987 const auto stateIt = states.find(type);
1988 if (stateIt != states.end())
1989 {
1990 // If the state didn't change, it's safe to ignore.
1991 if (stateIt->second == payload)
1992 {
1993 SAL_INFO("lok", "Skipping view duplicate [" << type << ',' << viewId << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping view duplicate [" << type <<
',' << viewId << "]: [" << payload <<
"].") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1993" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping view duplicate [" <<
type << ',' << viewId << "]: [" << payload
<< "]."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Skipping view duplicate [" <<
type << ',' << viewId << "]: [" << payload
<< "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1993" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Skipping view duplicate [" << type <<
',' << viewId << "]: [" << payload <<
"].") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1993" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Skipping view duplicate [" <<
type << ',' << viewId << "]: [" << payload
<< "]."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Skipping view duplicate [" <<
type << ',' << viewId << "]: [" << payload
<< "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1993" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1994 continue;
1995 }
1996
1997 SAL_INFO("lok", "Replacing an element in view states [" << type << ',' << viewId << "]: [" << payload << "].")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Replacing an element in view states [" << type
<< ',' << viewId << "]: [" << payload
<< "].") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1997" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Replacing an element in view states ["
<< type << ',' << viewId << "]: [" <<
payload << "]."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Replacing an element in view states ["
<< type << ',' << viewId << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1997" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Replacing an element in view states [" << type
<< ',' << viewId << "]: [" << payload
<< "].") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1997" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Replacing an element in view states ["
<< type << ',' << viewId << "]: [" <<
payload << "]."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Replacing an element in view states ["
<< type << ',' << viewId << "]: [" <<
payload << "]."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "1997" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1998 stateIt->second = payload;
1999 }
2000 else
2001 {
2002 SAL_INFO("lok", "Inserted a new element in view states: [" << type << ',' << viewId << "]: [" << payload << "]")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Inserted a new element in view states: [" <<
type << ',' << viewId << "]: [" << payload
<< "]") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2002" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Inserted a new element in view states: ["
<< type << ',' << viewId << "]: [" <<
payload << "]"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Inserted a new element in view states: ["
<< type << ',' << viewId << "]: [" <<
payload << "]"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2002" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Inserted a new element in view states: [" <<
type << ',' << viewId << "]: [" << payload
<< "]") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2002" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Inserted a new element in view states: ["
<< type << ',' << viewId << "]: [" <<
payload << "]"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Inserted a new element in view states: ["
<< type << ',' << viewId << "]: [" <<
payload << "]"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2002" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2003 states.emplace(type, payload);
2004
2005 }
2006 }
2007 }
2008
2009 m_pCallback(type, payload.c_str(), m_pData);
2010 }
2011
2012 m_queue.clear();
2013}
2014
2015bool CallbackFlushHandler::removeAll(const std::function<bool (const CallbackFlushHandler::queue_type::value_type&)>& rTestFunc)
2016{
2017 auto newEnd = std::remove_if(m_queue.begin(), m_queue.end(), rTestFunc);
2018 if (newEnd != m_queue.end())
2019 {
2020 m_queue.erase(newEnd, m_queue.end());
2021 return true;
2022 }
2023
2024 return false;
2025}
2026
2027void CallbackFlushHandler::addViewStates(int viewId)
2028{
2029 const auto& result = m_viewStates.emplace(viewId, decltype(m_viewStates)::mapped_type());
2030 if (!result.second && result.first != m_viewStates.end())
2031 {
2032 result.first->second.clear();
2033 }
2034}
2035
2036void CallbackFlushHandler::removeViewStates(int viewId)
2037{
2038 m_viewStates.erase(viewId);
2039}
2040
2041
2042static void doc_destroy(LibreOfficeKitDocument *pThis)
2043{
2044 comphelper::ProfileZone aZone("doc_destroy");
2045
2046 SolarMutexGuard aGuard;
2047
2048 LOKClipboardFactory::releaseClipboardForView(-1);
2049
2050 LibLODocument_Impl *pDocument = static_cast<LibLODocument_Impl*>(pThis);
2051 delete pDocument;
2052}
2053
2054static void lo_destroy (LibreOfficeKit* pThis);
2055static int lo_initialize (LibreOfficeKit* pThis, const char* pInstallPath, const char* pUserProfilePath);
2056static LibreOfficeKitDocument* lo_documentLoad (LibreOfficeKit* pThis, const char* pURL);
2057static char * lo_getError (LibreOfficeKit* pThis);
2058static void lo_freeError (char* pFree);
2059static LibreOfficeKitDocument* lo_documentLoadWithOptions (LibreOfficeKit* pThis,
2060 const char* pURL,
2061 const char* pOptions);
2062static void lo_registerCallback (LibreOfficeKit* pThis,
2063 LibreOfficeKitCallback pCallback,
2064 void* pData);
2065static char* lo_getFilterTypes(LibreOfficeKit* pThis);
2066static void lo_setOptionalFeatures(LibreOfficeKit* pThis, unsigned long long features);
2067static void lo_setDocumentPassword(LibreOfficeKit* pThis,
2068 const char* pURL,
2069 const char* pPassword);
2070static char* lo_getVersionInfo(LibreOfficeKit* pThis);
2071static int lo_runMacro (LibreOfficeKit* pThis, const char* pURL);
2072
2073static bool lo_signDocument(LibreOfficeKit* pThis,
2074 const char* pUrl,
2075 const unsigned char* pCertificateBinary,
2076 const int nCertificateBinarySize,
2077 const unsigned char* pPrivateKeyBinary,
2078 const int nPrivateKeyBinarySize);
2079
2080static void lo_runLoop(LibreOfficeKit* pThis,
2081 LibreOfficeKitPollCallback pPollCallback,
2082 LibreOfficeKitWakeCallback pWakeCallback,
2083 void* pData);
2084
2085LibLibreOffice_Impl::LibLibreOffice_Impl()
2086 : m_pOfficeClass( gOfficeClass.lock() )
2087 , maThread(nullptr)
2088 , mpCallback(nullptr)
2089 , mpCallbackData(nullptr)
2090 , mOptionalFeatures(0)
2091{
2092 if(!m_pOfficeClass) {
2093 m_pOfficeClass = std::make_shared<LibreOfficeKitClass>();
2094 m_pOfficeClass->nSize = sizeof(LibreOfficeKitClass);
2095
2096 m_pOfficeClass->destroy = lo_destroy;
2097 m_pOfficeClass->documentLoad = lo_documentLoad;
2098 m_pOfficeClass->getError = lo_getError;
2099 m_pOfficeClass->freeError = lo_freeError;
2100 m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions;
2101 m_pOfficeClass->registerCallback = lo_registerCallback;
2102 m_pOfficeClass->getFilterTypes = lo_getFilterTypes;
2103 m_pOfficeClass->setOptionalFeatures = lo_setOptionalFeatures;
2104 m_pOfficeClass->setDocumentPassword = lo_setDocumentPassword;
2105 m_pOfficeClass->getVersionInfo = lo_getVersionInfo;
2106 m_pOfficeClass->runMacro = lo_runMacro;
2107 m_pOfficeClass->signDocument = lo_signDocument;
2108 m_pOfficeClass->runLoop = lo_runLoop;
2109
2110 gOfficeClass = m_pOfficeClass;
2111 }
2112
2113 pClass = m_pOfficeClass.get();
2114}
2115
2116LibLibreOffice_Impl::~LibLibreOffice_Impl()
2117{
2118}
2119
2120namespace
2121{
2122
2123#ifdef IOS
2124void paintTileToCGContext(ITiledRenderable* pDocument,
2125 void* rCGContext, const Size nCanvasSize,
2126 const int nTilePosX, const int nTilePosY,
2127 const int nTileWidth, const int nTileHeight)
2128{
2129 SystemGraphicsData aData;
2130 aData.rCGContext = reinterpret_cast<CGContextRef>(rCGContext);
2131
2132 ScopedVclPtrInstance<VirtualDevice> pDevice(aData, Size(1, 1), DeviceFormat::DEFAULT);
2133 pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
2134 pDevice->SetOutputSizePixel(nCanvasSize);
2135 pDocument->paintTile(*pDevice, nCanvasSize.Width(), nCanvasSize.Height(),
2136 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2137}
2138
2139void paintTileIOS(LibreOfficeKitDocument* pThis,
2140 unsigned char* pBuffer,
2141 const int nCanvasWidth, const int nCanvasHeight, const double fDPIScale,
2142 const int nTilePosX, const int nTilePosY,
2143 const int nTileWidth, const int nTileHeight)
2144{
2145 CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
2146 nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
2147 kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little);
2148
2149 CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
2150 CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
2151
2152 doc_paintTileToCGContext(pThis, (void*) pCGContext, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2153
2154 CGContextRelease(pCGContext);
2155}
2156#endif
2157
2158void setLanguageAndLocale(OUString const & aLangISO)
2159{
2160 SvtSysLocaleOptions aLocalOptions;
2161 aLocalOptions.SetLocaleConfigString(aLangISO);
2162 aLocalOptions.SetUILocaleConfigString(aLangISO);
2163 aLocalOptions.Commit();
2164}
2165
2166void setFormatSpecificFilterData(OUString const & sFormat, comphelper::SequenceAsHashMap & rFilterDataMap)
2167{
2168 if (sFormat == "pdf")
2169 {
2170 // always export bookmarks, which is needed for annotations
2171 rFilterDataMap["ExportBookmarks"] <<= true;
2172 }
2173}
2174
2175} // anonymous namespace
2176
2177// Wonder global state ...
2178static uno::Reference<css::uno::XComponentContext> xContext;
2179static uno::Reference<css::lang::XMultiServiceFactory> xSFactory;
2180static uno::Reference<css::lang::XMultiComponentFactory> xFactory;
2181
2182static LibreOfficeKitDocument* lo_documentLoad(LibreOfficeKit* pThis, const char* pURL)
2183{
2184 return lo_documentLoadWithOptions(pThis, pURL, nullptr);
2185}
2186
2187static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, const char* pURL, const char* pOptions)
2188{
2189 comphelper::ProfileZone aZone("lo_documentLoadWithOptions");
2190
2191 SolarMutexGuard aGuard;
2192
2193 static int nDocumentIdCounter = 0;
2194
2195 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
2196 pLib->maLastExceptionMsg.clear();
2197
2198 OUString aURL(getAbsoluteURL(pURL));
2199 if (aURL.isEmpty())
2200 {
2201 pLib->maLastExceptionMsg = "Filename to load was not provided.";
2202 SAL_INFO("lok", "URL for load is empty")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "URL for load is empty") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2202" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "URL for load is empty"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"URL for load is empty"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2202" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "URL for load is empty") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2202" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "URL for load is empty"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"URL for load is empty"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2202" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2203 return nullptr;
2204 }
2205
2206 pLib->maLastExceptionMsg.clear();
2207
2208 if (!xContext.is())
2209 {
2210 pLib->maLastExceptionMsg = "ComponentContext is not available";
2211 SAL_INFO("lok", "ComponentContext is not available")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentContext is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2211" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentContext is not available")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentContext is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2211" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentContext is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2211" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentContext is not available")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentContext is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2211" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2212 return nullptr;
2213 }
2214
2215 uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext);
2216
2217 if (!xComponentLoader.is())
2218 {
2219 pLib->maLastExceptionMsg = "ComponentLoader is not available";
2220 SAL_INFO("lok", "ComponentLoader is not available")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentLoader is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2220" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentLoader is not available"),
0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentLoader is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2220" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentLoader is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2220" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentLoader is not available"),
0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentLoader is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2220" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2221 return nullptr;
2222 }
2223
2224 try
2225 {
2226 // 'Language=...' is an option that LOK consumes by itself, and does
2227 // not pass it as a parameter to the filter
2228 OUString aOptions = getUString(pOptions);
2229 const OUString aLanguage = extractParameter(aOptions, "Language");
2230
2231 if (!aLanguage.isEmpty())
2232 {
2233 SfxLokHelper::setDefaultLanguage(aLanguage);
2234 // Set the LOK language tag, used for dialog tunneling.
2235 comphelper::LibreOfficeKit::setLanguageTag(LanguageTag(aLanguage));
2236 comphelper::LibreOfficeKit::setLocale(LanguageTag(aLanguage));
2237
2238 SAL_INFO("lok", "Set document language to " << aLanguage)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Set document language to " << aLanguage) ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2238" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Set document language to " <<
aLanguage), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Set document language to " <<
aLanguage; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO)
, ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2238" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Set document language to " << aLanguage) ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2238" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Set document language to " <<
aLanguage), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Set document language to " <<
aLanguage; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO)
, ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2238" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2239 // use with care - it sets it for the entire core, not just the
2240 // document
2241 setLanguageAndLocale(aLanguage);
2242 // Need to reset the static initialized values
2243 SvNumberFormatter::resetTheCurrencyTable();
2244 }
2245
2246 const OUString aDeviceFormFactor = extractParameter(aOptions, "DeviceFormFactor");
2247 SfxLokHelper::setDeviceFormFactor(aDeviceFormFactor);
2248
2249 uno::Sequence<css::beans::PropertyValue> aFilterOptions(2);
2250 aFilterOptions[0] = css::beans::PropertyValue( "FilterOptions",
2251 0,
2252 uno::makeAny(aOptions),
2253 beans::PropertyState_DIRECT_VALUE);
2254
2255 rtl::Reference<LOKInteractionHandler> const pInteraction(
2256 new LOKInteractionHandler("load", pLib));
2257 auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction)));
2258 comphelper::ScopeGuard const g([&] () {
2259 if (pair.second)
2260 {
2261 pLib->mInteractionMap.erase(aURL.toUtf8());
2262 }
2263 });
2264 uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction.get());
2265 aFilterOptions[1].Name = "InteractionHandler";
2266 aFilterOptions[1].Value <<= xInteraction;
2267
2268 /* TODO
2269 sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG;
2270 aFilterOptions[2].Name = "MacroExecutionMode";
2271 aFilterOptions[2].Value <<= nMacroExecMode;
2272
2273 sal_Int16 nUpdateDoc = document::UpdateDocMode::ACCORDING_TO_CONFIG;
2274 aFilterOptions[3].Name = "UpdateDocMode";
2275 aFilterOptions[3].Value <<= nUpdateDoc;
2276 */
2277
2278 uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL(
2279 aURL, "_blank", 0,
2280 aFilterOptions);
2281
2282 assert(!xComponent.is() || pair.second)(static_cast <bool> (!xComponent.is() || pair.second) ?
void (0) : __assert_fail ("!xComponent.is() || pair.second",
"/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 2282, __extension__ __PRETTY_FUNCTION__))
; // concurrent loading of same URL ought to fail
2283
2284 if (!xComponent.is())
2285 {
2286 pLib->maLastExceptionMsg = "loadComponentFromURL returned an empty reference";
2287 SAL_INFO("lok", "Document can't be loaded - " << pLib->maLastExceptionMsg)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Document can't be loaded - " << pLib->maLastExceptionMsg
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2287" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Document can't be loaded - " <<
pLib->maLastExceptionMsg), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Document can't be loaded - "
<< pLib->maLastExceptionMsg; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2287" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Document can't be loaded - " << pLib->maLastExceptionMsg
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2287" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Document can't be loaded - " <<
pLib->maLastExceptionMsg), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Document can't be loaded - "
<< pLib->maLastExceptionMsg; ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2287" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2288 return nullptr;
2289 }
2290
2291 LibLODocument_Impl* pDocument = new LibLODocument_Impl(xComponent, nDocumentIdCounter++);
2292
2293 // Do we know that after loading the document, its initial view is the "current" view?
2294 SfxLokHelper::setDocumentIdOfView(pDocument->mnDocumentId);
2295 if (pLib->mpCallback)
2296 {
2297 int nState = doc_getSignatureState(pDocument);
2298 pLib->mpCallback(LOK_CALLBACK_SIGNATURE_STATUS, OString::number(nState).getStr(), pLib->mpCallbackData);
2299 }
2300 return pDocument;
2301 }
2302 catch (const uno::Exception& exception)
2303 {
2304 pLib->maLastExceptionMsg = exception.Message;
2305 TOOLS_INFO_EXCEPTION("lok", "Document can't be loaded")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Document can't be loaded" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2305" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Document can't be loaded" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Document can't be loaded" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2305" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Document can't be loaded" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2305" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Document can't be loaded" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Document can't be loaded" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2305" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
2306 }
2307
2308 return nullptr;
2309}
2310
2311static int lo_runMacro(LibreOfficeKit* pThis, const char *pURL)
2312{
2313 comphelper::ProfileZone aZone("lo_runMacro");
2314
2315 SolarMutexGuard aGuard;
2316
2317 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
2318 pLib->maLastExceptionMsg.clear();
2319
2320 OUString sURL( pURL, strlen(pURL), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) );
2321 if (sURL.isEmpty())
2322 {
2323 pLib->maLastExceptionMsg = "Macro to run was not provided.";
2324 SAL_INFO("lok", "Macro URL is empty")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro URL is empty") == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2324" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro URL is empty"), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"Macro URL is empty"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2324" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro URL is empty") == 1) { ::sal_detail_log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2324" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro URL is empty"), 0); } else { ::
std::ostringstream sal_detail_stream; sal_detail_stream <<
"Macro URL is empty"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2324" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2325 return false;
2326 }
2327
2328 if (!sURL.startsWith("macro://"))
2329 {
2330 pLib->maLastExceptionMsg = "This doesn't look like macro URL";
2331 SAL_INFO("lok", "Macro URL is invalid")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro URL is invalid") == 1) { ::sal_detail_log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2331" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro URL is invalid"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Macro URL is invalid"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2331" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro URL is invalid") == 1) { ::sal_detail_log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2331" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro URL is invalid"), 0); } else {
::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Macro URL is invalid"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2331" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2332 return false;
2333 }
2334
2335 pLib->maLastExceptionMsg.clear();
2336
2337 if (!xContext.is())
2338 {
2339 pLib->maLastExceptionMsg = "ComponentContext is not available";
2340 SAL_INFO("lok", "ComponentContext is not available")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentContext is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2340" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentContext is not available")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentContext is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2340" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentContext is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2340" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentContext is not available")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentContext is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2340" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2341 return false;
2342 }
2343
2344 util::URL aURL;
2345 aURL.Complete = sURL;
2346
2347 uno::Reference < util::XURLTransformer > xParser( util::URLTransformer::create( xContext ) );
2348
2349 if( xParser.is() )
2350 xParser->parseStrict( aURL );
2351
2352 uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext);
2353
2354 if (!xComponentLoader.is())
2355 {
2356 pLib->maLastExceptionMsg = "ComponentLoader is not available";
2357 SAL_INFO("lok", "ComponentLoader is not available")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentLoader is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2357" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentLoader is not available"),
0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentLoader is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2357" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ComponentLoader is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2357" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "ComponentLoader is not available"),
0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ComponentLoader is not available"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2357" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2358 return false;
2359 }
2360
2361 xFactory = xContext->getServiceManager();
2362
2363 if (xFactory.is())
2364 {
2365 uno::Reference<frame::XDispatchProvider> xDP;
2366 xSFactory.set(xFactory, uno::UNO_QUERY_THROW);
2367 xDP.set( xSFactory->createInstance("com.sun.star.comp.sfx2.SfxMacroLoader"), uno::UNO_QUERY );
2368 uno::Reference<frame::XDispatch> xD = xDP->queryDispatch( aURL, OUString(), 0);
2369
2370 if (!xD.is())
2371 {
2372 pLib->maLastExceptionMsg = "Macro loader is not available";
2373 SAL_INFO("lok", "Macro loader is not available")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro loader is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2373" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro loader is not available"), 0)
; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Macro loader is not available"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2373" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro loader is not available") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2373" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro loader is not available"), 0)
; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Macro loader is not available"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2373" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2374 return false;
2375 }
2376
2377 uno::Reference < frame::XSynchronousDispatch > xSyncDisp( xD, uno::UNO_QUERY_THROW );
2378 uno::Sequence<css::beans::PropertyValue> aEmpty;
2379 css::beans::PropertyValue aErr;
2380 uno::Any aRet = xSyncDisp->dispatchWithReturnValue( aURL, aEmpty );
2381 aRet >>= aErr;
2382
2383 if (aErr.Name == "ErrorCode")
2384 {
2385 sal_uInt32 nErrCode = 0; // ERRCODE_NONE
2386 aErr.Value >>= nErrCode;
2387
2388 pLib->maLastExceptionMsg = "An error occurred running macro (error code: " + OUString::number( nErrCode ) + ")";
2389 SAL_INFO("lok", "Macro execution terminated with error code " << nErrCode)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro execution terminated with error code " <<
nErrCode) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2389" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro execution terminated with error code "
<< nErrCode), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Macro execution terminated with error code "
<< nErrCode; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2389" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Macro execution terminated with error code " <<
nErrCode) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2389" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Macro execution terminated with error code "
<< nErrCode), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Macro execution terminated with error code "
<< nErrCode; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2389" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2390
2391 return false;
2392 }
2393
2394 return true;
2395 }
2396
2397 return false;
2398}
2399
2400static bool lo_signDocument(LibreOfficeKit* /*pThis*/,
2401 const char* pURL,
2402 const unsigned char* pCertificateBinary,
2403 const int nCertificateBinarySize,
2404 const unsigned char* pPrivateKeyBinary,
2405 const int nPrivateKeyBinarySize)
2406{
2407 comphelper::ProfileZone aZone("lo_signDocument");
2408
2409 OUString aURL(getAbsoluteURL(pURL));
2410 if (aURL.isEmpty())
2411 return false;
2412
2413 if (!xContext.is())
2414 return false;
2415
2416 uno::Sequence<sal_Int8> aCertificateSequence;
2417
2418 std::string aCertificateString(reinterpret_cast<const char*>(pCertificateBinary), nCertificateBinarySize);
2419 std::string aCertificateBase64String = extractCertificate(aCertificateString);
2420 if (!aCertificateBase64String.empty())
2421 {
2422 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
2423 comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
2424 }
2425 else
2426 {
2427 aCertificateSequence.realloc(nCertificateBinarySize);
2428 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.begin());
2429 }
2430
2431 uno::Sequence<sal_Int8> aPrivateKeySequence;
2432 std::string aPrivateKeyString(reinterpret_cast<const char*>(pPrivateKeyBinary), nPrivateKeyBinarySize);
2433 std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
2434 if (!aPrivateKeyBase64String.empty())
2435 {
2436 OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String.c_str());
2437 comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
2438 }
2439 else
2440 {
2441 aPrivateKeySequence.realloc(nPrivateKeyBinarySize);
2442 std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeyBinarySize, aPrivateKeySequence.begin());
2443 }
2444
2445 uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(xContext);
2446 uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString());
2447 if (!xSecurityContext.is())
2448 return false;
2449
2450 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = xSecurityContext->getSecurityEnvironment();
2451 uno::Reference<xml::crypto::XCertificateCreator> xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
2452
2453 if (!xCertificateCreator.is())
2454 return false;
2455
2456 uno::Reference<security::XCertificate> xCertificate = xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, aPrivateKeySequence);
2457
2458 if (!xCertificate.is())
2459 return false;
2460
2461 sfx2::DocumentSigner aDocumentSigner(aURL);
2462 if (!aDocumentSigner.signDocument(xCertificate))
2463 return false;
2464
2465 return true;
2466}
2467
2468static void lo_registerCallback (LibreOfficeKit* pThis,
2469 LibreOfficeKitCallback pCallback,
2470 void* pData)
2471{
2472 SolarMutexGuard aGuard;
2473
2474 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
2475 pLib->maLastExceptionMsg.clear();
2476
2477 pLib->mpCallback = pCallback;
2478 pLib->mpCallbackData = pData;
2479}
2480
2481static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const char* pFormat, const char* pFilterOptions)
2482{
2483 comphelper::ProfileZone aZone("doc_saveAs");
2484
2485 SolarMutexGuard aGuard;
2486 SetLastExceptionMsg();
2487
2488 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
2489
2490 OUString sFormat = getUString(pFormat);
2491 OUString aURL(getAbsoluteURL(sUrl));
2492
2493 uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
2494
2495 if (aURL.isEmpty())
2496 {
2497 SetLastExceptionMsg("Filename to save to was not provided.");
2498 SAL_INFO("lok", "URL for save is empty")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "URL for save is empty") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2498" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "URL for save is empty"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"URL for save is empty"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2498" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "URL for save is empty") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2498" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "URL for save is empty"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"URL for save is empty"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2498" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2499 return false;
2500 }
2501
2502 try
2503 {
2504 const ExtensionMap* pMap;
2505
2506 switch (doc_getDocumentType(pThis))
2507 {
2508 case LOK_DOCTYPE_SPREADSHEET:
2509 pMap = aCalcExtensionMap;
2510 break;
2511 case LOK_DOCTYPE_PRESENTATION:
2512 pMap = aImpressExtensionMap;
2513 break;
2514 case LOK_DOCTYPE_DRAWING:
2515 pMap = aDrawExtensionMap;
2516 break;
2517 case LOK_DOCTYPE_TEXT:
2518 pMap = aWriterExtensionMap;
2519 break;
2520 case LOK_DOCTYPE_OTHER:
2521 default:
2522 SAL_INFO("lok", "Can't save document - unsupported document type.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Can't save document - unsupported document type."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2522" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Can't save document - unsupported document type."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Can't save document - unsupported document type.";
::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), (
"/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2522" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Can't save document - unsupported document type."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2522" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Can't save document - unsupported document type."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Can't save document - unsupported document type.";
::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), (
"/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2522" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2523 return false;
2524 }
2525
2526 if (pFormat == nullptr)
2527 {
2528 // sniff from the extension
2529 sal_Int32 idx = aURL.lastIndexOf(".");
2530 if( idx > 0 )
2531 {
2532 sFormat = aURL.copy( idx + 1 );
2533 }
2534 else
2535 {
2536 SetLastExceptionMsg("input filename without a suffix");
2537 return false;
2538 }
2539 }
2540
2541 OUString aFilterName;
2542 for (sal_Int32 i = 0; pMap[i].extn; ++i)
2543 {
2544 if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[i].extn))
2545 {
2546 aFilterName = getUString(pMap[i].filterName);
2547 break;
2548 }
2549 }
2550 if (aFilterName.isEmpty())
2551 {
2552 SetLastExceptionMsg("no output filter found for provided suffix");
2553 return false;
2554 }
2555
2556 OUString aFilterOptions = getUString(pFilterOptions);
2557
2558 // Check if watermark for pdf is passed by filteroptions...
2559 // It is not a real filter option so it must be filtered out.
2560 OUString watermarkText, sFullSheetPreview;
2561 int aIndex = -1;
2562 if ((aIndex = aFilterOptions.indexOf(",Watermark=")) >= 0)
2563 {
2564 int bIndex = aFilterOptions.indexOf("WATERMARKEND");
2565 watermarkText = aFilterOptions.copy(aIndex+11, bIndex-(aIndex+11));
2566
2567 OUString temp = aFilterOptions.copy(0, aIndex);
2568 aFilterOptions = temp + aFilterOptions.copy(bIndex+12);
2569 }
2570
2571 if ((aIndex = aFilterOptions.indexOf(",FullSheetPreview=")) >= 0)
2572 {
2573 int bIndex = aFilterOptions.indexOf("FULLSHEETPREVEND");
2574 sFullSheetPreview = aFilterOptions.copy(aIndex+18, bIndex-(aIndex+18));
2575
2576 OUString temp = aFilterOptions.copy(0, aIndex);
2577 aFilterOptions = temp + aFilterOptions.copy(bIndex+16);
2578 }
2579
2580 bool bFullSheetPreview = sFullSheetPreview == "true";
2581
2582 // 'TakeOwnership' == this is a 'real' SaveAs (that is, the document
2583 // gets a new name). When this is not provided, the meaning of
2584 // saveAs() is more like save-a-copy, which allows saving to any
2585 // random format like PDF or PNG.
2586 // It is not a real filter option, so we have to filter it out.
2587 const uno::Sequence<OUString> aOptionSeq = comphelper::string::convertCommaSeparated(aFilterOptions);
2588 std::vector<OUString> aFilteredOptionVec;
2589 bool bTakeOwnership = false;
2590 MediaDescriptor aSaveMediaDescriptor;
2591 for (const auto& rOption : aOptionSeq)
2592 {
2593 if (rOption == "TakeOwnership")
2594 bTakeOwnership = true;
2595 else if (rOption == "NoFileSync")
2596 aSaveMediaDescriptor["NoFileSync"] <<= true;
2597 else
2598 aFilteredOptionVec.push_back(rOption);
2599 }
2600
2601 aSaveMediaDescriptor["Overwrite"] <<= true;
2602 aSaveMediaDescriptor["FilterName"] <<= aFilterName;
2603
2604 auto aFilteredOptionSeq = comphelper::containerToSequence<OUString>(aFilteredOptionVec);
2605 aFilterOptions = comphelper::string::convertCommaSeparated(aFilteredOptionSeq);
2606 aSaveMediaDescriptor[MediaDescriptor::PROP_FILTEROPTIONS()] <<= aFilterOptions;
2607
2608 comphelper::SequenceAsHashMap aFilterDataMap;
2609
2610 setFormatSpecificFilterData(sFormat, aFilterDataMap);
2611
2612 if (!watermarkText.isEmpty())
2613 aFilterDataMap["TiledWatermark"] <<= watermarkText;
2614
2615 if (bFullSheetPreview)
2616 aFilterDataMap["SinglePageSheets"] <<= true;
2617
2618 if (!aFilterDataMap.empty())
2619 {
2620 aSaveMediaDescriptor["FilterData"] <<= aFilterDataMap.getAsConstPropertyValueList();
2621 }
2622
2623 // add interaction handler too
2624 if (gImpl)
2625 {
2626 // gImpl does not have to exist when running from a unit test
2627 rtl::Reference<LOKInteractionHandler> const pInteraction(
2628 new LOKInteractionHandler("saveas", gImpl, pDocument));
2629 uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction.get());
2630
2631 aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteraction;
2632 }
2633
2634
2635 if (bTakeOwnership)
2636 xStorable->storeAsURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
2637 else
2638 xStorable->storeToURL(aURL, aSaveMediaDescriptor.getAsConstPropertyValueList());
2639
2640 return true;
2641 }
2642 catch (const uno::Exception& exception)
2643 {
2644 SetLastExceptionMsg("exception: " + exception.Message);
2645 }
2646 return false;
2647}
2648
2649/**
2650 * Initialize UNO commands, in the sense that from now on, the LOK client gets updates for status
2651 * changes of these commands. This is necessary, because (unlike in the desktop case) there are no
2652 * toolbars hosting widgets these UNO commands, so no such status updates would be sent to the
2653 * headless LOK clients out of the box.
2654 */
2655static void doc_iniUnoCommands ()
2656{
2657 SolarMutexGuard aGuard;
2658 SetLastExceptionMsg();
2659
2660 OUString sUnoCommands[] =
2661 {
2662 OUString(".uno:AlignLeft"),
2663 OUString(".uno:AlignHorizontalCenter"),
2664 OUString(".uno:AlignRight"),
2665 OUString(".uno:BackColor"),
2666 OUString(".uno:BackgroundColor"),
2667 OUString(".uno:TableCellBackgroundColor"),
2668 OUString(".uno:Bold"),
2669 OUString(".uno:CenterPara"),
2670 OUString(".uno:CharBackColor"),
2671 OUString(".uno:CharBackgroundExt"),
2672 OUString(".uno:CharFontName"),
2673 OUString(".uno:Color"),
2674 OUString(".uno:ControlCodes"),
2675 OUString(".uno:DecrementIndent"),
2676 OUString(".uno:DefaultBullet"),
2677 OUString(".uno:DefaultNumbering"),
2678 OUString(".uno:FontColor"),
2679 OUString(".uno:FontHeight"),
2680 OUString(".uno:IncrementIndent"),
2681 OUString(".uno:Italic"),
2682 OUString(".uno:JustifyPara"),
2683 OUString(".uno:OutlineFont"),
2684 OUString(".uno:LeftPara"),
2685 OUString(".uno:LanguageStatus"),
2686 OUString(".uno:RightPara"),
2687 OUString(".uno:Shadowed"),
2688 OUString(".uno:SubScript"),
2689 OUString(".uno:SuperScript"),
2690 OUString(".uno:Strikeout"),
2691 OUString(".uno:StyleApply"),
2692 OUString(".uno:Underline"),
2693 OUString(".uno:ModifiedStatus"),
2694 OUString(".uno:Undo"),
2695 OUString(".uno:Redo"),
2696 OUString(".uno:InsertPage"),
2697 OUString(".uno:DeletePage"),
2698 OUString(".uno:DuplicatePage"),
2699 OUString(".uno:Cut"),
2700 OUString(".uno:Copy"),
2701 OUString(".uno:Paste"),
2702 OUString(".uno:SelectAll"),
2703 OUString(".uno:InsertAnnotation"),
2704 OUString(".uno:DeleteAnnotation"),
2705 OUString(".uno:ReplyComment"),
2706 OUString(".uno:ResolveComment"),
2707 OUString(".uno:ResolveCommentThread"),
2708 OUString(".uno:InsertRowsBefore"),
2709 OUString(".uno:InsertRowsAfter"),
2710 OUString(".uno:InsertColumnsBefore"),
2711 OUString(".uno:InsertColumnsAfter"),
2712 OUString(".uno:MergeCells"),
2713 OUString(".uno:DeleteRows"),
2714 OUString(".uno:DeleteColumns"),
2715 OUString(".uno:DeleteTable"),
2716 OUString(".uno:SelectTable"),
2717 OUString(".uno:EntireRow"),
2718 OUString(".uno:EntireColumn"),
2719 OUString(".uno:EntireCell"),
2720 OUString(".uno:AssignLayout"),
2721 OUString(".uno:StatusDocPos"),
2722 OUString(".uno:RowColSelCount"),
2723 OUString(".uno:StatusPageStyle"),
2724 OUString(".uno:InsertMode"),
2725 OUString(".uno:SpellOnline"),
2726 OUString(".uno:StatusSelectionMode"),
2727 OUString(".uno:StateTableCell"),
2728 OUString(".uno:StatusBarFunc"),
2729 OUString(".uno:StatePageNumber"),
2730 OUString(".uno:StateWordCount"),
2731 OUString(".uno:SelectionMode"),
2732 OUString(".uno:PageStatus"),
2733 OUString(".uno:LayoutStatus"),
2734 OUString(".uno:Context"),
2735 OUString(".uno:WrapText"),
2736 OUString(".uno:ToggleMergeCells"),
2737 OUString(".uno:NumberFormatCurrency"),
2738 OUString(".uno:NumberFormatPercent"),
2739 OUString(".uno:NumberFormatDecimal"),
2740 OUString(".uno:NumberFormatDate"),
2741 OUString(".uno:FrameLineColor"),
2742 OUString(".uno:SortAscending"),
2743 OUString(".uno:SortDescending"),
2744 OUString(".uno:TrackChanges"),
2745 OUString(".uno:ShowTrackedChanges"),
2746 OUString(".uno:NextTrackedChange"),
2747 OUString(".uno:PreviousTrackedChange"),
2748 OUString(".uno:AcceptAllTrackedChanges"),
2749 OUString(".uno:RejectAllTrackedChanges"),
2750 OUString(".uno:TableDialog"),
2751 OUString(".uno:FormatCellDialog"),
2752 OUString(".uno:FontDialog"),
2753 OUString(".uno:ParagraphDialog"),
2754 OUString(".uno:OutlineBullet"),
2755 OUString(".uno:InsertIndexesEntry"),
2756 OUString(".uno:DocumentRepair"),
2757 OUString(".uno:TransformDialog"),
2758 OUString(".uno:InsertPageHeader"),
2759 OUString(".uno:InsertPageFooter"),
2760 OUString(".uno:OnlineAutoFormat"),
2761 OUString(".uno:InsertObjectChart"),
2762 OUString(".uno:InsertSection"),
2763 OUString(".uno:InsertAnnotation"),
2764 OUString(".uno:InsertPagebreak"),
2765 OUString(".uno:InsertColumnBreak"),
2766 OUString(".uno:HyperlinkDialog"),
2767 OUString(".uno:InsertSymbol"),
2768 OUString(".uno:EditRegion"),
2769 OUString(".uno:ThesaurusDialog"),
2770 OUString(".uno:FormatArea"),
2771 OUString(".uno:FormatLine"),
2772 OUString(".uno:FormatColumns"),
2773 OUString(".uno:Watermark"),
2774 OUString(".uno:ResetAttributes"),
2775 OUString(".uno:Orientation"),
2776 OUString(".uno:ObjectAlignLeft"),
2777 OUString(".uno:ObjectAlignRight"),
2778 OUString(".uno:AlignCenter"),
2779 OUString(".uno:TransformPosX"),
2780 OUString(".uno:TransformPosY"),
2781 OUString(".uno:TransformWidth"),
2782 OUString(".uno:TransformHeight"),
2783 OUString(".uno:ObjectBackOne"),
2784 OUString(".uno:SendToBack"),
2785 OUString(".uno:ObjectForwardOne"),
2786 OUString(".uno:BringToFront"),
2787 OUString(".uno:WrapRight"),
2788 OUString(".uno:WrapThrough"),
2789 OUString(".uno:WrapLeft"),
2790 OUString(".uno:WrapIdeal"),
2791 OUString(".uno:WrapOn"),
2792 OUString(".uno:WrapOff"),
2793 OUString(".uno:UpdateCurIndex"),
2794 OUString(".uno:InsertCaptionDialog"),
2795 OUString(".uno:FormatGroup"),
2796 OUString(".uno:SplitTable"),
2797 OUString(".uno:MergeCells"),
2798 OUString(".uno:DeleteNote"),
2799 OUString(".uno:AcceptChanges"),
2800 OUString(".uno:FormatPaintbrush"),
2801 OUString(".uno:SetDefault"),
2802 OUString(".uno:ParaLeftToRight"),
2803 OUString(".uno:ParaRightToLeft"),
2804 OUString(".uno:ParaspaceIncrease"),
2805 OUString(".uno:ParaspaceDecrease"),
2806 OUString(".uno:AcceptTrackedChange"),
2807 OUString(".uno:RejectTrackedChange"),
2808 OUString(".uno:ShowResolvedAnnotations"),
2809 OUString(".uno:InsertBreak"),
2810 OUString(".uno:InsertEndnote"),
2811 OUString(".uno:InsertFootnote"),
2812 OUString(".uno:InsertReferenceField"),
2813 OUString(".uno:InsertBookmark"),
2814 OUString(".uno:InsertAuthoritiesEntry"),
2815 OUString(".uno:InsertMultiIndex"),
2816 OUString(".uno:InsertField"),
2817 OUString(".uno:InsertPageNumberField"),
2818 OUString(".uno:InsertPageCountField"),
2819 OUString(".uno:InsertDateField"),
2820 OUString(".uno:InsertTitleField"),
2821 OUString(".uno:InsertFieldCtrl"),
2822 OUString(".uno:CharmapControl"),
2823 OUString(".uno:EnterGroup"),
2824 OUString(".uno:LeaveGroup"),
2825 OUString(".uno:AlignUp"),
2826 OUString(".uno:AlignMiddle"),
2827 OUString(".uno:AlignDown"),
2828 OUString(".uno:TraceChangeMode"),
2829 OUString(".uno:Combine"),
2830 OUString(".uno:Merge"),
2831 OUString(".uno:Dismantle"),
2832 OUString(".uno:Substract"),
2833 OUString(".uno:DistributeSelection"),
2834 OUString(".uno:Intersect"),
2835 OUString(".uno:BorderInner"),
2836 OUString(".uno:BorderOuter"),
2837 OUString(".uno:FreezePanes"),
2838 OUString(".uno:FreezePanesColumn"),
2839 OUString(".uno:FreezePanesRow"),
2840 OUString(".uno:Sidebar")
2841 };
2842
2843 util::URL aCommandURL;
2844 SfxViewShell* pViewShell = SfxViewShell::Current();
2845 SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr;
2846
2847 // check if Frame-Controller were created.
2848 if (!pViewFrame)
2849 {
2850 SAL_WARN("lok", "iniUnoCommands: No Frame-Controller created.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "iniUnoCommands: No Frame-Controller created.") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2850" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "iniUnoCommands: No Frame-Controller created."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "iniUnoCommands: No Frame-Controller created."; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2850" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "iniUnoCommands: No Frame-Controller created.") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2850" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "iniUnoCommands: No Frame-Controller created."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "iniUnoCommands: No Frame-Controller created."; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2850" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2851 return;
2852 }
2853
2854 if (!xContext.is())
2855 xContext = comphelper::getProcessComponentContext();
2856 if (!xContext.is())
2857 {
2858 SAL_WARN("lok", "iniUnoCommands: Component context is not available")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "iniUnoCommands: Component context is not available"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2858" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "iniUnoCommands: Component context is not available"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "iniUnoCommands: Component context is not available"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2858" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "iniUnoCommands: Component context is not available"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2858" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "iniUnoCommands: Component context is not available"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "iniUnoCommands: Component context is not available"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "2858" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
2859 return;
2860 }
2861
2862 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool(pViewFrame);
2863 uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(xContext));
2864
2865 for (const auto & sUnoCommand : sUnoCommands)
2866 {
2867 aCommandURL.Complete = sUnoCommand;
2868 xParser->parseStrict(aCommandURL);
2869
2870 // when null, this command is not supported by the given component
2871 // (like eg. Calc does not have ".uno:DefaultBullet" etc.)
2872 if (const SfxSlot* pSlot = rSlotPool.GetUnoSlot(aCommandURL.Path))
2873 {
2874 // Initialize slot to dispatch .uno: Command.
2875 pViewFrame->GetBindings().GetDispatch(pSlot, aCommandURL, false);
2876 }
2877 }
2878}
2879
2880static int doc_getDocumentType (LibreOfficeKitDocument* pThis)
2881{
2882 comphelper::ProfileZone aZone("doc_getDocumentType");
2883
2884 SolarMutexGuard aGuard;
2885 SetLastExceptionMsg();
2886
2887 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
2888
2889 try
2890 {
2891 uno::Reference<lang::XServiceInfo> xDocument(pDocument->mxComponent, uno::UNO_QUERY_THROW);
2892
2893 if (xDocument->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
2894 {
2895 return LOK_DOCTYPE_SPREADSHEET;
2896 }
2897 else if (xDocument->supportsService("com.sun.star.presentation.PresentationDocument"))
2898 {
2899 return LOK_DOCTYPE_PRESENTATION;
2900 }
2901 else if (xDocument->supportsService("com.sun.star.drawing.DrawingDocument"))
2902 {
2903 return LOK_DOCTYPE_DRAWING;
2904 }
2905 else if (xDocument->supportsService("com.sun.star.text.TextDocument") || xDocument->supportsService("com.sun.star.text.WebDocument"))
2906 {
2907 return LOK_DOCTYPE_TEXT;
2908 }
2909 else
2910 {
2911 SetLastExceptionMsg("unknown document type");
2912 }
2913 }
2914 catch (const uno::Exception& exception)
2915 {
2916 SetLastExceptionMsg("exception: " + exception.Message);
2917 }
2918 return LOK_DOCTYPE_OTHER;
2919}
2920
2921static int doc_getParts (LibreOfficeKitDocument* pThis)
2922{
2923 comphelper::ProfileZone aZone("doc_getParts");
2924
2925 SolarMutexGuard aGuard;
2926
2927 ITiledRenderable* pDoc = getTiledRenderable(pThis);
2928 if (!pDoc)
2929 {
2930 SetLastExceptionMsg("Document doesn't support tiled rendering");
2931 return 0;
2932 }
2933
2934 return pDoc->getParts();
2935}
2936
2937static int doc_getPart (LibreOfficeKitDocument* pThis)
2938{
2939 comphelper::ProfileZone aZone("doc_getPart");
2940
2941 SolarMutexGuard aGuard;
2942 SetLastExceptionMsg();
2943
2944 ITiledRenderable* pDoc = getTiledRenderable(pThis);
2945 if (!pDoc)
2946 {
2947 SetLastExceptionMsg("Document doesn't support tiled rendering");
2948 return 0;
2949 }
2950
2951 return pDoc->getPart();
2952}
2953
2954static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart)
2955{
2956 comphelper::ProfileZone aZone("doc_setPart");
2957
2958 SolarMutexGuard aGuard;
2959 SetLastExceptionMsg();
2960
2961 ITiledRenderable* pDoc = getTiledRenderable(pThis);
2962 if (!pDoc)
2963 {
2964 SetLastExceptionMsg("Document doesn't support tiled rendering");
2965 return;
2966 }
2967
2968 pDoc->setPart( nPart );
2969}
2970
2971static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart)
2972{
2973 comphelper::ProfileZone aZone("doc_getPartInfo");
2974
2975 SolarMutexGuard aGuard;
2976 ITiledRenderable* pDoc = getTiledRenderable(pThis);
2977 if (!pDoc)
2978 {
2979 SetLastExceptionMsg("Document doesn't support tiled rendering");
2980 return nullptr;
2981 }
2982
2983 return convertOUString(pDoc->getPartInfo(nPart));
2984}
2985
2986static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect)
2987{
2988 SolarMutexGuard aGuard;
2989 if (gImpl)
2990 gImpl->maLastExceptionMsg.clear();
2991
2992 ITiledRenderable* pDoc = getTiledRenderable(pThis);
2993 if (!pDoc)
2994 {
2995 gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
2996 return;
2997 }
2998
2999 pDoc->selectPart( nPart, nSelect );
3000}
3001
3002static void doc_moveSelectedParts(LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate)
3003{
3004 SolarMutexGuard aGuard;
3005 if (gImpl)
3006 gImpl->maLastExceptionMsg.clear();
3007
3008 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3009 if (!pDoc)
3010 {
3011 gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
3012 return;
3013 }
3014
3015 pDoc->moveSelectedParts(nPosition, bDuplicate);
3016}
3017
3018static char* doc_getPartPageRectangles(LibreOfficeKitDocument* pThis)
3019{
3020 comphelper::ProfileZone aZone("doc_getPartPageRectangles");
3021
3022 SolarMutexGuard aGuard;
3023 SetLastExceptionMsg();
3024
3025 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3026 if (!pDoc)
3027 {
3028 SetLastExceptionMsg("Document doesn't support tiled rendering");
3029 return nullptr;
3030 }
3031
3032 return convertOUString(pDoc->getPartPageRectangles());
3033}
3034
3035static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart)
3036{
3037 comphelper::ProfileZone aZone("doc_getPartName");
3038
3039 SolarMutexGuard aGuard;
3040 SetLastExceptionMsg();
3041
3042 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3043 if (!pDoc)
3044 {
3045 SetLastExceptionMsg("Document doesn't support tiled rendering");
3046 return nullptr;
3047 }
3048
3049 return convertOUString(pDoc->getPartName(nPart));
3050}
3051
3052static char* doc_getPartHash(LibreOfficeKitDocument* pThis, int nPart)
3053{
3054 comphelper::ProfileZone aZone("doc_getPartHash");
3055
3056 SolarMutexGuard aGuard;
3057 SetLastExceptionMsg();
3058
3059 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3060 if (!pDoc)
3061 {
3062 SetLastExceptionMsg("Document doesn't support tiled rendering");
3063 return nullptr;
3064 }
3065
3066 return convertOUString(pDoc->getPartHash(nPart));
3067}
3068
3069static void doc_setPartMode(LibreOfficeKitDocument* pThis,
3070 int nPartMode)
3071{
3072 comphelper::ProfileZone aZone("doc_setPartMode");
3073
3074 SolarMutexGuard aGuard;
3075 SetLastExceptionMsg();
3076
3077 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3078 if (!pDoc)
3079 {
3080 SetLastExceptionMsg("Document doesn't support tiled rendering");
3081 return;
3082 }
3083
3084
3085 int nCurrentPart = pDoc->getPart();
3086
3087 pDoc->setPartMode(nPartMode);
3088
3089 // We need to make sure the internal state is updated, just changing the mode
3090 // might not update the relevant shells (i.e. impress will keep rendering the
3091 // previous mode unless we do this).
3092 // TODO: we might want to do this within the relevant components rather than
3093 // here, but that's also dependent on how we implement embedded object
3094 // rendering I guess?
3095 // TODO: we could be clever and e.g. set to 0 when we change to/from
3096 // embedded object mode, and not when changing between slide/notes/combined
3097 // modes?
3098 if ( nCurrentPart < pDoc->getParts() )
3099 {
3100 pDoc->setPart( nCurrentPart );
3101 }
3102 else
3103 {
3104 pDoc->setPart( 0 );
3105 }
3106}
3107
3108static void doc_paintTile(LibreOfficeKitDocument* pThis,
3109 unsigned char* pBuffer,
3110 const int nCanvasWidth, const int nCanvasHeight,
3111 const int nTilePosX, const int nTilePosY,
3112 const int nTileWidth, const int nTileHeight)
3113{
3114 comphelper::ProfileZone aZone("doc_paintTile");
3115
3116 SolarMutexGuard aGuard;
3117 SetLastExceptionMsg();
3118
3119 SAL_INFO( "lok.tiledrendering", "paintTile: painting [" << nTileWidth << "x" << nTileHeight <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintTile: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTile: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"paintTile: painting [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintTile: painting [" << nTileWidth <<
"x" << nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTile: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"paintTile: painting [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3120 "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintTile: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTile: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"paintTile: painting [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintTile: painting [" << nTileWidth <<
"x" << nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTile: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"paintTile: painting [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3121 nCanvasWidth << "x" << nCanvasHeight << "]px" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintTile: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTile: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"paintTile: painting [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintTile: painting [" << nTileWidth <<
"x" << nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTile: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"paintTile: painting [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3121" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3122
3123 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3124 if (!pDoc)
3125 {
3126 SetLastExceptionMsg("Document doesn't support tiled rendering");
3127 return;
3128 }
3129
3130#if defined(UNX1) && !defined(MACOSX) && !defined(ENABLE_HEADLESS)
3131
3132 // Painting of zoomed or HiDPI spreadsheets is special, we actually draw everything at 100%,
3133 // and only set cairo's (or CoreGraphic's, in the iOS case) scale factor accordingly, so that
3134 // everything is painted bigger or smaller. This is different to what Calc's internal scaling
3135 // would do - because that one is trying to fit the lines between cells to integer multiples of
3136 // pixels.
3137 comphelper::ScopeGuard dpiScaleGuard([]() { comphelper::LibreOfficeKit::setDPIScale(1.0); });
3138
3139#if defined(IOS)
3140 double fDPIScaleX = 1.0;
3141 paintTileIOS(pThis, pBuffer, nCanvasWidth, nCanvasHeight, fDPIScaleX, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3142#else
3143 ScopedVclPtrInstance< VirtualDevice > pDevice(DeviceFormat::DEFAULT);
3144
3145#if !defined(ANDROID) || HAVE_FEATURE_ANDROID_LOK0
3146 // Don't set the transparent background in the 'old' (JNI-based) Android
3147 // app - no idea why it needs avoiding this.
3148 // Set background to transparent by default.
3149 pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
3150#endif
3151
3152 pDevice->SetOutputSizePixelScaleOffsetAndBuffer(
3153 Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(),
3154 pBuffer);
3155
3156 pDoc->paintTile(*pDevice, nCanvasWidth, nCanvasHeight,
3157 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3158
3159 static bool bDebug = getenv("LOK_DEBUG_TILES") != nullptr;
3160 if (bDebug)
3161 {
3162 // Draw a small red rectangle in the top left corner so that it's easy to see where a new tile begins.
3163 tools::Rectangle aRect(0, 0, 5, 5);
3164 aRect = pDevice->PixelToLogic(aRect);
3165 pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
3166 pDevice->SetFillColor(COL_LIGHTRED);
3167 pDevice->SetLineColor();
3168 pDevice->DrawRect(aRect);
3169 pDevice->Pop();
3170 }
3171#endif
3172
3173#else
3174 (void) pBuffer;
3175#endif
3176}
3177
3178#ifdef IOS
3179
3180// This function is separate only to be used by LibreOfficeLight. If that app can be retired, this
3181// function's code can be inlined.
3182static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
3183 void* rCGContext,
3184 const int nCanvasWidth, const int nCanvasHeight,
3185 const int nTilePosX, const int nTilePosY,
3186 const int nTileWidth, const int nTileHeight)
3187{
3188 SolarMutexGuard aGuard;
3189 SetLastExceptionMsg();
3190
3191 SAL_INFO( "lok.tiledrendering", "paintTileToCGContext: painting [" << nTileWidth << "x" << nTileHeight <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTileToCGContext: painting [" <<
nTileWidth << "x" << nTileHeight << "]@(" <<
nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight <<
"]px"), 0); } else { ::std::ostringstream sal_detail_stream;
sal_detail_stream << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintTileToCGContext: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTileToCGContext: painting [" <<
nTileWidth << "x" << nTileHeight << "]@(" <<
nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight <<
"]px"), 0); } else { ::std::ostringstream sal_detail_stream;
sal_detail_stream << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3192 "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTileToCGContext: painting [" <<
nTileWidth << "x" << nTileHeight << "]@(" <<
nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight <<
"]px"), 0); } else { ::std::ostringstream sal_detail_stream;
sal_detail_stream << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintTileToCGContext: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTileToCGContext: painting [" <<
nTileWidth << "x" << nTileHeight << "]@(" <<
nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight <<
"]px"), 0); } else { ::std::ostringstream sal_detail_stream;
sal_detail_stream << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3193 nCanvasWidth << "x" << nCanvasHeight << "]px" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTileToCGContext: painting [" <<
nTileWidth << "x" << nTileHeight << "]@(" <<
nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight <<
"]px"), 0); } else { ::std::ostringstream sal_detail_stream;
sal_detail_stream << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintTileToCGContext: painting [" << nTileWidth
<< "x" << nTileHeight << "]@(" << nTilePosX
<< ", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintTileToCGContext: painting [" <<
nTileWidth << "x" << nTileHeight << "]@(" <<
nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight <<
"]px"), 0); } else { ::std::ostringstream sal_detail_stream;
sal_detail_stream << "paintTileToCGContext: painting ["
<< nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3193" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3194
3195 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3196 if (!pDoc)
3197 {
3198 SetLastExceptionMsg("Document doesn't support tiled rendering");
3199 return;
3200 }
3201
3202 Size aCanvasSize(nCanvasWidth, nCanvasHeight);
3203 paintTileToCGContext(pDoc, rCGContext, aCanvasSize, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3204}
3205
3206#endif
3207
3208static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
3209 unsigned char* pBuffer,
3210 const int nPart,
3211 const int nCanvasWidth, const int nCanvasHeight,
3212 const int nTilePosX, const int nTilePosY,
3213 const int nTileWidth, const int nTileHeight)
3214{
3215 comphelper::ProfileZone aZone("doc_paintPartTile");
3216
3217 SolarMutexGuard aGuard;
3218 SetLastExceptionMsg();
3219
3220 SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintPartTile: painting @ " << nPart <<
" [" << nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3221 << nTileWidth << "x" << nTileHeight << "]@("do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintPartTile: painting @ " << nPart <<
" [" << nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3222 << nTilePosX << ", " << nTilePosY << ") to ["do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintPartTile: painting @ " << nPart <<
" [" << nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
3223 << nCanvasWidth << "x" << nCanvasHeight << "]px" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok.tiledrendering")) { case SAL_DETAIL_LOG_ACTION_IGNORE:
break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "paintPartTile: painting @ " << nPart <<
" [" << nTileWidth << "x" << nTileHeight <<
"]@(" << nTilePosX << ", " << nTilePosY <<
") to [" << nCanvasWidth << "x" << nCanvasHeight
<< "]px") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok.tiledrendering"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "paintPartTile: painting @ " <<
nPart << " [" << nTileWidth << "x" <<
nTileHeight << "]@(" << nTilePosX << ", " <<
nTilePosY << ") to [" << nCanvasWidth << "x"
<< nCanvasHeight << "]px"), 0); } else { ::std::
ostringstream sal_detail_stream; sal_detail_stream << "paintPartTile: painting @ "
<< nPart << " [" << nTileWidth << "x"
<< nTileHeight << "]@(" << nTilePosX <<
", " << nTilePosY << ") to [" << nCanvasWidth
<< "x" << nCanvasHeight << "]px"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok.tiledrendering"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3223" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3224
3225 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
3226 int nOrigViewId = doc_getView(pThis);
3227
3228 if (nOrigViewId < 0)
3229 {
3230 // tile painting always needs a SfxViewShell::Current(), but actually
3231 // it does not really matter which one - all of them should paint the
3232 // same thing. It's important to get a view for the correct document,
3233 // though.
3234 // doc_getViewsCount() returns the count of views for the document in the current view.
3235 int viewCount = doc_getViewsCount(pThis);
3236 if (viewCount == 0)
3237 return;
3238
3239 std::vector<int> viewIds(viewCount);
3240 doc_getViewIds(pThis, viewIds.data(), viewCount);
3241
3242 nOrigViewId = viewIds[0];
3243 doc_setView(pThis, nOrigViewId);
3244 }
3245
3246 // Disable callbacks while we are painting.
3247 if (nOrigViewId >= 0)
3248 {
3249 const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nOrigViewId);
3250 if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
3251 handlerIt->second->disableCallbacks();
3252 }
3253
3254 try
3255 {
3256 // Text documents have a single coordinate system; don't change part.
3257 int nOrigPart = 0;
3258 const bool isText = (doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT);
3259 int nViewId = nOrigViewId;
3260 if (!isText)
3261 {
3262 // Check if just switching to another view is enough, that has
3263 // less side-effects.
3264 if (nPart != doc_getPart(pThis))
3265 {
3266 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
3267 while (pViewShell)
3268 {
3269 if (pViewShell->getPart() == nPart)
3270 {
3271 nViewId = static_cast<sal_Int32>(pViewShell->GetViewShellId());
3272 doc_setView(pThis, nViewId);
3273 break;
3274 }
3275 pViewShell = SfxViewShell::GetNext(*pViewShell);
3276 }
3277 }
3278
3279 nOrigPart = doc_getPart(pThis);
3280 if (nPart != nOrigPart)
3281 {
3282 doc_setPart(pThis, nPart);
3283 }
3284 }
3285
3286 doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3287
3288 if (!isText && nPart != nOrigPart)
3289 {
3290 doc_setPart(pThis, nOrigPart);
3291 }
3292 if (!isText && nViewId != nOrigViewId)
3293 {
3294 doc_setView(pThis, nOrigViewId);
3295 }
3296 }
3297 catch (const std::exception&)
3298 {
3299 // Nothing to do but restore the PartTilePainting flag.
3300 }
3301
3302 if (nOrigViewId >= 0)
3303 {
3304 const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nOrigViewId);
3305 if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
3306 handlerIt->second->enableCallbacks();
3307 }
3308}
3309
3310static int doc_getTileMode(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/)
3311{
3312 SetLastExceptionMsg();
3313 return LOK_TILEMODE_BGRA;
3314}
3315
3316static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
3317 long* pWidth,
3318 long* pHeight)
3319{
3320 comphelper::ProfileZone aZone("doc_getDocumentSize");
3321
3322 SolarMutexGuard aGuard;
3323 SetLastExceptionMsg();
3324
3325 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3326 if (pDoc)
3327 {
3328 Size aDocumentSize = pDoc->getDocumentSize();
3329 *pWidth = aDocumentSize.Width();
3330 *pHeight = aDocumentSize.Height();
3331 }
3332 else
3333 {
3334 SetLastExceptionMsg("Document doesn't support tiled rendering");
3335 }
3336}
3337
3338static void doc_initializeForRendering(LibreOfficeKitDocument* pThis,
3339 const char* pArguments)
3340{
3341 comphelper::ProfileZone aZone("doc_initializeForRendering");
3342
3343 SolarMutexGuard aGuard;
3344 SetLastExceptionMsg();
3345
3346 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3347 if (pDoc)
3348 {
3349 doc_iniUnoCommands();
3350 pDoc->initializeForTiledRendering(
3351 comphelper::containerToSequence(jsonToPropertyValuesVector(pArguments)));
3352 }
3353}
3354
3355static void doc_registerCallback(LibreOfficeKitDocument* pThis,
3356 LibreOfficeKitCallback pCallback,
3357 void* pData)
3358{
3359 SolarMutexGuard aGuard;
3360 SetLastExceptionMsg();
3361
3362 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
3363
3364 int nView = SfxLokHelper::getView();
3365 if (nView < 0)
3366 return;
3367
3368 if (pCallback != nullptr)
3369 {
3370 size_t nId = nView;
3371 for (auto& pair : pDocument->mpCallbackFlushHandlers)
3372 {
3373 if (pair.first == nId)
3374 continue;
3375
3376 pair.second->addViewStates(nView);
3377 }
3378 }
3379 else
3380 {
3381 size_t nId = nView;
3382 for (auto& pair : pDocument->mpCallbackFlushHandlers)
3383 {
3384 if (pair.first == nId)
3385 continue;
3386
3387 pair.second->removeViewStates(nView);
3388 }
3389 }
3390
3391 pDocument->mpCallbackFlushHandlers[nView] = std::make_shared<CallbackFlushHandler>(pThis, pCallback, pData);
3392
3393 if (pCallback != nullptr)
3394 {
3395 size_t nId = nView;
3396 for (const auto& pair : pDocument->mpCallbackFlushHandlers)
3397 {
3398 if (pair.first == nId)
3399 continue;
3400
3401 pDocument->mpCallbackFlushHandlers[nView]->addViewStates(pair.first);
3402 }
3403 }
3404
3405 if (SfxViewShell* pViewShell = SfxViewShell::Current())
3406 {
3407 pViewShell->registerLibreOfficeKitViewCallback(CallbackFlushHandler::callback, pDocument->mpCallbackFlushHandlers[nView].get());
3408 }
3409}
3410
3411/// Returns the JSON representation of all the comments in the document
3412static char* getPostIts(LibreOfficeKitDocument* pThis)
3413{
3414 SetLastExceptionMsg();
3415 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3416 if (!pDoc)
3417 {
3418 SetLastExceptionMsg("Document doesn't support tiled rendering");
3419 return nullptr;
3420 }
3421 tools::JsonWriter aJsonWriter;
3422 pDoc->getPostIts(aJsonWriter);
3423 return aJsonWriter.extractData();
3424}
3425
3426/// Returns the JSON representation of the positions of all the comments in the document
3427static char* getPostItsPos(LibreOfficeKitDocument* pThis)
3428{
3429 SetLastExceptionMsg();
3430 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3431 if (!pDoc)
3432 {
3433 SetLastExceptionMsg("Document doesn't support tiled rendering");
3434 return nullptr;
3435 }
3436 tools::JsonWriter aJsonWriter;
3437 pDoc->getPostItsPos(aJsonWriter);
3438 return aJsonWriter.extractData();
3439}
3440
3441static char* getRulerState(LibreOfficeKitDocument* pThis)
3442{
3443 SetLastExceptionMsg();
3444 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3445 if (!pDoc)
3446 {
3447 SetLastExceptionMsg("Document doesn't support tiled rendering");
3448 return nullptr;
3449 }
3450 tools::JsonWriter aJsonWriter;
3451 pDoc->getRulerState(aJsonWriter);
3452 return aJsonWriter.extractData();
3453}
3454
3455static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nCharCode, int nKeyCode)
3456{
3457 comphelper::ProfileZone aZone("doc_postKeyEvent");
3458
3459 SolarMutexGuard aGuard;
3460 SetLastExceptionMsg();
3461
3462 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3463 if (!pDoc)
3464 {
3465 SetLastExceptionMsg("Document doesn't support tiled rendering");
3466 return;
3467 }
3468
3469 try
3470 {
3471 pDoc->postKeyEvent(nType, nCharCode, nKeyCode);
3472 }
3473 catch (const uno::Exception& exception)
3474 {
3475 SetLastExceptionMsg(exception.Message);
3476 SAL_INFO("lok", "Failed to postKeyEvent " << exception.Message)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to postKeyEvent " << exception.Message
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3476" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to postKeyEvent " << exception
.Message), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Failed to postKeyEvent " <<
exception.Message; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3476" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to postKeyEvent " << exception.Message
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3476" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to postKeyEvent " << exception
.Message), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Failed to postKeyEvent " <<
exception.Message; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3476" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3477 }
3478}
3479
3480static void doc_postWindowExtTextInputEvent(LibreOfficeKitDocument* pThis, unsigned nWindowId, int nType, const char* pText)
3481{
3482 comphelper::ProfileZone aZone("doc_postWindowExtTextInputEvent");
3483
3484 SolarMutexGuard aGuard;
3485 VclPtr<vcl::Window> pWindow;
3486 if (nWindowId == 0)
3487 {
3488 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3489 if (!pDoc)
3490 {
3491 SetLastExceptionMsg("Document doesn't support tiled rendering");
3492 return;
3493 }
3494 pWindow = pDoc->getDocWindow();
3495 }
3496 else
3497 {
3498 pWindow = vcl::Window::FindLOKWindow(nWindowId);
3499 }
3500
3501 if (!pWindow)
3502 {
3503 SetLastExceptionMsg("No window found for window id: " + OUString::number(nWindowId));
3504 return;
3505 }
3506
3507 SfxLokHelper::postExtTextEventAsync(pWindow, nType, OUString::fromUtf8(OString(pText, strlen(pText))));
3508}
3509
3510static void doc_removeTextContext(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, int nCharBefore, int nCharAfter)
3511{
3512 SolarMutexGuard aGuard;
3513 VclPtr<vcl::Window> pWindow;
3514 if (nLOKWindowId == 0)
3515 {
3516 ITiledRenderable* pDoc = getTiledRenderable(pThis);
3517 if (!pDoc)
3518 {
3519 gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
3520 return;
3521 }
3522 pWindow = pDoc->getDocWindow();
3523 }
3524 else
3525 {
3526 pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
3527 }
3528
3529 if (!pWindow)
3530 {
3531 gImpl->maLastExceptionMsg = "No window found for window id: " + OUString::number(nLOKWindowId);
3532 return;
3533 }
3534
3535 // Annoyingly - backspace and delete are handled in the apps via an accelerator
3536 // which are PostMessage'd by SfxViewShell::ExecKey_Impl so to stay in the same
3537 // order we do this synchronously here, unless we're in a dialog.
3538 if (nCharBefore > 0)
3539 {
3540 // backspace
3541 if (nLOKWindowId == 0)
3542 {
3543 KeyEvent aEvt(8, 1283);
3544 for (int i = 0; i < nCharBefore; ++i)
3545 pWindow->KeyInput(aEvt);
3546 }
3547 else
3548 SfxLokHelper::postKeyEventAsync(pWindow, LOK_KEYEVENT_KEYINPUT, 8, 1283, nCharBefore - 1);
3549 }
3550
3551 if (nCharAfter > 0)
3552 {
3553 // delete (forward)
3554 if (nLOKWindowId == 0)
3555 {
3556 KeyEvent aEvt(46, 1286);
3557 for (int i = 0; i < nCharAfter; ++i)
3558 pWindow->KeyInput(aEvt);
3559 }
3560 else
3561 SfxLokHelper::postKeyEventAsync(pWindow, LOK_KEYEVENT_KEYINPUT, 46, 1286, nCharAfter - 1);
3562 }
3563}
3564
3565static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId, int nType, int nCharCode, int nKeyCode)
3566{
3567 comphelper::ProfileZone aZone("doc_postWindowKeyEvent");
3568
3569 SolarMutexGuard aGuard;
3570 SetLastExceptionMsg();
3571
3572 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
3573 if (!pWindow)
3574 {
3575 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
3576 return;
3577 }
3578
3579 KeyEvent aEvent(nCharCode, nKeyCode, 0);
3580
3581 switch (nType)
3582 {
3583 case LOK_KEYEVENT_KEYINPUT:
3584 Application::PostKeyEvent(VclEventId::WindowKeyInput, pWindow, &aEvent);
3585 break;
3586 case LOK_KEYEVENT_KEYUP:
3587 Application::PostKeyEvent(VclEventId::WindowKeyUp, pWindow, &aEvent);
3588 break;
3589 default:
3590 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 3590, __extension__ __PRETTY_FUNCTION__))
;
3591 break;
3592 }
3593}
3594
3595static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput)
3596{
3597 comphelper::ProfileZone aZone("doc_renderShapeSelection");
3598
3599 SolarMutexGuard aGuard;
3600 SetLastExceptionMsg();
3601
3602 LokChartHelper aChartHelper(SfxViewShell::Current());
3603
3604 if (aChartHelper.GetWindow())
3605 return 0;
3606
3607 try
3608 {
3609 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
3610
3611 uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
3612
3613 SvMemoryStream aOutStream;
3614 uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aOutStream);
3615
3616 utl::MediaDescriptor aMediaDescriptor;
3617 switch (doc_getDocumentType(pThis))
3618 {
3619 case LOK_DOCTYPE_PRESENTATION:
3620 aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
3621 break;
3622 case LOK_DOCTYPE_TEXT:
3623 aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export");
3624 break;
3625 case LOK_DOCTYPE_SPREADSHEET:
3626 aMediaDescriptor["FilterName"] <<= OUString("calc_svg_Export");
3627 break;
3628 default:
3629 SAL_WARN("lok", "Failed to render shape selection: Document type is not supported")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to render shape selection: Document type is not supported"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3629" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to render shape selection: Document type is not supported"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Failed to render shape selection: Document type is not supported"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3629" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to render shape selection: Document type is not supported"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3629" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to render shape selection: Document type is not supported"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Failed to render shape selection: Document type is not supported"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3629" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3630 }
3631 aMediaDescriptor["SelectionOnly"] <<= true;
3632 aMediaDescriptor["OutputStream"] <<= xOut;
3633
3634 xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
3635
3636 if (pOutput)
3637 {
3638 const size_t nOutputSize = aOutStream.GetEndOfData();
3639 *pOutput = static_cast<char*>(malloc(nOutputSize));
3640 if (*pOutput)
3641 {
3642 std::memcpy(*pOutput, aOutStream.GetData(), nOutputSize);
3643 return nOutputSize;
3644 }
3645 }
3646 }
3647 catch (const uno::Exception& exception)
3648 {
3649 css::uno::Any exAny( cppu::getCaughtException() );
3650 SetLastExceptionMsg(exception.Message);
3651 SAL_WARN("lok", "Failed to render shape selection: " << exceptionToString(exAny))do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to render shape selection: " << exceptionToString
(exAny)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3651" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to render shape selection: "
<< exceptionToString(exAny)), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Failed to render shape selection: "
<< exceptionToString(exAny); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3651" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to render shape selection: " << exceptionToString
(exAny)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3651" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to render shape selection: "
<< exceptionToString(exAny)), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Failed to render shape selection: "
<< exceptionToString(exAny); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "3651" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
3652 }
3653
3654 return 0;
3655}
3656
3657namespace {
3658
3659/** Class to react on finishing of a dispatched command.
3660
3661 This will call a LOK_COMMAND_FINISHED callback when postUnoCommand was
3662 called with the parameter requesting the notification.
3663
3664 @see LibreOfficeKitCallbackType::LOK_CALLBACK_UNO_COMMAND_RESULT.
3665*/
3666class DispatchResultListener : public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
3667{
3668 OString maCommand; ///< Command for which this is the result.
3669 std::shared_ptr<CallbackFlushHandler> mpCallback; ///< Callback to call.
3670
3671public:
3672 DispatchResultListener(const char* pCommand, std::shared_ptr<CallbackFlushHandler> const & pCallback)
3673 : maCommand(pCommand)
3674 , mpCallback(pCallback)
3675 {
3676 assert(mpCallback)(static_cast <bool> (mpCallback) ? void (0) : __assert_fail
("mpCallback", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 3676, __extension__ __PRETTY_FUNCTION__))
;
3677 }
3678
3679 virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& rEvent) override
3680 {
3681 boost::property_tree::ptree aTree;
3682 aTree.put("commandName", maCommand.getStr());
3683
3684 if (rEvent.State != frame::DispatchResultState::DONTKNOW)
3685 {
3686 bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS);
3687 aTree.put("success", bSuccess);
3688 }
3689
3690 aTree.add_child("result", unoAnyToPropertyTree(rEvent.Result));
3691
3692 std::stringstream aStream;
3693 boost::property_tree::write_json(aStream, aTree);
3694 OString aPayload = aStream.str().c_str();
3695 mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aPayload.getStr());
3696 }
3697
3698 virtual void SAL_CALL disposing(const css::lang::EventObject&) override {}
3699};
3700
3701} // anonymous namespace
3702
3703static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned long long int nWindowId, const char* pArguments)
3704{
3705 SolarMutexGuard aGuard;
3706
3707 StringMap aMap(jsonToStringMap(pArguments));
3708 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nWindowId);
3709
3710 if (!pWindow && nWindowId >= 1000000000 /* why unsigned? */)
3711 pWindow = getSidebarWindow();
3712
3713 if (aMap.find("id") == aMap.end())
3714 return;
3715
3716 static constexpr OUStringLiteral sClickAction(u"CLICK");
3717 static constexpr OUStringLiteral sSelectAction(u"SELECT");
3718 static constexpr OUStringLiteral sClearAction(u"CLEAR");
3719 static constexpr OUStringLiteral sTypeAction(u"TYPE");
3720 static constexpr OUStringLiteral sUpAction(u"UP");
3721 static constexpr OUStringLiteral sDownAction(u"DOWN");
3722 static constexpr OUStringLiteral sValue(u"VALUE");
3723
3724 bool bIsWeldedDialog = false;
3725
3726 try
3727 {
3728 OString sControlId = OUStringToOString(aMap["id"], RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)));
3729
3730 bIsWeldedDialog = jsdialog::ExecuteAction(nWindowId, sControlId, aMap);
3731 if (!bIsWeldedDialog)
3732 bIsWeldedDialog = jsdialog::ExecuteAction(reinterpret_cast<sal_uInt64>(SfxViewShell::Current()),
3733 sControlId, aMap);
3734
3735 if (!pWindow)
3736 {
3737 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
3738 return;
3739 }
3740
3741 if (!bIsWeldedDialog)
3742 {
3743 WindowUIObject aUIObject(pWindow);
3744 std::unique_ptr<UIObject> pUIWindow(aUIObject.get_visible_child(aMap["id"]));
3745 if (pUIWindow) {
3746 bool bIsClickAction = false;
3747
3748 if (aMap.find("cmd") != aMap.end()) {
3749 if (aMap["cmd"] == "selected")
3750 {
3751 aMap["POS"] = aMap["data"];
3752 aMap["TEXT"] = aMap["data"];
3753
3754 pUIWindow->execute(sSelectAction, aMap);
3755 }
3756 else if (aMap["cmd"] == "plus")
3757 {
3758 pUIWindow->execute(sUpAction, aMap);
3759 }
3760 else if (aMap["cmd"] == "minus")
3761 {
3762 pUIWindow->execute(sDownAction, aMap);
3763 }
3764 else if (aMap["cmd"] == "set")
3765 {
3766 aMap["TEXT"] = aMap["data"];
3767
3768 pUIWindow->execute(sClearAction, aMap);
3769 pUIWindow->execute(sTypeAction, aMap);
3770 }
3771 else if (aMap["cmd"] == "value")
3772 {
3773 aMap["VALUE"] = aMap["data"];
3774 pUIWindow->execute(sValue, aMap);
3775 }
3776 else
3777 bIsClickAction = true;
3778 }
3779 else
3780 bIsClickAction = true;
3781
3782 if (bIsClickAction)
3783 pUIWindow->execute(sClickAction, aMap);
3784 }
3785 }
3786 } catch(...) {}
3787
3788 // force resend
3789 if (!bIsWeldedDialog)
3790 pWindow->Resize();
3791}
3792
3793static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, const char* pArguments, bool bNotifyWhenFinished)
3794{
3795 comphelper::ProfileZone aZone("doc_postUnoCommand");
3796
3797 SolarMutexGuard aGuard;
3798 SetLastExceptionMsg();
3799
3800 SfxObjectShell* pDocSh = SfxObjectShell::Current();
3801 OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
3802 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
3803
3804 std::vector<beans::PropertyValue> aPropertyValuesVector(jsonToPropertyValuesVector(pArguments));
3805
3806 if (!vcl::lok::isUnipoll())
3807 {
3808 beans::PropertyValue aSynchronMode;
3809 aSynchronMode.Name = "SynchronMode";
3810 aSynchronMode.Value <<= false;
3811 aPropertyValuesVector.push_back(aSynchronMode);
3812 }
3813
3814 int nView = SfxLokHelper::getView();
3815 if (nView < 0)
3816 return;
3817
3818 if (gImpl && aCommand == ".uno:ToggleOrientation")
3819 {
3820 ExecuteOrientationChange();
3821 return;
3822 }
3823
3824 // handle potential interaction
3825 if (gImpl && aCommand == ".uno:Save")
3826 {
3827 // Check if saving a PDF file
3828 OUString aMimeType = lcl_getCurrentDocumentMimeType(pDocument);
3829 if (aMimeType == "application/pdf")
3830 {
3831 // If we have a PDF file (for saving annotations for example), we need
3832 // to run save-as to the same file as the opened document. Plain save
3833 // doesn't work as the PDF is not a "native" format.
3834 uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
3835 OUString aURL = xStorable->getLocation();
3836 OString aURLUtf8 = OUStringToOString(aURL, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
3837 bool bResult = doc_saveAs(pThis, aURLUtf8.getStr(), "pdf", nullptr);
3838
3839 // Send the result of save
3840 boost::property_tree::ptree aTree;
3841 aTree.put("commandName", pCommand);
3842 aTree.put("success", bResult);
3843 std::stringstream aStream;
3844 boost::property_tree::write_json(aStream, aTree);
3845 OString aPayload = aStream.str().c_str();
3846 pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aPayload.getStr());
3847 return;
3848 }
3849
3850
3851 rtl::Reference<LOKInteractionHandler> const pInteraction(
3852 new LOKInteractionHandler("save", gImpl, pDocument));
3853 uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction.get());
3854
3855 beans::PropertyValue aValue;
3856 aValue.Name = "InteractionHandler";
3857 aValue.Value <<= xInteraction;
3858 aPropertyValuesVector.push_back(aValue);
3859
3860 bool bDontSaveIfUnmodified = false;
3861 aPropertyValuesVector.erase(std::remove_if(aPropertyValuesVector.begin(),
3862 aPropertyValuesVector.end(),
3863 [&bDontSaveIfUnmodified](const beans::PropertyValue& aItem){
3864 if (aItem.Name == "DontSaveIfUnmodified")
3865 {
3866 bDontSaveIfUnmodified = aItem.Value.get<bool>();
3867 return true;
3868 }
3869 return false;
3870 }), aPropertyValuesVector.end());
3871
3872 // skip saving and tell the result via UNO_COMMAND_RESULT
3873 if (bDontSaveIfUnmodified && !pDocSh->IsModified())
3874 {
3875 boost::property_tree::ptree aTree;
3876 aTree.put("commandName", pCommand);
3877 aTree.put("success", false);
3878
3879 // Add the reason for not saving
3880 const uno::Any aResultValue = uno::makeAny(OUString("unmodified"));
3881 aTree.add_child("result", unoAnyToPropertyTree(aResultValue));
3882
3883 std::stringstream aStream;
3884 boost::property_tree::write_json(aStream, aTree);
3885 OString aPayload = aStream.str().c_str();
3886 pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aPayload.getStr());
3887 return;
3888 }
3889 }
3890 else if (gImpl && aCommand == ".uno:TransformDialog")
3891 {
3892 bool bNeedConversion = false;
3893 SfxViewShell* pViewShell = SfxViewShell::Current();
3894 LokChartHelper aChartHelper(pViewShell);
3895
3896 if (aChartHelper.GetWindow() )
3897 {
3898 bNeedConversion = true;
3899 }
3900 else if (const SdrView* pView = pViewShell->GetDrawView())
3901 {
3902 if (OutputDevice* pOutputDevice = pView->GetFirstOutputDevice())
3903 {
3904 bNeedConversion = (pOutputDevice->GetMapMode().GetMapUnit() == MapUnit::Map100thMM);
3905 }
3906 }
3907
3908 if (bNeedConversion)
3909 {
3910 sal_Int32 value;
3911 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
3912 {
3913 if (rPropValue.Name == "TransformPosX"
3914 || rPropValue.Name == "TransformPosY"
3915 || rPropValue.Name == "TransformWidth"
3916 || rPropValue.Name == "TransformHeight"
3917 || rPropValue.Name == "TransformRotationX"
3918 || rPropValue.Name == "TransformRotationY")
3919 {
3920 rPropValue.Value >>= value;
3921 value = OutputDevice::LogicToLogic(value, MapUnit::MapTwip, MapUnit::Map100thMM);
3922 rPropValue.Value <<= value;
3923 }
3924 }
3925 }
3926
3927 if (aChartHelper.GetWindow() && aPropertyValuesVector.size() > 0)
3928 {
3929 if (aPropertyValuesVector[0].Name != "Action")
3930 {
3931 tools::Rectangle aChartBB = aChartHelper.GetChartBoundingBox();
3932 int nLeft = OutputDevice::LogicToLogic(aChartBB.Left(), MapUnit::MapTwip, MapUnit::Map100thMM);
3933 int nTop = OutputDevice::LogicToLogic(aChartBB.Top(), MapUnit::MapTwip, MapUnit::Map100thMM);
3934
3935 for (beans::PropertyValue& rPropValue: aPropertyValuesVector)
3936 {
3937 if (rPropValue.Name == "TransformPosX" || rPropValue.Name == "TransformRotationX")
3938 {
3939 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3940 rPropValue.Value <<= value - nLeft;
3941 }
3942 else if (rPropValue.Name == "TransformPosY" || rPropValue.Name == "TransformRotationY")
3943 {
3944 auto const value = *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3945 rPropValue.Value <<= value - nTop;
3946 }
3947 }
3948 }
3949 util::URL aCommandURL;
3950 aCommandURL.Path = "LOKTransform";
3951 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
3952 aChartDispatcher->dispatch(aCommandURL, comphelper::containerToSequence(aPropertyValuesVector));
3953 return;
3954 }
3955 }
3956 else if (gImpl && aCommand == ".uno:LOKSidebarWriterPage")
3957 {
3958 setupSidebar("WriterPageDeck");
3959 return;
3960 }
3961 else if (gImpl && aCommand == ".uno:SidebarShow")
3962 {
3963 setupSidebar();
3964 return;
3965 }
3966 else if (gImpl && aCommand == ".uno:SidebarHide")
3967 {
3968 hideSidebar();
3969 return;
3970 }
3971
3972 bool bResult = false;
3973 LokChartHelper aChartHelper(SfxViewShell::Current());
3974
3975 if (aChartHelper.GetWindow() && aCommand != ".uno:Save" )
3976 {
3977 util::URL aCommandURL;
3978 aCommandURL.Path = aCommand.copy(5);
3979 css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
3980 aChartDispatcher->dispatch(aCommandURL, comphelper::containerToSequence(aPropertyValuesVector));
3981 return;
3982 }
3983 else if (bNotifyWhenFinished && pDocument->mpCallbackFlushHandlers.count(nView))
3984 {
3985 bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector),
3986 new DispatchResultListener(pCommand, pDocument->mpCallbackFlushHandlers[nView]));
3987 }
3988 else
3989 bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector));
3990
3991 if (!bResult)
3992 {
3993 SetLastExceptionMsg("Failed to dispatch " + aCommand);
3994 }
3995}
3996
3997static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
3998{
3999 comphelper::ProfileZone aZone("doc_postMouseEvent");
4000
4001 SolarMutexGuard aGuard;
4002 SetLastExceptionMsg();
4003
4004 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4005 if (!pDoc)
4006 {
4007 SetLastExceptionMsg("Document doesn't support tiled rendering");
4008 return;
4009 }
4010 try
4011 {
4012 pDoc->postMouseEvent(nType, nX, nY, nCount, nButtons, nModifier);
4013 }
4014 catch (const uno::Exception& exception)
4015 {
4016 SetLastExceptionMsg(exception.Message);
4017 SAL_INFO("lok", "Failed to postMouseEvent " << exception.Message)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to postMouseEvent " << exception.Message
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4017" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to postMouseEvent " <<
exception.Message), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Failed to postMouseEvent " <<
exception.Message; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4017" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to postMouseEvent " << exception.Message
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4017" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Failed to postMouseEvent " <<
exception.Message), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Failed to postMouseEvent " <<
exception.Message; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4017" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
4018 }
4019}
4020
4021static void doc_postWindowMouseEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
4022{
4023 comphelper::ProfileZone aZone("doc_postWindowMouseEvent");
4024
4025 SolarMutexGuard aGuard;
4026 SetLastExceptionMsg();
4027
4028 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
4029 if (!pWindow)
4030 {
4031 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
4032 return;
4033 }
4034
4035 const Point aPos(nX, nY);
4036
4037 MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
4038
4039 vcl::EnableDialogInput(pWindow);
4040
4041 switch (nType)
4042 {
4043 case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
4044 Application::PostMouseEvent(VclEventId::WindowMouseButtonDown, pWindow, &aEvent);
4045 break;
4046 case LOK_MOUSEEVENT_MOUSEBUTTONUP:
4047 Application::PostMouseEvent(VclEventId::WindowMouseButtonUp, pWindow, &aEvent);
4048 break;
4049 case LOK_MOUSEEVENT_MOUSEMOVE:
4050 Application::PostMouseEvent(VclEventId::WindowMouseMove, pWindow, &aEvent);
4051 break;
4052 default:
4053 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4053, __extension__ __PRETTY_FUNCTION__))
;
4054 break;
4055 }
4056}
4057
4058static void doc_postWindowGestureEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId, const char* pType, int nX, int nY, int nOffset)
4059{
4060 comphelper::ProfileZone aZone("doc_postWindowGestureEvent");
4061
4062 SolarMutexGuard aGuard;
4063 SetLastExceptionMsg();
4064
4065 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
4066 if (!pWindow)
4067 {
4068 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
4069 return;
4070 }
4071
4072 OString aType(pType);
4073 GestureEventType eEventType = GestureEventType::PanningUpdate;
4074
4075 if (aType == "panBegin")
4076 eEventType = GestureEventType::PanningBegin;
4077 else if (aType == "panEnd")
4078 eEventType = GestureEventType::PanningEnd;
4079
4080 GestureEvent aEvent {
4081 sal_Int32(nX),
4082 sal_Int32(nY),
4083 eEventType,
4084 sal_Int32(nOffset),
4085 PanningOrientation::Vertical,
4086 };
4087
4088 vcl::EnableDialogInput(pWindow);
4089
4090 Application::PostGestureEvent(VclEventId::WindowGestureEvent, pWindow, &aEvent);
4091}
4092
4093static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
4094{
4095 comphelper::ProfileZone aZone("doc_setTextSelection");
4096
4097 SolarMutexGuard aGuard;
4098 SetLastExceptionMsg();
4099
4100 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4101 if (!pDoc)
4102 {
4103 SetLastExceptionMsg("Document doesn't support tiled rendering");
4104 return;
4105 }
4106
4107 pDoc->setTextSelection(nType, nX, nY);
4108}
4109
4110static void doc_setWindowTextSelection(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId, bool swap, int nX, int nY)
4111{
4112 comphelper::ProfileZone aZone("doc_setWindowTextSelection");
4113
4114 SolarMutexGuard aGuard;
4115 SetLastExceptionMsg();
4116
4117 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
4118 if (!pWindow)
4119 {
4120 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
4121 return;
4122 }
4123
4124
4125 Size aOffset(pWindow->GetOutOffXPixel(), pWindow->GetOutOffYPixel());
4126 Point aCursorPos(nX, nY);
4127 aCursorPos.Move(aOffset);
4128 sal_uInt16 nModifier = swap ? KEY_MOD1 + KEY_MOD2 : KEY_SHIFT;
4129
4130 MouseEvent aCursorEvent(aCursorPos, 1, MouseEventModifiers::SIMPLECLICK, 0, nModifier);
4131 Application::PostMouseEvent(VclEventId::WindowMouseButtonDown, pWindow, &aCursorEvent);
4132 Application::PostMouseEvent(VclEventId::WindowMouseButtonUp, pWindow, &aCursorEvent);
4133}
4134
4135static bool getFromTransferrable(
4136 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4137 const OString &aInMimeType, OString &aRet);
4138
4139static bool encodeImageAsHTML(
4140 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4141 const OString &aMimeType, OString &aRet)
4142{
4143 if (!getFromTransferrable(xTransferable, aMimeType, aRet))
4144 return false;
4145
4146 // Encode in base64.
4147 auto aSeq = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),
4148 aRet.getLength());
4149 OUStringBuffer aBase64Data;
4150 comphelper::Base64::encode(aBase64Data, aSeq);
4151
4152 // Embed in HTML.
4153 aRet = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
4154 "<html><head>"
4155 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
4156 "name=\"generator\" content=\""
4157 + getGenerator().toUtf8()
4158 + "\"/>"
4159 "</head><body><img src=\"data:" + aMimeType + ";base64,"
4160 + aBase64Data.makeStringAndClear().toUtf8() + "\"/></body></html>";
4161
4162 return true;
4163}
4164
4165static bool encodeTextAsHTML(
4166 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4167 const OString &aMimeType, OString &aRet)
4168{
4169 if (!getFromTransferrable(xTransferable, aMimeType, aRet))
4170 return false;
4171
4172 // Embed in HTML - FIXME: needs some escaping.
4173 aRet = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
4174 "<html><head>"
4175 "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/><meta "
4176 "name=\"generator\" content=\""
4177 + getGenerator().toUtf8()
4178 + "\"/></head><body><pre>" + aRet + "</pre></body></html>";
4179
4180 return true;
4181}
4182
4183static bool getFromTransferrable(
4184 const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
4185 const OString &aInMimeType, OString &aRet)
4186{
4187 OString aMimeType(aInMimeType);
4188
4189 // Take care of UTF-8 text here.
4190 bool bConvert = false;
4191 sal_Int32 nIndex = 0;
4192 if (aMimeType.getToken(0, ';', nIndex) == "text/plain")
4193 {
4194 if (aMimeType.getToken(0, ';', nIndex) == "charset=utf-8")
4195 {
4196 aMimeType = "text/plain;charset=utf-16";
4197 bConvert = true;
4198 }
4199 }
4200
4201 datatransfer::DataFlavor aFlavor;
4202 aFlavor.MimeType = OUString::fromUtf8(aMimeType.getStr());
4203 if (aMimeType == "text/plain;charset=utf-16")
4204 aFlavor.DataType = cppu::UnoType<OUString>::get();
4205 else
4206 aFlavor.DataType = cppu::UnoType< uno::Sequence<sal_Int8> >::get();
4207
4208 if (!xTransferable->isDataFlavorSupported(aFlavor))
4209 {
4210 // Try harder for HTML it is our copy/paste meta-file format
4211 if (aInMimeType == "text/html")
4212 {
4213 // Desperate measures - convert text to HTML instead.
4214 if (encodeTextAsHTML(xTransferable, "text/plain;charset=utf-8", aRet))
4215 return true;
4216 // If html is not supported, might be a graphic-selection,
4217 if (encodeImageAsHTML(xTransferable, "image/png", aRet))
4218 return true;
4219 }
4220
4221 SetLastExceptionMsg("Flavor " + aFlavor.MimeType + " is not supported");
4222 return false;
4223 }
4224
4225 uno::Any aAny;
4226 try
4227 {
4228 aAny = xTransferable->getTransferData(aFlavor);
4229 }
4230 catch (const css::datatransfer::UnsupportedFlavorException& e)
4231 {
4232 SetLastExceptionMsg("Unsupported flavor " + aFlavor.MimeType + " exception " + e.Message);
4233 return false;
4234 }
4235 catch (const css::uno::Exception& e)
4236 {
4237 SetLastExceptionMsg("Exception getting " + aFlavor.MimeType + " exception " + e.Message);
4238 return false;
4239 }
4240
4241 if (aFlavor.DataType == cppu::UnoType<OUString>::get())
4242 {
4243 OUString aString;
4244 aAny >>= aString;
4245 if (bConvert)
4246 aRet = OUStringToOString(aString, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
4247 else
4248 aRet = OString(reinterpret_cast<const char *>(aString.getStr()), aString.getLength() * sizeof(sal_Unicode));
4249 }
4250 else
4251 {
4252 uno::Sequence<sal_Int8> aSequence;
4253 aAny >>= aSequence;
4254 aRet = OString(reinterpret_cast<char*>(aSequence.getArray()), aSequence.getLength());
4255 }
4256
4257 return true;
4258}
4259
4260static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, const char* pMimeType, char** pUsedMimeType)
4261{
4262 comphelper::ProfileZone aZone("doc_getTextSelection");
4263
4264 SolarMutexGuard aGuard;
4265 SetLastExceptionMsg();
4266
4267 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4268 if (!pDoc)
4269 {
4270 SetLastExceptionMsg("Document doesn't support tiled rendering");
4271 return nullptr;
4272 }
4273
4274 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->getSelection();
4275 if (!xTransferable)
4276 {
4277 SetLastExceptionMsg("No selection available");
4278 return nullptr;
4279 }
4280
4281 const char *pType = pMimeType;
4282 if (!pType || pType[0] == '\0')
4283 pType = "text/plain;charset=utf-8";
4284
4285 OString aRet;
4286 bool bSuccess = getFromTransferrable(xTransferable, OString(pType), aRet);
4287 if (!bSuccess)
4288 return nullptr;
4289
4290 if (pUsedMimeType) // legacy
4291 {
4292 if (pMimeType)
4293 *pUsedMimeType = strdup(pMimeType);
4294 else
4295 *pUsedMimeType = nullptr;
4296 }
4297
4298 return convertOString(aRet);
4299}
4300
4301static int doc_getSelectionType(LibreOfficeKitDocument* pThis)
4302{
4303 comphelper::ProfileZone aZone("doc_getSelectionType");
4304
4305 SolarMutexGuard aGuard;
4306 SetLastExceptionMsg();
4307
4308 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4309 if (!pDoc)
4310 {
4311 SetLastExceptionMsg("Document doesn't support tiled rendering");
4312 return LOK_SELTYPE_NONE;
4313 }
4314
4315 css::uno::Reference<css::datatransfer::XTransferable2> xTransferable(pDoc->getSelection(), css::uno::UNO_QUERY);
4316 if (!xTransferable)
4317 {
4318 SetLastExceptionMsg("No selection available");
4319 return LOK_SELTYPE_NONE;
4320 }
4321
4322 if (xTransferable->isComplex())
4323 return LOK_SELTYPE_COMPLEX;
4324
4325 OString aRet;
4326 bool bSuccess = getFromTransferrable(xTransferable, "text/plain;charset=utf-8", aRet);
4327 if (!bSuccess)
4328 return LOK_SELTYPE_NONE;
4329
4330 if (aRet.getLength() > 10000)
4331 return LOK_SELTYPE_COMPLEX;
4332
4333 return aRet.getLength() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE;
4334}
4335
4336static int doc_getClipboard(LibreOfficeKitDocument* pThis,
4337 const char **pMimeTypes,
4338 size_t *pOutCount,
4339 char ***pOutMimeTypes,
4340 size_t **pOutSizes,
4341 char ***pOutStreams)
4342{
4343 comphelper::ProfileZone aZone("doc_getClipboard");
4344
4345 SolarMutexGuard aGuard;
4346 SetLastExceptionMsg();
4347
4348 assert (pOutCount)(static_cast <bool> (pOutCount) ? void (0) : __assert_fail
("pOutCount", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4348, __extension__ __PRETTY_FUNCTION__))
;
4349 assert (pOutMimeTypes)(static_cast <bool> (pOutMimeTypes) ? void (0) : __assert_fail
("pOutMimeTypes", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4349, __extension__ __PRETTY_FUNCTION__))
;
4350 assert (pOutSizes)(static_cast <bool> (pOutSizes) ? void (0) : __assert_fail
("pOutSizes", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4350, __extension__ __PRETTY_FUNCTION__))
;
4351 assert (pOutStreams)(static_cast <bool> (pOutStreams) ? void (0) : __assert_fail
("pOutStreams", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4351, __extension__ __PRETTY_FUNCTION__))
;
4352
4353 *pOutCount = 0;
4354 *pOutMimeTypes = nullptr;
4355 *pOutSizes = nullptr;
4356 *pOutStreams = nullptr;
4357
4358 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4359 if (!pDoc)
4360 {
4361 SetLastExceptionMsg("Document doesn't support tiled rendering");
4362 return 0;
4363 }
4364
4365 rtl::Reference<LOKClipboard> xClip(LOKClipboardFactory::getClipboardForCurView());
4366
4367 css::uno::Reference<css::datatransfer::XTransferable> xTransferable = xClip->getContents();
4368 SAL_INFO("lok", "Got from clip: " << xClip.get() << " transferrable: " << xTransferable)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Got from clip: " << xClip.get() << " transferrable: "
<< xTransferable) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4368" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Got from clip: " << xClip.get
() << " transferrable: " << xTransferable), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Got from clip: " << xClip.get() << " transferrable: "
<< xTransferable; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4368" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Got from clip: " << xClip.get() << " transferrable: "
<< xTransferable) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4368" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Got from clip: " << xClip.get
() << " transferrable: " << xTransferable), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Got from clip: " << xClip.get() << " transferrable: "
<< xTransferable; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4368" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
4369 if (!xTransferable)
4370 {
4371 SetLastExceptionMsg("No clipboard content available");
4372 return 0;
4373 }
4374
4375 std::vector<OString> aMimeTypes;
4376 if (!pMimeTypes) // everything
4377 {
4378 const uno::Sequence< css::datatransfer::DataFlavor > flavors = xTransferable->getTransferDataFlavors();
4379 if (!flavors.getLength())
4380 {
4381 SetLastExceptionMsg("Flavourless selection");
4382 return 0;
4383 }
4384 for (const auto &it : flavors)
4385 aMimeTypes.push_back(OUStringToOString(it.MimeType, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
4386 }
4387 else
4388 {
4389 for (size_t i = 0; pMimeTypes[i]; ++i)
4390 aMimeTypes.push_back(OString(pMimeTypes[i]));
4391 }
4392
4393 *pOutCount = aMimeTypes.size();
4394 *pOutSizes = static_cast<size_t *>(malloc(*pOutCount * sizeof(size_t)));
4395 *pOutMimeTypes = static_cast<char **>(malloc(*pOutCount * sizeof(char *)));
4396 *pOutStreams = static_cast<char **>(malloc(*pOutCount * sizeof(char *)));
4397 for (size_t i = 0; i < aMimeTypes.size(); ++i)
4398 {
4399 if (aMimeTypes[i] == "text/plain;charset=utf-16")
4400 (*pOutMimeTypes)[i] = strdup("text/plain;charset=utf-8");
4401 else
4402 (*pOutMimeTypes)[i] = strdup(aMimeTypes[i].getStr());
4403
4404 OString aRet;
4405 bool bSuccess = getFromTransferrable(xTransferable, (*pOutMimeTypes)[i], aRet);
4406 if (!bSuccess || aRet.getLength() < 1)
4407 {
4408 (*pOutSizes)[i] = 0;
4409 (*pOutStreams)[i] = nullptr;
4410 }
4411 else
4412 {
4413 (*pOutSizes)[i] = aRet.getLength();
4414 (*pOutStreams)[i] = convertOString(aRet);
4415 }
4416 }
4417
4418 return 1;
4419}
4420
4421static int doc_setClipboard(LibreOfficeKitDocument* pThis,
4422 const size_t nInCount,
4423 const char **pInMimeTypes,
4424 const size_t *pInSizes,
4425 const char **pInStreams)
4426{
4427#ifdef IOS
4428 (void) pThis;
4429 (void) nInCount;
4430 (void) pInMimeTypes;
4431 (void) pInSizes;
4432 (void) pInStreams;
4433#else
4434 comphelper::ProfileZone aZone("doc_setClipboard");
4435
4436 SolarMutexGuard aGuard;
4437 SetLastExceptionMsg();
4438
4439 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4440 if (!pDoc)
4441 {
4442 SetLastExceptionMsg("Document doesn't support tiled rendering");
4443 return false;
4444 }
4445
4446 uno::Reference<datatransfer::XTransferable> xTransferable(new LOKTransferable(nInCount, pInMimeTypes, pInSizes, pInStreams));
4447
4448 auto xClip = forceSetClipboardForCurrentView(pThis);
4449 xClip->setContents(xTransferable, uno::Reference<datatransfer::clipboard::XClipboardOwner>());
4450
4451 SAL_INFO("lok", "Set clip: " << xClip.get() << " to: " << xTransferable)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Set clip: " << xClip.get() << " to: "
<< xTransferable) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4451" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Set clip: " << xClip.get() <<
" to: " << xTransferable), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Set clip: " <<
xClip.get() << " to: " << xTransferable; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4451" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Set clip: " << xClip.get() << " to: "
<< xTransferable) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4451" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Set clip: " << xClip.get() <<
" to: " << xTransferable), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Set clip: " <<
xClip.get() << " to: " << xTransferable; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "4451" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
4452
4453 if (!pDoc->isMimeTypeSupported())
4454 {
4455 SetLastExceptionMsg("Document doesn't support this mime type");
4456 return false;
4457 }
4458#endif
4459 return true;
4460}
4461
4462static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, const char* pData, size_t nSize)
4463{
4464 comphelper::ProfileZone aZone("doc_paste");
4465
4466 SolarMutexGuard aGuard;
4467
4468 const char *pInMimeTypes[1];
4469 const char *pInStreams[1];
4470 size_t pInSizes[1];
4471 pInMimeTypes[0] = pMimeType;
4472 pInSizes[0] = nSize;
4473 pInStreams[0] = pData;
4474
4475 if (!doc_setClipboard(pThis, 1, pInMimeTypes, pInSizes, pInStreams))
4476 return false;
4477
4478 uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
4479 {
4480 {"AnchorType", uno::makeAny(static_cast<sal_uInt16>(text::TextContentAnchorType_AS_CHARACTER))},
4481 {"IgnoreComments", uno::makeAny(true)},
4482 }));
4483 if (!comphelper::dispatchCommand(".uno:Paste", aPropertyValues))
4484 {
4485 SetLastExceptionMsg("Failed to dispatch the .uno: command");
4486 return false;
4487 }
4488
4489 return true;
4490}
4491
4492static void doc_setGraphicSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
4493{
4494 comphelper::ProfileZone aZone("doc_setGraphicSelection");
4495
4496 SolarMutexGuard aGuard;
4497 SetLastExceptionMsg();
4498
4499 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4500 if (!pDoc)
4501 {
4502 SetLastExceptionMsg("Document doesn't support tiled rendering");
4503 return;
4504 }
4505
4506 pDoc->setGraphicSelection(nType, nX, nY);
4507}
4508
4509static void doc_resetSelection(LibreOfficeKitDocument* pThis)
4510{
4511 comphelper::ProfileZone aZone("doc_resetSelection");
4512
4513 SolarMutexGuard aGuard;
4514 SetLastExceptionMsg();
4515
4516 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4517 if (!pDoc)
4518 {
4519 SetLastExceptionMsg("Document doesn't support tiled rendering");
4520 return;
4521 }
4522
4523 pDoc->resetSelection();
4524}
4525
4526static char* getLanguages(const char* pCommand)
4527{
4528 css::uno::Sequence< css::lang::Locale > aLocales;
4529
4530 if (xContext.is())
4531 {
4532 css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLangSrv = css::linguistic2::LinguServiceManager::create(xContext);
4533 if (xLangSrv.is())
4534 {
4535 css::uno::Reference<css::linguistic2::XSpellChecker> xSpell = xLangSrv->getSpellChecker();
4536 if (xSpell.is())
4537 aLocales = xSpell->getLocales();
4538 }
4539 }
4540
4541 boost::property_tree::ptree aTree;
4542 aTree.put("commandName", pCommand);
4543 boost::property_tree::ptree aValues;
4544 boost::property_tree::ptree aChild;
4545 OUString sLanguage;
4546 for ( css::lang::Locale const & locale : std::as_const(aLocales) )
4547 {
4548 const LanguageTag aLanguageTag( locale );
4549 sLanguage = SvtLanguageTable::GetLanguageString(aLanguageTag.getLanguageType());
4550 if (sLanguage.startsWith("{") && sLanguage.endsWith("}"))
4551 continue;
4552
4553 sLanguage += ";" + aLanguageTag.getBcp47(false);
4554 aChild.put("", sLanguage.toUtf8());
4555 aValues.push_back(std::make_pair("", aChild));
4556 }
4557 aTree.add_child("commandValues", aValues);
4558 std::stringstream aStream;
4559 boost::property_tree::write_json(aStream, aTree);
4560 char* pJson = static_cast<char*>(malloc(aStream.str().size() + 1));
4561 assert(pJson)(static_cast <bool> (pJson) ? void (0) : __assert_fail (
"pJson", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4561, __extension__ __PRETTY_FUNCTION__))
; // Don't handle OOM conditions
4562 strcpy(pJson, aStream.str().c_str());
4563 pJson[aStream.str().size()] = '\0';
4564 return pJson;
4565}
4566
4567static char* getFonts (const char* pCommand)
4568{
4569 SfxObjectShell* pDocSh = SfxObjectShell::Current();
4570 const SvxFontListItem* pFonts = static_cast<const SvxFontListItem*>(
4571 pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST( 10000 + 22 )));
4572 const FontList* pList = pFonts ? pFonts->GetFontList() : nullptr;
4573
4574 boost::property_tree::ptree aTree;
4575 aTree.put("commandName", pCommand);
4576 boost::property_tree::ptree aValues;
4577 if ( pList )
4578 {
4579 sal_uInt16 nFontCount = pList->GetFontNameCount();
4580 for (sal_uInt16 i = 0; i < nFontCount; ++i)
4581 {
4582 boost::property_tree::ptree aChildren;
4583 const FontMetric& rFontMetric = pList->GetFontName(i);
4584 const int* pAry = pList->GetSizeAry(rFontMetric);
4585 sal_uInt16 nSizeCount = 0;
4586 while (pAry[nSizeCount])
4587 {
4588 boost::property_tree::ptree aChild;
4589 aChild.put("", static_cast<float>(pAry[nSizeCount]) / 10);
4590 aChildren.push_back(std::make_pair("", aChild));
4591 nSizeCount++;
4592 }
4593 aValues.add_child(rFontMetric.GetFamilyName().toUtf8().getStr(), aChildren);
4594 }
4595 }
4596 aTree.add_child("commandValues", aValues);
4597 std::stringstream aStream;
4598 boost::property_tree::write_json(aStream, aTree);
4599 char* pJson = static_cast<char*>(malloc(aStream.str().size() + 1));
4600 assert(pJson)(static_cast <bool> (pJson) ? void (0) : __assert_fail (
"pJson", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4600, __extension__ __PRETTY_FUNCTION__))
; // Don't handle OOM conditions
4601 strcpy(pJson, aStream.str().c_str());
4602 pJson[aStream.str().size()] = '\0';
4603 return pJson;
4604}
4605
4606static char* getFontSubset (const OString& aFontName)
4607{
4608 OUString aFoundFont(::rtl::Uri::decode(OStringToOUString(aFontName, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))), rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
4609 SfxObjectShell* pDocSh = SfxObjectShell::Current();
4610 const SvxFontListItem* pFonts = static_cast<const SvxFontListItem*>(
4611 pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST( 10000 + 22 )));
4612 const FontList* pList = pFonts ? pFonts->GetFontList() : nullptr;
4613
4614 boost::property_tree::ptree aTree;
4615 aTree.put("commandName", ".uno:FontSubset");
4616 boost::property_tree::ptree aValues;
4617
4618 if ( pList && !aFoundFont.isEmpty() )
4619 {
4620 sal_uInt16 nFontCount = pList->GetFontNameCount();
4621 sal_uInt16 nItFont = 0;
4622 for (; nItFont < nFontCount; ++nItFont)
4623 {
4624 if (aFoundFont == pList->GetFontName(nItFont).GetFamilyName())
4625 {
4626 break;
4627 }
4628 }
4629
4630 if ( nItFont < nFontCount )
4631 {
4632 FontCharMapRef xFontCharMap (new FontCharMap());
4633 auto aDevice(VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT));
4634 const vcl::Font& aFont(pList->GetFontName(nItFont));
4635
4636 aDevice->SetFont(aFont);
4637 aDevice->GetFontCharMap(xFontCharMap);
4638 SubsetMap aSubMap(xFontCharMap);
4639
4640 for (auto const& subset : aSubMap.GetSubsetMap())
4641 {
4642 boost::property_tree::ptree aChild;
4643 aChild.put("", static_cast<int>(ublock_getCodeublock_getCode_67(subset.GetRangeMin())));
4644 aValues.push_back(std::make_pair("", aChild));
4645 }
4646 }
4647 }
4648
4649 aTree.add_child("commandValues", aValues);
4650 std::stringstream aStream;
4651 boost::property_tree::write_json(aStream, aTree);
4652 char* pJson = static_cast<char*>(malloc(aStream.str().size() + 1));
4653 assert(pJson)(static_cast <bool> (pJson) ? void (0) : __assert_fail (
"pJson", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4653, __extension__ __PRETTY_FUNCTION__))
; // Don't handle OOM conditions
4654 strcpy(pJson, aStream.str().c_str());
4655 pJson[aStream.str().size()] = '\0';
4656 return pJson;
4657}
4658
4659static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand)
4660{
4661 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
4662
4663 boost::property_tree::ptree aTree;
4664 aTree.put("commandName", pCommand);
4665 uno::Reference<css::style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(pDocument->mxComponent, uno::UNO_QUERY);
4666 const uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
4667 const uno::Sequence<OUString> aStyleFamilies = xStyleFamilies->getElementNames();
4668
4669 static const std::vector<OUString> aWriterStyles =
4670 {
4671 "Text body",
4672 "Quotations",
4673 "Title",
4674 "Subtitle",
4675 "Heading 1",
4676 "Heading 2",
4677 "Heading 3"
4678 };
4679
4680 // We need to keep a list of the default style names
4681 // in order to filter these out later when processing
4682 // the full list of styles.
4683 std::set<OUString> aDefaultStyleNames;
4684
4685 boost::property_tree::ptree aValues;
4686 for (OUString const & sStyleFam : aStyleFamilies)
4687 {
4688 boost::property_tree::ptree aChildren;
4689 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(sStyleFam), uno::UNO_QUERY);
4690
4691 // Writer provides a huge number of styles, we have a list of 7 "default" styles which
4692 // should be shown in the normal dropdown, which we should add to the start of the list
4693 // to simplify their selection.
4694 if (sStyleFam == "ParagraphStyles"
4695 && doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT)
4696 {
4697 for (const OUString& rStyle: aWriterStyles)
4698 {
4699 aDefaultStyleNames.insert( rStyle );
4700
4701 boost::property_tree::ptree aChild;
4702 aChild.put("", rStyle.toUtf8());
4703 aChildren.push_back(std::make_pair("", aChild));
4704 }
4705 }
4706
4707 const uno::Sequence<OUString> aStyles = xStyleFamily->getElementNames();
4708 for (const OUString& rStyle: aStyles )
4709 {
4710 // Filter out the default styles - they are already at the top
4711 // of the list
4712 if (aDefaultStyleNames.find(rStyle) == aDefaultStyleNames.end() ||
4713 (sStyleFam != "ParagraphStyles" || doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT) )
4714 {
4715 boost::property_tree::ptree aChild;
4716 aChild.put("", rStyle.toUtf8());
4717 aChildren.push_back(std::make_pair("", aChild));
4718 }
4719 }
4720 aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren);
4721 }
4722
4723 // Header & Footer Styles
4724 {
4725 boost::property_tree::ptree aChild;
4726 boost::property_tree::ptree aChildren;
4727 const OUString sPageStyles("PageStyles");
4728 uno::Reference<beans::XPropertySet> xProperty;
4729 uno::Reference<container::XNameContainer> xContainer;
4730
4731 if (xStyleFamilies->hasByName(sPageStyles) && (xStyleFamilies->getByName(sPageStyles) >>= xContainer))
4732 {
4733 const uno::Sequence<OUString> aSeqNames = xContainer->getElementNames();
4734 for (OUString const & sName : aSeqNames)
4735 {
4736 bool bIsPhysical;
4737 xProperty.set(xContainer->getByName(sName), uno::UNO_QUERY);
4738 if (xProperty.is() && (xProperty->getPropertyValue("IsPhysical") >>= bIsPhysical) && bIsPhysical)
4739 {
4740 OUString displayName;
4741 xProperty->getPropertyValue("DisplayName") >>= displayName;
4742 aChild.put("", displayName.toUtf8());
4743 aChildren.push_back(std::make_pair("", aChild));
4744 }
4745 }
4746 aValues.add_child("HeaderFooter", aChildren);
4747 }
4748 }
4749
4750 {
4751 boost::property_tree::ptree aCommandList;
4752
4753 {
4754 boost::property_tree::ptree aChild;
4755
4756 OUString sClearFormat = SvxResId(RID_SVXSTR_CLEARFORMreinterpret_cast<char const *>("RID_SVXSTR_CLEARFORM" "\004"
u8"Clear formatting")
);
4757
4758 boost::property_tree::ptree aName;
4759 aName.put("", sClearFormat.toUtf8());
4760 aChild.push_back(std::make_pair("text", aName));
4761
4762 boost::property_tree::ptree aCommand;
4763 aCommand.put("", ".uno:ResetAttributes");
4764 aChild.push_back(std::make_pair("id", aCommand));
4765
4766 aCommandList.push_back(std::make_pair("", aChild));
4767 }
4768
4769 aValues.add_child("Commands", aCommandList);
4770 }
4771
4772 aTree.add_child("commandValues", aValues);
4773 std::stringstream aStream;
4774 boost::property_tree::write_json(aStream, aTree);
4775 char* pJson = static_cast<char*>(malloc(aStream.str().size() + 1));
4776 assert(pJson)(static_cast <bool> (pJson) ? void (0) : __assert_fail (
"pJson", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 4776, __extension__ __PRETTY_FUNCTION__))
; // Don't handle OOM conditions
4777 strcpy(pJson, aStream.str().c_str());
4778 pJson[aStream.str().size()] = '\0';
4779 return pJson;
4780}
4781
4782namespace {
4783
4784enum class UndoOrRedo
4785{
4786 UNDO,
4787 REDO
4788};
4789
4790}
4791
4792/// Returns the JSON representation of either an undo or a redo stack.
4793static char* getUndoOrRedo(LibreOfficeKitDocument* pThis, UndoOrRedo eCommand)
4794{
4795 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
4796
4797 auto pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
4798 if (!pBaseModel)
4799 return nullptr;
4800
4801 SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
4802 if (!pObjectShell)
4803 return nullptr;
4804
4805 SfxUndoManager* pUndoManager = pObjectShell->GetUndoManager();
4806 if (!pUndoManager)
4807 return nullptr;
4808
4809 OUString aString;
4810 if (eCommand == UndoOrRedo::UNDO)
4811 aString = pUndoManager->GetUndoActionsInfo();
4812 else
4813 aString = pUndoManager->GetRedoActionsInfo();
4814 char* pJson = strdup(aString.toUtf8().getStr());
4815 return pJson;
4816}
4817
4818/// Returns the JSON representation of the redline stack.
4819static char* getTrackedChanges(LibreOfficeKitDocument* pThis)
4820{
4821 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
4822
4823 uno::Reference<document::XRedlinesSupplier> xRedlinesSupplier(pDocument->mxComponent, uno::UNO_QUERY);
4824 tools::JsonWriter aJson;
4825 // We want positions of the track changes also which is not possible from
4826 // UNO. Enable positioning information for text documents only for now, so
4827 // construct the tracked changes JSON from inside the sw/, not here using UNO
4828 if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT && xRedlinesSupplier.is())
4829 {
4830 auto redlinesNode = aJson.startNode("redlines");
4831 uno::Reference<container::XEnumeration> xRedlines = xRedlinesSupplier->getRedlines()->createEnumeration();
4832 for (size_t nIndex = 0; xRedlines->hasMoreElements(); ++nIndex)
4833 {
4834 uno::Reference<beans::XPropertySet> xRedline(xRedlines->nextElement(), uno::UNO_QUERY);
4835 auto redlineNode = aJson.startNode("");
4836 aJson.put("index", static_cast<sal_Int32>(nIndex));
4837
4838 OUString sAuthor;
4839 xRedline->getPropertyValue("RedlineAuthor") >>= sAuthor;
4840 aJson.put("author", sAuthor);
4841
4842 OUString sType;
4843 xRedline->getPropertyValue("RedlineType") >>= sType;
4844 aJson.put("type", sType);
4845
4846 OUString sComment;
4847 xRedline->getPropertyValue("RedlineComment") >>= sComment;
4848 aJson.put("comment", sComment);
4849
4850 OUString sDescription;
4851 xRedline->getPropertyValue("RedlineDescription") >>= sDescription;
4852 aJson.put("description", sDescription);
4853
4854 util::DateTime aDateTime;
4855 xRedline->getPropertyValue("RedlineDateTime") >>= aDateTime;
4856 OUString sDateTime = utl::toISO8601(aDateTime);
4857 aJson.put("dateTime", sDateTime);
4858 }
4859 }
4860 else
4861 {
4862 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4863 if (!pDoc)
4864 {
4865 SetLastExceptionMsg("Document doesn't support tiled rendering");
4866 return nullptr;
4867 }
4868 pDoc->getTrackedChanges(aJson);
4869 }
4870
4871 return aJson.extractData();
4872}
4873
4874
4875/// Returns the JSON representation of the redline author table.
4876static char* getTrackedChangeAuthors(LibreOfficeKitDocument* pThis)
4877{
4878 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4879 if (!pDoc)
4880 {
4881 SetLastExceptionMsg("Document doesn't support tiled rendering");
4882 return nullptr;
4883 }
4884 tools::JsonWriter aJsonWriter;
4885 pDoc->getTrackedChangeAuthors(aJsonWriter);
4886 return aJsonWriter.extractData();
4887}
4888
4889static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand)
4890{
4891 comphelper::ProfileZone aZone("doc_getCommandValues");
4892
4893 SolarMutexGuard aGuard;
4894 SetLastExceptionMsg();
4895
4896 OString aCommand(pCommand);
4897 static constexpr OStringLiteral aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
4898 static constexpr OStringLiteral aSheetGeometryData(".uno:SheetGeometryData");
4899 static constexpr OStringLiteral aCellCursor(".uno:CellCursor");
4900 static constexpr OStringLiteral aFontSubset(".uno:FontSubset&name=");
4901
4902 if (!strcmp(pCommand, ".uno:LanguageStatus"))
4903 {
4904 return getLanguages(pCommand);
4905 }
4906 else if (!strcmp(pCommand, ".uno:CharFontName"))
4907 {
4908 return getFonts(pCommand);
4909 }
4910 else if (!strcmp(pCommand, ".uno:StyleApply"))
4911 {
4912 return getStyles(pThis, pCommand);
4913 }
4914 else if (aCommand == ".uno:Undo")
4915 {
4916 return getUndoOrRedo(pThis, UndoOrRedo::UNDO);
4917 }
4918 else if (aCommand == ".uno:Redo")
4919 {
4920 return getUndoOrRedo(pThis, UndoOrRedo::REDO);
4921 }
4922 else if (aCommand == ".uno:AcceptTrackedChanges")
4923 {
4924 return getTrackedChanges(pThis);
4925 }
4926 else if (aCommand == ".uno:TrackedChangeAuthors")
4927 {
4928 return getTrackedChangeAuthors(pThis);
4929 }
4930 else if (aCommand == ".uno:ViewAnnotations")
4931 {
4932 return getPostIts(pThis);
4933 }
4934 else if (aCommand == ".uno:ViewAnnotationsPosition")
4935 {
4936 return getPostItsPos(pThis);
4937 }
4938 else if (aCommand == ".uno:RulerState")
4939 {
4940 return getRulerState(pThis);
4941 }
4942 else if (aCommand.startsWith(aViewRowColumnHeaders))
4943 {
4944 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4945 if (!pDoc)
4946 {
4947 SetLastExceptionMsg("Document doesn't support tiled rendering");
4948 return nullptr;
4949 }
4950
4951 tools::Rectangle aRectangle;
4952 if (aCommand.getLength() > aViewRowColumnHeaders.getLength())
4953 {
4954 // Command has parameters.
4955 int nX = 0;
4956 int nY = 0;
4957 int nWidth = 0;
4958 int nHeight = 0;
4959 OString aArguments = aCommand.copy(aViewRowColumnHeaders.getLength() + 1);
4960 sal_Int32 nParamIndex = 0;
4961 do
4962 {
4963 OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
4964 sal_Int32 nIndex = 0;
4965 OString aKey;
4966 OString aValue;
4967 do
4968 {
4969 OString aToken = aParamToken.getToken(0, '=', nIndex);
4970 if (!aKey.getLength())
4971 aKey = aToken;
4972 else
4973 aValue = aToken;
4974 }
4975 while (nIndex >= 0);
4976 if (aKey == "x")
4977 nX = aValue.toInt32();
4978 else if (aKey == "y")
4979 nY = aValue.toInt32();
4980 else if (aKey == "width")
4981 nWidth = aValue.toInt32();
4982 else if (aKey == "height")
4983 nHeight = aValue.toInt32();
4984 }
4985 while (nParamIndex >= 0);
4986
4987 aRectangle = tools::Rectangle(nX, nY, nX + nWidth, nY + nHeight);
4988 }
4989
4990 tools::JsonWriter aJsonWriter;
4991 pDoc->getRowColumnHeaders(aRectangle, aJsonWriter);
4992 return aJsonWriter.extractData();
4993 }
4994 else if (aCommand.startsWith(aSheetGeometryData))
4995 {
4996 ITiledRenderable* pDoc = getTiledRenderable(pThis);
4997 if (!pDoc)
4998 {
4999 SetLastExceptionMsg("Document doesn't support tiled rendering");
5000 return nullptr;
5001 }
5002
5003 bool bColumns = true;
5004 bool bRows = true;
5005 bool bSizes = true;
5006 bool bHidden = true;
5007 bool bFiltered = true;
5008 bool bGroups = true;
5009 if (aCommand.getLength() > aSheetGeometryData.getLength())
5010 {
5011 bColumns = bRows = bSizes = bHidden = bFiltered = bGroups = false;
5012
5013 OString aArguments = aCommand.copy(aSheetGeometryData.getLength() + 1);
5014 sal_Int32 nParamIndex = 0;
5015 do
5016 {
5017 OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
5018 sal_Int32 nIndex = 0;
5019 OString aKey;
5020 OString aValue;
5021 do
5022 {
5023 OString aToken = aParamToken.getToken(0, '=', nIndex);
5024 if (!aKey.getLength())
5025 aKey = aToken;
5026 else
5027 aValue = aToken;
5028
5029 } while (nIndex >= 0);
5030
5031 bool bEnableFlag = aValue.isEmpty() ||
5032 aValue.equalsIgnoreAsciiCase("true") || aValue.toInt32() > 0;
5033 if (!bEnableFlag)
5034 continue;
5035
5036 if (aKey == "columns")
5037 bColumns = true;
5038 else if (aKey == "rows")
5039 bRows = true;
5040 else if (aKey == "sizes")
5041 bSizes = true;
5042 else if (aKey == "hidden")
5043 bHidden = true;
5044 else if (aKey == "filtered")
5045 bFiltered = true;
5046 else if (aKey == "groups")
5047 bGroups = true;
5048
5049 } while (nParamIndex >= 0);
5050 }
5051
5052 OString aGeomDataStr
5053 = pDoc->getSheetGeometryData(bColumns, bRows, bSizes, bHidden, bFiltered, bGroups);
5054
5055 if (aGeomDataStr.isEmpty())
5056 return nullptr;
5057
5058 return convertOString(aGeomDataStr);
5059 }
5060 else if (aCommand.startsWith(aCellCursor))
5061 {
5062 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5063 if (!pDoc)
5064 {
5065 SetLastExceptionMsg("Document doesn't support tiled rendering");
5066 return nullptr;
5067 }
5068 // Ignore command's deprecated parameters.
5069 tools::JsonWriter aJsonWriter;
5070 pDoc->getCellCursor(aJsonWriter);
5071 return aJsonWriter.extractData();
5072 }
5073 else if (aCommand.startsWith(aFontSubset))
5074 {
5075 return getFontSubset(OString(pCommand + aFontSubset.getLength()));
5076 }
5077 else
5078 {
5079 SetLastExceptionMsg("Unknown command, no values returned");
5080 return nullptr;
5081 }
5082}
5083
5084static void doc_setClientZoom(LibreOfficeKitDocument* pThis, int nTilePixelWidth, int nTilePixelHeight,
5085 int nTileTwipWidth, int nTileTwipHeight)
5086{
5087 comphelper::ProfileZone aZone("doc_setClientZoom");
5088
5089 SolarMutexGuard aGuard;
5090 SetLastExceptionMsg();
5091
5092 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5093 if (!pDoc)
5094 {
5095 SetLastExceptionMsg("Document doesn't support tiled rendering");
5096 return;
5097 }
5098
5099 pDoc->setClientZoom(nTilePixelWidth, nTilePixelHeight, nTileTwipWidth, nTileTwipHeight);
5100}
5101
5102static void doc_setClientVisibleArea(LibreOfficeKitDocument* pThis, int nX, int nY, int nWidth, int nHeight)
5103{
5104 comphelper::ProfileZone aZone("doc_setClientVisibleArea");
5105
5106 SolarMutexGuard aGuard;
5107 SetLastExceptionMsg();
5108
5109 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5110 if (!pDoc)
5111 {
5112 SetLastExceptionMsg("Document doesn't support tiled rendering");
5113 return;
5114 }
5115
5116 tools::Rectangle aRectangle(Point(nX, nY), Size(nWidth, nHeight));
5117 pDoc->setClientVisibleArea(aRectangle);
5118}
5119
5120static void doc_setOutlineState(LibreOfficeKitDocument* pThis, bool bColumn, int nLevel, int nIndex, bool bHidden)
5121{
5122 comphelper::ProfileZone aZone("doc_setOutlineState");
5123
5124 SolarMutexGuard aGuard;
5125 SetLastExceptionMsg();
5126
5127 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5128 if (!pDoc)
5129 {
5130 SetLastExceptionMsg("Document doesn't support tiled rendering");
5131 return;
5132 }
5133
5134 pDoc->setOutlineState(bColumn, nLevel, nIndex, bHidden);
5135}
5136
5137static int doc_createViewWithOptions(LibreOfficeKitDocument* pThis,
5138 const char* pOptions)
5139{
5140 comphelper::ProfileZone aZone("doc_createView");
5141
5142 SolarMutexGuard aGuard;
5143 SetLastExceptionMsg();
5144
5145 OUString aOptions = getUString(pOptions);
5146 const OUString aLanguage = extractParameter(aOptions, "Language");
5147
5148 if (!aLanguage.isEmpty())
5149 {
5150 // Set the LOK language tag, used for dialog tunneling.
5151 comphelper::LibreOfficeKit::setLanguageTag(LanguageTag(aLanguage));
5152 comphelper::LibreOfficeKit::setLocale(LanguageTag(aLanguage));
5153 }
5154
5155 const OUString aDeviceFormFactor = extractParameter(aOptions, "DeviceFormFactor");
5156 SfxLokHelper::setDeviceFormFactor(aDeviceFormFactor);
5157
5158 int nId = SfxLokHelper::createView();
5159
5160#ifdef IOS
5161 (void) pThis;
5162#else
5163 forceSetClipboardForCurrentView(pThis);
5164#endif
5165
5166 return nId;
5167}
5168
5169static int doc_createView(LibreOfficeKitDocument* pThis)
5170{
5171 return doc_createViewWithOptions(pThis, nullptr); // No options.
5172}
5173
5174static void doc_destroyView(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/, int nId)
5175{
5176 comphelper::ProfileZone aZone("doc_destroyView");
5177
5178 SolarMutexGuard aGuard;
5179 SetLastExceptionMsg();
5180
5181 LOKClipboardFactory::releaseClipboardForView(nId);
5182
5183 SfxLokHelper::destroyView(nId);
5184}
5185
5186static void doc_setView(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/, int nId)
5187{
5188 comphelper::ProfileZone aZone("doc_setView");
5189
5190 SolarMutexGuard aGuard;
5191 SetLastExceptionMsg();
5192
5193 SfxLokHelper::setView(nId);
5194}
5195
5196static int doc_getView(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/)
5197{
5198 comphelper::ProfileZone aZone("doc_getView");
5199
5200 SolarMutexGuard aGuard;
5201 SetLastExceptionMsg();
5202
5203 return SfxLokHelper::getView();
5204}
5205
5206static int doc_getViewsCount(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/)
5207{
5208 comphelper::ProfileZone aZone("doc_getViewsCount");
5209
5210 SolarMutexGuard aGuard;
5211 SetLastExceptionMsg();
5212
5213 return SfxLokHelper::getViewsCount();
5214}
5215
5216static bool doc_getViewIds(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/, int* pArray, size_t nSize)
5217{
5218 comphelper::ProfileZone aZone("doc_getViewsIds");
5219
5220 SolarMutexGuard aGuard;
5221 SetLastExceptionMsg();
5222
5223 return SfxLokHelper::getViewIds(pArray, nSize);
5224}
5225
5226static void doc_setViewLanguage(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/, int nId, const char* language)
5227{
5228 comphelper::ProfileZone aZone("doc_setViewLanguage");
5229
5230 SolarMutexGuard aGuard;
5231 SetLastExceptionMsg();
5232
5233 OUString sLanguage = OStringToOUString(language, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
5234 SfxLokHelper::setViewLanguage(nId, sLanguage);
5235 SfxLokHelper::setViewLocale(nId, sLanguage);
5236}
5237
5238
5239
5240unsigned char* doc_renderFont(LibreOfficeKitDocument* pThis,
5241 const char* pFontName,
5242 const char* pChar,
5243 int* pFontWidth,
5244 int* pFontHeight)
5245{
5246 return doc_renderFontOrientation(pThis, pFontName, pChar, pFontWidth, pFontHeight, 0);
5247}
5248
5249unsigned char* doc_renderFontOrientation(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKitDocument* /*pThis*/,
5250 const char* pFontName,
5251 const char* pChar,
5252 int* pFontWidth,
5253 int* pFontHeight,
5254 int pOrientation)
5255{
5256 comphelper::ProfileZone aZone("doc_renderFont");
5257
5258 SolarMutexGuard aGuard;
5259 SetLastExceptionMsg();
5260
5261 OString aSearchedFontName(pFontName);
5262 OUString aText(OStringToOUString(pChar, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
5263 SfxObjectShell* pDocSh = SfxObjectShell::Current();
5264 const SvxFontListItem* pFonts = static_cast<const SvxFontListItem*>(
5265 pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST( 10000 + 22 )));
5266 const FontList* pList = pFonts ? pFonts->GetFontList() : nullptr;
5267
5268 const int nDefaultFontSize = 25;
5269
5270 if ( pList )
5271 {
5272 sal_uInt16 nFontCount = pList->GetFontNameCount();
5273 for (sal_uInt16 i = 0; i < nFontCount; ++i)
5274 {
5275 const FontMetric& rFontMetric = pList->GetFontName(i);
5276 const OUString& aFontName = rFontMetric.GetFamilyName();
5277 if (aSearchedFontName != aFontName.toUtf8())
5278 continue;
5279
5280 if (aText.isEmpty())
5281 aText = rFontMetric.GetFamilyName();
5282
5283 auto aDevice(VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT));
5284 ::tools::Rectangle aRect;
5285 vcl::Font aFont(rFontMetric);
5286 aFont.SetFontSize(Size(0, nDefaultFontSize));
5287 aFont.SetOrientation(pOrientation);
5288 aDevice->SetFont(aFont);
5289 aDevice->GetTextBoundRect(aRect, aText);
5290 if (aRect.IsEmpty())
5291 break;
5292
5293 int nFontWidth = aRect.BottomRight().X() + 1;
5294 int nFontHeight = aRect.BottomRight().Y() + 1;
5295
5296 if (nFontWidth <= 0 || nFontHeight <= 0)
5297 break;
5298
5299 if (*pFontWidth > 0 && *pFontHeight > 0)
5300 {
5301 double fScaleX = *pFontWidth / static_cast<double>(nFontWidth) / 1.5;
5302 double fScaleY = *pFontHeight / static_cast<double>(nFontHeight) / 1.5;
5303
5304 double fScale = std::min(fScaleX, fScaleY);
5305
5306 if (fScale >= 1.0)
5307 {
5308 int nFontSize = fScale * nDefaultFontSize;
5309 aFont.SetFontSize(Size(0, nFontSize));
5310 aDevice->SetFont(aFont);
5311 }
5312
5313 aRect = tools::Rectangle(0, 0, *pFontWidth, *pFontHeight);
5314
5315 nFontWidth = *pFontWidth;
5316 nFontHeight = *pFontHeight;
5317
5318 }
5319
5320 unsigned char* pBuffer = static_cast<unsigned char*>(malloc(4 * nFontWidth * nFontHeight));
5321 if (!pBuffer)
5322 break;
5323
5324 memset(pBuffer, 0, nFontWidth * nFontHeight * 4);
5325 aDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
5326 aDevice->SetOutputSizePixelScaleOffsetAndBuffer(
5327 Size(nFontWidth, nFontHeight), Fraction(1.0), Point(),
5328 pBuffer);
5329
5330 if (*pFontWidth > 0 && *pFontHeight > 0)
5331 {
5332 DrawTextFlags const nStyle =
5333 DrawTextFlags::Center
5334 | DrawTextFlags::VCenter
5335 | DrawTextFlags::Bottom
5336 | DrawTextFlags::MultiLine
5337 | DrawTextFlags::WordBreak;// | DrawTextFlags::WordBreakHyphenation ;
5338
5339 aDevice->DrawText(aRect, aText, nStyle);
5340 }
5341 else
5342 {
5343 *pFontWidth = nFontWidth;
5344 *pFontHeight = nFontHeight;
5345
5346 aDevice->DrawText(Point(0,0), aText);
5347 }
5348
5349
5350 return pBuffer;
5351 }
5352 }
5353 return nullptr;
5354}
5355
5356
5357static void doc_paintWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId,
5358 unsigned char* pBuffer,
5359 const int nX, const int nY,
5360 const int nWidth, const int nHeight)
5361{
5362 doc_paintWindowDPI(pThis, nLOKWindowId, pBuffer, nX, nY, nWidth, nHeight, 1.0);
1
Calling 'doc_paintWindowDPI'
5363}
5364
5365static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId,
5366 unsigned char* pBuffer,
5367 const int nX, const int nY,
5368 const int nWidth, const int nHeight,
5369 const double fDPIScale)
5370{
5371 doc_paintWindowForView(pThis, nLOKWindowId, pBuffer, nX, nY, nWidth, nHeight, fDPIScale, -1);
2
Calling 'doc_paintWindowForView'
5372}
5373
5374static void doc_paintWindowForView(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId,
5375 unsigned char* pBuffer, const int nX, const int nY,
5376 const int nWidth, const int nHeight,
5377 const double fDPIScale, int viewId)
5378{
5379 comphelper::ProfileZone aZone("doc_paintWindowDPI");
5380
5381 SolarMutexGuard aGuard;
5382 SetLastExceptionMsg();
5383
5384 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
5385 if (!pWindow)
3
Taking false branch
5386 {
5387 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
5388 return;
5389 }
5390
5391 // Used to avoid work in setView if set.
5392 comphelper::LibreOfficeKit::setDialogPainting(true);
5393
5394 if (viewId
3.1
'viewId' is < 0
3.1
'viewId' is < 0
3.1
'viewId' is < 0
3.1
'viewId' is < 0
>= 0)
4
Taking false branch
5395 doc_setView(pThis, viewId);
5396
5397 // Setup cairo (or CoreGraphics, in the iOS case) to draw with the changed DPI scale (and return
5398 // back to 1.0 when the painting finishes)
5399 comphelper::ScopeGuard dpiScaleGuard([]() { comphelper::LibreOfficeKit::setDPIScale(1.0); });
5400 comphelper::LibreOfficeKit::setDPIScale(fDPIScale);
5401
5402#if defined(IOS)
5403
5404 CGContextRef cgc = CGBitmapContextCreate(pBuffer, nWidth, nHeight, 8, nWidth*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little);
5405
5406 CGContextTranslateCTM(cgc, 0, nHeight);
5407 CGContextScaleCTM(cgc, fDPIScale, -fDPIScale);
5408
5409 SystemGraphicsData aData;
5410 aData.rCGContext = cgc;
5411
5412 ScopedVclPtrInstance<VirtualDevice> pDevice(aData, Size(1, 1), DeviceFormat::DEFAULT);
5413 pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
5414
5415 pDevice->SetOutputSizePixel(Size(nWidth, nHeight));
5416
5417 MapMode aMapMode(pDevice->GetMapMode());
5418 aMapMode.SetOrigin(Point(-(nX / fDPIScale), -(nY / fDPIScale)));
5419 pDevice->SetMapMode(aMapMode);
5420
5421 pWindow->PaintToDevice(pDevice.get(), Point(0, 0));
5422
5423 CGContextRelease(cgc);
5424
5425#else
5426
5427 ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
5
Calling constructor for 'ScopedVclPtrInstance<VirtualDevice>'
7
Returning from constructor for 'ScopedVclPtrInstance<VirtualDevice>'
5428 pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
5429
5430 pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nWidth, nHeight), Fraction(1.0), Point(), pBuffer);
5431
5432 MapMode aMapMode(pDevice->GetMapMode());
5433 aMapMode.SetOrigin(Point(-(nX / fDPIScale), -(nY / fDPIScale)));
5434 pDevice->SetMapMode(aMapMode);
5435
5436 pWindow->PaintToDevice(pDevice.get(), Point(0, 0));
5437#endif
5438
5439 comphelper::LibreOfficeKit::setDialogPainting(false);
5440}
8
Calling implicit destructor for 'ScopedVclPtrInstance<VirtualDevice>'
9
Calling '~ScopedVclPtr'
5441
5442static void doc_postWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId, int nAction, const char* pData)
5443{
5444 comphelper::ProfileZone aZone("doc_postWindow");
5445
5446 SolarMutexGuard aGuard;
5447 SetLastExceptionMsg();
5448
5449 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
5450 if (!pWindow)
5451 {
5452 SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
5453 return;
5454 }
5455
5456 if (nAction == LOK_WINDOW_CLOSE)
5457 {
5458 bool bWasDialog = vcl::CloseDialog(pWindow);
5459 if (!bWasDialog)
5460 {
5461 if (FloatingWindow* pFloatWin = dynamic_cast<FloatingWindow*>(pWindow.get()))
5462 pFloatWin->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll);
5463 }
5464 }
5465 else if (nAction == LOK_WINDOW_PASTE)
5466 {
5467 OUString aMimeType;
5468 css::uno::Sequence<sal_Int8> aData;
5469 std::vector<beans::PropertyValue> aArgs(jsonToPropertyValuesVector(pData));
5470 {
5471 aArgs.size() == 2 &&
5472 aArgs[0].Name == "MimeType" && (aArgs[0].Value >>= aMimeType) &&
5473 aArgs[1].Name == "Data" && (aArgs[1].Value >>= aData);
5474 }
5475
5476 if (!aMimeType.isEmpty() && aData.hasElements())
5477 {
5478 uno::Reference<datatransfer::XTransferable> xTransferable(new LOKTransferable(aMimeType, aData));
5479 uno::Reference<datatransfer::clipboard::XClipboard> xClipboard(new LOKClipboard);
5480 xClipboard->setContents(xTransferable, uno::Reference<datatransfer::clipboard::XClipboardOwner>());
5481 pWindow->SetClipboard(xClipboard);
5482
5483 KeyEvent aEvent(0, KEY_PASTE, 0);
5484 Application::PostKeyEvent(VclEventId::WindowKeyInput, pWindow, &aEvent);
5485 }
5486 else
5487 SetLastExceptionMsg("Window command 'paste': wrong parameters.");
5488 }
5489}
5490
5491// CERTIFICATE AND DOCUMENT SIGNING
5492static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
5493 const unsigned char* pCertificateBinary, const int nCertificateBinarySize,
5494 const unsigned char* pPrivateKeyBinary, const int nPrivateKeySize)
5495{
5496 comphelper::ProfileZone aZone("doc_insertCertificate");
5497
5498 if (!xContext.is())
5499 return false;
5500
5501 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
5502
5503 if (!pDocument->mxComponent.is())
5504 return false;
5505
5506 SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
5507 if (!pBaseModel)
5508 return false;
5509
5510 SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
5511
5512 if (!pObjectShell)
5513 return false;
5514
5515 uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(xContext);
5516 uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString());
5517 if (!xSecurityContext.is())
5518 return false;
5519
5520 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = xSecurityContext->getSecurityEnvironment();
5521 uno::Reference<xml::crypto::XCertificateCreator> xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
5522
5523 if (!xCertificateCreator.is())
5524 return false;
5525
5526 uno::Sequence<sal_Int8> aCertificateSequence;
5527
5528 std::string aCertificateString(reinterpret_cast<const char*>(pCertificateBinary), nCertificateBinarySize);
5529 std::string aCertificateBase64String = extractCertificate(aCertificateString);
5530 if (!aCertificateBase64String.empty())
5531 {
5532 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
5533 comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
5534 }
5535 else
5536 {
5537 aCertificateSequence.realloc(nCertificateBinarySize);
5538 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.begin());
5539 }
5540
5541 uno::Sequence<sal_Int8> aPrivateKeySequence;
5542 std::string aPrivateKeyString(reinterpret_cast<const char*>(pPrivateKeyBinary), nPrivateKeySize);
5543 std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
5544 if (!aPrivateKeyBase64String.empty())
5545 {
5546 OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String.c_str());
5547 comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
5548 }
5549 else
5550 {
5551 aPrivateKeySequence.realloc(nPrivateKeySize);
5552 std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeySize, aPrivateKeySequence.begin());
5553 }
5554
5555 uno::Reference<security::XCertificate> xCertificate = xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, aPrivateKeySequence);
5556
5557 if (!xCertificate.is())
5558 return false;
5559
5560 SolarMutexGuard aGuard;
5561
5562 return pObjectShell->SignDocumentContentUsingCertificate(xCertificate);
5563}
5564
5565static bool doc_addCertificate(LibreOfficeKitDocument* pThis,
5566 const unsigned char* pCertificateBinary, const int nCertificateBinarySize)
5567{
5568 comphelper::ProfileZone aZone("doc_addCertificate");
5569
5570 if (!xContext.is())
5571 return false;
5572
5573 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
5574
5575 if (!pDocument->mxComponent.is())
5576 return false;
5577
5578 SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
5579 if (!pBaseModel)
5580 return false;
5581
5582 SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
5583
5584 if (!pObjectShell)
5585 return false;
5586
5587 uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(xContext);
5588 uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = xSEInitializer->createSecurityContext(OUString());
5589 if (!xSecurityContext.is())
5590 return false;
5591
5592 uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = xSecurityContext->getSecurityEnvironment();
5593 uno::Reference<xml::crypto::XCertificateCreator> xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
5594
5595 if (!xCertificateCreator.is())
5596 return false;
5597
5598 uno::Sequence<sal_Int8> aCertificateSequence;
5599
5600 std::string aCertificateString(reinterpret_cast<const char*>(pCertificateBinary), nCertificateBinarySize);
5601 std::string aCertificateBase64String = extractCertificate(aCertificateString);
5602 if (!aCertificateBase64String.empty())
5603 {
5604 OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
5605 comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
5606 }
5607 else
5608 {
5609 aCertificateSequence.realloc(nCertificateBinarySize);
5610 std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.begin());
5611 }
5612
5613 uno::Reference<security::XCertificate> xCertificate = xCertificateCreator->addDERCertificateToTheDatabase(aCertificateSequence, "TCu,Cu,Tu");
5614
5615 if (!xCertificate.is())
5616 return false;
5617
5618 SAL_INFO("lok", "Certificate Added = IssuerName: " << xCertificate->getIssuerName() << " SubjectName: " << xCertificate->getSubjectName())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Certificate Added = IssuerName: " << xCertificate
->getIssuerName() << " SubjectName: " << xCertificate
->getSubjectName()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5618" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Certificate Added = IssuerName: " <<
xCertificate->getIssuerName() << " SubjectName: " <<
xCertificate->getSubjectName()), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Certificate Added = IssuerName: "
<< xCertificate->getIssuerName() << " SubjectName: "
<< xCertificate->getSubjectName(); ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5618" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Certificate Added = IssuerName: " << xCertificate
->getIssuerName() << " SubjectName: " << xCertificate
->getSubjectName()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5618" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Certificate Added = IssuerName: " <<
xCertificate->getIssuerName() << " SubjectName: " <<
xCertificate->getSubjectName()), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Certificate Added = IssuerName: "
<< xCertificate->getIssuerName() << " SubjectName: "
<< xCertificate->getSubjectName(); ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5618" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
5619
5620 return true;
5621}
5622
5623static int doc_getSignatureState(LibreOfficeKitDocument* pThis)
5624{
5625 comphelper::ProfileZone aZone("doc_getSignatureState");
5626
5627 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
5628
5629 if (!pDocument->mxComponent.is())
5630 return int(SignatureState::UNKNOWN);
5631
5632 SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
5633 if (!pBaseModel)
5634 return int(SignatureState::UNKNOWN);
5635
5636 SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
5637 if (!pObjectShell)
5638 return int(SignatureState::UNKNOWN);
5639
5640 SolarMutexGuard aGuard;
5641
5642 pObjectShell->RecheckSignature(false);
5643
5644 return int(pObjectShell->GetDocumentSignatureState());
5645}
5646
5647static void doc_resizeWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId,
5648 const int nWidth, const int nHeight)
5649{
5650 SolarMutexGuard aGuard;
5651 if (gImpl)
5652 gImpl->maLastExceptionMsg.clear();
5653
5654 VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
5655 if (!pWindow)
5656 {
5657 gImpl->maLastExceptionMsg = "Document doesn't support dialog resizing, or window not found.";
5658 return;
5659 }
5660
5661 pWindow->SetSizePixel(Size(nWidth, nHeight));
5662}
5663
5664static void doc_completeFunction(LibreOfficeKitDocument* pThis, const char* pFunctionName)
5665{
5666 SolarMutexGuard aGuard;
5667 SetLastExceptionMsg();
5668
5669 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5670 if (!pDoc)
5671 {
5672 SetLastExceptionMsg("Document doesn't support tiled rendering");
5673 return;
5674 }
5675
5676 pDoc->completeFunction(OUString::fromUtf8(pFunctionName));
5677}
5678
5679
5680static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis, const char* pArguments)
5681{
5682 SolarMutexGuard aGuard;
5683
5684 // Supported in Writer only
5685 if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT)
5686 return;
5687
5688 StringMap aMap(jsonToStringMap(pArguments));
5689 ITiledRenderable* pDoc = getTiledRenderable(pThis);
5690 if (!pDoc)
5691 {
5692 SetLastExceptionMsg("Document doesn't support tiled rendering!");
5693 return;
5694 }
5695
5696 // Sanity check
5697 if (aMap.find("type") == aMap.end() || aMap.find("cmd") == aMap.end())
5698 {
5699 SetLastExceptionMsg("Wrong arguments for sendFormFieldEvent!");
5700 return;
5701 }
5702
5703 pDoc->executeFromFieldEvent(aMap);
5704}
5705
5706static char* lo_getError (LibreOfficeKit *pThis)
5707{
5708 comphelper::ProfileZone aZone("lo_getError");
5709
5710 SolarMutexGuard aGuard;
5711
5712 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
5713 return convertOUString(pLib->maLastExceptionMsg);
5714}
5715
5716static void lo_freeError(char* pFree)
5717{
5718 free(pFree);
5719}
5720
5721static char* lo_getFilterTypes(LibreOfficeKit* pThis)
5722{
5723 SolarMutexGuard aGuard;
5724 SetLastExceptionMsg();
5725
5726 LibLibreOffice_Impl* pImpl = static_cast<LibLibreOffice_Impl*>(pThis);
5727
5728 if (!xSFactory.is())
5729 xSFactory = comphelper::getProcessServiceFactory();
5730
5731 if (!xSFactory.is())
5732 {
5733 pImpl->maLastExceptionMsg = "Service factory is not available";
5734 return nullptr;
5735 }
5736
5737 uno::Reference<container::XNameAccess> xTypeDetection(xSFactory->createInstance("com.sun.star.document.TypeDetection"), uno::UNO_QUERY);
5738 const uno::Sequence<OUString> aTypes = xTypeDetection->getElementNames();
5739 boost::property_tree::ptree aTree;
5740 for (const OUString& rType : aTypes)
5741 {
5742 uno::Sequence<beans::PropertyValue> aValues;
5743 if (xTypeDetection->getByName(rType) >>= aValues)
5744 {
5745 auto it = std::find_if(aValues.begin(), aValues.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "MediaType"; });
5746 OUString aValue;
5747 if (it != aValues.end() && (it->Value >>= aValue) && !aValue.isEmpty())
5748 {
5749 boost::property_tree::ptree aChild;
5750 aChild.put("MediaType", aValue.toUtf8());
5751 aTree.add_child(rType.toUtf8().getStr(), aChild);
5752 }
5753 }
5754 }
5755 std::stringstream aStream;
5756 boost::property_tree::write_json(aStream, aTree);
5757 return strdup(aStream.str().c_str());
5758}
5759
5760static void lo_setOptionalFeatures(LibreOfficeKit* pThis, unsigned long long const features)
5761{
5762 comphelper::ProfileZone aZone("lo_setOptionalFeatures");
5763
5764 SolarMutexGuard aGuard;
5765 SetLastExceptionMsg();
5766
5767 LibLibreOffice_Impl *const pLib = static_cast<LibLibreOffice_Impl*>(pThis);
5768 pLib->mOptionalFeatures = features;
5769 if (features & LOK_FEATURE_PART_IN_INVALIDATION_CALLBACK)
5770 comphelper::LibreOfficeKit::setPartInInvalidation(true);
5771 if (features & LOK_FEATURE_NO_TILED_ANNOTATIONS)
5772 comphelper::LibreOfficeKit::setTiledAnnotations(false);
5773 if (features & LOK_FEATURE_RANGE_HEADERS)
5774 comphelper::LibreOfficeKit::setRangeHeaders(true);
5775 if (features & LOK_FEATURE_VIEWID_IN_VISCURSOR_INVALIDATION_CALLBACK)
5776 comphelper::LibreOfficeKit::setViewIdForVisCursorInvalidation(true);
5777}
5778
5779static void lo_setDocumentPassword(LibreOfficeKit* pThis,
5780 const char* pURL, const char* pPassword)
5781{
5782 comphelper::ProfileZone aZone("lo_setDocumentPassword");
5783
5784 SolarMutexGuard aGuard;
5785 SetLastExceptionMsg();
5786
5787 assert(pThis)(static_cast <bool> (pThis) ? void (0) : __assert_fail (
"pThis", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 5787, __extension__ __PRETTY_FUNCTION__))
;
5788 assert(pURL)(static_cast <bool> (pURL) ? void (0) : __assert_fail (
"pURL", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 5788, __extension__ __PRETTY_FUNCTION__))
;
5789 LibLibreOffice_Impl *const pLib = static_cast<LibLibreOffice_Impl*>(pThis);
5790 assert(pLib->mInteractionMap.find(OString(pURL)) != pLib->mInteractionMap.end())(static_cast <bool> (pLib->mInteractionMap.find(OString
(pURL)) != pLib->mInteractionMap.end()) ? void (0) : __assert_fail
("pLib->mInteractionMap.find(OString(pURL)) != pLib->mInteractionMap.end()"
, "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 5790, __extension__ __PRETTY_FUNCTION__))
;
5791 pLib->mInteractionMap.find(OString(pURL))->second->SetPassword(pPassword);
5792}
5793
5794static char* lo_getVersionInfo(SAL_UNUSED_PARAMETER__attribute__ ((unused)) LibreOfficeKit* /*pThis*/)
5795{
5796 SetLastExceptionMsg();
5797 return convertOUString(ReplaceStringHookProc(
5798 "{ "
5799 "\"ProductName\": \"%PRODUCTNAME\", "
5800 "\"ProductVersion\": \"%PRODUCTVERSION\", "
5801 "\"ProductExtension\": \"%PRODUCTEXTENSION\", "
5802 "\"BuildId\": \"%BUILDID\" "
5803 "}"));
5804}
5805
5806static void aBasicErrorFunc(const OUString& rError, const OUString& rAction)
5807{
5808 OString aBuffer = "Unexpected dialog: " +
5809 OUStringToOString(rAction, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))) +
5810 " Error: " +
5811 OUStringToOString(rError, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)));
5812
5813 fprintf(stderrstderr, "Unexpected basic error dialog '%s'\n", aBuffer.getStr());
5814}
5815
5816static bool initialize_uno(const OUString& aAppProgramURL)
5817{
5818#ifdef IOS
5819 // For iOS we already hardcode the inifile as "rc" in the .app directory.
5820 rtl::Bootstrap::setIniFilename(aAppProgramURL + "/" SAL_CONFIGFILE("fundamental")"fundamental" "rc");
5821 xContext = cppu::defaultBootstrap_InitialComponentContext(aAppProgramURL + "/rc");
5822#elif defined MACOSX
5823 rtl::Bootstrap::setIniFilename(aAppProgramURL + "/../Resources/" SAL_CONFIGFILE("soffice")"soffice" "rc");
5824 xContext = cppu::defaultBootstrap_InitialComponentContext();
5825#else
5826 rtl::Bootstrap::setIniFilename(aAppProgramURL + "/" SAL_CONFIGFILE("soffice")"soffice" "rc");
5827 xContext = cppu::defaultBootstrap_InitialComponentContext();
5828#endif
5829
5830 if (!xContext.is())
5831 {
5832 SetLastExceptionMsg("XComponentContext could not be created");
5833 SAL_INFO("lok", "XComponentContext could not be created")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "XComponentContext could not be created") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5833" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "XComponentContext could not be created"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "XComponentContext could not be created"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5833" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "XComponentContext could not be created") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5833" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "XComponentContext could not be created"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "XComponentContext could not be created"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5833" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
5834 return false;
5835 }
5836
5837 xFactory = xContext->getServiceManager();
5838 if (!xFactory.is())
5839 {
5840 SetLastExceptionMsg("XMultiComponentFactory could not be created");
5841 SAL_INFO("lok", "XMultiComponentFactory could not be created")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "XMultiComponentFactory could not be created") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5841" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "XMultiComponentFactory could not be created"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "XMultiComponentFactory could not be created"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5841" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "XMultiComponentFactory could not be created") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"
), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5841" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "XMultiComponentFactory could not be created"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "XMultiComponentFactory could not be created"; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5841" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
5842 return false;
5843 }
5844
5845 xSFactory.set(xFactory, uno::UNO_QUERY_THROW);
5846 comphelper::setProcessServiceFactory(xSFactory);
5847
5848 SAL_INFO("lok", "Uno initialized - " << xContext.is())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Uno initialized - " << xContext.is()) == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5848" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Uno initialized - " << xContext
.is()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Uno initialized - " << xContext.is(); ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5848" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Uno initialized - " << xContext.is()) == 1
) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"),
("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5848" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Uno initialized - " << xContext
.is()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Uno initialized - " << xContext.is(); ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "5848" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
5849
5850 // set UserInstallation to user profile dir in test/user-template
5851// rtl::Bootstrap aDefaultVars;
5852// aDefaultVars.set(OUString("UserInstallation"), aAppProgramURL + "../registry" );
5853 // configmgr setup ?
5854
5855 return true;
5856}
5857
5858// pre-unipoll version.
5859static void lo_startmain(void*)
5860{
5861 osl_setThreadName("lo_startmain");
5862
5863 if (comphelper::SolarMutex::get())
5864 Application::GetSolarMutex().tryToAcquire();
5865
5866 Application::UpdateMainThread();
5867
5868 soffice_main();
5869
5870 Application::ReleaseSolarMutex();
5871}
5872
5873// unipoll version.
5874static void lo_runLoop(LibreOfficeKit* /*pThis*/,
5875 LibreOfficeKitPollCallback pPollCallback,
5876 LibreOfficeKitWakeCallback pWakeCallback,
5877 void* pData)
5878{
5879#if defined(IOS) || defined(ANDROID)
5880 Application::GetSolarMutex().acquire();
5881#endif
5882
5883 {
5884 SolarMutexGuard aGuard;
5885
5886 vcl::lok::registerPollCallbacks(pPollCallback, pWakeCallback, pData);
5887 Application::UpdateMainThread();
5888 soffice_main();
5889 }
5890#if defined(IOS) || defined(ANDROID)
5891 vcl::lok::unregisterPollCallbacks();
5892 Application::ReleaseSolarMutex();
5893#endif
5894}
5895
5896static bool bInitialized = false;
5897
5898static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit::statusIndicatorCallbackType type, int percent)
5899{
5900 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(data);
5901
5902 if (!pLib->mpCallback)
5903 return;
5904
5905 switch (type)
5906 {
5907 case comphelper::LibreOfficeKit::statusIndicatorCallbackType::Start:
5908 pLib->mpCallback(LOK_CALLBACK_STATUS_INDICATOR_START, nullptr, pLib->mpCallbackData);
5909 break;
5910 case comphelper::LibreOfficeKit::statusIndicatorCallbackType::SetValue:
5911 pLib->mpCallback(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE,
5912 OUString(OUString::number(percent)).toUtf8().getStr(), pLib->mpCallbackData);
5913 break;
5914 case comphelper::LibreOfficeKit::statusIndicatorCallbackType::Finish:
5915 pLib->mpCallback(LOK_CALLBACK_STATUS_INDICATOR_FINISH, nullptr, pLib->mpCallbackData);
5916 break;
5917 }
5918}
5919
5920/// Used only by LibreOfficeKit when used by Online to pre-initialize
5921static void preloadData()
5922{
5923 comphelper::ProfileZone aZone("preload data");
5924
5925 // Create user profile in the temp directory for loading the dictionaries
5926 OUString sUserPath;
5927 rtl::Bootstrap::get("UserInstallation", sUserPath);
5928 utl::TempFile aTempDir(nullptr, true);
5929 aTempDir.EnableKillingFile();
5930 rtl::Bootstrap::set("UserInstallation", aTempDir.GetURL());
5931
5932 // Register the bundled extensions
5933 desktop::Desktop::SynchronizeExtensionRepositories(true);
5934 bool bAbort = desktop::Desktop::CheckExtensionDependencies();
5935 if(bAbort)
5936 std::cerr << "CheckExtensionDependencies failed" << std::endl;
5937
5938 // preload all available dictionaries
5939 css::uno::Reference<css::linguistic2::XLinguServiceManager> xLngSvcMgr =
5940 css::linguistic2::LinguServiceManager::create(comphelper::getProcessComponentContext());
5941 css::uno::Reference<linguistic2::XSpellChecker> xSpellChecker(xLngSvcMgr->getSpellChecker());
5942
5943 std::cerr << "Preloading dictionaries: ";
5944 css::uno::Reference<linguistic2::XSupportedLocales> xSpellLocales(xSpellChecker, css::uno::UNO_QUERY_THROW);
5945 uno::Sequence< css::lang::Locale > aLocales = xSpellLocales->getLocales();
5946 for (auto &it : aLocales)
5947 {
5948 std::cerr << it.Language << "_" << it.Country << " ";
5949 css::beans::PropertyValues aNone;
5950 xSpellChecker->isValid("forcefed", it, aNone);
5951 }
5952 std::cerr << "\n";
5953
5954 // Hack to load and cache the module liblocaledata_others.so which is not loaded normally
5955 // (when loading dictionaries of just non-Asian locales). Creating a XCalendar4 of one Asian locale
5956 // will cheaply load this missing "others" locale library. Appending an Asian locale in
5957 // LOK_ALLOWLIST_LANGUAGES env-var also works but at the cost of loading that dictionary.
5958 css::uno::Reference< css::i18n::XCalendar4 > xCal = css::i18n::LocaleCalendar2::create(comphelper::getProcessComponentContext());
5959 css::lang::Locale aAsianLocale = {"hi", "IN", ""};
5960 xCal->loadDefaultCalendar(aAsianLocale);
5961
5962 // preload all available thesauri
5963 css::uno::Reference<linguistic2::XThesaurus> xThesaurus(xLngSvcMgr->getThesaurus());
5964 css::uno::Reference<linguistic2::XSupportedLocales> xThesLocales(xSpellChecker, css::uno::UNO_QUERY_THROW);
5965 aLocales = xThesLocales->getLocales();
5966 std::cerr << "Preloading thesauri: ";
5967 for (auto &it : aLocales)
5968 {
5969 std::cerr << it.Language << "_" << it.Country << " ";
5970 css::beans::PropertyValues aNone;
5971 xThesaurus->queryMeanings("forcefed", it, aNone);
5972 }
5973 std::cerr << "\n";
5974
5975 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = css::ui::GlobalAcceleratorConfiguration::create(
5976 comphelper::getProcessComponentContext());
5977 xGlobalCfg->getAllKeyEvents();
5978
5979 std::cerr << "Preload icons\n";
5980 ImageTree &images = ImageTree::get();
5981 images.getImageUrl("forcefed.png", "style", "FO_oo");
5982
5983 std::cerr << "Preload languages\n";
5984
5985 // force load language singleton
5986 SvtLanguageTable::HasLanguageType(LANGUAGE_SYSTEMLanguageType(0x0000));
5987 (void)LanguageTag::isValidBcp47("foo", nullptr);
5988
5989 std::cerr << "Preload fonts\n";
5990
5991 // Initialize fonts.
5992 css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLangSrv = css::linguistic2::LinguServiceManager::create(xContext);
5993 if (xLangSrv.is())
5994 {
5995 css::uno::Reference<css::linguistic2::XSpellChecker> xSpell = xLangSrv->getSpellChecker();
5996 if (xSpell.is())
5997 aLocales = xSpell->getLocales();
5998 }
5999
6000 for (const auto& aLocale : std::as_const(aLocales))
6001 {
6002 //TODO: Add more types and cache more aggressively. For now this initializes the fontcache.
6003 using namespace ::com::sun::star::i18n::ScriptType;
6004 LanguageType nLang;
6005 nLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType(aLocale, false), LATIN);
6006 OutputDevice::GetDefaultFont(DefaultFontType::LATIN_SPREADSHEET, nLang, GetDefaultFontFlags::OnlyOne);
6007 nLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType(aLocale, false), ASIAN);
6008 OutputDevice::GetDefaultFont(DefaultFontType::CJK_SPREADSHEET, nLang, GetDefaultFontFlags::OnlyOne);
6009 nLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType(aLocale, false), COMPLEX);
6010 OutputDevice::GetDefaultFont(DefaultFontType::CTL_SPREADSHEET, nLang, GetDefaultFontFlags::OnlyOne);
6011 }
6012
6013 // Set user profile's path back to the original one
6014 rtl::Bootstrap::set("UserInstallation", sUserPath);
6015}
6016
6017namespace {
6018
6019class ProfileZoneDumper : public AutoTimer
6020{
6021 static const int dumpTimeoutMS = 5000;
6022public:
6023 ProfileZoneDumper() : AutoTimer( "zone dumper" )
6024 {
6025 SetTimeout(dumpTimeoutMS);
6026 Start();
6027 }
6028 virtual void Invoke() override
6029 {
6030 const css::uno::Sequence<OUString> aEvents =
6031 comphelper::ProfileRecording::getRecordingAndClear();
6032 OStringBuffer aOutput;
6033 for (const auto &s : aEvents)
6034 {
6035 aOutput.append(OUStringToOString(s, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))));
6036 aOutput.append("\n");
6037 }
6038 OString aChunk = aOutput.makeStringAndClear();
6039 if (gImpl && gImpl->mpCallback)
6040 gImpl->mpCallback(LOK_CALLBACK_PROFILE_FRAME, aChunk.getStr(), gImpl->mpCallbackData);
6041 }
6042};
6043
6044static void activateNotebookbar(const OUString& rApp)
6045{
6046 OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" + rApp;
6047
6048 const utl::OConfigurationTreeRoot aAppNode(xContext, aPath, true);
6049
6050 if (aAppNode.isValid())
6051 {
6052 aAppNode.setNodeValue("Active", makeAny(OUString("notebookbar.ui")));
6053 aAppNode.commit();
6054 }
6055}
6056
6057}
6058
6059static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char* pUserProfileUrl)
6060{
6061 enum {
6062 PRE_INIT, // setup shared data in master process
6063 SECOND_INIT, // complete init. after fork
6064 FULL_INIT // do a standard complete init.
6065 } eStage;
6066
6067 // Did we do a pre-initialize
6068 static bool bPreInited = false;
6069 static bool bUnipoll = false;
6070 static bool bProfileZones = false;
6071 static bool bNotebookbar = false;
6072
6073 { // cf. string lifetime for preinit
6074 std::vector<OUString> aOpts;
6075
6076 // ':' delimited options - avoiding ABI change for new parameters
6077 const char *pOptions = getenv("SAL_LOK_OPTIONS");
6078 if (pOptions)
6079 aOpts = comphelper::string::split(OUString(pOptions, strlen(pOptions), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))), ':');
6080 for (const auto &it : aOpts)
6081 {
6082 if (it == "unipoll")
6083 bUnipoll = true;
6084 else if (it == "profile_events")
6085 bProfileZones = true;
6086 else if (it == "sc_no_grid_bg")
6087 comphelper::LibreOfficeKit::setCompatFlag(
6088 comphelper::LibreOfficeKit::Compat::scNoGridBackground);
6089 else if (it == "sc_print_twips_msgs")
6090 comphelper::LibreOfficeKit::setCompatFlag(
6091 comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
6092 else if (it == "notebookbar")
6093 bNotebookbar = true;
6094 }
6095 }
6096
6097 // What stage are we at ?
6098 if (pThis == nullptr)
6099 eStage = PRE_INIT;
6100 else if (bPreInited)
6101 eStage = SECOND_INIT;
6102 else
6103 eStage = FULL_INIT;
6104
6105 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
6106
6107 if (bInitialized)
6108 return 1;
6109
6110 // Turn profile zones on early
6111 if (bProfileZones && eStage == SECOND_INIT)
6112 {
6113 comphelper::ProfileRecording::startRecording(true);
6114 new ProfileZoneDumper();
6115 }
6116
6117 comphelper::ProfileZone aZone("lok-init");
6118
6119 if (eStage == PRE_INIT)
6120 rtl_alloc_preInit(true);
6121 else if (eStage == SECOND_INIT)
6122 rtl_alloc_preInit(false);
6123
6124 if (eStage != SECOND_INIT)
6125 comphelper::LibreOfficeKit::setActive();
6126
6127 if (eStage != PRE_INIT)
6128 comphelper::LibreOfficeKit::setStatusIndicatorCallback(lo_status_indicator_callback, pLib);
6129
6130 if (pUserProfileUrl && eStage != PRE_INIT)
6131 {
6132 OUString url(
6133 pUserProfileUrl, strlen(pUserProfileUrl), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
6134 OUString path;
6135 if (url.startsWithIgnoreAsciiCase("vnd.sun.star.pathname:", &path))
6136 {
6137 OUString url2;
6138 osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath(
6139 path, url2);
6140 if (e == osl::FileBase::E_None)
6141 url = url2;
6142 else
6143 SAL_WARN("lok", "resolving <" << url << "> failed with " << +e)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "resolving <" << url << "> failed with "
<< +e) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6143" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "resolving <" << url <<
"> failed with " << +e), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "resolving <"
<< url << "> failed with " << +e; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6143" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "resolving <" << url << "> failed with "
<< +e) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6143" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "resolving <" << url <<
"> failed with " << +e), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "resolving <"
<< url << "> failed with " << +e; ::sal
::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6143" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6144 }
6145 rtl::Bootstrap::set("UserInstallation", url);
6146 if (eStage == SECOND_INIT)
6147 utl::Bootstrap::reloadData();
6148 }
6149
6150 OUString aAppPath;
6151 if (pAppPath)
6152 {
6153 aAppPath = OUString(pAppPath, strlen(pAppPath), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)));
6154 }
6155 else
6156 {
6157#ifdef ANDROID
6158 aAppPath = OUString::fromUtf8(lo_get_app_data_dir()) + "/program";
6159#else
6160 // Fun conversion dance back and forth between URLs and system paths...
6161 OUString aAppURL;
6162 ::osl::Module::getUrlFromAddress( reinterpret_cast< oslGenericFunction >(lo_initialize),
6163 aAppURL);
6164 osl::FileBase::getSystemPathFromFileURL( aAppURL, aAppPath );
6165#endif
6166
6167#ifdef IOS
6168 // The above gives something like
6169 // "/private/var/containers/Bundle/Application/953AA851-CC15-4C60-A2CB-C2C6F24E6F71/Foo.app/Foo",
6170 // and we want to drop the final component (the binary name).
6171 sal_Int32 lastSlash = aAppPath.lastIndexOf('/');
6172 assert(lastSlash > 0)(static_cast <bool> (lastSlash > 0) ? void (0) : __assert_fail
("lastSlash > 0", "/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
, 6172, __extension__ __PRETTY_FUNCTION__))
;
6173 aAppPath = aAppPath.copy(0, lastSlash);
6174#endif
6175 }
6176
6177 OUString aAppURL;
6178 if (osl::FileBase::getFileURLFromSystemPath(aAppPath, aAppURL) != osl::FileBase::E_None)
6179 return 0;
6180
6181#ifdef IOS
6182 // A LibreOffice-using iOS app should have the ICU data file in the app bundle. Initialize ICU
6183 // to use that.
6184 NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
6185
6186 int fd = open([[bundlePath stringByAppendingPathComponent:@"ICU.dat"] UTF8String], O_RDONLY);
6187 if (fd == -1)
6188 NSLog(@"Could not open ICU data file %s", [[bundlePath stringByAppendingPathComponent:@"ICU.dat"] UTF8String]);
6189 else
6190 {
6191 struct stat st;
6192 if (fstat(fd, &st) == -1)
6193 NSLog(@"fstat on ICU data file failed: %s", strerror(errno(*__errno_location ())));
6194 else
6195 {
6196 void *icudata = mmap(0, (size_t) st.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
6197 if (icudata == MAP_FAILED)
6198 NSLog(@"mmap failed: %s", strerror(errno(*__errno_location ())));
6199 else
6200 {
6201 UErrorCode icuStatus = U_ZERO_ERROR;
6202 udata_setCommonDataudata_setCommonData_67(icudata, &icuStatus);
6203 if (U_FAILURE(icuStatus))
6204 NSLog(@"udata_setCommonData failed");
6205 else
6206 {
6207 // Quick test that ICU works...
6208 UConverter *cnv = ucnv_openucnv_open_67("iso-8859-3", &icuStatus);
6209 if (U_SUCCESS(icuStatus))
6210 ucnv_closeucnv_close_67(cnv);
6211 else
6212 NSLog(@"ucnv_open() failed: %s", u_errorNameu_errorName_67(icuStatus));
6213 }
6214 }
6215 }
6216 close(fd);
6217 }
6218#endif
6219
6220 try
6221 {
6222 if (eStage != SECOND_INIT)
6223 {
6224 SAL_INFO("lok", "Attempting to initialize UNO")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Attempting to initialize UNO") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6224" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Attempting to initialize UNO"), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Attempting to initialize UNO"; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6224" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Attempting to initialize UNO") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6224" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Attempting to initialize UNO"), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Attempting to initialize UNO"; ::sal::detail::log(
(::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6224" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6225
6226 if (!initialize_uno(aAppURL))
6227 return false;
6228
6229 // Force headless -- this is only for bitmap rendering.
6230 rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
6231
6232 // We specifically need to make sure we have the "headless"
6233 // command arg set (various code specifically checks via
6234 // CommandLineArgs):
6235 desktop::Desktop::GetCommandLineArgs().setHeadless();
6236
6237#ifdef IOS
6238 if (InitVCL() && [NSThread isMainThread])
6239 {
6240 static bool bFirstTime = true;
6241 if (bFirstTime)
6242 {
6243 Application::GetSolarMutex().release();
6244 bFirstTime = false;
6245 }
6246 }
6247 SfxApplication::GetOrCreate();
6248#endif
6249
6250#if HAVE_FEATURE_ANDROID_LOK0
6251 // Register the bundled extensions - so that the dictionaries work
6252 desktop::Desktop::SynchronizeExtensionRepositories(false);
6253 bool bFailed = desktop::Desktop::CheckExtensionDependencies();
6254 if (bFailed)
6255 SAL_INFO("lok", "CheckExtensionDependencies failed")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "CheckExtensionDependencies failed") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6255" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "CheckExtensionDependencies failed")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "CheckExtensionDependencies failed"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6255" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "CheckExtensionDependencies failed") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6255" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "CheckExtensionDependencies failed")
, 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "CheckExtensionDependencies failed"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6255" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6256#endif
6257
6258 if (eStage == PRE_INIT)
6259 {
6260 {
6261 comphelper::ProfileZone aInit("Init vcl");
6262 std::cerr << "Init vcl\n";
6263 InitVCL();
6264 }
6265
6266 // pre-load all graphic libraries.
6267 GraphicFilter::GetGraphicFilter().preload();
6268
6269 // pre-load all component libraries.
6270 if (!xContext.is())
6271 throw css::uno::DeploymentException("preInit: XComponentContext is not created");
6272
6273 css::uno::Reference< css::uno::XInterface > xService;
6274 xContext->getValueByName("/singletons/com.sun.star.lang.theServiceManager") >>= xService;
6275 if (!xService.is())
6276 throw css::uno::DeploymentException("preInit: XMultiComponentFactory is not created");
6277
6278 css::uno::Reference<css::lang::XInitialization> aService(
6279 xService, css::uno::UNO_QUERY_THROW);
6280
6281 // pre-requisites:
6282 // In order to load implementations and invoke
6283 // component factory it is required:
6284 // 1) defaultBootstrap_InitialComponentContext()
6285 // 2) comphelper::setProcessServiceFactory(xSFactory);
6286 // 3) InitVCL()
6287 {
6288 comphelper::ProfileZone aInit("preload");
6289 aService->initialize({css::uno::makeAny<OUString>("preload")});
6290 }
6291 { // Force load some modules
6292 comphelper::ProfileZone aInit("preload modules");
6293 VclBuilder::preload();
6294 VclAbstractDialogFactory::Create();
6295 }
6296
6297 preloadData();
6298
6299 // Release Solar Mutex, lo_startmain thread should acquire it.
6300 Application::ReleaseSolarMutex();
6301 }
6302
6303 setLanguageAndLocale("en-US");
6304 }
6305
6306 if (eStage != PRE_INIT)
6307 {
6308 SAL_INFO("lok", "Re-initialize temp paths")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Re-initialize temp paths") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6308" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Re-initialize temp paths"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Re-initialize temp paths"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6308" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Re-initialize temp paths") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6308" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Re-initialize temp paths"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Re-initialize temp paths"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6308" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6309 SvtPathOptions aOptions;
6310 OUString aNewTemp;
6311 osl::FileBase::getTempDirURL(aNewTemp);
6312 aOptions.SetTempPath(aNewTemp);
6313 desktop::Desktop::CreateTemporaryDirectory();
6314
6315 // The RequestHandler is specifically set to be ready when all the other
6316 // init in Desktop::Main (run from soffice_main) is done. We can enable
6317 // the RequestHandler here (without starting any IPC thread;
6318 // shortcutting the invocation in Desktop::Main that would start the IPC
6319 // thread), and can then use it to wait until we're definitely ready to
6320 // continue.
6321
6322 SAL_INFO("lok", "Enabling RequestHandler")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Enabling RequestHandler") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6322" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Enabling RequestHandler"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Enabling RequestHandler"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6322" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Enabling RequestHandler") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6322" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Enabling RequestHandler"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Enabling RequestHandler"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6322" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6323 RequestHandler::Enable(false);
6324 SAL_INFO("lok", "Starting soffice_main")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Starting soffice_main") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6324" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Starting soffice_main"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Starting soffice_main"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6324" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Starting soffice_main") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6324" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Starting soffice_main"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Starting soffice_main"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6324" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6325 RequestHandler::SetReady(false);
6326 if (!bUnipoll)
6327 {
6328 // Start the main thread only in non-unipoll mode (i.e. multithreaded).
6329 pLib->maThread = osl_createThread(lo_startmain, nullptr);
6330 SAL_INFO("lok", "Waiting for RequestHandler")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Waiting for RequestHandler") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6330" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Waiting for RequestHandler"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Waiting for RequestHandler"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6330" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Waiting for RequestHandler") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6330" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Waiting for RequestHandler"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Waiting for RequestHandler"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6330" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6331 RequestHandler::WaitForReady();
6332 SAL_INFO("lok", "RequestHandler ready -- continuing")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "RequestHandler ready -- continuing") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6332" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "RequestHandler ready -- continuing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "RequestHandler ready -- continuing"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6332" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "RequestHandler ready -- continuing") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6332" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "RequestHandler ready -- continuing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "RequestHandler ready -- continuing"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6332" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6333 }
6334 else
6335 InitVCL();
6336 }
6337
6338 if (eStage != SECOND_INIT)
6339 ErrorRegistry::RegisterDisplay(aBasicErrorFunc);
6340
6341 SAL_INFO("lok", "LOK Initialized")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "LOK Initialized") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6341" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "LOK Initialized"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"LOK Initialized"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6341" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "LOK Initialized") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6341" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "LOK Initialized"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"LOK Initialized"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6341" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6342 if (eStage == PRE_INIT)
6343 bPreInited = true;
6344 else
6345 bInitialized = true;
6346 }
6347 catch (css::uno::Exception& exception)
6348 {
6349 fprintf(stderrstderr, "Bootstrapping exception '%s'\n",
6350 OUStringToOString(exception.Message, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))).getStr());
6351 }
6352
6353 if (eStage == PRE_INIT)
6354 {
6355 comphelper::ThreadPool::getSharedOptimalPool().shutdown();
6356 }
6357
6358// Turn off quick editing on IOS and ANDROID
6359#if defined IOS || defined ANDROID
6360 if (officecfg::Office::Impress::Misc::TextObject::QuickEditing::get())
6361 {
6362 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
6363 officecfg::Office::Impress::Misc::TextObject::QuickEditing::set(false, batch);
6364 batch->commit();
6365 }
6366#endif
6367
6368 if (bNotebookbar)
6369 {
6370 activateNotebookbar("Writer");
6371 activateNotebookbar("Calc");
6372 activateNotebookbar("Impress");
6373 }
6374
6375 return bInitialized;
6376}
6377
6378SAL_JNI_EXPORT__attribute__ ((visibility("default")))
6379LibreOfficeKit *libreofficekit_hook_2(const char* install_path, const char* user_profile_url)
6380{
6381 if (!gImpl)
6382 {
6383 SAL_INFO("lok", "Create libreoffice object")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Create libreoffice object") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6383" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Create libreoffice object"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Create libreoffice object"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6383" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Create libreoffice object") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6383" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Create libreoffice object"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Create libreoffice object"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6383" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6384
6385 gImpl = new LibLibreOffice_Impl();
6386 if (!lo_initialize(gImpl, install_path, user_profile_url))
6387 {
6388 lo_destroy(gImpl);
6389 }
6390 }
6391 return static_cast<LibreOfficeKit*>(gImpl);
6392}
6393
6394SAL_JNI_EXPORT__attribute__ ((visibility("default")))
6395LibreOfficeKit *libreofficekit_hook(const char* install_path)
6396{
6397 return libreofficekit_hook_2(install_path, nullptr);
6398}
6399
6400SAL_JNI_EXPORT__attribute__ ((visibility("default")))
6401int lok_preinit(const char* install_path, const char* user_profile_url)
6402{
6403 return lo_initialize(nullptr, install_path, user_profile_url);
6404}
6405
6406static void lo_destroy(LibreOfficeKit* pThis)
6407{
6408 SolarMutexClearableGuard aGuard;
6409
6410 LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
6411 gImpl = nullptr;
6412
6413 SAL_INFO("lok", "LO Destroy")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "LO Destroy") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6413" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "LO Destroy"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "LO Destroy"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6413" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "LO Destroy") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6413" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "LO Destroy"), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "LO Destroy"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6413" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6414
6415 comphelper::LibreOfficeKit::setStatusIndicatorCallback(nullptr, nullptr);
6416 uno::Reference <frame::XDesktop2> xDesktop = frame::Desktop::create ( ::comphelper::getProcessComponentContext() );
6417 // FIXME: the terminate() call here is a no-op because it detects
6418 // that LibreOfficeKit::isActive() and then returns early!
6419 bool bSuccess = xDesktop.is() && xDesktop->terminate();
6420
6421 if (!bSuccess)
6422 {
6423 bSuccess = GetpApp() && GetpApp()->QueryExit();
6424 }
6425
6426 if (!bSuccess)
6427 {
6428 Application::Quit();
6429 }
6430
6431 aGuard.clear();
6432
6433 osl_joinWithThread(pLib->maThread);
6434 osl_destroyThread(pLib->maThread);
6435
6436 delete pLib;
6437 bInitialized = false;
6438 SAL_INFO("lok", "LO Destroy Done")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "LO Destroy Done") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6438" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "LO Destroy Done"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"LO Destroy Done"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6438" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "LO Destroy Done") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6438" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "LO Destroy Done"), 0); } else { ::std
::ostringstream sal_detail_stream; sal_detail_stream <<
"LO Destroy Done"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("lok"), ("/home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx"
":" "6438" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
6439}
6440
6441#ifdef IOS
6442
6443// Used by the unmaintained LibreOfficeLight app. Once that has been retired, get rid of this, too.
6444
6445__attribute__((visibility("default")))
6446void temporaryHackToInvokeCallbackHandlers(LibreOfficeKitDocument* pThis)
6447{
6448 SolarMutexGuard aGuard;
6449 LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
6450
6451 int nOrigViewId = doc_getView(pThis);
6452
6453 if (nOrigViewId >= 0 && pDocument->mpCallbackFlushHandlers[nOrigViewId])
6454 {
6455 pDocument->mpCallbackFlushHandlers[nOrigViewId]->Invoke();
6456 }
6457}
6458
6459#endif
6460
6461} // extern "C"
6462
6463/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
11
Calling 'Reference::clear'
18
Returning; memory was released
205 if (aTmp.get()) {
19
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
10
Calling 'VclPtr::disposeAndClear'
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
6
Memory is allocated
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody
11.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
11.1
Field 'm_pBody' is non-null
)
12
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
13
Calling 'VclReferenceBase::release'
17
Returning; memory was released
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
20
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
14
Assuming the condition is true
15
Taking true branch
40 delete this;
16
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif