Bug Summary

File:home/maarten/src/libreoffice/core/desktop/source/lib/init.cxx
Warning:line 2995, column 9
Called C++ object pointer is null

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;
1
Calling default constructor for 'SolarMutexGuard'
8
Returning from default constructor for 'SolarMutexGuard'
2989 if (gImpl)
9
Assuming 'gImpl' is null
10
Taking false branch
2990 gImpl->maLastExceptionMsg.clear();
2991
2992 ITiledRenderable* pDoc = getTiledRenderable(pThis);
2993 if (!pDoc)
11
Assuming 'pDoc' is null
12
Taking true branch
2994 {
2995 gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
13
Called C++ object pointer is null
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);
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);
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)
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 >= 0)
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);
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}
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/svapp.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_SVAPP_HXX
21#define INCLUDED_VCL_SVAPP_HXX
22
23#include <sal/config.h>
24#include <sal/types.h>
25
26#include <cassert>
27#include <vector>
28
29#include <comphelper/solarmutex.hxx>
30#include <osl/mutex.hxx>
31#include <rtl/ustring.hxx>
32#include <osl/thread.h>
33#include <tools/gen.hxx>
34#include <tools/link.hxx>
35#include <vcl/dllapi.h>
36#include <vcl/inputtypes.hxx>
37#include <vcl/exceptiontypes.hxx>
38#include <vcl/vclevent.hxx>
39#include <vcl/vclenum.hxx>
40#include <i18nlangtag/lang.h>
41#include <o3tl/typed_flags_set.hxx>
42#include <com/sun/star/uno/Reference.h>
43
44
45class BitmapEx;
46namespace weld
47{
48 class Builder;
49 class MessageDialog;
50 class Widget;
51 class Window;
52}
53class LocaleDataWrapper;
54class AllSettings;
55class DataChangedEvent;
56class Accelerator;
57class Help;
58class OutputDevice;
59namespace vcl { class Window; }
60namespace vcl { class KeyCode; }
61class NotifyEvent;
62class KeyEvent;
63class MouseEvent;
64class GestureEvent;
65struct ImplSVEvent;
66struct ConvertData;
67
68namespace com::sun::star::uno {
69 class XComponentContext;
70}
71namespace com::sun::star::ui::dialogs {
72 class XFilePicker2;
73 class XFolderPicker2;
74}
75namespace com::sun::star::awt {
76 class XToolkit;
77 class XDisplayConnection;
78 class XWindow;
79}
80
81// helper needed by SalLayout implementations as well as svx/source/dialog/svxbmpnumbalueset.cxx
82VCL_DLLPUBLIC__attribute__ ((visibility("default"))) sal_UCS4 GetMirroredChar( sal_UCS4 );
83VCL_DLLPUBLIC__attribute__ ((visibility("default"))) sal_UCS4 GetLocalizedChar( sal_UCS4, LanguageType );
84
85enum class SystemWindowFlags {
86 NOAUTOMODE = 0x0001,
87 DIALOG = 0x0002
88};
89namespace o3tl
90{
91 template<> struct typed_flags<SystemWindowFlags> : is_typed_flags<SystemWindowFlags, 0x03> {};
92}
93
94typedef long (*VCLEventHookProc)( NotifyEvent& rEvt, void* pData );
95
96/** An application can be notified of a number of different events:
97 - Type::Accept - listen for connection to the application (a connection
98 string is passed via the event)
99 - Type::Unaccept - stops listening for a connection to the app (determined by
100 a connection string passed via the event)
101 - Type::Appear - brings the app to the front (i.e. makes it "appear")
102 - Type::Version - display the app version
103 - Type::Help - opens a help topic (help topic passed as string)
104 - Type::OpenHELP_URL - opens a help URL (URL passed as a string)
105 - Type::ShowDialog - shows a dialog (dialog passed as a string)
106 - Type::Open - opens a document or group of documents (documents passed
107 as an array of strings)
108 - Type::Print - print a document or group of documents (documents passed
109 as an array of strings
110 - Type::PrivateDoShutdown - shutdown the app
111*/
112
113class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) ApplicationEvent
114{
115public:
116 enum class Type {
117 Accept, ///< Listen for connections
118 Appear, ///< Make application appear
119 Open, ///< Open a document
120 OpenHelpUrl, ///< Open a help URL
121 Print, ///< Print document
122 PrivateDoShutdown, ///< Shutdown application
123 QuickStart, ///< Start QuickStart
124 ShowDialog, ///< Show a dialog
125 Unaccept ///< Stop listening for connections
126 };
127
128 /** Explicit constructor for ApplicationEvent.
129
130 @attention Type::Appear, Type::PrivateDoShutdown and
131 Type::QuickStart are the \em only events that don't need to include
132 a data string with the event. No other events should use this
133 constructor!
134 */
135 explicit ApplicationEvent(Type type): aEvent(type)
136 {
137 assert(type == Type::Appear || type == Type::PrivateDoShutdown || type == Type::QuickStart)(static_cast <bool> (type == Type::Appear || type == Type
::PrivateDoShutdown || type == Type::QuickStart) ? void (0) :
__assert_fail ("type == Type::Appear || type == Type::PrivateDoShutdown || type == Type::QuickStart"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
137, __extension__ __PRETTY_FUNCTION__))
;
138 }
139
140 /** Constructor for ApplicationEvent, accepts a string for the data
141 associated with the event.
142
143 @attention Type::Accept, Type::OpenHelpUrl, Type::ShowDialog
144 and Type::Unaccept are the \em only events that accept a single
145 string as event data. No other events should use this constructor!
146 */
147 ApplicationEvent(Type type, OUString const & data): aEvent(type)
148 {
149 assert((static_cast <bool> (type == Type::Accept || type == Type
::OpenHelpUrl || type == Type::ShowDialog || type == Type::Unaccept
) ? void (0) : __assert_fail ("type == Type::Accept || type == Type::OpenHelpUrl || type == Type::ShowDialog || type == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
151, __extension__ __PRETTY_FUNCTION__))
150 type == Type::Accept || type == Type::OpenHelpUrl(static_cast <bool> (type == Type::Accept || type == Type
::OpenHelpUrl || type == Type::ShowDialog || type == Type::Unaccept
) ? void (0) : __assert_fail ("type == Type::Accept || type == Type::OpenHelpUrl || type == Type::ShowDialog || type == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
151, __extension__ __PRETTY_FUNCTION__))
151 || type == Type::ShowDialog || type == Type::Unaccept)(static_cast <bool> (type == Type::Accept || type == Type
::OpenHelpUrl || type == Type::ShowDialog || type == Type::Unaccept
) ? void (0) : __assert_fail ("type == Type::Accept || type == Type::OpenHelpUrl || type == Type::ShowDialog || type == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
151, __extension__ __PRETTY_FUNCTION__))
;
152 aData.push_back(data);
153 }
154
155 /** Constructor for ApplicationEvent, accepts an array of strings for
156 the data associated with the event.
157
158 @attention Type::Open and Type::Print can apply to multiple documents,
159 and are the \em only events that accept an array of strings. No other
160 events should use this constructor.
161 */
162 ApplicationEvent(Type type, std::vector<OUString> const & data):
163 aEvent(type), aData(data)
164 {
165 assert(type == Type::Open || type == Type::Print)(static_cast <bool> (type == Type::Open || type == Type
::Print) ? void (0) : __assert_fail ("type == Type::Open || type == Type::Print"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
165, __extension__ __PRETTY_FUNCTION__))
;
166 }
167
168 /** Get the type of event.
169
170 @returns The type of event.
171 */
172 Type GetEvent() const
173 {
174 return aEvent;
175 }
176
177 /** Gets the application event's data string.
178
179 @attention The \em only events that need a single string Type::Accept,
180 Type::OpenHelpUrl, Type::ShowDialog and Type::Unaccept
181
182 @returns The event's data string.
183 */
184 OUString const & GetStringData() const
185 {
186 assert((static_cast <bool> (aEvent == Type::Accept || aEvent ==
Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent ==
Type::Unaccept) ? void (0) : __assert_fail ("aEvent == Type::Accept || aEvent == Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
189, __extension__ __PRETTY_FUNCTION__))
187 aEvent == Type::Accept(static_cast <bool> (aEvent == Type::Accept || aEvent ==
Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent ==
Type::Unaccept) ? void (0) : __assert_fail ("aEvent == Type::Accept || aEvent == Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
189, __extension__ __PRETTY_FUNCTION__))
188 || aEvent == Type::OpenHelpUrl || aEvent == Type::ShowDialog(static_cast <bool> (aEvent == Type::Accept || aEvent ==
Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent ==
Type::Unaccept) ? void (0) : __assert_fail ("aEvent == Type::Accept || aEvent == Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
189, __extension__ __PRETTY_FUNCTION__))
189 || aEvent == Type::Unaccept)(static_cast <bool> (aEvent == Type::Accept || aEvent ==
Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent ==
Type::Unaccept) ? void (0) : __assert_fail ("aEvent == Type::Accept || aEvent == Type::OpenHelpUrl || aEvent == Type::ShowDialog || aEvent == Type::Unaccept"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
189, __extension__ __PRETTY_FUNCTION__))
;
190 assert(aData.size() == 1)(static_cast <bool> (aData.size() == 1) ? void (0) : __assert_fail
("aData.size() == 1", "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx"
, 190, __extension__ __PRETTY_FUNCTION__))
;
191 return aData[0];
192 }
193
194 /** Gets the event's array of strings.
195
196 @attention The \em only events that need an array of strings
197 are Type::Open and Type::Print.
198 */
199 std::vector<OUString> const & GetStringsData() const
200 {
201 assert(aEvent == Type::Open || aEvent == Type::Print)(static_cast <bool> (aEvent == Type::Open || aEvent == Type
::Print) ? void (0) : __assert_fail ("aEvent == Type::Open || aEvent == Type::Print"
, "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx",
201, __extension__ __PRETTY_FUNCTION__))
;
202 return aData;
203 }
204
205private:
206 Type aEvent;
207 std::vector<OUString> aData;
208};
209
210enum class DialogCancelMode {
211 Off, ///< do not automatically cancel dialogs
212 Silent, ///< silently cancel any dialogs
213 Fatal ///< cancel any dialogs by std::abort
214};
215
216/**
217 @brief Base class used mainly for the LibreOffice Desktop class.
218
219 The Application class is a base class mainly used by the Desktop
220 class. It is really meant to be subclassed, and the Main() function
221 should be overridden. Many of the ImplSVData members should be
222 moved to this class.
223
224 The reason Application exists is because the VCL used to be a
225 standalone framework, long since abandoned by anything other than
226 our application.
227
228 @see Desktop, ImplSVData
229 */
230class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) Application
231{
232public:
233 /** @name Initialization
234 The following functions perform initialization and deinitialization
235 of the application.
236 */
237 ///@{
238
239 /** Default constructor for Application class.
240
241 Initializes the LibreOffice global instance data structure if needed,
242 and then sets itself to be the Application class. Also initializes any
243 platform specific data structures.
244
245 @attention The initialization of the application itself is done in Init()
246 */
247 Application();
248
249 /** Virtual destructor for Application class.
250
251 Deinitializes the LibreOffice global instance data structure, then
252 deinitializes any platform specific data structures.
253 */
254 virtual ~Application();
255
256 /** Initialize the application itself.
257
258 @attention Note that the global data structures and platform specific
259 initialization is done in the constructor.
260
261 @see InitFinished, DeInit
262 */
263 virtual void Init();
264
265 /** Finish initialization of the application.
266
267 @see Init, DeInit
268 */
269 virtual void InitFinished();
270
271 /** Deinitialized the application itself.
272
273 @attention Note that the global data structures and platform specific
274 deinitialization is done in the destructor.
275
276 @see Init, InitFinished
277 */
278 virtual void DeInit();
279
280 ///@}
281
282 /** @brief Pure virtual entrypoint to the application.
283
284 Main() is the pure virtual entrypoint to your application. You
285 inherit your class from Application and subclass this function to
286 implement an application.
287
288 The Main() function does not pass in command line parameters,
289 you must use the functions GetCommandLineParamCount() and
290 GetCommandLineParam() to get these values as these are platform
291 independent ways of getting the command line (use GetAppFileName()
292 to get the invoked executable filename).
293
294 Once in this function, you create windows, etc. then call on
295 Execute() to start the application's main event loop.
296
297 An example code snippet follows (it won't compile, this just gives the
298 general flavour of the framework and is adapted from an old HelloWorld
299 example program that Star Division used to provide as part of their
300 library).
301
302 \code{.cpp}
303 class TheApplication : public Application
304 {
305 public:
306 virtual void Main();
307 };
308
309 class TheWindow : public WorkWindow
310 {
311 public:
312 TheWindow(vcl::Window *parent, WinBits windowStyle) :
313 WorkWindow(parent, windowStyle) {}
314
315 virtual void Paint(const Rectangle &);
316 };
317
318 void TheWindow::Paint(const Rectangle&)
319 {
320 DrawText(Point(100,100), String("Hello World!"));
321 }
322
323 void TheApplication::Main()
324 {
325 TheWindow aWindow(NULL, WB_APP | WB_STDWORK);
326 aWindow.Show();
327 Execute();
328 }
329
330 TheApplication anApplication;
331 \endcode
332
333 Some examples in the source tree can be found here:
334
335 vcl/workben/svdem.cxx
336
337 This is an example of how to use the Application and WorkWindow. Unfortunately, it
338 no longer compiles.
339
340 vcl/fpicker/test/svdem.cxx
341 */
342 virtual int Main();
343
344 /** Exit from the application
345
346 @returns true if exited successfully, false if not able to fully exit
347 */
348 virtual bool QueryExit();
349
350 virtual void Shutdown();
351
352 /** @name Change Notification Functions
353
354 Functions that notify when changes occur in the application.
355 */
356 ///@{
357
358 /** Notify all windows that the application has changed data.
359
360 @param rDCEvt Reference to a DataChangedEvent object
361
362 @see DataChanged
363 */
364 static void NotifyAllWindows( DataChangedEvent& rDCEvt );
365
366 ///@}
367
368 /** @name Command Line Processing
369
370 Command line processing is done via the following functions. They
371 give the number of parameters, the parameters themselves and a way
372 to get the name of the invoking application.
373 */
374
375 ///@{
376
377 /** Gets the number of command line parameters passed to the application
378
379 @return sal_uInt16 - the number of parameters
380
381 @see GetCommandLineParam, GetAppFileName
382 */
383 static sal_uInt16 GetCommandLineParamCount();
384
385 /** Gets a particular command line parameter
386
387 @param nParam The index of the parameter to return.
388
389 @return The command line parameter as an OUString
390
391 @see GetCommandLineParamCount, GetAppFileName
392 */
393 static OUString GetCommandLineParam( sal_uInt16 nParam );
394
395 /** Get the name of the file used to start the application
396
397 @return The filename as an OUString
398
399 @see GetCommandLineParamCount, GetCommandLineParam
400 */
401 static OUString GetAppFileName();
402
403 ///@}
404
405 /** @name Error Handling
406
407 \em Very rudimentary error handling is done by these
408 functions.
409
410 @{
411 */
412
413 /** Handles an error.
414
415 @param nCategory The error category, see include/vcl/exceptiontypes.hxx
416
417 @see Abort
418 */
419 virtual void Exception( ExceptionCategory nCategory );
420
421 /** Ends the program prematurely with an error message.
422
423 If the \code --norestore \endcode command line argument is given (assuming
424 this process is run by developers who are interested in cores,
425 vs. end users who are not) then it does a coredump.
426
427 @param rErrorText The error message to report.
428
429 @see Exception
430 */
431 static void Abort( const OUString& rErrorText );
432
433 ///@}
434
435 /** @name Event Loop Functions
436
437 Functions that handle the LibreOffice main event loop are here,
438 including a global lock called the Solar Mutex.
439 */
440 ///@{
441
442 /** Run the main event processing loop until it is quit by Quit().
443
444 @see Quit, Reschedule, Yield, EndYield, GetSolarMutex,
445 IsMainThread, ReleaseSolarMutex, AcquireSolarMutex,
446 */
447 static void Execute();
448
449 /** Quit the program
450
451 @see Execute, Reschedule, Yield, EndYield, GetSolarMutex,
452 IsMainThread, ReleaseSolarMutex, AcquireSolarMutex,
453 */
454 static void Quit();
455
456 /** Attempt to process current pending event(s)
457
458 It doesn't sleep if no events are available for processing.
459 This doesn't process any events generated after invoking the function.
460 So in contrast to Scheduler::ProcessEventsToIdle, this cannot become
461 busy-locked by an event-generating event in the event queue.
462
463 @param bHandleAllCurrentEvents If set to true, then try to process all
464 the current events. If set to false, then only process one event.
465 Defaults to false.
466
467 @returns true if any event was processed.
468
469 @see Yield, Scheduler::ProcessEventsToIdle
470 */
471 static bool Reschedule( bool bHandleAllCurrentEvents = false );
472
473 /** Process the next event.
474
475 It sleeps if no event is available for processing and just returns
476 if an event was processed.
477
478 @see Execute, Quit, Reschedule, EndYield, GetSolarMutex,
479 IsMainThread, ReleaseSolarMutex, AcquireSolarMutex,
480 */
481 static void Yield();
482
483 /**
484
485 @see Execute, Quit, Reschedule, Yield, GetSolarMutex,
486 IsMainThread, ReleaseSolarMutex, AcquireSolarMutex,
487 */
488 static void EndYield();
489
490 /** @brief Get the Solar Mutex for this thread.
491
492 Get the Solar Mutex that prevents other threads from accessing VCL
493 concurrently.
494
495 @returns SolarMutex reference
496
497 @see Execute, Quit, Reschedule, Yield, EndYield,
498 IsMainThread, ReleaseSolarMutex, AcquireSolarMutex,
499 */
500 static comphelper::SolarMutex& GetSolarMutex();
501
502 /** Queries whether we are in main thread.
503
504 @returns true if we are in main thread, false if not
505
506 @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
507 ReleaseSolarMutex, AcquireSolarMutex,
508 */
509 static bool IsMainThread();
510
511 /** @brief Release Solar Mutex(es) for this thread
512
513 Release the Solar Mutex(es) that prevents other threads from accessing
514 VCL concurrently.
515
516 @returns The number of mutexes that were acquired by this thread.
517
518 @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
519 IsMainThread, AcquireSolarMutex,
520 */
521 static sal_uInt32 ReleaseSolarMutex();
522
523 /** @brief Acquire Solar Mutex(es) for this thread.
524
525 Acquire the Solar Mutex(es) that prevents other threads from accessing
526 VCL concurrently.
527
528 @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
529 IsMainThread, ReleaseSolarMutex,
530 */
531 static void AcquireSolarMutex( sal_uInt32 nCount );
532
533 /** Queries whether the application is in "main", i.e. not yet in
534 the event loop
535
536 @returns true if in main, false if not in main
537
538 @see IsInExecute, IsInModalMode
539 */
540 static bool IsInMain();
541
542 /** Queries whether the application is in the event loop
543
544 @returns true if in the event loop, false if not
545
546 @see IsInMain, IsInModalMode
547 */
548 static bool IsInExecute();
549
550 /** Queries whether application has a modal dialog active.
551
552 @returns true if a modal dialog is active, false if not
553
554 @see IsInMain, IsInExecute
555 */
556 static bool IsInModalMode();
557
558 /** Return how many events are being dispatched.
559
560 @returns the number of events currently being dispatched
561 */
562 static sal_uInt16 GetDispatchLevel();
563
564 /** Determine if there are any pending input events.
565
566 @param nType input identifier, defined in include/vcl/inputtypes.hxx
567 The default is VCL_INPUT_ANY.
568
569 @returns true if there are pending events, false if not.
570
571 @see GetLastInputInterval
572 */
573 static bool AnyInput( VclInputFlags nType = VCL_INPUT_ANY(VclInputFlags::MOUSE | VclInputFlags::KEYBOARD | VclInputFlags
::PAINT | VclInputFlags::TIMER | VclInputFlags::OTHER | VclInputFlags
::APPEVENT)
);
574
575 /** The interval from the last time that input was received.
576
577 @returns system ticks - last input time
578
579 @see AnyInput
580 */
581 static sal_uInt64 GetLastInputInterval();
582
583 ///@}
584
585 /* Determines if the UI is captured.
586
587 The UI is considered captured if a system dialog is open (e.g. printer setup),
588 a floating window, menu or toolbox dropdown is open, or a window has been
589 captured by the mouse.
590
591 @returns true if UI is captured, false if not
592 */
593 static bool IsUICaptured();
594
595 /** @name Settings
596
597 The following functions set system settings (e.g. tab color, etc.). There are functions
598 that set settings objects, and functions that set and get the actual system settings for
599 the application.
600 */
601 ///@{
602
603 /** Sets user settings in settings object to override system settings
604
605 The system settings that can be overridden are:
606 - window dragging options (on or off, including live scrolling!)
607 - style settings (e.g. checkbox color, border color, 3D colors,
608 button rollover colors, etc.)
609 - mouse settings
610 - menu options, including the mouse follows the menu and whether menu
611 icons are used
612
613 @param rSettings Reference to the settings object to change.
614
615 @see MergeSystemSettings, SetSettings, GetSettings
616 */
617 virtual void OverrideSystemSettings( AllSettings& rSettings );
618
619 /** Set the settings object to the platform/desktop environment system
620 settings.
621
622 @param rSettings Reference to the settings object to change.
623
624 @see OverrideSystemSettings, SetSettings, GetSettings
625 */
626 static void MergeSystemSettings( AllSettings& rSettings );
627
628 /** Sets the application's settings and notifies all windows of the
629 change.
630
631 @param rSettings const reference to settings object used to
632 change the application's settings.
633
634 @see OverrideSystemSettings, MergeSystemSettings, GetSettings
635 */
636 static void SetSettings( const AllSettings& rSettings );
637
638 /** Gets the application's settings. If the application hasn't initialized
639 it's settings, then it does so (lazy initialization).
640
641 @returns AllSettings instance that contains the current settings of the
642 application.
643
644 @see OverrideSystemSettings, MergeSystemSettings, SetSettings
645 */
646 static const AllSettings& GetSettings();
647
648 /** Get the application's locale data wrapper.
649
650 @returns reference to a LocaleDataWrapper object
651 */
652 static const LocaleDataWrapper& GetAppLocaleDataWrapper();
653
654 ///@}
655
656 /** @name Event Listeners/Handlers
657
658 A set of event listeners and callers. Note that in this code there is
659 platform specific functions - namely for zoom and scroll events.
660 */
661 ///@{
662
663
664 /** Add a VCL event listener to the application. If no event listener exists,
665 then initialize the application's event listener with a new one, then add
666 the event listener.
667
668 @param rEventListener Const reference to the event listener to add.
669
670 @see RemoveEventListener, AddKeyListener, RemoveKeyListener
671 */
672 static void AddEventListener( const Link<VclSimpleEvent&,void>& rEventListener );
673
674 /** Remove a VCL event listener from the application.
675
676 @param rEventListener Const reference to the event listener to be removed
677
678 @see AddEventListener, AddKeyListener, RemoveKeyListener
679 */
680 static void RemoveEventListener( const Link<VclSimpleEvent&,void>& rEventListener );
681
682 /** Add a keypress listener to the application. If keypress listener exists,
683 then initialize the application's keypress event listener with a new one, then
684 add the keypress listener.
685
686 @param rKeyListener Const reference to the keypress event listener to add
687
688 @see AddEventListener, RemoveEventListener, RemoveKeyListener
689 */
690 static void AddKeyListener( const Link<VclWindowEvent&,bool>& rKeyListener );
691
692 /** Remove a keypress listener from the application.
693
694 @param rKeyListener Const reference to the keypress event listener to be removed
695
696 @see AddEventListener, RemoveEventListener, AddKeyListener
697 */
698 static void RemoveKeyListener( const Link<VclWindowEvent&,bool>& rKeyListener );
699
700 /** Send event to all VCL application event listeners
701
702 @param pWin Pointer to window to send event
703 @param pData Pointer to data to send with event
704
705 @see ImplCallEventListeners(VclSimpleEvent* pEvent)
706 */
707 static void ImplCallEventListenersApplicationDataChanged( void* pData );
708
709 /** Send event to all VCL application event listeners
710
711 @param rEvent Reference to VclSimpleEvent
712
713 @see ImplCallEventListeners(sal_uLong nEvent, Windows* pWin, void* pData);
714 */
715 static void ImplCallEventListeners( VclSimpleEvent& rEvent );
716
717 /** Handle keypress event
718
719 @param nEvent Event ID for keypress
720 @param pWin Pointer to window that receives the event
721 @param pKeyEvent Received key event
722
723 @see PostKeyEvent
724 */
725 static bool HandleKey( VclEventId nEvent, vcl::Window *pWin, KeyEvent* pKeyEvent );
726
727 /** Send keypress event
728
729 @param nEvent Event ID for keypress
730 @param pWin Pointer to window to which the event is sent
731 @param pKeyEvent Key event to send
732
733 @see HandleKey
734 */
735 static ImplSVEvent * PostKeyEvent( VclEventId nEvent, vcl::Window *pWin, KeyEvent const * pKeyEvent );
736
737 /** Send mouse event
738
739 @param nEvent Event ID for mouse event
740 @param pWin Pointer to window to which the event is sent
741 @param pMouseEvent Mouse event to send
742 */
743 static ImplSVEvent * PostMouseEvent( VclEventId nEvent, vcl::Window *pWin, MouseEvent const * pMouseEvent );
744
745 static ImplSVEvent* PostGestureEvent(VclEventId nEvent, vcl::Window* pWin, GestureEvent const * pGestureEvent);
746
747 /** Remove mouse and keypress events from a window... any also zoom and scroll events
748 if the platform supports it.
749
750 @param pWin Window to remove events from
751
752 @see HandleKey, PostKeyEvent, PostMouseEvent
753 */
754 static void RemoveMouseAndKeyEvents( vcl::Window *pWin );
755
756 /** Post a user event to the default window.
757
758 User events allow for the deferral of work to later in the main-loop - at idle.
759
760 Execution of the deferred work is thread-safe which means all the tasks are executed
761 serially, so no thread-safety locks between tasks are necessary.
762
763 @param rLink Link to event callback function
764 @param pCaller Pointer to data sent to the event by the caller. Optional.
765 @param bReferenceLink If true - hold a VclPtr<> reference on the Link's instance.
766 Taking the reference is guarded by a SolarMutexGuard.
767
768 @return the event ID used to post the event.
769 */
770 static ImplSVEvent * PostUserEvent( const Link<void*,void>& rLink, void* pCaller = nullptr,
771 bool bReferenceLink = false );
772
773 /** Remove user event based on event ID
774
775 @param nUserEvent User event to remove
776 */
777 static void RemoveUserEvent( ImplSVEvent * nUserEvent );
778
779 /*** Get the DisplayConnection.
780
781 It is a reference to XDisplayConnection, which allows toolkits to send display
782 events to the application.
783
784 @returns UNO reference to an object that implements the css:awt:XDisplayConnection
785 interface.
786 */
787 static css::uno::Reference< css::awt::XDisplayConnection > GetDisplayConnection();
788
789 /** @deprecated AppEvent is used only in the Desktop class now. However, it is
790 intended to notify the application that an event has occurred. It was in oldsv.cxx,
791 but is still needed by a number of functions.
792
793 @param rAppEvent const reference to ApplicationEvent event
794 */
795 virtual void AppEvent( const ApplicationEvent& rAppEvent );
796
797 ///@}
798
799 /** @name Application Window Functions
800
801 Functions that deal with the application's windows
802 */
803 ///@{
804
805 /** Get the currently focused window.
806
807 @returns Pointer to focused window.
808
809 @see GetDefaultDevice
810 */
811 static vcl::Window* GetFocusWindow();
812
813 /** Get the default "device" (in this case the default window).
814
815 @returns Pointer to an OutputDevice. However, it is a Window object -
816 Window class subclasses OutputDevice.
817
818 @see GetFocusWindow
819 */
820 static OutputDevice* GetDefaultDevice();
821
822 /** Get the first top-level window of the application.
823
824 @returns Pointer to top-level window (a Window object)
825
826 @see GetNextTopLevelWindow, GetTopWindowCount, GetTopWindow,
827 GetActiveTopWindow
828 */
829 static vcl::Window* GetFirstTopLevelWindow();
830
831 /** Get the next top level window.
832
833 @param pWindow Pointer to Window object you wish to get the next
834 window from.
835
836 @returns Pointer to next top window.
837 */
838 static vcl::Window* GetNextTopLevelWindow( vcl::Window const * pWindow );
839
840 /** Return the number of top-level windows being used by the application
841
842 @returns the number of top-level windows
843
844 @see GetFirstTopLevelWindow, GetNextTopLevelWindow, GetTopWindow,
845 GetActiveTopWindow
846
847 */
848 static long GetTopWindowCount();
849
850 /** Get the nth top window.
851
852 @remark Top windows are actually implemented in a one-way linked list.
853 This iterates through top level windows n times.
854
855 @param nIndex The index of the top-level window
856
857 @returns The nth top-level window of the application
858
859 @see GetFirstTopLevelWindow, GetNextTopLevelWindow, GetTopWindowCount,
860 GetActiveTopWindow
861 */
862 static vcl::Window* GetTopWindow( long nIndex );
863
864 /** Get the "active" top window.
865
866 An "active" top window is one that has a child window that has the
867 application's focus.
868
869 @returns the active top window
870
871 @see GetFirstTopLevelWindow, GetNextTopLevelWindow, GetTopWindowCount,
872 GetTopWindow
873 */
874 static vcl::Window* GetActiveTopWindow();
875
876 ///@}
877
878 /** Set the application's name.
879
880 @param rUniqueName What to set the application name to
881
882 @see GetAppName
883 */
884 static void SetAppName( const OUString& rUniqueName );
885
886
887 /** @name Application Name, Branding
888 */
889 ///@{
890
891 /** Get the application's name.
892
893 @returns The application name.
894 */
895 static OUString GetAppName();
896
897 /** Get useful OS, Hardware and configuration information,
898 * cf. Help->About, and User-Agent
899 * bSelection = 0 to return all info, 1 for environment only,
900 * and 2 for VCL/render related infos
901 */
902 static OUString GetHWOSConfInfo(const int bSelection = 0, bool bLocalize = true);
903
904 /** Load a localized branding PNG file as a bitmap.
905
906 @param pName Name of the bitmap to load.
907 @param rBitmap Reference to BitmapEx object to load PNG into
908
909 @returns true if the PNG could be loaded, otherwise returns false.
910 */
911 static bool LoadBrandBitmap (const char* pName, BitmapEx &rBitmap);
912
913 ///@}
914
915 /** @name Display and Screen
916 */
917 ///@{
918
919 /** Set the default name of the application for message dialogs and printing.
920
921 @param rDisplayName const reference to string to set the Display name to.
922
923 @see GetDisplayName
924 */
925 static void SetDisplayName( const OUString& rDisplayName );
926
927 /** Get the default name of the application for message dialogs and printing.
928
929 @returns The display name of the application.
930 */
931 static OUString GetDisplayName();
932
933 /** Get the toolkit's name. e.g. gtk3
934
935 @returns The toolkit name.
936 */
937 static OUString GetToolkitName();
938
939 /** Get the number of screens available for the display.
940
941 @returns The number of screens available.
942
943 @see GetScreenPosSizePixel
944 */
945 static unsigned int GetScreenCount();
946
947 /** Get a screen's rectangular area.
948
949 @param nScreen The number of the screen requested.
950
951 @returns The area of the screen in a Rectangle object.
952
953 @see GetScreenCount
954 */
955 static tools::Rectangle GetScreenPosSizePixel( unsigned int nScreen );
956
957 /** Determines if the screens that make up a display are separate or
958 form one large display area.
959
960 @returns true when screens form up one large display area windows can be
961 moved between single screens (e.g. Xserver with Xinerama, Windows)
962 and false when different screens are separate and windows cannot be moved
963 between them (e.g. Xserver with multiple screens)
964
965 @see GetBestScreen, GetDisplayBuiltInScreen
966 */
967 static bool IsUnifiedDisplay();
968
969 /** Get the "best" screen.
970
971 @returns If IsUnifiedDisplay() == true the return value will be
972 nearest screen of the target rectangle.
973
974 In case of IsUnifiedDisplay() == false the return value
975 will always be GetDisplayDefaultScreen().
976
977 @see IsUnifiedDisplay, GetDisplayBuiltInScreen
978 */
979 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) static unsigned int GetBestScreen( const tools::Rectangle& );
980
981 /** Get the built-in screen.
982
983 @return
984 This returns the LCD screen number for a laptop, or the primary
985 external VGA display for a desktop machine - it is where a presenter
986 console should be rendered if there are other (non-built-in) screens
987 present.
988
989 @see IsUnifiedDisplay, GetBestScreen
990 */
991 static unsigned int GetDisplayBuiltInScreen();
992
993 /** Get the display's external screen.
994
995 Practically, this means - Get the screen we should run a presentation on.
996
997 @returns 0 or 1 currently, will fallback to the first available screen if
998 there are more than one external screens. May be changed in the future.
999 */
1000 static unsigned int GetDisplayExternalScreen();
1001
1002 ///@}
1003
1004 /** @name Accelerators and Mnemonics
1005
1006 Accelerators allow a user to hold down Ctrl+key (or CMD+key on macOS)
1007 combination to gain quick access to functionality.
1008
1009 Mnemonics are underline letters in things like menus and dialog boxes
1010 that allow a user to type in the letter to activate the menu or option.
1011 */
1012 ///@{
1013
1014 /** Insert accelerator
1015
1016 @param pAccel Pointer to an Accelerator object to insert
1017
1018 @returns true if successful, false if otherwise
1019
1020 @see RemoveAccel
1021 */
1022 static bool InsertAccel( Accelerator* pAccel );
1023
1024 /** Remove accelerator
1025
1026 @param pAccel Pointer to Accelerator object to remove
1027
1028 @see InsertAccel
1029 */
1030 static void RemoveAccel( Accelerator const * pAccel );
1031
1032 /** Get the number of reserved key codes used by the application.
1033
1034 @returns number of reserved key codes
1035
1036 @see GetReservedKeyCode
1037 */
1038 static size_t GetReservedKeyCodeCount();
1039
1040 /** Get the reserved key code.
1041
1042 @param i The keycode number to retrieve
1043
1044 @returns Const pointer to a KeyCode object
1045
1046 @see GetReservedKeyCodeCount
1047 */
1048 static const vcl::KeyCode* GetReservedKeyCode( size_t i );
1049
1050 ///@}
1051
1052 /** @name Application Help
1053
1054 Deals with the help system, and "auto-help", where a user hovers a mouse above
1055 a UI element and a tooltip with an explanation pops up.
1056 */
1057 ///@{
1058
1059 /** Sets up help
1060
1061 @param pHelp Pointer to a Help object (optional, can by NULL)
1062
1063 @see GetHelp
1064 */
1065 static void SetHelp( Help* pHelp = nullptr );
1066
1067 /** Gets the application's help
1068
1069 @returns Pointer to application's help object. Note that the application may
1070 not have a help object, so it might return NULL.
1071
1072 @see SetHelp
1073 */
1074 static Help* GetHelp();
1075
1076 ///@}
1077
1078 /** @name Dialogs
1079
1080 @remark "Dialog cancel mode" tells a headless install whether to
1081 cancel dialogs when they appear. See the DialogCancelMode
1082 enumerator.
1083 */
1084 ///@{
1085
1086 /** Get the default parent window for dialog boxes.
1087
1088 @remark GetDefDialogParent does all sorts of things find a useful parent
1089 window for dialogs. It first uses the topmost parent of the active
1090 window to avoid using floating windows or other dialog boxes. If
1091 there are no active windows, then it will take a random stab and
1092 choose the first visible top window. Otherwise, it defaults to
1093 the desktop.
1094
1095 @returns Pointer to the default window.
1096 */
1097 static vcl::Window* GetDefDialogParent();
1098
1099
1100 /** Gets the dialog cancel mode for headless environments.
1101
1102 @return DialogCancelMode value
1103
1104 @see SetDialogCancelMode, IsDialogCancelEnabled
1105 */
1106 static DialogCancelMode GetDialogCancelMode();
1107
1108 /** Sets the dialog cancel mode for headless environments.
1109
1110 This should be private, but XFrameImpl needs to access it and current
1111 baseline gcc doesn't support forward definition of anonymous classes.
1112 You probably should use EnableHeadlessMode instead.
1113
1114 @param mode DialogCancel mode value
1115
1116 @see GetDialogCancelMode, IsDialogCancelEnabled, EnableHeadlessMode
1117 */
1118 static void SetDialogCancelMode( DialogCancelMode mode );
1119
1120 /** Determines if dialog cancel mode is enabled.
1121
1122 @returns True if dialog cancel mode is enabled, false if disabled.
1123
1124 @see GetDialogCancelMode, SetDialogCancelMode
1125 */
1126 static bool IsDialogCancelEnabled();
1127
1128
1129 /** Make a dialog box a system window or not.
1130
1131 @param nMode Can be either: SystemWindowFlags::NOAUTOMODE (0x0001) or
1132 SystemWindowFlags::DIALOG (0x0002)
1133
1134 @see GetSystemWindowMode
1135 */
1136 static void SetSystemWindowMode( SystemWindowFlags nMode );
1137
1138 /** Get the system window mode of dialogs.
1139
1140 @returns SystemWindowFlags::NOAUTOMODE (0x0001) or SystemWindowFlags::DIALOG (0x0002)
1141
1142 @see SetSystemWindowMode
1143 */
1144 static SystemWindowFlags GetSystemWindowMode();
1145
1146 ///@}
1147
1148 /** @name VCL Toolkit and UNO Wrapper
1149
1150 The VCL Toolkit implements the UNO XToolkit interface, which specifies a
1151 factory interface for the window toolkit. It is similar to the abstract window
1152 toolkit (AWT) in Java.
1153
1154 */
1155 ///@{
1156
1157 /** Gets the VCL toolkit.
1158
1159 @attention The global service manager has to be created before getting the toolkit!
1160
1161 @returns UNO reference to VCL toolkit
1162 */
1163 static css::uno::Reference< css::awt::XToolkit > GetVCLToolkit();
1164
1165 ///@}
1166
1167
1168 /*** @name Graphic Filters
1169 */
1170 ///@{
1171
1172 /** Setup a new graphics filter
1173
1174 @param rLink Const reference to a Link object, which the filter calls upon.
1175
1176 @see GetFilterHdl
1177 */
1178 static void SetFilterHdl( const Link<ConvertData&,bool>& rLink );
1179
1180 ///@}
1181
1182 /** @name Headless Mode
1183 */
1184
1185 /** Enables headless mode.
1186
1187 @param dialogsAreFatal Set to true if a dialog ends the session, false if not.
1188 */
1189 static void EnableHeadlessMode( bool dialogsAreFatal );
1190
1191 /** Determines if headless mode is enabled
1192
1193 @return True if headless mode is enabled, false if not.
1194 */
1195 static bool IsHeadlessModeEnabled();
1196
1197 /** Enable Console Only mode
1198
1199 Convenience function to enable headless and bitmap rendering.
1200 */
1201 static void EnableConsoleOnly();
1202
1203 /** Enable software-only bitmap rendering
1204 */
1205 static void EnableBitmapRendering();
1206
1207 /** Determines if bitmap rendering is enabled
1208
1209 @return True if bitmap rendering is enabled.
1210 */
1211 static bool IsBitmapRendering();
1212
1213 ///@}
1214
1215 /** @name Event Testing Mode
1216 */
1217
1218 /** Enables event testing mode.
1219
1220 */
1221 static void EnableEventTestingMode();
1222
1223 /** Determines if event testing mode is enabled
1224
1225 @return True if event testing mode is enabled, false if not.
1226 */
1227 static bool IsEventTestingModeEnabled();
1228
1229 /** Set safe mode to enabled */
1230 static void EnableSafeMode();
1231
1232 /** Determines if safe mode is enabled */
1233 static bool IsSafeModeEnabled();
1234
1235 ///@}
1236
1237 /** Get the desktop environment the process is currently running in
1238
1239 @returns String representing the desktop environment
1240 */
1241 static const OUString& GetDesktopEnvironment();
1242
1243 /*** @name Platform Functionality
1244 */
1245 ///@{
1246
1247 /** Add a file to the system shells recent document list if there is any.
1248 This function may have no effect under Unix because there is no standard
1249 API among the different desktop managers.
1250
1251 @param rFileUrl The file url of the document.
1252
1253 @param rMimeType The mime content type of the document specified by aFileUrl.
1254 If an empty string will be provided "application/octet-stream"
1255 will be used.
1256
1257 @param rDocumentService The app (or "document service") you will be adding the file to
1258 e.g. com.sun.star.text.TextDocument
1259 */
1260 static void AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType, const OUString& rDocumentService);
1261
1262 /*** Show a native error messagebox
1263
1264 @param sTitle Title of error messagebox
1265
1266 @param sMessage Message displayed in messagebox
1267 */
1268 static void ShowNativeErrorBox(const OUString& sTitle ,
1269 const OUString& sMessage);
1270
1271 /** Update main thread identifier */
1272 static void UpdateMainThread();
1273
1274 /** Do we have a native / system file selector available?
1275
1276 @returns True if native file selector is available, false otherwise.
1277 */
1278 static bool hasNativeFileSelection();
1279
1280 /** Create a platform specific file picker, if one is available, otherwise return an
1281 empty reference.
1282
1283 @param rServiceManager Const reference to a UNO component context (service manager).
1284
1285 @returns File picker if available, otherwise an empty reference.
1286 */
1287 static css::uno::Reference< css::ui::dialogs::XFilePicker2 >
1288 createFilePicker( const css::uno::Reference< css::uno::XComponentContext >& rServiceManager );
1289
1290 /** Create a platform specific folder picker, if one is available, otherwise return an
1291 empty reference
1292
1293 @param rServiceManager Const reference to a UNO component context (service manager).
1294
1295 @returns Folder picker if available, otherwise an empty reference.
1296 */
1297 static css::uno::Reference< css::ui::dialogs::XFolderPicker2 >
1298 createFolderPicker( const css::uno::Reference< css::uno::XComponentContext >& rServiceManager );
1299
1300 /** Cancel all open dialogs
1301 */
1302 static void EndAllDialogs();
1303
1304 /** Cancel all open popups
1305 */
1306 static void EndAllPopups();
1307
1308 ///@}
1309
1310 /** Lock font updates for all output devices
1311
1312 @remark When performing operations that might involve multiple registration of fonts, such as
1313 opening/closing documents with multiple embedded fonts, then each font addition/removal
1314 might cause an event that initiates a rebuild of each OutputDevice's font lists.
1315
1316 Locking font updates disables processing such events, and unlocking causes a single such
1317 processing for all OutputDevices.
1318 */
1319 static void LockFontUpdates(bool bLock);
1320
1321 // For vclbootstrapprotector:
1322 static void setDeInitHook(Link<LinkParamNone*,void> const & hook);
1323
1324 static weld::Builder* CreateBuilder(weld::Widget* pParent, const OUString &rUIFile, bool bMobile = false);
1325 // For the duration of vcl parent windows
1326 static weld::Builder* CreateInterimBuilder(vcl::Window* pParent, const OUString &rUIFile, bool bAllowCycleFocusOut, sal_uInt64 nLOKWindowId = 0);
1327
1328 static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent, VclMessageType eMessageType,
1329 VclButtonsType eButtonType, const OUString& rPrimaryMessage,
1330 bool bMobile = false);
1331
1332 static weld::Window* GetFrameWeld(const css::uno::Reference<css::awt::XWindow>& rWindow);
1333private:
1334 DECL_STATIC_LINK( Application, PostEventHandler, void*, void )static void LinkStubPostEventHandler(void *, void*); static void
PostEventHandler(Application *, void*)
;
1335};
1336
1337class SolarMutexGuard
1338 : public osl::Guard<comphelper::SolarMutex>
1339{
1340public:
1341 SolarMutexGuard()
1342 : osl::Guard<comphelper::SolarMutex>( Application::GetSolarMutex() ) {}
2
Calling constructor for 'Guard<comphelper::SolarMutex>'
7
Returning from constructor for 'Guard<comphelper::SolarMutex>'
1343};
1344
1345class SolarMutexClearableGuard
1346 : public osl::ClearableGuard<comphelper::SolarMutex>
1347{
1348public:
1349 SolarMutexClearableGuard()
1350 : osl::ClearableGuard<comphelper::SolarMutex>( Application::GetSolarMutex() ) {}
1351};
1352
1353class SolarMutexResettableGuard
1354 : public osl::ResettableGuard<comphelper::SolarMutex>
1355{
1356public:
1357 SolarMutexResettableGuard()
1358 : osl::ResettableGuard<comphelper::SolarMutex>( Application::GetSolarMutex() ) {}
1359};
1360
1361namespace vcl
1362{
1363
1364/** guard class that uses tryToAcquire() and has isAcquired() to check
1365 */
1366class SolarMutexTryAndBuyGuard
1367{
1368private:
1369 bool m_isAcquired;
1370#ifdef DBG_UTIL
1371 bool m_isChecked;
1372#endif
1373 comphelper::SolarMutex& m_rSolarMutex;
1374
1375 SolarMutexTryAndBuyGuard(const SolarMutexTryAndBuyGuard&) = delete;
1376 SolarMutexTryAndBuyGuard& operator=(const SolarMutexTryAndBuyGuard&) = delete;
1377
1378public:
1379
1380 SolarMutexTryAndBuyGuard()
1381 : m_isAcquired(false)
1382#ifdef DBG_UTIL
1383 , m_isChecked(false)
1384#endif
1385 , m_rSolarMutex(Application::GetSolarMutex())
1386
1387 {
1388 m_isAcquired = m_rSolarMutex.tryToAcquire();
1389 }
1390
1391 ~SolarMutexTryAndBuyGuard()
1392 {
1393#ifdef DBG_UTIL
1394 assert(m_isChecked)(static_cast <bool> (m_isChecked) ? void (0) : __assert_fail
("m_isChecked", "/home/maarten/src/libreoffice/core/include/vcl/svapp.hxx"
, 1394, __extension__ __PRETTY_FUNCTION__))
;
1395#endif
1396 if (m_isAcquired)
1397 m_rSolarMutex.release();
1398 }
1399
1400 bool isAcquired()
1401 {
1402#ifdef DBG_UTIL
1403 m_isChecked = true;
1404#endif
1405 return m_isAcquired;
1406 }
1407};
1408
1409} // namespace vcl
1410
1411/**
1412 A helper class that calls Application::ReleaseSolarMutex() in its constructor
1413 and restores the mutex in its destructor.
1414*/
1415class SolarMutexReleaser
1416{
1417 const sal_uInt32 mnReleased;
1418public:
1419 SolarMutexReleaser(): mnReleased(Application::ReleaseSolarMutex()) {}
1420 ~SolarMutexReleaser() { Application::AcquireSolarMutex( mnReleased ); }
1421};
1422
1423VCL_DLLPUBLIC__attribute__ ((visibility("default"))) Application* GetpApp();
1424
1425// returns true if vcl is already initialized
1426VCL_DLLPUBLIC__attribute__ ((visibility("default"))) bool IsVCLInit();
1427// returns true if vcl successfully initializes or was already initialized
1428VCL_DLLPUBLIC__attribute__ ((visibility("default"))) bool InitVCL();
1429VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void DeInitVCL();
1430
1431VCL_DLLPUBLIC__attribute__ ((visibility("default"))) bool InitAccessBridge();
1432
1433// only allowed to call, if no thread is running. You must call JoinMainLoopThread to free all memory.
1434VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void CreateMainLoopThread( oslWorkerFunction pWorker, void * pThreadData );
1435VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void JoinMainLoopThread();
1436
1437/// The following are to manage per-view (frame) help data.
1438struct ImplSVHelpData;
1439VCL_DLLPUBLIC__attribute__ ((visibility("default"))) ImplSVHelpData* CreateSVHelpData();
1440VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void DestroySVHelpData(ImplSVHelpData*);
1441VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void SetSVHelpData(ImplSVHelpData*);
1442
1443/// The following are to manage per-view (frame) window data.
1444struct ImplSVWinData;
1445VCL_DLLPUBLIC__attribute__ ((visibility("default"))) ImplSVWinData* CreateSVWinData();
1446VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void DestroySVWinData(ImplSVWinData*);
1447VCL_DLLPUBLIC__attribute__ ((visibility("default"))) void SetSVWinData(ImplSVWinData*);
1448
1449inline void Application::EndYield()
1450{
1451 PostUserEvent( Link<void*,void>() );
1452}
1453
1454#endif // _APP_HXX
1455
1456/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/osl/mutex.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_OSL_MUTEX_HXX
21#define INCLUDED_OSL_MUTEX_HXX
22
23#include "osl/mutex.h"
24
25#include <cassert>
26
27namespace osl
28{
29 /** A mutual exclusion synchronization object
30 */
31 class SAL_WARN_UNUSED__attribute__((warn_unused)) Mutex {
32
33 public:
34 /** Create a mutex.
35 @return 0 if the mutex could not be created, otherwise a handle to the mutex.
36 @see ::osl_createMutex()
37 */
38 Mutex()
39 {
40 mutex = osl_createMutex();
41 }
42
43 /** Release the OS-structures and free mutex data-structure.
44 @see ::osl_destroyMutex()
45 */
46 ~Mutex()
47 {
48 osl_destroyMutex(mutex);
49 }
50
51 /** Acquire the mutex, block if already acquired by another thread.
52 @return false if system-call fails.
53 @see ::osl_acquireMutex()
54 */
55 bool acquire()
56 {
57 return osl_acquireMutex(mutex);
58 }
59
60 /** Try to acquire the mutex without blocking.
61 @return false if it could not be acquired.
62 @see ::osl_tryToAcquireMutex()
63 */
64 bool tryToAcquire()
65 {
66 return osl_tryToAcquireMutex(mutex);
67 }
68
69 /** Release the mutex.
70 @return false if system-call fails.
71 @see ::osl_releaseMutex()
72 */
73 bool release()
74 {
75 return osl_releaseMutex(mutex);
76 }
77
78 /** Returns a global static mutex object.
79 The global and static mutex object can be used to initialize other
80 static objects in a thread safe manner.
81 @return the global mutex object
82 @see ::osl_getGlobalMutex()
83 */
84 static Mutex * getGlobalMutex()
85 {
86 return reinterpret_cast<Mutex *>(osl_getGlobalMutex());
87 }
88
89 private:
90 oslMutex mutex;
91
92 /** The underlying oslMutex has no reference count.
93
94 Since the underlying oslMutex is not a reference counted object, copy
95 constructed Mutex may work on an already destructed oslMutex object.
96
97 */
98 Mutex(const Mutex&) SAL_DELETED_FUNCTION= delete;
99
100 /** This assignment operator is deleted for the same reason as
101 the copy constructor.
102 */
103 Mutex& operator= (const Mutex&) SAL_DELETED_FUNCTION= delete;
104 };
105
106 /** Object lifetime scoped mutex object or interface lock.
107 *
108 * Acquires the template object on construction and releases it on
109 * destruction.
110 *
111 * @see MutexGuard
112 */
113 template<class T>
114 class Guard
115 {
116 Guard(const Guard&) SAL_DELETED_FUNCTION= delete;
117 Guard& operator=(const Guard&) SAL_DELETED_FUNCTION= delete;
118
119 protected:
120 T * pT;
121
122 public:
123 /** Acquires the object specified as parameter.
124 */
125 Guard(T * pT_) : pT(pT_)
126 {
127 assert(pT != NULL)(static_cast <bool> (pT != __null) ? void (0) : __assert_fail
("pT != NULL", "/home/maarten/src/libreoffice/core/include/osl/mutex.hxx"
, 127, __extension__ __PRETTY_FUNCTION__))
;
128 pT->acquire();
129 }
130
131 /** Acquires the object specified as parameter.
132 */
133 Guard(T & t) : pT(&t)
134 {
135 pT->acquire();
3
Calling 'SolarMutex::acquire'
6
Returning from 'SolarMutex::acquire'
136 }
137
138 /** Releases the mutex or interface. */
139 ~Guard()
140 {
141 pT->release();
142 }
143 };
144
145 /** Object lifetime scoped mutex object or interface lock with unlock.
146 *
147 * Use this if you can't use scoped code blocks and Guard.
148 *
149 * @see ClearableMutexGuard, Guard
150 */
151 template<class T>
152 class ClearableGuard
153 {
154 ClearableGuard( const ClearableGuard& ) SAL_DELETED_FUNCTION= delete;
155 ClearableGuard& operator=(const ClearableGuard&) SAL_DELETED_FUNCTION= delete;
156
157 protected:
158 T * pT;
159
160 public:
161 /** Acquires the object specified as parameter.
162 */
163 ClearableGuard(T * pT_) : pT(pT_)
164 {
165 assert(pT != NULL)(static_cast <bool> (pT != __null) ? void (0) : __assert_fail
("pT != NULL", "/home/maarten/src/libreoffice/core/include/osl/mutex.hxx"
, 165, __extension__ __PRETTY_FUNCTION__))
;
166 pT->acquire();
167 }
168
169 /** Acquires the object specified as parameter.
170 */
171 ClearableGuard(T & t) : pT(&t)
172 {
173 pT->acquire();
174 }
175
176 /** Releases the mutex or interface if not already released by clear().
177 */
178 ~ClearableGuard()
179 {
180 if (pT)
181 pT->release();
182 }
183
184 /** Releases the mutex or interface.
185 */
186 void clear()
187 {
188#ifdef LIBO_INTERNAL_ONLY1
189 assert(pT)(static_cast <bool> (pT) ? void (0) : __assert_fail ("pT"
, "/home/maarten/src/libreoffice/core/include/osl/mutex.hxx",
189, __extension__ __PRETTY_FUNCTION__))
;
190#else
191 if (pT)
192#endif
193 {
194 pT->release();
195 pT = NULL__null;
196 }
197 }
198 };
199
200 /** Template for temporary releasable mutex objects and interfaces locks.
201 *
202 * Use this if you want to acquire a lock but need to temporary release
203 * it and can't use multiple scoped Guard objects.
204 *
205 * @see ResettableMutexGuard
206 */
207 template< class T >
208 class ResettableGuard : public ClearableGuard< T >
209 {
210 ResettableGuard(const ResettableGuard&) SAL_DELETED_FUNCTION= delete;
211 ResettableGuard& operator=(const ResettableGuard&) SAL_DELETED_FUNCTION= delete;
212
213 protected:
214 T* pResetT;
215
216 public:
217 /** Acquires the object specified as parameter.
218 */
219 ResettableGuard( T* pT_ ) :
220 ClearableGuard<T>( pT_ ),
221 pResetT( pT_ )
222 {}
223
224 /** Acquires the object specified as parameter.
225 */
226 ResettableGuard( T& rT ) :
227 ClearableGuard<T>( rT ),
228 pResetT( &rT )
229 {}
230
231 /** Re-acquires the mutex or interface.
232 */
233 void reset()
234 {
235#ifdef LIBO_INTERNAL_ONLY1
236 assert(!this->pT)(static_cast <bool> (!this->pT) ? void (0) : __assert_fail
("!this->pT", "/home/maarten/src/libreoffice/core/include/osl/mutex.hxx"
, 236, __extension__ __PRETTY_FUNCTION__))
;
237#endif
238 if (pResetT)
239 {
240 this->pT = pResetT;
241 this->pT->acquire();
242 }
243 }
244 };
245
246 typedef Guard<Mutex> MutexGuard;
247 typedef ClearableGuard<Mutex> ClearableMutexGuard;
248 typedef ResettableGuard< Mutex > ResettableMutexGuard;
249}
250
251#endif // INCLUDED_OSL_MUTEX_HXX
252
253/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/comphelper/solarmutex.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_COMPHELPER_SOLARMUTEX_HXX
21#define INCLUDED_COMPHELPER_SOLARMUTEX_HXX
22
23#include <sal/config.h>
24
25#include <assert.h>
26#include <atomic>
27
28#include <osl/thread.h>
29#include <osl/mutex.hxx>
30#include <comphelper/comphelperdllapi.h>
31
32namespace comphelper {
33
34
35/**
36 * SolarMutex, needed for VCL's Application::GetSolarMutex().
37 *
38 * The SolarMutex is the one big recursive code lock used
39 * to protect the vast majority of the LibreOffice code-base,
40 * in particular anything that is graphical and the cores of
41 * the applications.
42 *
43 * Treat this as a singleton, as its constructor sets a global
44 * pointing at itself.
45 */
46class COMPHELPER_DLLPUBLIC__attribute__ ((visibility("default"))) SolarMutex {
47public:
48 typedef void (*BeforeReleaseHandler) ();
49
50 SolarMutex();
51 virtual ~SolarMutex();
52
53 void SetBeforeReleaseHandler( const BeforeReleaseHandler& rLink )
54 { m_aBeforeReleaseHandler = rLink; }
55
56 void acquire( sal_uInt32 nLockCount = 1 );
57 sal_uInt32 release( bool bUnlockAll = false );
58
59 virtual bool tryToAcquire();
60
61 // returns true, if the mutex is owned by the current thread
62 virtual bool IsCurrentThread() const;
63
64 /// Help components to get the SolarMutex easily.
65 static SolarMutex *get();
66
67protected:
68 virtual sal_uInt32 doRelease( bool bUnlockAll );
69 virtual void doAcquire( sal_uInt32 nLockCount );
70
71 osl::Mutex m_aMutex;
72 sal_uInt32 m_nCount;
73
74private:
75 std::atomic<oslThreadIdentifier> m_nThreadId;
76
77 SolarMutex(const SolarMutex&) = delete;
78 SolarMutex& operator=(const SolarMutex&) = delete;
79
80 BeforeReleaseHandler m_aBeforeReleaseHandler;
81};
82
83inline void SolarMutex::acquire( sal_uInt32 nLockCount )
84{
85 assert( nLockCount > 0 )(static_cast <bool> (nLockCount > 0) ? void (0) : __assert_fail
("nLockCount > 0", "/home/maarten/src/libreoffice/core/include/comphelper/solarmutex.hxx"
, 85, __extension__ __PRETTY_FUNCTION__))
;
4
'?' condition is true
86 doAcquire( nLockCount );
5
Value assigned to 'gImpl'
87}
88
89inline sal_uInt32 SolarMutex::release( bool bUnlockAll )
90{
91 return doRelease( bUnlockAll );
92}
93
94}
95
96#endif // INCLUDED_COMPHELPER_SOLARMUTEX_HXX
97
98/* vim:set shiftwidth=4 softtabstop=4 expandtab: */