summaryrefslogtreecommitdiffstats
path: root/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'desktop')
-rw-r--r--desktop/CppunitTest_desktop_app.mk3
-rw-r--r--desktop/CppunitTest_desktop_lib.mk2
-rw-r--r--desktop/CustomTarget_soffice.mk19
-rw-r--r--desktop/Executable_oosplash.mk8
-rw-r--r--desktop/Executable_soffice_bin.mk32
-rw-r--r--desktop/Extension_test-crashextension.mk24
-rw-r--r--desktop/IwyuFilter_desktop.yaml6
-rw-r--r--desktop/Library_crashextension.mk28
-rw-r--r--desktop/Library_crashreport.mk4
-rw-r--r--desktop/Library_migrationoo3.mk2
-rw-r--r--desktop/Library_offacc.mk4
-rw-r--r--desktop/Library_sofficeapp.mk24
-rw-r--r--desktop/Module_desktop.mk10
-rw-r--r--desktop/README.md15
-rw-r--r--desktop/Rdb_crashextension.mk12
-rw-r--r--desktop/inc/app.hxx8
-rw-r--r--desktop/inc/bitmaps.hlst8
-rw-r--r--desktop/inc/dp_misc.h4
-rw-r--r--desktop/inc/lib/init.hxx66
-rw-r--r--desktop/inc/pch/precompiled_deployment.hxx2
-rw-r--r--desktop/inc/pch/precompiled_sofficeapp.hxx5
-rw-r--r--desktop/inc/strings.hrc3
-rw-r--r--desktop/inc/strings.hxx2
-rw-r--r--desktop/lokclipboard.component26
-rw-r--r--desktop/qa/data/3page.odgbin0 -> 11175 bytes
-rw-r--r--desktop/qa/data/ThemeDocument.docxbin0 -> 13121 bytes
-rw-r--r--desktop/qa/data/comments.odtbin9694 -> 10507 bytes
-rw-r--r--desktop/qa/deployment_misc/test_dp_version.cxx2
-rw-r--r--desktop/qa/desktop_lib/test_desktop_lib.cxx852
-rw-r--r--desktop/scripts/gdbtrace4
-rwxr-xr-xdesktop/scripts/soffice.sh12
-rwxr-xr-xdesktop/scripts/unopkg.sh17
-rw-r--r--desktop/source/app/app.cxx175
-rw-r--r--desktop/source/app/appinit.cxx34
-rw-r--r--desktop/source/app/check_ext_deps.cxx23
-rw-r--r--desktop/source/app/cmdlineargs.cxx34
-rw-r--r--desktop/source/app/cmdlineargs.hxx6
-rw-r--r--desktop/source/app/cmdlinehelp.cxx9
-rw-r--r--desktop/source/app/crashreport.cxx30
-rw-r--r--desktop/source/app/dispatchwatcher.cxx83
-rw-r--r--desktop/source/app/dispatchwatcher.hxx5
-rw-r--r--desktop/source/app/langselect.cxx2
-rw-r--r--desktop/source/app/lockfile2.cxx8
-rw-r--r--desktop/source/app/officeipcthread.cxx68
-rw-r--r--desktop/source/app/officeipcthread.hxx5
-rw-r--r--desktop/source/app/opencl.cxx4
-rw-r--r--desktop/source/app/sofficemain.cxx5
-rw-r--r--desktop/source/app/updater.cxx88
-rw-r--r--desktop/source/app/userinstall.cxx2
-rw-r--r--desktop/source/deployment/dp_log.cxx8
-rw-r--r--desktop/source/deployment/dp_persmap.cxx11
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.cxx75
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.hxx11
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx87
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx5
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.cxx36
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.hxx3
-rw-r--r--desktop/source/deployment/gui/dp_gui_theextmgr.cxx28
-rw-r--r--desktop/source/deployment/gui/dp_gui_theextmgr.hxx2
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedata.hxx5
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.cxx48
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.hxx4
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx24
-rw-r--r--desktop/source/deployment/inc/dp_interact.h11
-rw-r--r--desktop/source/deployment/inc/dp_platform.hxx2
-rw-r--r--desktop/source/deployment/inc/dp_ucb.h2
-rw-r--r--desktop/source/deployment/inc/dp_update.hxx4
-rw-r--r--desktop/source/deployment/inc/dp_version.hxx4
-rw-r--r--desktop/source/deployment/manager/dp_commandenvironments.cxx7
-rw-r--r--desktop/source/deployment/manager/dp_commandenvironments.hxx2
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.cxx16
-rw-r--r--desktop/source/deployment/manager/dp_extensionmanager.hxx4
-rw-r--r--desktop/source/deployment/manager/dp_informationprovider.cxx2
-rw-r--r--desktop/source/deployment/manager/dp_manager.cxx30
-rw-r--r--desktop/source/deployment/manager/dp_manager.h11
-rw-r--r--desktop/source/deployment/manager/dp_properties.cxx2
-rw-r--r--desktop/source/deployment/misc/dp_dependencies.cxx12
-rw-r--r--desktop/source/deployment/misc/dp_descriptioninfoset.cxx7
-rw-r--r--desktop/source/deployment/misc/dp_misc.cxx62
-rw-r--r--desktop/source/deployment/misc/dp_platform.cxx57
-rw-r--r--desktop/source/deployment/misc/dp_resource.cxx1
-rw-r--r--desktop/source/deployment/misc/dp_ucb.cxx4
-rw-r--r--desktop/source/deployment/misc/dp_update.cxx6
-rw-r--r--desktop/source/deployment/misc/dp_version.cxx20
-rw-r--r--desktop/source/deployment/misc/lockfile.cxx26
-rw-r--r--desktop/source/deployment/registry/component/dp_component.cxx80
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.cxx60
-rw-r--r--desktop/source/deployment/registry/dp_backend.cxx27
-rw-r--r--desktop/source/deployment/registry/dp_registry.cxx21
-rw-r--r--desktop/source/deployment/registry/help/dp_help.cxx16
-rw-r--r--desktop/source/deployment/registry/inc/dp_backend.h26
-rw-r--r--desktop/source/deployment/registry/package/dp_package.cxx38
-rw-r--r--desktop/source/deployment/registry/script/dp_lib_container.cxx1
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.cxx9
-rw-r--r--desktop/source/inc/helpids.h6
-rw-r--r--desktop/source/lib/init.cxx3299
-rw-r--r--desktop/source/lib/lokclipboard.cxx19
-rw-r--r--desktop/source/lib/lokinteractionhandler.cxx54
-rw-r--r--desktop/source/lib/lokinteractionhandler.hxx7
-rw-r--r--desktop/source/migration/migration.cxx202
-rw-r--r--desktop/source/migration/migration_impl.hxx15
-rw-r--r--desktop/source/migration/services/basicmigration.cxx2
-rw-r--r--desktop/source/migration/services/jvmfwk.cxx2
-rw-r--r--desktop/source/migration/services/oo3extensionmigration.cxx3
-rw-r--r--desktop/source/migration/services/wordbookmigration.cxx2
-rw-r--r--desktop/source/minidump/minidump.cxx56
-rw-r--r--desktop/source/offacc/acceptor.cxx20
-rw-r--r--desktop/source/offacc/acceptor.hxx5
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_app.cxx54
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx25
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_misc.cxx14
-rw-r--r--desktop/source/pkgchk/unopkg/unopkg_shared.h5
-rw-r--r--desktop/source/splash/splash.cxx71
-rw-r--r--desktop/test/deployment/active/active_python.py2
-rw-r--r--desktop/test/deployment/crashextension/Addons.xcu62
-rw-r--r--desktop/test/deployment/crashextension/META-INF/manifest.xml21
-rw-r--r--desktop/test/deployment/crashextension/ProtocolHandler.xcu20
-rw-r--r--desktop/test/deployment/crashextension/crash.pngbin0 -> 83469 bytes
-rw-r--r--desktop/test/deployment/crashextension/crashextension.component16
-rw-r--r--desktop/test/deployment/crashextension/crashextension.cxx152
-rw-r--r--desktop/test/deployment/crashextension/description.xml21
-rw-r--r--desktop/test/deployment/locationtest/LocationTest.idl7
-rw-r--r--desktop/test/deployment/passive/passive_python.py2
-rw-r--r--desktop/test/deployment/update/platform/linux_loongarch64.oxtbin0 -> 819 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_riscv64.oxtbin0 -> 815 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_s390.oxtbin705 -> 0 bytes
-rw-r--r--desktop/test/deployment/update/platform/linux_sparc64.oxtbin0 -> 812 bytes
-rw-r--r--desktop/test/deployment/update/platform/readme.txt1
-rw-r--r--desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl7
-rw-r--r--desktop/uiconfig/ui/dependenciesdialog.ui9
-rw-r--r--desktop/uiconfig/ui/extensionmanager.ui194
-rw-r--r--desktop/uiconfig/ui/updateinstalldialog.ui2
-rw-r--r--desktop/unx/source/splashx.c8
-rw-r--r--desktop/unx/source/start.c34
-rw-r--r--desktop/win32/source/applauncher/launcher.cxx23
-rw-r--r--desktop/win32/source/loader.cxx430
-rw-r--r--desktop/win32/source/loader.hxx54
-rw-r--r--desktop/win32/source/unoinfo.cxx39
138 files changed, 4970 insertions, 2697 deletions
diff --git a/desktop/CppunitTest_desktop_app.mk b/desktop/CppunitTest_desktop_app.mk
index ee5c1247cc91..d6159e28136f 100644
--- a/desktop/CppunitTest_desktop_app.mk
+++ b/desktop/CppunitTest_desktop_app.mk
@@ -47,10 +47,9 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_app, \
tl \
ucbhelper \
utl \
+ vcl \
))
-$(eval $(call gb_CppunitTest_use_glxtest,desktop_app,-lm))
-
ifeq ($(OS),WNT)
$(eval $(call gb_CppunitTest_use_static_libraries,desktop_app,\
$(if $(ENABLE_ONLINE_UPDATE_MAR),\
diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk
index 61d5cb1f31c5..878235d4da6f 100644
--- a/desktop/CppunitTest_desktop_lib.mk
+++ b/desktop/CppunitTest_desktop_lib.mk
@@ -26,6 +26,7 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_lib, \
sfx \
sofficeapp \
subsequenttest \
+ svt \
sw \
test \
unotest \
@@ -75,6 +76,7 @@ $(eval $(call gb_CppunitTest_use_packages,desktop_lib, \
wizards_basicsrvsfdatabases \
wizards_basicsrvsfdialogs \
wizards_basicsrvsfdocuments \
+ wizards_basicsrvsfunittests \
wizards_basicsrvsfwidgets \
wizards_basicsrvtemplate \
wizards_basicsrvtools \
diff --git a/desktop/CustomTarget_soffice.mk b/desktop/CustomTarget_soffice.mk
index d56f571628fe..4df29fc3cae3 100644
--- a/desktop/CustomTarget_soffice.mk
+++ b/desktop/CustomTarget_soffice.mk
@@ -9,6 +9,23 @@
$(eval $(call gb_CustomTarget_CustomTarget,desktop/soffice))
+ifeq ($(OS), MACOSX)
+
+ifeq (,$(ENABLE_RELEASE_BUILD))
+
+# Add entitlements if this is a non-release build. Just to be safe,
+# this target will always be run and MACOSX_CODESIGNING_IDENTITY is
+# set to empty as we don't want to sign $(INSTROOTBASE). Ignore
+# failures as it appears that setting only entitlements can fail
+# with certain macOS SDKs.
+$(call gb_CustomTarget_get_target,desktop/soffice) : \
+ $(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice
+ -MACOSX_CODESIGNING_IDENTITY= $(SRCDIR)/solenv/bin/macosx-codesign-app-bundle $(INSTROOTBASE)
+
+endif
+
+else
+
$(call gb_CustomTarget_get_target,desktop/soffice) : \
$(call gb_CustomTarget_get_workdir,desktop/soffice)/soffice.sh
@@ -25,4 +42,6 @@ else
endif
$(call gb_Trace_EndRange,$(subst $(WORKDIR)/,,$@),SED)
+endif
+
# vim:set shiftwidth=4 tabstop=4 noexpandtab:
diff --git a/desktop/Executable_oosplash.mk b/desktop/Executable_oosplash.mk
index 5c7e4ac95bb4..2808e0113510 100644
--- a/desktop/Executable_oosplash.mk
+++ b/desktop/Executable_oosplash.mk
@@ -23,16 +23,10 @@ $(eval $(call gb_Executable_add_cobjects,oosplash,\
desktop/unx/source/start \
))
-ifneq ($(USE_XINERAMA),)
-
-$(eval $(call gb_Executable_add_defs,oosplash,\
- -DUSE_XINERAMA \
-))
-
+ifneq ($(USING_X11),)
$(eval $(call gb_Executable_add_libs,oosplash,\
-lXinerama \
))
-
endif
ifneq ($(DISABLE_GUI),TRUE)
diff --git a/desktop/Executable_soffice_bin.mk b/desktop/Executable_soffice_bin.mk
index a3c3ff258613..34146dc5bfe9 100644
--- a/desktop/Executable_soffice_bin.mk
+++ b/desktop/Executable_soffice_bin.mk
@@ -27,7 +27,9 @@ $(eval $(call gb_Executable_add_cobjects,soffice_bin,\
desktop/source/app/main \
))
+ifeq ($(OS)-$(ENABLE_QT5),EMSCRIPTEN-TRUE)
$(eval $(call gb_Executable_add_prejs,soffice_bin,$(SRCDIR)/static/emscripten/soffice_args.js))
+endif
ifeq ($(OS),WNT)
@@ -47,4 +49,34 @@ endif
endif
+ifeq ($(OS),EMSCRIPTEN)
+$(call gb_LinkTarget_get_target,$(call gb_Executable_get_linktarget,soffice_bin)) : $(call gb_StaticLibrary_get_linktarget_target,unoembind)
+$(call gb_LinkTarget_get_headers_target,$(call gb_Executable_get_linktarget,soffice_bin)) : $(call gb_StaticLibrary_get_headers_target,unoembind)
+$(call gb_LinkTarget__static_lib_dummy_depend,unoembind)
+
+$(eval $(call gb_Executable_add_ldflags,soffice_bin,\
+ -s EXPORTED_FUNCTIONS=["_main"$(COMMA)"_libreofficekit_hook"$(COMMA)"_libreofficekit_hook_2"$(COMMA)"_lok_preinit"$(COMMA)"_lok_preinit_2"$(COMMA)"_malloc"$(COMMA)"_free"] -Wl$(COMMA)--whole-archive $(call gb_StaticLibrary_get_target,unoembind) -Wl$(COMMA)--no-whole-archive \
+))
+ifeq ($(ENABLE_QT6),TRUE)
+$(eval $(call gb_Executable_add_ldflags,soffice_bin, \
+ -s MODULARIZE=1 \
+ -s EXPORT_NAME=soffice_entry \
+))
+endif
+
+ifneq ($(ENABLE_DBGUTIL),)
+
+$(call gb_Executable_get_linktarget_target,soffice_bin): \
+ $(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.js \
+ $(SRCDIR)/unotest/source/embindtest/embindtest.js
+
+$(eval $(call gb_Executable_add_ldflags,soffice_bin, \
+ --post-js $(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.js \
+ --post-js $(SRCDIR)/unotest/source/embindtest/embindtest.js \
+))
+
+endif
+
+endif
+
# vim: set ts=4 sw=4 et:
diff --git a/desktop/Extension_test-crashextension.mk b/desktop/Extension_test-crashextension.mk
new file mode 100644
index 000000000000..aa525f72b8b2
--- /dev/null
+++ b/desktop/Extension_test-crashextension.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Extension_Extension,test-crashextension,desktop/test/deployment/crashextension,nodeliver))
+
+$(eval $(call gb_Extension_add_file,test-crashextension,platform.components,$(call gb_Rdb_get_target,crashextension)))
+
+$(eval $(call gb_Extension_add_files,test-crashextension,, \
+ $(SRCDIR)/desktop/test/deployment/crashextension/Addons.xcu \
+ $(SRCDIR)/desktop/test/deployment/crashextension/ProtocolHandler.xcu \
+ $(SRCDIR)/desktop/test/deployment/crashextension/crash.png \
+))
+
+$(eval $(call gb_Extension_add_libraries,test-crashextension, \
+ crashextension \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/desktop/IwyuFilter_desktop.yaml b/desktop/IwyuFilter_desktop.yaml
index cfe94e22cc28..76a0c31ad2d5 100644
--- a/desktop/IwyuFilter_desktop.yaml
+++ b/desktop/IwyuFilter_desktop.yaml
@@ -94,3 +94,9 @@ excludelist:
desktop/source/splash/splash.cxx:
# Needed for rtl::math::round
- rtl/math.hxx
+ desktop/source/lib/lokandroid.cxx:
+ # Needed for osl_getThreadTextEncoding
+ - osl/thread.hxx
+ desktop/source/deployment/misc/dp_misc.cxx:
+ # Needed for osl_getThreadTextEncoding
+ - osl/thread.hxx
diff --git a/desktop/Library_crashextension.mk b/desktop/Library_crashextension.mk
new file mode 100644
index 000000000000..ae18412688a6
--- /dev/null
+++ b/desktop/Library_crashextension.mk
@@ -0,0 +1,28 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,crashextension))
+
+$(eval $(call gb_Library_add_exception_objects,crashextension, \
+ desktop/test/deployment/crashextension/crashextension \
+))
+
+$(eval $(call gb_Library_set_componentfile,crashextension,desktop/test/deployment/crashextension/crashextension,crashextension))
+
+$(eval $(call gb_Library_set_external_code,crashextension))
+
+$(eval $(call gb_Library_use_libraries,crashextension, \
+ cppu \
+ cppuhelper \
+ sal \
+))
+
+$(eval $(call gb_Library_use_sdk_api,crashextension))
+
+# vim: set noet sw=4 ts=4:
diff --git a/desktop/Library_crashreport.mk b/desktop/Library_crashreport.mk
index ba267e212974..c00814c82cee 100644
--- a/desktop/Library_crashreport.mk
+++ b/desktop/Library_crashreport.mk
@@ -31,6 +31,10 @@ $(eval $(call gb_Library_add_libs,crashreport,\
$(eval $(call gb_Library_use_sdk_api,crashreport))
+$(eval $(call gb_Library_use_custom_headers,crashreport,\
+ officecfg/registry \
+))
+
$(eval $(call gb_Library_use_libraries,crashreport,\
comphelper \
cppu \
diff --git a/desktop/Library_migrationoo3.mk b/desktop/Library_migrationoo3.mk
index 10a63e3d841e..b18f77ebf66c 100644
--- a/desktop/Library_migrationoo3.mk
+++ b/desktop/Library_migrationoo3.mk
@@ -12,10 +12,10 @@ $(eval $(call gb_Library_Library,migrationoo3))
$(eval $(call gb_Library_use_sdk_api,migrationoo3))
$(eval $(call gb_Library_use_libraries,migrationoo3,\
+ comphelper \
cppu \
cppuhelper \
sal \
- tl \
utl \
))
diff --git a/desktop/Library_offacc.mk b/desktop/Library_offacc.mk
index a7f560379627..fb1a162b2b90 100644
--- a/desktop/Library_offacc.mk
+++ b/desktop/Library_offacc.mk
@@ -11,6 +11,10 @@ $(eval $(call gb_Library_Library,offacc))
$(eval $(call gb_Library_use_sdk_api,offacc))
+$(eval $(call gb_Library_use_custom_headers,offacc,\
+ officecfg/registry \
+))
+
$(eval $(call gb_Library_use_libraries,offacc,\
comphelper \
cppu \
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index d10c4f3c3403..cc39ccd12f92 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -24,9 +24,10 @@ $(eval $(call gb_Library_use_externals,sofficeapp, \
icu_headers \
icui18n \
icuuc \
+ $(if $(ENABLE_CURL), \
$(if $(filter-out EMSCRIPTEN iOS,$(OS)), \
curl \
- )\
+ ))\
$(if $(ENABLE_ONLINE_UPDATE_MAR),\
orcus-parser \
orcus )\
@@ -36,6 +37,12 @@ $(eval $(call gb_Library_use_custom_headers,sofficeapp,\
officecfg/registry \
))
+ifeq ($(OS),EMSCRIPTEN)
+$(eval $(call gb_Library_use_custom_headers,sofficeapp, \
+ static/unoembind \
+))
+endif
+
$(eval $(call gb_Library_use_api,sofficeapp,\
udkapi \
offapi \
@@ -73,10 +80,9 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\
tl \
ucbhelper \
utl \
+ vcl \
))
-$(eval $(call gb_Library_use_glxtest,sofficeapp,-lm))
-
ifeq ($(OS),WNT)
$(eval $(call gb_Library_use_static_libraries,sofficeapp,\
$(if $(ENABLE_ONLINE_UPDATE_MAR),\
@@ -137,20 +143,16 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
$(if $(filter $(OS),ANDROID), \
desktop/source/lib/lokandroid) \
))
+$(if $(filter-out $(OS),IOS), \
+ $(eval $(call gb_Library_set_componentfile,sofficeapp,desktop/lokclipboard,services)))
else
-ifeq ($(USING_X11),TRUE)
+ifneq ($(filter TRUE,$(USING_X11) $(DISABLE_GUI))($filter EMSCRIPTEN,$(OS)),)
$(eval $(call gb_Library_add_exception_objects,sofficeapp,\
desktop/source/lib/init \
desktop/source/lib/lokinteractionhandler \
desktop/source/lib/lokclipboard \
))
-endif
-ifeq ($(DISABLE_GUI),TRUE)
-$(eval $(call gb_Library_add_exception_objects,sofficeapp,\
- desktop/source/lib/init \
- desktop/source/lib/lokinteractionhandler \
- desktop/source/lib/lokclipboard \
-))
+$(eval $(call gb_Library_set_componentfile,sofficeapp,desktop/lokclipboard,services))
endif
endif
diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk
index d160bc6128dc..de56f3bd139f 100644
--- a/desktop/Module_desktop.mk
+++ b/desktop/Module_desktop.mk
@@ -46,7 +46,7 @@ $(eval $(call gb_Module_add_targets,desktop,\
Pagein_impress \
Pagein_writer \
) \
- $(if $(filter-out MACOSX WNT,$(OS)),CustomTarget_soffice) \
+ $(if $(filter-out WNT,$(OS)),CustomTarget_soffice) \
))
ifeq ($(USING_X11),TRUE)
@@ -124,6 +124,14 @@ $(eval $(call gb_Module_add_targets,desktop, \
))
endif
+ifneq (,$(filter Extension_test-crashextension,$(MAKECMDGOALS)))
+$(eval $(call gb_Module_add_targets,desktop, \
+ Extension_test-crashextension \
+ Library_crashextension \
+ Rdb_crashextension \
+))
+endif
+
$(eval $(call gb_Module_add_check_targets,desktop, \
CppunitTest_desktop_app \
CppunitTest_desktop_version \
diff --git a/desktop/README.md b/desktop/README.md
index 1474f11e2718..88bed9658369 100644
--- a/desktop/README.md
+++ b/desktop/README.md
@@ -39,3 +39,18 @@ separated from each other by two-byte `NUL` code units.
### oosplash
Splash screen for the LibreOffice `soffice` binary.
+
+
+## Extensions
+
+The directory `test/deployment` contains some extensions to be used for testing:
+
+* `test/deployment/crashextension`: C++ extension to make LibreOffice crash. Useful for testing Crashreporter.
+ * Build with `Extension_test-crashextension`.
+ * Extension can be found in `workdir/Extension/test-crashextension.oxt`
+* `test/deployment/passive`: C++, Java and Python extension samples with passive registration.
+ * Build with `make Extension_test-passive`.
+ * Extension can be found in `workdir/Extension/test-passive.oxt`
+* `test/deployment/active`: C++, Java and Python extension samples with active registration.
+ * Build with `make Extension_test-active`.
+ * Extension can be found in `workdir/Extension/test-active.oxt`
diff --git a/desktop/Rdb_crashextension.mk b/desktop/Rdb_crashextension.mk
new file mode 100644
index 000000000000..9229fe4b904d
--- /dev/null
+++ b/desktop/Rdb_crashextension.mk
@@ -0,0 +1,12 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Rdb_Rdb,crashextension))
+
+# vim: set noet sw=4 ts=4:
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index e2ecf5920aa0..0c96240f1b0d 100644
--- a/desktop/inc/app.hxx
+++ b/desktop/inc/app.hxx
@@ -58,7 +58,8 @@ class Desktop final : public Application
BE_LANGUAGE_MISSING,
BE_USERINSTALL_NOTENOUGHDISKSPACE,
BE_USERINSTALL_NOWRITEACCESS,
- BE_OFFICECONFIG_BROKEN
+ BE_OFFICECONFIG_BROKEN,
+ BE_2NDOFFICE_WITHCAT,
};
enum BootstrapStatus
{
@@ -68,7 +69,7 @@ class Desktop final : public Application
Desktop();
virtual ~Desktop() override;
- virtual int Main( ) override;
+ virtual int Main() override;
virtual void Init() override;
virtual void InitFinished() override;
virtual void DeInit() override;
@@ -123,8 +124,7 @@ class Desktop final : public Application
// throws an exception upon failure
private:
- void RegisterServices(
- css::uno::Reference< css::uno::XComponentContext > const & context);
+ void RegisterServices();
static void DeregisterServices();
public:
diff --git a/desktop/inc/bitmaps.hlst b/desktop/inc/bitmaps.hlst
index 69005c522c50..1f565b47dd6e 100644
--- a/desktop/inc/bitmaps.hlst
+++ b/desktop/inc/bitmaps.hlst
@@ -9,9 +9,9 @@
#pragma once
-inline constexpr OUStringLiteral RID_BMP_WARNING = u"desktop/res/caution_16.png";
-inline constexpr OUStringLiteral RID_BMP_LOCKED = u"desktop/res/lock_16.png";
-inline constexpr OUStringLiteral RID_BMP_SHARED = u"desktop/res/shared_16.png";
-inline constexpr OUStringLiteral RID_BMP_EXTENSION = u"desktop/res/extension_32.png";
+inline constexpr OUString RID_BMP_WARNING = u"desktop/res/caution_16.png"_ustr;
+inline constexpr OUString RID_BMP_LOCKED = u"desktop/res/lock_16.png"_ustr;
+inline constexpr OUString RID_BMP_SHARED = u"desktop/res/shared_16.png"_ustr;
+inline constexpr OUString RID_BMP_EXTENSION = u"desktop/res/extension_32.png"_ustr;
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/desktop/inc/dp_misc.h b/desktop/inc/dp_misc.h
index f4c222a943a7..f9ac5687e46a 100644
--- a/desktop/inc/dp_misc.h
+++ b/desktop/inc/dp_misc.h
@@ -64,7 +64,7 @@ OUString expandUnoRcUrl( OUString const & url );
be again encoded for use in an "expand" URL.
*/
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString makeURL(
- OUString const & baseURL, OUString const & relPath );
+ std::u16string_view baseURL, OUString const & relPath );
/** appends a relative path to a url.
@@ -73,7 +73,7 @@ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString makeURL(
of an system path.
*/
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString makeURLAppendSysPathSegment(
- OUString const & baseURL, OUString const & relPath );
+ std::u16string_view baseURL, OUString const & relPath );
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString generateRandomPipeId();
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 288fa8ebfcc0..614ef404ddd2 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -13,6 +13,7 @@
#include <unordered_map>
#include <memory>
#include <mutex>
+#include <set>
#include <string_view>
#include <boost/property_tree/ptree.hpp>
@@ -21,6 +22,7 @@
#include <osl/thread.h>
#include <rtl/ref.hxx>
+#include <rtl/strbuf.hxx>
#include <vcl/idle.hxx>
#include <LibreOfficeKit/LibreOfficeKit.h>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -41,6 +43,7 @@ namespace desktop {
{
tools::Rectangle m_aRectangle;
int m_nPart;
+ int m_nMode;
// This is the "EMPTY" rectangle, which somewhat confusingly actually means
// to drop all rectangles (see LOK_CALLBACK_INVALIDATE_TILES documentation),
@@ -49,22 +52,24 @@ namespace desktop {
RectangleAndPart()
: m_nPart(INT_MIN) // -1 is reserved to mean "all parts".
+ , m_nMode(0)
{
}
- RectangleAndPart(const tools::Rectangle* pRect, int nPart)
+ RectangleAndPart(const tools::Rectangle* pRect, int nPart, int nMode)
: m_aRectangle( pRect ? SanitizedRectangle(*pRect) : emptyAllRectangle)
, m_nPart(nPart)
+ , m_nMode(nMode)
{
}
OString toString() const
{
if (m_nPart >= -1)
- return (isInfinite() ? "EMPTY" : m_aRectangle.toString())
- + ", " + OString::number(m_nPart);
+ return (isInfinite() ? "EMPTY"_ostr : m_aRectangle.toString())
+ + ", " + OString::number(m_nPart) + ", " + OString::number(m_nMode);
else
- return (isInfinite() ? "EMPTY" : m_aRectangle.toString());
+ return (isInfinite() ? "EMPTY"_ostr : m_aRectangle.toString());
}
/// Infinite Rectangle is both sides are
@@ -81,21 +86,21 @@ namespace desktop {
return m_aRectangle.IsEmpty();
}
- static RectangleAndPart Create(const std::string& rPayload);
+ static RectangleAndPart Create(const OString& rPayload);
/// Makes sure a rectangle is valid (apparently some code does not like negative coordinates for example).
static tools::Rectangle SanitizedRectangle(tools::Long nLeft, tools::Long nTop, tools::Long nWidth, tools::Long nHeight);
static tools::Rectangle SanitizedRectangle(const tools::Rectangle& rect);
};
/// One instance of this per view, handles flushing callbacks
- class DESKTOP_DLLPUBLIC CallbackFlushHandler final : public Idle, public SfxLokCallbackInterface
+ class SAL_DLLPUBLIC_RTTI CallbackFlushHandler final : public Idle, public SfxLokCallbackInterface
{
public:
- explicit CallbackFlushHandler(LibreOfficeKitDocument* pDocument, LibreOfficeKitCallback pCallback, void* pData);
- virtual ~CallbackFlushHandler() override;
+ DESKTOP_DLLPUBLIC explicit CallbackFlushHandler(LibreOfficeKitDocument* pDocument, LibreOfficeKitCallback pCallback, void* pData);
+ DESKTOP_DLLPUBLIC virtual ~CallbackFlushHandler() override;
virtual void Invoke() override;
// TODO This should be dropped and the binary libreOfficeKitViewCallback() variants should be called?
- void queue(const int type, const char* data);
+ DESKTOP_DLLPUBLIC void queue(const int type, const OString& data);
/// Disables callbacks on this handler. Must match with identical count
/// of enableCallbacks. Used during painting and changing views.
@@ -112,32 +117,39 @@ namespace desktop {
void setViewId( int viewId ) { m_viewId = viewId; }
// SfxLockCallbackInterface
- virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) override;
- virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) override;
- virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart) override;
+ virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) override;
+ virtual void libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId) override;
+ DESKTOP_DLLPUBLIC virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart, int nMode) override;
virtual void libreOfficeKitViewUpdatedCallback(int nType) override;
virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) override;
+ virtual void libreOfficeKitViewAddPendingInvalidateTiles() override;
+ virtual void dumpState(rtl::OStringBuffer &rState) override;
private:
struct CallbackData
{
- CallbackData(const char* payload)
- : PayloadString(payload ? payload : "(nil)")
+ CallbackData(OString payload)
+ : PayloadString(std::move(payload))
{
}
- CallbackData(const char* payload, int viewId)
- : PayloadString(payload ? payload : "(nil)")
+ CallbackData(OString payload, int viewId)
+ : PayloadString(std::move(payload))
, PayloadObject(viewId)
{
}
CallbackData(const tools::Rectangle* pRect, int viewId)
- : PayloadObject(RectangleAndPart(pRect, viewId))
+ : PayloadObject(RectangleAndPart(pRect, viewId, 0))
{ // PayloadString will be done on demand
}
- const std::string& getPayload() const;
+ CallbackData(const tools::Rectangle* pRect, int part, int mode)
+ : PayloadObject(RectangleAndPart(pRect, part, mode))
+ { // PayloadString will be done on demand
+ }
+
+ const OString& getPayload() const;
/// Update a RectangleAndPart object and update PayloadString if necessary.
void updateRectangleAndPart(const RectangleAndPart& rRectAndPart);
/// Return the parsed RectangleAndPart instance.
@@ -153,7 +165,7 @@ namespace desktop {
bool isEmpty() const
{
- return PayloadString.empty() && PayloadObject.which() == 0;
+ return PayloadString.isEmpty() && PayloadObject.which() == 0;
}
void clear()
{
@@ -168,7 +180,7 @@ namespace desktop {
bool isCached() const { return PayloadObject.which() != 0; }
private:
- mutable std::string PayloadString;
+ mutable OString PayloadString;
/// The parsed payload cache. Update validate() when changing this.
mutable boost::variant<boost::blank, RectangleAndPart, boost::property_tree::ptree, int> PayloadObject;
@@ -177,6 +189,7 @@ namespace desktop {
typedef std::vector<int> queue_type1;
typedef std::vector<CallbackData> queue_type2;
+ void startTimer();
bool removeAll(int type);
bool removeAll(int type, const std::function<bool (const CallbackData&)>& rTestFunc);
bool processInvalidateTilesEvent(int type, CallbackData& aCallbackData);
@@ -191,9 +204,9 @@ namespace desktop {
so we split the queue in 2 to make the scanning cache friendly. */
queue_type1 m_queue1;
queue_type2 m_queue2;
- std::map<int, std::string> m_states;
- std::unordered_map<std::string, std::string> m_lastStateChange;
- std::unordered_map<int, std::unordered_map<int, std::string>> m_viewStates;
+ std::map<int, OString> m_states;
+ std::unordered_map<OString, OString> m_lastStateChange;
+ std::unordered_map<int, std::unordered_map<int, OString>> m_viewStates;
// For some types only the last message matters (see isUpdatedType()) or only the last message
// per each viewId value matters (see isUpdatedTypePerViewId()), so instead of using push model
@@ -219,7 +232,7 @@ namespace desktop {
LibreOfficeKitCallback m_pCallback;
void *m_pData;
int m_nDisableCallbacks;
- std::mutex m_mutex;
+ std::recursive_mutex m_mutex;
class TimeoutIdle : public Timer
{
public:
@@ -237,8 +250,9 @@ namespace desktop {
std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
std::map<size_t, std::shared_ptr<CallbackFlushHandler>> mpCallbackFlushHandlers;
const int mnDocumentId;
+ std::set<OUString> maFontsMissing;
- explicit LibLODocument_Impl(const css::uno::Reference<css::lang::XComponent>& xComponent,
+ explicit LibLODocument_Impl(css::uno::Reference<css::lang::XComponent> xComponent,
int nDocumentId);
~LibLODocument_Impl();
};
@@ -260,6 +274,8 @@ namespace desktop {
{
return (mOptionalFeatures & feature) != 0;
}
+
+ void dumpState(rtl::OStringBuffer &aState);
};
/// Helper function to extract the value from parameters delimited by
diff --git a/desktop/inc/pch/precompiled_deployment.hxx b/desktop/inc/pch/precompiled_deployment.hxx
index f4e8cf931cef..bc0dd95fd4ea 100644
--- a/desktop/inc/pch/precompiled_deployment.hxx
+++ b/desktop/inc/pch/precompiled_deployment.hxx
@@ -76,7 +76,7 @@
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <svl/inettype.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <ucbhelper/content.hxx>
#include <unotools/unotoolsdllapi.h>
#include <xmlscript/xml_helper.hxx>
diff --git a/desktop/inc/pch/precompiled_sofficeapp.hxx b/desktop/inc/pch/precompiled_sofficeapp.hxx
index 58efb5dc3b0f..3635613937e9 100644
--- a/desktop/inc/pch/precompiled_sofficeapp.hxx
+++ b/desktop/inc/pch/precompiled_sofficeapp.hxx
@@ -102,12 +102,11 @@
#include <vcl/bitmapex.hxx>
#include <vcl/checksum.hxx>
#include <vcl/dllapi.h>
-#include <vcl/errcode.hxx>
+#include <comphelper/errcode.hxx>
#include <vcl/fntstyle.hxx>
#include <vcl/font.hxx>
#include <vcl/mapmod.hxx>
#include <vcl/region.hxx>
-#include <vcl/scopedbitmapaccess.hxx>
#include <vcl/vclenum.hxx>
#include <vcl/vclptr.hxx>
#endif // PCH_LEVEL >= 2
@@ -172,7 +171,7 @@
#include <svtools/svtdllapi.h>
#include <tools/color.hxx>
#include <tools/degree.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <tools/fontenum.hxx>
#include <tools/gen.hxx>
#include <tools/link.hxx>
diff --git a/desktop/inc/strings.hrc b/desktop/inc/strings.hrc
index b18117bb5a0d..eb4e238d1a6e 100644
--- a/desktop/inc/strings.hrc
+++ b/desktop/inc/strings.hrc
@@ -19,7 +19,7 @@
#pragma once
-#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+#define NC_(Context, String) TranslateId(Context, u8##String)
#define RID_STR_COPYING_PACKAGE NC_("RID_STR_COPYING_PACKAGE", "Copying: ")
#define RID_STR_ERROR_WHILE_ADDING NC_("RID_STR_ERROR_WHILE_ADDING", "Error while adding: ")
@@ -163,6 +163,7 @@
#define STR_BOOTSTRAP_ERR_LANGUAGE_MISSING NC_("STR_BOOTSTRAP_ERR_LANGUAGE_MISSING", "The user interface language cannot be determined.")
#define STR_BOOTSTRAP_ERR_USERINSTALL_FAILED NC_("STR_BOOTSTRAP_ERR_USERINSTALL_FAILED", "User installation could not be completed. ")
#define STR_BOOTSTRAP_ERR_NO_CFG_SERVICE NC_("STR_BOOTSTRAP_ERR_NO_CFG_SERVICE", "The configuration service is not available.")
+#define STR_BOOTSTRAP_ERR_2NDOFFICE_WITHCAT NC_("STR_BOOTSTRAP_ERR_2NDOFFICE_WITHCAT", "There is already another %PRODUCTNAME instance running. Please close all %PRODUCTNAME processes before running with the '--cat' or '--script-cat' option.")
#define STR_ASK_START_SETUP_MANUALLY NC_("STR_ASK_START_SETUP_MANUALLY", "Start the setup application to repair the installation from the CD or the folder containing the installation packages.")
#define STR_CONFIG_ERR_ACCESS_GENERAL NC_("STR_CONFIG_ERR_ACCESS_GENERAL", "A general error occurred while accessing your central configuration. ")
#define STR_LO_MUST_BE_RESTARTED NC_("STR_LO_MUST_BE_RESTARTED", "%PRODUCTNAME must unfortunately be manually restarted once after installation or update." )
diff --git a/desktop/inc/strings.hxx b/desktop/inc/strings.hxx
index 9b086b52693e..09582c6c5e66 100644
--- a/desktop/inc/strings.hxx
+++ b/desktop/inc/strings.hxx
@@ -11,6 +11,6 @@
#include <rtl/ustring.hxx>
-inline constexpr OUStringLiteral RID_APPTITLE = u"%PRODUCTNAME %PRODUCTVERSION%PRODUCTEXTENSION";
+inline constexpr OUString RID_APPTITLE = u"%PRODUCTNAME %PRODUCTVERSION%PRODUCTEXTENSION"_ustr;
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/desktop/lokclipboard.component b/desktop/lokclipboard.component
new file mode 100644
index 000000000000..a2c7c63284aa
--- /dev/null
+++ b/desktop/lokclipboard.component
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.datatransfer.LOKClipboard"
+ constructor="desktop_LOKClipboard_get_implementation">
+ <service name="com.sun.star.datatransfer.clipboard.LokClipboard"/>
+ </implementation>
+</component>
diff --git a/desktop/qa/data/3page.odg b/desktop/qa/data/3page.odg
new file mode 100644
index 000000000000..1fad913e0493
--- /dev/null
+++ b/desktop/qa/data/3page.odg
Binary files differ
diff --git a/desktop/qa/data/ThemeDocument.docx b/desktop/qa/data/ThemeDocument.docx
new file mode 100644
index 000000000000..4dbba883d9b6
--- /dev/null
+++ b/desktop/qa/data/ThemeDocument.docx
Binary files differ
diff --git a/desktop/qa/data/comments.odt b/desktop/qa/data/comments.odt
index ee7f15f8b755..1bcdcc0385ea 100644
--- a/desktop/qa/data/comments.odt
+++ b/desktop/qa/data/comments.odt
Binary files differ
diff --git a/desktop/qa/deployment_misc/test_dp_version.cxx b/desktop/qa/deployment_misc/test_dp_version.cxx
index e896686865be..1b8fb9086769 100644
--- a/desktop/qa/deployment_misc/test_dp_version.cxx
+++ b/desktop/qa/deployment_misc/test_dp_version.cxx
@@ -60,7 +60,7 @@ void Test::test() {
OUString("9223372036854775807"),
::dp_misc::GREATER }
};
- for (std::size_t i = 0; i < SAL_N_ELEMENTS(data); ++i) {
+ for (std::size_t i = 0; i < std::size(data); ++i) {
CPPUNIT_ASSERT_EQUAL(
data[i].order,
::dp_misc::compareVersions(data[i].version1, data[i].version2));
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 689a406e4a07..4310e64f25dd 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -11,7 +11,6 @@
#include <memory>
#include <string_view>
-#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/awt/Key.hpp>
@@ -21,6 +20,7 @@
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
#include <vcl/scheduler.hxx>
#include <vcl/svapp.hxx>
@@ -30,13 +30,10 @@
#include <vcl/uitest/uiobject.hxx>
#include <comphelper/processfactory.hxx>
#include <rtl/math.hxx>
-#include <rtl/uri.hxx>
-#include <sfx2/app.hxx>
#include <sfx2/childwin.hxx>
#include <sfx2/lokhelper.hxx>
#include <test/unoapi_test.hxx>
#include <comphelper/lok.hxx>
-#include <comphelper/dispatchcommand.hxx>
#include <comphelper/propertysequence.hxx>
#include <osl/conditn.hxx>
#include <svl/srchitem.hxx>
@@ -50,18 +47,22 @@
#include <comphelper/string.hxx>
#include <comphelper/scopeguard.hxx>
#include <cairo.h>
-#include <config_features.h>
#include <config_fonts.h>
#include <config_mpl.h>
#include <tools/json_writer.hxx>
#include <o3tl/unit_conversion.hxx>
+#include <o3tl/string_view.hxx>
#include <lib/init.hxx>
#include <svx/svxids.hrc>
#include <cppunit/TestAssert.h>
#include <vcl/BitmapTools.hxx>
-#include <vcl/pngwrite.hxx>
+#include <vcl/filter/PngImageWriter.hxx>
+#include <vcl/filter/PDFiumLibrary.hxx>
+#include <svtools/colorcfg.hxx>
+#include <sal/types.h>
+#include <test/lokcallback.hxx>
#if USE_TLS_NSS
#include <nss.h>
@@ -113,28 +114,27 @@ public:
comphelper::LibreOfficeKit::setActive(true);
UnoApiTest::setUp();
- mxDesktop.set(frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
- SfxApplication::GetOrCreate();
}
virtual void tearDown() override
{
closeDoc();
- UnoApiTest::tearDown();
+ // documents are already closed, no need to call UnoApiTest::tearDown
+ test::BootstrapFixture::tearDown();
comphelper::LibreOfficeKit::setActive(false);
}
- std::pair<std::unique_ptr<LibLODocument_Impl>, uno::Reference<lang::XComponent>>
+ std::unique_ptr<LibLODocument_Impl>
loadDocImpl(const char* pName, LibreOfficeKitDocumentType eType);
private:
- std::pair<std::unique_ptr<LibLODocument_Impl>, uno::Reference<lang::XComponent>>
+ std::unique_ptr<LibLODocument_Impl>
loadDocImpl(const char* pName);
public:
- std::pair<std::unique_ptr<LibLODocument_Impl>, uno::Reference<lang::XComponent>>
+ std::unique_ptr<LibLODocument_Impl>
loadDocUrlImpl(const OUString& rFileURL, LibreOfficeKitDocumentType eType);
LibLODocument_Impl* loadDocUrl(const OUString& rFileURL, LibreOfficeKitDocumentType eType);
@@ -144,9 +144,8 @@ public:
return loadDoc(pName, getDocumentTypeFromName(pName));
}
- void closeDoc(std::unique_ptr<LibLODocument_Impl>& loDocument,
- uno::Reference<lang::XComponent>& xComponent);
- void closeDoc() { closeDoc(m_pDocument, mxComponent); }
+ void closeDoc(std::unique_ptr<LibLODocument_Impl>& loDocument);
+ void closeDoc() { closeDoc(m_pDocument); }
static void callback(int nType, const char* pPayload, void* pData);
void callbackImpl(int nType, const char* pPayload);
@@ -159,6 +158,7 @@ public:
void testSearchAllNotificationsCalc();
void testPaintTile();
void testSaveAs();
+ void testSaveAsJsonOptions();
void testSaveAsCalc();
void testPasteWriter();
void testPasteWriterJPEG();
@@ -170,6 +170,7 @@ public:
void testWriterComments();
void testSheetOperations();
void testSheetSelections();
+ void testSheetDragDrop();
void testContextMenuCalc();
void testContextMenuWriter();
void testContextMenuImpress();
@@ -182,6 +183,7 @@ public:
void testTrackChanges();
void testRedlineCalc();
void testPaintPartTile();
+ void testPaintPartTileDifferentSchemes();
#if HAVE_MORE_FONTS
void testGetFontSubset();
#endif
@@ -194,16 +196,16 @@ public:
void testExtractParameter();
void testGetSignatureState_NonSigned();
void testGetSignatureState_Signed();
+#if 0 // broken with system nss on RHEL 7
void testInsertCertificate_DER_ODT();
void testInsertCertificate_PEM_ODT();
void testInsertCertificate_PEM_DOCX();
+#endif
void testSignDocument_PEM_PDF();
void testTextSelectionHandles();
void testComplexSelection();
void testSpellcheckerMultiView();
void testDialogPaste();
- void testShowHideDialog();
- void testDialogInput();
void testCalcSaveAs();
void testControlState();
void testMetricField();
@@ -213,6 +215,7 @@ public:
void testRenderSearchResult_CommonNode();
void testNoDuplicateTableSelection();
void testMultiViewTableSelection();
+ void testColorPaletteCallback();
void testABI();
CPPUNIT_TEST_SUITE(DesktopLOKTest);
@@ -225,6 +228,7 @@ public:
CPPUNIT_TEST(testSearchAllNotificationsCalc);
CPPUNIT_TEST(testPaintTile);
CPPUNIT_TEST(testSaveAs);
+ CPPUNIT_TEST(testSaveAsJsonOptions);
CPPUNIT_TEST(testSaveAsCalc);
CPPUNIT_TEST(testPasteWriter);
CPPUNIT_TEST(testPasteWriterJPEG);
@@ -236,6 +240,7 @@ public:
CPPUNIT_TEST(testWriterComments);
CPPUNIT_TEST(testSheetOperations);
CPPUNIT_TEST(testSheetSelections);
+ CPPUNIT_TEST(testSheetDragDrop);
CPPUNIT_TEST(testContextMenuCalc);
CPPUNIT_TEST(testContextMenuWriter);
CPPUNIT_TEST(testContextMenuImpress);
@@ -248,6 +253,7 @@ public:
CPPUNIT_TEST(testTrackChanges);
CPPUNIT_TEST(testRedlineCalc);
CPPUNIT_TEST(testPaintPartTile);
+ CPPUNIT_TEST(testPaintPartTileDifferentSchemes);
#if HAVE_MORE_FONTS
CPPUNIT_TEST(testGetFontSubset);
#endif
@@ -261,17 +267,17 @@ public:
CPPUNIT_TEST(testGetSignatureState_Signed);
CPPUNIT_TEST(testGetSignatureState_NonSigned);
#if !MPL_HAVE_SUBSET
+#if 0 // broken with system nss on RHEL 7
CPPUNIT_TEST(testInsertCertificate_DER_ODT);
CPPUNIT_TEST(testInsertCertificate_PEM_ODT);
CPPUNIT_TEST(testInsertCertificate_PEM_DOCX);
+#endif
CPPUNIT_TEST(testSignDocument_PEM_PDF);
#endif
CPPUNIT_TEST(testTextSelectionHandles);
CPPUNIT_TEST(testComplexSelection);
CPPUNIT_TEST(testSpellcheckerMultiView);
CPPUNIT_TEST(testDialogPaste);
- CPPUNIT_TEST(testShowHideDialog);
- CPPUNIT_TEST(testDialogInput);
CPPUNIT_TEST(testCalcSaveAs);
CPPUNIT_TEST(testControlState);
CPPUNIT_TEST(testMetricField);
@@ -281,10 +287,10 @@ public:
CPPUNIT_TEST(testRenderSearchResult_CommonNode);
CPPUNIT_TEST(testNoDuplicateTableSelection);
CPPUNIT_TEST(testMultiViewTableSelection);
+ CPPUNIT_TEST(testColorPaletteCallback);
CPPUNIT_TEST(testABI);
CPPUNIT_TEST_SUITE_END();
- uno::Reference<lang::XComponent> mxComponent;
OString m_aTextSelection;
OString m_aTextSelectionStart;
OString m_aTextSelectionEnd;
@@ -333,7 +339,7 @@ static Control* GetFocusControl(vcl::Window const * pParent)
return nullptr;
}
-std::pair<std::unique_ptr<LibLODocument_Impl>, uno::Reference<lang::XComponent>>
+std::unique_ptr<LibLODocument_Impl>
DesktopLOKTest::loadDocUrlImpl(const OUString& rFileURL, LibreOfficeKitDocumentType eType)
{
OUString aService;
@@ -355,23 +361,22 @@ DesktopLOKTest::loadDocUrlImpl(const OUString& rFileURL, LibreOfficeKitDocumentT
static int nDocumentIdCounter = 0;
SfxViewShell::SetCurrentDocId(ViewShellDocId(nDocumentIdCounter));
- uno::Reference<lang::XComponent> xComponent = loadFromDesktop(rFileURL, aService);
+ mxComponent = loadFromDesktop(rFileURL, aService);
- std::unique_ptr<LibLODocument_Impl> pDocument(new LibLODocument_Impl(xComponent, nDocumentIdCounter));
+ std::unique_ptr<LibLODocument_Impl> pDocument(new LibLODocument_Impl(mxComponent, nDocumentIdCounter));
++nDocumentIdCounter;
- return std::make_pair(std::move(pDocument), xComponent);
+ return pDocument;
}
-std::pair<std::unique_ptr<LibLODocument_Impl>, uno::Reference<lang::XComponent>>
+std::unique_ptr<LibLODocument_Impl>
DesktopLOKTest::loadDocImpl(const char* pName, LibreOfficeKitDocumentType eType)
{
- OUString aFileURL;
- createFileURL(OUString::createFromAscii(pName), aFileURL);
+ OUString aFileURL = createFileURL(OUString::createFromAscii(pName));
return loadDocUrlImpl(aFileURL, eType);
}
-std::pair<std::unique_ptr<LibLODocument_Impl>, uno::Reference<lang::XComponent>>
+std::unique_ptr<LibLODocument_Impl>
DesktopLOKTest::loadDocImpl(const char* pName)
{
return loadDocImpl(pName, getDocumentTypeFromName(pName));
@@ -379,18 +384,17 @@ DesktopLOKTest::loadDocImpl(const char* pName)
LibLODocument_Impl* DesktopLOKTest::loadDocUrl(const OUString& rFileURL, LibreOfficeKitDocumentType eType)
{
- std::tie(m_pDocument, mxComponent) = loadDocUrlImpl(rFileURL, eType);
+ m_pDocument = loadDocUrlImpl(rFileURL, eType);
return m_pDocument.get();
}
LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType)
{
- std::tie(m_pDocument, mxComponent) = loadDocImpl(pName, eType);
+ m_pDocument = loadDocImpl(pName, eType);
return m_pDocument.get();
}
-void DesktopLOKTest::closeDoc(std::unique_ptr<LibLODocument_Impl>& pDocument,
- uno::Reference<lang::XComponent>& xComponent)
+void DesktopLOKTest::closeDoc(std::unique_ptr<LibLODocument_Impl>& pDocument)
{
if (pDocument)
{
@@ -398,10 +402,11 @@ void DesktopLOKTest::closeDoc(std::unique_ptr<LibLODocument_Impl>& pDocument,
pDocument.reset();
}
- if (xComponent.is())
+ if (mxComponent.is())
{
- closeDocument(xComponent);
- xComponent.clear();
+ css::uno::Reference<util::XCloseable> xCloseable(mxComponent, css::uno::UNO_QUERY_THROW);
+ xCloseable->close(false);
+ mxComponent.clear();
}
}
@@ -451,7 +456,7 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload)
case LOK_CALLBACK_STATE_CHANGED:
{
OString aPayload(pPayload);
- OString aPrefix(".uno:ModifiedStatus=");
+ OString aPrefix(".uno:ModifiedStatus="_ostr);
if (aPayload.startsWith(aPrefix))
{
m_bModified = aPayload.copy(aPrefix.getLength()).toBoolean();
@@ -597,12 +602,11 @@ void DesktopLOKTest::testSearchCalc()
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
- {"SearchItem.SearchString", uno::makeAny(OUString("foo"))},
- {"SearchItem.Backward", uno::makeAny(false)},
- {"SearchItem.Command", uno::makeAny(static_cast<sal_uInt16>(SvxSearchCmd::FIND_ALL))},
+ {"SearchItem.SearchString", uno::Any(OUString("foo"))},
+ {"SearchItem.Backward", uno::Any(false)},
+ {"SearchItem.Command", uno::Any(static_cast<sal_uInt16>(SvxSearchCmd::FIND_ALL))},
}));
- comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
- Scheduler::ProcessEventsToIdle();
+ dispatchCommand(mxComponent, ".uno:ExecuteSearch", aPropertyValues);
std::vector<OString> aSelections;
sal_Int32 nIndex = 0;
@@ -628,12 +632,11 @@ void DesktopLOKTest::testSearchAllNotificationsCalc()
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
- {"SearchItem.SearchString", uno::makeAny(OUString("foo"))},
- {"SearchItem.Backward", uno::makeAny(false)},
- {"SearchItem.Command", uno::makeAny(static_cast<sal_uInt16>(SvxSearchCmd::FIND_ALL))},
+ {"SearchItem.SearchString", uno::Any(OUString("foo"))},
+ {"SearchItem.Backward", uno::Any(false)},
+ {"SearchItem.Command", uno::Any(static_cast<sal_uInt16>(SvxSearchCmd::FIND_ALL))},
}));
- comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
- Scheduler::ProcessEventsToIdle();
+ dispatchCommand(mxComponent, ".uno:ExecuteSearch", aPropertyValues);
// This was 1, make sure that we get no notifications about selection changes during search.
CPPUNIT_ASSERT_EQUAL(0, m_nSelectionBeforeSearchResult);
@@ -670,30 +673,49 @@ void DesktopLOKTest::testPaintTile()
void DesktopLOKTest::testSaveAs()
{
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
- CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "png", nullptr));
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "png", nullptr));
+}
+
+void DesktopLOKTest::testSaveAsJsonOptions()
+{
+ // Given a document with 3 pages:
+ LibLODocument_Impl* pDocument = loadDoc("3page.odg");
+
+ // When exporting that document to PDF, skipping the first page:
+ OString aOptions("{\"PageRange\":{\"type\":\"string\",\"value\":\"2-\"}}"_ostr);
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "pdf", aOptions.getStr()));
+
+ std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+ if (!pPDFium)
+ return;
+
+ // Then make sure the resulting PDF has 2 pages:
+ std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
+ = parsePDFExport();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 3
+ // i.e. FilterOptions was ignored.
+ CPPUNIT_ASSERT_EQUAL(2, pPdfDocument->getPageCount());
}
void DesktopLOKTest::testSaveAsCalc()
{
LibLODocument_Impl* pDocument = loadDoc("search.ods");
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
- CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "png", nullptr));
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "png", nullptr));
}
void DesktopLOKTest::testPasteWriter()
{
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- OString aText("hello");
+ OString aText("hello"_ostr);
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength()));
pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", nullptr, false);
Scheduler::ProcessEventsToIdle();
char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr);
- CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText));
+ CPPUNIT_ASSERT_EQUAL("hello"_ostr, OString(pText));
free(pText);
// textt/plain should be rejected.
@@ -704,7 +726,7 @@ void DesktopLOKTest::testPasteWriter()
// Overwrite doc contents with a HTML paste.
pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", nullptr, false);
Scheduler::ProcessEventsToIdle();
- OString aComment("foo <!-- bar --> baz");
+ OString aComment("foo <!-- bar --> baz"_ostr);
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/html", aComment.getStr(), aComment.getLength()));
// Check if we have a comment.
@@ -724,8 +746,7 @@ void DesktopLOKTest::testPasteWriterJPEG()
{
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- OUString aFileURL;
- createFileURL(u"paste.jpg", aFileURL);
+ OUString aFileURL = createFileURL(u"paste.jpg");
std::ifstream aImageStream(aFileURL.toUtf8().copy(strlen("file://")).getStr());
std::vector<char> aImageContents((std::istreambuf_iterator<char>(aImageStream)), std::istreambuf_iterator<char>());
@@ -744,9 +765,9 @@ void DesktopLOKTest::testPasteWriterJPEG()
uno::Reference<lang::XComponent>(xShape, uno::UNO_QUERY_THROW)->dispose();
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
- {"AnchorType", uno::makeAny(static_cast<sal_uInt16>(text::TextContentAnchorType_AT_CHARACTER))},
+ {"AnchorType", uno::Any(static_cast<sal_uInt16>(text::TextContentAnchorType_AT_CHARACTER))},
}));
- comphelper::dispatchCommand(".uno:Paste", aPropertyValues);
+ dispatchCommand(mxComponent, ".uno:Paste", aPropertyValues);
xShape.set(xDrawPage->getByIndex(0), uno::UNO_QUERY);
// This was text::TextContentAnchorType_AS_CHARACTER, AnchorType argument was ignored.
CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, xShape->getPropertyValue("AnchorType").get<text::TextContentAnchorType>());
@@ -829,14 +850,14 @@ void DesktopLOKTest::testRowColumnHeaders()
bool bNotEnoughHeaders = true;
for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows"))
{
- sal_Int32 nSize = OString(rValue.second.get<std::string>("size").c_str()).toInt32();
+ sal_Int32 nSize = o3tl::toInt32(rValue.second.get<std::string>("size"));
nSize = o3tl::convert(nSize, o3tl::Length::px, o3tl::Length::twip);
- OString aText(rValue.second.get<std::string>("text").c_str());
+ OString aText(rValue.second.get<std::string>("text"));
if (bFirstHeader)
{
CPPUNIT_ASSERT(nSize <= nY);
- CPPUNIT_ASSERT_EQUAL(OString("10"), aText);
+ CPPUNIT_ASSERT_EQUAL("10"_ostr, aText);
bFirstHeader = false;
}
else
@@ -858,13 +879,13 @@ void DesktopLOKTest::testRowColumnHeaders()
bNotEnoughHeaders = true;
for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns"))
{
- sal_Int32 nSize = OString(rValue.second.get<std::string>("size").c_str()).toInt32();
+ sal_Int32 nSize = o3tl::toInt32(rValue.second.get<std::string>("size"));
nSize = o3tl::convert(nSize, o3tl::Length::px, o3tl::Length::twip);
- OString aText(rValue.second.get<std::string>("text").c_str());
+ OString aText(rValue.second.get<std::string>("text"));
if (bFirstHeader)
{
CPPUNIT_ASSERT(nSize <= nX);
- CPPUNIT_ASSERT_EQUAL(OString("3"), aText);
+ CPPUNIT_ASSERT_EQUAL("3"_ostr, aText);
bFirstHeader = false;
}
else
@@ -908,7 +929,7 @@ void DesktopLOKTest::testHiddenRowHeaders()
sal_Int32 nIndex = 0;
for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows"))
{
- sal_Int32 nSize = OString(rValue.second.get<std::string>("size").c_str()).toInt32();
+ sal_Int32 nSize = o3tl::toInt32(rValue.second.get<std::string>("size"));
if (nIndex++ == 2)
{
@@ -934,9 +955,9 @@ void DesktopLOKTest::testCellCursor()
boost::property_tree::read_json(aStream, aTree);
- OString aRectangle(aTree.get<std::string>("commandValues").c_str());
+ OString aRectangle(aTree.get<std::string>("commandValues"));
// cell cursor geometry + col + row
- CPPUNIT_ASSERT_EQUAL(OString("0, 0, 1274, 254, 0, 0"), aRectangle);
+ CPPUNIT_ASSERT_EQUAL("0, 0, 1274, 254, 0, 0"_ostr, aRectangle);
}
void DesktopLOKTest::testCommandResult()
@@ -966,7 +987,7 @@ void DesktopLOKTest::testCommandResult()
m_aCommandResultCondition.wait(aTimeValue);
boost::property_tree::ptree aTree;
- std::stringstream aStream(m_aCommandResult.getStr());
+ std::stringstream aStream((std::string(m_aCommandResult)));
boost::property_tree::read_json(aStream, aTree);
CPPUNIT_ASSERT_EQUAL(std::string(".uno:Bold"), aTree.get_child("commandName").get_value<std::string>());
@@ -1055,7 +1076,7 @@ void DesktopLOKTest::testSheetOperations()
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT_EQUAL(6, pDocument->pClass->getParts(pDocument));
- std::vector<OString> aExpected = { "FirstSheet", "Renamed", "Sheet3", "Sheet4", "Sheet5", "LastSheet" };
+ std::vector<OString> aExpected = { "FirstSheet"_ostr, "Renamed"_ostr, "Sheet3"_ostr, "Sheet4"_ostr, "Sheet5"_ostr, "LastSheet"_ostr };
for (int i = 0; i < 6; ++i)
{
char* pPartName = pDocument->pClass->getPartName(pDocument, i);
@@ -1114,11 +1135,11 @@ void DesktopLOKTest::testSheetSelections()
char* pCopiedContent = pDocument->pClass->getTextSelection(pDocument, nullptr, &pUsedMimeType);
std::vector<long> aExpected = {5, 6, 7, 8, 9};
std::istringstream iss(pCopiedContent);
- for (size_t i = 0; i < aExpected.size(); i++)
+ for (const long nIndex : aExpected)
{
std::string token;
iss >> token;
- CPPUNIT_ASSERT_EQUAL(aExpected[i], strtol(token.c_str(), nullptr, 10));
+ CPPUNIT_ASSERT_EQUAL(nIndex, strtol(token.c_str(), nullptr, 10));
}
free(pUsedMimeType);
@@ -1128,20 +1149,6 @@ void DesktopLOKTest::testSheetSelections()
/*
* Check if clicking inside the selection deselects the whole selection
*/
- int const row10 = 2400;
- // Select starting from row5, col1 to row10, col5
- pDocument->pClass->postMouseEvent(pDocument,
- LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
- col1, row5,
- 1, 1, 0);
- pDocument->pClass->postMouseEvent(pDocument,
- LOK_MOUSEEVENT_MOUSEMOVE,
- col5, row5,
- 1, 1, 0);
- pDocument->pClass->postMouseEvent(pDocument,
- LOK_MOUSEEVENT_MOUSEBUTTONUP,
- col5, row10,
- 1, 1, 0);
// Click at row5, col4
pDocument->pClass->postMouseEvent(pDocument,
@@ -1161,11 +1168,11 @@ void DesktopLOKTest::testSheetSelections()
char* pCopiedContent = pDocument->pClass->getTextSelection(pDocument, nullptr, &pUsedMimeType);
std::vector<long> aExpected = { 8 };
std::istringstream iss(pCopiedContent);
- for (size_t i = 0; i < aExpected.size(); i++)
+ for (const long nIndex : aExpected)
{
std::string token;
iss >> token;
- CPPUNIT_ASSERT_EQUAL(aExpected[i], strtol(token.c_str(), nullptr, 10));
+ CPPUNIT_ASSERT_EQUAL(nIndex, strtol(token.c_str(), nullptr, 10));
}
free(pUsedMimeType);
@@ -1173,6 +1180,132 @@ void DesktopLOKTest::testSheetSelections()
}
}
+void DesktopLOKTest::testSheetDragDrop()
+{
+ LibLODocument_Impl* pDocument = loadDoc("sheets.ods", LOK_DOCTYPE_SPREADSHEET);
+ pDocument->pClass->initializeForRendering(pDocument, nullptr);
+ pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
+
+ int row01 = 100;
+ int col01 = 1100;
+ int col02 = 2200;
+ int col03 = 3300;
+ int col05 = 5500;
+ int col07 = 5700;
+
+ // Select row 01 from column 01 through column 05
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+ col01, row01,
+ 1, 1, 0);
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEMOVE,
+ col02, row01,
+ 1, 1, 0);
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEMOVE,
+ col05, row01,
+ 1, 1, 0);
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEBUTTONUP,
+ col05, row01,
+ 1, 1, 0);
+
+ Scheduler::ProcessEventsToIdle();
+ {
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
+
+ OUString sValue;
+ css::uno::Any aValue;
+ css::util::URL aURL;
+ std::unique_ptr<SfxPoolItem> pState;
+
+ aURL.Protocol = ".uno:";
+ aURL.Complete = ".uno:Address";
+ aURL.Path = "Address";
+ aURL.Main = ".uno:Address";
+
+ rViewFrame.GetBindings().QueryState(rViewFrame.GetBindings().QuerySlotId(aURL), pState);
+ pState->QueryValue(aValue);
+ aValue >>= sValue;
+ CPPUNIT_ASSERT_EQUAL(OUString("Sheet5.A1:E1"), sValue);
+ }
+
+ // Check selection content
+ {
+ char* pMimeType = nullptr;
+ char* pContent = pDocument->pClass->getTextSelection(pDocument, nullptr, &pMimeType);
+ std::vector<long> aExpected = {1, 2, 3, 4, 5};
+ std::istringstream aContent(pContent);
+ std::string token;
+ for (const long nIndex : aExpected)
+ {
+ aContent >> token;
+ CPPUNIT_ASSERT_EQUAL(nIndex, strtol(token.c_str(), nullptr, 10));
+ }
+
+ free(pMimeType);
+ free(pContent);
+ }
+
+ // drag and drop
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+ col01, row01,
+ 1, 1, 0);
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEMOVE,
+ col02, row01,
+ 1, 1, 0);
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEMOVE,
+ col03, row01,
+ 1, 1, 0);
+ pDocument->pClass->postMouseEvent(pDocument,
+ LOK_MOUSEEVENT_MOUSEBUTTONUP,
+ col07, row01,
+ 1, 1, 0);
+
+ Scheduler::ProcessEventsToIdle();
+ {
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
+
+ OUString sValue;
+ css::uno::Any aValue;
+ css::util::URL aURL;
+ std::unique_ptr<SfxPoolItem> pState;
+
+ aURL.Protocol = ".uno:";
+ aURL.Complete = ".uno:Address";
+ aURL.Path = "Address";
+ aURL.Main = ".uno:Address";
+
+ rViewFrame.GetBindings().QueryState(rViewFrame.GetBindings().QuerySlotId(aURL), pState);
+ pState->QueryValue(aValue);
+ aValue >>= sValue;
+ CPPUNIT_ASSERT_EQUAL(OUString("Sheet5.D1:H1"), sValue);
+ }
+
+ // Check selection content
+ {
+ char* pMimeType = nullptr;
+ char* pContent = pDocument->pClass->getTextSelection(pDocument, nullptr, &pMimeType);
+ std::vector<long> aExpected = {1, 2, 3, 4, 5};
+ std::istringstream aContent(pContent);
+ std::string token;
+ for (const long nIndex : aExpected)
+ {
+ aContent >> token;
+ CPPUNIT_ASSERT_EQUAL(nIndex, strtol(token.c_str(), nullptr, 10));
+ }
+
+ free(pMimeType);
+ free(pContent);
+ }
+}
+
namespace {
void verifyContextMenuStructure(boost::property_tree::ptree& aRoot)
@@ -1548,37 +1681,37 @@ void DesktopLOKTest::testNotificationCompression()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // 0
- handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"); // Superseded.
- handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // Should be dropped.
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"); // 1
- handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"); // Should be dropped.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""); // Superseded.
- handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 2
- handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:Bold"); // 3
- handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 4
- handler->queue(LOK_CALLBACK_MOUSE_POINTER, "text"); // 5
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"); // Should be dropped.
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"); // Should be dropped.
- handler->queue(LOK_CALLBACK_MOUSE_POINTER, "text"); // Should be dropped.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15, 25, 15, 10"); // Superseded.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15, 25, 15, 10"); // Superseded.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"); // Superseded.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15, 25, 15, 10"); // Should be dropped.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15, 25, 15, 10"); // Should be dropped.
- handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""); // 7
- handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15, 25, 15, 10"); // 8
- handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15, 25, 15, 10"); // 9
- handler->queue(LOK_CALLBACK_CELL_CURSOR, "15, 25, 15, 10"); // 10
- handler->queue(LOK_CALLBACK_CURSOR_VISIBLE, ""); // 11
- handler->queue(LOK_CALLBACK_CELL_CURSOR, "15, 25, 15, 10"); // Should be dropped.
- handler->queue(LOK_CALLBACK_CELL_FORMULA, "blah"); // 12
- handler->queue(LOK_CALLBACK_SET_PART, "1"); // 13
- handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:AssignLayout=20"); // Superseded
- handler->queue(LOK_CALLBACK_CURSOR_VISIBLE, ""); // Should be dropped.
- handler->queue(LOK_CALLBACK_CELL_FORMULA, "blah"); // Should be dropped.
- handler->queue(LOK_CALLBACK_SET_PART, "1"); // Should be dropped.
- handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:AssignLayout=1"); // 14
+ handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""_ostr); // 0
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"_ostr); // Superseded.
+ handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"_ostr); // 1
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""_ostr); // Superseded.
+ handler->queue(LOK_CALLBACK_STATE_CHANGED, ""_ostr); // 2
+ handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:Bold"_ostr); // 3
+ handler->queue(LOK_CALLBACK_STATE_CHANGED, ""_ostr); // 4
+ handler->queue(LOK_CALLBACK_MOUSE_POINTER, "text"_ostr); // 5
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_MOUSE_POINTER, "text"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15, 25, 15, 10"_ostr); // Superseded.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15, 25, 15, 10"_ostr); // Superseded.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"_ostr); // Superseded.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15, 25, 15, 10"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15, 25, 15, 10"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""_ostr); // 7
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15, 25, 15, 10"_ostr); // 8
+ handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15, 25, 15, 10"_ostr); // 9
+ handler->queue(LOK_CALLBACK_CELL_CURSOR, "15, 25, 15, 10"_ostr); // 10
+ handler->queue(LOK_CALLBACK_CURSOR_VISIBLE, ""_ostr); // 11
+ handler->queue(LOK_CALLBACK_CELL_CURSOR, "15, 25, 15, 10"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_CELL_FORMULA, "blah"_ostr); // 12
+ handler->queue(LOK_CALLBACK_SET_PART, "1"_ostr); // 13
+ handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:AssignLayout=20"_ostr); // Superseded
+ handler->queue(LOK_CALLBACK_CURSOR_VISIBLE, ""_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_CELL_FORMULA, "blah"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_SET_PART, "1"_ostr); // Should be dropped.
+ handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:AssignLayout=1"_ostr); // 14
Scheduler::ProcessEventsToIdle();
@@ -1644,11 +1777,11 @@ void DesktopLOKTest::testTileInvalidationCompression()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-100, -50, 500, 650, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "100, 100, 200, 200, 0");
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-100, -50, 500, 650, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "100, 100, 200, 200, 0, 0"_ostr);
Scheduler::ProcessEventsToIdle();
@@ -1656,7 +1789,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
size_t i = 0;
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 400, 600, 0"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 400, 600, 0, 0"), std::get<1>(notifs[i++]));
}
// Part Number
@@ -1665,11 +1798,11 @@ void DesktopLOKTest::testTileInvalidationCompression()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 1"); // Different part
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 0, 0, 2"); // Invalid
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 200, 200, 0"); // Inside first
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 1"); // Invalid
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 1, 0"_ostr); // Different part
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 0, 0, 2, 0"_ostr); // Invalid
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 200, 200, 0, 0"_ostr); // Inside first
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 1, 0"_ostr); // Invalid
Scheduler::ProcessEventsToIdle();
@@ -1677,10 +1810,10 @@ void DesktopLOKTest::testTileInvalidationCompression()
size_t i = 0;
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 200, 200, 1"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 200, 200, 1, 0"), std::get<1>(notifs[i++]));
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 239, 239, 0"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 239, 239, 0, 0"), std::get<1>(notifs[i++]));
}
// All Parts
@@ -1689,14 +1822,14 @@ void DesktopLOKTest::testTileInvalidationCompression()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0"); // 0
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 1"); // 1: Different part
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 0, 0, -1"); // Invalid
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 200, 200, -1"); // 0: All parts
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, -1"); // Invalid
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-100, -100, 1200, 1200, -1"); // 0: All parts
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 3"); // Overlapped
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "1000, 1000, 1239, 1239, 2"); // 1: Unique region
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0, 0"_ostr); // 0
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 1, 0"_ostr); // 1: Different part
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 0, 0, -1, 0"_ostr); // Invalid
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 200, 200, -1, 0"_ostr); // 0: All parts
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, -1, 0"_ostr); // Invalid
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-100, -100, 1200, 1200, -1, 0"_ostr); // 0: All parts
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 3, 0"_ostr); // Overlapped
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "1000, 1000, 1239, 1239, 2, 0"_ostr); // 1: Unique region
Scheduler::ProcessEventsToIdle();
@@ -1704,10 +1837,10 @@ void DesktopLOKTest::testTileInvalidationCompression()
size_t i = 0;
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 1100, 1100, -1"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 1100, 1100, -1, 0"), std::get<1>(notifs[i++]));
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("1000, 1000, 1239, 1239, 2"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("1000, 1000, 1239, 1239, 2, 0"), std::get<1>(notifs[i++]));
}
// All Parts (partial)
@@ -1716,14 +1849,14 @@ void DesktopLOKTest::testTileInvalidationCompression()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 0"); // 0
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 100, 100, 1"); // 1: Different part
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 0, 0, -1"); // Invalid
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "150, 150, 50, 50, -1"); // 2: All-parts
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, -1"); // Invalid
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "150, 150, 40, 40, 3"); // Overlapped w/ 2
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 4"); // 3: Unique
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "1000, 1000, 1239, 1239, 1"); // 4: Unique
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 0, 0"_ostr); // 0
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 100, 100, 1, 0"_ostr); // 1: Different part
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 0, 0, -1, 0"_ostr); // Invalid
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "150, 150, 50, 50, -1, 0"_ostr); // 2: All-parts
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, -1, 0"_ostr); // Invalid
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "150, 150, 40, 40, 3, 0"_ostr); // Overlapped w/ 2
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 200, 200, 4, 0"_ostr); // 3: Unique
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "1000, 1000, 1239, 1239, 1, 0"_ostr); // 4: Unique
Scheduler::ProcessEventsToIdle();
@@ -1731,19 +1864,19 @@ void DesktopLOKTest::testTileInvalidationCompression()
size_t i = 0;
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 200, 200, 0"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 200, 200, 0, 0"), std::get<1>(notifs[i++]));
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 100, 100, 1"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 100, 100, 1, 0"), std::get<1>(notifs[i++]));
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("150, 150, 50, 50, -1"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("150, 150, 50, 50, -1, 0"), std::get<1>(notifs[i++]));
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 200, 200, 4"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 200, 200, 4, 0"), std::get<1>(notifs[i++]));
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("1000, 1000, 1239, 1239, 1"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("1000, 1000, 1239, 1239, 1, 0"), std::get<1>(notifs[i++]));
}
// Merge with "EMPTY"
@@ -1752,11 +1885,11 @@ void DesktopLOKTest::testTileInvalidationCompression()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "EMPTY, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 240, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 300, 300, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 0");
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "EMPTY, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 240, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 300, 300, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 0, 0"_ostr);
Scheduler::ProcessEventsToIdle();
@@ -1764,7 +1897,7 @@ void DesktopLOKTest::testTileInvalidationCompression()
size_t i = 0;
CPPUNIT_ASSERT_EQUAL(int(LOK_CALLBACK_INVALIDATE_TILES), std::get<0>(notifs[i]));
- CPPUNIT_ASSERT_EQUAL(std::string("EMPTY, 0"), std::get<1>(notifs[i++]));
+ CPPUNIT_ASSERT_EQUAL(std::string("EMPTY, 0, 0"), std::get<1>(notifs[i++]));
}
}
@@ -1777,8 +1910,8 @@ void DesktopLOKTest::testPartInInvalidation()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10");
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10"_ostr);
Scheduler::ProcessEventsToIdle();
@@ -1793,8 +1926,8 @@ void DesktopLOKTest::testPartInInvalidation()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "40, 10, 20, 10");
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "40, 10, 20, 10"_ostr);
Scheduler::ProcessEventsToIdle();
@@ -1813,8 +1946,8 @@ void DesktopLOKTest::testPartInInvalidation()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10, 0");
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10, 0, 0"_ostr);
Scheduler::ProcessEventsToIdle();
@@ -1832,8 +1965,8 @@ void DesktopLOKTest::testPartInInvalidation()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10, 0");
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10, 1");
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "10, 10, 20, 10, 0, 0"_ostr);
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "20, 10, 20, 10, 1, 0"_ostr);
Scheduler::ProcessEventsToIdle();
@@ -1854,14 +1987,14 @@ void DesktopLOKTest::testBinaryCallback()
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
const tools::Rectangle rect1(Point(10,15),Size(20,25));
- const std::string rect1String(rect1.toString().getStr());
+ const std::string rect1String(rect1.toString());
// Verify that using queue() and libreOfficeKitViewInvalidateTilesCallback() has the same result.
{
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackBinaryCallbackTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->queue(LOK_CALLBACK_INVALIDATE_TILES, rect1String.c_str());
+ handler->queue(LOK_CALLBACK_INVALIDATE_TILES, OString(rect1String));
Scheduler::ProcessEventsToIdle();
@@ -1874,7 +2007,7 @@ void DesktopLOKTest::testBinaryCallback()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackBinaryCallbackTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->libreOfficeKitViewInvalidateTilesCallback(&rect1, INT_MIN);
+ handler->libreOfficeKitViewInvalidateTilesCallback(&rect1, INT_MIN, 0);
Scheduler::ProcessEventsToIdle();
@@ -1888,7 +2021,7 @@ void DesktopLOKTest::testBinaryCallback()
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackBinaryCallbackTest, &notifs));
handler->setViewId(SfxLokHelper::getView());
- handler->libreOfficeKitViewInvalidateTilesCallback(nullptr, INT_MIN);
+ handler->libreOfficeKitViewInvalidateTilesCallback(nullptr, INT_MIN, 0);
Scheduler::ProcessEventsToIdle();
@@ -1898,40 +2031,10 @@ void DesktopLOKTest::testBinaryCallback()
}
}
-void DesktopLOKTest::testDialogInput()
-{
- comphelper::LibreOfficeKit::setActive();
- LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- pDocument->pClass->postUnoCommand(pDocument, ".uno:HyperlinkDialog", nullptr, false);
- Scheduler::ProcessEventsToIdle();
-
- SfxViewShell* pViewShell = SfxViewShell::Current();
- pViewShell->GetViewFrame()->GetBindings().Update();
-
- VclPtr<vcl::Window> pWindow(Application::GetActiveTopWindow());
- CPPUNIT_ASSERT(pWindow);
-
- Control* pCtrlFocused = GetFocusControl(pWindow.get());
- CPPUNIT_ASSERT(pCtrlFocused);
- CPPUNIT_ASSERT_EQUAL(WindowType::COMBOBOX, pCtrlFocused->GetType());
- CPPUNIT_ASSERT_EQUAL(OUString(""), pCtrlFocused->GetText());
-
- vcl::LOKWindowId nDialogId = pWindow->GetLOKWindowId();
- pDocument->pClass->postWindowExtTextInputEvent(pDocument, nDialogId, LOK_EXT_TEXTINPUT, "wiki.");
- pDocument->pClass->postWindowExtTextInputEvent(pDocument, nDialogId, LOK_EXT_TEXTINPUT_END, "wiki.");
- pDocument->pClass->removeTextContext(pDocument, nDialogId, 1, 0);
- Scheduler::ProcessEventsToIdle();
- CPPUNIT_ASSERT_EQUAL(OUString("wiki"), pCtrlFocused->GetText());
-
- static_cast<SystemWindow*>(pWindow.get())->Close();
- Scheduler::ProcessEventsToIdle();
-}
-
void DesktopLOKTest::testInput()
{
// Load a Writer document, enable change recording and press a key.
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
Scheduler::ProcessEventsToIdle(); // Get focus & other bits setup.
@@ -1959,7 +2062,7 @@ void DesktopLOKTest::testInput()
Scheduler::ProcessEventsToIdle();
char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr);
CPPUNIT_ASSERT(pText != nullptr);
- CPPUNIT_ASSERT_EQUAL(OString("far beyond lovely "), OString(pText));
+ CPPUNIT_ASSERT_EQUAL("far beyond lovely "_ostr, OString(pText));
free(pText);
}
@@ -1968,7 +2071,7 @@ void DesktopLOKTest::testRedlineWriter()
// Load a Writer document, enable change recording and press a key.
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
- xPropertySet->setPropertyValue("RecordChanges", uno::makeAny(true));
+ xPropertySet->setPropertyValue("RecordChanges", uno::Any(true));
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 't', 0);
Scheduler::ProcessEventsToIdle();
@@ -1995,7 +2098,7 @@ void DesktopLOKTest::testRedlineCalc()
// Load a Writer document, enable change recording and press a key.
LibLODocument_Impl* pDocument = loadDoc("sheets.ods");
uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
- xPropertySet->setPropertyValue("RecordChanges", uno::makeAny(true));
+ xPropertySet->setPropertyValue("RecordChanges", uno::Any(true));
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 't', 0);
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
@@ -2026,13 +2129,13 @@ class ViewCallback
public:
OString m_aCellFormula;
int m_nTableSelectionCount;
+ int m_nColorPaletteCallbackCount = 0;
bool m_bEmptyTableSelection;
bool m_bTilesInvalidated;
bool m_bZeroCursor;
tools::Rectangle m_aOwnCursor;
boost::property_tree::ptree m_aCommentCallbackResult;
- boost::property_tree::ptree m_aCallbackWindowResult;
- bool m_bWindowHidden;
+ boost::property_tree::ptree m_aColorPaletteCallbackResult;
ViewCallback(LibLODocument_Impl* pDocument)
: mpDocument(pDocument),
@@ -2089,16 +2192,6 @@ public:
m_aCommentCallbackResult = m_aCommentCallbackResult.get_child("comment");
}
break;
- case LOK_CALLBACK_WINDOW:
- {
- m_aCallbackWindowResult.clear();
- std::stringstream aStream(pPayload);
- boost::property_tree::read_json(aStream, m_aCallbackWindowResult);
-
- std::string sAction = m_aCallbackWindowResult.get<std::string>("action");
- if (sAction == "hide")
- m_bWindowHidden = true;
- }
break;
case LOK_CALLBACK_CELL_FORMULA:
{
@@ -2111,6 +2204,14 @@ public:
++m_nTableSelectionCount;
}
break;
+ case LOK_CALLBACK_COLOR_PALETTES:
+ {
+ m_aColorPaletteCallbackResult.clear();
+ std::stringstream aStream(pPayload);
+ boost::property_tree::read_json(aStream, m_aColorPaletteCallbackResult);
+ ++m_nColorPaletteCallbackCount;
+ }
+ break;
}
}
};
@@ -2145,7 +2246,7 @@ void DesktopLOKTest::testPaintPartTile()
// Call paintPartTile() to paint the second part (in whichever view it finds suitable for this).
unsigned char pPixels[256 * 256 * 4];
- pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 256, 256, 0, 0, 256, 256);
+ pDocument->m_pDocumentClass->paintPartTile(pDocument, pPixels, 1, 0, 256, 256, 0, 0, 256, 256);
// Type again.
Scheduler::ProcessEventsToIdle();
@@ -2158,7 +2259,85 @@ void DesktopLOKTest::testPaintPartTile()
//CPPUNIT_ASSERT(aView1.m_bTilesInvalidated);
}
+void DesktopLOKTest::testPaintPartTileDifferentSchemes()
+{
+ Color aDarkColor(0x1c, 0x1c, 0x1c);
+
+ // Add a minimal dark scheme
+ {
+ svtools::EditableColorConfig aColorConfig;
+ svtools::ColorConfigValue aValue;
+ aValue.bIsVisible = true;
+ aValue.nColor = aDarkColor;
+ aColorConfig.SetColorValue(svtools::DOCCOLOR, aValue);
+ aColorConfig.AddScheme(u"Dark"_ustr);
+ }
+
+ // Add a minimal light scheme
+ {
+ svtools::EditableColorConfig aColorConfig;
+ svtools::ColorConfigValue aValue;
+ aValue.bIsVisible = true;
+ aValue.nColor = COL_WHITE;
+ aColorConfig.SetColorValue(svtools::DOCCOLOR, aValue);
+ aColorConfig.AddScheme(u"Light"_ustr);
+ }
+
+ // This view will default to light scheme
+ LibLODocument_Impl* pDocument = loadDoc("2slides.odp");
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+ int nView1 = pDocument->m_pDocumentClass->getView(pDocument);
+
+ // Create a second view
+ pDocument->m_pDocumentClass->createView(pDocument);
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+
+ // Go to the second slide in the second view
+ pDocument->m_pDocumentClass->setPart(pDocument, 1);
+
+ // Set to dark scheme
+ {
+ uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence(
+ {
+ { "NewTheme", uno::Any(OUString("Dark")) },
+ }
+ );
+ dispatchCommand(mxComponent, ".uno:ChangeTheme", aPropertyValues);
+ }
+
+ constexpr int nCanvasWidth = 256;
+ constexpr int nCanvasHeight = 256;
+
+ // Just a random pixel in the middle of the canvas
+ constexpr int nPixelX = 128;
+ constexpr int nPixelY = 128 * nCanvasWidth;
+
+ std::array<sal_uInt8, nCanvasWidth * nCanvasHeight * 4> aPixels;
+
+ // Both parts should be painted with dark scheme
+ pDocument->m_pDocumentClass->paintPartTile(pDocument, aPixels.data(), 0, 0, nCanvasWidth, nCanvasHeight, 0, 0, nCanvasWidth, nCanvasHeight);
+ Color aPixel(aPixels[nPixelX + nPixelY + 0], aPixels[nPixelX + nPixelY + 1], aPixels[nPixelX + nPixelY + 2]);
+ CPPUNIT_ASSERT_EQUAL(aDarkColor, aPixel);
+
+ pDocument->m_pDocumentClass->paintPartTile(pDocument, aPixels.data(), 0, 0, nCanvasWidth, nCanvasHeight, 0, 0, nCanvasWidth, nCanvasHeight);
+ aPixel = Color(aPixels[nPixelX + nPixelY + 0], aPixels[nPixelX + nPixelY + 1], aPixels[nPixelX + nPixelY + 2]);
+ CPPUNIT_ASSERT_EQUAL(aDarkColor, aPixel);
+
+ // Switch back to first view
+ pDocument->m_pDocumentClass->setView(pDocument, nView1);
+
+ // Both parts should be painted with light scheme
+ pDocument->m_pDocumentClass->paintPartTile(pDocument, aPixels.data(), 0, 0, nCanvasWidth, nCanvasHeight, 0, 0, nCanvasWidth, nCanvasHeight);
+ aPixel = Color(aPixels[nPixelX + nPixelY + 0], aPixels[nPixelX + nPixelY + 1], aPixels[nPixelX + nPixelY + 2]);
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, aPixel);
+
+ pDocument->m_pDocumentClass->paintPartTile(pDocument, aPixels.data(), 0, 0, nCanvasWidth, nCanvasHeight, 0, 0, nCanvasWidth, nCanvasHeight);
+ aPixel = Color(aPixels[nPixelX + nPixelY + 0], aPixels[nPixelX + nPixelY + 1], aPixels[nPixelX + nPixelY + 2]);
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, aPixel);
+}
+
#if HAVE_MORE_FONTS
+#include <rtl/uri.hxx>
void DesktopLOKTest::testGetFontSubset()
{
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
@@ -2213,7 +2392,7 @@ void DesktopLOKTest::testCommentsWriter()
CPPUNIT_ASSERT(!rComment.second.get<std::string>("text").empty());
// Has a valid iso 8601 date time string
css::util::DateTime aDateTime;
- OUString aDateTimeString = OUString::createFromAscii(rComment.second.get<std::string>("dateTime").c_str());
+ OUString aDateTimeString = OUString::createFromAscii(rComment.second.get<std::string>("dateTime"));
CPPUNIT_ASSERT(utl::ISO8601parseDateTime(aDateTimeString, aDateTime));
// This comment has a marked text range
@@ -2225,7 +2404,7 @@ void DesktopLOKTest::testCommentsWriter()
// This is a reply comment
else if (rComment.second.get<std::string>("text") == "Reply to Comment 2")
{
- CPPUNIT_ASSERT_EQUAL(nComment2Id, rComment.second.get<int>("parent"));
+ CPPUNIT_ASSERT_EQUAL(nComment2Id, rComment.second.get<int>("parentId"));
}
}
@@ -2261,14 +2440,14 @@ void DesktopLOKTest::testCommentsCalc()
{
CPPUNIT_ASSERT_EQUAL(std::string("4"), rComment.second.get<std::string>("tab"));
CPPUNIT_ASSERT_EQUAL(std::string("Comment1"), rComment.second.get<std::string>("text"));
- CPPUNIT_ASSERT_EQUAL(std::string("7650, 3570, 1274, 254"), rComment.second.get<std::string>("cellPos"));
+ CPPUNIT_ASSERT_EQUAL(std::string("6 14 6 14"), rComment.second.get<std::string>("cellRange"));
}
break;
case 1:
{
CPPUNIT_ASSERT_EQUAL(std::string("4"), rComment.second.get<std::string>("tab"));
CPPUNIT_ASSERT_EQUAL(std::string("Comment2"), rComment.second.get<std::string>("text"));
- CPPUNIT_ASSERT_EQUAL(std::string("8925, 4335, 1274, 254"), rComment.second.get<std::string>("cellPos"));
+ CPPUNIT_ASSERT_EQUAL(std::string("7 17 7 17"), rComment.second.get<std::string>("cellRange"));
}
break;
}
@@ -2313,7 +2492,7 @@ void DesktopLOKTest::testCommentsImpress()
CPPUNIT_ASSERT_EQUAL(std::string("This is comment1"), rComment.second.get<std::string>("text"));
CPPUNIT_ASSERT_EQUAL(std::string("LOK User1"), rComment.second.get<std::string>("author"));
css::util::DateTime aDateTime;
- OUString aDateTimeString = OUString::createFromAscii(rComment.second.get<std::string>("dateTime").c_str());
+ OUString aDateTimeString = OUString::createFromAscii(rComment.second.get<std::string>("dateTime"));
CPPUNIT_ASSERT(utl::ISO8601parseDateTime(aDateTimeString, aDateTime));
}
break;
@@ -2323,7 +2502,7 @@ void DesktopLOKTest::testCommentsImpress()
CPPUNIT_ASSERT_EQUAL(std::string("This is comment2"), rComment.second.get<std::string>("text"));
CPPUNIT_ASSERT_EQUAL(std::string("LOK User2"), rComment.second.get<std::string>("author"));
css::util::DateTime aDateTime;
- OUString aDateTimeString = OUString::createFromAscii(rComment.second.get<std::string>("dateTime").c_str());
+ OUString aDateTimeString = OUString::createFromAscii(rComment.second.get<std::string>("dateTime"));
CPPUNIT_ASSERT(utl::ISO8601parseDateTime(aDateTimeString, aDateTime));
}
break;
@@ -2350,7 +2529,7 @@ void DesktopLOKTest::testCommentsCallbacksWriter()
ViewCallback aView2(pDocument);
// Add a new comment
- OString aCommandArgs("{ \"Text\": { \"type\": \"string\", \"value\": \"Additional comment\" }, \"Author\": { \"type\": \"string\", \"value\": \"LOK User1\" } }");
+ OString aCommandArgs("{ \"Text\": { \"type\": \"string\", \"value\": \"Additional comment\" }, \"Author\": { \"type\": \"string\", \"value\": \"LOK User1\" } }"_ostr);
pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", aCommandArgs.getStr(), false);
Scheduler::ProcessEventsToIdle();
@@ -2367,8 +2546,8 @@ void DesktopLOKTest::testCommentsCallbacksWriter()
// We received a LOK_CALLBACK_COMMENT callback with comment 'Add' action and linked to its parent comment
CPPUNIT_ASSERT_EQUAL(std::string("Add"), aView1.m_aCommentCallbackResult.get<std::string>("action"));
CPPUNIT_ASSERT_EQUAL(std::string("Add"), aView2.m_aCommentCallbackResult.get<std::string>("action"));
- CPPUNIT_ASSERT_EQUAL(nCommentId1, aView1.m_aCommentCallbackResult.get<int>("parent"));
- CPPUNIT_ASSERT_EQUAL(nCommentId1, aView2.m_aCommentCallbackResult.get<int>("parent"));
+ CPPUNIT_ASSERT_EQUAL(nCommentId1, aView1.m_aCommentCallbackResult.get<int>("parentId"));
+ CPPUNIT_ASSERT_EQUAL(nCommentId1, aView2.m_aCommentCallbackResult.get<int>("parentId"));
CPPUNIT_ASSERT_EQUAL(std::string("Reply comment"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
CPPUNIT_ASSERT_EQUAL(std::string("Reply comment"), aView2.m_aCommentCallbackResult.get<std::string>("text"));
int nCommentId2 = aView1.m_aCommentCallbackResult.get<int>("id");
@@ -2382,8 +2561,8 @@ void DesktopLOKTest::testCommentsCallbacksWriter()
CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView1.m_aCommentCallbackResult.get<std::string>("action"));
CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView2.m_aCommentCallbackResult.get<std::string>("action"));
// parent is unchanged still
- CPPUNIT_ASSERT_EQUAL(nCommentId1, aView1.m_aCommentCallbackResult.get<int>("parent"));
- CPPUNIT_ASSERT_EQUAL(nCommentId1, aView2.m_aCommentCallbackResult.get<int>("parent"));
+ CPPUNIT_ASSERT_EQUAL(nCommentId1, aView1.m_aCommentCallbackResult.get<int>("parentId"));
+ CPPUNIT_ASSERT_EQUAL(nCommentId1, aView2.m_aCommentCallbackResult.get<int>("parentId"));
CPPUNIT_ASSERT_EQUAL(std::string("Edited comment"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
CPPUNIT_ASSERT_EQUAL(std::string("Edited comment"), aView2.m_aCommentCallbackResult.get<std::string>("text"));
@@ -2406,8 +2585,8 @@ void DesktopLOKTest::testCommentsCallbacksWriter()
// We received a LOK_CALLBACK_COMMENT callback with comment 'Add' action and linked to its parent comment
CPPUNIT_ASSERT_EQUAL(std::string("Add"), aView1.m_aCommentCallbackResult.get<std::string>("action"));
CPPUNIT_ASSERT_EQUAL(std::string("Add"), aView2.m_aCommentCallbackResult.get<std::string>("action"));
- CPPUNIT_ASSERT_EQUAL(nCommentId1, aView1.m_aCommentCallbackResult.get<int>("parent"));
- CPPUNIT_ASSERT_EQUAL(nCommentId1, aView2.m_aCommentCallbackResult.get<int>("parent"));
+ CPPUNIT_ASSERT_EQUAL(nCommentId1, aView1.m_aCommentCallbackResult.get<int>("parentId"));
+ CPPUNIT_ASSERT_EQUAL(nCommentId1, aView2.m_aCommentCallbackResult.get<int>("parentId"));
CPPUNIT_ASSERT_EQUAL(std::string("Reply comment again"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
CPPUNIT_ASSERT_EQUAL(std::string("Reply comment again"), aView2.m_aCommentCallbackResult.get<std::string>("text"));
@@ -2447,7 +2626,7 @@ void DesktopLOKTest::testCommentsAddEditDeleteDraw()
tools::JsonWriter aJson;
addParameter(aJson, "Text", "string", "Comment");
addParameter(aJson, "Author", "string", "LOK User1");
- aCommandArgs = aJson.extractAsOString();
+ aCommandArgs = aJson.finishAndGetAsOString();
}
pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", aCommandArgs.getStr(), false);
@@ -2462,7 +2641,7 @@ void DesktopLOKTest::testCommentsAddEditDeleteDraw()
tools::JsonWriter aJson;
addParameter(aJson, "Id", "string", OString::number(nCommentId1));
addParameter(aJson, "Text", "string", "Edited comment");
- aCommandArgs = aJson.extractAsOString();
+ aCommandArgs = aJson.finishAndGetAsOString();
}
pDocument->pClass->postUnoCommand(pDocument, ".uno:EditAnnotation", aCommandArgs.getStr(), false);
@@ -2476,7 +2655,7 @@ void DesktopLOKTest::testCommentsAddEditDeleteDraw()
{
tools::JsonWriter aJson;
addParameter(aJson, "Id", "string", OString::number(nCommentId1));
- aCommandArgs = aJson.extractAsOString();
+ aCommandArgs = aJson.finishAndGetAsOString();
}
pDocument->pClass->postUnoCommand(pDocument, ".uno:DeleteAnnotation", aCommandArgs.getStr(), false);
Scheduler::ProcessEventsToIdle();
@@ -2492,10 +2671,10 @@ void DesktopLOKTest::testRunMacro()
bool bGoodMacro, bNonExistentMacro;
// Tools macros come pre-installed in system share/basic folder,
- bGoodMacro = aOffice.m_pOfficeClass->runMacro(&aOffice, OString("macro:///Tools.Debug.ActivateReadOnlyFlag()").getStr());
+ bGoodMacro = aOffice.m_pOfficeClass->runMacro(&aOffice, "macro:///Tools.Debug.ActivateReadOnlyFlag()");
CPPUNIT_ASSERT(bGoodMacro);
- bNonExistentMacro = aOffice.m_pOfficeClass->runMacro(&aOffice, OString("macro:///I.Am.Not(There)").getStr());
+ bNonExistentMacro = aOffice.m_pOfficeClass->runMacro(&aOffice, "macro:///I.Am.Not(There)");
CPPUNIT_ASSERT(!bNonExistentMacro);
}
@@ -2530,8 +2709,7 @@ void DesktopLOKTest::testExtractParameter()
void DesktopLOKTest::readFileIntoByteVector(std::u16string_view sFilename, std::vector<unsigned char> & rByteVector)
{
rByteVector.clear();
- OUString aURL;
- createFileURL(sFilename, aURL);
+ OUString aURL = createFileURL(sFilename);
SvFileStream aStream(aURL, StreamMode::READ);
rByteVector.resize(aStream.remainingSize());
aStream.ReadBytes(rByteVector.data(), aStream.remainingSize());
@@ -2579,16 +2757,15 @@ void DesktopLOKTest::testGetSignatureState_NonSigned()
CPPUNIT_ASSERT_EQUAL(int(0), nState);
}
+#if 0 // broken with system nss on RHEL 7
void DesktopLOKTest::testInsertCertificate_DER_ODT()
{
// Load the document, save it into a temp file and load that file again
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
- CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
closeDoc();
- pDocument = loadDocUrl(aTempFile.GetURL(), LOK_DOCTYPE_TEXT);
+ pDocument = loadDocUrl(maTempFile.GetURL(), LOK_DOCTYPE_TEXT);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(mxComponent.is());
@@ -2633,12 +2810,10 @@ void DesktopLOKTest::testInsertCertificate_PEM_ODT()
{
// Load the document, save it into a temp file and load that file again
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
- CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
closeDoc();
- pDocument = loadDocUrl(aTempFile.GetURL(), LOK_DOCTYPE_TEXT);
+ pDocument = loadDocUrl(maTempFile.GetURL(), LOK_DOCTYPE_TEXT);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(mxComponent.is());
@@ -2690,12 +2865,10 @@ void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
{
// Load the document, save it into a temp file and load that file again
LibLODocument_Impl* pDocument = loadDoc("blank_text.docx");
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
- CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "docx", nullptr));
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "docx", nullptr));
closeDoc();
- pDocument = loadDocUrl(aTempFile.GetURL(), LOK_DOCTYPE_TEXT);
+ pDocument = loadDocUrl(maTempFile.GetURL(), LOK_DOCTYPE_TEXT);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(mxComponent.is());
@@ -2742,13 +2915,12 @@ void DesktopLOKTest::testInsertCertificate_PEM_DOCX()
int nState = pDocument->m_pDocumentClass->getSignatureState(pDocument);
CPPUNIT_ASSERT_EQUAL(int(5), nState);
}
+#endif
void DesktopLOKTest::testSignDocument_PEM_PDF()
{
// Load the document, save it into a temp file and load that file again
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(mxComponent.is());
@@ -2782,7 +2954,7 @@ void DesktopLOKTest::testSignDocument_PEM_PDF()
CPPUNIT_ASSERT(bResult);
}
- CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "pdf", nullptr));
+ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "pdf", nullptr));
closeDoc();
@@ -2792,7 +2964,7 @@ void DesktopLOKTest::testSignDocument_PEM_PDF()
readFileIntoByteVector(u"test-PK-signing.pem", aPrivateKey);
LibLibreOffice_Impl aOffice;
- bool bResult = aOffice.m_pOfficeClass->signDocument(&aOffice, aTempFile.GetURL().toUtf8().getStr(),
+ bool bResult = aOffice.m_pOfficeClass->signDocument(&aOffice, maTempFile.GetURL().toUtf8().getStr(),
aCertificate.data(), int(aCertificate.size()),
aPrivateKey.data(), int(aPrivateKey.size()));
@@ -2804,7 +2976,7 @@ void DesktopLOKTest::testTextSelectionHandles()
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
- OString aText("hello");
+ OString aText("hello"_ostr);
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength()));
// select the inserted text
@@ -2813,12 +2985,12 @@ void DesktopLOKTest::testTextSelectionHandles()
char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr);
CPPUNIT_ASSERT_EQUAL(aText, OString(pText));
free(pText);
- CPPUNIT_ASSERT_EQUAL(OString("1418, 1418, 0, 275"), m_aTextSelectionStart);
- CPPUNIT_ASSERT_EQUAL(OString("1898, 1418, 0, 275"), m_aTextSelectionEnd);
+ CPPUNIT_ASSERT_EQUAL("1418, 1418, 0, 275"_ostr, m_aTextSelectionStart);
+ CPPUNIT_ASSERT_EQUAL("1898, 1418, 0, 275"_ostr, m_aTextSelectionEnd);
// deselect & check
- m_aTextSelectionStart = "";
- m_aTextSelectionEnd = "";
+ m_aTextSelectionStart = ""_ostr;
+ m_aTextSelectionEnd = ""_ostr;
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 0, com::sun::star::awt::Key::ESCAPE);
Scheduler::ProcessEventsToIdle();
pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr);
@@ -2834,8 +3006,8 @@ void DesktopLOKTest::testTextSelectionHandles()
pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr);
CPPUNIT_ASSERT_EQUAL(aText, OString(pText));
free(pText);
- CPPUNIT_ASSERT_EQUAL(OString("1418, 1418, 0, 275"), m_aTextSelectionStart);
- CPPUNIT_ASSERT_EQUAL(OString("1898, 1418, 0, 275"), m_aTextSelectionEnd);
+ CPPUNIT_ASSERT_EQUAL("1418, 1418, 0, 275"_ostr, m_aTextSelectionStart);
+ CPPUNIT_ASSERT_EQUAL("1898, 1418, 0, 275"_ostr, m_aTextSelectionEnd);
}
void DesktopLOKTest::testDialogPaste()
@@ -2845,7 +3017,7 @@ void DesktopLOKTest::testDialogPaste()
Scheduler::ProcessEventsToIdle();
SfxViewShell* pViewShell = SfxViewShell::Current();
- pViewShell->GetViewFrame()->GetBindings().Update();
+ pViewShell->GetViewFrame().GetBindings().Update();
VclPtr<vcl::Window> pWindow(Application::GetActiveTopWindow());
CPPUNIT_ASSERT(pWindow);
@@ -2863,49 +3035,27 @@ void DesktopLOKTest::testDialogPaste()
Scheduler::ProcessEventsToIdle();
}
-void DesktopLOKTest::testShowHideDialog()
-{
-
- LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
-
- pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
- ViewCallback aView(pDocument);
-
- pDocument->pClass->postUnoCommand(pDocument, ".uno:HyperlinkDialog", nullptr, false);
- Scheduler::ProcessEventsToIdle();
-
- VclPtr<vcl::Window> pWindow(Application::GetActiveTopWindow());
- CPPUNIT_ASSERT(pWindow);
-
- aView.m_bWindowHidden = false;
-
- pWindow->Hide();
- Scheduler::ProcessEventsToIdle();
-
- CPPUNIT_ASSERT_EQUAL(true, aView.m_bWindowHidden);
-
- static_cast<SystemWindow*>(pWindow.get())->Close();
- Scheduler::ProcessEventsToIdle();
-}
-
void DesktopLOKTest::testComplexSelection()
{
// Start with a blank text file and add contents.
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
- static constexpr OStringLiteral aText("hello world");
+ static constexpr OString aText("hello world"_ostr);
// Certainly not complex.
CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionType(pDocument));
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionTypeAndText(pDocument,
+ "", nullptr, nullptr));
// Paste text.
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength()));
// No selection.
CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionType(pDocument));
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_NONE), pDocument->pClass->getSelectionTypeAndText(pDocument,
+ "", nullptr, nullptr));
// Paste an image.
- OUString aFileURL;
- createFileURL(u"paste.jpg", aFileURL);
+ OUString aFileURL = createFileURL(u"paste.jpg");
std::ifstream aImageStream(aFileURL.toUtf8().copy(strlen("file://")).getStr());
std::vector<char> aImageContents((std::istreambuf_iterator<char>(aImageStream)), std::istreambuf_iterator<char>());
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "image/jpeg", aImageContents.data(), aImageContents.size()));
@@ -2917,7 +3067,7 @@ void DesktopLOKTest::testComplexSelection()
// Export as plain text, we should get only the text part "hello".
char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", nullptr);
CPPUNIT_ASSERT(pText != nullptr);
- CPPUNIT_ASSERT_EQUAL(OString(aText), OString(pText));
+ CPPUNIT_ASSERT_EQUAL(aText, OString(pText));
free(pText);
// Export as rtf, we should also get the image.
@@ -2936,12 +3086,12 @@ void DesktopLOKTest::testComplexSelection()
// We expect this to be complex.
CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionType(pDocument));
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(LOK_SELTYPE_COMPLEX), pDocument->pClass->getSelectionTypeAndText(pDocument,
+ "", nullptr, nullptr));
}
void DesktopLOKTest::testCalcSaveAs()
{
- comphelper::LibreOfficeKit::setActive();
-
LibLODocument_Impl* pDocument = loadDoc("sheets.ods");
CPPUNIT_ASSERT(pDocument);
@@ -2951,13 +3101,11 @@ void DesktopLOKTest::testCalcSaveAs()
Scheduler::ProcessEventsToIdle();
// Save as a new file.
- utl::TempFile aTempFile;
- aTempFile.EnableKillingFile();
- pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "ods", nullptr);
+ pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "ods", nullptr);
closeDoc();
// Load the new document and verify that the in-flight changes are saved.
- pDocument = loadDocUrl(aTempFile.GetURL(), LOK_DOCTYPE_SPREADSHEET);
+ pDocument = loadDocUrl(maTempFile.GetURL(), LOK_DOCTYPE_SPREADSHEET);
CPPUNIT_ASSERT(pDocument);
ViewCallback aView(pDocument);
@@ -2970,12 +3118,12 @@ void DesktopLOKTest::testCalcSaveAs()
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 0, KEY_LEFT);
Scheduler::ProcessEventsToIdle();
- CPPUNIT_ASSERT_EQUAL(OString("X"), aView.m_aCellFormula);
+ CPPUNIT_ASSERT_EQUAL("X"_ostr, aView.m_aCellFormula);
}
void DesktopLOKTest::testSpellcheckerMultiView()
{
- static constexpr OUStringLiteral aLangISO(u"en-US");
+ static constexpr OUString aLangISO(u"en-US"_ustr);
SvtSysLocaleOptions aSysLocaleOptions;
aSysLocaleOptions.SetLocaleConfigString(aLangISO);
aSysLocaleOptions.SetUILocaleConfigString(aLangISO);
@@ -3027,9 +3175,7 @@ void DesktopLOKTest::testMultiDocuments()
for (int i = 0; i < 3; i++)
{
// Load a document.
- uno::Reference<lang::XComponent> xComponent1;
- std::unique_ptr<LibLODocument_Impl> document1;
- std::tie(document1, xComponent1) = loadDocImpl("blank_text.odt");
+ std::unique_ptr<LibLODocument_Impl> document1 = loadDocImpl("blank_text.odt");
LibLODocument_Impl* pDocument1 = document1.get();
CPPUNIT_ASSERT_EQUAL(1, pDocument1->m_pDocumentClass->getViewsCount(pDocument1));
const int nDocId1 = pDocument1->mnDocumentId;
@@ -3058,9 +3204,7 @@ void DesktopLOKTest::testMultiDocuments()
CPPUNIT_ASSERT_EQUAL(2, pDocument1->m_pDocumentClass->getViewsCount(pDocument1));
// Load another document.
- uno::Reference<lang::XComponent> xComponent2;
- std::unique_ptr<LibLODocument_Impl> document2;
- std::tie(document2, xComponent2) = loadDocImpl("blank_presentation.odp");
+ std::unique_ptr<LibLODocument_Impl> document2 = loadDocImpl("blank_presentation.odp");
LibLODocument_Impl* pDocument2 = document2.get();
CPPUNIT_ASSERT_EQUAL(1, pDocument2->m_pDocumentClass->getViewsCount(pDocument2));
const int nDocId2 = pDocument2->mnDocumentId;
@@ -3112,9 +3256,9 @@ void DesktopLOKTest::testMultiDocuments()
pDocument2->m_pDocumentClass->destroyView(pDocument2, nDoc2View1);
CPPUNIT_ASSERT_EQUAL(1, pDocument2->m_pDocumentClass->getViewsCount(pDocument2));
- closeDoc(document2, xComponent2);
+ closeDoc(document2);
- closeDoc(document1, xComponent1);
+ closeDoc(document1);
}
}
@@ -3122,12 +3266,13 @@ void DesktopLOKTest::testControlState()
{
LibLODocument_Impl* pDocument = loadDoc("search.ods");
pDocument->pClass->postUnoCommand(pDocument, ".uno:StarShapes", nullptr, false);
+ TestLokCallbackWrapper::InitializeSidebar();
Scheduler::ProcessEventsToIdle();
boost::property_tree::ptree aState;
SfxViewShell* pViewShell = SfxViewShell::Current();
- pViewShell->GetViewFrame()->GetBindings().Update();
- pViewShell->GetViewFrame()->GetBindings().QueryControlState(SID_ATTR_TRANSFORM_WIDTH, aState);
+ pViewShell->GetViewFrame().GetBindings().Update();
+ pViewShell->GetViewFrame().GetBindings().QueryControlState(SID_ATTR_TRANSFORM_WIDTH, aState);
CPPUNIT_ASSERT(!aState.empty());
}
@@ -3135,17 +3280,9 @@ void DesktopLOKTest::testMetricField()
{
LibLODocument_Impl* pDocument = loadDoc("search.ods");
pDocument->pClass->postUnoCommand(pDocument, ".uno:StarShapes", nullptr, false);
+ SfxChildWindow* pSideBar = TestLokCallbackWrapper::InitializeSidebar();
Scheduler::ProcessEventsToIdle();
- SfxViewShell* pViewShell = SfxViewShell::Current();
- CPPUNIT_ASSERT(pViewShell);
-
- SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
- CPPUNIT_ASSERT(pViewFrame);
-
- SfxChildWindow* pSideBar = pViewFrame->GetChildWindow(SID_SIDEBAR);
- CPPUNIT_ASSERT(pSideBar);
-
vcl::Window* pWin = pSideBar->GetWindow();
CPPUNIT_ASSERT(pWin);
@@ -3204,7 +3341,7 @@ void DesktopLOKTest::testRenderSearchResult_WriterNode()
OString aPayload =
"<indexing>"
"<paragraph node_type=\"writer\" index=\"19\">ABC</paragraph>"
- "</indexing>";
+ "</indexing>"_ostr;
int nWidth = 0;
int nHeight = 0;
@@ -3222,13 +3359,13 @@ void DesktopLOKTest::testRenderSearchResult_WriterNode()
CPPUNIT_ASSERT_EQUAL(size_t(1440648), nByteSize);
const sal_uInt8* pD = reinterpret_cast<const sal_uInt8*>(pBuffer);
- BitmapEx aBitmap = vcl::bitmap::CreateFromData(pD, nWidth, nHeight, nWidth * 4, vcl::PixelFormat::N32_BPP, true, true);
+ BitmapEx aBitmap = vcl::bitmap::CreateFromData(pD, nWidth, nHeight, nWidth * 4, /*nBitsPerPixel*/32, true, true);
if (bDumpBitmap)
{
SvFileStream aStream("~/SearchResultBitmap.png", StreamMode::WRITE | StreamMode::TRUNC);
- vcl::PNGWriter aPNGWriter(aBitmap);
- aPNGWriter.Write(aStream);
+ vcl::PngImageWriter aPNGWriter(aStream);
+ aPNGWriter.write(aBitmap);
}
CPPUNIT_ASSERT_EQUAL(tools::Long(642), aBitmap.GetSizePixel().Width());
CPPUNIT_ASSERT_EQUAL(tools::Long(561), aBitmap.GetSizePixel().Height());
@@ -3249,7 +3386,7 @@ void DesktopLOKTest::testRenderSearchResult_CommonNode()
OString aPayload =
"<indexing>"
"<paragraph node_type=\"common\" index=\"0\" object_name=\"Shape 1\" />"
- "</indexing>";
+ "</indexing>"_ostr;
int nWidth = 0;
int nHeight = 0;
@@ -3267,13 +3404,13 @@ void DesktopLOKTest::testRenderSearchResult_CommonNode()
CPPUNIT_ASSERT_EQUAL(size_t(73728), nByteSize);
const sal_uInt8* pD = reinterpret_cast<const sal_uInt8*>(pBuffer);
- BitmapEx aBitmap = vcl::bitmap::CreateFromData(pD, nWidth, nHeight, nWidth * 4, vcl::PixelFormat::N32_BPP, true, true);
+ BitmapEx aBitmap = vcl::bitmap::CreateFromData(pD, nWidth, nHeight, nWidth * 4, /*nBitsPerPixel*/32, true, true);
if (bDumpBitmap)
{
SvFileStream aStream("~/SearchResultBitmap.png", StreamMode::WRITE | StreamMode::TRUNC);
- vcl::PNGWriter aPNGWriter(aBitmap);
- aPNGWriter.Write(aStream);
+ vcl::PngImageWriter aPNGWriter(aStream);
+ aPNGWriter.write(aBitmap);
}
CPPUNIT_ASSERT_EQUAL(tools::Long(192), aBitmap.GetSizePixel().Width());
CPPUNIT_ASSERT_EQUAL(tools::Long(96), aBitmap.GetSizePixel().Height());
@@ -3292,7 +3429,6 @@ static void lcl_repeatKeyStroke(LibLODocument_Impl *pDocument, int nCharCode, in
void DesktopLOKTest::testNoDuplicateTableSelection()
{
- comphelper::LibreOfficeKit::setActive();
LibLODocument_Impl* pDocument = loadDoc("table-selection.odt");
// Create view 1.
@@ -3326,7 +3462,6 @@ void DesktopLOKTest::testNoDuplicateTableSelection()
void DesktopLOKTest::testMultiViewTableSelection()
{
- comphelper::LibreOfficeKit::setActive();
LibLODocument_Impl* pDocument = loadDoc("table-selection.odt");
// Create view 1.
@@ -3388,6 +3523,34 @@ void DesktopLOKTest::testMultiViewTableSelection()
CPPUNIT_ASSERT(!aView1.m_bEmptyTableSelection);
}
+void DesktopLOKTest::testColorPaletteCallback()
+{
+ LibLODocument_Impl* pDocument = loadDoc("ThemeDocument.docx");
+
+ // Create view 1.
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+ ViewCallback aView1(pDocument);
+ Scheduler::ProcessEventsToIdle();
+ {
+ CPPUNIT_ASSERT_EQUAL(1, aView1.m_nColorPaletteCallbackCount);
+ boost::property_tree::ptree aValues = aView1.m_aColorPaletteCallbackResult.get_child("ThemeColors");
+ CPPUNIT_ASSERT(!aValues.empty());
+ CPPUNIT_ASSERT_EQUAL(size_t(6), aValues.size());
+ }
+
+ // Create view 2.
+ pDocument->m_pDocumentClass->createView(pDocument);
+ pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+ ViewCallback aView2(pDocument);
+ Scheduler::ProcessEventsToIdle();
+ {
+ CPPUNIT_ASSERT_EQUAL(1, aView2.m_nColorPaletteCallbackCount);
+ boost::property_tree::ptree aValues = aView1.m_aColorPaletteCallbackResult.get_child("ThemeColors");
+ CPPUNIT_ASSERT(!aValues.empty());
+ CPPUNIT_ASSERT_EQUAL(size_t(6), aValues.size());
+ }
+}
+
namespace {
constexpr size_t classOffset(int i)
@@ -3417,6 +3580,20 @@ void DesktopLOKTest::testABI()
CPPUNIT_ASSERT_EQUAL(classOffset(9), offsetof(struct _LibreOfficeKitClass, getVersionInfo));
CPPUNIT_ASSERT_EQUAL(classOffset(10), offsetof(struct _LibreOfficeKitClass, runMacro));
CPPUNIT_ASSERT_EQUAL(classOffset(11), offsetof(struct _LibreOfficeKitClass, signDocument));
+ CPPUNIT_ASSERT_EQUAL(classOffset(12), offsetof(struct _LibreOfficeKitClass, runLoop));
+ CPPUNIT_ASSERT_EQUAL(classOffset(13), offsetof(struct _LibreOfficeKitClass, sendDialogEvent));
+ CPPUNIT_ASSERT_EQUAL(classOffset(14), offsetof(struct _LibreOfficeKitClass, setOption));
+ CPPUNIT_ASSERT_EQUAL(classOffset(15), offsetof(struct _LibreOfficeKitClass, dumpState));
+ CPPUNIT_ASSERT_EQUAL(classOffset(16), offsetof(struct _LibreOfficeKitClass, extractRequest));
+ CPPUNIT_ASSERT_EQUAL(classOffset(17), offsetof(struct _LibreOfficeKitClass, trimMemory));
+ CPPUNIT_ASSERT_EQUAL(classOffset(18), offsetof(struct _LibreOfficeKitClass, startURP));
+ CPPUNIT_ASSERT_EQUAL(classOffset(19), offsetof(struct _LibreOfficeKitClass, stopURP));
+ CPPUNIT_ASSERT_EQUAL(classOffset(20), offsetof(struct _LibreOfficeKitClass, joinThreads));
+ CPPUNIT_ASSERT_EQUAL(classOffset(21), offsetof(struct _LibreOfficeKitClass, setForkedChild));
+
+ // When extending LibreOfficeKit with a new function pointer, add new assert for the offsetof the
+ // new function pointer and bump this assert for the size of the class.
+ CPPUNIT_ASSERT_EQUAL(classOffset(22), sizeof(struct _LibreOfficeKitClass));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(0), offsetof(struct _LibreOfficeKitDocumentClass, destroy));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(1), offsetof(struct _LibreOfficeKitDocumentClass, saveAs));
@@ -3487,10 +3664,19 @@ void DesktopLOKTest::testABI()
CPPUNIT_ASSERT_EQUAL(documentClassOffset(61), offsetof(struct _LibreOfficeKitDocumentClass, sendFormFieldEvent));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(62), offsetof(struct _LibreOfficeKitDocumentClass, setBlockedCommandList));
CPPUNIT_ASSERT_EQUAL(documentClassOffset(63), offsetof(struct _LibreOfficeKitDocumentClass, renderSearchResult));
-
- // Extending is fine, update this, and add new assert for the offsetof the
- // new method
- CPPUNIT_ASSERT_EQUAL(documentClassOffset(64), sizeof(struct _LibreOfficeKitDocumentClass));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(64), offsetof(struct _LibreOfficeKitDocumentClass, sendContentControlEvent));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(65), offsetof(struct _LibreOfficeKitDocumentClass, getSelectionTypeAndText));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(66), offsetof(struct _LibreOfficeKitDocumentClass, getDataArea));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), offsetof(struct _LibreOfficeKitDocumentClass, getEditMode));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(68), offsetof(struct _LibreOfficeKitDocumentClass, setViewTimezone));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(69), offsetof(struct _LibreOfficeKitDocumentClass, setAccessibilityState));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(70), offsetof(struct _LibreOfficeKitDocumentClass, getA11yFocusedParagraph));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(71), offsetof(struct _LibreOfficeKitDocumentClass, getA11yCaretPosition));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(72), offsetof(struct _LibreOfficeKitDocumentClass, setViewReadOnly));
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(73), offsetof(struct _LibreOfficeKitDocumentClass, setAllowChangeComments));
+
+ // As above
+ CPPUNIT_ASSERT_EQUAL(documentClassOffset(74), sizeof(struct _LibreOfficeKitDocumentClass));
}
CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
diff --git a/desktop/scripts/gdbtrace b/desktop/scripts/gdbtrace
index f5fbf6325d11..d4eae973c56a 100644
--- a/desktop/scripts/gdbtrace
+++ b/desktop/scripts/gdbtrace
@@ -3,11 +3,11 @@ echo log will be saved as gdbtrace.log, this will take some time, patience...\n
handle SIGPIPE SIGXCPU SIG33 SIG35 SIGPWR nostop noprint
set logging redirect on
set logging file gdbtrace.log
-set logging on
+set logging enabled on
set logging overwrite on
run
bt
thread apply all bt
quit
-set logging off
+set logging enabled off
echo log is saved as gdbtrace.log\n
diff --git a/desktop/scripts/soffice.sh b/desktop/scripts/soffice.sh
index 67cc0b89751f..90f5ec784027 100755
--- a/desktop/scripts/soffice.sh
+++ b/desktop/scripts/soffice.sh
@@ -77,7 +77,7 @@ test -n "$RR" && EXTRAOPT="--record"
for arg in "$@" $EXTRAOPT ; do
case "$arg" in
--record)
- if which rr >/dev/null 2>&1 ; then
+ if command -v rr >/dev/null ; then
# smoketest may already be recorded => ignore nested
RRCHECK="rr record --nested=ignore"
checks="c$checks"
@@ -87,7 +87,7 @@ for arg in "$@" $EXTRAOPT ; do
fi
;;
--backtrace)
- if which gdb >/dev/null 2>&1 ; then
+ if command -v gdb >/dev/null ; then
GDBTRACECHECK="gdb -nx --command=$sd_prog/gdbtrace --args"
checks="c$checks"
else
@@ -96,7 +96,7 @@ for arg in "$@" $EXTRAOPT ; do
fi
;;
--strace)
- if which strace >/dev/null 2>&1 ; then
+ if command -v strace >/dev/null ; then
STRACECHECK="strace -o strace.log -f -tt -s 256"
checks="c$checks"
else
@@ -106,7 +106,7 @@ for arg in "$@" $EXTRAOPT ; do
;;
--valgrind)
test -n "$VALGRINDCHECK" && continue;
- if which valgrind >/dev/null 2>&1 ; then
+ if command -v valgrind >/dev/null ; then
# another valgrind tool might be forced via the environment variable
test -z "$VALGRIND" && VALGRIND="memcheck"
# --trace-children-skip is pretty useful but supported only with valgrind >= 3.6.0
@@ -163,10 +163,6 @@ NetBSD|DragonFly)
LD_LIBRARY_PATH="$sd_prog${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH
;;
-AIX)
- LIBPATH="$sd_prog${LIBPATH:+:$LIBPATH}"
- export LIBPATH
- ;;
esac
# restore locale setting, avoiding to export empty LC_ALL, s. tdf#130080
diff --git a/desktop/scripts/unopkg.sh b/desktop/scripts/unopkg.sh
index 3adf69c2e56e..de3823857fd2 100755
--- a/desktop/scripts/unopkg.sh
+++ b/desktop/scripts/unopkg.sh
@@ -49,10 +49,6 @@ NetBSD|FreeBSD|DragonFly)
LD_LIBRARY_PATH="$sd_prog${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
export LD_LIBRARY_PATH
;;
-AIX)
- LIBPATH="$sd_prog${LIBPATH:+:${LIBPATH}}"
- export LIBPATH
- ;;
esac
for arg in "$@"
@@ -72,17 +68,8 @@ if [ -x "${sd_prog}/javaldx" ] ; then
my_path=$("${sd_prog}/javaldx" "$BOOTSTRAPVARS" \
"-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc")
if [ -n "$my_path" ] ; then
- sd_platform=$(uname -s)
- case "$sd_platform" in
- AIX)
- LIBPATH="$my_path${LIBPATH:+:$LIBPATH}"
- export LIBPATH
- ;;
- *)
- LD_LIBRARY_PATH="$my_path${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
- export LD_LIBRARY_PATH
- ;;
- esac
+ LD_LIBRARY_PATH="$my_path${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
+ export LD_LIBRARY_PATH
fi
fi
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index ada608229f8b..0e529e071427 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -28,6 +28,7 @@
#include <sal/config.h>
+#include <cstdlib>
#include <iostream>
#include <string_view>
@@ -59,7 +60,6 @@
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/StartModule.hpp>
-#include <com/sun/star/view/XPrintable.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/util/URLTransformer.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
@@ -81,6 +81,7 @@
#include <desktop/exithelper.h>
#include <sal/log.hxx>
#include <toolkit/helper/vclunohelper.hxx>
+#include <comphelper/lok.hxx>
#include <comphelper/configuration.hxx>
#include <comphelper/fileurl.hxx>
#include <comphelper/threadpool.hxx>
@@ -105,7 +106,6 @@
#endif
#include <rtl/bootstrap.hxx>
#include <vcl/test/GraphicsRenderTests.hxx>
-#include <vcl/glxtestprocess.hxx>
#include <vcl/help.hxx>
#include <vcl/weld.hxx>
#include <vcl/settings.hxx>
@@ -118,7 +118,7 @@
#include <basic/sbstar.hxx>
#include <desktop/crashreport.hxx>
#include <tools/urlobj.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <svtools/fontsubstconfig.hxx>
#include <svtools/accessibilityoptions.hxx>
#include <svtools/apearcfg.hxx>
@@ -127,6 +127,10 @@
#include "langselect.hxx"
#include <salhelper/thread.hxx>
+#if HAVE_FEATURE_UPDATE_MAR
+#include <tools/time.hxx>
+#endif
+
#if defined MACOSX
#include <errno.h>
#include <sys/wait.h>
@@ -155,7 +159,6 @@ using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::document;
-using namespace ::com::sun::star::view;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::system;
using namespace ::com::sun::star::ui;
@@ -286,12 +289,11 @@ bool shouldLaunchQuickstart()
bool bQuickstart = Desktop::GetCommandLineArgs().IsQuickstart();
if (!bQuickstart)
{
- const SfxPoolItem* pItem=nullptr;
SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aQLSet(SfxGetpApp()->GetPool());
- SfxGetpApp()->GetOptions(aQLSet);
- SfxItemState eState = aQLSet.GetItemState(SID_ATTR_QUICKLAUNCHER, false, &pItem);
- if (SfxItemState::SET == eState)
- bQuickstart = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ SfxApplication::GetOptions(aQLSet);
+ const SfxBoolItem* pLauncherItem = aQLSet.GetItemIfSet(SID_ATTR_QUICKLAUNCHER, false);
+ if (pLauncherItem)
+ bQuickstart = pLauncherItem->GetValue();
}
return bQuickstart;
}
@@ -340,10 +342,13 @@ void RemoveIconCacheDirectory()
namespace {
+#if !defined(EMSCRIPTEN)
void runGraphicsRenderTests()
{
+ if (comphelper::LibreOfficeKit::isActive())
+ return;
#if !ENABLE_WASM_STRIP_PINGUSER
- if (!utl::isProductVersionUpgraded(false))
+ if (!utl::isProductVersionUpgraded())
{
return;
}
@@ -351,6 +356,7 @@ void runGraphicsRenderTests()
GraphicsRenderTests TestObject;
TestObject.run();
}
+#endif
OUString MakeStartupErrorMessage(std::u16string_view aErrorMessage)
@@ -457,7 +463,8 @@ void Desktop::Init()
}
catch (css::uno::Exception & e)
{
- SetBootstrapError( BE_UNO_SERVICEMANAGER, e.Message );
+ HandleBootstrapErrors( BE_UNO_SERVICEMANAGER, e.Message );
+ std::abort();
}
// Check whether safe mode is enabled
@@ -474,30 +481,34 @@ void Desktop::Init()
// the UserConfiguration directory
comphelper::BackupFileHelper::reactOnSafeMode(Application::IsSafeModeEnabled());
- if ( m_aBootstrapError == BE_OK )
+ // tdf117100: do not try to re-install extensions after the requested restart
+ if (officecfg::Setup::Office::OfficeRestartInProgress::get())
{
- try
- {
- if (!langselect::prepareLocale())
- {
- SetBootstrapError( BE_LANGUAGE_MISSING, OUString() );
- }
- }
- catch (css::uno::Exception & e)
+ if (!officecfg::Office::Common::Misc::FirstRun::get())
+ GetCommandLineArgs().RemoveFilesFromOpenListEndingWith(".oxt");
+ }
+
+ try
+ {
+ if (!langselect::prepareLocale())
{
- SetBootstrapError( BE_OFFICECONFIG_BROKEN, e.Message );
+ SetBootstrapError( BE_LANGUAGE_MISSING, OUString() );
}
+ }
+ catch (css::uno::Exception & e)
+ {
+ SetBootstrapError( BE_OFFICECONFIG_BROKEN, e.Message );
+ }
- // test code for ProfileSafeMode to allow testing the fail
- // of loading the office configuration initially. To use,
- // either set to true and compile, or set a breakpoint
- // in debugger and change the local bool
- static bool bTryHardOfficeconfigBroken(false); // loplugin:constvars:ignore
+ // test code for ProfileSafeMode to allow testing the fail
+ // of loading the office configuration initially. To use,
+ // either set to true and compile, or set a breakpoint
+ // in debugger and change the local bool
+ static bool bTryHardOfficeconfigBroken(false); // loplugin:constvars:ignore
- if (bTryHardOfficeconfigBroken)
- {
- SetBootstrapError(BE_OFFICECONFIG_BROKEN, OUString());
- }
+ if (bTryHardOfficeconfigBroken)
+ {
+ SetBootstrapError(BE_OFFICECONFIG_BROKEN, OUString());
}
// start ipc thread only for non-remote offices
@@ -523,6 +534,10 @@ void Desktop::Init()
else if ( aStatus == RequestHandler::IPC_STATUS_2ND_OFFICE )
{
// 2nd office startup should terminate after sending cmdlineargs through pipe
+ if (rCmdLineArgs.IsTextCat() || rCmdLineArgs.IsScriptCat())
+ {
+ HandleBootstrapErrors( BE_2NDOFFICE_WITHCAT, OUString() );
+ }
SetBootstrapStatus(BS_TERMINATE);
}
else if ( !rCmdLineArgs.GetUnknown().isEmpty()
@@ -577,7 +592,7 @@ bool Desktop::QueryExit()
{
}
- static constexpr OUStringLiteral SUSPEND_QUICKSTARTVETO = u"SuspendQuickstartVeto";
+ static constexpr OUString SUSPEND_QUICKSTARTVETO = u"SuspendQuickstartVeto"_ustr;
Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
Reference< XPropertySet > xPropertySet(xDesktop, UNO_QUERY_THROW);
@@ -589,7 +604,7 @@ bool Desktop::QueryExit()
{
xPropertySet->setPropertyValue( SUSPEND_QUICKSTARTVETO, Any(false) );
}
- else if (!Application::IsEventTestingModeEnabled())
+ else
{
FlushConfiguration();
try
@@ -880,6 +895,11 @@ void Desktop::HandleBootstrapErrors(
FatalError(MakeStartupErrorMessage(aDiagnosticMessage));
}
+ else if ( aBootstrapError == BE_2NDOFFICE_WITHCAT )
+ {
+ OUString aDiagnosticMessage = DpResId(STR_BOOTSTRAP_ERR_2NDOFFICE_WITHCAT);
+ FatalError(MakeStartupErrorMessage(aDiagnosticMessage));
+ }
}
@@ -1111,7 +1131,7 @@ bool isTimeForUpdateCheck()
sal_uInt64 nLastUpdate = officecfg::Office::Update::Update::LastUpdateTime::get();
sal_uInt64 nNow = tools::Time::GetSystemTicks();
- sal_uInt64 n7DayInMS = 1000 * 60 * 60 * 12 * 1; // 12 hours in ms
+ sal_uInt64 n7DayInMS = 1000 * 60 * 60 * 24 * 7; // 7 days in ms
if (nNow - n7DayInMS >= nLastUpdate)
return true;
@@ -1227,14 +1247,12 @@ struct ExecuteGlobals
{
Reference < css::document::XDocumentEventListener > xGlobalBroadcaster;
bool bRestartRequested;
- bool bUseSystemFileDialog;
std::unique_ptr<SvtCTLOptions> pCTLLanguageOptions;
std::unique_ptr<SvtPathOptions> pPathOptions;
rtl::Reference< JVMloadThread > xJVMloadThread;
ExecuteGlobals()
: bRestartRequested( false )
- , bUseSystemFileDialog( true )
{}
};
@@ -1306,7 +1324,7 @@ int Desktop::Main()
Reference< XDesktop2 > xDesktop;
- RegisterServices(xContext);
+ RegisterServices();
SetSplashScreenProgress(25);
@@ -1343,6 +1361,22 @@ int Desktop::Main()
if ( !InitializeConfiguration() )
return EXIT_FAILURE;
+ SetSplashScreenProgress(30);
+
+ // create title string
+ OUString aTitle(ReplaceStringHookProc(RID_APPTITLE));
+#ifdef DBG_UTIL
+ //include buildid in non product builds
+ aTitle += " [" + utl::Bootstrap::getBuildIdData("development") + "]";
+#endif
+
+ SetDisplayName( aTitle );
+ SetSplashScreenProgress(35);
+ pExecGlobals->pPathOptions.reset( new SvtPathOptions);
+ SetSplashScreenProgress(40);
+
+ xDesktop = css::frame::Desktop::create( xContext );
+
#if HAVE_FEATURE_UPDATE_MAR
const char* pUpdaterTestEnable = std::getenv("LIBO_UPDATER_TEST_ENABLE");
if (pUpdaterTestEnable || officecfg::Office::Update::Update::Enabled::get())
@@ -1406,7 +1440,10 @@ int Desktop::Main()
CloseSplashScreen();
bool bSuccess = update();
if (bSuccess)
+ {
+ xDesktop->terminate();
return EXIT_SUCCESS;
+ }
}
else if (isTimeForUpdateCheck() || pForcedUpdateCheck)
{
@@ -1421,22 +1458,6 @@ int Desktop::Main()
}
#endif
- SetSplashScreenProgress(30);
-
- // create title string
- OUString aTitle(ReplaceStringHookProc(RID_APPTITLE));
-#ifdef DBG_UTIL
- //include buildid in non product builds
- aTitle += " [" + utl::Bootstrap::getBuildIdData("development") + "]";
-#endif
-
- SetDisplayName( aTitle );
- SetSplashScreenProgress(35);
- pExecGlobals->pPathOptions.reset( new SvtPathOptions);
- SetSplashScreenProgress(40);
-
- xDesktop = css::frame::Desktop::create( xContext );
-
// create service for loading SFX (still needed in startup)
pExecGlobals->xGlobalBroadcaster = Reference < css::document::XDocumentEventListener >
( css::frame::theGlobalEventBroadcaster::get(xContext), UNO_SET_THROW );
@@ -1511,18 +1532,6 @@ int Desktop::Main()
}
}
- if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
- {
- // Ensure that we use not the system file dialogs as
- // headless mode relies on Application::EnableHeadlessMode()
- // which does only work for VCL dialogs!!
- pExecGlobals->bUseSystemFileDialog = officecfg::Office::Common::Misc::UseSystemFileDialog::get();
- std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
- comphelper::ConfigurationChanges::create());
- officecfg::Office::Common::Misc::UseSystemFileDialog::set( false, xChanges );
- xChanges->commit();
- }
-
pExecGlobals->bRestartRequested = xRestartManager->isRestartRequested(true);
if ( !pExecGlobals->bRestartRequested )
{
@@ -1540,11 +1549,9 @@ int Desktop::Main()
svtools::ApplyFontSubstitutionsToVcl();
- SvtTabAppearanceCfg aAppearanceCfg;
SvtTabAppearanceCfg::SetInitialized();
- aAppearanceCfg.SetApplicationDefaults( this );
- SvtAccessibilityOptions aOptions;
- aOptions.SetVCLSettings();
+ SvtTabAppearanceCfg::SetApplicationDefaults( this );
+ SvtAccessibilityOptions::SetVCLSettings();
SetSplashScreenProgress(60);
if ( !pExecGlobals->bRestartRequested )
@@ -1572,11 +1579,14 @@ int Desktop::Main()
CheckOpenCLCompute(xDesktop);
#endif
+#if !defined(EMSCRIPTEN)
//Running the VCL graphics rendering tests
- runGraphicsRenderTests();
-
- // Reap the process started by fire_glxtest_process().
- reap_glxtest_process();
+ const char * pDisplay = std::getenv("DISPLAY");
+ if (!pDisplay || pDisplay[0] == ':')
+ {
+ runGraphicsRenderTests();
+ }
+#endif
// Post user event to startup first application component window
// We have to send this OpenClients message short before execute() to
@@ -1635,16 +1645,7 @@ int Desktop::doShutdown()
if ( pExecGlobals->bRestartRequested )
SetRestartState();
- // Restore old value
const CommandLineArgs& rCmdLineArgs = GetCommandLineArgs();
- if ( rCmdLineArgs.IsHeadless() || rCmdLineArgs.IsEventTesting() )
- {
- std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
- comphelper::ConfigurationChanges::create());
- officecfg::Office::Common::Misc::UseSystemFileDialog::set( pExecGlobals->bUseSystemFileDialog, xChanges );
- xChanges->commit();
- }
-
OUString pidfileName = rCmdLineArgs.GetPidfileName();
if ( !pidfileName.isEmpty() )
{
@@ -1849,23 +1850,23 @@ void Desktop::OverrideSystemSettings( AllSettings& rSettings )
DragFullOptions nDragFullOptions = hStyleSettings.GetDragFullOptions();
- SvtTabAppearanceCfg aAppearanceCfg;
- DragMode nDragMode = aAppearanceCfg.GetDragMode();
+ sal_uInt16 nDragMode = officecfg::Office::Common::View::Window::Drag::get();
switch ( nDragMode )
{
- case DragMode::FullWindow:
+ case 0: //FullWindow:
nDragFullOptions |= DragFullOptions::All;
break;
- case DragMode::Frame:
+ case 1: // Frame:
nDragFullOptions &= ~DragFullOptions::All;
break;
- case DragMode::SystemDep:
+ case 2: // SystemDep
default:
break;
}
MouseFollowFlags nFollow = hMouseSettings.GetFollow();
- hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
+ bool bMenuFollowMouse = officecfg::Office::Common::View::Menu::FollowMouse::get();
+ hMouseSettings.SetFollow( bMenuFollowMouse ? (nFollow|MouseFollowFlags::Menu) : (nFollow&~MouseFollowFlags::Menu));
rSettings.SetMouseSettings(hMouseSettings);
bool bMenuIcons = officecfg::Office::Common::View::Menu::ShowIconsInMenues::get();
diff --git a/desktop/source/app/appinit.cxx b/desktop/source/app/appinit.cxx
index 98a1fa61ca2f..887b717d43ad 100644
--- a/desktop/source/app/appinit.cxx
+++ b/desktop/source/app/appinit.cxx
@@ -24,7 +24,6 @@
#include <dp_shared.hxx>
#include "cmdlineargs.hxx"
#include <strings.hrc>
-#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/Exception.hpp>
@@ -34,20 +33,23 @@
#include <osl/file.hxx>
#include <rtl/bootstrap.hxx>
#include <sal/log.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/ucbhelper.hxx>
#include <unotools/tempfile.hxx>
#include <vcl/svapp.hxx>
#include <unotools/pathoptions.hxx>
+
+#include <iostream>
#include <map>
-using namespace desktop;
+#if defined EMSCRIPTEN
+#include <bindings_uno.hxx>
+#endif
+
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::beans;
-using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::ucb;
namespace desktop
@@ -82,9 +84,12 @@ void Desktop::InitApplicationServiceManager()
UNO_QUERY_THROW);
#endif
comphelper::setProcessServiceFactory(sm);
+#if defined EMSCRIPTEN
+ init_unoembind_uno();
+#endif
}
-void Desktop::RegisterServices(Reference< XComponentContext > const & context)
+void Desktop::RegisterServices()
{
if( m_bServicesRegistered )
return;
@@ -93,14 +98,12 @@ void Desktop::RegisterServices(Reference< XComponentContext > const & context)
CommandLineArgs& rCmdLine = GetCommandLineArgs();
// Headless mode for FAT Office, auto cancels any dialogs that popup
- if (rCmdLine.IsEventTesting())
- Application::EnableEventTestingMode();
- else if (rCmdLine.IsHeadless())
+ if (rCmdLine.IsHeadless())
Application::EnableHeadlessMode(false);
// read accept string from configuration
OUString conDcpCfg(
- officecfg::Setup::Office::ooSetupConnectionURL::get(context));
+ officecfg::Setup::Office::ooSetupConnectionURL::get());
if (!conDcpCfg.isEmpty()) {
createAcceptor(conDcpCfg);
}
@@ -141,7 +144,11 @@ void Desktop::createAcceptor(const OUString& aAcceptString)
AcceptorMap &rMap = acceptorMap();
AcceptorMap::const_iterator pIter = rMap.find(aAcceptString);
if (pIter != rMap.end() )
+ {
+ // there is already an acceptor with this description
+ SAL_WARN( "desktop.app", "Acceptor already exists.");
return;
+ }
Sequence< Any > aSeq{ Any(aAcceptString), Any(bAccept) };
Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
@@ -164,8 +171,7 @@ void Desktop::createAcceptor(const OUString& aAcceptString)
}
else
{
- // there is already an acceptor with this description
- SAL_WARN( "desktop.app", "Acceptor already exists.");
+ ::std::cerr << "UNO Remote Protocol acceptor could not be created, presumably because it has been disabled in configuration." << ::std::endl;
}
}
@@ -245,11 +251,11 @@ void Desktop::CreateTemporaryDirectory()
}
// create new current temporary directory
- OUString aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempBaseURL );
+ OUString aTempPath = ::utl::SetTempNameBaseDirectory( aTempBaseURL );
if ( aTempPath.isEmpty()
&& ::osl::File::getTempDirURL( aTempBaseURL ) == osl::FileBase::E_None )
{
- aTempPath = ::utl::TempFile::SetTempNameBaseDirectory( aTempBaseURL );
+ aTempPath = ::utl::SetTempNameBaseDirectory( aTempBaseURL );
}
// set new current temporary directory
diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx
index a5978696f6e5..7f76d155c31e 100644
--- a/desktop/source/app/check_ext_deps.cxx
+++ b/desktop/source/app/check_ext_deps.cxx
@@ -25,7 +25,7 @@
#include <sal/log.hxx>
#include <cppuhelper/implbase.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <comphelper/lok.hxx>
@@ -51,6 +51,7 @@
#include <com/sun/star/util/XChangesBatch.hpp>
#include <app.hxx>
+#include <utility>
#include <dp_misc.h>
@@ -75,7 +76,7 @@ class SilentCommandEnv
public:
SilentCommandEnv(
- uno::Reference<uno::XComponentContext> const & xContext,
+ uno::Reference<uno::XComponentContext> xContext,
Desktop* pDesktop );
virtual ~SilentCommandEnv() override;
@@ -97,9 +98,9 @@ public:
SilentCommandEnv::SilentCommandEnv(
- uno::Reference<uno::XComponentContext> const & xContext,
+ uno::Reference<uno::XComponentContext> xContext,
Desktop* pDesktop ):
- mxContext( xContext ),
+ mxContext(std::move( xContext )),
mpDesktop( pDesktop ),
mnLevel( 0 ),
mnProgress( 25 )
@@ -207,7 +208,7 @@ void SilentCommandEnv::pop()
} // end namespace
-constexpr OUStringLiteral aAccessSrvc = u"com.sun.star.configuration.ConfigurationUpdateAccess";
+constexpr OUString aAccessSrvc = u"com.sun.star.configuration.ConfigurationUpdateAccess"_ustr;
static sal_Int16 impl_showExtensionDialog( uno::Reference< uno::XComponentContext > const &xContext )
{
@@ -254,13 +255,13 @@ static bool impl_checkDependencies( const uno::Reference< uno::XComponentContext
e.Context, anyEx );
}
-#ifdef DEBUG
+#if OSL_DEBUG_LEVEL >= 2
sal_Int32 const nMax = 3;
#else
sal_Int32 const nMax = 2;
#endif
- for ( uno::Sequence< uno::Reference< deployment::XPackage > > const & xPackageList : std::as_const(xAllPackages) )
+ for (uno::Sequence<uno::Reference<deployment::XPackage>> const& xPackageList : xAllPackages)
{
for ( sal_Int32 j = 0; (j<nMax) && (j < xPackageList.getLength()); ++j )
{
@@ -316,12 +317,12 @@ static void impl_setNeedsCompatCheck()
comphelper::getProcessComponentContext() ) );
beans::NamedValue v( "nodepath",
- makeAny( OUString("org.openoffice.Setup/Office") ) );
+ Any( OUString("org.openoffice.Setup/Office") ) );
Sequence< Any > theArgs{ Any(v) };
Reference< beans::XPropertySet > pset(
theConfigProvider->createInstanceWithArguments( aAccessSrvc, theArgs ), UNO_QUERY_THROW );
- Any value = makeAny( OUString("never") );
+ Any value( OUString("never") );
pset->setPropertyValue("LastCompatibilityCheckID", value );
Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
@@ -346,7 +347,7 @@ static bool impl_needsCompatCheck()
comphelper::getProcessComponentContext() ) );
beans::NamedValue v( "nodepath",
- makeAny( OUString("org.openoffice.Setup/Office") ) );
+ Any( OUString("org.openoffice.Setup/Office") ) );
Sequence< Any > theArgs{ Any(v) };
Reference< beans::XPropertySet > pset(
theConfigProvider->createInstanceWithArguments( aAccessSrvc, theArgs ), UNO_QUERY_THROW );
@@ -361,7 +362,7 @@ static bool impl_needsCompatCheck()
pset->setPropertyValue("LastCompatibilityCheckID", result );
Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
}
-#ifdef DEBUG
+#if OSL_DEBUG_LEVEL >= 2
bNeedsCheck = true;
#endif
}
diff --git a/desktop/source/app/cmdlineargs.cxx b/desktop/source/app/cmdlineargs.cxx
index 4d5a3bb78396..f96814e8e7ff 100644
--- a/desktop/source/app/cmdlineargs.cxx
+++ b/desktop/source/app/cmdlineargs.cxx
@@ -28,6 +28,7 @@
#include "cmdlineargs.hxx"
#include <osl/thread.hxx>
#include <tools/stream.hxx>
+#include <tools/urlobj.hxx>
#include <rtl/ustring.hxx>
#include <rtl/process.h>
#include <comphelper/lok.hxx>
@@ -39,9 +40,7 @@
#include <osl/file.hxx>
#include <sal/log.hxx>
-using namespace com::sun::star::lang;
-using namespace com::sun::star::uri;
-using namespace com::sun::star::uno;
+#include <mutex>
namespace desktop
{
@@ -166,7 +165,14 @@ CommandLineEvent CheckOfficeURI(/* in,out */ OUString& arg, CommandLineEvent cur
}
if (nURIlen < 0)
nURIlen = rest2.getLength();
- arg = rest2.copy(0, nURIlen);
+ auto const uri = rest2.subView(0, nURIlen);
+ if (INetURLObject(uri).GetProtocol() == INetProtocol::Macro) {
+ // Let the "Open" machinery process the full command URI (leading to failure, by intention,
+ // as the "Open" machinery does not know about those command URI schemes):
+ curEvt = CommandLineEvent::Open;
+ } else {
+ arg = uri;
+ }
return curEvt;
}
@@ -190,8 +196,8 @@ CommandLineEvent CheckWebQuery(/* in,out */ OUString& arg, CommandLineEvent curE
if (!arg.endsWithIgnoreAsciiCase(".iqy"))
return curEvt;
- static osl::Mutex aMutex;
- osl::MutexGuard aGuard(aMutex);
+ static std::mutex aMutex;
+ std::lock_guard aGuard(aMutex);
try
{
@@ -219,7 +225,7 @@ CommandLineEvent CheckWebQuery(/* in,out */ OUString& arg, CommandLineEvent curE
if (!SkipNewline(pPos))
return curEvt;
- OStringBuffer aResult(static_cast<unsigned int>(nRead));
+ OStringBuffer aResult(nRead);
do
{
const char* pPos1 = pPos;
@@ -234,7 +240,7 @@ CommandLineEvent CheckWebQuery(/* in,out */ OUString& arg, CommandLineEvent curE
stream.Close();
- arg = OStringToOUString(aResult.makeStringAndClear(), osl_getThreadTextEncoding());
+ arg = OStringToOUString(aResult, osl_getThreadTextEncoding());
return CommandLineEvent::ForceNew;
}
catch (...)
@@ -251,8 +257,6 @@ CommandLineArgs::Supplier::Exception::Exception() {}
CommandLineArgs::Supplier::Exception::Exception(Exception const &) {}
-CommandLineArgs::Supplier::Exception::~Exception() {}
-
CommandLineArgs::Supplier::Exception &
CommandLineArgs::Supplier::Exception::operator =(Exception const &)
{ return *this; }
@@ -318,10 +322,6 @@ void CommandLineArgs::ParseCommandLine_Impl( Supplier& supplier )
{
setHeadless();
}
- else if ( oArg == "eventtesting" )
- {
- m_eventtesting = true;
- }
else if ( oArg == "safe-mode" )
{
m_safemode = true;
@@ -699,7 +699,6 @@ void CommandLineArgs::InitParamValues()
m_invisible = true;
m_headless = true;
#endif
- m_eventtesting = false;
m_quickstart = false;
m_noquickstart = false;
m_terminateafterinit = false;
@@ -737,6 +736,11 @@ bool CommandLineArgs::HasModuleParam() const
|| m_web || m_base;
}
+void CommandLineArgs::RemoveFilesFromOpenListEndingWith(const OUString& rExt)
+{
+ std::erase_if(m_openlist, [rExt](OUString url) { return url.endsWithIgnoreAsciiCase(rExt); });
+}
+
std::vector< OUString > CommandLineArgs::GetOpenList() const
{
return translateExternalUris(m_openlist);
diff --git a/desktop/source/app/cmdlineargs.hxx b/desktop/source/app/cmdlineargs.hxx
index fd9aa8f11380..a9eca1d980f1 100644
--- a/desktop/source/app/cmdlineargs.hxx
+++ b/desktop/source/app/cmdlineargs.hxx
@@ -40,7 +40,6 @@ class CommandLineArgs
public:
Exception();
Exception(Exception const &);
- ~Exception();
Exception & operator =(Exception const &);
};
@@ -61,12 +60,11 @@ class CommandLineArgs
bool IsMinimized() const { return m_minimized;}
bool IsInvisible() const
{
- return m_invisible || (m_headless && !m_eventtesting);
+ return m_invisible || m_headless;
}
bool IsNoRestore() const { return m_norestore;}
bool IsNoDefault() const { return m_nodefault;}
bool IsHeadless() const { return m_headless;}
- bool IsEventTesting() const { return m_eventtesting;}
bool IsQuickstart() const { return m_quickstart;}
bool IsNoQuickstart() const { return m_noquickstart;}
bool IsTerminateAfterInit() const { return m_terminateafterinit;}
@@ -101,6 +99,7 @@ class CommandLineArgs
bool HasSplashPipe() const { return m_splashpipe;}
std::vector< OUString > const & GetAccept() const { return m_accept;}
std::vector< OUString > const & GetUnaccept() const { return m_unaccept;}
+ void RemoveFilesFromOpenListEndingWith(const OUString& rExt);
std::vector< OUString > GetOpenList() const;
std::vector< OUString > GetViewList() const;
std::vector< OUString > GetStartList() const;
@@ -132,7 +131,6 @@ class CommandLineArgs
bool m_invisible;
bool m_norestore;
bool m_headless;
- bool m_eventtesting;
bool m_quickstart;
bool m_noquickstart;
bool m_terminateafterinit;
diff --git a/desktop/source/app/cmdlinehelp.cxx b/desktop/source/app/cmdlinehelp.cxx
index 419b03b3acda..9c9fd940f233 100644
--- a/desktop/source/app/cmdlinehelp.cxx
+++ b/desktop/source/app/cmdlinehelp.cxx
@@ -35,9 +35,9 @@
namespace desktop
{
- constexpr OUStringLiteral aCmdLineHelp_version =
+ constexpr OUString aCmdLineHelp_version =
u"%PRODUCTNAME %PRODUCTVERSION%PRODUCTEXTENSION %BUILDID\n"
- "\n";
+ "\n"_ustr;
constexpr OUStringLiteral aCmdLineHelp =
u"Usage: %CMDNAME [argument...]\n"
" argument - switches, switch parameters and document URIs (filenames). \n\n"
@@ -46,7 +46,10 @@ namespace desktop
" {file} Tries to open the file (files) in the components \n"
" suitable for them. \n"
" {file} {macro:///Library.Module.MacroName} \n"
- " Opens the file and runs specified macros from \n"
+ " Opens the file and runs specified macro from \n"
+ " My Macros container. \n"
+ " {file} {macro://./Library.Module.MacroName} \n"
+ " Opens the file and runs specified macro from \n"
" the file. \n\n"
"Getting help and information: \n"
" --help | -h | -? Shows this help and quits. \n"
diff --git a/desktop/source/app/crashreport.cxx b/desktop/source/app/crashreport.cxx
index a14527c621e2..18db12d07b38 100644
--- a/desktop/source/app/crashreport.cxx
+++ b/desktop/source/app/crashreport.cxx
@@ -68,15 +68,10 @@ static bool dumpCallback(const wchar_t* path, const wchar_t* id,
MDRawAssertionInfo* /*assertion*/,
bool succeeded)
{
- // TODO: moggi: can we avoid this conversion
-#ifdef _MSC_VER
-#pragma warning (disable: 4996)
-#endif
- std::wstring_convert<std::codecvt_utf8<wchar_t>> conv1;
- std::string aPath = conv1.to_bytes(std::wstring(path)) + conv1.to_bytes(std::wstring(id)) + ".dmp";
+ OUString aPath(OUString::Concat(o3tl::toU(path)) + o3tl::toU(id) + ".dmp");
CrashReporter::addKeyValue("Active-SfxObject",CrashReporter::getActiveSfxObjectName(),CrashReporter::AddItem);
CrashReporter::addKeyValue("Last-4-Uno-Commands",CrashReporter::getLoggedUnoCommands(),CrashReporter::AddItem);
- CrashReporter::addKeyValue("DumpFile", OStringToOUString(aPath.c_str(), RTL_TEXTENCODING_UTF8), CrashReporter::AddItem);
+ CrashReporter::addKeyValue("DumpFile", aPath, CrashReporter::AddItem);
CrashReporter::addKeyValue("GDIHandles", OUString::number(::GetGuiResources(::GetCurrentProcess(), GR_GDIOBJECTS)), CrashReporter::Write);
SAL_WARN("desktop", "minidump generated: " << aPath);
return succeeded;
@@ -135,11 +130,11 @@ void CrashReporter::writeCommonInfo()
ucbhelper::InternetProxyDecider proxy_decider(::comphelper::getProcessComponentContext());
- static const OUStringLiteral protocol = u"https";
- static const OUStringLiteral url = u"crashreport.libreoffice.org";
+ static constexpr OUString protocol = u"https"_ustr;
+ static constexpr OUString url = u"crashreport.libreoffice.org"_ustr;
const sal_Int32 port = 443;
- const ucbhelper::InternetProxyServer proxy_server = proxy_decider.getProxy(protocol, url, port);
+ const OUString proxy_server = proxy_decider.getProxy(protocol, url, port);
// save the new Keys
vmaKeyValues atlast = maKeyValues;
@@ -152,9 +147,9 @@ void CrashReporter::writeCommonInfo()
addKeyValue("BuildID", utl::Bootstrap::getBuildIdData(""), AddItem);
addKeyValue("URL", protocol + "://" + url + "/submit/", AddItem);
- if (!proxy_server.aName.isEmpty())
+ if (!proxy_server.isEmpty())
{
- addKeyValue("Proxy", proxy_server.aName + ":" + OUString::number(proxy_server.nPort), AddItem);
+ addKeyValue("Proxy", proxy_server, AddItem);
}
// write the new keys at the end
@@ -198,8 +193,7 @@ OUString CrashReporter::getLoggedUnoCommands()
for( auto& unocommand: maloggedUnoCommands)
{
- aUnoCommandBuffer.append(aCommandSeperator);
- aUnoCommandBuffer.append(unocommand);
+ aUnoCommandBuffer.append(aCommandSeperator + unocommand);
aCommandSeperator=",";
}
return aUnoCommandBuffer.makeStringAndClear();
@@ -235,11 +229,11 @@ void CrashReporter::updateMinidumpLocation()
#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
OUString aURL = getCrashDirectory();
OString aOStringUrl = OUStringToOString(aURL, RTL_TEXTENCODING_UTF8);
- google_breakpad::MinidumpDescriptor descriptor(aOStringUrl.getStr());
+ google_breakpad::MinidumpDescriptor descriptor(std::string{aOStringUrl});
mpExceptionHandler->set_minidump_descriptor(descriptor);
#elif defined _WIN32
OUString aURL = getCrashDirectory();
- mpExceptionHandler->set_dump_path(o3tl::toW(aURL.getStr()));
+ mpExceptionHandler->set_dump_path(std::wstring(o3tl::toW(aURL)));
#endif
}
@@ -293,7 +287,7 @@ std::string CrashReporter::getIniFileName()
{
OUString url = getCrashDirectory() + "dump.ini";
OString aUrl = OUStringToOString(url, RTL_TEXTENCODING_UTF8);
- std::string aRet(aUrl.getStr());
+ std::string aRet(aUrl);
return aRet;
}
@@ -346,6 +340,7 @@ void CrashReporter::writeSystemInfo()
#elif defined _WIN32
void CrashReporter::writeSystemInfo()
{
+#if !defined(_ARM64_)
// Get CPU model name and flags.
// See https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex
// and https://en.wikipedia.org/wiki/CPUID .
@@ -456,6 +451,7 @@ void CrashReporter::writeSystemInfo()
}
if( !flags.isEmpty())
addKeyValue( "CPUFlags", flags.makeStringAndClear(), AddItem );
+#endif
// Get total memory.
MEMORYSTATUSEX memoryStatus;
memoryStatus.dwLength = sizeof( memoryStatus );
diff --git a/desktop/source/app/dispatchwatcher.cxx b/desktop/source/app/dispatchwatcher.cxx
index 3d24a158261e..af26ef9eaab9 100644
--- a/desktop/source/app/dispatchwatcher.cxx
+++ b/desktop/source/app/dispatchwatcher.cxx
@@ -20,7 +20,6 @@
#include <sal/config.h>
#include <sal/log.hxx>
-#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/fcontnr.hxx>
#include <svl/fstathelper.hxx>
@@ -54,7 +53,7 @@
#include <comphelper/propertyvalue.hxx>
#include <comphelper/sequence.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <tools/urlobj.hxx>
#include <unotools/mediadescriptor.hxx>
#include <unotools/tempfile.hxx>
@@ -63,6 +62,7 @@
#include <osl/file.hxx>
#include <iostream>
#include <string_view>
+#include <utility>
using namespace ::osl;
using namespace ::com::sun::star::uno;
@@ -84,8 +84,8 @@ namespace {
struct DispatchHolder
{
- DispatchHolder( const URL& rURL, Reference< XDispatch > const & rDispatch ) :
- aURL( rURL ), xDispatch( rDispatch ) {}
+ DispatchHolder( URL _aURL, Reference< XDispatch > const & rDispatch ) :
+ aURL(std::move( _aURL )), xDispatch( rDispatch ) {}
URL aURL;
Reference< XDispatch > xDispatch;
@@ -243,16 +243,16 @@ void scriptCat(const Reference< XModel >& xDoc )
}
// Perform batch print
-void batchPrint( const OUString &rPrinterName, const Reference< XPrintable > &xDoc,
+void batchPrint( std::u16string_view rPrinterName, const Reference< XPrintable > &xDoc,
const INetURLObject &aObj, const OUString &aName )
{
OUString aFilterOut;
OUString aPrinterName;
- sal_Int32 nPathIndex = rPrinterName.lastIndexOf( ';' );
- if( nPathIndex != -1 )
- aFilterOut=rPrinterName.copy( nPathIndex+1 );
+ size_t nPathIndex = rPrinterName.rfind( ';' );
+ if( nPathIndex != std::u16string_view::npos )
+ aFilterOut=rPrinterName.substr( nPathIndex+1 );
if( nPathIndex != 0 )
- aPrinterName=rPrinterName.copy( 0, nPathIndex );
+ aPrinterName=rPrinterName.substr( 0, nPathIndex );
INetURLObject aOutFilename( aObj );
aOutFilename.SetExtension( u"pdf" );
@@ -266,7 +266,7 @@ void batchPrint( const OUString &rPrinterName, const Reference< XPrintable > &xD
OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding() );
std::cout << "print " << aSource8 << " -> " << aTargetURL8;
- std::cout << " using " << (aPrinterName.isEmpty() ? "<default_printer>" : OUStringToOString( aPrinterName, osl_getThreadTextEncoding() ));
+ std::cout << " using " << (aPrinterName.isEmpty() ? "<default_printer>"_ostr : OUStringToOString( aPrinterName, osl_getThreadTextEncoding() ));
std::cout << std::endl;
// create the custom printer, if given
@@ -283,6 +283,44 @@ void batchPrint( const OUString &rPrinterName, const Reference< XPrintable > &xD
xDoc->print( aPrinterArgs );
}
+// Get xDoc module name
+OUString getName(const Reference< XInterface > & xDoc)
+{
+ Reference< XModel > xModel( xDoc, UNO_QUERY );
+ if (!xModel)
+ return OUString();
+ utl::MediaDescriptor aMediaDesc( xModel->getArgs() );
+ OUString aDocService = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE, OUString() );
+ if (aDocService == "com.sun.star.text.TextDocument")
+ return "Writer";
+ else if (aDocService == "com.sun.star.text.GlobalDocument")
+ return "Writer master";
+ else if (aDocService == "com.sun.star.text.WebDocument")
+ return "Writer/Web";
+ else if (aDocService == "com.sun.star.drawing.DrawingDocument")
+ return "Draw";
+ else if (aDocService == "com.sun.star.presentation.PresentationDocument")
+ return "Impress";
+ else if (aDocService == "com.sun.star.sheet.SpreadsheetDocument")
+ return "Calc";
+ else if (aDocService == "com.sun.star.script.BasicIDE")
+ return "Basic";
+ else if (aDocService == "com.sun.star.formula.FormulaProperties")
+ return "Math";
+ else if (aDocService == "com.sun.star.sdb.RelationDesign")
+ return "Relation Design";
+ else if (aDocService == "com.sun.star.sdb.QueryDesign")
+ return "Query Design";
+ else if (aDocService == "com.sun.star.sdb.TableDesign")
+ return "Table Design";
+ else if (aDocService == "com.sun.star.sdb.DataSourceBrowser")
+ return "Data Source Browser";
+ else if (aDocService == "com.sun.star.sdb.DatabaseDocument")
+ return "Database";
+
+ return OUString();
+}
+
} // anonymous namespace
DispatchWatcher::DispatchWatcher()
@@ -397,11 +435,8 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
"unsupported dispatch request <" << aName << ">");
if( xDispatcher.is() )
{
- {
- osl::MutexGuard aGuard(m_mutex);
- // Remember request so we can find it in statusChanged!
- m_nRequestCount++;
- }
+ // Remember request so we can find it in statusChanged!
+ m_nRequestCount++;
// Use local vector to store dispatcher because we have to fill our request container before
// we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
@@ -571,10 +606,10 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
OUString aOutFile
= aOutFilename.GetMainURL(INetURLObject::DecodeMechanism::NONE);
- std::unique_ptr<utl::TempFile> fileForCat;
+ std::unique_ptr<utl::TempFileNamed> fileForCat;
if( aDispatchRequest.aRequestType == REQUEST_CAT )
{
- fileForCat = std::make_unique<utl::TempFile>();
+ fileForCat = std::make_unique<utl::TempFileNamed>();
if (fileForCat->IsValid())
fileForCat->EnableKillingFile();
else
@@ -663,7 +698,10 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding());
if (aDispatchRequest.aRequestType != REQUEST_CAT)
{
+ OUString name=getName(xDoc);
std::cout << "convert " << aSource8;
+ if (!name.isEmpty())
+ std::cout << " as a " << name <<" document";
if (!bMultiFileTarget)
std::cout << " -> " << aTargetURL8;
std::cout << " using filter : " << OUStringToOString(aFilter, osl_getThreadTextEncoding()) << std::endl;
@@ -769,18 +807,13 @@ bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest
xDisp->dispatchWithNotification( aDispatche.aURL, aArgs, this );
else
{
- {
- osl::MutexGuard aGuard(m_mutex);
- m_nRequestCount--;
- }
+ m_nRequestCount--;
xDispatch->dispatch( aDispatche.aURL, aArgs );
}
}
}
- ::osl::ClearableMutexGuard aGuard(m_mutex);
bool bEmpty = (m_nRequestCount == 0);
- aGuard.clear();
// No more asynchronous requests?
// The requests are removed from the request container after they called back to this
@@ -808,9 +841,7 @@ void SAL_CALL DispatchWatcher::disposing( const css::lang::EventObject& )
void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& )
{
- osl::ClearableMutexGuard aGuard(m_mutex);
- sal_Int16 nCount = --m_nRequestCount;
- aGuard.clear();
+ int nCount = --m_nRequestCount;
RequestHandler::RequestsCompleted();
if ( !nCount && !RequestHandler::AreRequestsPending() )
{
diff --git a/desktop/source/app/dispatchwatcher.hxx b/desktop/source/app/dispatchwatcher.hxx
index 221cac915af3..70a7fd42e679 100644
--- a/desktop/source/app/dispatchwatcher.hxx
+++ b/desktop/source/app/dispatchwatcher.hxx
@@ -22,7 +22,7 @@
#include <cppuhelper/implbase.hxx>
#include <com/sun/star/frame/XDispatchResultListener.hpp>
#include <optional>
-
+#include <atomic>
#include <vector>
namespace desktop
@@ -77,9 +77,8 @@ class DispatchWatcher : public ::cppu::WeakImplHelper< css::frame::XDispatchResu
bool executeDispatchRequests( const std::vector<DispatchRequest>& aDispatches, bool bNoTerminate );
private:
- osl::Mutex m_mutex;
- sal_Int16 m_nRequestCount;
+ std::atomic<int> m_nRequestCount;
};
}
diff --git a/desktop/source/app/langselect.cxx b/desktop/source/app/langselect.cxx
index 8a07e26c3134..5eb2f0636bcd 100644
--- a/desktop/source/app/langselect.cxx
+++ b/desktop/source/app/langselect.cxx
@@ -36,7 +36,7 @@
#include <rtl/ustring.hxx>
#include <svl/languageoptions.hxx>
#include <svtools/langhelp.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <app.hxx>
diff --git a/desktop/source/app/lockfile2.cxx b/desktop/source/app/lockfile2.cxx
index 44447927f63b..98c2903f9403 100644
--- a/desktop/source/app/lockfile2.cxx
+++ b/desktop/source/app/lockfile2.cxx
@@ -31,10 +31,10 @@ bool Lockfile_execWarning( Lockfile const * that )
// read information from lock
OUString aLockname = that->m_aLockname;
Config aConfig(aLockname);
- aConfig.SetGroup( LOCKFILE_GROUP );
- OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY );
- OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY );
- OString aTime = aConfig.ReadKey( LOCKFILE_TIMEKEY );
+ aConfig.SetGroup( LOCKFILE_GROUP ""_ostr );
+ OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY ""_ostr );
+ OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY ""_ostr );
+ OString aTime = aConfig.ReadKey( LOCKFILE_TIMEKEY ""_ostr );
// display warning and return response
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
index d748bef60c68..9d342bf35a84 100644
--- a/desktop/source/app/officeipcthread.cxx
+++ b/desktop/source/app/officeipcthread.cxx
@@ -31,6 +31,7 @@
#include <salhelper/thread.hxx>
#include <sal/log.hxx>
#include <unotools/bootstrap.hxx>
+#include <utility>
#include <vcl/svapp.hxx>
#include <unotools/configmgr.hxx>
#include <osl/pipe.hxx>
@@ -42,10 +43,12 @@
#include <cppuhelper/supportsservice.hxx>
#include <osl/file.hxx>
#include <rtl/process.h>
+#include <o3tl/string_view.hxx>
#include <cassert>
#include <cstdlib>
#include <memory>
+#include <thread>
#if ENABLE_DBUS
#include <dbus/dbus.h>
@@ -70,10 +73,10 @@ char const PROCESSING_DONE[] = "InternalIPC::ProcessingDone";
OString readStringFromPipe(osl::StreamPipe const & pipe) {
for (OStringBuffer str;;) {
char buf[1024];
- sal_Int32 n = pipe.recv(buf, SAL_N_ELEMENTS(buf));
+ sal_Int32 n = pipe.recv(buf, std::size(buf));
if (n <= 0) {
SAL_INFO("desktop.app", "read empty string");
- return "";
+ return ""_ostr;
}
bool end = false;
if (buf[n - 1] == '\0') {
@@ -99,7 +102,7 @@ namespace {
class Parser: public CommandLineArgs::Supplier {
public:
- explicit Parser(OString const & input): m_input(input) {
+ explicit Parser(OString input): m_input(std::move(input)) {
if (!m_input.match(ARGUMENT_PREFIX) ||
m_input.getLength() == RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX))
{
@@ -301,7 +304,7 @@ static void ImplPostProcessDocumentsEvent( std::unique_ptr<ProcessDocumentsReque
oslSignalAction SalMainPipeExchangeSignal_impl(SAL_UNUSED_PARAMETER void* /*pData*/, oslSignalInfo* pInfo)
{
if( pInfo->Signal == osl_Signal_Terminate )
- RequestHandler::SetDowning();
+ RequestHandler::Disable();
return osl_Signal_ActCallNextHdl;
}
@@ -377,8 +380,8 @@ public:
static RequestHandler::Status enable(rtl::Reference<IpcThread> * thread);
private:
- explicit PipeIpcThread(osl::Pipe const & pipe):
- IpcThread("PipeIPC"), pipe_(pipe)
+ explicit PipeIpcThread(osl::Pipe pipe):
+ IpcThread("PipeIPC"), pipe_(std::move(pipe))
{}
virtual ~PipeIpcThread() override {}
@@ -661,9 +664,7 @@ void RequestHandler::EnableRequests()
if (pGlobal->mState != State::Downing) {
pGlobal->mState = State::RequestsEnabled;
}
- // hit the compiler over the head - this avoids GCC -Werror=maybe-uninitialized
- std::optional<OUString> tmp;
- ProcessDocumentsRequest aEmptyReq(tmp);
+ ProcessDocumentsRequest aEmptyReq(std::nullopt);
// trigger already queued requests
RequestHandler::ExecuteCmdLineRequests(aEmptyReq, true);
}
@@ -792,10 +793,7 @@ RequestHandler::Status PipeIpcThread::enable(rtl::Reference<IpcThread> * thread)
else
{
// Pipe connection failed (other office exited or crashed)
- TimeValue tval;
- tval.Seconds = 0;
- tval.Nanosec = 500000000;
- salhelper::Thread::wait( tval );
+ std::this_thread::sleep_for( std::chrono::milliseconds(500) );
}
}
else
@@ -805,10 +803,7 @@ RequestHandler::Status PipeIpcThread::enable(rtl::Reference<IpcThread> * thread)
return RequestHandler::IPC_STATUS_PIPE_ERROR;
// Wait for second office to be ready
- TimeValue aTimeValue;
- aTimeValue.Seconds = 0;
- aTimeValue.Nanosec = 10000000; // 10ms
- salhelper::Thread::wait( aTimeValue );
+ std::this_thread::sleep_for( std::chrono::milliseconds(10) );
}
} while ( nPipeMode == PIPEMODE_DONTKNOW );
@@ -1071,12 +1066,12 @@ bool IpcThread::process(OString const & arguments, bool * waitProcessed) {
aHelpURLBuffer.append("vnd.sun.star.help://smath/start");
}
if (bShowHelp) {
- aHelpURLBuffer.append("?Language=");
- aHelpURLBuffer.append(utl::ConfigManager::getUILocale());
+ aHelpURLBuffer.append("?Language="
+ + utl::ConfigManager::getUILocale()
#if defined UNX
- aHelpURLBuffer.append("&System=UNX");
+ + "&System=UNX");
#elif defined _WIN32
- aHelpURLBuffer.append("&System=WIN");
+ + "&System=WIN");
#endif
ApplicationEvent* pAppEvent = new ApplicationEvent(
ApplicationEvent::Type::OpenHelpUrl,
@@ -1154,10 +1149,10 @@ void PipeIpcThread::execute()
// notify client we're ready to process its args:
SAL_INFO("desktop.app", "writing <" << SEND_ARGUMENTS << ">");
- sal_Int32 n = aStreamPipe.write(
- SEND_ARGUMENTS, SAL_N_ELEMENTS(SEND_ARGUMENTS));
+ std::size_t n = aStreamPipe.write(
+ SEND_ARGUMENTS, std::size(SEND_ARGUMENTS));
// incl. terminating NUL
- if (n != SAL_N_ELEMENTS(SEND_ARGUMENTS)) {
+ if (n != std::size(SEND_ARGUMENTS)) {
SAL_WARN("desktop.app", "short write: " << n);
continue;
}
@@ -1186,9 +1181,9 @@ void PipeIpcThread::execute()
{
// processing finished, inform the requesting end:
SAL_INFO("desktop.app", "writing <" << PROCESSING_DONE << ">");
- n = aStreamPipe.write(PROCESSING_DONE, SAL_N_ELEMENTS(PROCESSING_DONE));
+ n = aStreamPipe.write(PROCESSING_DONE, std::size(PROCESSING_DONE));
// incl. terminating NUL
- if (n != SAL_N_ELEMENTS(PROCESSING_DONE))
+ if (n != std::size(PROCESSING_DONE))
{
SAL_WARN("desktop.app", "short write: " << n);
continue;
@@ -1206,10 +1201,7 @@ void PipeIpcThread::execute()
}
SAL_WARN( "desktop.app", "Error on accept: " << static_cast<int>(nError));
- TimeValue tval;
- tval.Seconds = 1;
- tval.Nanosec = 0;
- salhelper::Thread::wait( tval );
+ std::this_thread::sleep_for( std::chrono::seconds(1) );
}
} while( schedule() );
}
@@ -1236,7 +1228,7 @@ static void AddConversionsToDispatchList(
const OUString& rPrinterName,
const OUString& rFactory,
const OUString& rParamOut,
- const OUString& rImgOut,
+ std::u16string_view rImgOut,
const bool isTextCat,
const bool isScriptCat )
{
@@ -1249,7 +1241,6 @@ static void AddConversionsToDispatchList(
nType = DispatchWatcher::REQUEST_CAT;
else
nType = DispatchWatcher::REQUEST_CONVERSION;
- aParam = rParam;
}
else
{
@@ -1262,8 +1253,6 @@ static void AddConversionsToDispatchList(
}
}
- OUString aOutDir( rParamOut.trim() );
- OUString aImgOut( rImgOut.trim() );
OUString aPWD;
if (cwdUrl)
{
@@ -1274,11 +1263,10 @@ static void AddConversionsToDispatchList(
utl::Bootstrap::getProcessWorkingDir( aPWD );
}
- if( !::osl::FileBase::getAbsoluteFileURL( aPWD, rParamOut, aOutDir ) )
- ::osl::FileBase::getSystemPathFromFileURL( aOutDir, aOutDir );
-
- if( !rParamOut.trim().isEmpty() )
+ if (OUString aOutDir(rParamOut.trim()); !aOutDir.isEmpty())
{
+ if (osl::FileBase::getAbsoluteFileURL(aPWD, rParamOut, aOutDir) == osl::FileBase::E_None)
+ osl::FileBase::getSystemPathFromFileURL(aOutDir, aOutDir);
aParam += ";" + aOutDir;
}
else
@@ -1287,8 +1275,8 @@ static void AddConversionsToDispatchList(
aParam += ";" + aPWD;
}
- if( !rImgOut.trim().isEmpty() )
- aParam += "|" + aImgOut;
+ if( !rImgOut.empty() )
+ aParam += OUString::Concat("|") + o3tl::trim(rImgOut);
for (auto const& request : rRequestList)
{
diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx
index a1de351bc7f5..a233c18e012b 100644
--- a/desktop/source/app/officeipcthread.hxx
+++ b/desktop/source/app/officeipcthread.hxx
@@ -21,6 +21,7 @@
#include <sal/config.h>
+#include <utility>
#include <vector>
#include <com/sun/star/lang/XServiceInfo.hpp>
@@ -42,8 +43,8 @@ oslSignalAction SalMainPipeExchangeSignal_impl(void* /*pData*/, oslSignalInfo* p
// that was given by command line or by IPC pipe communication.
struct ProcessDocumentsRequest
{
- explicit ProcessDocumentsRequest(std::optional< OUString > const & cwdUrl):
- aCwdUrl(cwdUrl), pcProcessed( nullptr ), bTextCat( false ), bScriptCat( false ) {}
+ explicit ProcessDocumentsRequest(std::optional< OUString > cwdUrl):
+ aCwdUrl(std::move(cwdUrl)), pcProcessed( nullptr ), bTextCat( false ), bScriptCat( false ) {}
std::optional< OUString > aCwdUrl;
OUString aModule;
diff --git a/desktop/source/app/opencl.cxx b/desktop/source/app/opencl.cxx
index fb5c3723ed8b..ad3df6bf3fd6 100644
--- a/desktop/source/app/opencl.cxx
+++ b/desktop/source/app/opencl.cxx
@@ -26,7 +26,7 @@
#include <comphelper/propertyvalue.hxx>
#include <svl/documentlockfile.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <com/sun/star/table/XCell2.hpp>
#include <com/sun/star/sheet/XCalculatable.hpp>
@@ -198,7 +198,7 @@ void Desktop::CheckOpenCLCompute(const Reference< XDesktop2 > &xDesktop)
OUString aDevice = officecfg::Office::Calc::Formula::Calculation::OpenCLDevice::get();
OUString aSelectedCLDeviceVersionID;
if (!openclwrapper::switchOpenCLDevice(
- &aDevice,
+ aDevice,
officecfg::Office::Calc::Formula::Calculation::OpenCLAutoSelect::get(),
false /* bForceEvaluation */,
aSelectedCLDeviceVersionID))
diff --git a/desktop/source/app/sofficemain.cxx b/desktop/source/app/sofficemain.cxx
index d95356fd255d..448977684b9a 100644
--- a/desktop/source/app/sofficemain.cxx
+++ b/desktop/source/app/sofficemain.cxx
@@ -30,10 +30,8 @@
#include <prewin.h>
#include <rtl/bootstrap.hxx>
-#include <sal/log.hxx>
#include <sal/main.h>
#include <tools/extendapplicationenvironment.hxx>
-#include <vcl/glxtestprocess.hxx>
#include <vcl/svmain.hxx>
#if HAVE_FEATURE_BREAKPAD
@@ -59,9 +57,6 @@ extern "C" int DESKTOP_DLLPUBLIC soffice_main()
CrashReporter::installExceptionHandler();
#endif
- bool bSuccess = fire_glxtest_process();
- SAL_WARN_IF(!bSuccess, "desktop.opengl", "problems with glxtest");
-
#if defined ANDROID
try {
rtl::Bootstrap::setIniFilename("file:///assets/program/lofficerc");
diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx
index 2748373e5f62..12bb4969a68c 100644
--- a/desktop/source/app/updater.cxx
+++ b/desktop/source/app/updater.cxx
@@ -28,15 +28,18 @@
#include <rtl/ustring.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/configmgr.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
#include <osl/file.hxx>
#include <rtl/process.h>
#include <sal/log.hxx>
+#include <tools/stream.hxx>
#include <curl/curl.h>
#include <orcus/json_document_tree.hpp>
#include <orcus/config.hpp>
-#include <orcus/pstring.hpp>
+
+#include <systools/curlinit.hxx>
#include <comphelper/hash.hxx>
#include <com/sun/star/container/XNameAccess.hpp>
@@ -46,6 +49,7 @@
#include <functional>
#include <memory>
#include <set>
+#include <string_view>
namespace {
@@ -83,7 +87,12 @@ const char* pSofficeExeName = "soffice.exe";
OUString normalizePath(const OUString& rPath)
{
- OUString aPath = rPath.replaceAll("//", "/");
+ OUString aPath = rPath;
+#if defined WNT
+ aPath = aPath.replace('\\', '/');
+#endif
+
+ aPath = aPath.replaceAll("//", "/");
// remove final /
if (aPath.endsWith("/"))
@@ -105,7 +114,10 @@ OUString normalizePath(const OUString& rPath)
aPath = aTempPath.copy(0, i) + aPath.copy(nIndex + 3);
}
- return aPath.replaceAll("\\", "/");
+#if defined WNT
+ aPath = aPath.replace('/', '\\');
+#endif
+ return aPath;
}
void CopyFileToDir(const OUString& rTempDirURL, const OUString & rFileName, const OUString& rOldDir)
@@ -133,14 +145,17 @@ void CopyUpdaterToTempDir(const OUString& rInstallDirURL, const OUString& rTempD
{
OUString aUpdaterName = OUString::fromUtf8(pUpdaterName);
CopyFileToDir(rTempDirURL, aUpdaterName, rInstallDirURL);
+ CopyFileToDir(rTempDirURL, u"updater.ini"_ustr, rInstallDirURL);
}
#ifdef UNX
typedef char CharT;
#define tstrncpy std::strncpy
+char const * toStream(char const * s) { return s; }
#elif defined(_WIN32)
typedef wchar_t CharT;
#define tstrncpy std::wcsncpy
+OUString toStream(wchar_t const * s) { return OUString(o3tl::toU(s)); }
#else
#error "Need an implementation"
#endif
@@ -160,17 +175,14 @@ void createStr(const OUString& rStr, CharT** pArgs, size_t i)
pArgs[i] = pStr;
}
-CharT** createCommandLine()
+CharT** createCommandLine(OUString const & argv0, int * argc)
{
OUString aInstallDir = Updater::getInstallationPath();
size_t nCommandLineArgs = rtl_getAppCommandArgCount();
size_t nArgs = 8 + nCommandLineArgs;
CharT** pArgs = new CharT*[nArgs];
- {
- OUString aUpdaterName = OUString::fromUtf8(pUpdaterName);
- createStr(aUpdaterName, pArgs, 0);
- }
+ createStr(argv0, pArgs, 0);
{
// directory with the patch log
OUString aPatchDir = Updater::getPatchDirURL();
@@ -226,6 +238,7 @@ CharT** createCommandLine()
pArgs[nArgs - 1] = nullptr;
+ *argc = nArgs - 1;
return pArgs;
}
@@ -285,14 +298,15 @@ bool isUserWritable(const OUString& rFileURL)
bool update()
{
- utl::TempFile aTempDir(nullptr, true);
+ utl::TempFileNamed aTempDir(nullptr, true);
OUString aTempDirURL = aTempDir.GetURL();
CopyUpdaterToTempDir(Updater::getExecutableDirURL(), aTempDirURL);
OUString aUpdaterPath = getPathFromURL(aTempDirURL + "/" + OUString::fromUtf8(pUpdaterName));
Updater::log("Calling the updater with parameters: ");
- CharT** pArgs = createCommandLine();
+ int argc;
+ CharT** pArgs = createCommandLine(aUpdaterPath, &argc);
bool bSuccess = true;
const char* pUpdaterTestReplace = std::getenv("LIBO_UPDATER_TEST_REPLACE");
@@ -306,7 +320,7 @@ bool update()
bSuccess = false;
}
#elif defined(_WIN32)
- bSuccess = WinLaunchChild((wchar_t*)aUpdaterPath.getStr(), 8, pArgs);
+ bSuccess = WinLaunchChild((wchar_t*)aUpdaterPath.getStr(), argc, pArgs);
#endif
}
else
@@ -314,7 +328,7 @@ bool update()
SAL_WARN("desktop.updater", "Updater executable path: " << aUpdaterPath);
for (size_t i = 0; i < 8 + rtl_getAppCommandArgCount(); ++i)
{
- SAL_WARN("desktop.updater", pArgs[i]);
+ SAL_WARN("desktop.updater", toStream(pArgs[i]));
}
bSuccess = false;
}
@@ -389,9 +403,9 @@ public:
}
};
-OUString toOUString(const std::string& rStr)
+OUString toOUString(const std::string_view& rStr)
{
- return OUString::fromUtf8(rStr.c_str());
+ return OUString::fromUtf8(rStr);
}
update_file parse_update_file(orcus::json::node& rNode)
@@ -420,12 +434,12 @@ update_file parse_update_file(orcus::json::node& rNode)
}
update_file aUpdateFile;
- aUpdateFile.aURL = toOUString(aURLNode.string_value().str());
+ aUpdateFile.aURL = toOUString(aURLNode.string_value());
if (aUpdateFile.aURL.isEmpty())
throw invalid_update_info();
- aUpdateFile.aHash = toOUString(aHashNode.string_value().str());
+ aUpdateFile.aHash = toOUString(aHashNode.string_value());
aUpdateFile.nSize = static_cast<sal_uInt32>(aSizeNode.numeric_value());
return aUpdateFile;
}
@@ -452,7 +466,7 @@ update_info parse_response(const std::string& rResponse)
{
update_info aUpdateInfo;
auto aMsgNode = aDocumentRoot.child("response");
- aUpdateInfo.aMessage = toOUString(aMsgNode.string_value().str());
+ aUpdateInfo.aMessage = toOUString(aMsgNode.string_value());
return aUpdateInfo;
}
@@ -475,23 +489,23 @@ update_info parse_response(const std::string& rResponse)
}
orcus::json::node aLanguageNode = aDocumentRoot.child("languages");
- if (aUpdateNode.type() != orcus::json::node_t::object)
+ if (aLanguageNode.type() != orcus::json::node_t::object)
{
throw invalid_update_info();
}
update_info aUpdateInfo;
- aUpdateInfo.aFromBuildID = toOUString(aFromNode.string_value().str());
- aUpdateInfo.aSeeAlsoURL = toOUString(aSeeAlsoNode.string_value().str());
+ aUpdateInfo.aFromBuildID = toOUString(aFromNode.string_value());
+ aUpdateInfo.aSeeAlsoURL = toOUString(aSeeAlsoNode.string_value());
aUpdateInfo.aUpdateFile = parse_update_file(aUpdateNode);
- std::vector<orcus::pstring> aLanguages = aLanguageNode.keys();
+ std::vector<std::string_view> aLanguages = aLanguageNode.keys();
for (auto const& language : aLanguages)
{
language_file aLanguageFile;
auto aLangEntry = aLanguageNode.child(language);
- aLanguageFile.aLangCode = toOUString(language.str());
+ aLanguageFile.aLangCode = toOUString(language);
aLanguageFile.aUpdateFile = parse_update_file(aLangEntry);
aUpdateInfo.aLanguageFiles.push_back(aLanguageFile);
}
@@ -546,6 +560,8 @@ std::string download_content(const OString& rURL, bool bFile, OUString& rHash)
if (!curl)
return std::string();
+ ::InitCurl_easy(curl.get());
+
curl_easy_setopt(curl.get(), CURLOPT_URL, rURL.getStr());
curl_easy_setopt(curl.get(), CURLOPT_USERAGENT, kUserAgent);
bool bUseProxy = false;
@@ -562,11 +578,15 @@ std::string download_content(const OString& rURL, bool bFile, OUString& rHash)
headerlist = curl_slist_append(headerlist, buf);
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1); // follow redirects
- // only allow redirect to http:// and https://
- curl_easy_setopt(curl.get(), CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+ // only allow redirect to https://
+#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 85)
+ curl_easy_setopt(curl.get(), CURLOPT_REDIR_PROTOCOLS_STR, "https");
+#else
+ curl_easy_setopt(curl.get(), CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
+#endif
std::string response_body;
- utl::TempFile aTempFile;
+ utl::TempFileNamed aTempFile;
WriteDataFile aFile(aTempFile.GetStream(StreamMode::WRITE));
if (!bFile)
{
@@ -655,9 +675,11 @@ void download_file(const OUString& rURL, size_t nFileSize, const OUString& rHash
throw invalid_hash(rHash, aHash);
}
- OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/");
+ OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/updates/");
rtl::Bootstrap::expandMacros(aPatchDirURL);
osl::Directory::create(aPatchDirURL);
+ aPatchDirURL += "0/";
+ osl::Directory::create(aPatchDirURL);
OUString aDestFile = aPatchDirURL + aFileName;
Updater::log("Destination File: " + aDestFile);
@@ -743,6 +765,14 @@ void update_checker()
comphelper::ConfigurationChanges::create());
officecfg::Office::Update::Update::SeeAlso::set(aSeeAlsoURL, batch);
batch->commit();
+ OUString const statUrl = Updater::getPatchDirURL() + "update.status";
+ SvFileStream stat(statUrl, StreamMode::WRITE | StreamMode::TRUNC);
+ stat.WriteOString("pending-service");
+ stat.Flush();
+ if (auto const e = stat.GetError()) {
+ Updater::log("Writing <" + statUrl + "> failed with " + e.toString());
+ }
+ stat.Close();
}
}
}
@@ -775,7 +805,7 @@ void update_checker()
OUString Updater::getUpdateInfoLog()
{
- OUString aUpdateInfoURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/updating.log");
+ OUString aUpdateInfoURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/updates/updating.log");
rtl::Bootstrap::expandMacros(aUpdateInfoURL);
return aUpdateInfoURL;
@@ -783,7 +813,7 @@ OUString Updater::getUpdateInfoLog()
OUString Updater::getPatchDirURL()
{
- OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/patch/");
+ OUString aPatchDirURL("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/updates/0/");
rtl::Bootstrap::expandMacros(aPatchDirURL);
return aPatchDirURL;
@@ -834,7 +864,7 @@ void Updater::log(const char* pMessage)
OUString aUpdateLog = getUpdateInfoLog();
SvFileStream aLog(aUpdateLog, StreamMode::STD_READWRITE);
aLog.Seek(aLog.Tell() + aLog.remainingSize()); // make sure we are at the end
- aLog.WriteCharPtr(pMessage);
+ aLog.WriteOString(pMessage);
}
OUString Updater::getBuildID()
diff --git a/desktop/source/app/userinstall.cxx b/desktop/source/app/userinstall.cxx
index 669a7316cb42..7243db43e691 100644
--- a/desktop/source/app/userinstall.cxx
+++ b/desktop/source/app/userinstall.cxx
@@ -31,7 +31,7 @@
#include <rtl/bootstrap.hxx>
#endif
#include <rtl/ustring.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <unotools/bootstrap.hxx>
#include "userinstall.hxx"
diff --git a/desktop/source/deployment/dp_log.cxx b/desktop/source/deployment/dp_log.cxx
index 9cdf8d071a99..5d75422cf0d5 100644
--- a/desktop/source/deployment/dp_log.cxx
+++ b/desktop/source/deployment/dp_log.cxx
@@ -40,7 +40,7 @@ namespace {
class ProgressLogImpl : public cppu::BaseMutex, public t_log_helper
{
- std::unique_ptr<comphelper::EventLogger> m_logger;
+ comphelper::EventLogger m_logger;
protected:
virtual void SAL_CALL disposing() override;
@@ -77,9 +77,9 @@ ProgressLogImpl::ProgressLogImpl(
Sequence<Any> const & /* args */,
Reference<XComponentContext> const & xContext )
: t_log_helper( m_aMutex )
-{
// Use the logger created by unopkg app
- m_logger.reset(new comphelper::EventLogger(xContext, "unopkg"));
+ , m_logger(xContext, "unopkg")
+{
}
// XServiceInfo
@@ -122,7 +122,7 @@ void ProgressLogImpl::update( Any const & Status )
logLevel = LogLevel::SEVERE;
buf.append( ::comphelper::anyToString(Status) );
}
- m_logger->log(logLevel, buf.makeStringAndClear());
+ m_logger.log(logLevel, buf.makeStringAndClear());
}
diff --git a/desktop/source/deployment/dp_persmap.cxx b/desktop/source/deployment/dp_persmap.cxx
index 222a6cf99c03..8b032fffb96e 100644
--- a/desktop/source/deployment/dp_persmap.cxx
+++ b/desktop/source/deployment/dp_persmap.cxx
@@ -17,8 +17,13 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <cstddef>
+
#include <dp_misc.h>
#include <dp_persmap.h>
+#include <o3tl/safeint.hxx>
#include <rtl/byteseq.hxx>
#include <rtl/strbuf.hxx>
#include <sal/log.hxx>
@@ -175,7 +180,7 @@ void PersistentMap::readAll()
if( nBytesRead != sizeof(aHeaderBytes))
return;
// check header magic
- for( int i = 0; i < int(sizeof(PmapMagic)); ++i)
+ for( std::size_t i = 0; i < sizeof(PmapMagic); ++i)
if( aHeaderBytes[i] != PmapMagic[i])
return;
@@ -239,13 +244,13 @@ void PersistentMap::flush()
const OString aKeyString = encodeString( entry.first);
const sal_Int32 nKeyLen = aKeyString.getLength();
m_MapFile.write( aKeyString.getStr(), nKeyLen, nBytesWritten);
- OSL_ASSERT( nKeyLen == static_cast<sal_Int32>(nBytesWritten));
+ OSL_ASSERT( o3tl::make_unsigned(nKeyLen) == nBytesWritten);
m_MapFile.write( "\n", 1, nBytesWritten);
// write line for value
const OString& rValString = encodeString( entry.second);
const sal_Int32 nValLen = rValString.getLength();
m_MapFile.write( rValString.getStr(), nValLen, nBytesWritten);
- OSL_ASSERT( nValLen == static_cast<sal_Int32>(nBytesWritten));
+ OSL_ASSERT( o3tl::make_unsigned(nValLen) == nBytesWritten);
m_MapFile.write( "\n", 1, nBytesWritten);
}
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
index 3169904aa4a6..d5af09441405 100644
--- a/desktop/source/deployment/gui/dp_gui_dialog2.cxx
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
@@ -34,10 +34,10 @@
#include <fpicker/strings.hrc>
+#include <utility>
#include <vcl/commandevent.hxx>
#include <vcl/svapp.hxx>
-#include <osl/mutex.hxx>
#include <sal/log.hxx>
#include <rtl/ustrbuf.hxx>
@@ -51,7 +51,7 @@
#include <cppuhelper/supportsservice.hxx>
#include <comphelper/processfactory.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <unotools/configmgr.hxx>
#include <com/sun/star/deployment/DeploymentException.hpp>
@@ -76,7 +76,7 @@ using namespace ::com::sun::star::system;
namespace dp_gui {
constexpr OUStringLiteral USER_PACKAGE_MANAGER = u"user";
-constexpr OUStringLiteral SHARED_PACKAGE_MANAGER = u"shared";
+constexpr OUString SHARED_PACKAGE_MANAGER = u"shared"_ustr;
constexpr OUStringLiteral BUNDLED_PACKAGE_MANAGER = u"bundled";
// ExtBoxWithBtns_Impl
@@ -87,7 +87,7 @@ class ExtBoxWithBtns_Impl : public ExtensionBox_Impl
ExtMgrDialog* m_pParent;
void SetButtonStatus( const TEntry_Impl& rEntry );
- OString ShowPopupMenu( const Point &rPos, const tools::Long nPos );
+ OUString ShowPopupMenu( const Point &rPos, const tools::Long nPos );
public:
explicit ExtBoxWithBtns_Impl(std::unique_ptr<weld::ScrolledWindow> xScroll);
@@ -199,7 +199,7 @@ bool ExtBoxWithBtns_Impl::Command(const CommandEvent& rCEvt)
const Point aMousePos(rCEvt.GetMousePosPixel());
const auto nPos = PointToPos(aMousePos);
- OString sCommand = ShowPopupMenu(aMousePos, nPos);
+ OUString sCommand = ShowPopupMenu(aMousePos, nPos);
if (sCommand == "CMD_ENABLE")
m_pParent->enablePackage( GetEntryData( nPos )->m_xPackage, true );
@@ -220,7 +220,7 @@ bool ExtBoxWithBtns_Impl::Command(const CommandEvent& rCEvt)
return true;
}
-OString ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const tools::Long nPos )
+OUString ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const tools::Long nPos )
{
if ( nPos >= static_cast<tools::Long>(getItemCount()) )
return "CMD_NONE";
@@ -436,6 +436,7 @@ ExtMgrDialog::ExtMgrDialog(weld::Window *pParent, TheExtensionManager *pManager)
, m_xProgressText(m_xBuilder->weld_label("progressft"))
, m_xProgressBar(m_xBuilder->weld_progress_bar("progressbar"))
, m_xCancelBtn(m_xBuilder->weld_button("cancel"))
+ , m_xSearchEntry(m_xBuilder->weld_entry("search"))
{
m_xExtensionBox->InitFromDialog(this);
@@ -453,6 +454,8 @@ ExtMgrDialog::ExtMgrDialog(weld::Window *pParent, TheExtensionManager *pManager)
m_xSharedCbx->connect_toggled( LINK( this, ExtMgrDialog, HandleExtTypeCbx ) );
m_xUserCbx->connect_toggled( LINK( this, ExtMgrDialog, HandleExtTypeCbx ) );
+ m_xSearchEntry->connect_changed( LINK( this, ExtMgrDialog, HandleSearch ) );
+
m_xBundledCbx->set_active(true);
m_xSharedCbx->set_active(true);
m_xUserCbx->set_active(true);
@@ -497,6 +500,18 @@ void ExtMgrDialog::addPackageToList( const uno::Reference< deployment::XPackage
const SolarMutexGuard aGuard;
m_xUpdateBtn->set_sensitive(true);
+ bool bSearchMatch = m_xSearchEntry->get_text().isEmpty();
+ if (!m_xSearchEntry->get_text().isEmpty()
+ && xPackage->getDisplayName().toAsciiLowerCase().indexOf(
+ m_xSearchEntry->get_text().toAsciiLowerCase())
+ >= 0)
+ {
+ bSearchMatch = true;
+ }
+
+ if (!bSearchMatch)
+ return;
+
if (m_xBundledCbx->get_active() && (xPackage->getRepositoryName() == BUNDLED_PACKAGE_MANAGER) )
{
m_xExtensionBox->addEntry( xPackage, bLicenseMissing );
@@ -511,6 +526,14 @@ void ExtMgrDialog::addPackageToList( const uno::Reference< deployment::XPackage
}
}
+void ExtMgrDialog::updateList()
+{
+ // re-creates the list of packages with addEntry selecting the packages
+ prepareChecking();
+ m_pManager->createPackageList();
+ checkEntries();
+}
+
void ExtMgrDialog::prepareChecking()
{
m_xExtensionBox->prepareChecking();
@@ -753,7 +776,7 @@ IMPL_LINK_NOARG(ExtMgrDialog, HandleCloseBtn, weld::Button&, void)
IMPL_LINK( ExtMgrDialog, startProgress, void*, _bLockInterface, void )
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
bool bLockInterface = static_cast<bool>(_bLockInterface);
if ( m_bStartProgress && !m_bHasProgress )
@@ -792,7 +815,7 @@ IMPL_LINK( ExtMgrDialog, startProgress, void*, _bLockInterface, void )
void ExtMgrDialog::showProgress( bool _bStart )
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
bool bStart = _bStart;
@@ -818,7 +841,7 @@ void ExtMgrDialog::updateProgress( const tools::Long nProgress )
{
if ( m_nProgress != nProgress )
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
m_nProgress = nProgress;
m_aIdle.Start();
}
@@ -828,7 +851,7 @@ void ExtMgrDialog::updateProgress( const tools::Long nProgress )
void ExtMgrDialog::updateProgress( const OUString &rText,
const uno::Reference< task::XAbortChannel > &xAbortChannel)
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
m_xAbortChannel = xAbortChannel;
m_sProgressText = rText;
@@ -903,10 +926,12 @@ IMPL_LINK_NOARG(ExtMgrDialog, HandleEnableBtn, weld::Button&, void)
IMPL_LINK_NOARG(ExtMgrDialog, HandleExtTypeCbx, weld::Toggleable&, void)
{
- // re-creates the list of packages with addEntry selecting the packages
- prepareChecking();
- m_pManager->createPackageList();
- checkEntries();
+ updateList();
+}
+
+IMPL_LINK_NOARG(ExtMgrDialog, HandleSearch, weld::Entry&, void)
+{
+ updateList();
}
IMPL_LINK_NOARG(ExtMgrDialog, HandleUpdateBtn, weld::Button&, void)
@@ -1054,7 +1079,7 @@ IMPL_LINK_NOARG(UpdateRequiredDialog, HandleCancelBtn, weld::Button&, void)
IMPL_LINK( UpdateRequiredDialog, startProgress, void*, _bLockInterface, void )
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
bool bLockInterface = static_cast<bool>(_bLockInterface);
if ( m_bStartProgress && !m_bHasProgress )
@@ -1080,7 +1105,7 @@ IMPL_LINK( UpdateRequiredDialog, startProgress, void*, _bLockInterface, void )
void UpdateRequiredDialog::showProgress( bool _bStart )
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
bool bStart = _bStart;
@@ -1106,7 +1131,7 @@ void UpdateRequiredDialog::updateProgress( const tools::Long nProgress )
{
if ( m_nProgress != nProgress )
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
m_nProgress = nProgress;
m_aIdle.Start();
}
@@ -1116,7 +1141,7 @@ void UpdateRequiredDialog::updateProgress( const tools::Long nProgress )
void UpdateRequiredDialog::updateProgress( const OUString &rText,
const uno::Reference< task::XAbortChannel > &xAbortChannel)
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
m_xAbortChannel = xAbortChannel;
m_sProgressText = rText;
@@ -1146,7 +1171,7 @@ void UpdateRequiredDialog::updatePackageInfo( const uno::Reference< deployment::
IMPL_LINK_NOARG(UpdateRequiredDialog, HandleUpdateBtn, weld::Button&, void)
{
- ::osl::ClearableMutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
std::vector< uno::Reference< deployment::XPackage > > vUpdateEntries;
sal_Int32 nCount = m_xExtensionBox->GetEntryCount();
@@ -1157,7 +1182,7 @@ IMPL_LINK_NOARG(UpdateRequiredDialog, HandleUpdateBtn, weld::Button&, void)
vUpdateEntries.push_back( pEntry->m_xPackage );
}
- aGuard.clear();
+ aGuard.unlock();
m_pManager->getCmdQueue()->checkForUpdates( std::move(vUpdateEntries) );
}
@@ -1165,7 +1190,7 @@ IMPL_LINK_NOARG(UpdateRequiredDialog, HandleUpdateBtn, weld::Button&, void)
IMPL_LINK_NOARG(UpdateRequiredDialog, HandleCloseBtn, weld::Button&, void)
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
if ( !isBusy() )
{
@@ -1276,7 +1301,7 @@ bool UpdateRequiredDialog::checkDependencies( const uno::Reference< deployment::
bool UpdateRequiredDialog::hasActiveEntries()
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
bool bRet = false;
tools::Long nCount = m_xExtensionBox->GetEntryCount();
@@ -1297,7 +1322,7 @@ bool UpdateRequiredDialog::hasActiveEntries()
void UpdateRequiredDialog::disableAllEntries()
{
- ::osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
incBusy();
@@ -1332,8 +1357,8 @@ ShowLicenseDialog::~ShowLicenseDialog()
// UpdateRequiredDialogService
UpdateRequiredDialogService::UpdateRequiredDialogService( SAL_UNUSED_PARAMETER uno::Sequence< uno::Any > const&,
- uno::Reference< uno::XComponentContext > const& xComponentContext )
- : m_xComponentContext( xComponentContext )
+ uno::Reference< uno::XComponentContext > xComponentContext )
+ : m_xComponentContext(std::move( xComponentContext ))
{
}
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.hxx b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
index 2a90d1ca060c..b235aed18589 100644
--- a/desktop/source/deployment/gui/dp_gui_dialog2.hxx
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
@@ -25,7 +25,7 @@
#include <vcl/customweld.hxx>
#include <vcl/weld.hxx>
-#include <osl/mutex.hxx>
+#include <mutex>
#include <rtl/ustring.hxx>
@@ -92,7 +92,7 @@ class ExtMgrDialog : public weld::GenericDialogController
{
const OUString m_sAddPackages;
OUString m_sProgressText;
- ::osl::Mutex m_aMutex;
+ std::mutex m_aMutex;
bool m_bHasProgress;
bool m_bProgressChanged;
bool m_bStartProgress;
@@ -122,6 +122,7 @@ class ExtMgrDialog : public weld::GenericDialogController
std::unique_ptr<weld::Label> m_xProgressText;
std::unique_ptr<weld::ProgressBar> m_xProgressBar;
std::unique_ptr<weld::Button> m_xCancelBtn;
+ std::unique_ptr<weld::Entry> m_xSearchEntry;
bool removeExtensionWarn(std::u16string_view rExtensionTitle);
@@ -133,6 +134,7 @@ class ExtMgrDialog : public weld::GenericDialogController
DECL_LINK( HandleCancelBtn, weld::Button&, void );
DECL_LINK( HandleCloseBtn, weld::Button&, void );
DECL_LINK( HandleExtTypeCbx, weld::Toggleable&, void );
+ DECL_LINK( HandleSearch, weld::Entry&, void );
DECL_LINK( TimeOutHdl, Timer *, void );
DECL_LINK( startProgress, void *, void );
@@ -160,6 +162,7 @@ public:
TheExtensionManager* getExtensionManager() const { return m_pManager; }
+ void updateList();
virtual void prepareChecking() override;
virtual void checkEntries() override;
@@ -181,7 +184,7 @@ class UpdateRequiredDialog : public weld::GenericDialogController
{
const OUString m_sCloseText;
OUString m_sProgressText;
- ::osl::Mutex m_aMutex;
+ std::mutex m_aMutex;
bool m_bHasProgress;
bool m_bProgressChanged;
bool m_bStartProgress;
@@ -247,7 +250,7 @@ class UpdateRequiredDialogService : public ::cppu::WeakImplHelper< css::ui::dial
css::uno::Reference< css::uno::XComponentContext > const m_xComponentContext;
public:
UpdateRequiredDialogService( css::uno::Sequence< css::uno::Any > const & args,
- css::uno::Reference< css::uno::XComponentContext> const & xComponentContext );
+ css::uno::Reference< css::uno::XComponentContext> xComponentContext );
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override;
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
index 863e6811c32d..c91ec4a0b132 100644
--- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
@@ -46,9 +46,7 @@
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/TypeClass.hpp>
#include <o3tl/any.hxx>
-#include <osl/conditn.hxx>
#include <osl/diagnose.h>
-#include <osl/mutex.hxx>
#include <rtl/ref.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
@@ -57,6 +55,7 @@
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/implbase.hxx>
#include <comphelper/anytostring.hxx>
+#include <utility>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
@@ -73,8 +72,10 @@
#include <dp_identifier.hxx>
#include <dp_version.hxx>
+#include <condition_variable>
#include <queue>
#include <memory>
+#include <mutex>
#ifdef _WIN32
#include <o3tl/safeCoInitUninit.hxx>
@@ -127,12 +128,12 @@ public:
will be handled and in the second case a VersionException will be handled.
*/
- ProgressCmdEnv( const uno::Reference< uno::XComponentContext >& rContext,
+ ProgressCmdEnv( uno::Reference< uno::XComponentContext > xContext,
DialogHelper* pDialogHelper,
- const OUString& rTitle )
- : m_xContext( rContext )
+ OUString aTitle )
+ : m_xContext(std::move( xContext ))
, m_pDialogHelper( pDialogHelper )
- , m_sTitle( rTitle )
+ , m_sTitle(std::move( aTitle ))
, m_bWarnUser( false )
, m_nCurrentProgress(0)
{}
@@ -171,18 +172,18 @@ struct ExtensionCmd
std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
ExtensionCmd( const E_CMD_TYPE eCommand,
- const OUString &rExtensionURL,
- const OUString &rRepository,
+ OUString aExtensionURL,
+ OUString aRepository,
const bool bWarnUser )
: m_eCmdType( eCommand ),
m_bWarnUser( bWarnUser ),
- m_sExtensionURL( rExtensionURL ),
- m_sRepository( rRepository ) {};
+ m_sExtensionURL(std::move( aExtensionURL )),
+ m_sRepository(std::move( aRepository )) {};
ExtensionCmd( const E_CMD_TYPE eCommand,
- const uno::Reference< deployment::XPackage > &rPackage )
+ uno::Reference< deployment::XPackage > xPackage )
: m_eCmdType( eCommand ),
m_bWarnUser( false ),
- m_xPackage( rPackage ) {};
+ m_xPackage(std::move( xPackage )) {};
ExtensionCmd( const E_CMD_TYPE eCommand,
std::vector<uno::Reference<deployment::XPackage > >&&vExtensionList )
: m_eCmdType( eCommand ),
@@ -200,7 +201,7 @@ class ExtensionCmdQueue::Thread: public salhelper::Thread
public:
Thread( DialogHelper *pDialogHelper,
TheExtensionManager *pManager,
- const uno::Reference< uno::XComponentContext > & rContext );
+ uno::Reference< uno::XComponentContext > xContext );
void addExtension( const OUString &rExtensionURL,
const OUString &rRepository,
@@ -248,8 +249,8 @@ private:
const OUString m_sRemovingPackages;
const OUString m_sDefaultCmd;
const OUString m_sAcceptLicense;
- osl::Condition m_wakeup;
- osl::Mutex m_mutex;
+ std::condition_variable m_wakeup;
+ std::mutex m_mutex;
Input m_eInput;
bool m_bStopped;
bool m_bWorking;
@@ -362,7 +363,7 @@ void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const &
{
std::vector< OUString > deps;
deps.reserve(depExc.UnsatisfiedDependencies.getLength());
- for (auto const & i : std::as_const(depExc.UnsatisfiedDependencies))
+ for (auto const& i : depExc.UnsatisfiedDependencies)
{
deps.push_back( dp_misc::Dependencies::getErrorText(i) );
}
@@ -580,9 +581,9 @@ void ProgressCmdEnv::pop()
ExtensionCmdQueue::Thread::Thread( DialogHelper *pDialogHelper,
TheExtensionManager *pManager,
- const uno::Reference< uno::XComponentContext > & rContext ) :
+ uno::Reference< uno::XComponentContext > xContext ) :
salhelper::Thread( "dp_gui_extensioncmdqueue" ),
- m_xContext( rContext ),
+ m_xContext(std::move( xContext )),
m_pDialogHelper( pDialogHelper ),
m_pManager( pManager ),
m_sEnablingPackages( DpResId( RID_STR_ENABLING_PACKAGES ) ),
@@ -655,16 +656,16 @@ void ExtensionCmdQueue::Thread::checkForUpdates(
//Stopping this thread will not abort the installation of extensions.
void ExtensionCmdQueue::Thread::stop()
{
- osl::MutexGuard aGuard( m_mutex );
+ std::scoped_lock aGuard( m_mutex );
m_bStopped = true;
m_eInput = STOP;
- m_wakeup.set();
+ m_wakeup.notify_all();
}
bool ExtensionCmdQueue::Thread::isBusy()
{
- osl::MutexGuard aGuard( m_mutex );
+ std::scoped_lock aGuard( m_mutex );
return m_bWorking;
}
@@ -682,33 +683,29 @@ void ExtensionCmdQueue::Thread::execute()
#endif
for (;;)
{
- if ( m_wakeup.wait() != osl::Condition::result_ok )
- {
- dp_misc::TRACE( "dp_gui::ExtensionCmdQueue::Thread::run: ignored "
- "osl::Condition::wait failure\n" );
- }
- m_wakeup.reset();
-
int nSize;
Input eInput;
{
- osl::MutexGuard aGuard( m_mutex );
+ std::unique_lock aGuard( m_mutex );
+ while (m_eInput == NONE) {
+ m_wakeup.wait(aGuard);
+ }
eInput = m_eInput;
m_eInput = NONE;
nSize = m_queue.size();
+ // coverity[missing_lock: FALSE] - maybe due to (by-design) unique_lock vs. scoped_lock?
m_bWorking = false;
}
- // If this thread has been woken up by anything else except start, stop
- // then input is NONE and we wait again.
+ if ( eInput == STOP )
+ break;
+
// We only install the extension which are currently in the queue.
// The progressbar will be set to show the progress of the current number
// of extensions. If we allowed to add extensions now then the progressbar may
// have reached the end while we still install newly added extensions.
- if ( ( eInput == NONE ) || ( nSize == 0 ) )
+ if ( nSize == 0 )
continue;
- if ( eInput == STOP )
- break;
::rtl::Reference< ProgressCmdEnv > currentCmdEnv( new ProgressCmdEnv( m_xContext, m_pDialogHelper, m_sDefaultCmd ) );
@@ -720,7 +717,7 @@ void ExtensionCmdQueue::Thread::execute()
while ( --nSize >= 0 )
{
{
- osl::MutexGuard aGuard( m_mutex );
+ std::scoped_lock aGuard( m_mutex );
m_bWorking = true;
}
@@ -728,7 +725,7 @@ void ExtensionCmdQueue::Thread::execute()
{
TExtensionCmd pEntry;
{
- ::osl::MutexGuard queueGuard( m_mutex );
+ std::scoped_lock queueGuard( m_mutex );
pEntry = m_queue.front();
m_queue.pop();
}
@@ -766,7 +763,7 @@ void ExtensionCmdQueue::Thread::execute()
//Then we cancel the installation of all extensions and remove them from
//the queue.
{
- ::osl::MutexGuard queueGuard2(m_mutex);
+ std::scoped_lock queueGuard2(m_mutex);
while ( --nSize >= 0 )
m_queue.pop();
}
@@ -813,14 +810,14 @@ void ExtensionCmdQueue::Thread::execute()
//Continue with installation of the remaining extensions
}
{
- osl::MutexGuard aGuard( m_mutex );
+ std::scoped_lock aGuard( m_mutex );
m_bWorking = false;
}
}
{
// when leaving the while loop with break, we should set working to false, too
- osl::MutexGuard aGuard( m_mutex );
+ std::scoped_lock aGuard( m_mutex );
m_bWorking = false;
}
@@ -1043,7 +1040,7 @@ void ExtensionCmdQueue::Thread::_acceptLicense( ::rtl::Reference< ProgressCmdEnv
void ExtensionCmdQueue::Thread::_insert(const TExtensionCmd& rExtCmd)
{
- ::osl::MutexGuard aGuard( m_mutex );
+ std::scoped_lock aGuard( m_mutex );
// If someone called stop then we do not process the command -> game over!
if ( m_bStopped )
@@ -1051,7 +1048,7 @@ void ExtensionCmdQueue::Thread::_insert(const TExtensionCmd& rExtCmd)
m_queue.push( rExtCmd );
m_eInput = START;
- m_wakeup.set();
+ m_wakeup.notify_all();
}
@@ -1064,7 +1061,8 @@ ExtensionCmdQueue::ExtensionCmdQueue( DialogHelper * pDialogHelper,
}
ExtensionCmdQueue::~ExtensionCmdQueue() {
- stop();
+ m_thread->stop();
+ m_thread->join();
}
void ExtensionCmdQueue::addExtension( const OUString & extensionURL,
@@ -1100,11 +1098,6 @@ void ExtensionCmdQueue::syncRepositories( const uno::Reference< uno::XComponentC
dp_misc::syncRepositories( false, new ProgressCmdEnv( xContext, nullptr, "Extension Manager" ) );
}
-void ExtensionCmdQueue::stop()
-{
- m_thread->stop();
-}
-
bool ExtensionCmdQueue::isBusy()
{
return m_thread->isBusy();
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
index c88e1223f357..3703d1e8c52c 100644
--- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
@@ -75,11 +75,6 @@ public:
void checkForUpdates( std::vector< css::uno::Reference< css::deployment::XPackage > > && vList );
void acceptLicense( const css::uno::Reference< css::deployment::XPackage > &rPackage );
static void syncRepositories( const css::uno::Reference< css::uno::XComponentContext > & xContext );
- /**
- This call does not block. It signals the internal thread
- that it should install the remaining extensions and then terminate.
- */
- void stop();
bool isBusy();
private:
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
index f66c016ea6a7..7e8bb6a455eb 100644
--- a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
@@ -35,8 +35,10 @@
#include <com/sun/star/system/SystemShellExecute.hpp>
#include <cppuhelper/weakref.hxx>
#include <i18nlangtag/languagetag.hxx>
+#include <o3tl/safeint.hxx>
#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>
+#include <utility>
#include <vcl/event.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/svapp.hxx>
@@ -57,7 +59,7 @@ struct FindWeakRef
{
const uno::Reference<deployment::XPackage> m_extension;
- explicit FindWeakRef( uno::Reference<deployment::XPackage> const & ext): m_extension(ext) {}
+ explicit FindWeakRef( uno::Reference<deployment::XPackage> ext): m_extension(std::move(ext)) {}
bool operator () (uno::WeakReference< deployment::XPackage > const & ref);
};
@@ -146,10 +148,10 @@ void Entry_Impl::checkDependencies()
if ( e.Cause >>= depExc )
{
OUStringBuffer aMissingDep( DpResId( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
- for ( const auto& i : std::as_const(depExc.UnsatisfiedDependencies) )
+ for (const auto& i : depExc.UnsatisfiedDependencies)
{
- aMissingDep.append("\n");
- aMissingDep.append(dp_misc::Dependencies::getErrorText(i));
+ aMissingDep.append("\n"
+ + dp_misc::Dependencies::getErrorText(i));
}
aMissingDep.append("\n");
m_sErrorText = aMissingDep.makeStringAndClear();
@@ -218,8 +220,8 @@ void ExtensionBox_Impl::Init()
m_xRemoveListener = new ExtensionRemovedListener( this );
m_pLocale.reset( new lang::Locale( Application::GetSettings().GetLanguageTag().getLocale() ) );
- m_pCollator.reset( new CollatorWrapper( ::comphelper::getProcessComponentContext() ) );
- m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
+ m_oCollator.emplace( ::comphelper::getProcessComponentContext() );
+ m_oCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
}
ExtensionBox_Impl::~ExtensionBox_Impl()
@@ -239,7 +241,7 @@ ExtensionBox_Impl::~ExtensionBox_Impl()
m_xRemoveListener.clear();
m_pLocale.reset();
- m_pCollator.reset();
+ m_oCollator.reset();
}
sal_Int32 ExtensionBox_Impl::getItemCount() const
@@ -354,7 +356,7 @@ void ExtensionBox_Impl::selectEntry( const tools::Long nPos )
m_vEntries[ m_nActive ]->m_bActive = false;
}
- if ( ( nPos >= 0 ) && ( nPos < static_cast<tools::Long>(m_vEntries.size()) ) )
+ if ( ( nPos >= 0 ) && ( o3tl::make_unsigned(nPos) < m_vEntries.size() ) )
{
m_bHasActive = true;
m_nActive = nPos;
@@ -623,7 +625,7 @@ bool ExtensionBox_Impl::HandleCursorKey( sal_uInt16 nKeyCode )
if ( nSelect < 0 )
nSelect = 0;
- if ( nSelect >= static_cast<tools::Long>(m_vEntries.size()) )
+ if ( o3tl::make_unsigned(nSelect) >= m_vEntries.size() )
nSelect = m_vEntries.size() - 1;
selectEntry( nSelect );
@@ -732,7 +734,7 @@ bool ExtensionBox_Impl::MouseMove( const MouseEvent& rMEvt )
bool bOverHyperlink = false;
auto nPos = PointToPos( rMEvt.GetPosPixel() );
- if ( ( nPos >= 0 ) && ( nPos < static_cast<tools::Long>(m_vEntries.size()) ) )
+ if ( ( nPos >= 0 ) && ( o3tl::make_unsigned(nPos) < m_vEntries.size() ) )
{
const auto& rEntry = m_vEntries[nPos];
bOverHyperlink = !rEntry->m_sPublisher.isEmpty() && rEntry->m_aLinkRect.Contains(rMEvt.GetPosPixel());
@@ -749,7 +751,7 @@ bool ExtensionBox_Impl::MouseMove( const MouseEvent& rMEvt )
OUString ExtensionBox_Impl::RequestHelp(tools::Rectangle& rRect)
{
auto nPos = PointToPos( rRect.TopLeft() );
- if ( ( nPos >= 0 ) && ( nPos < static_cast<tools::Long>(m_vEntries.size()) ) )
+ if ( ( nPos >= 0 ) && ( o3tl::make_unsigned(nPos) < m_vEntries.size() ) )
{
const auto& rEntry = m_vEntries[nPos];
bool bOverHyperlink = !rEntry->m_sPublisher.isEmpty() && rEntry->m_aLinkRect.Contains(rRect);
@@ -774,7 +776,7 @@ bool ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
{
auto nPos = PointToPos( rMEvt.GetPosPixel() );
- if ( ( nPos >= 0 ) && ( nPos < static_cast<tools::Long>(m_vEntries.size()) ) )
+ if ( ( nPos >= 0 ) && ( o3tl::make_unsigned(nPos) < m_vEntries.size() ) )
{
const auto& rEntry = m_vEntries[nPos];
if (!rEntry->m_sPublisher.isEmpty() && rEntry->m_aLinkRect.Contains(rMEvt.GetPosPixel()))
@@ -824,7 +826,7 @@ bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl& rEntry, const tools::Lo
if ( nStart == nEnd )
{
- eCompare = rEntry->CompareTo( m_pCollator.get(), m_vEntries[ nStart ] );
+ eCompare = rEntry->CompareTo( &*m_oCollator, m_vEntries[ nStart ] );
if ( eCompare < 0 )
return false;
else if ( eCompare == 0 )
@@ -845,7 +847,7 @@ bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl& rEntry, const tools::Lo
}
const tools::Long nMid = nStart + ( ( nEnd - nStart ) / 2 );
- eCompare = rEntry->CompareTo( m_pCollator.get(), m_vEntries[ nMid ] );
+ eCompare = rEntry->CompareTo( &*m_oCollator, m_vEntries[ nMid ] );
if ( eCompare < 0 )
return FindEntryPos( rEntry, nStart, nMid-1, nPos );
@@ -866,12 +868,11 @@ bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl& rEntry, const tools::Lo
void ExtensionBox_Impl::cleanVecListenerAdded()
{
- m_vListenerAdded.erase(std::remove_if(m_vListenerAdded.begin(), m_vListenerAdded.end(),
+ std::erase_if(m_vListenerAdded,
[](const uno::WeakReference<deployment::XPackage>& rxListener) {
const uno::Reference<deployment::XPackage> hardRef(rxListener);
return !hardRef.is();
- }),
- m_vListenerAdded.end());
+ });
}
void ExtensionBox_Impl::addEventListenerOnce(
@@ -1106,6 +1107,7 @@ void ExtensionBox_Impl::checkEntries()
m_bHasActive = false;
}
m_vRemovedEntries.push_back(*iIndex);
+ (*iIndex)->m_xPackage->removeEventListener(m_xRemoveListener);
iIndex = m_vEntries.erase(iIndex);
}
}
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.hxx b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
index d706975dcdfd..cfc04f115d22 100644
--- a/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
@@ -33,6 +33,7 @@
#include <com/sun/star/deployment/XPackage.hpp>
#include <memory>
+#include <optional>
#include "dp_gui.h"
@@ -137,7 +138,7 @@ class ExtensionBox_Impl : public weld::CustomWidgetController
std::vector< TEntry_Impl > m_vRemovedEntries;
std::unique_ptr<css::lang::Locale> m_pLocale;
- std::unique_ptr<CollatorWrapper> m_pCollator;
+ std::optional<CollatorWrapper> m_oCollator;
//Holds weak references to extensions to which is we have added an XEventListener
std::vector< css::uno::WeakReference<
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
index 6d39433a8f27..8cf6623d9676 100644
--- a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <utility>
#include <vcl/svapp.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
@@ -31,7 +32,7 @@
#include <comphelper/propertysequence.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <osl/diagnose.h>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include "dp_gui_dialog2.hxx"
#include "dp_gui_extensioncmdqueue.hxx"
@@ -40,7 +41,7 @@
#include <dp_update.hxx>
constexpr OUStringLiteral USER_PACKAGE_MANAGER = u"user";
-constexpr OUStringLiteral SHARED_PACKAGE_MANAGER = u"shared";
+constexpr OUString SHARED_PACKAGE_MANAGER = u"shared"_ustr;
using namespace ::com::sun::star;
@@ -53,10 +54,10 @@ namespace dp_gui {
// TheExtensionManager
-TheExtensionManager::TheExtensionManager( const uno::Reference< awt::XWindow > &xParent,
+TheExtensionManager::TheExtensionManager( uno::Reference< awt::XWindow > xParent,
const uno::Reference< uno::XComponentContext > &xContext ) :
m_xContext( xContext ),
- m_xParent( xParent ),
+ m_xParent(std::move( xParent )),
m_bModified(false),
m_bExtMgrDialogExecuting(false)
{
@@ -157,7 +158,8 @@ void TheExtensionManager::SetText( const OUString &rTitle )
{
const SolarMutexGuard guard;
- getDialog()->set_title( rTitle );
+ if (weld::Window* pDialog = getDialog())
+ pDialog->set_title( rTitle );
}
@@ -165,7 +167,8 @@ void TheExtensionManager::ToTop()
{
const SolarMutexGuard guard;
- getDialog()->present();
+ if (weld::Window* pDialog = getDialog())
+ pDialog->present();
}
void TheExtensionManager::Close()
@@ -220,7 +223,7 @@ void TheExtensionManager::checkUpdates()
e.Context, anyEx );
}
- for ( auto const & i : std::as_const(xAllPackages) )
+ for (auto const& i : xAllPackages)
{
uno::Reference< deployment::XPackage > xPackage = dp_misc::getExtensionWithHighestVersion(i);
OSL_ASSERT(xPackage.is());
@@ -303,7 +306,7 @@ void TheExtensionManager::createPackageList()
e.Context, anyEx );
}
- for ( uno::Sequence< uno::Reference< deployment::XPackage > > const & xPackageList : std::as_const(xAllPackages) )
+ for (uno::Sequence<uno::Reference<deployment::XPackage>> const& xPackageList : xAllPackages)
{
for ( uno::Reference< deployment::XPackage > const & xPackage : xPackageList )
{
@@ -495,9 +498,12 @@ void TheExtensionManager::notifyTermination( ::lang::EventObject const & rEvt )
void TheExtensionManager::modified( ::lang::EventObject const & /*rEvt*/ )
{
m_bModified = true;
- getDialogHelper()->prepareChecking();
+ DialogHelper *pDialogHelper = getDialogHelper();
+ if (!pDialogHelper)
+ return;
+ pDialogHelper->prepareChecking();
createPackageList();
- getDialogHelper()->checkEntries();
+ pDialogHelper->checkEntries();
}
@@ -519,7 +525,7 @@ void TheExtensionManager::modified( ::lang::EventObject const & /*rEvt*/ )
if ( ! s_ExtMgr.is() )
{
OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
- s_ExtMgr = that;
+ s_ExtMgr = std::move(that);
}
if ( !extensionURL.isEmpty() )
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
index 914cc15d477c..13c329d6d142 100644
--- a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
@@ -59,7 +59,7 @@ private:
public:
static ::rtl::Reference<TheExtensionManager> s_ExtMgr;
- TheExtensionManager( const css::uno::Reference< css::awt::XWindow > &xParent,
+ TheExtensionManager( css::uno::Reference< css::awt::XWindow > xParent,
const css::uno::Reference< css::uno::XComponentContext > &xContext );
virtual ~TheExtensionManager() override;
diff --git a/desktop/source/deployment/gui/dp_gui_updatedata.hxx b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
index a3d82fa61965..efac4c587bc6 100644
--- a/desktop/source/deployment/gui/dp_gui_updatedata.hxx
+++ b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
@@ -21,6 +21,7 @@
#include <sal/config.h>
#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Reference.hxx>
+#include <utility>
namespace com::sun::star::deployment {
class XPackage;
@@ -34,8 +35,8 @@ namespace dp_gui {
struct UpdateData
{
- explicit UpdateData( css::uno::Reference< css::deployment::XPackage > const & aExt):
- bIsShared(false), aInstalledPackage(aExt) {};
+ explicit UpdateData( css::uno::Reference< css::deployment::XPackage > xExt):
+ bIsShared(false), aInstalledPackage(std::move(xExt)) {};
//When entries added to the listbox then there can be one for the user update and one
//for the shared update. However, both list entries will contain the same UpdateData.
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.cxx b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
index 26820c5ea97f..85786e63535c 100644
--- a/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
@@ -117,13 +117,13 @@ struct UpdateDialog::IgnoredUpdate {
OUString sExtensionID;
OUString sVersion;
- IgnoredUpdate( const OUString &rExtensionID, const OUString &rVersion );
+ IgnoredUpdate( OUString aExtensionID, OUString aVersion );
};
-UpdateDialog::IgnoredUpdate::IgnoredUpdate( const OUString &rExtensionID, const OUString &rVersion ):
- sExtensionID( rExtensionID ),
- sVersion( rVersion )
+UpdateDialog::IgnoredUpdate::IgnoredUpdate( OUString aExtensionID, OUString aVersion ):
+ sExtensionID(std::move( aExtensionID )),
+ sVersion(std::move( aVersion ))
{}
@@ -134,11 +134,11 @@ struct UpdateDialog::Index
sal_uInt16 m_nIndex;
OUString m_aName;
- Index( Kind theKind, sal_uInt16 nIndex, const OUString &rName ) :
+ Index( Kind theKind, sal_uInt16 nIndex, OUString aName ) :
m_eKind( theKind ),
m_bIgnored( false ),
m_nIndex( nIndex ),
- m_aName( rName ) {}
+ m_aName(std::move( aName )) {}
};
@@ -489,23 +489,23 @@ short UpdateDialog::run() {
IMPL_LINK(UpdateDialog, entryToggled, const weld::TreeView::iter_col&, rRowCol, void)
{
// error's can't be enabled
- const UpdateDialog::Index* p = reinterpret_cast<UpdateDialog::Index const *>(m_xUpdates->get_id(rRowCol.first).toInt64());
+ const UpdateDialog::Index* p = weld::fromId<UpdateDialog::Index const *>(m_xUpdates->get_id(rRowCol.first));
if (p->m_eKind == SPECIFIC_ERROR)
m_xUpdates->set_toggle(rRowCol.first, TRISTATE_FALSE);
enableOk();
}
-void UpdateDialog::insertItem(UpdateDialog::Index *pEntry, bool bEnabledCheckBox)
+void UpdateDialog::insertItem(const UpdateDialog::Index *pEntry, bool bEnabledCheckBox)
{
int nEntry = m_xUpdates->n_children();
m_xUpdates->append();
m_xUpdates->set_toggle(nEntry, bEnabledCheckBox ? TRISTATE_TRUE : TRISTATE_FALSE);
m_xUpdates->set_text(nEntry, pEntry->m_aName, 0);
- m_xUpdates->set_id(nEntry, OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ m_xUpdates->set_id(nEntry, weld::toId(pEntry));
}
-void UpdateDialog::addAdditional(UpdateDialog::Index * index, bool bEnabledCheckBox)
+void UpdateDialog::addAdditional(const UpdateDialog::Index * index, bool bEnabledCheckBox)
{
m_xAll->set_sensitive(true);
if (m_xAll->get_active())
@@ -658,20 +658,19 @@ void UpdateDialog::notifyMenubar( bool bPrepareOnly, bool bRecheckOnly )
for (sal_uInt16 i = 0, nItemCount = m_xUpdates->n_children(); i < nItemCount; ++i)
{
- UpdateDialog::Index const * p = reinterpret_cast< UpdateDialog::Index const * >(m_xUpdates->get_id(i).toInt64());
+ UpdateDialog::Index const * p = weld::fromId<UpdateDialog::Index const*>(m_xUpdates->get_id(i));
if ( p->m_eKind == ENABLED_UPDATE )
{
dp_gui::UpdateData aUpdData = m_enabledUpdates[ p->m_nIndex ];
dp_misc::DescriptionInfoset aInfoset( m_context, aUpdData.aUpdateInfo );
- uno::Sequence< OUString > aItem
+ aItemList.realloc(nCount + 1);
+ aItemList.getArray()[nCount] =
{
dp_misc::getIdentifier( aUpdData.aInstalledPackage ),
aInfoset.getVersion()
};
- aItemList.realloc( nCount + 1 );
- aItemList.getArray()[ nCount ] = aItem;
nCount += 1;
}
else
@@ -829,7 +828,7 @@ IMPL_LINK_NOARG(UpdateDialog, selectionHandler, weld::TreeView&, void)
const UpdateDialog::Index* p = nullptr;
if (nSelectedPos != -1)
- p = reinterpret_cast<UpdateDialog::Index const *>(m_xUpdates->get_id(nSelectedPos).toInt64());
+ p = weld::fromId<UpdateDialog::Index const*>(m_xUpdates->get_id(nSelectedPos));
if (p != nullptr)
{
sal_uInt16 pos = p->m_nIndex;
@@ -881,31 +880,25 @@ IMPL_LINK_NOARG(UpdateDialog, selectionHandler, weld::TreeView&, void)
m_noDependency = m_noDependency.replaceAt( nPos, sProductName.getLength(), utl::ConfigManager::getProductName() );
}
- b.append(m_noInstall);
- b.append(LF);
- b.append(m_noDependency);
+ b.append(m_noInstall + OUStringChar(LF) + m_noDependency);
for (sal_Int32 i = 0;
i < data.unsatisfiedDependencies.getLength(); ++i)
{
- b.append(LF);
- b.append(" ");
+ b.append(OUStringChar(LF) + " ");
// U+2003 EM SPACE would be better than two spaces,
// but some fonts do not contain it
b.append(
confineToParagraph(
data.unsatisfiedDependencies[i]));
}
- b.append(LF);
- b.append(" ");
- b.append(m_noDependencyCurVer);
+ b.append(OUStringChar(LF) + " " + m_noDependencyCurVer);
}
break;
}
case SPECIFIC_ERROR:
{
UpdateDialog::SpecificError & data = m_specificErrors[ pos ];
- b.append(m_failure);
- b.append(LF);
+ b.append(m_failure + OUStringChar(LF));
b.append( data.message.isEmpty() ? m_unknownError : data.message );
break;
}
@@ -941,7 +934,7 @@ IMPL_LINK_NOARG(UpdateDialog, allHandler, weld::Toggleable&, void)
for (sal_uInt16 i = m_xUpdates->n_children(); i != 0 ;)
{
i -= 1;
- UpdateDialog::Index const * p = reinterpret_cast< UpdateDialog::Index const * >( m_xUpdates->get_id(i).toInt64() );
+ UpdateDialog::Index const * p = weld::fromId<UpdateDialog::Index const*>(m_xUpdates->get_id(i));
if ( p->m_bIgnored || ( p->m_eKind != ENABLED_UPDATE ) )
{
m_xUpdates->remove(i);
@@ -976,8 +969,7 @@ IMPL_LINK_NOARG(UpdateDialog, okHandler, weld::Button&, void)
for (sal_uInt16 i = 0, nCount = m_xUpdates->n_children(); i < nCount; ++i)
{
UpdateDialog::Index const * p =
- reinterpret_cast< UpdateDialog::Index const * >(
- m_xUpdates->get_id(i).toInt64());
+ weld::fromId<UpdateDialog::Index const*>(m_xUpdates->get_id(i));
if (p->m_eKind == ENABLED_UPDATE && m_xUpdates->get_toggle(i) == TRISTATE_TRUE) {
m_updateData.push_back( m_enabledUpdates[ p->m_nIndex ] );
}
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.hxx b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
index 24728467debb..cbf376955d22 100644
--- a/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
@@ -96,8 +96,8 @@ private:
friend class CheckListBox;
- void insertItem(UpdateDialog::Index *pIndex, bool bEnableCheckBox);
- void addAdditional(UpdateDialog::Index *pIndex, bool bEnableCheckBox);
+ void insertItem(const UpdateDialog::Index *pIndex, bool bEnableCheckBox);
+ void addAdditional(const UpdateDialog::Index *pIndex, bool bEnableCheckBox);
bool isIgnoredUpdate( UpdateDialog::Index *pIndex );
void addEnabledUpdate( OUString const & name, dp_gui::UpdateData const & data );
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
index 4db98a876b05..0248a1537fa1 100644
--- a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
@@ -23,6 +23,7 @@
#include <sal/config.h>
#include <osl/file.hxx>
#include <cppuhelper/exc_hlp.hxx>
+#include <utility>
#include <vcl/svapp.hxx>
#include <cppuhelper/implbase.hxx>
@@ -102,8 +103,8 @@ class UpdateCommandEnv
css::uno::Reference< css::uno::XComponentContext > m_xContext;
public:
- UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > const & xCtx,
- ::rtl::Reference<UpdateInstallDialog::Thread>const & thread);
+ UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > xCtx,
+ ::rtl::Reference<UpdateInstallDialog::Thread> thread);
// XCommandEnvironment
virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
@@ -372,14 +373,11 @@ void UpdateInstallDialog::Thread::downloadExtensions()
{
if (nPos)
buf.append("\n");
- buf.append("Could not download ");
- buf.append(elem.first);
- buf.append(". ");
- buf.append(elem.second.Message);
+ buf.append("Could not download " + elem.first + ". " + elem.second.Message);
++nPos;
}
m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, updateData.aInstalledPackage->getDisplayName(),
- buf.makeStringAndClear());
+ buf);
}
}
@@ -441,7 +439,7 @@ void UpdateInstallDialog::Thread::installExtensions()
}
if (!updateData.aUpdateSource.is() && !updateData.sLocalURL.isEmpty())
{
- css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::makeAny(OUString("1")));
+ css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::Any(OUString("1")));
if (!updateData.bIsShared)
xExtension = m_dialog.getExtensionManager()->addExtension(
updateData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
@@ -458,7 +456,7 @@ void UpdateInstallDialog::Thread::installExtensions()
//add extension. Currently it contains only "SUPPRESS_LICENSE". So it could happen
//that a license is displayed when updating from the shared repository, although the
//shared extension was installed using "SUPPRESS_LICENSE".
- css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::makeAny(OUString("1")));
+ css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::Any(OUString("1")));
if (!updateData.bIsShared)
xExtension = m_dialog.getExtensionManager()->addExtension(
updateData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
@@ -578,10 +576,10 @@ bool UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, Update
return m_stop;
}
-UpdateCommandEnv::UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > const & xCtx,
- ::rtl::Reference<UpdateInstallDialog::Thread>const & thread)
- : m_installThread(thread),
- m_xContext(xCtx)
+UpdateCommandEnv::UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > xCtx,
+ ::rtl::Reference<UpdateInstallDialog::Thread> thread)
+ : m_installThread(std::move(thread)),
+ m_xContext(std::move(xCtx))
{
}
diff --git a/desktop/source/deployment/inc/dp_interact.h b/desktop/source/deployment/inc/dp_interact.h
index 645a3a80ba0d..6a041d99f179 100644
--- a/desktop/source/deployment/inc/dp_interact.h
+++ b/desktop/source/deployment/inc/dp_interact.h
@@ -24,6 +24,7 @@
#include <cppuhelper/implbase.hxx>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/task/XAbortChannel.hpp>
+#include <utility>
#include "dp_misc_api.hxx"
namespace dp_misc
@@ -37,7 +38,7 @@ inline void progressUpdate(
css::uno::Reference<css::ucb::XProgressHandler> xProgressHandler(
xCmdEnv->getProgressHandler() );
if (xProgressHandler.is()) {
- xProgressHandler->update( css::uno::makeAny(status) );
+ xProgressHandler->update( css::uno::Any(status) );
}
}
}
@@ -65,7 +66,7 @@ inline ProgressLevel::ProgressLevel(
if (xCmdEnv.is())
m_xProgressHandler = xCmdEnv->getProgressHandler();
if (m_xProgressHandler.is())
- m_xProgressHandler->push( css::uno::makeAny(status) );
+ m_xProgressHandler->push( css::uno::Any(status) );
}
@@ -79,7 +80,7 @@ inline ProgressLevel::~ProgressLevel()
inline void ProgressLevel::update( OUString const & status ) const
{
if (m_xProgressHandler.is())
- m_xProgressHandler->update( css::uno::makeAny(status) );
+ m_xProgressHandler->update( css::uno::Any(status) );
}
@@ -124,9 +125,9 @@ public:
const ::rtl::Reference<AbortChannel> m_abortChannel;
public:
Chain(
- ::rtl::Reference<AbortChannel> const & abortChannel,
+ ::rtl::Reference<AbortChannel> abortChannel,
css::uno::Reference<css::task::XAbortChannel> const & xNext )
- : m_abortChannel( abortChannel )
+ : m_abortChannel(std::move( abortChannel ))
{ if (m_abortChannel.is()) m_abortChannel->m_xNext = xNext; }
~Chain()
{ if (m_abortChannel.is()) m_abortChannel->m_xNext.clear(); }
diff --git a/desktop/source/deployment/inc/dp_platform.hxx b/desktop/source/deployment/inc/dp_platform.hxx
index 9547bc07df18..5e454700d276 100644
--- a/desktop/source/deployment/inc/dp_platform.hxx
+++ b/desktop/source/deployment/inc/dp_platform.hxx
@@ -29,7 +29,7 @@ namespace dp_misc
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString const& getPlatformString();
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
-bool platform_fits(OUString const& platform_string);
+bool platform_fits(std::u16string_view platform_string);
/** determines if the current platform corresponds to one of the platform strings.
diff --git a/desktop/source/deployment/inc/dp_ucb.h b/desktop/source/deployment/inc/dp_ucb.h
index 291b28b9b972..e72a2cce9332 100644
--- a/desktop/source/deployment/inc/dp_ucb.h
+++ b/desktop/source/deployment/inc/dp_ucb.h
@@ -80,7 +80,7 @@ std::vector<sal_Int8> readFile( ::ucbhelper::Content & ucb_content );
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
-bool readLine( OUString * res, OUString const & startingWith,
+bool readLine( OUString * res, std::u16string_view startingWith,
::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc );
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
diff --git a/desktop/source/deployment/inc/dp_update.hxx b/desktop/source/deployment/inc/dp_update.hxx
index 8dce9b583729..f673d2f66a95 100644
--- a/desktop/source/deployment/inc/dp_update.hxx
+++ b/desktop/source/deployment/inc/dp_update.hxx
@@ -60,7 +60,7 @@ UPDATE_SOURCE isUpdateUserExtension(
OUString const & userVersion,
OUString const & sharedVersion,
OUString const & bundledVersion,
- OUString const & onlineVersion);
+ std::u16string_view onlineVersion);
/* determine if an update is available which is installed in the
shared repository.
@@ -74,7 +74,7 @@ UPDATE_SOURCE isUpdateSharedExtension(
bool bReadOnlyShared,
OUString const & sharedVersion,
OUString const & bundledVersion,
- OUString const & onlineVersion);
+ std::u16string_view onlineVersion);
/* determines the extension with the highest identifier and returns it
diff --git a/desktop/source/deployment/inc/dp_version.hxx b/desktop/source/deployment/inc/dp_version.hxx
index 342e2bf8c737..2b7c8787bdc0 100644
--- a/desktop/source/deployment/inc/dp_version.hxx
+++ b/desktop/source/deployment/inc/dp_version.hxx
@@ -21,16 +21,16 @@
#include <sal/config.h>
-#include <rtl/ustring.hxx>
#include "dp_misc_api.hxx"
+#include <string_view>
namespace dp_misc {
enum Order { LESS, EQUAL, GREATER };
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Order compareVersions(
- OUString const & version1, OUString const & version2);
+ std::u16string_view version1, std::u16string_view version2);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/deployment/manager/dp_commandenvironments.cxx b/desktop/source/deployment/manager/dp_commandenvironments.cxx
index 755657a9d21e..2b98ff971908 100644
--- a/desktop/source/deployment/manager/dp_commandenvironments.cxx
+++ b/desktop/source/deployment/manager/dp_commandenvironments.cxx
@@ -24,8 +24,7 @@
#include <com/sun/star/deployment/DependencyException.hpp>
#include <com/sun/star/deployment/PlatformException.hpp>
#include <com/sun/star/task/XInteractionApprove.hpp>
-#include <com/sun/star/task/XInteractionHandler.hpp>
-#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <utility>
#include "dp_commandenvironments.hxx"
#include <osl/diagnose.h>
@@ -154,8 +153,8 @@ void TmpRepositoryCommandEnv::handle(
LicenseCommandEnv::LicenseCommandEnv(
css::uno::Reference< css::task::XInteractionHandler> const & handler,
bool bSuppressLicense,
- OUString const & repository):
- BaseCommandEnv(handler), m_repository(repository),
+ OUString repository):
+ BaseCommandEnv(handler), m_repository(std::move(repository)),
m_bSuppressLicense(bSuppressLicense)
{
}
diff --git a/desktop/source/deployment/manager/dp_commandenvironments.hxx b/desktop/source/deployment/manager/dp_commandenvironments.hxx
index 4251d081bcfd..6533d45b4fc3 100644
--- a/desktop/source/deployment/manager/dp_commandenvironments.hxx
+++ b/desktop/source/deployment/manager/dp_commandenvironments.hxx
@@ -88,7 +88,7 @@ public:
LicenseCommandEnv(
css::uno::Reference< css::task::XInteractionHandler> const & handler,
bool bSuppressLicense,
- OUString const & repository);
+ OUString repository);
// XInteractionHandler
virtual void SAL_CALL handle(
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx
index 3466a818b870..6c210101fcc0 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.cxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx
@@ -24,14 +24,12 @@
#include <cppuhelper/exc_hlp.hxx>
#include <rtl/bootstrap.hxx>
#include <com/sun/star/deployment/DeploymentException.hpp>
-#include <com/sun/star/deployment/XExtensionManager.hpp>
#include <com/sun/star/deployment/thePackageManagerFactory.hpp>
#include <com/sun/star/deployment/XPackageManager.hpp>
#include <com/sun/star/deployment/XPackage.hpp>
#include <com/sun/star/deployment/InstallException.hpp>
#include <com/sun/star/deployment/VersionException.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
-#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/Optional.hpp>
#include <com/sun/star/task/XInteractionApprove.hpp>
#include <com/sun/star/beans/Ambiguous.hpp>
@@ -39,8 +37,8 @@
#include <com/sun/star/ucb/CommandFailedException.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/io/XInputStream.hpp>
-#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <comphelper/sequence.hxx>
+#include <utility>
#include <xmlscript/xml_helper.hxx>
#include <osl/diagnose.h>
#include <dp_interact.h>
@@ -103,7 +101,7 @@ void writeLastModified(OUString & url, Reference<ucb::XCommandEnvironment> const
::rtl::Bootstrap::expandMacros(url);
::ucbhelper::Content ucbStamp(url, xCmdEnv, xContext);
dp_misc::erase_path( url, xCmdEnv );
- OString stamp("1" );
+ OString stamp("1"_ostr );
Reference<css::io::XInputStream> xData(
::xmlscript::createInputStream(
reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
@@ -125,9 +123,9 @@ class ExtensionRemoveGuard
public:
ExtensionRemoveGuard(){};
ExtensionRemoveGuard(
- css::uno::Reference<css::deployment::XPackage> const & extension,
- css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager):
- m_extension(extension), m_xPackageManager(xPackageManager) {}
+ css::uno::Reference<css::deployment::XPackage> extension,
+ css::uno::Reference<css::deployment::XPackageManager> xPackageManager):
+ m_extension(std::move(extension)), m_xPackageManager(std::move(xPackageManager)) {}
~ExtensionRemoveGuard();
void set(css::uno::Reference<css::deployment::XPackage> const & extension,
@@ -295,7 +293,7 @@ std::vector<Reference<css::deployment::XPackage> >
std::vector<Reference<css::deployment::XPackage> > extensionList;
Reference<css::deployment::XPackageManager> lRepos[] = {
getUserRepository(), getSharedRepository(), getBundledRepository() };
- for (int i(0); i != SAL_N_ELEMENTS(lRepos); ++i)
+ for (std::size_t i(0); i != std::size(lRepos); ++i)
{
Reference<css::deployment::XPackage> xPackage;
try
@@ -626,7 +624,7 @@ Reference<css::deployment::XPackage> ExtensionManager::addExtension(
static_cast<cppu::OWeakObject*>(this), 0);
//We must make sure that the xTmpExtension is not create twice, because this
//would remove the first one.
- ::osl::MutexGuard addGuard(m_addMutex);
+ std::unique_lock addGuard(m_addMutex);
Reference<css::deployment::XPackageManager> xTmpRepository(getTmpRepository());
// make sure xTmpRepository is alive as long as xTmpExtension is; as
diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx
index 0e08314c36f6..a70f4fbd2e26 100644
--- a/desktop/source/deployment/manager/dp_extensionmanager.hxx
+++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx
@@ -28,7 +28,7 @@
#include <com/sun/star/deployment/XPackageManagerFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
-#include <osl/mutex.hxx>
+#include <mutex>
#include <vector>
#include <unordered_map>
@@ -146,7 +146,7 @@ private:
css::uno::Reference<css::deployment::XPackageManagerFactory> m_xPackageManagerFactory;
//only to be used within addExtension
- ::osl::Mutex m_addMutex;
+ std::mutex m_addMutex;
/* contains the names of all repositories (except tmp) in order of there
priority. That is, the first element is "user" followed by "shared" and
then "bundled"
diff --git a/desktop/source/deployment/manager/dp_informationprovider.cxx b/desktop/source/deployment/manager/dp_informationprovider.cxx
index 1e7beea34a05..5b6d6a92b947 100644
--- a/desktop/source/deployment/manager/dp_informationprovider.cxx
+++ b/desktop/source/deployment/manager/dp_informationprovider.cxx
@@ -36,7 +36,7 @@
#include <com/sun/star/uno/Reference.hxx>
#include <osl/diagnose.h>
#include <rtl/ustring.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <ucbhelper/content.hxx>
#include <dp_dependencies.hxx>
diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx
index 2f0cecc470fa..d882b77bafa3 100644
--- a/desktop/source/deployment/manager/dp_manager.cxx
+++ b/desktop/source/deployment/manager/dp_manager.cxx
@@ -34,13 +34,14 @@
#include <rtl/bootstrap.hxx>
#include <sal/log.hxx>
#include <tools/urlobj.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <osl/diagnose.h>
#include <osl/file.hxx>
#include <osl/security.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <comphelper/logging.hxx>
#include <comphelper/sequence.hxx>
+#include <utility>
#include <xmlscript/xml_helper.hxx>
#include <svl/inettype.hxx>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
@@ -85,7 +86,7 @@ namespace {
struct MatchTempDir
{
OUString m_str;
- explicit MatchTempDir( OUString const & str ) : m_str( str ) {}
+ explicit MatchTempDir( OUString str ) : m_str(std::move( str )) {}
bool operator () ( ActivePackages::Entries::value_type const & v ) const {
return v.second.temporaryName.equalsIgnoreAsciiCase( m_str );
}
@@ -250,7 +251,7 @@ void PackageManagerImpl::initActivationLayer(
ucbhelper::Content remFileContent(
url + "removed", Reference<XCommandEnvironment>(), m_xComponentContext);
std::vector<sal_Int8> data = dp_misc::readFile(remFileContent);
- OString osData(reinterpret_cast<const char*>(data.data()),
+ std::string_view osData(reinterpret_cast<const char*>(data.data()),
data.size());
OUString sData = OStringToOUString(
osData, RTL_TEXTENCODING_UTF8);
@@ -607,9 +608,7 @@ OUString PackageManagerImpl::insertToActivationLayer(
Reference<XCommandEnvironment> xCmdEnv(
sourceContent.getCommandEnvironment() );
- OUString baseDir(m_activePackages_expanded);
- ::utl::TempFile aTemp(&baseDir, false);
- OUString tempEntry = aTemp.GetURL();
+ OUString tempEntry = ::utl::CreateTempURL(&m_activePackages_expanded, false);
tempEntry = tempEntry.copy(tempEntry.lastIndexOf('/') + 1);
OUString destFolder = makeURL( m_activePackages, tempEntry) + "_";
@@ -792,7 +791,7 @@ Reference<deployment::XPackage> PackageManagerImpl::addPackage(
{
OUString const id = dp_misc::getIdentifier( xPackage );
- ::osl::MutexGuard g(m_addMutex);
+ std::unique_lock g(m_addMutex);
if (isInstalled(xPackage))
{
//Do not guard the complete function with the getMutex
@@ -942,17 +941,16 @@ void PackageManagerImpl::removePackage(
OUString PackageManagerImpl::getDeployPath( ActivePackages::Data const & data )
{
- OUStringBuffer buf;
- buf.append( data.temporaryName );
+ OUStringBuffer buf( data.temporaryName );
//The bundled extensions are not contained in an additional folder
//with a unique name. data.temporaryName contains already the
//UTF8 encoded folder name. See PackageManagerImpl::synchronize
if (m_context != "bundled")
{
- buf.append( "_/" );
- buf.append( ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
- rtl_UriEncodeIgnoreEscapes,
- RTL_TEXTENCODING_UTF8 ) );
+ buf.append( "_/"
+ + ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
}
return makeURL( m_activePackages, buf.makeStringAndClear() );
}
@@ -983,7 +981,7 @@ Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
INetContentTypeParameterList params;
if (INetContentTypes::parse( data.mediaType, type, subType, &params ))
{
- auto const iter = params.find(OString("platform"));
+ auto const iter = params.find("platform"_ostr);
if (iter != params.end() && !platform_fits(iter->second.m_sValue))
throw lang::IllegalArgumentException(
DpResId(RID_STR_NO_SUCH_PACKAGE) + id,
@@ -1202,7 +1200,7 @@ bool PackageManagerImpl::synchronizeRemovedExtensions(
//shared repository including the temporary name
OUString url = makeURL(m_activePackages, elem.second.temporaryName);
if (bShared)
- url = makeURLAppendSysPathSegment( url + "_", elem.second.fileName);
+ url = makeURLAppendSysPathSegment( Concat2View(url + "_"), elem.second.fileName);
bool bRemoved = false;
//Check if the URL to the extension is still the same
@@ -1448,7 +1446,7 @@ Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWit
//Prepare the URL to the extension
OUString url = makeURL(m_activePackages, elem.second.temporaryName);
if (bShared)
- url = makeURLAppendSysPathSegment( url + "_", elem.second.fileName);
+ url = makeURLAppendSysPathSegment( Concat2View(url + "_"), elem.second.fileName);
Reference<deployment::XPackage> p = m_xRegistry->bindPackage(
url, OUString(), false, OUString(), xCmdEnv );
diff --git a/desktop/source/deployment/manager/dp_manager.h b/desktop/source/deployment/manager/dp_manager.h
index 56a48420e355..dce57d418e3f 100644
--- a/desktop/source/deployment/manager/dp_manager.h
+++ b/desktop/source/deployment/manager/dp_manager.h
@@ -27,7 +27,9 @@
#include <com/sun/star/deployment/XPackageRegistry.hpp>
#include <com/sun/star/deployment/XPackageManager.hpp>
#include <memory>
+#include <mutex>
#include <string_view>
+#include <utility>
namespace dp_manager {
@@ -48,7 +50,7 @@ class PackageManagerImpl final : private cppu::BaseMutex, public t_pm_helper
OUString m_activePackages_expanded;
std::unique_ptr< ActivePackages > m_activePackagesDB;
//This mutex is only used for synchronization in addPackage
- ::osl::Mutex m_addMutex;
+ std::mutex m_addMutex;
css::uno::Reference<css::ucb::XProgressHandler> m_xLogFile;
inline void logIntern( css::uno::Any const & status );
void fireModified();
@@ -116,11 +118,10 @@ class PackageManagerImpl final : private cppu::BaseMutex, public t_pm_helper
virtual ~PackageManagerImpl() override;
PackageManagerImpl(
- css::uno::Reference<css::uno::XComponentContext>
- const & xComponentContext, OUString const & context )
+ css::uno::Reference<css::uno::XComponentContext> xComponentContext, OUString context )
: t_pm_helper( m_aMutex ),
- m_xComponentContext( xComponentContext ),
- m_context( context ),
+ m_xComponentContext(std::move( xComponentContext )),
+ m_context(std::move( context )),
m_readOnly( true )
{}
diff --git a/desktop/source/deployment/manager/dp_properties.cxx b/desktop/source/deployment/manager/dp_properties.cxx
index b0d2245e8fde..6dc1fff30351 100644
--- a/desktop/source/deployment/manager/dp_properties.cxx
+++ b/desktop/source/deployment/manager/dp_properties.cxx
@@ -33,7 +33,7 @@ namespace uno = com::sun::star::uno;
using ::com::sun::star::uno::Reference;
-constexpr OUStringLiteral PROP_SUPPRESS_LICENSE = u"SUPPRESS_LICENSE";
+constexpr OUString PROP_SUPPRESS_LICENSE = u"SUPPRESS_LICENSE"_ustr;
constexpr OUStringLiteral PROP_EXTENSION_UPDATE = u"EXTENSION_UPDATE";
namespace dp_manager {
diff --git a/desktop/source/deployment/misc/dp_dependencies.cxx b/desktop/source/deployment/misc/dp_dependencies.cxx
index e187a69746f1..eea3cfba9cde 100644
--- a/desktop/source/deployment/misc/dp_dependencies.cxx
+++ b/desktop/source/deployment/misc/dp_dependencies.cxx
@@ -43,14 +43,14 @@ namespace {
char const namespaceLibreOffice[] =
"http://libreoffice.org/extensions/description/2011";
-constexpr OUStringLiteral namespaceOpenOfficeOrg =
- u"http://openoffice.org/extensions/description/2006";
+constexpr OUString namespaceOpenOfficeOrg =
+ u"http://openoffice.org/extensions/description/2006"_ustr;
char const minimalVersionLibreOffice[] = "LibreOffice-minimal-version";
char const maximalVersionLibreOffice[] = "LibreOffice-maximal-version";
-constexpr OUStringLiteral minimalVersionOpenOfficeOrg =
- u"OpenOffice.org-minimal-version";
+constexpr OUString minimalVersionOpenOfficeOrg =
+ u"OpenOffice.org-minimal-version"_ustr;
char const maximalVersionOpenOfficeOrg[] =
"OpenOffice.org-maximal-version";
@@ -73,13 +73,13 @@ OUString getReferenceOpenOfficeOrgMajorMinor() {
}
bool satisfiesMinimalVersion(
- OUString const & actual, OUString const & specified)
+ std::u16string_view actual, std::u16string_view specified)
{
return dp_misc::compareVersions(actual, specified) != dp_misc::LESS;
}
bool satisfiesMaximalVersion(
- OUString const & actual, OUString const & specified)
+ std::u16string_view actual, std::u16string_view specified)
{
return dp_misc::compareVersions(actual, specified) != dp_misc::GREATER;
}
diff --git a/desktop/source/deployment/misc/dp_descriptioninfoset.cxx b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
index 00315cb3bad5..00b32c04f2c4 100644
--- a/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
+++ b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
@@ -56,6 +56,7 @@
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <ucbhelper/content.hxx>
+#include <o3tl/string_view.hxx>
namespace {
@@ -473,7 +474,7 @@ css::uno::Sequence< OUString > DescriptionInfoset::getSupportedPlatforms() const
sal_Int32 nIndex = 0;
do
{
- const OUString aToken = value.getToken( 0, ',', nIndex ).trim();
+ const OUString aToken( o3tl::trim(o3tl::getToken(value, 0, ',', nIndex )) );
if (!aToken.isEmpty())
vec.push_back(aToken);
@@ -651,13 +652,13 @@ DescriptionInfoset::getSimpleLicenseAttributes() const
::std::optional< OUString > suppressOnUpdate = getOptionalValue("/desc:description/desc:registration/desc:simple-license/@suppress-on-update");
if (suppressOnUpdate)
- attributes.suppressOnUpdate = (*suppressOnUpdate).trim().equalsIgnoreAsciiCase("true");
+ attributes.suppressOnUpdate = o3tl::equalsIgnoreAsciiCase(o3tl::trim(*suppressOnUpdate), u"true");
else
attributes.suppressOnUpdate = false;
::std::optional< OUString > suppressIfRequired = getOptionalValue("/desc:description/desc:registration/desc:simple-license/@suppress-if-required");
if (suppressIfRequired)
- attributes.suppressIfRequired = (*suppressIfRequired).trim().equalsIgnoreAsciiCase("true");
+ attributes.suppressIfRequired = o3tl::equalsIgnoreAsciiCase(o3tl::trim(*suppressIfRequired), u"true");
else
attributes.suppressIfRequired = false;
diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx
index f4437711dab5..6011d15cb11d 100644
--- a/desktop/source/deployment/misc/dp_misc.cxx
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -19,11 +19,11 @@
#include <config_folders.h>
#include <config_features.h>
-#include <chrono>
#include <dp_misc.h>
#include <dp_interact.h>
#include <dp_shared.hxx>
+#include <o3tl/string_view.hxx>
#include <rtl/uri.hxx>
#include <rtl/digest.h>
#include <rtl/random.h>
@@ -45,6 +45,7 @@
#include <com/sun/star/task/OfficeRestartManager.hpp>
#include <memory>
#include <string_view>
+#include <thread>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <salhelper/linkhelper.hxx>
@@ -60,15 +61,17 @@ using namespace ::com::sun::star::uno;
namespace dp_misc {
namespace {
-struct UnoRc : public rtl::StaticWithInit<
- std::shared_ptr<rtl::Bootstrap>, UnoRc> {
- std::shared_ptr<rtl::Bootstrap> operator () () {
- OUString unorc( "$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("louno") );
- ::rtl::Bootstrap::expandMacros( unorc );
- auto ret = std::make_shared<::rtl::Bootstrap>( unorc );
- OSL_ASSERT( ret->getHandle() != nullptr );
- return ret;
- }
+std::shared_ptr<rtl::Bootstrap> & UnoRc()
+{
+ static std::shared_ptr<rtl::Bootstrap> theRc = []()
+ {
+ OUString unorc( "$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("louno") );
+ ::rtl::Bootstrap::expandMacros( unorc );
+ auto ret = std::make_shared<::rtl::Bootstrap>( unorc );
+ OSL_ASSERT( ret->getHandle() != nullptr );
+ return ret;
+ }();
+ return theRc;
};
OUString generateOfficePipeId()
@@ -100,8 +103,7 @@ OUString generateOfficePipeId()
// create hex-value string from the MD5 value to keep
// the string size minimal
- OUStringBuffer buf;
- buf.append( "SingleOfficeIPC_" );
+ OUStringBuffer buf( "SingleOfficeIPC_" );
for ( sal_uInt32 i = 0; i < md5_key_len; ++i ) {
buf.append( static_cast<sal_Int32>(md5_buf[ i ]), 0x10 );
}
@@ -224,12 +226,12 @@ bool needToSyncRepository(std::u16string_view name)
namespace {
-OUString encodeForRcFile( OUString const & str )
+OUString encodeForRcFile( std::u16string_view str )
{
// escape $\{} (=> rtl bootstrap files)
OUStringBuffer buf(64);
- sal_Int32 pos = 0;
- const sal_Int32 len = str.getLength();
+ size_t pos = 0;
+ const size_t len = str.size();
for ( ; pos < len; ++pos ) {
sal_Unicode c = str[ pos ];
switch (c) {
@@ -247,11 +249,11 @@ OUString encodeForRcFile( OUString const & str )
}
-OUString makeURL( OUString const & baseURL, OUString const & relPath_ )
+OUString makeURL( std::u16string_view baseURL, OUString const & relPath_ )
{
OUStringBuffer buf(128);
- if (baseURL.getLength() > 1 && baseURL[ baseURL.getLength() - 1 ] == '/')
- buf.append( baseURL.subView(0, baseURL.getLength() - 1) );
+ if (baseURL.size() > 1 && baseURL[ baseURL.size() - 1 ] == '/')
+ buf.append( baseURL.substr(0, baseURL.size() - 1) );
else
buf.append( baseURL );
OUString relPath(relPath_);
@@ -260,7 +262,7 @@ OUString makeURL( OUString const & baseURL, OUString const & relPath_ )
if (!relPath.isEmpty())
{
buf.append( '/' );
- if (baseURL.match( "vnd.sun.star.expand:" )) {
+ if (o3tl::starts_with(baseURL, u"vnd.sun.star.expand:" )) {
// encode for macro expansion: relPath is supposed to have no
// macros, so encode $, {} \ (bootstrap mimic)
relPath = encodeForRcFile(relPath);
@@ -277,7 +279,7 @@ OUString makeURL( OUString const & baseURL, OUString const & relPath_ )
return buf.makeStringAndClear();
}
-OUString makeURLAppendSysPathSegment( OUString const & baseURL, OUString const & segment )
+OUString makeURLAppendSysPathSegment( std::u16string_view baseURL, OUString const & segment )
{
OSL_ASSERT(segment.indexOf(u'/') == -1);
@@ -291,16 +293,14 @@ OUString makeURLAppendSysPathSegment( OUString const & baseURL, OUString const &
OUString expandUnoRcTerm( OUString const & term_ )
{
OUString term(term_);
- UnoRc::get()->expandMacrosFrom( term );
+ UnoRc()->expandMacrosFrom( term );
return term;
}
OUString makeRcTerm( OUString const & url )
{
OSL_ASSERT( url.match( "vnd.sun.star.expand:" ));
- if (url.match( "vnd.sun.star.expand:" )) {
- // cut protocol:
- OUString rcterm( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
+ if (OUString rcterm; url.startsWithIgnoreAsciiCase("vnd.sun.star.expand:", &rcterm)) {
// decode uric class chars:
rcterm = ::rtl::Uri::decode(
rcterm, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
@@ -313,14 +313,12 @@ OUString makeRcTerm( OUString const & url )
OUString expandUnoRcUrl( OUString const & url )
{
- if (url.match( "vnd.sun.star.expand:" )) {
- // cut protocol:
- OUString rcurl( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
+ if (OUString rcurl; url.startsWithIgnoreAsciiCase("vnd.sun.star.expand:", &rcurl)) {
// decode uric class chars:
rcurl = ::rtl::Uri::decode(
rcurl, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
// expand macro string:
- UnoRc::get()->expandMacrosFrom( rcurl );
+ UnoRc()->expandMacrosFrom( rcurl );
return rcurl;
}
else {
@@ -416,7 +414,7 @@ OUString generateRandomPipeId()
throw RuntimeException( "cannot create random pool!?", nullptr );
sal_uInt8 bytes[ 32 ];
if (rtl_random_getBytes(
- s_hPool, bytes, SAL_N_ELEMENTS(bytes) ) != rtl_Random_E_None) {
+ s_hPool, bytes, std::size(bytes) ) != rtl_Random_E_None) {
throw RuntimeException( "random pool error!?", nullptr );
}
OUStringBuffer buf;
@@ -446,7 +444,7 @@ Reference<XInterface> resolveUnoURL(
catch (const connection::NoConnectException &) {
if (i < 40)
{
- ::osl::Thread::wait( std::chrono::milliseconds(500) );
+ std::this_thread::sleep_for( std::chrono::milliseconds(500) );
}
else throw;
}
@@ -513,7 +511,9 @@ void syncRepositories(
Reference<task::XAbortChannel>(), xCmdEnv);
}
}
-#if !HAVE_FEATURE_MACOSX_SANDBOX
+#if HAVE_FEATURE_MACOSX_SANDBOX
+ (void) bModified;
+#else
if (bModified && !comphelper::LibreOfficeKit::isActive())
{
Reference<task::XRestartManager> restarter(task::OfficeRestartManager::get(comphelper::getProcessComponentContext()));
diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx
index 79fb78c0b9ba..aeab3e567051 100644
--- a/desktop/source/deployment/misc/dp_platform.cxx
+++ b/desktop/source/deployment/misc/dp_platform.cxx
@@ -20,9 +20,9 @@
#include <dp_platform.hxx>
#include <rtl/ustring.hxx>
-#include <rtl/instance.hxx>
#include <rtl/bootstrap.hxx>
#include <osl/diagnose.h>
+#include <o3tl/string_view.hxx>
constexpr OUStringLiteral PLATFORM_ALL = u"all";
@@ -31,36 +31,39 @@ namespace dp_misc
{
namespace
{
- struct StrOperatingSystem :
- public rtl::StaticWithInit<OUString, StrOperatingSystem> {
- OUString operator () () {
+ const OUString & StrOperatingSystem()
+ {
+ static const OUString theOS = []()
+ {
OUString os( "$_OS" );
::rtl::Bootstrap::expandMacros( os );
return os;
- }
+ }();
+ return theOS;
};
- struct StrCPU :
- public rtl::StaticWithInit<OUString, StrCPU> {
- OUString operator () () {
+ const OUString & StrCPU()
+ {
+ static const OUString theCPU = []()
+ {
OUString arch( "$_ARCH" );
::rtl::Bootstrap::expandMacros( arch );
return arch;
- }
+ }();
+ return theCPU;
};
- struct StrPlatform : public rtl::StaticWithInit<
- OUString, StrPlatform> {
- OUString operator () () {
- return StrOperatingSystem::get() + "_" + StrCPU::get();
- }
+ const OUString & StrPlatform()
+ {
+ static const OUString thePlatform = StrOperatingSystem() + "_" + StrCPU();
+ return thePlatform;
};
bool checkOSandCPU(std::u16string_view os, std::u16string_view cpu)
{
- return (os == StrOperatingSystem::get())
- && (cpu == StrCPU::get());
+ return (os == StrOperatingSystem())
+ && (cpu == StrCPU());
}
bool isPlatformSupported( std::u16string_view token )
@@ -80,8 +83,6 @@ namespace
ret = checkOSandCPU(u"Solaris", u"SPARC64");
else if (token == u"solaris_x86")
ret = checkOSandCPU(u"Solaris", u"x86");
- else if (token == u"aix_powerpc")
- ret = checkOSandCPU(u"AIX", u"PowerPC");
else if (token == u"macosx_aarch64")
ret = checkOSandCPU(u"MacOSX", u"AARCH64");
else if (token == u"macosx_x86_64")
@@ -116,8 +117,6 @@ namespace
ret = checkOSandCPU(u"Linux", u"IA64");
else if (token == u"linux_m68k")
ret = checkOSandCPU(u"Linux", u"M68K");
- else if (token == u"linux_s390")
- ret = checkOSandCPU(u"Linux", u"S390");
else if (token == u"linux_s390x")
ret = checkOSandCPU(u"Linux", u"S390x");
else if (token == u"linux_hppa")
@@ -126,6 +125,10 @@ namespace
ret = checkOSandCPU(u"Linux", u"ALPHA");
else if (token == u"linux_aarch64")
ret = checkOSandCPU(u"Linux", u"AARCH64");
+ else if (token == u"linux_riscv64")
+ ret = checkOSandCPU(u"Linux", u"RISCV64");
+ else if (token == u"linux_loongarch64")
+ ret = checkOSandCPU(u"Linux", u"LOONGARCH64");
else if (token == u"freebsd_x86")
ret = checkOSandCPU(u"FreeBSD", u"x86");
else if (token == u"freebsd_x86_64")
@@ -164,20 +167,20 @@ namespace
OUString const & getPlatformString()
{
- return StrPlatform::get();
+ return StrPlatform();
}
-bool platform_fits( OUString const & platform_string )
+bool platform_fits( std::u16string_view platform_string )
{
sal_Int32 index = 0;
for (;;)
{
- const OUString token(
- platform_string.getToken( 0, ',', index ).trim() );
+ const std::u16string_view token(
+ o3tl::trim(o3tl::getToken(platform_string, 0, ',', index )) );
// check if this platform:
- if (token.equalsIgnoreAsciiCase( StrPlatform::get() ) ||
- (token.indexOf( '_' ) < 0 && /* check OS part only */
- token.equalsIgnoreAsciiCase( StrOperatingSystem::get() )))
+ if (o3tl::equalsIgnoreAsciiCase( token, StrPlatform() ) ||
+ (token.find( '_' ) == std::u16string_view::npos && /* check OS part only */
+ o3tl::equalsIgnoreAsciiCase( token, StrOperatingSystem() )))
{
return true;
}
diff --git a/desktop/source/deployment/misc/dp_resource.cxx b/desktop/source/deployment/misc/dp_resource.cxx
index 682c90e52458..30caef8d9a7d 100644
--- a/desktop/source/deployment/misc/dp_resource.cxx
+++ b/desktop/source/deployment/misc/dp_resource.cxx
@@ -22,7 +22,6 @@
#include <i18nlangtag/languagetag.hxx>
using namespace ::com::sun::star;
-using namespace ::com::sun::star::uno;
namespace dp_misc
{
diff --git a/desktop/source/deployment/misc/dp_ucb.cxx b/desktop/source/deployment/misc/dp_ucb.cxx
index 28f4192eeca6..5ca42f31aeac 100644
--- a/desktop/source/deployment/misc/dp_ucb.cxx
+++ b/desktop/source/deployment/misc/dp_ucb.cxx
@@ -197,7 +197,7 @@ std::vector<sal_Int8> readFile( ::ucbhelper::Content & ucb_content )
}
-bool readLine( OUString * res, OUString const & startingWith,
+bool readLine( OUString * res, std::u16string_view startingWith,
::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc )
{
// read whole file:
@@ -211,7 +211,7 @@ bool readLine( OUString * res, OUString const & startingWith,
{
OUStringBuffer buf;
sal_Int32 start = pos;
- pos += startingWith.getLength();
+ pos += startingWith.size();
for (;;)
{
pos = file.indexOf( LF, pos );
diff --git a/desktop/source/deployment/misc/dp_update.cxx b/desktop/source/deployment/misc/dp_update.cxx
index 7116be42bf44..650d648e8a3c 100644
--- a/desktop/source/deployment/misc/dp_update.cxx
+++ b/desktop/source/deployment/misc/dp_update.cxx
@@ -41,7 +41,7 @@ int determineHighestVersion(
OUString const & userVersion,
OUString const & sharedVersion,
OUString const & bundledVersion,
- OUString const & onlineVersion)
+ std::u16string_view onlineVersion)
{
int index = 0;
OUString greatest = userVersion;
@@ -236,7 +236,7 @@ UPDATE_SOURCE isUpdateUserExtension(
OUString const & userVersion,
OUString const & sharedVersion,
OUString const & bundledVersion,
- OUString const & onlineVersion)
+ std::u16string_view onlineVersion)
{
UPDATE_SOURCE retVal = UPDATE_SOURCE_NONE;
if (bReadOnlyShared)
@@ -285,7 +285,7 @@ UPDATE_SOURCE isUpdateSharedExtension(
bool bReadOnlyShared,
OUString const & sharedVersion,
OUString const & bundledVersion,
- OUString const & onlineVersion)
+ std::u16string_view onlineVersion)
{
if (bReadOnlyShared)
return UPDATE_SOURCE_NONE;
diff --git a/desktop/source/deployment/misc/dp_version.cxx b/desktop/source/deployment/misc/dp_version.cxx
index 703045ddebb1..6f918068541a 100644
--- a/desktop/source/deployment/misc/dp_version.cxx
+++ b/desktop/source/deployment/misc/dp_version.cxx
@@ -20,18 +20,18 @@
#include <sal/config.h>
-#include <rtl/ustring.hxx>
+#include <o3tl/string_view.hxx>
#include <dp_version.hxx>
namespace {
-OUString getElement(OUString const & version, ::sal_Int32 * index)
+std::u16string_view getElement(std::u16string_view version, std::size_t * index)
{
- while (*index < version.getLength() && version[*index] == '0') {
+ while (*index < version.size() && version[*index] == '0') {
++*index;
}
- return version.getToken(0, '.', *index);
+ return o3tl::getToken(version, u'.', *index);
}
}
@@ -39,14 +39,14 @@ OUString getElement(OUString const & version, ::sal_Int32 * index)
namespace dp_misc {
::dp_misc::Order compareVersions(
- OUString const & version1, OUString const & version2)
+ std::u16string_view version1, std::u16string_view version2)
{
- for (::sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0;) {
- OUString e1(i1 >= 0 ? getElement(version1, &i1) : OUString());
- OUString e2(i2 >= 0 ? getElement(version2, &i2) : OUString());
- if (e1.getLength() < e2.getLength()) {
+ for (size_t i1 = 0, i2 = 0; i1 != std::u16string_view::npos || i2 != std::u16string_view::npos;) {
+ std::u16string_view e1(i1 != std::u16string_view::npos ? getElement(version1, &i1) : std::u16string_view());
+ std::u16string_view e2(i2 != std::u16string_view::npos ? getElement(version2, &i2) : std::u16string_view());
+ if (e1.size() < e2.size()) {
return ::dp_misc::LESS;
- } else if (e1.getLength() > e2.getLength()) {
+ } else if (e1.size() > e2.size()) {
return ::dp_misc::GREATER;
} else if (e1 < e2) {
return ::dp_misc::LESS;
diff --git a/desktop/source/deployment/misc/lockfile.cxx b/desktop/source/deployment/misc/lockfile.cxx
index 206da8286d76..1a87e8bc0f6f 100644
--- a/desktop/source/deployment/misc/lockfile.cxx
+++ b/desktop/source/deployment/misc/lockfile.cxx
@@ -67,7 +67,7 @@ static OString impl_getHostname()
aHost = OString( pHostName );
}
else
- aHost = OString("UNKNOWN");
+ aHost = "UNKNOWN"_ostr;
#endif
return aHost;
@@ -91,7 +91,9 @@ namespace desktop {
time_t t = time(nullptr);
for (int i = 0; i<nIdBytes; i++) {
int tmpByte = comphelper::rng::uniform_int_distribution(0, 0xFF);
+ SAL_WNODEPRECATED_DECLARATIONS_PUSH // sprintf (macOS 13 SDK)
sprintf( tmpId+i*2, "%02X", tmpByte );
+ SAL_WNODEPRECATED_DECLARATIONS_POP
}
tmpId[nIdBytes*2]=0x00;
m_aId = OUString::createFromAscii( tmpId );
@@ -151,13 +153,13 @@ namespace desktop {
// to assume that it is a stale lockfile which can be overwritten
OUString aLockname = m_aLockname;
Config aConfig(aLockname);
- aConfig.SetGroup(LOCKFILE_GROUP);
- OString aIPCserver = aConfig.ReadKey( LOCKFILE_IPCKEY );
+ aConfig.SetGroup(LOCKFILE_GROUP ""_ostr);
+ OString aIPCserver = aConfig.ReadKey( LOCKFILE_IPCKEY ""_ostr );
if (!aIPCserver.equalsIgnoreAsciiCase("true"))
return false;
- OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY );
- OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY );
+ OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY ""_ostr );
+ OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY ""_ostr );
// lockfile from same host?
OString myHost( impl_getHostname() );
@@ -177,7 +179,7 @@ namespace desktop {
{
OUString aLockname = m_aLockname;
Config aConfig(aLockname);
- aConfig.SetGroup(LOCKFILE_GROUP);
+ aConfig.SetGroup(LOCKFILE_GROUP ""_ostr);
// get information
OString aHost( impl_getHostname() );
@@ -189,13 +191,13 @@ namespace desktop {
OString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US );
// write information
- aConfig.WriteKey( LOCKFILE_USERKEY, aUser );
- aConfig.WriteKey( LOCKFILE_HOSTKEY, aHost );
- aConfig.WriteKey( LOCKFILE_STAMPKEY, aStamp );
- aConfig.WriteKey( LOCKFILE_TIMEKEY, aTime );
+ aConfig.WriteKey( LOCKFILE_USERKEY ""_ostr, aUser );
+ aConfig.WriteKey( LOCKFILE_HOSTKEY ""_ostr, aHost );
+ aConfig.WriteKey( LOCKFILE_STAMPKEY ""_ostr, aStamp );
+ aConfig.WriteKey( LOCKFILE_TIMEKEY ""_ostr, aTime );
aConfig.WriteKey(
- LOCKFILE_IPCKEY,
- m_bIPCserver ? OString("true") : OString("false") );
+ LOCKFILE_IPCKEY ""_ostr,
+ m_bIPCserver ? "true"_ostr : "false"_ostr );
aConfig.Flush( );
}
diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx
index d29229aa5a05..7a692ec8c6c5 100644
--- a/desktop/source/deployment/registry/component/dp_component.cxx
+++ b/desktop/source/deployment/registry/component/dp_component.cxx
@@ -33,9 +33,11 @@
#include <cppuhelper/supportsservice.hxx>
#include <ucbhelper/content.hxx>
#include <comphelper/sequence.hxx>
+#include <utility>
#include <xmlscript/xml_helper.hxx>
#include <svl/inettype.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
+#include <o3tl/string_view.hxx>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/deployment/DeploymentException.hpp>
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
@@ -81,7 +83,7 @@ std::vector<OUString> getCmdBootstrapVariables()
}
bool jarManifestHeaderPresent(
- OUString const & url, OUString const & name,
+ OUString const & url, std::u16string_view name,
Reference<XCommandEnvironment> const & xCmdEnv )
{
OUString buf = "vnd.sun.star.zip://"
@@ -142,7 +144,7 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
::rtl::Reference<PackageRegistryBackend> const & myBackend,
OUString const & url, OUString const & name,
Reference<deployment::XPackageTypeInfo> const & xPackageType,
- OUString const & loader, bool bRemoved,
+ OUString loader, bool bRemoved,
OUString const & identifier);
};
friend class ComponentPackageImpl;
@@ -210,7 +212,7 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
::rtl::Reference<PackageRegistryBackend> const & myBackend,
OUString const & url, OUString const & name,
Reference<deployment::XPackageTypeInfo> const & xPackageType,
- bool bRemoved, OUString const & identifier, OUString const& rPlatform);
+ bool bRemoved, OUString const & identifier, OUString platform);
private:
BackendImpl * getMyBackend() const;
@@ -334,11 +336,11 @@ BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
::rtl::Reference<PackageRegistryBackend> const & myBackend,
OUString const & url, OUString const & name,
Reference<deployment::XPackageTypeInfo> const & xPackageType,
- OUString const & loader, bool bRemoved,
+ OUString loader, bool bRemoved,
OUString const & identifier)
: Package( myBackend, url, name, name /* display-name */,
xPackageType, bRemoved, identifier),
- m_loader( loader ),
+ m_loader(std::move( loader )),
m_registered( Reg::Uninit )
{}
@@ -619,7 +621,7 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_(
else if (title.endsWithIgnoreAsciiCase(".jar"))
{
if (jarManifestHeaderPresent(
- url, "RegistrationClassName", xCmdEnv ))
+ url, u"RegistrationClassName", xCmdEnv ))
mediaType = "application/vnd.sun.star.uno-component;type=Java";
if (mediaType.isEmpty())
mediaType = "application/vnd.sun.star.uno-typelibrary;type=Java";
@@ -652,7 +654,7 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_(
{
// xxx todo: probe and evaluate component xml description
- auto const iter = params.find(OString("platform"));
+ auto const iter = params.find("platform"_ostr);
bool bPlatformFits(iter == params.end());
OUString aPlatform;
if (!bPlatformFits) // platform is specified, we have to check
@@ -663,7 +665,7 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_(
// If the package is being removed, do not care whether
// platform fits. We won't be using it anyway.
if (bPlatformFits || bRemoved) {
- auto const iterType = params.find(OString("type"));
+ auto const iterType = params.find("type"_ostr);
if (iterType != params.end())
{
OUString const & value = iterType->second.m_sValue;
@@ -695,7 +697,7 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_(
}
else if (subType.equalsIgnoreAsciiCase("vnd.sun.star.uno-components"))
{
- auto const iter = params.find(OString("platform"));
+ auto const iter = params.find("platform"_ostr);
if (iter == params.end() || platform_fits(iter->second.m_sValue)) {
return new BackendImpl::ComponentsPackageImpl(
this, url, name, m_xComponentsTypeInfo, bRemoved,
@@ -704,7 +706,7 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_(
}
else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.uno-typelibrary"))
{
- auto const iter = params.find(OString("type"));
+ auto const iter = params.find("type"_ostr);
if (iter != params.end()) {
OUString const & value = iter->second.m_sValue;
if (value.equalsIgnoreAsciiCase("RDB"))
@@ -746,12 +748,12 @@ void BackendImpl::unorc_verify_init(
xCmdEnv, false /* no throw */ ))
{
OUString line;
- if (readLine( &line, "UNO_JAVA_CLASSPATH=", ucb_content,
+ if (readLine( &line, u"UNO_JAVA_CLASSPATH=", ucb_content,
RTL_TEXTENCODING_UTF8 ))
{
sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
do {
- OUString token( line.getToken( 0, ' ', index ).trim() );
+ OUString token( o3tl::trim(o3tl::getToken(line, 0, ' ', index )) );
if (!token.isEmpty())
{
if (create_ucb_content(
@@ -768,11 +770,11 @@ void BackendImpl::unorc_verify_init(
}
while (index >= 0);
}
- if (readLine( &line, "UNO_TYPES=", ucb_content,
+ if (readLine( &line, u"UNO_TYPES=", ucb_content,
RTL_TEXTENCODING_UTF8 )) {
sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
do {
- OUString token( line.getToken( 0, ' ', index ).trim() );
+ OUString token( o3tl::trim(o3tl::getToken(line, 0, ' ', index )) );
if (!token.isEmpty())
{
if (token[ 0 ] == '?')
@@ -791,7 +793,7 @@ void BackendImpl::unorc_verify_init(
}
while (index >= 0);
}
- if (readLine( &line, "UNO_SERVICES=", ucb_content,
+ if (readLine( &line, u"UNO_SERVICES=", ucb_content,
RTL_TEXTENCODING_UTF8 ))
{
// The UNO_SERVICES line always has the BNF form
@@ -837,7 +839,7 @@ void BackendImpl::unorc_verify_init(
&ucb_content,
makeURL( getCachePath(), getPlatformString() + "rc"),
xCmdEnv, false /* no throw */ )) {
- if (readLine( &line, "UNO_SERVICES=", ucb_content,
+ if (readLine( &line, u"UNO_SERVICES=", ucb_content,
RTL_TEXTENCODING_UTF8 )) {
m_nativeRDB_orig = line.copy(
sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
@@ -856,13 +858,9 @@ void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
if (!m_unorc_inited || !m_unorc_modified)
return;
- OStringBuffer buf;
-
- buf.append("ORIGIN=");
OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
OString osOrigin = OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
- buf.append(osOrigin);
- buf.append(LF);
+ OStringBuffer buf("ORIGIN=" + osOrigin + OStringChar(LF));
if (! m_jar_typelibs.empty())
{
@@ -911,9 +909,8 @@ void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
bool space = false;
if (!sCommonRDB.isEmpty())
{
- buf.append( "?$ORIGIN/" );
- buf.append( OUStringToOString(
- sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( "?$ORIGIN/"
+ + OUStringToOString( sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
space = true;
}
if (!sNativeRDB.isEmpty())
@@ -949,8 +946,7 @@ void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
{
buf.append(' ');
}
- buf.append('?');
- buf.append(OUStringToOString(component, RTL_TEXTENCODING_UTF8));
+ buf.append("?" + OUStringToOString(component, RTL_TEXTENCODING_UTF8));
space = true;
}
buf.append(LF);
@@ -993,7 +989,7 @@ void BackendImpl::removeFromUnoRc(
const ::osl::MutexGuard guard( m_aMutex );
unorc_verify_init( xCmdEnv );
std::deque<OUString> & aRcItemList = getRcItemList(kind);
- aRcItemList.erase(std::remove(aRcItemList.begin(), aRcItemList.end(), rcterm), aRcItemList.end());
+ std::erase(aRcItemList, rcterm);
// write immediately:
m_unorc_modified = true;
unorc_flush( xCmdEnv );
@@ -1303,10 +1299,10 @@ BackendImpl::ComponentPackageImpl::isRegistered_(
{
//try to match only the file name
OUString thisUrl(getURL());
- OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
+ std::u16string_view thisFileName(thisUrl.subView(thisUrl.lastIndexOf('/')));
- OUString locationFileName(location.copy(location.lastIndexOf('/')));
- if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
+ std::u16string_view locationFileName(location.subView(location.lastIndexOf('/')));
+ if (o3tl::equalsIgnoreAsciiCase(locationFileName, thisFileName))
bAmbiguousComponentName = true;
}
}
@@ -1374,7 +1370,7 @@ void BackendImpl::ComponentPackageImpl::processPackage_(
impreg->registerImplementation(m_loader, url, rdb);
// Only write to unorc after successful registration; it may fail if
// there is no suitable java
- if (m_loader == "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url, "UNO-Type-Path", xCmdEnv))
+ if (m_loader == "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url, u"UNO-Type-Path", xCmdEnv))
{
that->addToUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
data.javaTypeLibrary = true;
@@ -1495,7 +1491,7 @@ void BackendImpl::TypelibraryPackageImpl::processPackage_(
"/singletons"
"/com.sun.star.reflection.theTypeDescriptionManager"),
css::uno::UNO_QUERY_THROW)->insert(
- css::uno::makeAny(expandUnoRcUrl(url)));
+ css::uno::Any(expandUnoRcUrl(url)));
}
that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB,
@@ -1513,7 +1509,7 @@ void BackendImpl::TypelibraryPackageImpl::processPackage_(
"/singletons"
"/com.sun.star.reflection.theTypeDescriptionManager"),
css::uno::UNO_QUERY_THROW)->remove(
- css::uno::makeAny(expandUnoRcUrl(url)));
+ css::uno::Any(expandUnoRcUrl(url)));
}
}
}
@@ -1522,9 +1518,9 @@ BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
::rtl::Reference<PackageRegistryBackend> const & myBackend,
OUString const & url, OUString const & name,
Reference<deployment::XPackageTypeInfo> const & xPackageType,
- bool bRemoved, OUString const & identifier, OUString const& rPlatform)
+ bool bRemoved, OUString const & identifier, OUString platform)
: Package(myBackend, url, name, name, xPackageType, bRemoved, identifier)
- , m_aPlatform(rPlatform)
+ , m_aPlatform(std::move(platform))
{
OSL_PRECOND(bRemoved, "this class can only be used for removing packages!");
}
@@ -1564,7 +1560,7 @@ BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
catch (registry::InvalidRegistryException const&)
{
// If the registry does not exist, we do not need to bother at all
- xRegistry.set(nullptr);
+ xRegistry.clear();
}
SAL_WARN_IF( !xRegistry.is(), "desktop.deployment", "could not create registry for the package's platform");
@@ -1669,13 +1665,13 @@ void BackendImpl::ComponentsPackageImpl::processPackage_(
// supporting the extended XSet semantics:
css::uno::Sequence< css::beans::NamedValue > args
{
- { "uri", css::uno::makeAny(expandUnoRcUrl(url)) },
- { "component-context", css::uno::makeAny(context) }
+ { "uri", css::uno::Any(expandUnoRcUrl(url)) },
+ { "component-context", css::uno::Any(context) }
};
css::uno::Reference< css::container::XSet > smgr(
that->getRootContext()->getServiceManager(),
css::uno::UNO_QUERY_THROW);
- smgr->insert(css::uno::makeAny(args));
+ smgr->insert(css::uno::Any(args));
}
that->addToUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
} else { // revoke
@@ -1683,11 +1679,11 @@ void BackendImpl::ComponentsPackageImpl::processPackage_(
if (!startup) {
// This relies on the root component context's service manager
// supporting the extended XSet semantics:
- css::uno::Sequence< css::beans::NamedValue > args { { "uri", css::uno::makeAny(expandUnoRcUrl(url)) } };
+ css::uno::Sequence< css::beans::NamedValue > args { { "uri", css::uno::Any(expandUnoRcUrl(url)) } };
css::uno::Reference< css::container::XSet > smgr(
that->getRootContext()->getServiceManager(),
css::uno::UNO_QUERY_THROW);
- smgr->remove(css::uno::makeAny(args));
+ smgr->remove(css::uno::Any(args));
}
that->releaseObject(url);
that->revokeEntryFromDb(url); // in case it got added with old code
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.cxx b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
index e2fb409c2f6a..9ef3cc969432 100644
--- a/desktop/source/deployment/registry/configuration/dp_configuration.cxx
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
@@ -30,14 +30,15 @@
#include <dp_ucb.h>
#include <rtl/string.hxx>
#include <rtl/strbuf.hxx>
-#include <rtl/ustrbuf.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <ucbhelper/content.hxx>
#include <unotools/ucbhelper.hxx>
#include <xmlscript/xml_helper.hxx>
#include <comphelper/lok.hxx>
+#include <comphelper/xmlencode.hxx>
#include <svl/inettype.hxx>
+#include <o3tl/string_view.hxx>
#include <com/sun/star/configuration/Update.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
@@ -380,12 +381,12 @@ void BackendImpl::configmgrini_verify_init(
xCmdEnv, false /* no throw */ ))
{
OUString line;
- if (readLine( &line, "SCHEMA=", ucb_content,
+ if (readLine( &line, u"SCHEMA=", ucb_content,
RTL_TEXTENCODING_UTF8 ))
{
sal_Int32 index = RTL_CONSTASCII_LENGTH("SCHEMA=");
do {
- OUString token( line.getToken( 0, ' ', index ).trim() );
+ OUString token( o3tl::trim(o3tl::getToken(line, 0, ' ', index )) );
if (!token.isEmpty()) {
//The file may not exist anymore if a shared or bundled
//extension was removed, but it can still be in the configmgrini.
@@ -396,20 +397,20 @@ void BackendImpl::configmgrini_verify_init(
}
while (index >= 0);
}
- if (readLine( &line, "DATA=", ucb_content,
+ if (readLine( &line, u"DATA=", ucb_content,
RTL_TEXTENCODING_UTF8 )) {
sal_Int32 index = RTL_CONSTASCII_LENGTH("DATA=");
do {
- OUString token( line.getToken( 0, ' ', index ).trim() );
- if (!token.isEmpty())
+ std::u16string_view token( o3tl::trim(o3tl::getToken(line, 0, ' ', index )) );
+ if (!token.empty())
{
if (token[ 0 ] == '?')
- token = token.copy( 1 );
+ token = token.substr( 1 );
//The file may not exist anymore if a shared or bundled
//extension was removed, but it can still be in the configmgrini.
//After running XExtensionManager::synchronize, the configmgrini is
//cleaned up
- m_xcu_files.push_back( token );
+ m_xcu_files.push_back( OUString(token) );
}
}
while (index >= 0);
@@ -565,39 +566,6 @@ BackendImpl::PackageImpl::isRegistered_(
}
-OUString encodeForXml( OUString const & text )
-{
- // encode conforming xml:
- sal_Int32 len = text.getLength();
- OUStringBuffer buf;
- for ( sal_Int32 pos = 0; pos < len; ++pos )
- {
- sal_Unicode c = text[ pos ];
- switch (c) {
- case '<':
- buf.append( "&lt;" );
- break;
- case '>':
- buf.append( "&gt;" );
- break;
- case '&':
- buf.append( "&amp;" );
- break;
- case '\'':
- buf.append( "&apos;" );
- break;
- case '\"':
- buf.append( "&quot;" );
- break;
- default:
- buf.append( c );
- break;
- }
- }
- return buf.makeStringAndClear();
-}
-
-
OUString replaceOrigin(
OUString const & url, std::u16string_view destFolder, Reference< XCommandEnvironment > const & xCmdEnv, Reference< XComponentContext > const & xContext, bool & out_replaced)
{
@@ -650,7 +618,7 @@ OUString replaceOrigin(
if (origin.isEmpty()) {
// encode only once
origin = OUStringToOString(
- encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
+ comphelper::string::encodeForXml( url.subView( 0, url.lastIndexOf( '/' ) ) ),
// xxx todo: encode always for UTF-8? => lookup doc-header?
RTL_TEXTENCODING_UTF8 );
}
@@ -685,7 +653,7 @@ OUString replaceOrigin(
void BackendImpl::PackageImpl::processPackage_(
- ::osl::ResettableMutexGuard &,
+ ::osl::ResettableMutexGuard & guard,
bool doRegisterPackage,
bool startup,
::rtl::Reference<AbortChannel> const &,
@@ -720,7 +688,10 @@ void BackendImpl::PackageImpl::processPackage_(
if ((that->m_eContext != Context::Bundled && !startup)
|| comphelper::LibreOfficeKit::isActive())
{
- if (m_isSchema)
+ bool bIsSchema = m_isSchema;
+ // tdf#159790 prevent lock-ordering deadlock, the code below might acquire the solar mutex
+ guard.clear();
+ if (bIsSchema)
{
css::configuration::Update::get(
that->m_xComponentContext)->insertExtensionXcsFile(
@@ -732,6 +703,7 @@ void BackendImpl::PackageImpl::processPackage_(
that->m_xComponentContext)->insertExtensionXcuFile(
that->m_eContext == Context::Shared, expandUnoRcUrl(url));
}
+ guard.reset();
}
that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
data.iniEntry = dp_misc::makeRcTerm(url);
diff --git a/desktop/source/deployment/registry/dp_backend.cxx b/desktop/source/deployment/registry/dp_backend.cxx
index ce37da6280fd..016ff66286d9 100644
--- a/desktop/source/deployment/registry/dp_backend.cxx
+++ b/desktop/source/deployment/registry/dp_backend.cxx
@@ -42,9 +42,10 @@
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/sdbc/XResultSet.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <unotools/tempfile.hxx>
#include <optional>
+#include <utility>
using namespace ::dp_misc;
using namespace ::com::sun::star;
@@ -214,9 +215,7 @@ OUString PackageRegistryBackend::createFolder(
ucbhelper::Content dataContent;
::dp_misc::create_folder(&dataContent, sDataFolder, xCmdEnv);
- const OUString baseDir(sDataFolder);
- ::utl::TempFile aTemp(&baseDir, true);
- const OUString& url = aTemp.GetURL();
+ const OUString url = ::utl::CreateTempURL(&sDataFolder, true);
return sDataFolder + url.subView(url.lastIndexOf('/'));
}
@@ -297,21 +296,21 @@ Package::~Package()
}
-Package::Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
- OUString const & url,
- OUString const & rName,
- OUString const & displayName,
+Package::Package( ::rtl::Reference<PackageRegistryBackend> myBackend,
+ OUString url,
+ OUString aName,
+ OUString displayName,
Reference<deployment::XPackageTypeInfo> const & xPackageType,
bool bRemoved,
- OUString const & identifier)
+ OUString identifier)
: t_PackageBase( m_aMutex ),
- m_myBackend( myBackend ),
- m_url( url ),
- m_name( rName ),
- m_displayName( displayName ),
+ m_myBackend(std::move( myBackend )),
+ m_url(std::move( url )),
+ m_name(std::move( aName )),
+ m_displayName(std::move( displayName )),
m_xPackageType( xPackageType ),
m_bRemoved(bRemoved),
- m_identifier(identifier)
+ m_identifier(std::move(identifier))
{
if (m_bRemoved)
{
diff --git a/desktop/source/deployment/registry/dp_registry.cxx b/desktop/source/deployment/registry/dp_registry.cxx
index 40239f2501b2..ac19bcd8e9d8 100644
--- a/desktop/source/deployment/registry/dp_registry.cxx
+++ b/desktop/source/deployment/registry/dp_registry.cxx
@@ -33,6 +33,7 @@
#include <cppuhelper/compbase.hxx>
#include <comphelper/sequence.hxx>
#include <ucbhelper/content.hxx>
+#include <o3tl/string_view.hxx>
#include <com/sun/star/ucb/ContentCreationException.hpp>
#include <com/sun/star/uno/DeploymentException.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
@@ -71,8 +72,8 @@ class PackageRegistryImpl : private cppu::BaseMutex, public t_helper
}
};
struct ci_string_equals {
- bool operator () ( OUString const & str1, std::u16string_view str2 ) const{
- return str1.equalsIgnoreAsciiCase( str2 );
+ bool operator () ( std::u16string_view str1, std::u16string_view str2 ) const{
+ return o3tl::equalsIgnoreAsciiCase( str1, str2 );
}
};
typedef std::unordered_map<
@@ -152,12 +153,12 @@ PackageRegistryImpl::~PackageRegistryImpl()
}
-OUString normalizeMediaType( OUString const & mediaType )
+OUString normalizeMediaType( std::u16string_view mediaType )
{
OUStringBuffer buf;
sal_Int32 index = 0;
for (;;) {
- buf.append( mediaType.getToken( 0, '/', index ).trim() );
+ buf.append( o3tl::trim(o3tl::getToken(mediaType, 0, '/', index )) );
if (index < 0)
break;
buf.append( '/' );
@@ -380,8 +381,8 @@ Reference<deployment::XPackageRegistry> PackageRegistryImpl::create(
OUStringBuffer buf;
buf.append(
Reference<lang::XServiceInfo>(
- ambiguousBackend, UNO_QUERY_THROW )->getImplementationName() );
- buf.append( ": " );
+ ambiguousBackend, UNO_QUERY_THROW )->getImplementationName()
+ + ": " );
const Sequence< Reference<deployment::XPackageTypeInfo> > types(
ambiguousBackend->getSupportedPackageTypes() );
for ( sal_Int32 pos = 0; pos < types.getLength(); ++pos ) {
@@ -390,14 +391,12 @@ Reference<deployment::XPackageRegistry> PackageRegistryImpl::create(
buf.append( xInfo->getMediaType() );
const OUString filter( xInfo->getFileFilter() );
if (!filter.isEmpty()) {
- buf.append( " (" );
- buf.append( filter );
- buf.append( ")" );
+ buf.append( " (" + filter + ")" );
}
if (pos < (types.getLength() - 1))
buf.append( ", " );
}
- dp_misc::TRACE(buf.makeStringAndClear() + "\n\n");
+ dp_misc::TRACE(buf + "\n\n");
}
allBackends.insert( that->m_ambiguousBackends.begin(),
that->m_ambiguousBackends.end() );
@@ -491,7 +490,7 @@ Reference<deployment::XPackage> PackageRegistryImpl::bindPackage(
iFind = m_mediaType2backend.find(
normalizeMediaType(
// cut parameters:
- mediaType.copy( 0, q ) ) );
+ mediaType.subView( 0, q ) ) );
}
}
if (iFind == m_mediaType2backend.end()) {
diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx
index 834f829ad35b..a84bc2809544 100644
--- a/desktop/source/deployment/registry/help/dp_help.cxx
+++ b/desktop/source/deployment/registry/help/dp_help.cxx
@@ -31,6 +31,7 @@
#include <svl/inettype.hxx>
#include <unotools/pathoptions.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <o3tl/string_view.hxx>
#if HAVE_FEATURE_XMLHELP
#include <helpcompiler/compilehelp.hxx>
@@ -391,7 +392,7 @@ void BackendImpl::implProcessHelp(
"No help folder";
OWeakObject* oWeakThis = this;
throw deployment::DeploymentException( OUString(), oWeakThis,
- makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
+ Any( uno::Exception( aErrStr, oWeakThis ) ) );
}
// Scan languages
@@ -420,7 +421,7 @@ void BackendImpl::implProcessHelp(
&langFolderContent,
langFolderDest, xCmdEnv);
- static const OUStringLiteral aHelpStr(u"help");
+ static constexpr OUString aHelpStr(u"help"_ustr);
OUString aJarFile(
makeURL(sHelpFolder, langFolderURLSegment + "/" + aHelpStr + ".jar"));
@@ -447,9 +448,8 @@ void BackendImpl::implProcessHelp(
implCollectXhpFiles( aSubFolderURL, aXhpFileVector );
// Copy to package (later: move?)
- OUString aDestPath = aDestBasePath;
- OUString aPureFolderName = aSubFolderURL.copy( nLenLangFolderURL );
- aDestPath += aPureFolderName;
+ std::u16string_view aPureFolderName = aSubFolderURL.subView( nLenLangFolderURL );
+ OUString aDestPath = aDestBasePath + aPureFolderName;
xSFA->copy( aSubFolderURL, aDestPath );
}
@@ -538,7 +538,7 @@ void BackendImpl::implProcessHelp(
OWeakObject* oWeakThis = this;
throw deployment::DeploymentException( OUString(), oWeakThis,
- makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
+ Any( uno::Exception( aErrStr, oWeakThis ) ) );
}
}
}
@@ -580,8 +580,8 @@ void BackendImpl::implCollectXhpFiles( const OUString& aDir,
sal_Int32 nLastDot = aURL.lastIndexOf( '.' );
if( nLastDot != -1 )
{
- OUString aExt = aURL.copy( nLastDot + 1 );
- if( aExt.equalsIgnoreAsciiCase( "xhp" ) )
+ std::u16string_view aExt = aURL.subView( nLastDot + 1 );
+ if( o3tl::equalsIgnoreAsciiCase( aExt, u"xhp" ) )
o_rXhpFileVector.push_back( aURL );
}
}
diff --git a/desktop/source/deployment/registry/inc/dp_backend.h b/desktop/source/deployment/registry/inc/dp_backend.h
index e6dd949f1b23..a68420d6b019 100644
--- a/desktop/source/deployment/registry/inc/dp_backend.h
+++ b/desktop/source/deployment/registry/inc/dp_backend.h
@@ -31,13 +31,14 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <unordered_map>
#include <strings.hrc>
+#include <utility>
namespace dp_registry::backend
{
class PackageRegistryBackend;
-inline constexpr OUStringLiteral BACKEND_SERVICE_NAME = u"com.sun.star.deployment.PackageRegistryBackend";
+inline constexpr OUString BACKEND_SERVICE_NAME = u"com.sun.star.deployment.PackageRegistryBackend"_ustr;
typedef ::cppu::WeakComponentImplHelper<
css::deployment::XPackage > t_PackageBase;
@@ -85,14 +86,13 @@ protected:
= 0;
virtual ~Package() override;
- Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
- OUString const & url,
- OUString const & name,
- OUString const & displayName,
- css::uno::Reference<css::deployment::XPackageTypeInfo> const &
- xPackageType,
+ Package( ::rtl::Reference<PackageRegistryBackend> myBackend,
+ OUString url,
+ OUString name,
+ OUString displayName,
+ css::uno::Reference<css::deployment::XPackageTypeInfo> const & xPackageType,
bool bRemoved,
- OUString const & identifier);
+ OUString identifier);
public:
@@ -104,11 +104,11 @@ public:
const OUString m_shortDescr;
public:
virtual ~TypeInfo() override;
- TypeInfo( OUString const & mediaType,
- OUString const & fileFilter,
- OUString const & shortDescr )
- : m_mediaType(mediaType), m_fileFilter(fileFilter),
- m_shortDescr(shortDescr)
+ TypeInfo( OUString mediaType,
+ OUString fileFilter,
+ OUString shortDescr )
+ : m_mediaType(std::move(mediaType)), m_fileFilter(std::move(fileFilter)),
+ m_shortDescr(std::move(shortDescr))
{}
// XPackageTypeInfo
virtual OUString SAL_CALL getMediaType() override;
diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx
index 321db824f40c..494ce437e1e9 100644
--- a/desktop/source/deployment/registry/package/dp_package.cxx
+++ b/desktop/source/deployment/registry/package/dp_package.cxx
@@ -32,6 +32,7 @@
#include <rtl/uri.hxx>
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/supportsservice.hxx>
@@ -67,11 +68,12 @@
#include <com/sun/star/deployment/PlatformException.hpp>
#include <com/sun/star/deployment/Prerequisites.hpp>
#include <optional>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <algorithm>
#include <memory>
#include <string_view>
+#include <utility>
#include <vector>
#include "dp_extbackenddb.hxx"
@@ -252,7 +254,7 @@ class XPackage_eq
{
OUString m_URL;
public:
- explicit XPackage_eq(const OUString & s) : m_URL(s) {}
+ explicit XPackage_eq(OUString s) : m_URL(std::move(s)) {}
bool operator() (const Reference<deployment::XPackage> & p) const
{
return m_URL == p->getURL();
@@ -307,7 +309,7 @@ sal_Bool BackendImpl::supportsService(OUString const & ServiceName)
Sequence<OUString> BackendImpl::getSupportedServiceNames()
{
- return { OUString(BACKEND_SERVICE_NAME) };
+ return { BACKEND_SERVICE_NAME };
}
// XPackageRegistry
@@ -779,7 +781,7 @@ uno::Reference< graphic::XGraphic > BackendImpl::PackageImpl::getIcon( sal_Bool
void BackendImpl::PackageImpl::processPackage_(
- ::osl::ResettableMutexGuard &,
+ ::osl::ResettableMutexGuard & guard,
bool doRegisterPackage,
bool startup,
::rtl::Reference<AbortChannel> const & abortChannel,
@@ -800,6 +802,13 @@ void BackendImpl::PackageImpl::processPackage_(
xPackage->createAbortChannel() );
AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
try {
+ // tdf#159790 temporarily release mutex for child packages
+ // This code is normally run on a separate thread so if a
+ // child package tries to acquire the solar mutex, a deadlock
+ // can occur if the main thread calls isRegistered() on this
+ // package or any of its parents. So, temporarily release
+ // this package's mutex while registering the child package.
+ osl::ResettableMutexGuardScopedReleaser releaser(guard);
xPackage->registerPackage( startup, xSubAbortChannel, xCmdEnv );
}
catch (const Exception &)
@@ -854,6 +863,7 @@ void BackendImpl::PackageImpl::processPackage_(
::cppu::throwException(exc);
}
}
+
data.items.emplace_back(xPackage->getURL(),
xPackage->getPackageType()->getMediaType());
}
@@ -1055,9 +1065,9 @@ void BackendImpl::PackageImpl::exportTo(
manifest.reserve( bundle.getLength() );
sal_Int32 baseURLlen = m_url_expanded.getLength();
Reference<deployment::XPackage> const *pbundle = bundle.getConstArray();
- static const OUStringLiteral strMediaType( u"MediaType" );
- static const OUStringLiteral strFullPath( u"FullPath" );
- static const OUStringLiteral strIsFolder( u"IsFolder" );
+ static constexpr OUStringLiteral strMediaType( u"MediaType" );
+ static constexpr OUStringLiteral strFullPath( u"FullPath" );
+ static constexpr OUStringLiteral strIsFolder( u"IsFolder" );
for ( sal_Int32 pos = bundle.getLength(); pos--; )
{
Reference<deployment::XPackage> const & xPackage = pbundle[ pos ];
@@ -1265,12 +1275,12 @@ Sequence< Reference<deployment::XPackage> > BackendImpl::PackageImpl::getBundle(
return *pBundle;
}
-bool isBundle_( OUString const & mediaType )
+bool isBundle_( std::u16string_view mediaType )
{
// xxx todo: additional parsing?
- return !mediaType.isEmpty() &&
- (mediaType.matchIgnoreAsciiCase( "application/vnd.sun.star.package-bundle") ||
- mediaType.matchIgnoreAsciiCase( "application/vnd.sun.star.legacy-package-bundle"));
+ return !mediaType.empty() &&
+ (o3tl::matchIgnoreAsciiCase( mediaType, u"application/vnd.sun.star.package-bundle") ||
+ o3tl::matchIgnoreAsciiCase( mediaType, u"application/vnd.sun.star.legacy-package-bundle"));
}
@@ -1381,7 +1391,7 @@ void BackendImpl::PackageImpl::scanBundle(
continue;
{
- auto const iter = params.find("platform");
+ auto const iter = params.find("platform"_ostr);
if (iter != params.end() && !platform_fits(iter->second.m_sValue))
continue;
}
@@ -1392,7 +1402,7 @@ void BackendImpl::PackageImpl::scanBundle(
subType.equalsIgnoreAsciiCase( "vnd.sun.star.package-bundle-description"))
{
// check locale:
- auto const iter = params.find("locale");
+ auto const iter = params.find("locale"_ostr);
if (iter == params.end())
{
if (descrFile.isEmpty())
@@ -1487,7 +1497,7 @@ void BackendImpl::PackageImpl::scanLegacyBundle(
// check for platform paths:
const OUString title( StrTitle::getTitle( ucbContent ) );
if (title.endsWithIgnoreAsciiCase( ".plt" ) &&
- !platform_fits( title.copy( 0, title.getLength() - 4 ) )) {
+ !platform_fits( title.subView( 0, title.getLength() - 4 ) )) {
return;
}
if (title.endsWithIgnoreAsciiCase("skip_registration") )
diff --git a/desktop/source/deployment/registry/script/dp_lib_container.cxx b/desktop/source/deployment/registry/script/dp_lib_container.cxx
index 3a6f30253fb0..601cb5b39daa 100644
--- a/desktop/source/deployment/registry/script/dp_lib_container.cxx
+++ b/desktop/source/deployment/registry/script/dp_lib_container.cxx
@@ -22,7 +22,6 @@
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <strings.hrc>
-#include <dp_resource.h>
#include <dp_shared.hxx>
#include <dp_xml.h>
#include "dp_lib_container.h"
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
index 34ff6d4ecd05..b617d7fa4ed1 100644
--- a/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
@@ -31,6 +31,7 @@
#include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
#include <com/sun/star/xml/sax/Parser.hpp>
#include <cppuhelper/supportsservice.hxx>
+#include <utility>
using namespace ::dp_misc;
@@ -71,7 +72,7 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
public:
PackageImpl(
::rtl::Reference<BackendImpl> const & myBackend,
- OUString const & url, OUString const & libType, bool bRemoved,
+ OUString const & url, OUString libType, bool bRemoved,
OUString const & identifier);
// XPackage
virtual OUString SAL_CALL getDescription() override;
@@ -135,11 +136,11 @@ OUString BackendImpl::PackageImpl::getLicenseText()
BackendImpl::PackageImpl::PackageImpl(
::rtl::Reference<BackendImpl> const & myBackend,
- OUString const & url, OUString const & libType, bool bRemoved,
+ OUString const & url, OUString libType, bool bRemoved,
OUString const & identifier)
: Package( myBackend, url, OUString(), OUString(),
myBackend->m_xTypeInfo, bRemoved, identifier),
- m_descr(libType)
+ m_descr(std::move(libType))
{
initPackageHandler();
@@ -356,7 +357,7 @@ void BackendImpl::PackageImpl::processPackage_(
if (doRegisterPackage)
{
// will throw if it fails
- m_xNameCntrPkgHandler->insertByName( m_url, makeAny( Reference< XPackage >(this) ) );
+ m_xNameCntrPkgHandler->insertByName( m_url, Any( Reference< XPackage >(this) ) );
}
else // revokePackage()
diff --git a/desktop/source/inc/helpids.h b/desktop/source/inc/helpids.h
index 023ffdea7bea..b7d7c4359770 100644
--- a/desktop/source/inc/helpids.h
+++ b/desktop/source/inc/helpids.h
@@ -19,9 +19,9 @@
#pragma once
-#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
-inline constexpr OStringLiteral HID_EXTENSION_MANAGER_LISTBOX_ENABLE = "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_ENABLE";
-inline constexpr OStringLiteral HID_EXTENSION_MANAGER_LISTBOX_DISABLE = "DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_DISABLE";
+inline constexpr OUString HID_EXTENSION_MANAGER_LISTBOX_ENABLE = u"DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_ENABLE"_ustr;
+inline constexpr OUString HID_EXTENSION_MANAGER_LISTBOX_DISABLE = u"DESKTOP_HID_EXTENSION_MANAGER_LISTBOX_DISABLE"_ustr;
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 3370779df25d..f13bc1f48e26 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -7,11 +7,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <sfx2/lokhelper.hxx>
+#include <sal/types.h>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <config_buildconfig.h>
+#include <config_cairo_rgba.h>
#include <config_features.h>
+#include <editeng/unolingu.hxx>
#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
#ifdef IOS
#include <sys/mman.h>
@@ -24,10 +30,26 @@
#include <postmac.h>
#endif
+#undef HAVE_MALLOC_TRIM
+
+#ifdef UNX
+# include <fcntl.h>
+#endif
+#ifdef LINUX
+#if defined __GLIBC__
+# include <malloc.h>
+# define HAVE_MALLOC_TRIM
+#endif
+#endif
+
#ifdef ANDROID
#include <osl/detail/android-bootstrap.h>
#endif
+#ifdef EMSCRIPTEN
+#include <osl/detail/emscripten-bootstrap.h>
+#endif
+
#include <algorithm>
#include <memory>
#include <iostream>
@@ -40,16 +62,19 @@
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sal/log.hxx>
+#include <utility>
#include <vcl/errinf.hxx>
#include <vcl/lok.hxx>
#include <o3tl/any.hxx>
#include <o3tl/unit_conversion.hxx>
+#include <o3tl/string_view.hxx>
#include <osl/file.hxx>
#include <osl/process.h>
#include <osl/thread.h>
#include <rtl/bootstrap.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/uri.hxx>
+#include <linguistic/misc.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <comphelper/base64.hxx>
#include <comphelper/dispatchcommand.hxx>
@@ -61,8 +86,10 @@
#include <comphelper/propertyvalue.hxx>
#include <comphelper/scopeguard.hxx>
#include <comphelper/threadpool.hxx>
+#include <comphelper/types.hxx>
#include <comphelper/sequenceashashmap.hxx>
+#include <com/sun/star/connection/XConnection.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
@@ -84,6 +111,10 @@
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/document/XRedlinesSupplier.hpp>
#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
+#include <com/sun/star/bridge/BridgeFactory.hpp>
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+#include <com/sun/star/bridge/XBridge.hpp>
+#include <com/sun/star/uno/XNamingService.hpp>
#include <com/sun/star/xml/crypto/SEInitializer.hpp>
#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
@@ -91,11 +122,15 @@
#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/linguistic2/DictionaryList.hpp>
#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
#include <com/sun/star/linguistic2/XSpellChecker.hpp>
+#include <com/sun/star/linguistic2/XProofreader.hpp>
#include <com/sun/star/i18n/LocaleCalendar2.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/i18n/BreakIterator.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <editeng/flstitem.hxx>
#ifdef IOS
@@ -108,10 +143,9 @@
#include <sfx2/viewfrm.hxx>
#include <sfx2/msgpool.hxx>
#include <sfx2/dispatch.hxx>
-#include <sfx2/lokcharthelper.hxx>
+#include <sfx2/lokcomponenthelpers.hxx>
#include <sfx2/DocumentSigner.hxx>
-#include <sfx2/sidebar/SidebarDockingWindow.hxx>
-#include <sfx2/sidebar/SidebarController.hxx>
+#include <sfx2/sidebar/Sidebar.hxx>
#include <svl/numformat.hxx>
#include <svx/dialmgr.hxx>
#include <svx/strings.hrc>
@@ -119,7 +153,7 @@
#include <svx/svxids.hrc>
#include <svx/ucsubset.hxx>
#include <vcl/vclevent.hxx>
-#include <vcl/GestureEvent.hxx>
+#include <vcl/GestureEventPan.hxx>
#include <vcl/svapp.hxx>
#include <unotools/resmgr.hxx>
#include <tools/fract.hxx>
@@ -134,6 +168,9 @@
#include <vcl/ImageTree.hxx>
#include <vcl/ITiledRenderable.hxx>
#include <vcl/dialoghelper.hxx>
+#ifdef _WIN32
+#include <vcl/BitmapReadAccess.hxx>
+#endif
#include <unicode/uchar.h>
#include <unotools/securityoptions.hxx>
#include <unotools/confignode.hxx>
@@ -150,13 +187,14 @@
#include <i18nlangtag/mslangid.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <vcl/abstdlg.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <vcl/uitest/uiobject.hxx>
#include <vcl/jsdialog/executor.hxx>
// Needed for getUndoManager()
#include <com/sun/star/document/XUndoManager.hpp>
#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+#include <com/sun/star/document/XLinkTargetSupplier.hpp>
#include <editeng/sizeitem.hxx>
#include <svx/rulritem.hxx>
#include <svx/pageitem.hxx>
@@ -173,28 +211,51 @@
#include "lokclipboard.hxx"
#include <officecfg/Office/Common.hxx>
#include <officecfg/Office/Impress.hxx>
+#include <officecfg/Office/Linguistic.hxx>
+#include <officecfg/Office/UI/ToolbarMode.hxx>
#include <unotools/optionsdlg.hxx>
#include <svl/ctloptions.hxx>
-#include <svtools/accessibilityoptions.hxx>
#include <svtools/colorcfg.hxx>
#include <svtools/miscopt.hxx>
-#include <svtools/slidesorterbaropt.hxx>
#include <unotools/cmdoptions.hxx>
-#include <unotools/compatibility.hxx>
-#include <unotools/fltrcfg.hxx>
#include <unotools/lingucfg.hxx>
#include <unotools/moduleoptions.hxx>
#include <unotools/searchopt.hxx>
#include <unotools/useroptions.hxx>
-#include <unotools/viewoptions.hxx>
#include <vcl/settings.hxx>
+#include <officecfg/Setup.hxx>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <svtools/acceleratorexecute.hxx>
+
+#include <tools/hostfilter.hxx>
+
using namespace css;
using namespace vcl;
using namespace desktop;
using namespace utl;
+using namespace bridge;
+using namespace uno;
+using namespace lang;
+
+#ifdef UNX
+
+static int urandom = -1;
+
+extern "C" {
+ int SAL_JNI_EXPORT lok_open_urandom()
+ {
+ return dup(urandom);
+ }
+};
+
+#endif
+
+
+using LanguageToolCfg = officecfg::Office::Linguistic::GrammarChecking::LanguageTool;
static LibLibreOffice_Impl *gImpl = nullptr;
+static bool lok_preinit_2_called = false;
static std::weak_ptr< LibreOfficeKitClass > gOfficeClass;
static std::weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass;
@@ -209,8 +270,8 @@ namespace {
struct ExtensionMap
{
- const char *extn;
- const char *filterName;
+ std::string_view extn;
+ OUString filterName;
};
class TraceEventDumper : public AutoTimer
@@ -236,8 +297,8 @@ public:
OStringBuffer aOutput;
for (const auto &s : aEvents)
{
- aOutput.append(OUStringToOString(s, RTL_TEXTENCODING_UTF8));
- aOutput.append("\n");
+ aOutput.append(OUStringToOString(s, RTL_TEXTENCODING_UTF8)
+ + "\n");
}
if (aOutput.getLength() > 0)
{
@@ -248,88 +309,81 @@ public:
}
};
-} // unnamed namespace
-
-static TraceEventDumper *traceEventDumper = nullptr;
-
-const ExtensionMap aWriterExtensionMap[] =
-{
- { "doc", "MS Word 97" },
- { "docm", "MS Word 2007 XML VBA" },
- { "docx", "MS Word 2007 XML" },
- { "fodt", "OpenDocument Text Flat XML" },
- { "html", "HTML (StarWriter)" },
- { "odt", "writer8" },
- { "ott", "writer8_template" },
- { "pdf", "writer_pdf_Export" },
- { "epub", "EPUB" },
- { "rtf", "Rich Text Format" },
- { "txt", "Text" },
- { "xhtml", "XHTML Writer File" },
- { "png", "writer_png_Export" },
- { "xml", "writer_indexing_export" },
- { nullptr, nullptr }
+TraceEventDumper *traceEventDumper = nullptr;
+
+constexpr ExtensionMap aWriterExtensionMap[] =
+{
+ { "doc", u"MS Word 97"_ustr },
+ { "docm", u"MS Word 2007 XML VBA"_ustr },
+ { "docx", u"MS Word 2007 XML"_ustr },
+ { "fodt", u"OpenDocument Text Flat XML"_ustr },
+ { "html", u"HTML (StarWriter)"_ustr },
+ { "odt", u"writer8"_ustr },
+ { "ott", u"writer8_template"_ustr },
+ { "pdf", u"writer_pdf_Export"_ustr },
+ { "epub", u"EPUB"_ustr },
+ { "rtf", u"Rich Text Format"_ustr },
+ { "txt", u"Text"_ustr },
+ { "xhtml", u"XHTML Writer File"_ustr },
+ { "png", u"writer_png_Export"_ustr },
+ { "xml", u"writer_indexing_export"_ustr },
};
-const ExtensionMap aCalcExtensionMap[] =
-{
- { "csv", "Text - txt - csv (StarCalc)" },
- { "fods", "OpenDocument Spreadsheet Flat XML" },
- { "html", "HTML (StarCalc)" },
- { "ods", "calc8" },
- { "ots", "calc8_template" },
- { "pdf", "calc_pdf_Export" },
- { "xhtml", "XHTML Calc File" },
- { "xls", "MS Excel 97" },
- { "xlsm", "Calc MS Excel 2007 VBA XML" },
- { "xlsx", "Calc MS Excel 2007 XML" },
- { "png", "calc_png_Export" },
- { nullptr, nullptr }
+constexpr ExtensionMap aCalcExtensionMap[] =
+{
+ { "csv", u"Text - txt - csv (StarCalc)"_ustr },
+ { "fods", u"OpenDocument Spreadsheet Flat XML"_ustr },
+ { "html", u"HTML (StarCalc)"_ustr },
+ { "ods", u"calc8"_ustr },
+ { "ots", u"calc8_template"_ustr },
+ { "pdf", u"calc_pdf_Export"_ustr },
+ { "xhtml", u"XHTML Calc File"_ustr },
+ { "xls", u"MS Excel 97"_ustr },
+ { "xlsm", u"Calc MS Excel 2007 VBA XML"_ustr },
+ { "xlsx", u"Calc MS Excel 2007 XML"_ustr },
+ { "png", u"calc_png_Export"_ustr },
};
-const ExtensionMap aImpressExtensionMap[] =
-{
- { "fodp", "OpenDocument Presentation Flat XML" },
- { "html", "impress_html_Export" },
- { "odg", "impress8_draw" },
- { "odp", "impress8" },
- { "otp", "impress8_template" },
- { "pdf", "impress_pdf_Export" },
- { "potm", "Impress MS PowerPoint 2007 XML Template" },
- { "pot", "MS PowerPoint 97 Vorlage" },
- { "pptm", "Impress MS PowerPoint 2007 XML VBA" },
- { "pptx", "Impress MS PowerPoint 2007 XML" },
- { "pps", "MS PowerPoint 97 Autoplay" },
- { "ppt", "MS PowerPoint 97" },
- { "svg", "impress_svg_Export" },
- { "xhtml", "XHTML Impress File" },
- { "png", "impress_png_Export"},
- { nullptr, nullptr }
+constexpr ExtensionMap aImpressExtensionMap[] =
+{
+ { "fodp", u"OpenDocument Presentation Flat XML"_ustr },
+ { "html", u"impress_html_Export"_ustr },
+ { "odg", u"impress8_draw"_ustr },
+ { "odp", u"impress8"_ustr },
+ { "otp", u"impress8_template"_ustr },
+ { "pdf", u"impress_pdf_Export"_ustr },
+ { "potm", u"Impress MS PowerPoint 2007 XML Template"_ustr },
+ { "pot", u"MS PowerPoint 97 Vorlage"_ustr },
+ { "pptm", u"Impress MS PowerPoint 2007 XML VBA"_ustr },
+ { "pptx", u"Impress MS PowerPoint 2007 XML"_ustr },
+ { "pps", u"MS PowerPoint 97 Autoplay"_ustr },
+ { "ppt", u"MS PowerPoint 97"_ustr },
+ { "svg", u"impress_svg_Export"_ustr },
+ { "xhtml", u"XHTML Impress File"_ustr },
+ { "png", u"impress_png_Export"_ustr },
};
-const ExtensionMap aDrawExtensionMap[] =
+constexpr ExtensionMap aDrawExtensionMap[] =
{
- { "fodg", "draw_ODG_FlatXML" },
- { "html", "draw_html_Export" },
- { "odg", "draw8" },
- { "pdf", "draw_pdf_Export" },
- { "svg", "draw_svg_Export" },
- { "xhtml", "XHTML Draw File" },
- { "png", "draw_png_Export"},
- { nullptr, nullptr }
+ { "fodg", u"draw_ODG_FlatXML"_ustr },
+ { "html", u"draw_html_Export"_ustr },
+ { "odg", u"draw8"_ustr },
+ { "pdf", u"draw_pdf_Export"_ustr },
+ { "svg", u"draw_svg_Export"_ustr },
+ { "xhtml", u"XHTML Draw File"_ustr },
+ { "png", u"draw_png_Export"_ustr },
};
-static OUString getUString(const char* pString)
+OUString getUString(const char* pString)
{
if (pString == nullptr)
return OUString();
- OString sString(pString, strlen(pString));
- return OStringToOUString(sString, RTL_TEXTENCODING_UTF8);
+ return OStringToOUString(pString, RTL_TEXTENCODING_UTF8);
}
// Tolerate embedded \0s etc.
-static char *convertOString(const OString &rStr)
+char *convertOString(const OString &rStr)
{
char* pMemory = static_cast<char*>(malloc(rStr.getLength() + 1));
assert(pMemory); // don't tolerate failed allocations.
@@ -337,13 +391,13 @@ static char *convertOString(const OString &rStr)
return pMemory;
}
-static char *convertOUString(std::u16string_view aStr)
+char *convertOUString(std::u16string_view aStr)
{
return convertOString(OUStringToOString(aStr, RTL_TEXTENCODING_UTF8));
}
/// Try to convert a relative URL to an absolute one, unless it already looks like a URL.
-static OUString getAbsoluteURL(const char* pURL)
+OUString getAbsoluteURL(const char* pURL)
{
OUString aURL(getUString(pURL));
if (aURL.isEmpty())
@@ -366,6 +420,8 @@ static OUString getAbsoluteURL(const char* pURL)
return OUString();
}
+} // unnamed namespace
+
std::vector<beans::PropertyValue> desktop::jsonToPropertyValuesVector(const char* pJSON)
{
std::vector<beans::PropertyValue> aArguments;
@@ -376,18 +432,76 @@ std::vector<beans::PropertyValue> desktop::jsonToPropertyValuesVector(const char
return aArguments;
}
-static void unoAnyToJson(tools::JsonWriter& rJson, const char * pNodeName, const uno::Any& anyItem)
+static void extractLinks(const uno::Reference< container::XNameAccess >& xLinks, bool subcontent, tools::JsonWriter& aJson)
+{
+ for (const OUString& aLink : xLinks->getElementNames())
+ {
+ uno::Any aAny;
+
+ try
+ {
+ aAny = xLinks->getByName( aLink );
+ }
+ catch(const uno::Exception&)
+ {
+ // if the name of the target was invalid (like empty headings)
+ // no object can be provided
+ continue;
+ }
+
+ uno::Reference< beans::XPropertySet > xTarget;
+ if( aAny >>= xTarget )
+ {
+ try
+ {
+ // get name to display
+ aAny = xTarget->getPropertyValue(u"LinkDisplayName"_ustr);
+ OUString aStrDisplayname;
+ aAny >>= aStrDisplayname;
+
+ if (subcontent)
+ {
+ aJson.put(aStrDisplayname, aLink);
+ }
+ else
+ {
+ uno::Reference<lang::XServiceInfo> xSI(xTarget, uno::UNO_QUERY_THROW);
+ if (xSI->supportsService(u"com.sun.star.document.LinkTarget"_ustr))
+ {
+ aJson.put(aStrDisplayname, aLink);
+ continue;
+ }
+ else
+ {
+ auto aNode = aJson.startNode(
+ OUStringToOString(aStrDisplayname, RTL_TEXTENCODING_UTF8));
+
+ uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, uno::UNO_QUERY );
+ if( xLTS.is() )
+ extractLinks(xLTS->getLinks(), true, aJson);
+ }
+ }
+ }
+ catch(...)
+ {
+ SAL_WARN("lok", "extractLinks: Exception");
+ }
+ }
+ }
+}
+
+static void unoAnyToJson(tools::JsonWriter& rJson, std::string_view pNodeName, const uno::Any& anyItem)
{
auto aNode = rJson.startNode(pNodeName);
OUString aType = anyItem.getValueTypeName();
- rJson.put("type", aType.toUtf8().getStr());
+ rJson.put("type", aType);
if (aType == "string")
- rJson.put("value", anyItem.get<OUString>().toUtf8().getStr());
+ rJson.put("value", anyItem.get<OUString>());
else if (aType == "unsigned long")
- rJson.put("value", OString::number(anyItem.get<sal_uInt32>()).getStr());
+ rJson.put("value", OString::number(anyItem.get<sal_uInt32>()));
else if (aType == "long")
- rJson.put("value", OString::number(anyItem.get<sal_Int32>()).getStr());
+ rJson.put("value", OString::number(anyItem.get<sal_Int32>()));
else if (aType == "[]any")
{
uno::Sequence<uno::Any> aSeq;
@@ -397,59 +511,88 @@ static void unoAnyToJson(tools::JsonWriter& rJson, const char * pNodeName, const
for (auto i = 0; i < aSeq.getLength(); ++i)
{
- unoAnyToJson(rJson, OString::number(i).getStr(), aSeq[i]);
+ unoAnyToJson(rJson, OString::number(i), aSeq[i]);
}
}
}
}
-static int lcl_getViewId(const std::string& payload);
+static int lcl_getViewId(std::string_view payload);
namespace desktop {
-RectangleAndPart RectangleAndPart::Create(const std::string& rPayload)
+RectangleAndPart RectangleAndPart::Create(const OString& rPayload)
{
RectangleAndPart aRet;
- if (rPayload.compare(0, 5, "EMPTY") == 0) // payload starts with "EMPTY"
+ if (rPayload.startsWith("EMPTY")) // payload starts with "EMPTY"
{
aRet.m_aRectangle = tools::Rectangle(0, 0, SfxLokHelper::MaxTwips, SfxLokHelper::MaxTwips);
if (comphelper::LibreOfficeKit::isPartInInvalidation())
- aRet.m_nPart = std::stol(rPayload.substr(6));
+ {
+ int nSeparatorPos = rPayload.indexOf(',', 6);
+ bool bHasMode = nSeparatorPos > 0;
+ if (bHasMode)
+ {
+ aRet.m_nPart = o3tl::toInt32(rPayload.subView(6, nSeparatorPos - 6));
+ assert(rPayload.getLength() > nSeparatorPos);
+ aRet.m_nMode = o3tl::toInt32(rPayload.subView(nSeparatorPos + 1));
+ }
+ else
+ {
+ aRet.m_nPart = o3tl::toInt32(rPayload.subView(6));
+ aRet.m_nMode = 0;
+ }
+ }
return aRet;
}
- // Read '<left>, <top>, <width>, <height>[, <part>]'. C++ streams are simpler but slower.
- const char* pos = rPayload.c_str();
- const char* end = rPayload.c_str() + rPayload.size();
+ // Read '<left>, <top>, <width>, <height>[, <part>, <mode>]'. C++ streams are simpler but slower.
+ const char* pos = rPayload.getStr();
+ const char* end = rPayload.getStr() + rPayload.getLength();
tools::Long nLeft = rtl_str_toInt64_WithLength(pos, 10, end - pos);
- while( *pos != ',' )
+ while (pos < end && *pos != ',')
+ ++pos;
+ if (pos < end)
++pos;
- ++pos;
assert(pos < end);
tools::Long nTop = rtl_str_toInt64_WithLength(pos, 10, end - pos);
- while( *pos != ',' )
+ while (pos < end && *pos != ',')
+ ++pos;
+ if (pos < end)
++pos;
- ++pos;
assert(pos < end);
tools::Long nWidth = rtl_str_toInt64_WithLength(pos, 10, end - pos);
- while( *pos != ',' )
+ while (pos < end && *pos != ',')
+ ++pos;
+ if (pos < end)
++pos;
- ++pos;
assert(pos < end);
tools::Long nHeight = rtl_str_toInt64_WithLength(pos, 10, end - pos);
tools::Long nPart = INT_MIN;
+ tools::Long nMode = 0;
if (comphelper::LibreOfficeKit::isPartInInvalidation())
{
- while( *pos != ',' )
+ while (pos < end && *pos != ',')
+ ++pos;
+ if (pos < end)
++pos;
- ++pos;
assert(pos < end);
nPart = rtl_str_toInt64_WithLength(pos, 10, end - pos);
+
+ while (pos < end && *pos != ',')
+ ++pos;
+ if (pos < end)
+ {
+ ++pos;
+ assert(pos < end);
+ nMode = rtl_str_toInt64_WithLength(pos, 10, end - pos);
+ }
}
aRet.m_aRectangle = SanitizedRectangle(nLeft, nTop, nWidth, nHeight);
aRet.m_nPart = nPart;
+ aRet.m_nMode = nMode;
return aRet;
}
@@ -480,12 +623,12 @@ tools::Rectangle RectangleAndPart::SanitizedRectangle(tools::Long nLeft, tools::
tools::Rectangle RectangleAndPart::SanitizedRectangle(const tools::Rectangle& rect)
{
- return SanitizedRectangle(rect.Left(), rect.Top(), rect.getWidth(), rect.getHeight());
+ return SanitizedRectangle(rect.Left(), rect.Top(), rect.getOpenWidth(), rect.getOpenHeight());
}
-const std::string& CallbackFlushHandler::CallbackData::getPayload() const
+const OString& CallbackFlushHandler::CallbackData::getPayload() const
{
- if(PayloadString.empty())
+ if(PayloadString.isEmpty())
{
// Do to-string conversion on demand, as many calls will get dropped without
// needing the string.
@@ -528,7 +671,7 @@ void CallbackFlushHandler::CallbackData::setJson(const boost::property_tree::ptr
std::stringstream aJSONStream;
constexpr bool bPretty = false; // Don't waste time and bloat logs.
boost::property_tree::write_json(aJSONStream, rTree, bPretty);
- PayloadString = boost::trim_copy(aJSONStream.str());
+ PayloadString = OString(o3tl::trim(aJSONStream.str()));
PayloadObject = rTree;
}
@@ -567,7 +710,7 @@ bool CallbackFlushHandler::CallbackData::validate() const
std::stringstream aJSONStream;
boost::property_tree::write_json(aJSONStream, getJson(), false);
const std::string aExpected = boost::trim_copy(aJSONStream.str());
- return aExpected == getPayload();
+ return getPayload() == std::string_view(aExpected);
}
// View id.
@@ -625,7 +768,7 @@ static bool isUpdatedTypePerViewId(int type)
}
}
-static int lcl_getViewId(const std::string& payload)
+static int lcl_getViewId(std::string_view payload)
{
// this is a cheap way how to get the viewId from a JSON message; proper
// parsing is terribly expensive, and we just need the viewId here
@@ -644,7 +787,7 @@ static int lcl_getViewId(const std::string& payload)
}
if (numberPos < payload.length() && payload[numberPos] >= '0' && payload[numberPos] <= '9')
- return strtol(payload.substr(numberPos).c_str(), nullptr, 10);
+ return o3tl::toInt32(payload.substr(numberPos));
return 0;
}
@@ -653,8 +796,8 @@ namespace {
std::string extractCertificate(const std::string & certificate)
{
- const std::string header("-----BEGIN CERTIFICATE-----");
- const std::string footer("-----END CERTIFICATE-----");
+ static constexpr std::string_view header("-----BEGIN CERTIFICATE-----");
+ static constexpr std::string_view footer("-----END CERTIFICATE-----");
std::string result;
@@ -674,8 +817,8 @@ std::string extractCertificate(const std::string & certificate)
std::string extractPrivateKey(const std::string & privateKey)
{
- const std::string header("-----BEGIN PRIVATE KEY-----");
- const std::string footer("-----END PRIVATE KEY-----");
+ static constexpr std::string_view header("-----BEGIN PRIVATE KEY-----");
+ static constexpr std::string_view footer("-----END PRIVATE KEY-----");
std::string result;
@@ -758,6 +901,10 @@ void ExecuteMarginULChange(
// Main function which toggles page orientation of the Writer doc. Needed by ToggleOrientation
void ExecuteOrientationChange()
{
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (!pViewFrm)
+ return;
+
std::unique_ptr<SvxPageItem> pPageItem(new SvxPageItem(SID_ATTR_PAGE));
// 1mm in twips rounded
@@ -765,23 +912,20 @@ void ExecuteOrientationChange()
constexpr tools::Long MINBODY = o3tl::toTwips(1, o3tl::Length::mm);
css::uno::Reference< css::document::XUndoManager > mxUndoManager(
- getUndoManager( SfxViewFrame::Current()->GetFrame().GetFrameInterface() ) );
+ getUndoManager( pViewFrm->GetFrame().GetFrameInterface() ) );
if ( mxUndoManager.is() )
mxUndoManager->enterUndoContext( "" );
+ SfxPoolItemHolder aResult;
+ pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_SIZE, aResult);
+ std::unique_ptr<SvxSizeItem> pPageSizeItem(static_cast<const SvxSizeItem*>(aResult.getItem())->Clone());
- const SfxPoolItem* pItem;
-
-
- SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_SIZE, pItem);
- std::unique_ptr<SvxSizeItem> pPageSizeItem(&pItem->Clone()->StaticWhichCast(SID_ATTR_PAGE_SIZE));
+ pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_LRSPACE, aResult);
+ std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(static_cast<const SvxLongLRSpaceItem*>(aResult.getItem())->Clone());
- SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_LRSPACE, pItem);
- std::unique_ptr<SvxLongLRSpaceItem> pPageLRMarginItem(&pItem->Clone()->StaticWhichCast(SID_ATTR_PAGE_LRSPACE));
-
- SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_ULSPACE, pItem);
- std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(&pItem->Clone()->StaticWhichCast(SID_ATTR_PAGE_ULSPACE));
+ pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_ULSPACE, aResult);
+ std::unique_ptr<SvxLongULSpaceItem> pPageULMarginItem(static_cast<const SvxLongULSpaceItem*>(aResult.getItem())->Clone());
{
bool bIsLandscape = false;
@@ -851,58 +995,14 @@ void ExecuteOrientationChange()
mxUndoManager->leaveUndoContext();
}
-void setupSidebar(std::u16string_view sidebarDeckId = u"")
-{
- SfxViewShell* pViewShell = SfxViewShell::Current();
- SfxViewFrame* pViewFrame = pViewShell ? pViewShell->GetViewFrame() : nullptr;
- if (pViewFrame)
- {
- if (!pViewFrame->GetChildWindow(SID_SIDEBAR))
- pViewFrame->SetChildWindow(SID_SIDEBAR, false /* create it */, true /* focus */);
-
- pViewFrame->ShowChildWindow(SID_SIDEBAR, true);
-
- // Force synchronous population of panels
- SfxChildWindow *pChild = pViewFrame->GetChildWindow(SID_SIDEBAR);
- if (!pChild)
- return;
-
- auto pDockingWin = dynamic_cast<sfx2::sidebar::SidebarDockingWindow *>(pChild->GetWindow());
- if (!pDockingWin)
- return;
-
- OUString currentDeckId = pDockingWin->GetSidebarController()->GetCurrentDeckId();
-
- // check if it is the chart deck id, if it is, don't switch to default deck
- bool switchToDefault = true;
-
- if (currentDeckId == "ChartDeck")
- switchToDefault = false;
-
- if (!sidebarDeckId.empty())
- {
- pDockingWin->GetSidebarController()->SwitchToDeck(sidebarDeckId);
- }
- else
- {
- if (switchToDefault)
- pDockingWin->GetSidebarController()->SwitchToDefaultDeck();
- }
-
- pDockingWin->SyncUpdate();
- }
- else
- SetLastExceptionMsg("No view shell or sidebar");
-}
-
void hideSidebar()
{
SfxViewShell* pViewShell = SfxViewShell::Current();
- SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr;
+ SfxViewFrame* pViewFrame = pViewShell ? &pViewShell->GetViewFrame() : nullptr;
if (pViewFrame)
pViewFrame->SetChildWindow(SID_SIDEBAR, false , false );
else
- SetLastExceptionMsg("No view shell or sidebar");
+ SetLastExceptionMsg(u"No view shell or sidebar"_ustr);
}
} // end anonymous namespace
@@ -965,21 +1065,16 @@ static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect
static void doc_moveSelectedParts(LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate);
static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart);
static void doc_setPartMode(LibreOfficeKitDocument* pThis, int nPartMode);
+static int doc_getEditMode(LibreOfficeKitDocument* pThis);
static void doc_paintTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nCanvasWidth, const int nCanvasHeight,
const int nTilePosX, const int nTilePosY,
const int nTileWidth, const int nTileHeight);
-#ifdef IOS
-static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
- void* rCGContext,
- const int nCanvasWidth, const int nCanvasHeight,
- const int nTilePosX, const int nTilePosY,
- const int nTileWidth, const int nTileHeight);
-#endif
static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nPart,
+ const int nMode,
const int nCanvasWidth, const int nCanvasHeight,
const int nTilePosX, const int nTilePosY,
const int nTileWidth, const int nTileHeight);
@@ -987,6 +1082,10 @@ static int doc_getTileMode(LibreOfficeKitDocument* pThis);
static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
long* pWidth,
long* pHeight);
+static void doc_getDataArea(LibreOfficeKitDocument* pThis,
+ long nTab,
+ long* pCol,
+ long* pRow);
static void doc_initializeForRendering(LibreOfficeKitDocument* pThis,
const char* pArguments);
@@ -1055,6 +1154,10 @@ static char* doc_getTextSelection(LibreOfficeKitDocument* pThis,
const char* pMimeType,
char** pUsedMimeType);
static int doc_getSelectionType(LibreOfficeKitDocument* pThis);
+static int doc_getSelectionTypeAndText(LibreOfficeKitDocument* pThis,
+ const char* pMimeType,
+ char** pText,
+ char** pUsedMimeType);
static int doc_getClipboard (LibreOfficeKitDocument* pThis,
const char **pMimeTypes,
size_t *pOutCount,
@@ -1150,6 +1253,19 @@ static bool doc_renderSearchResult(LibreOfficeKitDocument* pThis,
const char* pSearchResult, unsigned char** pBitmapBuffer,
int* pWidth, int* pHeight, size_t* pByteSize);
+static void doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const char* pArguments);
+
+static void doc_setViewTimezone(LibreOfficeKitDocument* pThis, int nId, const char* timezone);
+
+static void doc_setViewReadOnly(LibreOfficeKitDocument* pThis, int nId, const bool readonly);
+
+static void doc_setAllowChangeComments(LibreOfficeKitDocument* pThis, int nId, const bool allow);
+
+static void doc_setAccessibilityState(LibreOfficeKitDocument* pThis, int nId, bool bEnabled);
+
+static char* doc_getA11yFocusedParagraph(LibreOfficeKitDocument* pThis);
+
+static int doc_getA11yCaretPosition(LibreOfficeKitDocument* pThis);
} // extern "C"
namespace {
@@ -1180,19 +1296,21 @@ rtl::Reference<LOKClipboard> forceSetClipboardForCurrentView(LibreOfficeKitDocum
#endif
-const vcl::Font* FindFont(const OUString& rFontName)
+const vcl::Font* FindFont(std::u16string_view rFontName)
{
SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ if (!pDocSh)
+ return nullptr;
const SvxFontListItem* pFonts
= static_cast<const SvxFontListItem*>(pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST));
const FontList* pList = pFonts ? pFonts->GetFontList() : nullptr;
- if (pList && !rFontName.isEmpty())
+ if (pList && !rFontName.empty())
if (sal_Handle hMetric = pList->GetFirstFontMetric(rFontName))
return &FontList::GetFontMetric(hMetric);
return nullptr;
}
-vcl::Font FindFont_FallbackToDefault(const OUString& rFontName)
+vcl::Font FindFont_FallbackToDefault(std::u16string_view rFontName)
{
if (auto pFound = FindFont(rFontName))
return *pFound;
@@ -1200,10 +1318,49 @@ vcl::Font FindFont_FallbackToDefault(const OUString& rFontName)
return OutputDevice::GetDefaultFont(DefaultFontType::SANS_UNICODE, LANGUAGE_NONE,
GetDefaultFontFlags::NONE);
}
+
+int getDocumentType (LibreOfficeKitDocument* pThis)
+{
+ SetLastExceptionMsg();
+
+ LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+
+ try
+ {
+ uno::Reference<lang::XServiceInfo> xDocument(pDocument->mxComponent, uno::UNO_QUERY_THROW);
+
+ if (xDocument->supportsService(u"com.sun.star.sheet.SpreadsheetDocument"_ustr))
+ {
+ return LOK_DOCTYPE_SPREADSHEET;
+ }
+ else if (xDocument->supportsService(u"com.sun.star.presentation.PresentationDocument"_ustr))
+ {
+ return LOK_DOCTYPE_PRESENTATION;
+ }
+ else if (xDocument->supportsService(u"com.sun.star.drawing.DrawingDocument"_ustr))
+ {
+ return LOK_DOCTYPE_DRAWING;
+ }
+ else if (xDocument->supportsService(u"com.sun.star.text.TextDocument"_ustr) || xDocument->supportsService(u"com.sun.star.text.WebDocument"_ustr))
+ {
+ return LOK_DOCTYPE_TEXT;
+ }
+ else
+ {
+ SetLastExceptionMsg(u"unknown document type"_ustr);
+ }
+ }
+ catch (const uno::Exception& exception)
+ {
+ SetLastExceptionMsg("exception: " + exception.Message);
+ }
+ return LOK_DOCTYPE_OTHER;
+}
+
} // anonymous namespace
-LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent, int nDocumentId)
- : mxComponent(xComponent)
+LibLODocument_Impl::LibLODocument_Impl(uno::Reference <css::lang::XComponent> xComponent, int nDocumentId)
+ : mxComponent(std::move(xComponent))
, mnDocumentId(nDocumentId)
{
assert(nDocumentId != -1 && "Cannot set mnDocumentId to -1");
@@ -1226,13 +1383,12 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->moveSelectedParts = doc_moveSelectedParts;
m_pDocumentClass->getPartName = doc_getPartName;
m_pDocumentClass->setPartMode = doc_setPartMode;
+ m_pDocumentClass->getEditMode = doc_getEditMode;
m_pDocumentClass->paintTile = doc_paintTile;
-#ifdef IOS
- m_pDocumentClass->paintTileToCGContext = doc_paintTileToCGContext;
-#endif
m_pDocumentClass->paintPartTile = doc_paintPartTile;
m_pDocumentClass->getTileMode = doc_getTileMode;
m_pDocumentClass->getDocumentSize = doc_getDocumentSize;
+ m_pDocumentClass->getDataArea = doc_getDataArea;
m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
m_pDocumentClass->registerCallback = doc_registerCallback;
m_pDocumentClass->postKeyEvent = doc_postKeyEvent;
@@ -1247,6 +1403,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->setWindowTextSelection = doc_setWindowTextSelection;
m_pDocumentClass->getTextSelection = doc_getTextSelection;
m_pDocumentClass->getSelectionType = doc_getSelectionType;
+ m_pDocumentClass->getSelectionTypeAndText = doc_getSelectionTypeAndText;
m_pDocumentClass->getClipboard = doc_getClipboard;
m_pDocumentClass->setClipboard = doc_setClipboard;
m_pDocumentClass->paste = doc_paste;
@@ -1293,6 +1450,19 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->setBlockedCommandList = doc_setBlockedCommandList;
+ m_pDocumentClass->sendContentControlEvent = doc_sendContentControlEvent;
+
+ m_pDocumentClass->setViewTimezone = doc_setViewTimezone;
+
+ m_pDocumentClass->setAccessibilityState = doc_setAccessibilityState;
+
+ m_pDocumentClass->getA11yFocusedParagraph = doc_getA11yFocusedParagraph;
+ m_pDocumentClass->getA11yCaretPosition = doc_getA11yCaretPosition;
+
+ m_pDocumentClass->setViewReadOnly = doc_setViewReadOnly;
+
+ m_pDocumentClass->setAllowChangeComments = doc_setAllowChangeComments;
+
gDocumentClass = m_pDocumentClass;
}
pClass = m_pDocumentClass.get();
@@ -1317,8 +1487,8 @@ LibLODocument_Impl::~LibLODocument_Impl()
static OUString getGenerator()
{
OUString sGenerator(
- Translate::ExpandVariables("%PRODUCTNAME %PRODUCTVERSION%PRODUCTEXTENSION (%1)"));
- OUString os("$_OS");
+ Translate::ExpandVariables(u"%PRODUCTNAME %PRODUCTVERSION%PRODUCTEXTENSION (%1)"_ustr));
+ OUString os(u"$_OS"_ustr);
::rtl::Bootstrap::expandMacros(os);
return sGenerator.replaceFirst("%1", os);
}
@@ -1353,20 +1523,20 @@ CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, Li
// Add the states that are safe to skip duplicates on, even when
// not consequent (i.e. do no emit them if unchanged from last).
- m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL");
- m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL");
- m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL");
- m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL");
- m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL");
- m_states.emplace(LOK_CALLBACK_CELL_CURSOR, "NIL");
- m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL");
- m_states.emplace(LOK_CALLBACK_CELL_ADDRESS, "NIL");
- m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL");
- m_states.emplace(LOK_CALLBACK_SET_PART, "NIL");
- m_states.emplace(LOK_CALLBACK_TABLE_SELECTED, "NIL");
- m_states.emplace(LOK_CALLBACK_TAB_STOP_LIST, "NIL");
- m_states.emplace(LOK_CALLBACK_RULER_UPDATE, "NIL");
- m_states.emplace(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE, "NIL");
+ m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_CELL_CURSOR, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_CELL_ADDRESS, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_SET_PART, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_TABLE_SELECTED, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_TAB_STOP_LIST, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_RULER_UPDATE, "NIL"_ostr);
+ m_states.emplace(LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE, "NIL"_ostr);
}
CallbackFlushHandler::~CallbackFlushHandler()
@@ -1392,6 +1562,8 @@ void CallbackFlushHandler::setUpdatedType( int nType, bool value )
if( m_updatedTypes.size() <= o3tl::make_unsigned( nType ))
m_updatedTypes.resize( nType + 1 ); // new are default-constructed, i.e. false
m_updatedTypes[ nType ] = value;
+ if(value)
+ startTimer();
}
void CallbackFlushHandler::resetUpdatedType( int nType )
@@ -1406,6 +1578,8 @@ void CallbackFlushHandler::setUpdatedTypePerViewId( int nType, int nViewId, int
if( types.size() <= o3tl::make_unsigned( nType ))
types.resize( nType + 1 ); // new are default-constructed, i.e. 'set' is false
types[ nType ] = PerViewIdData{ value, nSourceViewId };
+ if(value)
+ startTimer();
}
void CallbackFlushHandler::resetUpdatedTypePerViewId( int nType, int nViewId )
@@ -1428,28 +1602,28 @@ void CallbackFlushHandler::resetUpdatedTypePerViewId( int nType, int nViewId )
}
}
-void CallbackFlushHandler::libreOfficeKitViewCallback(int nType, const char* pPayload)
+void CallbackFlushHandler::libreOfficeKitViewCallback(int nType, const OString& pPayload)
{
CallbackData callbackData(pPayload);
queue(nType, callbackData);
}
-void CallbackFlushHandler::libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId)
+void CallbackFlushHandler::libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId)
{
CallbackData callbackData(pPayload, nViewId);
queue(nType, callbackData);
}
-void CallbackFlushHandler::libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart)
+void CallbackFlushHandler::libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart, int nMode)
{
- CallbackData callbackData(pRect, nPart);
+ CallbackData callbackData(pRect, nPart, nMode);
queue(LOK_CALLBACK_INVALIDATE_TILES, callbackData);
}
void CallbackFlushHandler::libreOfficeKitViewUpdatedCallback(int nType)
{
assert(isUpdatedType( nType ));
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::unique_lock<std::recursive_mutex> lock(m_mutex);
SAL_INFO("lok", "Updated: [" << nType << "]");
setUpdatedType(nType, true);
}
@@ -1457,12 +1631,35 @@ void CallbackFlushHandler::libreOfficeKitViewUpdatedCallback(int nType)
void CallbackFlushHandler::libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId)
{
assert(isUpdatedTypePerViewId( nType ));
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::unique_lock<std::recursive_mutex> lock(m_mutex);
SAL_INFO("lok", "Updated: [" << nType << "]");
setUpdatedTypePerViewId(nType, nViewId, nSourceViewId, true);
}
-void CallbackFlushHandler::queue(const int type, const char* data)
+void CallbackFlushHandler::dumpState(rtl::OStringBuffer &rState)
+{
+ // NB. no locking
+ rState.append("\nView:\t");
+ rState.append(static_cast<sal_Int32>(m_viewId));
+ rState.append("\n\tDisableCallbacks:\t");
+ rState.append(static_cast<sal_Int32>(m_nDisableCallbacks));
+ rState.append("\n\tStates:\n");
+ for (const auto &i : m_states)
+ {
+ rState.append("\n\t\t");
+ rState.append(static_cast<sal_Int32>(i.first));
+ rState.append("\t");
+ rState.append(i.second);
+ }
+}
+
+void CallbackFlushHandler::libreOfficeKitViewAddPendingInvalidateTiles()
+{
+ // Invoke() will call flushPendingLOKInvalidateTiles(), so just make sure the timer is active.
+ startTimer();
+}
+
+void CallbackFlushHandler::queue(const int type, const OString& data)
{
CallbackData callbackData(data);
queue(type, callbackData);
@@ -1475,13 +1672,18 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
SAL_INFO("lok", "Queue: [" << type << "]: [" << aCallbackData.getPayload() << "] on " << m_queue1.size() << " entries.");
bool bIsChartActive = false;
+ bool bIsComment = false;
if (type == LOK_CALLBACK_GRAPHIC_SELECTION)
{
LokChartHelper aChartHelper(SfxViewShell::Current());
bIsChartActive = aChartHelper.GetWindow() != nullptr;
}
+ else if (type == LOK_CALLBACK_COMMENT)
+ {
+ bIsComment = true;
+ }
- if (callbacksDisabled() && !bIsChartActive)
+ if (callbacksDisabled() && !bIsChartActive && !bIsComment)
{
// We drop notifications when this is set, except for important ones.
// When we issue a complex command (such as .uno:InsertAnnotation)
@@ -1498,6 +1700,7 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
type != LOK_CALLBACK_TEXT_SELECTION &&
type != LOK_CALLBACK_TEXT_SELECTION_START &&
type != LOK_CALLBACK_TEXT_SELECTION_END &&
+ type != LOK_CALLBACK_MEDIA_SHAPE &&
type != LOK_CALLBACK_REFERENCE_MARKS)
{
SAL_INFO("lok", "Skipping while painting [" << type << "]: [" << aCallbackData.getPayload() << "].");
@@ -1511,9 +1714,9 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
// Suppress invalid payloads.
if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
- aCallbackData.getPayload().find(", 0, 0, ") != std::string::npos &&
- aCallbackData.getPayload().find("\"hyperlink\":\"\"") == std::string::npos &&
- aCallbackData.getPayload().find("\"hyperlink\": {}") == std::string::npos)
+ aCallbackData.getPayload().indexOf(", 0, 0, ") != -1 &&
+ aCallbackData.getPayload().indexOf("\"hyperlink\":\"\"") == -1 &&
+ aCallbackData.getPayload().indexOf("\"hyperlink\": {}") == -1)
{
// The cursor position is often the relative coordinates of the widget
// issuing it, instead of the absolute one that we expect.
@@ -1523,7 +1726,7 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
return;
}
- std::unique_lock<std::mutex> lock(m_mutex);
+ std::unique_lock<std::recursive_mutex> lock(m_mutex);
// Update types should be received via the updated callbacks for performance,
// getting them as normal callbacks is technically not wrong, but probably should be avoided.
@@ -1566,6 +1769,13 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
case LOK_CALLBACK_REFERENCE_MARKS:
case LOK_CALLBACK_CELL_AUTO_FILL_AREA:
+ case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
+ case LOK_CALLBACK_A11Y_CARET_CHANGED:
+ case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
+ case LOK_CALLBACK_A11Y_FOCUSED_CELL_CHANGED:
+ case LOK_CALLBACK_COLOR_PALETTES:
+ case LOK_CALLBACK_A11Y_EDITING_IN_SELECTION_STATE:
+ case LOK_CALLBACK_A11Y_SELECTION_CHANGED:
{
const auto& pos = std::find(m_queue1.rbegin(), m_queue1.rend(), type);
auto pos2 = toQueue2(pos);
@@ -1602,6 +1812,7 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
case LOK_CALLBACK_GRAPHIC_SELECTION:
case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
case LOK_CALLBACK_INVALIDATE_TILES:
+ case LOK_CALLBACK_TOOLTIP:
if (removeAll(type))
SAL_INFO("lok", "Removed dups of [" << type << "]: [" << aCallbackData.getPayload() << "].");
break;
@@ -1624,6 +1835,13 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
case LOK_CALLBACK_SET_PART:
case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
case LOK_CALLBACK_RULER_UPDATE:
+ case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
+ case LOK_CALLBACK_A11Y_CARET_CHANGED:
+ case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
+ case LOK_CALLBACK_A11Y_FOCUSED_CELL_CHANGED:
+ case LOK_CALLBACK_COLOR_PALETTES:
+ case LOK_CALLBACK_TOOLTIP:
+ case LOK_CALLBACK_SHAPE_INNER_TEXT:
{
if (removeAll(type))
SAL_INFO("lok", "Removed dups of [" << type << "]: [" << aCallbackData.getPayload() << "].");
@@ -1633,28 +1851,26 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
// These are safe to use the latest state and ignore previous
// ones (if any) since the last overrides previous ones,
// but only if the view is the same.
+ case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
+ // deleting the duplicate of visible cursor message can cause hyperlink popup not to show up on second/or more click on the same place.
+ // If the hyperlink is not empty we can bypass that to show the popup
+ if (aCallbackData.getPayload().indexOf("\"hyperlink\":\"\"") == -1
+ && aCallbackData.getPayload().indexOf("\"hyperlink\": {}") == -1)
+ break;
+ [[fallthrough]];
case LOK_CALLBACK_CELL_VIEW_CURSOR:
case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
- case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
case LOK_CALLBACK_TEXT_VIEW_SELECTION:
case LOK_CALLBACK_VIEW_CURSOR_VISIBLE:
case LOK_CALLBACK_CALC_FUNCTION_LIST:
case LOK_CALLBACK_FORM_FIELD_BUTTON:
{
- // deleting the duplicate of visible cursor message can cause hyperlink popup not to show up on second/or more click on the same place.
- // If the hyperlink is not empty we can bypass that to show the popup
- const bool hyperLinkException = type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
- aCallbackData.getPayload().find("\"hyperlink\":\"\"") == std::string::npos &&
- aCallbackData.getPayload().find("\"hyperlink\": {}") == std::string::npos;
- if(!hyperLinkException)
- {
- const int nViewId = aCallbackData.getViewId();
- removeAll(type, [nViewId] (const CallbackData& elemData) {
- return (nViewId == elemData.getViewId());
- }
- );
- }
+ const int nViewId = aCallbackData.getViewId();
+ removeAll(type, [nViewId] (const CallbackData& elemData) {
+ return (nViewId == elemData.getViewId());
+ }
+ );
}
break;
@@ -1668,16 +1884,16 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
case LOK_CALLBACK_STATE_CHANGED:
{
// Compare the state name=value and overwrite earlier entries with same name.
- const auto pos = aCallbackData.getPayload().find('=');
- if (pos != std::string::npos)
+ const auto pos = aCallbackData.getPayload().indexOf('=');
+ if (pos != -1)
{
- const std::string name = aCallbackData.getPayload().substr(0, pos + 1);
+ const std::string_view name = aCallbackData.getPayload().subView(0, pos + 1);
// This is needed because otherwise it creates some problems when
// a save occurs while a cell is still edited in Calc.
if (name != ".uno:ModifiedStatus=")
{
removeAll(type, [&name] (const CallbackData& elemData) {
- return (elemData.getPayload().compare(0, name.size(), name) == 0);
+ return elemData.getPayload().startsWith(name);
}
);
}
@@ -1695,7 +1911,7 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
// remove only selection ranges and 'EMPTY' messages
// always send 'INPLACE' and 'INPLACE EXIT' messages
removeAll(type, [] (const CallbackData& elemData)
- { return (elemData.getPayload().find("INPLACE") == std::string::npos); });
+ { return (elemData.getPayload().indexOf("INPLACE") == -1); });
}
break;
}
@@ -1730,12 +1946,7 @@ void CallbackFlushHandler::queue(const int type, CallbackData& aCallbackData)
#endif
lock.unlock();
- if (!IsActive())
- {
- Start();
- }
- if (!m_TimeoutIdle.IsActive())
- m_TimeoutIdle.Start();
+ startTimer();
}
bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& aCallbackData)
@@ -1755,14 +1966,15 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
{
auto pos2 = toQueue2(pos);
const RectangleAndPart& rcOld = pos2->getRectangleAndPart();
- if (rcOld.isInfinite() && (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart))
+ if (rcOld.isInfinite() && (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart) &&
+ (rcOld.m_nMode == rcNew.m_nMode))
{
SAL_INFO("lok", "Skipping queue [" << type << "]: [" << aCallbackData.getPayload()
<< "] since all tiles need to be invalidated.");
return true;
}
- if (rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart)
+ if ((rcOld.m_nPart == -1 || rcOld.m_nPart == rcNew.m_nPart) && (rcOld.m_nMode == rcNew.m_nMode))
{
// If fully overlapping.
if (rcOld.m_aRectangle.Contains(rcNew.m_aRectangle))
@@ -1780,7 +1992,8 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
<< "] so removing all with part " << rcNew.m_nPart << ".");
removeAll(LOK_CALLBACK_INVALIDATE_TILES, [&rcNew](const CallbackData& elemData) {
// Remove exiting if new is all-encompassing, or if of the same part.
- return (rcNew.m_nPart == -1 || rcNew.m_nPart == elemData.getRectangleAndPart().m_nPart);
+ return ((rcNew.m_nPart == -1 || rcNew.m_nPart == elemData.getRectangleAndPart().m_nPart)
+ && (rcNew.m_nMode == elemData.getRectangleAndPart().m_nMode));
});
}
else
@@ -1790,7 +2003,8 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
SAL_INFO("lok", "Have [" << type << "]: [" << aCallbackData.getPayload() << "] so merging overlapping.");
removeAll(LOK_CALLBACK_INVALIDATE_TILES,[&rcNew](const CallbackData& elemData) {
const RectangleAndPart& rcOld = elemData.getRectangleAndPart();
- if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 && rcOld.m_nPart != rcNew.m_nPart)
+ if (rcNew.m_nPart != -1 && rcOld.m_nPart != -1 &&
+ (rcOld.m_nPart != rcNew.m_nPart || rcOld.m_nMode != rcNew.m_nMode))
{
SAL_INFO("lok", "Nothing to merge between new: "
<< rcNew.toString() << ", and old: " << rcOld.toString());
@@ -1802,7 +2016,7 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
// Don't merge unless fully overlapped.
SAL_INFO("lok", "New " << rcNew.toString() << " has " << rcOld.toString()
<< "?");
- if (rcNew.m_aRectangle.Contains(rcOld.m_aRectangle))
+ if (rcNew.m_aRectangle.Contains(rcOld.m_aRectangle) && rcOld.m_nMode == rcNew.m_nMode)
{
SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".");
@@ -1814,7 +2028,7 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
// Don't merge unless fully overlapped.
SAL_INFO("lok", "Old " << rcOld.toString() << " has " << rcNew.toString()
<< "?");
- if (rcOld.m_aRectangle.Contains(rcNew.m_aRectangle))
+ if (rcOld.m_aRectangle.Contains(rcNew.m_aRectangle) && rcOld.m_nMode == rcNew.m_nMode)
{
SAL_INFO("lok", "New " << rcNew.toString() << " engulfs old "
<< rcOld.toString() << ".");
@@ -1825,7 +2039,7 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
{
const tools::Rectangle rcOverlap
= rcNew.m_aRectangle.GetIntersection(rcOld.m_aRectangle);
- const bool bOverlap = !rcOverlap.IsEmpty();
+ const bool bOverlap = !rcOverlap.IsEmpty() && rcOld.m_nMode == rcNew.m_nMode;
SAL_INFO("lok", "Merging " << rcNew.toString() << " & " << rcOld.toString()
<< " => " << rcOverlap.toString()
<< " Overlap: " << bOverlap);
@@ -1859,9 +2073,9 @@ bool CallbackFlushHandler::processInvalidateTilesEvent(int type, CallbackData& a
bool CallbackFlushHandler::processWindowEvent(int type, CallbackData& aCallbackData)
{
- const std::string& payload = aCallbackData.getPayload();
+ const OString& payload = aCallbackData.getPayload();
- boost::property_tree::ptree& aTree = aCallbackData.setJson(payload);
+ boost::property_tree::ptree& aTree = aCallbackData.setJson(std::string(payload));
const unsigned nLOKWindowId = aTree.get<unsigned>("id", 0);
const std::string aAction = aTree.get<std::string>("action", "");
if (aAction == "invalidate")
@@ -2000,7 +2214,7 @@ bool CallbackFlushHandler::processWindowEvent(int type, CallbackData& aCallbackD
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- gImpl->maLastExceptionMsg = "Document doesn't support dialog rendering, or window not found.";
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return false;
}
@@ -2037,7 +2251,7 @@ void CallbackFlushHandler::enqueueUpdatedTypes()
return;
assert(m_viewId >= 0);
SfxViewShell* viewShell = SfxViewShell::GetFirst( false,
- [this](const SfxViewShell* shell) { return shell->GetViewShellId().get() == m_viewId; } );
+ [this](const SfxViewShell& shell) { return shell.GetViewShellId().get() == m_viewId; } );
assert(viewShell != nullptr);
// First move data to local structures, so that callbacks don't possibly modify it.
@@ -2080,7 +2294,7 @@ void CallbackFlushHandler::enqueueUpdatedTypes()
{
assert(sourceViewId >= 0);
sourceViewShell = SfxViewShell::GetFirst( false,
- [sourceViewId](const SfxViewShell* shell) { return shell->GetViewShellId().get() == sourceViewId; } );
+ [sourceViewId](const SfxViewShell& shell) { return shell.GetViewShellId().get() == sourceViewId; } );
}
if(sourceViewShell == nullptr)
{
@@ -2095,11 +2309,15 @@ void CallbackFlushHandler::enqueueUpdatedTypes()
void CallbackFlushHandler::enqueueUpdatedType( int type, const SfxViewShell* viewShell, int viewId )
{
- bool ignore = false;
- OString payload = viewShell->getLOKPayload( type, viewId, &ignore );
- if(ignore)
+ if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR)
+ {
+ if (const SfxViewShell* viewShell2 = LokStarMathHelper(viewShell).GetSmViewShell())
+ viewShell = viewShell2;
+ }
+ std::optional<OString> payload = viewShell->getLOKPayload( type, viewId );
+ if(!payload)
return; // No actual payload to send.
- CallbackData callbackData(payload.getStr(), viewId);
+ CallbackData callbackData(*payload, viewId);
m_queue1.emplace_back(type);
m_queue2.emplace_back(callbackData);
SAL_INFO("lok", "Queued updated [" << type << "]: [" << callbackData.getPayload()
@@ -2117,12 +2335,12 @@ void CallbackFlushHandler::Invoke()
// so it must be done before taking the mutex.
assert(m_viewId >= 0);
if(SfxViewShell* viewShell = SfxViewShell::GetFirst( false,
- [this](const SfxViewShell* shell) { return shell->GetViewShellId().get() == m_viewId; } ))
+ [this](const SfxViewShell& shell) { return shell.GetViewShellId().get() == m_viewId; } ))
{
viewShell->flushPendingLOKInvalidateTiles();
}
- std::scoped_lock<std::mutex> lock(m_mutex);
+ std::unique_lock<std::recursive_mutex> lock(m_mutex);
// Append messages for updated types, fetch them only now.
enqueueUpdatedTypes();
@@ -2141,13 +2359,13 @@ void CallbackFlushHandler::Invoke()
// common code-path for events on this view:
if (viewId == -1)
{
- size_t idx;
+ sal_Int32 idx;
// key-value pairs
if (type == LOK_CALLBACK_STATE_CHANGED &&
- (idx = payload.find('=')) != std::string::npos)
+ (idx = payload.indexOf('=')) != -1)
{
- std::string key = payload.substr(0, idx);
- std::string value = payload.substr(idx+1);
+ OString key = payload.copy(0, idx);
+ OString value = payload.copy(idx+1);
const auto stateIt = m_lastStateChange.find(key);
if (stateIt != m_lastStateChange.end())
{
@@ -2209,7 +2427,7 @@ void CallbackFlushHandler::Invoke()
}
}
- m_pCallback(type, payload.c_str(), m_pData);
+ m_pCallback(type, payload.getStr(), m_pData);
}
m_queue1.clear();
@@ -2218,6 +2436,14 @@ void CallbackFlushHandler::Invoke()
m_TimeoutIdle.Stop();
}
+void CallbackFlushHandler::startTimer()
+{
+ if (!IsActive())
+ Start();
+ if (!m_TimeoutIdle.IsActive())
+ m_TimeoutIdle.Start();
+}
+
bool CallbackFlushHandler::removeAll(int type)
{
bool bErased = false;
@@ -2311,6 +2537,22 @@ static bool lo_signDocument(LibreOfficeKit* pThis,
const unsigned char* pPrivateKeyBinary,
const int nPrivateKeyBinarySize);
+static char* lo_extractRequest(LibreOfficeKit* pThis,
+ const char* pFilePath);
+
+static void lo_trimMemory(LibreOfficeKit* pThis, int nTarget);
+
+static void*
+lo_startURP(LibreOfficeKit* pThis, void* pReceiveURPFromLOContext, void* pSendURPToLOContext,
+ int (*fnReceiveURPFromLO)(void* pContext, const signed char* pBuffer, int nLen),
+ int (*fnSendURPToLO)(void* pContext, signed char* pBuffer, int nLen));
+
+static void lo_stopURP(LibreOfficeKit* pThis, void* pSendURPToLOContext);
+
+static int lo_joinThreads(LibreOfficeKit* pThis);
+
+static void lo_setForkedChild(LibreOfficeKit* pThis, bool bIsChild);
+
static void lo_runLoop(LibreOfficeKit* pThis,
LibreOfficeKitPollCallback pPollCallback,
LibreOfficeKitWakeCallback pWakeCallback,
@@ -2322,6 +2564,8 @@ static void lo_sendDialogEvent(LibreOfficeKit* pThis,
static void lo_setOption(LibreOfficeKit* pThis, const char* pOption, const char* pValue);
+static void lo_dumpState(LibreOfficeKit* pThis, const char* pOptions, char** pState);
+
LibLibreOffice_Impl::LibLibreOffice_Impl()
: m_pOfficeClass( gOfficeClass.lock() )
, maThread(nullptr)
@@ -2348,6 +2592,13 @@ LibLibreOffice_Impl::LibLibreOffice_Impl()
m_pOfficeClass->runLoop = lo_runLoop;
m_pOfficeClass->sendDialogEvent = lo_sendDialogEvent;
m_pOfficeClass->setOption = lo_setOption;
+ m_pOfficeClass->dumpState = lo_dumpState;
+ m_pOfficeClass->extractRequest = lo_extractRequest;
+ m_pOfficeClass->trimMemory = lo_trimMemory;
+ m_pOfficeClass->startURP = lo_startURP;
+ m_pOfficeClass->stopURP = lo_stopURP;
+ m_pOfficeClass->joinThreads = lo_joinThreads;
+ m_pOfficeClass->setForkedChild = lo_setForkedChild;
gOfficeClass = m_pOfficeClass;
}
@@ -2362,41 +2613,6 @@ LibLibreOffice_Impl::~LibLibreOffice_Impl()
namespace
{
-#ifdef IOS
-void paintTileToCGContext(ITiledRenderable* pDocument,
- void* rCGContext, const Size nCanvasSize,
- const int nTilePosX, const int nTilePosY,
- const int nTileWidth, const int nTileHeight)
-{
- SystemGraphicsData aData;
- aData.rCGContext = reinterpret_cast<CGContextRef>(rCGContext);
-
- ScopedVclPtrInstance<VirtualDevice> pDevice(aData, Size(1, 1), DeviceFormat::DEFAULT);
- pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
- pDevice->SetOutputSizePixel(nCanvasSize);
- pDocument->paintTile(*pDevice, nCanvasSize.Width(), nCanvasSize.Height(),
- nTilePosX, nTilePosY, nTileWidth, nTileHeight);
-}
-
-void paintTileIOS(LibreOfficeKitDocument* pThis,
- unsigned char* pBuffer,
- const int nCanvasWidth, const int nCanvasHeight, const double fDPIScale,
- const int nTilePosX, const int nTilePosY,
- const int nTileWidth, const int nTileHeight)
-{
- CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
- nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
- kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little);
-
- CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
- CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
-
- doc_paintTileToCGContext(pThis, (void*) pCGContext, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
-
- CGContextRelease(pCGContext);
-}
-#endif
-
void setLanguageAndLocale(OUString const & aLangISO)
{
SvtSysLocaleOptions aLocalOptions;
@@ -2410,7 +2626,7 @@ void setFormatSpecificFilterData(std::u16string_view sFormat, comphelper::Sequen
if (sFormat == u"pdf")
{
// always export bookmarks, which is needed for annotations
- rFilterDataMap["ExportBookmarks"] <<= true;
+ rFilterDataMap[u"ExportBookmarks"_ustr] <<= true;
}
}
@@ -2440,7 +2656,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
const OUString aURL(getAbsoluteURL(pURL));
if (aURL.isEmpty())
{
- pLib->maLastExceptionMsg = "Filename to load was not provided.";
+ pLib->maLastExceptionMsg = u"Filename to load was not provided."_ustr;
SAL_INFO("lok", "URL for load is empty");
return nullptr;
}
@@ -2449,7 +2665,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
if (!xContext.is())
{
- pLib->maLastExceptionMsg = "ComponentContext is not available";
+ pLib->maLastExceptionMsg = u"ComponentContext is not available"_ustr;
SAL_INFO("lok", "ComponentContext is not available");
return nullptr;
}
@@ -2458,7 +2674,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
if (!xComponentLoader.is())
{
- pLib->maLastExceptionMsg = "ComponentLoader is not available";
+ pLib->maLastExceptionMsg = u"ComponentLoader is not available"_ustr;
SAL_INFO("lok", "ComponentLoader is not available");
return nullptr;
}
@@ -2469,10 +2685,17 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
// not pass it as a parameter to the filter
OUString aOptions = getUString(pOptions);
const OUString aLanguage = extractParameter(aOptions, u"Language");
- bool isValidLangTag = LanguageTag::isValidBcp47(aLanguage, nullptr);
- if (!aLanguage.isEmpty() && isValidLangTag)
+ if (!aLanguage.isEmpty() && LanguageTag::isValidBcp47(aLanguage, nullptr))
{
+ static bool isLoading = true;
+ if (isLoading)
+ {
+ // Capture the language used to load the document.
+ SfxLokHelper::setLoadLanguage(aLanguage);
+ isLoading = false;
+ }
+
SfxLokHelper::setDefaultLanguage(aLanguage);
// Set the LOK language tag, used for dialog tunneling.
comphelper::LibreOfficeKit::setLanguageTag(LanguageTag(aLanguage));
@@ -2486,6 +2709,27 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
SvNumberFormatter::resetTheCurrencyTable();
}
+ // Set the timezone, if not empty.
+ const OUString aTimezone = extractParameter(aOptions, u"Timezone");
+ if (!aTimezone.isEmpty())
+ {
+ SfxLokHelper::setDefaultTimezone(true, aTimezone);
+ }
+ else
+ {
+ // Default to the TZ envar, if set.
+ const char* tz = ::getenv("TZ");
+ if (tz)
+ {
+ SfxLokHelper::setDefaultTimezone(true,
+ OStringToOUString(tz, RTL_TEXTENCODING_UTF8));
+ }
+ else
+ {
+ SfxLokHelper::setDefaultTimezone(false, OUString());
+ }
+ }
+
const OUString aDeviceFormFactor = extractParameter(aOptions, u"DeviceFormFactor");
SfxLokHelper::setDeviceFormFactor(aDeviceFormFactor);
@@ -2495,10 +2739,8 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
Application::SetDialogCancelMode(DialogCancelMode::LOKSilent);
}
- const OUString sFilterOptions = aOptions;
-
rtl::Reference<LOKInteractionHandler> const pInteraction(
- new LOKInteractionHandler("load", pLib));
+ new LOKInteractionHandler("load"_ostr, pLib));
auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction)));
comphelper::ScopeGuard const g([&] () {
if (pair.second)
@@ -2528,10 +2770,15 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
document::MacroExecMode::NEVER_EXECUTE;
#endif
+ // set AsTemplate explicitly false to be able to load template files
+ // as regular files, otherwise we cannot save them; it will try
+ // to bring saveas dialog which cannot work with LOK case
uno::Sequence<css::beans::PropertyValue> aFilterOptions{
- comphelper::makePropertyValue("FilterOptions", sFilterOptions),
- comphelper::makePropertyValue("InteractionHandler", xInteraction),
- comphelper::makePropertyValue("MacroExecutionMode", nMacroExecMode)
+ comphelper::makePropertyValue(u"FilterOptions"_ustr, aOptions),
+ comphelper::makePropertyValue(u"InteractionHandler"_ustr, xInteraction),
+ comphelper::makePropertyValue(u"MacroExecutionMode"_ustr, nMacroExecMode),
+ comphelper::makePropertyValue(u"AsTemplate"_ustr, false),
+ comphelper::makePropertyValue(u"Silent"_ustr, !aBatch.isEmpty())
};
/* TODO
@@ -2540,17 +2787,19 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
aFilterOptions[3].Value <<= nUpdateDoc;
*/
+ OutputDevice::StartTrackingFontMappingUse();
+
const int nThisDocumentId = nDocumentIdCounter++;
SfxViewShell::SetCurrentDocId(ViewShellDocId(nThisDocumentId));
uno::Reference<lang::XComponent> xComponent = xComponentLoader->loadComponentFromURL(
- aURL, "_blank", 0,
+ aURL, u"_blank"_ustr, 0,
aFilterOptions);
assert(!xComponent.is() || pair.second); // concurrent loading of same URL ought to fail
if (!xComponent.is())
{
- pLib->maLastExceptionMsg = "loadComponentFromURL returned an empty reference";
+ pLib->maLastExceptionMsg = u"loadComponentFromURL returned an empty reference"_ustr;
SAL_INFO("lok", "Document can't be loaded - " << pLib->maLastExceptionMsg);
return nullptr;
}
@@ -2563,6 +2812,102 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
int nState = doc_getSignatureState(pDocument);
pLib->mpCallback(LOK_CALLBACK_SIGNATURE_STATUS, OString::number(nState).getStr(), pLib->mpCallbackData);
}
+
+ auto aFontMappingUseData = OutputDevice::FinishTrackingFontMappingUse();
+
+ if (aFontMappingUseData.size() > 0)
+ {
+ SAL_INFO("lok.fontsubst", "================ Original substitutions:");
+ for (const auto &i : aFontMappingUseData)
+ {
+ SAL_INFO("lok.fontsubst", i.mOriginalFont);
+ for (const auto &j : i.mUsedFonts)
+ SAL_INFO("lok.fontsubst", " " << j);
+ }
+ }
+
+ // Filter out font substitutions that actually aren't any substitutions, like "Liberation
+ // Serif" -> "Liberation Serif/Regular". If even one of the "substitutions" of a font is to
+ // the same font, don't count that as a missing font.
+
+ std::erase_if
+ (aFontMappingUseData,
+ [](OutputDevice::FontMappingUseItem x)
+ {
+ // If the original font had an empty style and one of its
+ // replacement fonts has the same family name, we assume the font is
+ // present. The root problem here is that the code that collects
+ // font substitutions tends to get just empty styles for the font
+ // that is being substituted, as vcl::Font::GetStyleName() tends to
+ // return an empty string. (Italicness is instead indicated by what
+ // vcl::Font::GetItalic() returns and boldness by what
+ // vcl::Font::GetWeight() returns.)
+
+ if (x.mOriginalFont.indexOf('/') == -1)
+ for (const auto &j : x.mUsedFonts)
+ if (j == x.mOriginalFont ||
+ j.startsWith(Concat2View(x.mOriginalFont + "/")))
+ return true;
+
+ return false;
+ });
+
+ // Filter out substitutions where a proprietary font has been substituted by a
+ // metric-compatible one. Obviously this is just a heuristic and implemented only for some
+ // well-known cases.
+
+ std::erase_if
+ (aFontMappingUseData,
+ [](OutputDevice::FontMappingUseItem x)
+ {
+ // Again, handle only cases where the original font does not include
+ // a style. Unclear whether there ever will be a style part included
+ // in the mOriginalFont.
+
+ if (x.mOriginalFont.indexOf('/') == -1)
+ for (const auto &j : x.mUsedFonts)
+ if ((x.mOriginalFont == "Arial" &&
+ j.startsWith("Liberation Sans/")) ||
+ (x.mOriginalFont == "Times New Roman" &&
+ j.startsWith("Liberation Serif/")) ||
+ (x.mOriginalFont == "Courier New" &&
+ j.startsWith("Liberation Mono/")) ||
+ (x.mOriginalFont == "Arial Narrow" &&
+ j.startsWith("Liberation Sans Narrow/")) ||
+ (x.mOriginalFont == "Cambria" &&
+ j.startsWith("Caladea/")) ||
+ (x.mOriginalFont == "Calibri" &&
+ j.startsWith("Carlito/")) ||
+ (x.mOriginalFont == "Palatino Linotype" &&
+ j.startsWith("P052/")) ||
+ // Perhaps a risky heuristic? If some glyphs from Symbol
+ // have been mapped to ones in OpenSymbol, don't warn
+ // that Symbol is missing.
+ (x.mOriginalFont == "Symbol" &&
+ j.startsWith("OpenSymbol/")))
+ {
+ return true;
+ }
+
+ return false;
+ });
+
+ if (aFontMappingUseData.size() > 0)
+ {
+ SAL_INFO("lok.fontsubst", "================ Pruned substitutions:");
+ for (const auto &i : aFontMappingUseData)
+ {
+ SAL_INFO("lok.fontsubst", i.mOriginalFont);
+ for (const auto &j : i.mUsedFonts)
+ SAL_INFO("lok.fontsubst", " " << j);
+ }
+ }
+
+ for (std::size_t i = 0; i < aFontMappingUseData.size(); ++i)
+ {
+ pDocument->maFontsMissing.insert(aFontMappingUseData[i].mOriginalFont);
+ }
+
return pDocument;
}
catch (const uno::Exception& exception)
@@ -2586,14 +2931,14 @@ static int lo_runMacro(LibreOfficeKit* pThis, const char *pURL)
OUString sURL( pURL, strlen(pURL), RTL_TEXTENCODING_UTF8 );
if (sURL.isEmpty())
{
- pLib->maLastExceptionMsg = "Macro to run was not provided.";
+ pLib->maLastExceptionMsg = u"Macro to run was not provided."_ustr;
SAL_INFO("lok", "Macro URL is empty");
return false;
}
if (!sURL.startsWith("macro://"))
{
- pLib->maLastExceptionMsg = "This doesn't look like macro URL";
+ pLib->maLastExceptionMsg = u"This doesn't look like macro URL"_ustr;
SAL_INFO("lok", "Macro URL is invalid");
return false;
}
@@ -2602,7 +2947,7 @@ static int lo_runMacro(LibreOfficeKit* pThis, const char *pURL)
if (!xContext.is())
{
- pLib->maLastExceptionMsg = "ComponentContext is not available";
+ pLib->maLastExceptionMsg = u"ComponentContext is not available"_ustr;
SAL_INFO("lok", "ComponentContext is not available");
return false;
}
@@ -2619,7 +2964,7 @@ static int lo_runMacro(LibreOfficeKit* pThis, const char *pURL)
if (!xComponentLoader.is())
{
- pLib->maLastExceptionMsg = "ComponentLoader is not available";
+ pLib->maLastExceptionMsg = u"ComponentLoader is not available"_ustr;
SAL_INFO("lok", "ComponentLoader is not available");
return false;
}
@@ -2631,12 +2976,12 @@ static int lo_runMacro(LibreOfficeKit* pThis, const char *pURL)
uno::Reference<frame::XDispatchProvider> xDP;
xSFactory.set(xFactory, uno::UNO_QUERY_THROW);
- xDP.set( xSFactory->createInstance("com.sun.star.comp.sfx2.SfxMacroLoader"), uno::UNO_QUERY );
+ xDP.set( xSFactory->createInstance(u"com.sun.star.comp.sfx2.SfxMacroLoader"_ustr), uno::UNO_QUERY );
uno::Reference<frame::XDispatch> xD = xDP->queryDispatch( aURL, OUString(), 0);
if (!xD.is())
{
- pLib->maLastExceptionMsg = "Macro loader is not available";
+ pLib->maLastExceptionMsg = u"Macro loader is not available"_ustr;
SAL_INFO("lok", "Macro loader is not available");
return false;
}
@@ -2683,7 +3028,7 @@ static bool lo_signDocument(LibreOfficeKit* /*pThis*/,
std::string aCertificateBase64String = extractCertificate(aCertificateString);
if (!aCertificateBase64String.empty())
{
- OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
+ OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String);
comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
}
else
@@ -2697,7 +3042,7 @@ static bool lo_signDocument(LibreOfficeKit* /*pThis*/,
std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
if (!aPrivateKeyBase64String.empty())
{
- OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String.c_str());
+ OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String);
comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
}
else
@@ -2729,6 +3074,288 @@ static bool lo_signDocument(LibreOfficeKit* /*pThis*/,
return true;
}
+
+static char* lo_extractRequest(LibreOfficeKit* /*pThis*/, const char* pFilePath)
+{
+ uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext);
+ uno::Reference< css::lang::XComponent > xComp;
+ OUString aURL(getAbsoluteURL(pFilePath));
+ if (!aURL.isEmpty())
+ {
+ if (xComponentLoader.is())
+ {
+ try
+ {
+ uno::Sequence<css::beans::PropertyValue> aFilterOptions(comphelper::InitPropertySequence(
+ {
+ {u"Hidden"_ustr, css::uno::Any(true)},
+ {u"ReadOnly"_ustr, css::uno::Any(true)}
+ }));
+ xComp = xComponentLoader->loadComponentFromURL( aURL, u"_blank"_ustr, 0, aFilterOptions );
+ }
+ catch ( const lang::IllegalArgumentException& ex )
+ {
+ SAL_WARN("lok", "lo_extractRequest: IllegalArgumentException: " << ex.Message);
+ }
+ catch (...)
+ {
+ SAL_WARN("lok", "lo_extractRequest: Exception on loadComponentFromURL, url= " << aURL);
+ }
+
+ if (xComp.is())
+ {
+ uno::Reference< document::XLinkTargetSupplier > xLTS( xComp, uno::UNO_QUERY );
+
+ if( xLTS.is() )
+ {
+ tools::JsonWriter aJson;
+ {
+ auto aNode = aJson.startNode("Targets");
+ extractLinks(xLTS->getLinks(), false, aJson);
+ }
+ return convertOString(aJson.finishAndGetAsOString());
+ }
+ xComp->dispose();
+ }
+ }
+ }
+ return strdup("{ }");
+}
+
+static void lo_trimMemory(LibreOfficeKit* /* pThis */, int nTarget)
+{
+ vcl::lok::trimMemory(nTarget);
+
+ if (nTarget > 2000)
+ {
+ SolarMutexGuard aGuard;
+
+ // Flush all buffered VOC primitives from the pages.
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if (pViewShell)
+ {
+ const SdrView* pView = pViewShell->GetDrawView();
+ if (pView)
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+ if (pPageView)
+ {
+ SdrPage* pCurPage = pPageView->GetPage();
+ if (pCurPage)
+ {
+ SdrModel& sdrModel = pCurPage->getSdrModelFromSdrPage();
+ for (sal_uInt16 i = 0; i < sdrModel.GetPageCount(); ++i)
+ {
+ SdrPage* pPage = sdrModel.GetPage(i);
+ if (pPage)
+ pPage->GetViewContact().flushViewObjectContacts();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (nTarget > 1000)
+ {
+#ifdef HAVE_MALLOC_TRIM
+ malloc_trim(0);
+#endif
+ }
+}
+
+namespace
+{
+class FunctionBasedURPInstanceProvider
+ : public ::cppu::WeakImplHelper<css::bridge::XInstanceProvider>
+{
+private:
+ css::uno::Reference<css::uno::XComponentContext> m_rContext;
+
+public:
+ FunctionBasedURPInstanceProvider(
+ const css::uno::Reference<css::uno::XComponentContext>& rxContext);
+
+ // XInstanceProvider
+ virtual css::uno::Reference<css::uno::XInterface>
+ SAL_CALL getInstance(const OUString& aName) override;
+};
+
+// InstanceProvider
+FunctionBasedURPInstanceProvider::FunctionBasedURPInstanceProvider(
+ const Reference<XComponentContext>& rxContext)
+ : m_rContext(rxContext)
+{
+}
+
+Reference<XInterface> FunctionBasedURPInstanceProvider::getInstance(const OUString& aName)
+{
+ Reference<XInterface> rInstance;
+
+ if (aName == "StarOffice.ServiceManager")
+ {
+ rInstance.set(m_rContext->getServiceManager());
+ }
+ else if (aName == "StarOffice.ComponentContext")
+ {
+ rInstance = m_rContext;
+ }
+ else if (aName == "StarOffice.NamingService")
+ {
+ Reference<XNamingService> rNamingService(
+ m_rContext->getServiceManager()->createInstanceWithContext(
+ u"com.sun.star.uno.NamingService"_ustr, m_rContext),
+ UNO_QUERY);
+ if (rNamingService.is())
+ {
+ rNamingService->registerObject(u"StarOffice.ServiceManager"_ustr,
+ m_rContext->getServiceManager());
+ rNamingService->registerObject(u"StarOffice.ComponentContext"_ustr, m_rContext);
+ rInstance = rNamingService;
+ }
+ }
+ return rInstance;
+}
+
+class FunctionBasedURPConnection : public cppu::WeakImplHelper<css::connection::XConnection>
+{
+public:
+ explicit FunctionBasedURPConnection(void*, int (*)(void* pContext, const signed char* pBuffer, int nLen),
+ void*, int (*)(void* pContext, signed char* pBuffer, int nLen));
+ ~FunctionBasedURPConnection();
+
+ // These overridden member functions use "read" and "write" from the point of view of LO,
+ // i.e. the opposite to how startURP() uses them.
+ virtual sal_Int32 SAL_CALL read(Sequence<sal_Int8>& rReadBytes,
+ sal_Int32 nBytesToRead) override;
+ virtual void SAL_CALL write(const Sequence<sal_Int8>& aData) override;
+ virtual void SAL_CALL flush() override;
+ virtual void SAL_CALL close() override;
+ virtual OUString SAL_CALL getDescription() override;
+ void setBridge(const Reference<XBridge>&);
+ void* getContext();
+ inline static int g_connectionCount = 0;
+
+private:
+ void* m_pRecieveFromLOContext;
+ void* m_pSendURPToLOContext;
+ int (*m_fnReceiveURPFromLO)(void* pContext, const signed char* pBuffer, int nLen);
+ int (*m_fnSendURPToLO)(void* pContext, signed char* pBuffer, int nLen);
+ Reference<XBridge> m_URPBridge;
+};
+
+FunctionBasedURPConnection::FunctionBasedURPConnection(
+ void* pRecieveFromLOContext,
+ int (*fnReceiveURPFromLO)(void* pContext, const signed char* pBuffer, int nLen),
+ void* pSendURPToLOContext,
+ int (*fnSendURPToLO)(void* pContext, signed char* pBuffer, int nLen))
+ : m_pRecieveFromLOContext(pRecieveFromLOContext)
+ , m_pSendURPToLOContext(pSendURPToLOContext)
+ , m_fnReceiveURPFromLO(fnReceiveURPFromLO)
+ , m_fnSendURPToLO(fnSendURPToLO)
+{
+ g_connectionCount++;
+}
+
+FunctionBasedURPConnection::~FunctionBasedURPConnection()
+{
+ Reference<XComponent> xComp(m_URPBridge, UNO_QUERY_THROW);
+ xComp->dispose(); // TODO: check this doesn't deadlock
+}
+
+void* FunctionBasedURPConnection::getContext() { return this; }
+
+sal_Int32 FunctionBasedURPConnection::read(Sequence<sal_Int8>& rReadBytes, sal_Int32 nBytesToRead)
+{
+ if (nBytesToRead < 0)
+ return 0;
+
+ if (rReadBytes.getLength() != nBytesToRead)
+ rReadBytes.realloc(nBytesToRead);
+
+ // As with osl::StreamPipe, we must always read nBytesToRead...
+ return m_fnSendURPToLO(m_pSendURPToLOContext, rReadBytes.getArray(), nBytesToRead);
+}
+
+void FunctionBasedURPConnection::write(const Sequence<sal_Int8>& rData)
+{
+ m_fnReceiveURPFromLO(m_pRecieveFromLOContext, rData.getConstArray(), rData.getLength());
+}
+
+void FunctionBasedURPConnection::flush() {}
+
+void FunctionBasedURPConnection::close()
+{
+ SAL_INFO("lok.urp", "Requested to close FunctionBasedURPConnection");
+}
+
+OUString FunctionBasedURPConnection::getDescription() { return ""; }
+
+void FunctionBasedURPConnection::setBridge(const Reference<XBridge>& xBridge) { m_URPBridge = xBridge; }
+}
+
+static void*
+lo_startURP(LibreOfficeKit* /* pThis */, void* pRecieveFromLOContext, void* pSendToLOContext,
+ int (*fnReceiveURPFromLO)(void* pContext, const signed char* pBuffer, int nLen),
+ int (*fnSendURPToLO)(void* pContext, signed char* pBuffer, int nLen))
+{
+ // Here we will roughly do what desktop LO does when one passes a command-line switch like
+ // --accept=socket,port=nnnn;urp;StarOffice.ServiceManager. Except that no listening socket will
+ // be created. The communication to the URP will be through the nReceiveURPFromLO and nSendURPToLO
+ // functions.
+
+ rtl::Reference<FunctionBasedURPConnection> connection(
+ new FunctionBasedURPConnection(pRecieveFromLOContext, fnReceiveURPFromLO,
+ pSendToLOContext, fnSendURPToLO));
+
+ Reference<XBridgeFactory> xBridgeFactory = css::bridge::BridgeFactory::create(xContext);
+
+ Reference<XInstanceProvider> xInstanceProvider(new FunctionBasedURPInstanceProvider(xContext));
+
+ Reference<XBridge> xBridge(xBridgeFactory->createBridge(
+ "functionurp" + OUString::number(FunctionBasedURPConnection::g_connectionCount), u"urp"_ustr,
+ connection, xInstanceProvider));
+
+ connection->setBridge(std::move(xBridge));
+
+ return connection->getContext();
+}
+
+/**
+ * Stop a function based URP connection that you started with lo_startURP above
+ *
+ * @param pSendToLOContext a pointer to the context returned by lo_startURP */
+static void lo_stopURP(LibreOfficeKit* /* pThis */,
+ void* pFunctionBasedURPConnection/* FunctionBasedURPConnection* */)
+{
+ static_cast<FunctionBasedURPConnection*>(pFunctionBasedURPConnection)->close();
+}
+
+
+static int lo_joinThreads(LibreOfficeKit* /* pThis */)
+{
+ comphelper::ThreadPool &pool = comphelper::ThreadPool::getSharedOptimalPool();
+ pool.joinThreadsIfIdle();
+
+// if (comphelper::getWorkerCount() > 0)
+// return 0;
+
+ // Grammar checker thread
+ css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLangSrv =
+ css::linguistic2::LinguServiceManager::create(xContext);
+
+ auto joinable = dynamic_cast<comphelper::LibreOfficeKit::ThreadJoinable *>(xLangSrv.get());
+ if (joinable && !joinable->joinThreads())
+ return 0;
+
+ return 1;
+}
+
+static void lo_setForkedChild(LibreOfficeKit* /* pThis */, bool bIsChild)
+{
+ comphelper::LibreOfficeKit::setForkedChild(bIsChild);
+}
+
static void lo_registerCallback (LibreOfficeKit* pThis,
LibreOfficeKitCallback pCallback,
void* pData)
@@ -2745,6 +3372,19 @@ static void lo_registerCallback (LibreOfficeKit* pThis,
pApp->m_pCallbackData = pLib->mpCallbackData = pData;
}
+static SfxObjectShell* getSfxObjectShell(LibreOfficeKitDocument* pThis)
+{
+ LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+ if (!pDocument)
+ return nullptr;
+
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
+ if (!pBaseModel)
+ return nullptr;
+
+ return pBaseModel->GetObjectShell();
+}
+
static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const char* pFormat, const char* pFilterOptions)
{
comphelper::ProfileZone aZone("doc_saveAs");
@@ -2761,14 +3401,14 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
if (aURL.isEmpty())
{
- SetLastExceptionMsg("Filename to save to was not provided.");
+ SetLastExceptionMsg(u"Filename to save to was not provided."_ustr);
SAL_INFO("lok", "URL for save is empty");
return false;
}
try
{
- const ExtensionMap* pMap;
+ std::span<const ExtensionMap> pMap;
switch (doc_getDocumentType(pThis))
{
@@ -2800,23 +3440,23 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
}
else
{
- SetLastExceptionMsg("input filename without a suffix");
+ SetLastExceptionMsg("input URL '" + aURL + "' lacks a suffix");
return false;
}
}
OUString aFilterName;
- for (sal_Int32 i = 0; pMap[i].extn; ++i)
+ for (const auto& item : pMap)
{
- if (sFormat.equalsIgnoreAsciiCaseAscii(pMap[i].extn))
+ if (sFormat.equalsIgnoreAsciiCaseAscii(item.extn))
{
- aFilterName = getUString(pMap[i].filterName);
+ aFilterName = item.filterName;
break;
}
}
if (aFilterName.isEmpty())
{
- SetLastExceptionMsg("no output filter found for provided suffix");
+ SetLastExceptionMsg(u"no output filter found for provided suffix"_ustr);
return false;
}
@@ -2824,7 +3464,8 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
// Check if watermark for pdf is passed by filteroptions...
// It is not a real filter option so it must be filtered out.
- OUString watermarkText, sFullSheetPreview;
+ OUString watermarkText;
+ std::u16string_view sFullSheetPreview;
int aIndex = -1;
if ((aIndex = aFilterOptions.indexOf(",Watermark=")) >= 0)
{
@@ -2840,7 +3481,24 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+16);
}
- bool bFullSheetPreview = sFullSheetPreview == "true";
+ bool bFullSheetPreview = sFullSheetPreview == u"true";
+
+ OUString filePassword;
+ if ((aIndex = aFilterOptions.indexOf(",Password=")) >= 0)
+ {
+ int bIndex = aFilterOptions.indexOf("PASSWORDEND");
+ filePassword = aFilterOptions.subView(aIndex + 10, bIndex - (aIndex + 10));
+ aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex))
+ + aFilterOptions.subView(bIndex + 11);
+ }
+ OUString filePasswordToModify;
+ if ((aIndex = aFilterOptions.indexOf(",PasswordToModify=")) >= 0)
+ {
+ int bIndex = aFilterOptions.indexOf("PASSWORDTOMODIFYEND");
+ filePassword = aFilterOptions.subView(aIndex + 18, bIndex - (aIndex + 18));
+ aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex))
+ + aFilterOptions.subView(bIndex + 19);
+ }
// Select a pdf version if specified a valid one. If not specified then ignore.
// If invalid then fail.
@@ -2848,23 +3506,22 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
if ((aIndex = aFilterOptions.indexOf(",PDFVer=")) >= 0)
{
int bIndex = aFilterOptions.indexOf("PDFVEREND");
- OUString sPdfVer;
- sPdfVer = aFilterOptions.subView(aIndex+8, bIndex-(aIndex+8));
+ std::u16string_view sPdfVer = aFilterOptions.subView(aIndex+8, bIndex-(aIndex+8));
aFilterOptions = OUString::Concat(aFilterOptions.subView(0, aIndex)) + aFilterOptions.subView(bIndex+9);
- if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-1b"))
+ if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF/A-1b"))
pdfVer = 1;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-2b"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF/A-2b"))
pdfVer = 2;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF/A-3b"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF/A-3b"))
pdfVer = 3;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.5"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF-1.5"))
pdfVer = 15;
- else if (sPdfVer.equalsIgnoreAsciiCase("PDF-1.6"))
+ else if (o3tl::equalsIgnoreAsciiCase(sPdfVer, u"PDF-1.6"))
pdfVer = 16;
else
{
- SetLastExceptionMsg("wrong PDF version");
+ SetLastExceptionMsg(u"wrong PDF version"_ustr);
return false;
}
}
@@ -2877,19 +3534,31 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
const uno::Sequence<OUString> aOptionSeq = comphelper::string::convertCommaSeparated(aFilterOptions);
std::vector<OUString> aFilteredOptionVec;
bool bTakeOwnership = false;
+ bool bCreateFromTemplate = false;
MediaDescriptor aSaveMediaDescriptor;
for (const auto& rOption : aOptionSeq)
{
if (rOption == "TakeOwnership")
bTakeOwnership = true;
else if (rOption == "NoFileSync")
- aSaveMediaDescriptor["NoFileSync"] <<= true;
+ aSaveMediaDescriptor[u"NoFileSync"_ustr] <<= true;
+ else if (rOption == "FromTemplate")
+ bCreateFromTemplate = true;
else
aFilteredOptionVec.push_back(rOption);
}
- aSaveMediaDescriptor["Overwrite"] <<= true;
- aSaveMediaDescriptor["FilterName"] <<= aFilterName;
+ if (bCreateFromTemplate && bTakeOwnership)
+ {
+ if (SfxObjectShell* pObjectShell = getSfxObjectShell(pThis))
+ {
+ DateTime now( ::DateTime::SYSTEM );
+ pObjectShell->getDocProperties()->setCreationDate(now.GetUNODateTime());
+ }
+ }
+
+ aSaveMediaDescriptor[u"Overwrite"_ustr] <<= true;
+ aSaveMediaDescriptor[u"FilterName"_ustr] <<= aFilterName;
auto aFilteredOptionSeq = comphelper::containerToSequence<OUString>(aFilteredOptionVec);
aFilterOptions = comphelper::string::convertCommaSeparated(aFilteredOptionSeq);
@@ -2897,28 +3566,37 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha
comphelper::SequenceAsHashMap aFilterDataMap;
- setFormatSpecificFilterData(sFormat, aFilterDataMap);
+ // If filter options is JSON string, then make sure aFilterDataMap stays empty, otherwise we
+ // would ignore the filter options.
+ if (!aFilterOptions.startsWith("{"))
+ {
+ setFormatSpecificFilterData(sFormat, aFilterDataMap);
+ }
if (!watermarkText.isEmpty())
- aFilterDataMap["TiledWatermark"] <<= watermarkText;
+ aFilterDataMap[u"TiledWatermark"_ustr] <<= watermarkText;
if (bFullSheetPreview)
- aFilterDataMap["SinglePageSheets"] <<= true;
+ aFilterDataMap[u"SinglePageSheets"_ustr] <<= true;
if (pdfVer)
- aFilterDataMap["SelectPdfVersion"] <<= pdfVer;
+ aFilterDataMap[u"SelectPdfVersion"_ustr] <<= pdfVer;
if (!aFilterDataMap.empty())
{
- aSaveMediaDescriptor["FilterData"] <<= aFilterDataMap.getAsConstPropertyValueList();
+ aSaveMediaDescriptor[u"FilterData"_ustr] <<= aFilterDataMap.getAsConstPropertyValueList();
}
+ if (!filePassword.isEmpty())
+ aSaveMediaDescriptor[u"Password"_ustr] <<= filePassword;
+ if (!filePasswordToModify.isEmpty())
+ aSaveMediaDescriptor[u"PasswordToModify"_ustr] <<= filePasswordToModify;
// add interaction handler too
if (gImpl)
{
// gImpl does not have to exist when running from a unit test
rtl::Reference<LOKInteractionHandler> const pInteraction(
- new LOKInteractionHandler("saveas", gImpl, pDocument));
+ new LOKInteractionHandler("saveas"_ostr, gImpl, pDocument));
uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction);
aSaveMediaDescriptor[MediaDescriptor::PROP_INTERACTIONHANDLER] <<= xInteraction;
@@ -2950,200 +3628,231 @@ static void doc_iniUnoCommands ()
SolarMutexGuard aGuard;
SetLastExceptionMsg();
- OUString sUnoCommands[] =
- {
- OUString(".uno:AlignLeft"),
- OUString(".uno:AlignHorizontalCenter"),
- OUString(".uno:AlignRight"),
- OUString(".uno:BackColor"),
- OUString(".uno:BackgroundColor"),
- OUString(".uno:TableCellBackgroundColor"),
- OUString(".uno:Bold"),
- OUString(".uno:CenterPara"),
- OUString(".uno:CharBackColor"),
- OUString(".uno:CharBackgroundExt"),
- OUString(".uno:CharFontName"),
- OUString(".uno:Color"),
- OUString(".uno:ControlCodes"),
- OUString(".uno:DecrementIndent"),
- OUString(".uno:DefaultBullet"),
- OUString(".uno:DefaultNumbering"),
- OUString(".uno:FontColor"),
- OUString(".uno:FontHeight"),
- OUString(".uno:IncrementIndent"),
- OUString(".uno:Italic"),
- OUString(".uno:JustifyPara"),
- OUString(".uno:JumpToMark"),
- OUString(".uno:OutlineFont"),
- OUString(".uno:LeftPara"),
- OUString(".uno:LanguageStatus"),
- OUString(".uno:RightPara"),
- OUString(".uno:Shadowed"),
- OUString(".uno:SubScript"),
- OUString(".uno:SuperScript"),
- OUString(".uno:Strikeout"),
- OUString(".uno:StyleApply"),
- OUString(".uno:Underline"),
- OUString(".uno:ModifiedStatus"),
- OUString(".uno:Undo"),
- OUString(".uno:Redo"),
- OUString(".uno:InsertPage"),
- OUString(".uno:DeletePage"),
- OUString(".uno:DuplicatePage"),
- OUString(".uno:InsertSlide"),
- OUString(".uno:DeleteSlide"),
- OUString(".uno:DuplicateSlide"),
- OUString(".uno:Cut"),
- OUString(".uno:Copy"),
- OUString(".uno:Paste"),
- OUString(".uno:SelectAll"),
- OUString(".uno:ReplyComment"),
- OUString(".uno:ResolveComment"),
- OUString(".uno:ResolveCommentThread"),
- OUString(".uno:InsertRowsBefore"),
- OUString(".uno:InsertRowsAfter"),
- OUString(".uno:InsertColumnsBefore"),
- OUString(".uno:InsertColumnsAfter"),
- OUString(".uno:DeleteRows"),
- OUString(".uno:DeleteColumns"),
- OUString(".uno:DeleteTable"),
- OUString(".uno:SelectTable"),
- OUString(".uno:EntireRow"),
- OUString(".uno:EntireColumn"),
- OUString(".uno:EntireCell"),
- OUString(".uno:AssignLayout"),
- OUString(".uno:StatusDocPos"),
- OUString(".uno:RowColSelCount"),
- OUString(".uno:StatusPageStyle"),
- OUString(".uno:InsertMode"),
- OUString(".uno:SpellOnline"),
- OUString(".uno:StatusSelectionMode"),
- OUString(".uno:StateTableCell"),
- OUString(".uno:StatusBarFunc"),
- OUString(".uno:StatePageNumber"),
- OUString(".uno:StateWordCount"),
- OUString(".uno:SelectionMode"),
- OUString(".uno:PageStatus"),
- OUString(".uno:LayoutStatus"),
- OUString(".uno:Scale"),
- OUString(".uno:Context"),
- OUString(".uno:WrapText"),
- OUString(".uno:ToggleMergeCells"),
- OUString(".uno:NumberFormatCurrency"),
- OUString(".uno:NumberFormatPercent"),
- OUString(".uno:NumberFormatDecimal"),
- OUString(".uno:NumberFormatDate"),
- OUString(".uno:FrameLineColor"),
- OUString(".uno:SortAscending"),
- OUString(".uno:SortDescending"),
- OUString(".uno:TrackChanges"),
- OUString(".uno:ShowTrackedChanges"),
- OUString(".uno:NextTrackedChange"),
- OUString(".uno:PreviousTrackedChange"),
- OUString(".uno:AcceptAllTrackedChanges"),
- OUString(".uno:RejectAllTrackedChanges"),
- OUString(".uno:TableDialog"),
- OUString(".uno:FormatCellDialog"),
- OUString(".uno:FontDialog"),
- OUString(".uno:ParagraphDialog"),
- OUString(".uno:OutlineBullet"),
- OUString(".uno:InsertIndexesEntry"),
- OUString(".uno:DocumentRepair"),
- OUString(".uno:TransformDialog"),
- OUString(".uno:InsertPageHeader"),
- OUString(".uno:InsertPageFooter"),
- OUString(".uno:OnlineAutoFormat"),
- OUString(".uno:InsertObjectChart"),
- OUString(".uno:InsertSection"),
- OUString(".uno:InsertAnnotation"),
- OUString(".uno:DeleteAnnotation"),
- OUString(".uno:InsertPagebreak"),
- OUString(".uno:InsertColumnBreak"),
- OUString(".uno:HyperlinkDialog"),
- OUString(".uno:InsertSymbol"),
- OUString(".uno:EditRegion"),
- OUString(".uno:ThesaurusDialog"),
- OUString(".uno:FormatArea"),
- OUString(".uno:FormatLine"),
- OUString(".uno:FormatColumns"),
- OUString(".uno:Watermark"),
- OUString(".uno:ResetAttributes"),
- OUString(".uno:Orientation"),
- OUString(".uno:ObjectAlignLeft"),
- OUString(".uno:ObjectAlignRight"),
- OUString(".uno:AlignCenter"),
- OUString(".uno:TransformPosX"),
- OUString(".uno:TransformPosY"),
- OUString(".uno:TransformWidth"),
- OUString(".uno:TransformHeight"),
- OUString(".uno:ObjectBackOne"),
- OUString(".uno:SendToBack"),
- OUString(".uno:ObjectForwardOne"),
- OUString(".uno:BringToFront"),
- OUString(".uno:WrapRight"),
- OUString(".uno:WrapThrough"),
- OUString(".uno:WrapLeft"),
- OUString(".uno:WrapIdeal"),
- OUString(".uno:WrapOn"),
- OUString(".uno:WrapOff"),
- OUString(".uno:UpdateCurIndex"),
- OUString(".uno:InsertCaptionDialog"),
- OUString(".uno:FormatGroup"),
- OUString(".uno:SplitTable"),
- OUString(".uno:MergeCells"),
- OUString(".uno:DeleteNote"),
- OUString(".uno:AcceptChanges"),
- OUString(".uno:FormatPaintbrush"),
- OUString(".uno:SetDefault"),
- OUString(".uno:ParaLeftToRight"),
- OUString(".uno:ParaRightToLeft"),
- OUString(".uno:ParaspaceIncrease"),
- OUString(".uno:ParaspaceDecrease"),
- OUString(".uno:AcceptTrackedChange"),
- OUString(".uno:RejectTrackedChange"),
- OUString(".uno:ShowResolvedAnnotations"),
- OUString(".uno:InsertBreak"),
- OUString(".uno:InsertEndnote"),
- OUString(".uno:InsertFootnote"),
- OUString(".uno:InsertReferenceField"),
- OUString(".uno:InsertBookmark"),
- OUString(".uno:InsertAuthoritiesEntry"),
- OUString(".uno:InsertMultiIndex"),
- OUString(".uno:InsertField"),
- OUString(".uno:InsertPageNumberField"),
- OUString(".uno:InsertPageCountField"),
- OUString(".uno:InsertDateField"),
- OUString(".uno:InsertTitleField"),
- OUString(".uno:InsertFieldCtrl"),
- OUString(".uno:CharmapControl"),
- OUString(".uno:EnterGroup"),
- OUString(".uno:LeaveGroup"),
- OUString(".uno:AlignUp"),
- OUString(".uno:AlignMiddle"),
- OUString(".uno:AlignDown"),
- OUString(".uno:TraceChangeMode"),
- OUString(".uno:Combine"),
- OUString(".uno:Merge"),
- OUString(".uno:Dismantle"),
- OUString(".uno:Substract"),
- OUString(".uno:DistributeSelection"),
- OUString(".uno:Intersect"),
- OUString(".uno:BorderInner"),
- OUString(".uno:BorderOuter"),
- OUString(".uno:FreezePanes"),
- OUString(".uno:FreezePanesColumn"),
- OUString(".uno:FreezePanesRow"),
- OUString(".uno:Sidebar"),
- OUString(".uno:SheetRightToLeft"),
- OUString(".uno:RunMacro"),
- OUString(".uno:SpacePara1"),
- OUString(".uno:SpacePara15"),
- OUString(".uno:SpacePara2")
+ static constexpr OUString sUnoCommands[] =
+ {
+ u".uno:AlignLeft"_ustr,
+ u".uno:AlignHorizontalCenter"_ustr,
+ u".uno:AlignRight"_ustr,
+ u".uno:BackColor"_ustr,
+ u".uno:BackgroundColor"_ustr,
+ u".uno:TableCellBackgroundColor"_ustr,
+ u".uno:Bold"_ustr,
+ u".uno:CenterPara"_ustr,
+ u".uno:CharBackColor"_ustr,
+ u".uno:CharBackgroundExt"_ustr,
+ u".uno:CharFontName"_ustr,
+ u".uno:Color"_ustr,
+ u".uno:ControlCodes"_ustr,
+ u".uno:DecrementIndent"_ustr,
+ u".uno:DefaultBullet"_ustr,
+ u".uno:DefaultNumbering"_ustr,
+ u".uno:FontColor"_ustr,
+ u".uno:FontHeight"_ustr,
+ u".uno:IncrementIndent"_ustr,
+ u".uno:Italic"_ustr,
+ u".uno:JustifyPara"_ustr,
+ u".uno:JumpToMark"_ustr,
+ u".uno:OutlineFont"_ustr,
+ u".uno:LeftPara"_ustr,
+ u".uno:LanguageStatus"_ustr,
+ u".uno:RightPara"_ustr,
+ u".uno:Shadowed"_ustr,
+ u".uno:SubScript"_ustr,
+ u".uno:SuperScript"_ustr,
+ u".uno:Strikeout"_ustr,
+ u".uno:StyleApply"_ustr,
+ u".uno:Underline"_ustr,
+ u".uno:ModifiedStatus"_ustr,
+ u".uno:Undo"_ustr,
+ u".uno:Redo"_ustr,
+ u".uno:InsertPage"_ustr,
+ u".uno:DeletePage"_ustr,
+ u".uno:DuplicatePage"_ustr,
+ u".uno:InsertSlide"_ustr,
+ u".uno:DeleteSlide"_ustr,
+ u".uno:DuplicateSlide"_ustr,
+ u".uno:ChangeTheme"_ustr,
+ u".uno:Cut"_ustr,
+ u".uno:Copy"_ustr,
+ u".uno:Paste"_ustr,
+ u".uno:SelectAll"_ustr,
+ u".uno:ReplyComment"_ustr,
+ u".uno:ResolveComment"_ustr,
+ u".uno:ResolveCommentThread"_ustr,
+ u".uno:InsertRowsBefore"_ustr,
+ u".uno:InsertRowsAfter"_ustr,
+ u".uno:InsertColumnsBefore"_ustr,
+ u".uno:InsertColumnsAfter"_ustr,
+ u".uno:DeleteRows"_ustr,
+ u".uno:DeleteColumns"_ustr,
+ u".uno:DeleteTable"_ustr,
+ u".uno:SelectTable"_ustr,
+ u".uno:EntireRow"_ustr,
+ u".uno:EntireColumn"_ustr,
+ u".uno:EntireCell"_ustr,
+ u".uno:AssignLayout"_ustr,
+ u".uno:StatusDocPos"_ustr,
+ u".uno:RowColSelCount"_ustr,
+ u".uno:StatusPageStyle"_ustr,
+ u".uno:InsertMode"_ustr,
+ u".uno:SpellOnline"_ustr,
+ u".uno:StatusSelectionMode"_ustr,
+ u".uno:StateTableCell"_ustr,
+ u".uno:StatusBarFunc"_ustr,
+ u".uno:StatePageNumber"_ustr,
+ u".uno:StateWordCount"_ustr,
+ u".uno:SelectionMode"_ustr,
+ u".uno:PageStatus"_ustr,
+ u".uno:LayoutStatus"_ustr,
+ u".uno:Scale"_ustr,
+ u".uno:Context"_ustr,
+ u".uno:WrapText"_ustr,
+ u".uno:ToggleMergeCells"_ustr,
+ u".uno:NumberFormatCurrency"_ustr,
+ u".uno:NumberFormatPercent"_ustr,
+ u".uno:NumberFormatDecimal"_ustr,
+ u".uno:NumberFormatIncDecimals"_ustr,
+ u".uno:NumberFormatDecDecimals"_ustr,
+ u".uno:NumberFormatDate"_ustr,
+ u".uno:EditHeaderAndFooter"_ustr,
+ u".uno:FrameLineColor"_ustr,
+ u".uno:SortAscending"_ustr,
+ u".uno:SortDescending"_ustr,
+ u".uno:TrackChanges"_ustr,
+ u".uno:ShowTrackedChanges"_ustr,
+ u".uno:NextTrackedChange"_ustr,
+ u".uno:PreviousTrackedChange"_ustr,
+ u".uno:AcceptAllTrackedChanges"_ustr,
+ u".uno:RejectAllTrackedChanges"_ustr,
+ u".uno:TableDialog"_ustr,
+ u".uno:FormatCellDialog"_ustr,
+ u".uno:FontDialog"_ustr,
+ u".uno:ParagraphDialog"_ustr,
+ u".uno:OutlineBullet"_ustr,
+ u".uno:InsertIndexesEntry"_ustr,
+ u".uno:DocumentRepair"_ustr,
+ u".uno:TransformDialog"_ustr,
+ u".uno:InsertPageHeader"_ustr,
+ u".uno:InsertPageFooter"_ustr,
+ u".uno:OnlineAutoFormat"_ustr,
+ u".uno:InsertObjectChart"_ustr,
+ u".uno:InsertSection"_ustr,
+ u".uno:InsertAnnotation"_ustr,
+ u".uno:DeleteAnnotation"_ustr,
+ u".uno:InsertPagebreak"_ustr,
+ u".uno:InsertColumnBreak"_ustr,
+ u".uno:HyperlinkDialog"_ustr,
+ u".uno:InsertSymbol"_ustr,
+ u".uno:EditRegion"_ustr,
+ u".uno:ThesaurusDialog"_ustr,
+ u".uno:FormatArea"_ustr,
+ u".uno:FormatLine"_ustr,
+ u".uno:FormatColumns"_ustr,
+ u".uno:Watermark"_ustr,
+ u".uno:ResetAttributes"_ustr,
+ u".uno:Orientation"_ustr,
+ u".uno:ObjectAlignLeft"_ustr,
+ u".uno:ObjectAlignRight"_ustr,
+ u".uno:AlignCenter"_ustr,
+ u".uno:TransformPosX"_ustr,
+ u".uno:TransformPosY"_ustr,
+ u".uno:TransformWidth"_ustr,
+ u".uno:TransformHeight"_ustr,
+ u".uno:ObjectBackOne"_ustr,
+ u".uno:SendToBack"_ustr,
+ u".uno:ObjectForwardOne"_ustr,
+ u".uno:BringToFront"_ustr,
+ u".uno:WrapRight"_ustr,
+ u".uno:WrapThrough"_ustr,
+ u".uno:WrapLeft"_ustr,
+ u".uno:WrapIdeal"_ustr,
+ u".uno:WrapOn"_ustr,
+ u".uno:WrapOff"_ustr,
+ u".uno:UpdateCurIndex"_ustr,
+ u".uno:InsertCaptionDialog"_ustr,
+ u".uno:FormatGroup"_ustr,
+ u".uno:SplitTable"_ustr,
+ u".uno:SplitCell"_ustr,
+ u".uno:MergeCells"_ustr,
+ u".uno:DeleteNote"_ustr,
+ u".uno:AcceptChanges"_ustr,
+ u".uno:FormatPaintbrush"_ustr,
+ u".uno:SetDefault"_ustr,
+ u".uno:ParaLeftToRight"_ustr,
+ u".uno:ParaRightToLeft"_ustr,
+ u".uno:ParaspaceIncrease"_ustr,
+ u".uno:ParaspaceDecrease"_ustr,
+ u".uno:AcceptTrackedChange"_ustr,
+ u".uno:RejectTrackedChange"_ustr,
+ u".uno:AcceptTrackedChangeToNext"_ustr,
+ u".uno:RejectTrackedChangeToNext"_ustr,
+ u".uno:ShowResolvedAnnotations"_ustr,
+ u".uno:InsertBreak"_ustr,
+ u".uno:InsertEndnote"_ustr,
+ u".uno:InsertFootnote"_ustr,
+ u".uno:InsertReferenceField"_ustr,
+ u".uno:InsertBookmark"_ustr,
+ u".uno:InsertAuthoritiesEntry"_ustr,
+ u".uno:InsertMultiIndex"_ustr,
+ u".uno:InsertField"_ustr,
+ u".uno:PageNumberWizard"_ustr,
+ u".uno:InsertPageNumberField"_ustr,
+ u".uno:InsertPageCountField"_ustr,
+ u".uno:InsertDateField"_ustr,
+ u".uno:InsertTitleField"_ustr,
+ u".uno:InsertFieldCtrl"_ustr,
+ u".uno:CharmapControl"_ustr,
+ u".uno:EnterGroup"_ustr,
+ u".uno:LeaveGroup"_ustr,
+ u".uno:AlignUp"_ustr,
+ u".uno:AlignMiddle"_ustr,
+ u".uno:AlignDown"_ustr,
+ u".uno:TraceChangeMode"_ustr,
+ u".uno:Combine"_ustr,
+ u".uno:Merge"_ustr,
+ u".uno:Dismantle"_ustr,
+ u".uno:Substract"_ustr,
+ u".uno:DistributeSelection"_ustr,
+ u".uno:Intersect"_ustr,
+ u".uno:BorderInner"_ustr,
+ u".uno:BorderOuter"_ustr,
+ u".uno:FreezePanes"_ustr,
+ u".uno:FreezePanesColumn"_ustr,
+ u".uno:FreezePanesRow"_ustr,
+ u".uno:Sidebar"_ustr,
+ u".uno:SheetRightToLeft"_ustr,
+ u".uno:RunMacro"_ustr,
+ u".uno:SpacePara1"_ustr,
+ u".uno:SpacePara15"_ustr,
+ u".uno:SpacePara2"_ustr,
+ u".uno:InsertSparkline"_ustr,
+ u".uno:DeleteSparkline"_ustr,
+ u".uno:DeleteSparklineGroup"_ustr,
+ u".uno:EditSparklineGroup"_ustr,
+ u".uno:EditSparkline"_ustr,
+ u".uno:GroupSparklines"_ustr,
+ u".uno:UngroupSparklines"_ustr,
+ u".uno:FormatSparklineMenu"_ustr,
+ u".uno:DataDataPilotRun"_ustr,
+ u".uno:RecalcPivotTable"_ustr,
+ u".uno:DeletePivotTable"_ustr,
+ u".uno:Protect"_ustr,
+ u".uno:UnsetCellsReadOnly"_ustr,
+ u".uno:ContentControlProperties"_ustr,
+ u".uno:InsertCheckboxContentControl"_ustr,
+ u".uno:InsertContentControl"_ustr,
+ u".uno:InsertDateContentControl"_ustr,
+ u".uno:InsertDropdownContentControl"_ustr,
+ u".uno:InsertPlainTextContentControl"_ustr,
+ u".uno:InsertPictureContentControl"_ustr,
+ u".uno:DataFilterAutoFilter"_ustr,
+ u".uno:CellProtection"_ustr,
+ u".uno:MoveKeepInsertMode"_ustr
};
util::URL aCommandURL;
SfxViewShell* pViewShell = SfxViewShell::Current();
- SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr;
+ SfxViewFrame* pViewFrame = pViewShell ? &pViewShell->GetViewFrame() : nullptr;
// check if Frame-Controller were created.
if (!pViewFrame)
@@ -3160,6 +3869,22 @@ static void doc_iniUnoCommands ()
return;
}
+#if !defined IOS && !defined ANDROID && !defined __EMSCRIPTEN__
+ uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(xContext);
+ if (!xSEInitializer.is())
+ {
+ SAL_WARN("lok", "iniUnoCommands: XSEInitializer is not available");
+ return;
+ }
+
+ uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext =
+ xSEInitializer->createSecurityContext(OUString());
+ if (!xSecurityContext.is())
+ {
+ SAL_WARN("lok", "iniUnoCommands: failed to create security context");
+ }
+#endif
+
SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool(pViewFrame);
uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(xContext));
@@ -3183,40 +3908,7 @@ static int doc_getDocumentType (LibreOfficeKitDocument* pThis)
comphelper::ProfileZone aZone("doc_getDocumentType");
SolarMutexGuard aGuard;
- SetLastExceptionMsg();
-
- LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
-
- try
- {
- uno::Reference<lang::XServiceInfo> xDocument(pDocument->mxComponent, uno::UNO_QUERY_THROW);
-
- if (xDocument->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
- {
- return LOK_DOCTYPE_SPREADSHEET;
- }
- else if (xDocument->supportsService("com.sun.star.presentation.PresentationDocument"))
- {
- return LOK_DOCTYPE_PRESENTATION;
- }
- else if (xDocument->supportsService("com.sun.star.drawing.DrawingDocument"))
- {
- return LOK_DOCTYPE_DRAWING;
- }
- else if (xDocument->supportsService("com.sun.star.text.TextDocument") || xDocument->supportsService("com.sun.star.text.WebDocument"))
- {
- return LOK_DOCTYPE_TEXT;
- }
- else
- {
- SetLastExceptionMsg("unknown document type");
- }
- }
- catch (const uno::Exception& exception)
- {
- SetLastExceptionMsg("exception: " + exception.Message);
- }
- return LOK_DOCTYPE_OTHER;
+ return getDocumentType(pThis);
}
static int doc_getParts (LibreOfficeKitDocument* pThis)
@@ -3228,7 +3920,7 @@ static int doc_getParts (LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return 0;
}
@@ -3245,7 +3937,7 @@ static int doc_getPart (LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return 0;
}
@@ -3262,7 +3954,7 @@ static void doc_setPartImpl(LibreOfficeKitDocument* pThis, int nPart, bool bAllo
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -3282,7 +3974,7 @@ static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
@@ -3292,13 +3984,12 @@ static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart)
static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect)
{
SolarMutexGuard aGuard;
- if (gImpl)
- gImpl->maLastExceptionMsg.clear();
+ SetLastExceptionMsg();
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -3308,13 +3999,12 @@ static void doc_selectPart(LibreOfficeKitDocument* pThis, int nPart, int nSelect
static void doc_moveSelectedParts(LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate)
{
SolarMutexGuard aGuard;
- if (gImpl)
- gImpl->maLastExceptionMsg.clear();
+ SetLastExceptionMsg();
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -3331,13 +4021,53 @@ static char* doc_getPartPageRectangles(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
return convertOUString(pDoc->getPartPageRectangles());
}
+static char* doc_getA11yFocusedParagraph(LibreOfficeKitDocument* pThis)
+{
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return nullptr;
+ }
+
+ if (SfxViewShell* pViewShell = SfxViewShell::Current())
+ {
+ return convertOUString(pViewShell->getA11yFocusedParagraph());
+
+ }
+ return nullptr;
+}
+
+static int doc_getA11yCaretPosition(LibreOfficeKitDocument* pThis)
+{
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return -1;
+ }
+ if (SfxViewShell* pViewShell = SfxViewShell::Current())
+ {
+ return pViewShell->getA11yCaretPosition();
+
+ }
+ return -1;
+
+}
+
static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart)
{
comphelper::ProfileZone aZone("doc_getPartName");
@@ -3348,7 +4078,7 @@ static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
@@ -3365,7 +4095,7 @@ static char* doc_getPartHash(LibreOfficeKitDocument* pThis, int nPart)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
@@ -3383,7 +4113,7 @@ static void doc_setPartMode(LibreOfficeKitDocument* pThis,
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -3411,6 +4141,23 @@ static void doc_setPartMode(LibreOfficeKitDocument* pThis,
}
}
+static int doc_getEditMode(LibreOfficeKitDocument* pThis)
+{
+ comphelper::ProfileZone aZone("doc_getEditMode");
+
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return 0;
+ }
+
+ return pDoc->getEditMode();
+}
+
static void doc_paintTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nCanvasWidth, const int nCanvasHeight,
@@ -3429,11 +4176,11 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis,
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
-#if defined(UNX) && !defined(MACOSX)
+#if defined(UNX) && !defined(MACOSX) || defined(_WIN32)
// Painting of zoomed or HiDPI spreadsheets is special, we actually draw everything at 100%,
// and only set cairo's (or CoreGraphic's, in the iOS case) scale factor accordingly, so that
@@ -3443,15 +4190,40 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis,
comphelper::ScopeGuard dpiScaleGuard([]() { comphelper::LibreOfficeKit::setDPIScale(1.0); });
#if defined(IOS)
- double fDPIScaleX = 1.0;
- paintTileIOS(pThis, pBuffer, nCanvasWidth, nCanvasHeight, fDPIScaleX, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+ double fDPIScale = 1.0;
+
+ // Onine uses the LOK_TILEMODE_RGBA by default so flip the normal flags
+ // to kCGImageAlphaPremultipliedLast | kCGImageByteOrder32Big
+ CGContextRef pCGContext = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8,
+ nCanvasWidth * 4, CGColorSpaceCreateDeviceRGB(),
+ kCGImageAlphaPremultipliedLast | kCGImageByteOrder32Big);
+
+ CGContextTranslateCTM(pCGContext, 0, nCanvasHeight);
+ CGContextScaleCTM(pCGContext, fDPIScale, -fDPIScale);
+
+ SAL_INFO( "lok.tiledrendering", "doc_paintTile: painting [" << nTileWidth << "x" << nTileHeight <<
+ "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<
+ nCanvasWidth << "x" << nCanvasHeight << "]px" );
+
+ Size aCanvasSize(nCanvasWidth, nCanvasHeight);
+
+ SystemGraphicsData aData;
+ aData.rCGContext = reinterpret_cast<CGContextRef>(pCGContext);
+
+ ScopedVclPtrInstance<VirtualDevice> pDevice(aData, Size(1, 1), DeviceFormat::WITHOUT_ALPHA);
+ pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+ pDevice->SetOutputSizePixel(aCanvasSize);
+ pDoc->paintTile(*pDevice, aCanvasSize.Width(), aCanvasSize.Height(),
+ nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+
+ CGContextRelease(pCGContext);
#else
- ScopedVclPtrInstance< VirtualDevice > pDevice(DeviceFormat::DEFAULT);
+ ScopedVclPtrInstance< VirtualDevice > pDevice(DeviceFormat::WITHOUT_ALPHA);
// Set background to transparent by default.
pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
- pDevice->SetOutputSizePixelScaleOffsetAndBuffer(
+ pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(
Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(),
pBuffer);
@@ -3470,6 +4242,36 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis,
pDevice->DrawRect(aRect);
pDevice->Pop();
}
+
+#ifdef _WIN32
+ // pBuffer was not used there
+ pDevice->EnableMapMode(false);
+ BitmapEx aBmpEx = pDevice->GetBitmapEx({ 0, 0 }, { nCanvasWidth, nCanvasHeight });
+ Bitmap aBmp = aBmpEx.GetBitmap();
+ AlphaMask aAlpha = aBmpEx.GetAlphaMask();
+ BitmapScopedReadAccess sraBmp(aBmp);
+ BitmapScopedReadAccess sraAlpha(aAlpha);
+
+ assert(sraBmp->Height() == nCanvasHeight);
+ assert(sraBmp->Width() == nCanvasWidth);
+ assert(!sraAlpha || sraBmp->Height() == sraAlpha->Height());
+ assert(!sraAlpha || sraBmp->Width() == sraAlpha->Width());
+ auto p = pBuffer;
+ for (tools::Long y = 0; y < sraBmp->Height(); ++y)
+ {
+ Scanline dataBmp = sraBmp->GetScanline(y);
+ Scanline dataAlpha = sraAlpha ? sraAlpha->GetScanline(y) : nullptr;
+ for (tools::Long x = 0; x < sraBmp->Width(); ++x)
+ {
+ BitmapColor color = sraBmp->GetPixelFromData(dataBmp, x);
+ sal_uInt8 alpha = dataAlpha ? sraAlpha->GetPixelFromData(dataAlpha, x).GetBlue() : 255;
+ *p++ = color.GetBlue();
+ *p++ = color.GetGreen();
+ *p++ = color.GetRed();
+ *p++ = alpha;
+ }
+ }
+#endif
#endif
#else
@@ -3477,39 +4279,10 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis,
#endif
}
-#ifdef IOS
-
-// This function is separate only to be used by LibreOfficeLight. If that app can be retired, this
-// function's code can be inlined.
-static void doc_paintTileToCGContext(LibreOfficeKitDocument* pThis,
- void* rCGContext,
- const int nCanvasWidth, const int nCanvasHeight,
- const int nTilePosX, const int nTilePosY,
- const int nTileWidth, const int nTileHeight)
-{
- SolarMutexGuard aGuard;
- SetLastExceptionMsg();
-
- SAL_INFO( "lok.tiledrendering", "paintTileToCGContext: painting [" << nTileWidth << "x" << nTileHeight <<
- "]@(" << nTilePosX << ", " << nTilePosY << ") to [" <<
- nCanvasWidth << "x" << nCanvasHeight << "]px" );
-
- ITiledRenderable* pDoc = getTiledRenderable(pThis);
- if (!pDoc)
- {
- SetLastExceptionMsg("Document doesn't support tiled rendering");
- return;
- }
-
- Size aCanvasSize(nCanvasWidth, nCanvasHeight);
- paintTileToCGContext(pDoc, rCGContext, aCanvasSize, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
-}
-
-#endif
-
static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
unsigned char* pBuffer,
const int nPart,
+ const int nMode,
const int nCanvasWidth, const int nCanvasHeight,
const int nTilePosX, const int nTilePosY,
const int nTileWidth, const int nTileHeight)
@@ -3519,7 +4292,7 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
SolarMutexGuard aGuard;
SetLastExceptionMsg();
- SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " ["
+ SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " : " << nMode << " ["
<< nTileWidth << "x" << nTileHeight << "]@("
<< nTilePosX << ", " << nTilePosY << ") to ["
<< nCanvasWidth << "x" << nCanvasHeight << "]px" );
@@ -3527,6 +4300,13 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
int nOrigViewId = doc_getView(pThis);
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return;
+ }
+
if (nOrigViewId < 0)
{
// tile painting always needs a SfxViewShell::Current(), but actually
@@ -3557,43 +4337,121 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
{
// Text documents have a single coordinate system; don't change part.
int nOrigPart = 0;
- const bool isText = (doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT);
+ const int aType = doc_getDocumentType(pThis);
+ const bool isText = (aType == LOK_DOCTYPE_TEXT);
+ const bool isCalc = (aType == LOK_DOCTYPE_SPREADSHEET);
+ int nOrigEditMode = 0;
+ bool bPaintTextEdit = true;
int nViewId = nOrigViewId;
+ int nLastNonEditorView = -1;
+ int nViewMatchingMode = -1;
+ SfxViewShell* pCurrentViewShell = SfxViewShell::Current();
+
if (!isText)
{
// Check if just switching to another view is enough, that has
// less side-effects.
- if (nPart != doc_getPart(pThis))
+ if (nPart != doc_getPart(pThis) || nMode != pDoc->getEditMode())
{
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while (pViewShell)
{
- if (pViewShell->getPart() == nPart)
+ bool bIsInEdit = pViewShell->GetDrawView() &&
+ pViewShell->GetDrawView()->GetTextEditOutliner();
+
+ OString sCurrentViewRenderState = pDoc->getViewRenderState(pCurrentViewShell);
+ OString sNewRenderState = pDoc->getViewRenderState(pViewShell);
+
+ if (sCurrentViewRenderState == sNewRenderState && !bIsInEdit)
+ nLastNonEditorView = pViewShell->GetViewShellId().get();
+
+ if (pViewShell->getPart() == nPart &&
+ pViewShell->getEditMode() == nMode &&
+ sCurrentViewRenderState == sNewRenderState &&
+ !bIsInEdit)
{
nViewId = pViewShell->GetViewShellId().get();
+ nViewMatchingMode = nViewId;
+ nLastNonEditorView = nViewId;
doc_setView(pThis, nViewId);
break;
}
+ else if (pViewShell->getEditMode() == nMode && sCurrentViewRenderState == sNewRenderState && !bIsInEdit)
+ {
+ nViewMatchingMode = pViewShell->GetViewShellId().get();
+ }
+
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
}
+ // if not found view with correct part
+ // - at least avoid rendering active textbox, This is for Impress.
+ // - prefer view with the same mode
+ if (nViewMatchingMode >= 0 && nViewMatchingMode != nViewId)
+ {
+ nViewId = nViewMatchingMode;
+ doc_setView(pThis, nViewId);
+ }
+ else if (!isCalc && nLastNonEditorView >= 0 && nLastNonEditorView != nViewId &&
+ pCurrentViewShell && pCurrentViewShell->GetDrawView() &&
+ pCurrentViewShell->GetDrawView()->GetTextEditOutliner())
+ {
+ nViewId = nLastNonEditorView;
+ doc_setView(pThis, nViewId);
+ }
+
+ // Disable callbacks while we are painting - after setting the view
+ if (nViewId != nOrigViewId && nViewId >= 0)
+ {
+ const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId);
+ if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
+ handlerIt->second->disableCallbacks();
+ }
+
nOrigPart = doc_getPart(pThis);
if (nPart != nOrigPart)
{
doc_setPartImpl(pThis, nPart, false);
}
+
+ nOrigEditMode = pDoc->getEditMode();
+ if (nOrigEditMode != nMode)
+ {
+ SfxLokHelper::setEditMode(nMode, pDoc);
+ }
+
+ bPaintTextEdit = (nPart == nOrigPart && nMode == nOrigEditMode);
+ pDoc->setPaintTextEdit(bPaintTextEdit);
}
doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
- if (!isText && nPart != nOrigPart)
- {
- doc_setPartImpl(pThis, nOrigPart, false);
- }
- if (!isText && nViewId != nOrigViewId)
+ if (!isText)
{
- doc_setView(pThis, nOrigViewId);
+ pDoc->setPaintTextEdit(true);
+
+ if (nMode != nOrigEditMode)
+ {
+ SfxLokHelper::setEditMode(nOrigEditMode, pDoc);
+ }
+
+ if (nPart != nOrigPart)
+ {
+ doc_setPartImpl(pThis, nOrigPart, false);
+ }
+
+ if (nViewId != nOrigViewId)
+ {
+ if (nViewId >= 0)
+ {
+ const auto handlerIt = pDocument->mpCallbackFlushHandlers.find(nViewId);
+ if (handlerIt != pDocument->mpCallbackFlushHandlers.end())
+ handlerIt->second->enableCallbacks();
+ }
+
+ doc_setView(pThis, nOrigViewId);
+ }
}
}
catch (const std::exception&)
@@ -3612,7 +4470,11 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis,
static int doc_getTileMode(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/)
{
SetLastExceptionMsg();
+#if ENABLE_CAIRO_RGBA || defined IOS
+ return LOK_TILEMODE_RGBA;
+#else
return LOK_TILEMODE_BGRA;
+#endif
}
static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
@@ -3633,7 +4495,30 @@ static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
}
else
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ }
+}
+
+static void doc_getDataArea(LibreOfficeKitDocument* pThis,
+ long nTab,
+ long* pCol,
+ long* pRow)
+{
+ comphelper::ProfileZone aZone("doc_getDataArea");
+
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (pDoc)
+ {
+ Size aDocumentSize = pDoc->getDataArea(nTab);
+ *pCol = aDocumentSize.Width();
+ *pRow = aDocumentSize.Height();
+ }
+ else
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
}
}
@@ -3706,6 +4591,23 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis,
pDocument->mpCallbackFlushHandlers[nView]->setViewId(pViewShell->GetViewShellId().get());
pViewShell->setLibreOfficeKitViewCallback(pDocument->mpCallbackFlushHandlers[nView].get());
}
+
+ if (!pDocument->maFontsMissing.empty())
+ {
+ OString sPayload = "{ \"fontsmissing\": [ "_ostr;
+ bool bFirst = true;
+ for (const auto &f : pDocument->maFontsMissing)
+ {
+ if (bFirst)
+ bFirst = false;
+ else
+ sPayload += ", ";
+ sPayload += "\"" + f.toUtf8() + "\"";
+ }
+ sPayload += " ] }";
+ pCallback(LOK_CALLBACK_FONTS_MISSING, sPayload.getStr(), pData);
+ pDocument->maFontsMissing.clear();
+ }
}
else
{
@@ -3724,12 +4626,12 @@ static char* getPostIts(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
tools::JsonWriter aJsonWriter;
pDoc->getPostIts(aJsonWriter);
- return aJsonWriter.extractData();
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
/// Returns the JSON representation of the positions of all the comments in the document
@@ -3739,12 +4641,12 @@ static char* getPostItsPos(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
tools::JsonWriter aJsonWriter;
pDoc->getPostItsPos(aJsonWriter);
- return aJsonWriter.extractData();
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
static char* getRulerState(LibreOfficeKitDocument* pThis)
@@ -3753,12 +4655,12 @@ static char* getRulerState(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
tools::JsonWriter aJsonWriter;
pDoc->getRulerState(aJsonWriter);
- return aJsonWriter.extractData();
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nCharCode, int nKeyCode)
@@ -3771,7 +4673,7 @@ static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nChar
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -3803,7 +4705,7 @@ static void doc_postWindowExtTextInputEvent(LibreOfficeKitDocument* pThis, unsig
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
pWindow = pDoc->getDocWindow();
@@ -3825,13 +4727,17 @@ static void doc_postWindowExtTextInputEvent(LibreOfficeKitDocument* pThis, unsig
static void doc_removeTextContext(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, int nCharBefore, int nCharAfter)
{
SolarMutexGuard aGuard;
+
+ if (SfxViewShell::IsCurrentLokViewReadOnly())
+ return;
+
VclPtr<vcl::Window> pWindow;
if (nLOKWindowId == 0)
{
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
pWindow = pDoc->getDocWindow();
@@ -3843,7 +4749,7 @@ static void doc_removeTextContext(LibreOfficeKitDocument* pThis, unsigned nLOKWi
if (!pWindow)
{
- gImpl->maLastExceptionMsg = "No window found for window id: " + OUString::number(nLOKWindowId);
+ SetLastExceptionMsg("No window found for window id: " + OUString::number(nLOKWindowId));
return;
}
@@ -3855,12 +4761,12 @@ static void doc_removeTextContext(LibreOfficeKitDocument* pThis, unsigned nLOKWi
// backspace
if (nLOKWindowId == 0)
{
- KeyEvent aEvt(8, 1283);
+ KeyEvent aEvt(8, KEY_BACKSPACE);
for (int i = 0; i < nCharBefore; ++i)
pWindow->KeyInput(aEvt);
}
else
- SfxLokHelper::postKeyEventAsync(pWindow, LOK_KEYEVENT_KEYINPUT, 8, 1283, nCharBefore - 1);
+ SfxLokHelper::postKeyEventAsync(pWindow, LOK_KEYEVENT_KEYINPUT, 8, KEY_BACKSPACE, nCharBefore - 1);
}
if (nCharAfter > 0)
@@ -3868,12 +4774,12 @@ static void doc_removeTextContext(LibreOfficeKitDocument* pThis, unsigned nLOKWi
// delete (forward)
if (nLOKWindowId == 0)
{
- KeyEvent aEvt(46, 1286);
+ KeyEvent aEvt(46, KEY_DELETE);
for (int i = 0; i < nCharAfter; ++i)
pWindow->KeyInput(aEvt);
}
else
- SfxLokHelper::postKeyEventAsync(pWindow, LOK_KEYEVENT_KEYINPUT, 46, 1286, nCharAfter - 1);
+ SfxLokHelper::postKeyEventAsync(pWindow, LOK_KEYEVENT_KEYINPUT, 46, KEY_DELETE, nCharAfter - 1);
}
}
@@ -3887,7 +4793,7 @@ static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned n
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return;
}
@@ -3907,6 +4813,37 @@ static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned n
}
}
+// To be an exportable selection, there must be something selected and that
+// selection can't be "ScCellObj" which doesn't can't provide a svg.
+//
+// Typically a problem arises when double clicking a shape in calc. The 1st
+// click selects the shape, triggering generation of a preview, but the second
+// shape enters into edit mode before doc_renderShapeSelection has a chance to
+// fire, at which point the shape is no longer selected. Rather than generate
+// an error just return a 0 length result if there is no shape selected, so we
+// continue to generate an error if a shape is selected, but could not provide
+// an svg.
+static bool doc_hasShapeSelection(const css::uno::Reference<css::lang::XComponent>& rComponent)
+{
+ uno::Reference<frame::XModel> xModel(rComponent, uno::UNO_QUERY);
+ if (!xModel.is())
+ return false;
+
+ uno::Reference<frame::XController> xController(xModel->getCurrentController());
+ if (!xController.is())
+ return false;
+
+ uno::Reference<view::XSelectionSupplier> xSelectionSupplier(xController, uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return false;
+
+ Any selection = xSelectionSupplier->getSelection();
+ uno::Reference<lang::XServiceInfo> xSelection;
+ selection >>= xSelection;
+
+ return xSelection && xSelection->getImplementationName() != "ScCellObj";
+}
+
static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput)
{
comphelper::ProfileZone aZone("doc_renderShapeSelection");
@@ -3923,6 +4860,9 @@ static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOu
{
LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+ if (!doc_hasShapeSelection(pDocument->mxComponent))
+ return 0;
+
uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
SvMemoryStream aOutStream;
@@ -3932,24 +4872,25 @@ static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOu
switch (doc_getDocumentType(pThis))
{
case LOK_DOCTYPE_PRESENTATION:
- aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+ aMediaDescriptor[u"FilterName"_ustr] <<= u"impress_svg_Export"_ustr;
break;
case LOK_DOCTYPE_DRAWING:
- aMediaDescriptor["FilterName"] <<= OUString("draw_svg_Export");
+ aMediaDescriptor[u"FilterName"_ustr] <<= u"draw_svg_Export"_ustr;
break;
case LOK_DOCTYPE_TEXT:
- aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export");
+ aMediaDescriptor[u"FilterName"_ustr] <<= u"writer_svg_Export"_ustr;
break;
case LOK_DOCTYPE_SPREADSHEET:
- aMediaDescriptor["FilterName"] <<= OUString("calc_svg_Export");
+ aMediaDescriptor[u"FilterName"_ustr] <<= u"calc_svg_Export"_ustr;
break;
default:
SAL_WARN("lok", "Failed to render shape selection: Document type is not supported");
}
- aMediaDescriptor["SelectionOnly"] <<= true;
- aMediaDescriptor["OutputStream"] <<= xOut;
+ aMediaDescriptor[u"SelectionOnly"_ustr] <<= true;
+ aMediaDescriptor[u"OutputStream"_ustr] <<= xOut;
+ aMediaDescriptor[u"IsPreview"_ustr] <<= true; // will down-scale graphics
- xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
+ xStorable->storeToURL(u"private:stream"_ustr, aMediaDescriptor.getAsConstPropertyValueList());
if (pOutput)
{
@@ -3983,13 +4924,17 @@ namespace {
*/
class DispatchResultListener : public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
{
- OString maCommand; ///< Command for which this is the result.
- std::shared_ptr<CallbackFlushHandler> mpCallback; ///< Callback to call.
+ const OString maCommand; ///< Command for which this is the result.
+ const std::shared_ptr<CallbackFlushHandler> mpCallback; ///< Callback to call.
+ const std::chrono::steady_clock::time_point mSaveTime; //< The time we started saving.
+ const bool mbWasModified; //< Whether or not the document was modified before saving.
public:
- DispatchResultListener(const char* pCommand, std::shared_ptr<CallbackFlushHandler> const & pCallback)
+ DispatchResultListener(const char* pCommand, std::shared_ptr<CallbackFlushHandler> pCallback)
: maCommand(pCommand)
- , mpCallback(pCallback)
+ , mpCallback(std::move(pCallback))
+ , mSaveTime(std::chrono::steady_clock::now())
+ , mbWasModified(SfxObjectShell::Current()->IsModified())
{
assert(mpCallback);
}
@@ -4006,7 +4951,15 @@ public:
}
unoAnyToJson(aJson, "result", rEvent.Result);
- mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
+ aJson.put("wasModified", mbWasModified);
+ aJson.put("startUnixTimeMics",
+ std::chrono::time_point_cast<std::chrono::microseconds>(mSaveTime)
+ .time_since_epoch()
+ .count());
+ aJson.put("saveDurationMics", std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now() - mSaveTime)
+ .count());
+ mpCallback->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
}
virtual void SAL_CALL disposing(const css::lang::EventObject&) override {}
@@ -4021,25 +4974,42 @@ static void lcl_sendDialogEvent(unsigned long long int nWindowId, const char* pA
StringMap aMap(jsdialog::jsonToStringMap(pArguments));
- if (aMap.find("id") == aMap.end())
+ if (aMap.find(u"id"_ustr) == aMap.end())
return;
sal_uInt64 nCurrentShellId = reinterpret_cast<sal_uInt64>(SfxViewShell::Current());
try
{
- OString sControlId = OUStringToOString(aMap["id"], RTL_TEXTENCODING_ASCII_US);
+ OUString sControlId = aMap[u"id"_ustr];
+ OUString sWindowId = OUString::number(nWindowId);
+ OUString sCurrentShellId = OUString::number(nCurrentShellId);
+
+ // special values for window id
+ if (nWindowId == static_cast<unsigned long long int>(-1))
+ sWindowId = sCurrentShellId + "sidebar";
+ if (nWindowId == static_cast<unsigned long long int>(-2))
+ sWindowId = sCurrentShellId + "notebookbar";
+ if (nWindowId == static_cast<unsigned long long int>(-3))
+ sWindowId = sCurrentShellId + "formulabar";
// dialogs send own id but notebookbar and sidebar controls are remembered by SfxViewShell id
- bool bFoundWeldedControl = jsdialog::ExecuteAction(nWindowId, sControlId, aMap);
- if (!bFoundWeldedControl)
- bFoundWeldedControl = jsdialog::ExecuteAction(nCurrentShellId, sControlId, aMap);
+ if (jsdialog::ExecuteAction(sWindowId, sControlId, aMap))
+ return;
- if (bFoundWeldedControl)
+ if (jsdialog::ExecuteAction(sCurrentShellId + "sidebar", sControlId, aMap))
+ return;
+ if (jsdialog::ExecuteAction(sCurrentShellId + "notebookbar", sControlId, aMap))
+ return;
+ if (jsdialog::ExecuteAction(sCurrentShellId + "formulabar", sControlId, aMap))
+ return;
+ // this is needed for dialogs shown before document is loaded: MacroWarning dialog, etc...
+ // these dialogs are created with WindowId "0"
+ if (!SfxViewShell::Current() && jsdialog::ExecuteAction(u"0"_ustr, sControlId, aMap))
return;
// force resend - used in mobile-wizard
- jsdialog::SendFullUpdate(nCurrentShellId, "Panel");
+ jsdialog::SendFullUpdate(sCurrentShellId + "sidebar", u"Panel"_ustr);
} catch(...) {}
}
@@ -4085,6 +5055,81 @@ static void lo_setOption(LibreOfficeKit* /*pThis*/, const char *pOption, const c
else
sal_detail_set_log_selector(pCurrentSalLogOverride);
}
+#ifdef LINUX
+ else if (strcmp(pOption, "addfont") == 0)
+ {
+ if (memcmp(pValue, "file://", 7) == 0)
+ pValue += 7;
+
+ int fd = open(pValue, O_RDONLY);
+ if (fd == -1)
+ {
+ std::cerr << "Could not open font file '" << pValue << "': " << strerror(errno) << std::endl;
+ return;
+ }
+
+ OUString sMagicFileName = "file:///:FD:/" + OUString::number(fd);
+
+ OutputDevice *pDevice = Application::GetDefaultDevice();
+ OutputDevice::ImplClearAllFontData(false);
+ pDevice->AddTempDevFont(sMagicFileName, "");
+ OutputDevice::ImplRefreshAllFontData(false);
+ }
+#endif
+}
+
+static void lo_dumpState (LibreOfficeKit* pThis, const char* /* pOptions */, char** pState)
+{
+ if (!pState)
+ return;
+
+ // NB. no SolarMutexGuard since this may be caused in some extremis / deadlock
+ SetLastExceptionMsg();
+
+ *pState = nullptr;
+ OStringBuffer aState(4096*256);
+
+ LibLibreOffice_Impl* pLib = static_cast<LibLibreOffice_Impl*>(pThis);
+
+ pLib->dumpState(aState);
+
+ *pState = convertOString(aState.makeStringAndClear());
+}
+
+void LibLibreOffice_Impl::dumpState(rtl::OStringBuffer &rState)
+{
+ rState.append("LibreOfficeKit state:"
+ "\n\tLastExceptionMsg:\t");
+ rState.append(rtl::OUStringToOString(maLastExceptionMsg, RTL_TEXTENCODING_UTF8));
+ rState.append("\n\tUnipoll:\t");
+ rState.append(vcl::lok::isUnipoll() ? "yes" : "no: events on thread");
+ rState.append("\n\tOptionalFeatures:\t0x");
+ rState.append(static_cast<sal_Int64>(mOptionalFeatures), 16);
+ rState.append("\n\tCallbackData:\t0x");
+ rState.append(reinterpret_cast<sal_Int64>(mpCallback), 16);
+ // TODO: dump mInteractionMap
+ SfxLokHelper::dumpState(rState);
+ vcl::lok::dumpState(rState);
+}
+
+// We have special handling for some uno commands and it seems we need to check for readonly state.
+static bool isCommandAllowed(OUString& command) {
+ static constexpr OUString nonAllowedList[] = { u".uno:Save"_ustr, u".uno:TransformDialog"_ustr, u".uno:SidebarShow"_ustr, u".uno:SidebarHide"_ustr };
+
+ if (!SfxViewShell::IsCurrentLokViewReadOnly())
+ return true;
+ else
+ {
+ if (command == u".uno:Save"_ustr && SfxViewShell::Current() && SfxViewShell::Current()->IsAllowChangeComments())
+ return true;
+
+ for (size_t i = 0; i < std::size(nonAllowedList); i++)
+ {
+ if (nonAllowedList[i] == command)
+ return false;
+ }
+ return true;
+ }
}
static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, const char* pArguments, bool bNotifyWhenFinished)
@@ -4096,6 +5141,10 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
SfxObjectShell* pDocSh = SfxObjectShell::Current();
OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
+
+ if (!isCommandAllowed(aCommand))
+ return;
+
LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
std::vector<beans::PropertyValue> aPropertyValuesVector(jsonToPropertyValuesVector(pArguments));
@@ -4103,7 +5152,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
if (!vcl::lok::isUnipoll())
{
beans::PropertyValue aSynchronMode;
- aSynchronMode.Name = "SynchronMode";
+ aSynchronMode.Name = u"SynchronMode"_ustr;
aSynchronMode.Value <<= false;
aPropertyValuesVector.push_back(aSynchronMode);
}
@@ -4123,7 +5172,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
{
// Check if saving a PDF file
OUString aMimeType = lcl_getCurrentDocumentMimeType(pDocument);
- if (pDocSh->IsModified() && aMimeType == "application/pdf")
+ if (pDocSh && pDocSh->IsModified() && aMimeType == "application/pdf")
{
// If we have a PDF file (for saving annotations for example), we need
// to run save-as to the same file as the opened document. Plain save
@@ -4137,23 +5186,22 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
tools::JsonWriter aJson;
aJson.put("commandName", pCommand);
aJson.put("success", bResult);
- pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
+ pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
return;
}
rtl::Reference<LOKInteractionHandler> const pInteraction(
- new LOKInteractionHandler("save", gImpl, pDocument));
+ new LOKInteractionHandler("save"_ostr, gImpl, pDocument));
uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction);
beans::PropertyValue aValue;
- aValue.Name = "InteractionHandler";
+ aValue.Name = u"InteractionHandler"_ustr;
aValue.Value <<= xInteraction;
aPropertyValuesVector.push_back(aValue);
bool bDontSaveIfUnmodified = false;
- aPropertyValuesVector.erase(std::remove_if(aPropertyValuesVector.begin(),
- aPropertyValuesVector.end(),
+ std::erase_if(aPropertyValuesVector,
[&bDontSaveIfUnmodified](const beans::PropertyValue& aItem){
if (aItem.Name == "DontSaveIfUnmodified")
{
@@ -4161,10 +5209,10 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
return true;
}
return false;
- }), aPropertyValuesVector.end());
+ });
// skip saving and tell the result via UNO_COMMAND_RESULT
- if (bDontSaveIfUnmodified && !pDocSh->IsModified())
+ if (bDontSaveIfUnmodified && (!pDocSh || !pDocSh->IsModified()))
{
tools::JsonWriter aJson;
aJson.put("commandName", pCommand);
@@ -4175,7 +5223,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
aJson.put("type", "string");
aJson.put("value", "unmodified");
}
- pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.extractData());
+ pDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_UNO_COMMAND_RESULT, aJson.finishAndGetAsOString());
return;
}
}
@@ -4210,7 +5258,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
|| rPropValue.Name == "TransformRotationY")
{
rPropValue.Value >>= value;
- value = OutputDevice::LogicToLogic(value, MapUnit::MapTwip, MapUnit::Map100thMM);
+ value = o3tl::convert(value, o3tl::Length::twip, o3tl::Length::mm100);
rPropValue.Value <<= value;
}
}
@@ -4240,7 +5288,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
}
}
util::URL aCommandURL;
- aCommandURL.Path = "LOKTransform";
+ aCommandURL.Path = u"LOKTransform"_ustr;
css::uno::Reference<css::frame::XDispatch>& aChartDispatcher = aChartHelper.GetXDispatcher();
aChartDispatcher->dispatch(aCommandURL, comphelper::containerToSequence(aPropertyValuesVector));
return;
@@ -4248,12 +5296,18 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
}
else if (gImpl && aCommand == ".uno:LOKSidebarWriterPage")
{
- setupSidebar(u"WriterPageDeck");
+ if (!sfx2::sidebar::Sidebar::Setup(u"WriterPageDeck"))
+ {
+ SetLastExceptionMsg(u"failed to set up sidebar"_ustr);
+ }
return;
}
else if (gImpl && aCommand == ".uno:SidebarShow")
{
- setupSidebar();
+ if (!sfx2::sidebar::Sidebar::Setup(u""))
+ {
+ SetLastExceptionMsg(u"failed to set up sidebar"_ustr);
+ }
return;
}
else if (gImpl && aCommand == ".uno:SidebarHide")
@@ -4273,7 +5327,13 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma
aChartDispatcher->dispatch(aCommandURL, comphelper::containerToSequence(aPropertyValuesVector));
return;
}
- else if (bNotifyWhenFinished && pDocument->mpCallbackFlushHandlers.count(nView))
+ if (LokStarMathHelper aMathHelper(SfxViewShell::Current());
+ aMathHelper.GetGraphicWindow() && aCommand != ".uno:Save")
+ {
+ aMathHelper.Dispatch(aCommand, comphelper::containerToSequence(aPropertyValuesVector));
+ return;
+ }
+ if (bNotifyWhenFinished && pDocument->mpCallbackFlushHandlers.count(nView))
{
bResult = comphelper::dispatchCommand(aCommand, comphelper::containerToSequence(aPropertyValuesVector),
new DispatchResultListener(pCommand, pDocument->mpCallbackFlushHandlers[nView]));
@@ -4297,7 +5357,7 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX,
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
try
@@ -4321,7 +5381,7 @@ static void doc_postWindowMouseEvent(LibreOfficeKitDocument* /*pThis*/, unsigned
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return;
}
@@ -4358,19 +5418,19 @@ static void doc_postWindowGestureEvent(LibreOfficeKitDocument* /*pThis*/, unsign
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return;
}
OString aType(pType);
- GestureEventType eEventType = GestureEventType::PanningUpdate;
+ GestureEventPanType eEventType = GestureEventPanType::Update;
if (aType == "panBegin")
- eEventType = GestureEventType::PanningBegin;
+ eEventType = GestureEventPanType::Begin;
else if (aType == "panEnd")
- eEventType = GestureEventType::PanningEnd;
+ eEventType = GestureEventPanType::End;
- GestureEvent aEvent {
+ GestureEventPan aEvent {
sal_Int32(nX),
sal_Int32(nY),
eEventType,
@@ -4393,7 +5453,7 @@ static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int n
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -4410,7 +5470,7 @@ static void doc_setWindowTextSelection(LibreOfficeKitDocument* /*pThis*/, unsign
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return;
}
@@ -4425,7 +5485,7 @@ static void doc_setWindowTextSelection(LibreOfficeKitDocument* /*pThis*/, unsign
Application::PostMouseEvent(VclEventId::WindowMouseButtonUp, pWindow, &aCursorEvent);
}
-static bool getFromTransferrable(
+static bool getFromTransferable(
const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
const OString &aInMimeType, OString &aRet);
@@ -4433,13 +5493,13 @@ static bool encodeImageAsHTML(
const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
const OString &aMimeType, OString &aRet)
{
- if (!getFromTransferrable(xTransferable, aMimeType, aRet))
+ if (!getFromTransferable(xTransferable, aMimeType, aRet))
return false;
// Encode in base64.
auto aSeq = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),
aRet.getLength());
- OUStringBuffer aBase64Data;
+ OStringBuffer aBase64Data;
comphelper::Base64::encode(aBase64Data, aSeq);
// Embed in HTML.
@@ -4450,7 +5510,7 @@ static bool encodeImageAsHTML(
+ getGenerator().toUtf8()
+ "\"/>"
"</head><body><img src=\"data:" + aMimeType + ";base64,"
- + aBase64Data.makeStringAndClear().toUtf8() + "\"/></body></html>";
+ + aBase64Data + "\"/></body></html>";
return true;
}
@@ -4459,7 +5519,7 @@ static bool encodeTextAsHTML(
const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
const OString &aMimeType, OString &aRet)
{
- if (!getFromTransferrable(xTransferable, aMimeType, aRet))
+ if (!getFromTransferable(xTransferable, aMimeType, aRet))
return false;
// Embed in HTML - FIXME: needs some escaping.
@@ -4473,7 +5533,7 @@ static bool encodeTextAsHTML(
return true;
}
-static bool getFromTransferrable(
+static bool getFromTransferable(
const css::uno::Reference<css::datatransfer::XTransferable> &xTransferable,
const OString &aInMimeType, OString &aRet)
{
@@ -4482,17 +5542,17 @@ static bool getFromTransferrable(
// Take care of UTF-8 text here.
bool bConvert = false;
sal_Int32 nIndex = 0;
- if (aMimeType.getToken(0, ';', nIndex) == "text/plain")
+ if (o3tl::getToken(aMimeType, 0, ';', nIndex) == "text/plain")
{
- if (aMimeType.getToken(0, ';', nIndex) == "charset=utf-8")
+ if (o3tl::getToken(aMimeType, 0, ';', nIndex) == "charset=utf-8")
{
- aMimeType = "text/plain;charset=utf-16";
+ aMimeType = "text/plain;charset=utf-16"_ostr;
bConvert = true;
}
}
datatransfer::DataFlavor aFlavor;
- aFlavor.MimeType = OUString::fromUtf8(aMimeType.getStr());
+ aFlavor.MimeType = OUString::fromUtf8(aMimeType);
if (aMimeType == "text/plain;charset=utf-16")
aFlavor.DataType = cppu::UnoType<OUString>::get();
else
@@ -4504,10 +5564,10 @@ static bool getFromTransferrable(
if (aInMimeType == "text/html")
{
// Desperate measures - convert text to HTML instead.
- if (encodeTextAsHTML(xTransferable, "text/plain;charset=utf-8", aRet))
+ if (encodeTextAsHTML(xTransferable, "text/plain;charset=utf-8"_ostr, aRet))
return true;
// If html is not supported, might be a graphic-selection,
- if (encodeImageAsHTML(xTransferable, "image/png", aRet))
+ if (encodeImageAsHTML(xTransferable, "image/png"_ostr, aRet))
return true;
}
@@ -4560,23 +5620,22 @@ static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, const char* pMi
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->getSelection();
if (!xTransferable)
{
- SetLastExceptionMsg("No selection available");
+ SetLastExceptionMsg(u"No selection available"_ustr);
return nullptr;
}
- const char *pType = pMimeType;
- if (!pType || pType[0] == '\0')
- pType = "text/plain;charset=utf-8";
+ OString aType
+ = pMimeType && pMimeType[0] != '\0' ? OString(pMimeType) : "text/plain;charset=utf-8"_ostr;
OString aRet;
- bool bSuccess = getFromTransferrable(xTransferable, OString(pType), aRet);
+ bool bSuccess = getFromTransferable(xTransferable, aType, aRet);
if (!bSuccess)
return nullptr;
@@ -4601,29 +5660,85 @@ static int doc_getSelectionType(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return LOK_SELTYPE_NONE;
}
- css::uno::Reference<css::datatransfer::XTransferable2> xTransferable(pDoc->getSelection(), css::uno::UNO_QUERY);
+ css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->getSelection();
if (!xTransferable)
{
- SetLastExceptionMsg("No selection available");
+ SetLastExceptionMsg(u"No selection available"_ustr);
return LOK_SELTYPE_NONE;
}
- if (xTransferable->isComplex())
+ css::uno::Reference<css::datatransfer::XTransferable2> xTransferable2(xTransferable, css::uno::UNO_QUERY);
+ if (xTransferable2.is() && xTransferable2->isComplex())
return LOK_SELTYPE_COMPLEX;
OString aRet;
- bool bSuccess = getFromTransferrable(xTransferable, "text/plain;charset=utf-8", aRet);
+ bool bSuccess = getFromTransferable(xTransferable, "text/plain;charset=utf-8"_ostr, aRet);
if (!bSuccess)
return LOK_SELTYPE_NONE;
if (aRet.getLength() > 10000)
return LOK_SELTYPE_COMPLEX;
- return aRet.getLength() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE;
+ return !aRet.isEmpty() ? LOK_SELTYPE_TEXT : LOK_SELTYPE_NONE;
+}
+
+static int doc_getSelectionTypeAndText(LibreOfficeKitDocument* pThis, const char* pMimeType, char** pText, char** pUsedMimeType)
+{
+ // The purpose of this function is to avoid double call to pDoc->getSelection(),
+ // which may be expensive.
+ comphelper::ProfileZone aZone("doc_getSelectionTypeAndText");
+
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return LOK_SELTYPE_NONE;
+ }
+
+ css::uno::Reference<css::datatransfer::XTransferable> xTransferable = pDoc->getSelection();
+ if (!xTransferable)
+ {
+ SetLastExceptionMsg(u"No selection available"_ustr);
+ return LOK_SELTYPE_NONE;
+ }
+
+ css::uno::Reference<css::datatransfer::XTransferable2> xTransferable2(xTransferable, css::uno::UNO_QUERY);
+ if (xTransferable2.is() && xTransferable2->isComplex())
+ return LOK_SELTYPE_COMPLEX;
+
+ OString aType
+ = pMimeType && pMimeType[0] != '\0' ? OString(pMimeType) : "text/plain;charset=utf-8"_ostr;
+
+ OString aRet;
+ bool bSuccess = getFromTransferable(xTransferable, aType, aRet);
+ if (!bSuccess)
+ return LOK_SELTYPE_NONE;
+
+ if (aRet.getLength() > 10000)
+ return LOK_SELTYPE_COMPLEX;
+
+ if (aRet.isEmpty())
+ return LOK_SELTYPE_NONE;
+
+ if (pText)
+ *pText = convertOString(aRet);
+
+ if (pUsedMimeType) // legacy
+ {
+ if (pMimeType)
+ *pUsedMimeType = strdup(pMimeType);
+ else
+ *pUsedMimeType = nullptr;
+ }
+
+ return LOK_SELTYPE_TEXT;
}
static int doc_getClipboard(LibreOfficeKitDocument* pThis,
@@ -4663,17 +5778,17 @@ static int doc_getClipboard(LibreOfficeKitDocument* pThis,
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return 0;
}
rtl::Reference<LOKClipboard> xClip(LOKClipboardFactory::getClipboardForCurView());
css::uno::Reference<css::datatransfer::XTransferable> xTransferable = xClip->getContents();
- SAL_INFO("lok", "Got from clip: " << xClip.get() << " transferrable: " << xTransferable);
+ SAL_INFO("lok", "Got from clip: " << xClip.get() << " transferable: " << xTransferable);
if (!xTransferable)
{
- SetLastExceptionMsg("No clipboard content available");
+ SetLastExceptionMsg(u"No clipboard content available"_ustr);
return 0;
}
@@ -4683,7 +5798,7 @@ static int doc_getClipboard(LibreOfficeKitDocument* pThis,
const uno::Sequence< css::datatransfer::DataFlavor > flavors = xTransferable->getTransferDataFlavors();
if (!flavors.getLength())
{
- SetLastExceptionMsg("Flavourless selection");
+ SetLastExceptionMsg(u"Flavourless selection"_ustr);
return 0;
}
for (const auto &it : flavors)
@@ -4704,10 +5819,10 @@ static int doc_getClipboard(LibreOfficeKitDocument* pThis,
if (aMimeTypes[i] == "text/plain;charset=utf-16")
(*pOutMimeTypes)[i] = strdup("text/plain;charset=utf-8");
else
- (*pOutMimeTypes)[i] = strdup(aMimeTypes[i].getStr());
+ (*pOutMimeTypes)[i] = convertOString(aMimeTypes[i]);
OString aRet;
- bool bSuccess = getFromTransferrable(xTransferable, (*pOutMimeTypes)[i], aRet);
+ bool bSuccess = getFromTransferable(xTransferable, (*pOutMimeTypes)[i], aRet);
if (!bSuccess || aRet.getLength() < 1)
{
(*pOutSizes)[i] = 0;
@@ -4745,7 +5860,7 @@ static int doc_setClipboard(LibreOfficeKitDocument* pThis,
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return false;
}
@@ -4758,7 +5873,7 @@ static int doc_setClipboard(LibreOfficeKitDocument* pThis,
if (!pDoc->isMimeTypeSupported())
{
- SetLastExceptionMsg("Document doesn't support this mime type");
+ SetLastExceptionMsg(u"Document doesn't support this mime type"_ustr);
return false;
}
#endif
@@ -4783,12 +5898,12 @@ static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, cons
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
- {"AnchorType", uno::makeAny(static_cast<sal_uInt16>(css::text::TextContentAnchorType_AS_CHARACTER))},
- {"IgnoreComments", uno::makeAny(true)},
+ {"AnchorType", uno::Any(static_cast<sal_uInt16>(css::text::TextContentAnchorType_AS_CHARACTER))},
+ {"IgnoreComments", uno::Any(true)},
}));
- if (!comphelper::dispatchCommand(".uno:Paste", aPropertyValues))
+ if (!comphelper::dispatchCommand(u".uno:Paste"_ustr, aPropertyValues))
{
- SetLastExceptionMsg("Failed to dispatch the .uno: command");
+ SetLastExceptionMsg(u"Failed to dispatch the .uno: command"_ustr);
return false;
}
@@ -4805,7 +5920,7 @@ static void doc_setGraphicSelection(LibreOfficeKitDocument* pThis, int nType, in
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -4822,19 +5937,55 @@ static void doc_resetSelection(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
pDoc->resetSelection();
}
+static char* getDocReadOnly(LibreOfficeKitDocument* pThis)
+{
+ SfxObjectShell* pObjectShell = getSfxObjectShell(pThis);
+ if (!pObjectShell)
+ return nullptr;
+
+ boost::property_tree::ptree aTree;
+ aTree.put("commandName", ".uno:ReadOnly");
+ aTree.put("success", pObjectShell->IsLoadReadonly());
+
+ std::stringstream aStream;
+ boost::property_tree::write_json(aStream, aTree);
+ char* pJson = static_cast<char*>(malloc(aStream.str().size() + 1));
+ if (!pJson)
+ return nullptr;
+
+ strcpy(pJson, aStream.str().c_str());
+ pJson[aStream.str().size()] = '\0';
+ return pJson;
+}
+
+static void addLocale(boost::property_tree::ptree& rValues, css::lang::Locale const & rLocale)
+{
+ boost::property_tree::ptree aChild;
+ const LanguageTag aLanguageTag( rLocale );
+ OUString sLanguage = SvtLanguageTable::GetLanguageString(aLanguageTag.getLanguageType());
+ if (sLanguage.endsWith("}"))
+ return;
+
+ sLanguage += ";" + aLanguageTag.getBcp47(false);
+ aChild.put("", sLanguage.toUtf8());
+ rValues.push_back(std::make_pair("", aChild));
+}
+
static char* getLanguages(const char* pCommand)
{
css::uno::Sequence< css::lang::Locale > aLocales;
+ css::uno::Sequence< css::lang::Locale > aGrammarLocales;
if (xContext.is())
{
+ // SpellChecker
css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLangSrv = css::linguistic2::LinguServiceManager::create(xContext);
if (xLangSrv.is())
{
@@ -4842,24 +5993,25 @@ static char* getLanguages(const char* pCommand)
if (xSpell.is())
aLocales = xSpell->getLocales();
}
+
+ // LanguageTool
+ if (LanguageToolCfg::IsEnabled::get())
+ {
+ uno::Reference< linguistic2::XProofreader > xGC(
+ xContext->getServiceManager()->createInstanceWithContext(u"org.openoffice.lingu.LanguageToolGrammarChecker"_ustr, xContext),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< linguistic2::XSupportedLocales > xSuppLoc( xGC, uno::UNO_QUERY_THROW );
+ aGrammarLocales = xSuppLoc->getLocales();
+ }
}
boost::property_tree::ptree aTree;
aTree.put("commandName", pCommand);
boost::property_tree::ptree aValues;
- boost::property_tree::ptree aChild;
- OUString sLanguage;
- for ( css::lang::Locale const & locale : std::as_const(aLocales) )
- {
- const LanguageTag aLanguageTag( locale );
- sLanguage = SvtLanguageTable::GetLanguageString(aLanguageTag.getLanguageType());
- if (sLanguage.startsWith("{") && sLanguage.endsWith("}"))
- continue;
-
- sLanguage += ";" + aLanguageTag.getBcp47(false);
- aChild.put("", sLanguage.toUtf8());
- aValues.push_back(std::make_pair("", aChild));
- }
+ for (css::lang::Locale const& rLocale : aLocales)
+ addLocale(aValues, rLocale);
+ for (css::lang::Locale const& rLocale : aGrammarLocales)
+ addLocale(aValues, rLocale);
aTree.add_child("commandValues", aValues);
std::stringstream aStream;
boost::property_tree::write_json(aStream, aTree);
@@ -4873,6 +6025,8 @@ static char* getLanguages(const char* pCommand)
static char* getFonts (const char* pCommand)
{
SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ if (!pDocSh)
+ return nullptr;
const SvxFontListItem* pFonts = static_cast<const SvxFontListItem*>(
pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST));
const FontList* pList = pFonts ? pFonts->GetFontList() : nullptr;
@@ -4920,7 +6074,7 @@ static char* getFontSubset (std::string_view aFontName)
if (const vcl::Font* pFont = FindFont(aFoundFont))
{
FontCharMapRef xFontCharMap (new FontCharMap());
- auto aDevice(VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT));
+ auto aDevice(VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA));
aDevice->SetFont(*pFont);
aDevice->GetFontCharMap(xFontCharMap);
@@ -4954,15 +6108,15 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand)
const uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
const uno::Sequence<OUString> aStyleFamilies = xStyleFamilies->getElementNames();
- static const std::vector<OUString> aWriterStyles =
+ static constexpr OUString aWriterStyles[] =
{
- "Text body",
- "Quotations",
- "Title",
- "Subtitle",
- "Heading 1",
- "Heading 2",
- "Heading 3"
+ u"Text body"_ustr,
+ u"Quotations"_ustr,
+ u"Title"_ustr,
+ u"Subtitle"_ustr,
+ u"Heading 1"_ustr,
+ u"Heading 2"_ustr,
+ u"Heading 3"_ustr,
};
// We need to keep a list of the default style names
@@ -5012,7 +6166,7 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand)
{
boost::property_tree::ptree aChild;
boost::property_tree::ptree aChildren;
- static const OUStringLiteral sPageStyles(u"PageStyles");
+ static constexpr OUString sPageStyles(u"PageStyles"_ustr);
uno::Reference<beans::XPropertySet> xProperty;
uno::Reference<container::XNameContainer> xContainer;
@@ -5023,10 +6177,10 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand)
{
bool bIsPhysical;
xProperty.set(xContainer->getByName(sName), uno::UNO_QUERY);
- if (xProperty.is() && (xProperty->getPropertyValue("IsPhysical") >>= bIsPhysical) && bIsPhysical)
+ if (xProperty.is() && (xProperty->getPropertyValue(u"IsPhysical"_ustr) >>= bIsPhysical) && bIsPhysical)
{
OUString displayName;
- xProperty->getPropertyValue("DisplayName") >>= displayName;
+ xProperty->getPropertyValue(u"DisplayName"_ustr) >>= displayName;
aChild.put("", displayName.toUtf8());
aChildren.push_back(std::make_pair("", aChild));
}
@@ -5099,7 +6253,7 @@ static char* getUndoOrRedo(LibreOfficeKitDocument* pThis, UndoOrRedo eCommand)
aString = pUndoManager->GetUndoActionsInfo();
else
aString = pUndoManager->GetRedoActionsInfo();
- char* pJson = strdup(aString.toUtf8().getStr());
+ char* pJson = convertOUString(aString);
return pJson;
}
@@ -5124,23 +6278,23 @@ static char* getTrackedChanges(LibreOfficeKitDocument* pThis)
aJson.put("index", static_cast<sal_Int32>(nIndex));
OUString sAuthor;
- xRedline->getPropertyValue("RedlineAuthor") >>= sAuthor;
+ xRedline->getPropertyValue(u"RedlineAuthor"_ustr) >>= sAuthor;
aJson.put("author", sAuthor);
OUString sType;
- xRedline->getPropertyValue("RedlineType") >>= sType;
+ xRedline->getPropertyValue(u"RedlineType"_ustr) >>= sType;
aJson.put("type", sType);
OUString sComment;
- xRedline->getPropertyValue("RedlineComment") >>= sComment;
+ xRedline->getPropertyValue(u"RedlineComment"_ustr) >>= sComment;
aJson.put("comment", sComment);
OUString sDescription;
- xRedline->getPropertyValue("RedlineDescription") >>= sDescription;
+ xRedline->getPropertyValue(u"RedlineDescription"_ustr) >>= sDescription;
aJson.put("description", sDescription);
util::DateTime aDateTime;
- xRedline->getPropertyValue("RedlineDateTime") >>= aDateTime;
+ xRedline->getPropertyValue(u"RedlineDateTime"_ustr) >>= aDateTime;
OUString sDateTime = utl::toISO8601(aDateTime);
aJson.put("dateTime", sDateTime);
}
@@ -5150,13 +6304,13 @@ static char* getTrackedChanges(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
pDoc->getTrackedChanges(aJson);
}
- return aJson.extractData();
+ return convertOString(aJson.finishAndGetAsOString());
}
@@ -5166,12 +6320,12 @@ static char* getTrackedChangeAuthors(LibreOfficeKitDocument* pThis)
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return nullptr;
}
tools::JsonWriter aJsonWriter;
pDoc->getTrackedChangeAuthors(aJsonWriter);
- return aJsonWriter.extractData();
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand)
@@ -5181,21 +6335,31 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
SolarMutexGuard aGuard;
SetLastExceptionMsg();
- OString aCommand(pCommand);
- static constexpr OStringLiteral aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
- static constexpr OStringLiteral aSheetGeometryData(".uno:SheetGeometryData");
- static constexpr OStringLiteral aCellCursor(".uno:CellCursor");
- static constexpr OStringLiteral aFontSubset(".uno:FontSubset&name=");
+ const std::string_view aCommand(pCommand);
+ static constexpr std::string_view aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
+ static constexpr std::string_view aSheetGeometryData(".uno:SheetGeometryData");
+ static constexpr std::string_view aFontSubset(".uno:FontSubset&name=");
+
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return nullptr;
+ }
- if (!strcmp(pCommand, ".uno:LanguageStatus"))
+ if (aCommand == ".uno:ReadOnly")
+ {
+ return getDocReadOnly(pThis);
+ }
+ else if (aCommand == ".uno:LanguageStatus")
{
return getLanguages(pCommand);
}
- else if (!strcmp(pCommand, ".uno:CharFontName"))
+ else if (aCommand == ".uno:CharFontName")
{
return getFonts(pCommand);
}
- else if (!strcmp(pCommand, ".uno:StyleApply"))
+ else if (aCommand == ".uno:StyleApply")
{
return getStyles(pThis, pCommand);
}
@@ -5227,48 +6391,45 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
{
return getRulerState(pThis);
}
- else if (aCommand.startsWith(aViewRowColumnHeaders))
+ else if (aCommand == ".uno:ViewRenderState")
+ {
+ return convertOString(pDoc->getViewRenderState());
+ }
+ else if (aCommand.starts_with(aViewRowColumnHeaders))
{
- ITiledRenderable* pDoc = getTiledRenderable(pThis);
- if (!pDoc)
- {
- SetLastExceptionMsg("Document doesn't support tiled rendering");
- return nullptr;
- }
-
tools::Rectangle aRectangle;
- if (aCommand.getLength() > aViewRowColumnHeaders.getLength())
+ if (aCommand.size() > aViewRowColumnHeaders.size())
{
// Command has parameters.
int nX = 0;
int nY = 0;
int nWidth = 0;
int nHeight = 0;
- OString aArguments = aCommand.copy(aViewRowColumnHeaders.getLength() + 1);
+ std::string_view aArguments = aCommand.substr(aViewRowColumnHeaders.size() + 1);
sal_Int32 nParamIndex = 0;
do
{
- OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
+ std::string_view aParamToken = o3tl::getToken(aArguments, 0, '&', nParamIndex);
sal_Int32 nIndex = 0;
- OString aKey;
- OString aValue;
+ std::string_view aKey;
+ std::string_view aValue;
do
{
- OString aToken = aParamToken.getToken(0, '=', nIndex);
- if (!aKey.getLength())
+ std::string_view aToken = o3tl::getToken(aParamToken, 0, '=', nIndex);
+ if (aKey.empty())
aKey = aToken;
else
aValue = aToken;
}
while (nIndex >= 0);
if (aKey == "x")
- nX = aValue.toInt32();
+ nX = o3tl::toInt32(aValue);
else if (aKey == "y")
- nY = aValue.toInt32();
+ nY = o3tl::toInt32(aValue);
else if (aKey == "width")
- nWidth = aValue.toInt32();
+ nWidth = o3tl::toInt32(aValue);
else if (aKey == "height")
- nHeight = aValue.toInt32();
+ nHeight = o3tl::toInt32(aValue);
}
while (nParamIndex >= 0);
@@ -5277,47 +6438,40 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
tools::JsonWriter aJsonWriter;
pDoc->getRowColumnHeaders(aRectangle, aJsonWriter);
- return aJsonWriter.extractData();
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
- else if (aCommand.startsWith(aSheetGeometryData))
+ else if (aCommand.starts_with(aSheetGeometryData))
{
- ITiledRenderable* pDoc = getTiledRenderable(pThis);
- if (!pDoc)
- {
- SetLastExceptionMsg("Document doesn't support tiled rendering");
- return nullptr;
- }
-
bool bColumns = true;
bool bRows = true;
bool bSizes = true;
bool bHidden = true;
bool bFiltered = true;
bool bGroups = true;
- if (aCommand.getLength() > aSheetGeometryData.getLength())
+ if (aCommand.size() > aSheetGeometryData.size())
{
bColumns = bRows = bSizes = bHidden = bFiltered = bGroups = false;
- OString aArguments = aCommand.copy(aSheetGeometryData.getLength() + 1);
+ std::string_view aArguments = aCommand.substr(aSheetGeometryData.size() + 1);
sal_Int32 nParamIndex = 0;
do
{
- OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
+ std::string_view aParamToken = o3tl::getToken(aArguments, 0, '&', nParamIndex);
sal_Int32 nIndex = 0;
- OString aKey;
- OString aValue;
+ std::string_view aKey;
+ std::string_view aValue;
do
{
- OString aToken = aParamToken.getToken(0, '=', nIndex);
- if (!aKey.getLength())
+ std::string_view aToken = o3tl::getToken(aParamToken, 0, '=', nIndex);
+ if (aKey.empty())
aKey = aToken;
else
aValue = aToken;
} while (nIndex >= 0);
- bool bEnableFlag = aValue.isEmpty() ||
- aValue.equalsIgnoreAsciiCase("true") || aValue.toInt32() > 0;
+ bool bEnableFlag = aValue.empty() ||
+ o3tl::equalsIgnoreAsciiCase(aValue, "true") || o3tl::toInt32(aValue) > 0;
if (!bEnableFlag)
continue;
@@ -5345,26 +6499,26 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
return convertOString(aGeomDataStr);
}
- else if (aCommand.startsWith(aCellCursor))
+ else if (aCommand.starts_with(".uno:CellCursor"))
{
- ITiledRenderable* pDoc = getTiledRenderable(pThis);
- if (!pDoc)
- {
- SetLastExceptionMsg("Document doesn't support tiled rendering");
- return nullptr;
- }
// Ignore command's deprecated parameters.
tools::JsonWriter aJsonWriter;
pDoc->getCellCursor(aJsonWriter);
- return aJsonWriter.extractData();
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
- else if (aCommand.startsWith(aFontSubset))
+ else if (aCommand.starts_with(aFontSubset))
{
- return getFontSubset(std::string_view(pCommand + aFontSubset.getLength()));
+ return getFontSubset(aCommand.substr(aFontSubset.size()));
+ }
+ else if (pDoc->supportsCommand(INetURLObject(OUString::fromUtf8(aCommand)).GetURLPath()))
+ {
+ tools::JsonWriter aJsonWriter;
+ pDoc->getCommandValues(aJsonWriter, aCommand);
+ return convertOString(aJsonWriter.finishAndGetAsOString());
}
else
{
- SetLastExceptionMsg("Unknown command, no values returned");
+ SetLastExceptionMsg(u"Unknown command, no values returned"_ustr);
return nullptr;
}
}
@@ -5380,7 +6534,7 @@ static void doc_setClientZoom(LibreOfficeKitDocument* pThis, int nTilePixelWidth
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -5397,7 +6551,7 @@ static void doc_setClientVisibleArea(LibreOfficeKitDocument* pThis, int nX, int
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -5415,7 +6569,7 @@ static void doc_setOutlineState(LibreOfficeKitDocument* pThis, bool bColumn, int
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -5533,8 +6687,6 @@ static void doc_setViewLanguage(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*p
SfxLokHelper::setViewLocale(nId, sLanguage);
}
-
-
unsigned char* doc_renderFont(LibreOfficeKitDocument* pThis,
const char* pFontName,
const char* pChar,
@@ -5564,7 +6716,7 @@ unsigned char* doc_renderFontOrientation(SAL_UNUSED_PARAMETER LibreOfficeKitDocu
if (aText.isEmpty())
aText = aFont.GetFamilyName();
- auto aDevice(VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT));
+ auto aDevice(VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA));
::tools::Rectangle aRect;
aFont.SetFontSize(Size(0, nDefaultFontSize));
aFont.SetOrientation(Degree10(pOrientation));
@@ -5606,7 +6758,7 @@ unsigned char* doc_renderFontOrientation(SAL_UNUSED_PARAMETER LibreOfficeKitDocu
memset(pBuffer, 0, nFontWidth * nFontHeight * 4);
aDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
- aDevice->SetOutputSizePixelScaleOffsetAndBuffer(
+ aDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(
Size(nFontWidth, nFontHeight), Fraction(1.0), Point(),
pBuffer);
@@ -5663,7 +6815,7 @@ static void doc_paintWindowForView(LibreOfficeKitDocument* pThis, unsigned nLOKW
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return;
}
@@ -5679,8 +6831,9 @@ static void doc_paintWindowForView(LibreOfficeKitDocument* pThis, unsigned nLOKW
comphelper::LibreOfficeKit::setDPIScale(fDPIScale);
#if defined(IOS)
-
- CGContextRef cgc = CGBitmapContextCreate(pBuffer, nWidth, nHeight, 8, nWidth*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little);
+ // Onine uses the LOK_TILEMODE_RGBA by default so flip the normal flags
+ // to kCGImageAlphaNoneSkipLast | kCGImageByteOrder32Big
+ CGContextRef cgc = CGBitmapContextCreate(pBuffer, nWidth, nHeight, 8, nWidth*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipLast | kCGImageByteOrder32Big);
CGContextTranslateCTM(cgc, 0, nHeight);
CGContextScaleCTM(cgc, fDPIScale, -fDPIScale);
@@ -5688,7 +6841,7 @@ static void doc_paintWindowForView(LibreOfficeKitDocument* pThis, unsigned nLOKW
SystemGraphicsData aData;
aData.rCGContext = cgc;
- ScopedVclPtrInstance<VirtualDevice> pDevice(aData, Size(1, 1), DeviceFormat::DEFAULT);
+ ScopedVclPtrInstance<VirtualDevice> pDevice(aData, Size(1, 1), DeviceFormat::WITHOUT_ALPHA);
pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
pDevice->SetOutputSizePixel(Size(nWidth, nHeight));
@@ -5703,10 +6856,10 @@ static void doc_paintWindowForView(LibreOfficeKitDocument* pThis, unsigned nLOKW
#else
- ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+ ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::WITHOUT_ALPHA);
pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
- pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nWidth, nHeight), Fraction(1.0), Point(), pBuffer);
+ pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(Size(nWidth, nHeight), Fraction(1.0), Point(), pBuffer);
MapMode aMapMode(pDevice->GetMapMode());
aMapMode.SetOrigin(Point(-(nX / fDPIScale), -(nY / fDPIScale)));
@@ -5728,7 +6881,7 @@ static void doc_postWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindo
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found.");
+ SetLastExceptionMsg(u"Document doesn't support dialog rendering, or window not found."_ustr);
return;
}
@@ -5759,7 +6912,7 @@ static void doc_postWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindo
Application::PostKeyEvent(VclEventId::WindowKeyInput, pWindow, &aEvent);
}
else
- SetLastExceptionMsg("Window command 'paste': wrong parameters.");
+ SetLastExceptionMsg(u"Window command 'paste': wrong parameters."_ustr);
#else
(void) pData;
assert(!"doc_postWindow() with LOK_WINDOW_PASTE should not be called on iOS");
@@ -5808,7 +6961,7 @@ static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
std::string aCertificateBase64String = extractCertificate(aCertificateString);
if (!aCertificateBase64String.empty())
{
- OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
+ OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String);
comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
}
else
@@ -5822,7 +6975,7 @@ static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
if (!aPrivateKeyBase64String.empty())
{
- OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String.c_str());
+ OUString aBase64OUString = OUString::createFromAscii(aPrivateKeyBase64String);
comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
}
else
@@ -5880,7 +7033,7 @@ static bool doc_addCertificate(LibreOfficeKitDocument* pThis,
std::string aCertificateBase64String = extractCertificate(aCertificateString);
if (!aCertificateBase64String.empty())
{
- OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String.c_str());
+ OUString aBase64OUString = OUString::createFromAscii(aCertificateBase64String);
comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
}
else
@@ -5889,7 +7042,7 @@ static bool doc_addCertificate(LibreOfficeKitDocument* pThis,
std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.getArray());
}
- uno::Reference<security::XCertificate> xCertificate = xCertificateCreator->addDERCertificateToTheDatabase(aCertificateSequence, "TCu,Cu,Tu");
+ uno::Reference<security::XCertificate> xCertificate = xCertificateCreator->addDERCertificateToTheDatabase(aCertificateSequence, u"TCu,Cu,Tu"_ustr);
if (!xCertificate.is())
return false;
@@ -5927,13 +7080,12 @@ static void doc_resizeWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWin
const int nWidth, const int nHeight)
{
SolarMutexGuard aGuard;
- if (gImpl)
- gImpl->maLastExceptionMsg.clear();
+ SetLastExceptionMsg();
VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nLOKWindowId);
if (!pWindow)
{
- gImpl->maLastExceptionMsg = "Document doesn't support dialog resizing, or window not found.";
+ SetLastExceptionMsg(u"Document doesn't support dialog resizing, or window not found."_ustr);
return;
}
@@ -5948,7 +7100,7 @@ static void doc_completeFunction(LibreOfficeKitDocument* pThis, const char* pFun
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return;
}
@@ -5968,14 +7120,14 @@ static void doc_sendFormFieldEvent(LibreOfficeKitDocument* pThis, const char* pA
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering!");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering!"_ustr);
return;
}
// Sanity check
- if (aMap.find("type") == aMap.end() || aMap.find("cmd") == aMap.end())
+ if (aMap.find(u"type"_ustr) == aMap.end() || aMap.find(u"cmd"_ustr) == aMap.end())
{
- SetLastExceptionMsg("Wrong arguments for sendFormFieldEvent!");
+ SetLastExceptionMsg(u"Wrong arguments for sendFormFieldEvent!"_ustr);
return;
}
@@ -5998,7 +7150,7 @@ static bool doc_renderSearchResult(LibreOfficeKitDocument* pThis,
ITiledRenderable* pDoc = getTiledRenderable(pThis);
if (!pDoc)
{
- SetLastExceptionMsg("Document doesn't support tiled rendering");
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
return false;
}
@@ -6032,6 +7184,86 @@ static bool doc_renderSearchResult(LibreOfficeKitDocument* pThis,
return true;
}
+static void doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const char* pArguments)
+{
+ SolarMutexGuard aGuard;
+
+ // Supported in Writer only
+ if (doc_getDocumentType(pThis) != LOK_DOCTYPE_TEXT)
+ {
+ return;
+ }
+
+ if (SfxViewShell::IsCurrentLokViewReadOnly())
+ return;
+
+ StringMap aMap(jsdialog::jsonToStringMap(pArguments));
+ ITiledRenderable* pDoc = getTiledRenderable(pThis);
+ if (!pDoc)
+ {
+ SetLastExceptionMsg(u"Document doesn't support tiled rendering"_ustr);
+ return;
+ }
+
+ // Sanity check
+ if (aMap.find(u"type"_ustr) == aMap.end())
+ {
+ SetLastExceptionMsg(u"Missing 'type' argument for sendContentControlEvent"_ustr);
+ return;
+ }
+
+ pDoc->executeContentControlEvent(aMap);
+}
+
+static void doc_setViewTimezone(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/, int nId,
+ const char* pTimezone)
+{
+ comphelper::ProfileZone aZone("doc_setViewTimezone");
+
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ // Leave the default if we get a null timezone.
+ if (pTimezone)
+ {
+ OUString sTimezone = OStringToOUString(pTimezone, RTL_TEXTENCODING_UTF8);
+ SfxLokHelper::setViewTimezone(nId, true, sTimezone);
+ }
+}
+
+static void doc_setViewReadOnly(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* pThis, int nId, const bool readOnly)
+{
+ comphelper::ProfileZone aZone("doc_setViewReadOnly");
+
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ doc_setView(pThis, nId);
+ SfxViewShell::Current()->SetLokReadOnlyView(readOnly);
+}
+
+static void doc_setAllowChangeComments(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* pThis, int nId, const bool allow)
+{
+ comphelper::ProfileZone aZone("doc_setAllowChangeComments");
+
+ SolarMutexGuard aGuard;
+ SetLastExceptionMsg();
+
+ doc_setView(pThis, nId);
+ SfxViewShell::Current()->SetAllowChangeComments(allow);
+}
+
+static void doc_setAccessibilityState(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* pThis, int nId, bool nEnabled)
+{
+ SolarMutexGuard aGuard;
+
+ int nDocType = getDocumentType(pThis);
+ if (!(nDocType == LOK_DOCTYPE_TEXT || nDocType == LOK_DOCTYPE_PRESENTATION || nDocType == LOK_DOCTYPE_SPREADSHEET))
+ return;
+
+ SfxLokHelper::setAccessibilityState(nId, nEnabled);
+}
+
static char* lo_getError (LibreOfficeKit *pThis)
{
comphelper::ProfileZone aZone("lo_getError");
@@ -6059,11 +7291,11 @@ static char* lo_getFilterTypes(LibreOfficeKit* pThis)
if (!xSFactory.is())
{
- pImpl->maLastExceptionMsg = "Service factory is not available";
+ pImpl->maLastExceptionMsg = u"Service factory is not available"_ustr;
return nullptr;
}
- uno::Reference<container::XNameAccess> xTypeDetection(xSFactory->createInstance("com.sun.star.document.TypeDetection"), uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xTypeDetection(xSFactory->createInstance(u"com.sun.star.document.TypeDetection"_ustr), uno::UNO_QUERY);
const uno::Sequence<OUString> aTypes = xTypeDetection->getElementNames();
tools::JsonWriter aJson;
for (const OUString& rType : aTypes)
@@ -6075,13 +7307,13 @@ static char* lo_getFilterTypes(LibreOfficeKit* pThis)
OUString aValue;
if (it != std::cend(aValues) && (it->Value >>= aValue) && !aValue.isEmpty())
{
- auto typeNode = aJson.startNode(rType.toUtf8().getStr());
+ auto typeNode = aJson.startNode(rType.toUtf8());
aJson.put("MediaType", aValue.toUtf8());
}
}
}
- return aJson.extractData();
+ return convertOString(aJson.finishAndGetAsOString());
}
static void lo_setOptionalFeatures(LibreOfficeKit* pThis, unsigned long long const features)
@@ -6122,12 +7354,15 @@ static char* lo_getVersionInfo(SAL_UNUSED_PARAMETER LibreOfficeKit* /*pThis*/)
{
SetLastExceptionMsg();
return convertOUString(ReplaceStringHookProc(
- "{ "
+ u"{ "
"\"ProductName\": \"%PRODUCTNAME\", "
"\"ProductVersion\": \"%PRODUCTVERSION\", "
"\"ProductExtension\": \"%PRODUCTEXTENSION\", "
- "\"BuildId\": \"%BUILDID\" "
- "}"));
+ "\"BuildId\": \"%BUILDID\""
+#if BUILDCONFIG_RECORDED
+ ", \"BuildConfig\": \"" BUILDCONFIG "\""
+#endif
+ " }"_ustr));
}
static void aBasicErrorFunc(const OUString& rError, const OUString& rAction)
@@ -6156,7 +7391,7 @@ static bool initialize_uno(const OUString& aAppProgramURL)
if (!xContext.is())
{
- SetLastExceptionMsg("XComponentContext could not be created");
+ SetLastExceptionMsg(u"XComponentContext could not be created"_ustr);
SAL_INFO("lok", "XComponentContext could not be created");
return false;
}
@@ -6164,7 +7399,7 @@ static bool initialize_uno(const OUString& aAppProgramURL)
xFactory = xContext->getServiceManager();
if (!xFactory.is())
{
- SetLastExceptionMsg("XMultiComponentFactory could not be created");
+ SetLastExceptionMsg(u"XMultiComponentFactory could not be created"_ustr);
SAL_INFO("lok", "XMultiComponentFactory could not be created");
return false;
}
@@ -6203,7 +7438,7 @@ static void lo_runLoop(LibreOfficeKit* /*pThis*/,
LibreOfficeKitWakeCallback pWakeCallback,
void* pData)
{
-#if defined(IOS) || defined(ANDROID)
+#if defined(IOS) || defined(ANDROID) || defined(__EMSCRIPTEN__)
Application::GetSolarMutex().acquire();
#endif
@@ -6214,7 +7449,7 @@ static void lo_runLoop(LibreOfficeKit* /*pThis*/,
Application::UpdateMainThread();
soffice_main();
}
-#if defined(IOS) || defined(ANDROID)
+#if defined(IOS) || defined(ANDROID) || defined(__EMSCRIPTEN__)
vcl::lok::unregisterPollCallbacks();
Application::ReleaseSolarMutex();
#endif
@@ -6244,6 +7479,43 @@ static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit:
}
}
+/// Used by preloadData (LibreOfficeKit) for providing different shortcuts for different languages.
+static void preLoadShortCutAccelerators()
+{
+ std::unordered_map<OUString, css::uno::Reference<com::sun::star::ui::XAcceleratorConfiguration>>& acceleratorConfs = SfxLokHelper::getAcceleratorConfs();
+ css::uno::Sequence<OUString> installedLocales(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
+ OUString actualLang = officecfg::Setup::L10N::ooLocale::get();
+
+ for (sal_Int32 i = 0; i < installedLocales.getLength(); i++)
+ {
+ // Set the UI language to current one, before creating the accelerator.
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Setup::L10N::ooLocale::set(installedLocales[i], batch);
+ batch->commit();
+
+ // Supported module names: Writer, Calc, Draw, Impress
+ static constexpr OUString supportedModuleNames[] = {
+ u"com.sun.star.text.TextDocument"_ustr,
+ u"com.sun.star.sheet.SpreadsheetDocument"_ustr,
+ u"com.sun.star.drawing.DrawingDocument"_ustr,
+ u"com.sun.star.presentation.PresentationDocument"_ustr,
+ };
+ // Create the accelerators.
+ for (const OUString& supportedModuleName : supportedModuleNames)
+ {
+ OUString key = supportedModuleName + installedLocales[i];
+ acceleratorConfs[key] = svt::AcceleratorExecute::lok_createNewAcceleratorConfiguration(::comphelper::getProcessComponentContext(), supportedModuleName);
+ }
+ }
+
+ // Set the UI language back to default one.
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Setup::L10N::ooLocale::set(actualLang, batch);
+ batch->commit();
+}
+
+void setLanguageToolConfig();
+
/// Used only by LibreOfficeKit when used by Online to pre-initialize
static void preloadData()
{
@@ -6251,10 +7523,10 @@ static void preloadData()
// Create user profile in the temp directory for loading the dictionaries
OUString sUserPath;
- rtl::Bootstrap::get("UserInstallation", sUserPath);
- utl::TempFile aTempDir(nullptr, true);
+ rtl::Bootstrap::get(u"UserInstallation"_ustr, sUserPath);
+ utl::TempFileNamed aTempDir(nullptr, true);
aTempDir.EnableKillingFile();
- rtl::Bootstrap::set("UserInstallation", aTempDir.GetURL());
+ rtl::Bootstrap::set(u"UserInstallation"_ustr, aTempDir.GetURL());
// Register the bundled extensions
desktop::Desktop::SynchronizeExtensionRepositories(true);
@@ -6262,7 +7534,20 @@ static void preloadData()
if(bAbort)
std::cerr << "CheckExtensionDependencies failed" << std::endl;
+ // inhibit forced 2nd synchronization from Main
+ ::rtl::Bootstrap::set( "DISABLE_EXTENSION_SYNCHRONIZATION", "true");
+
+ std::cerr << "Preload textencodings"; // sal_textenc
+ // Use RTL_TEXTENCODING_MS_1250 to trigger Impl_getTextEncodingData
+ // to dlopen sal_textenclo
+ (void)OUStringToOString(u"arbitrary string", RTL_TEXTENCODING_MS_1250);
+ std::cerr << "\n";
+
+ // setup LanguageTool config before spell checking init
+ setLanguageToolConfig();
+
// preload all available dictionaries
+ linguistic2::DictionaryList::create(comphelper::getProcessComponentContext());
css::uno::Reference<css::linguistic2::XLinguServiceManager> xLngSvcMgr =
css::linguistic2::LinguServiceManager::create(comphelper::getProcessComponentContext());
css::uno::Reference<linguistic2::XSpellChecker> xSpellChecker(xLngSvcMgr->getSpellChecker());
@@ -6270,11 +7555,11 @@ static void preloadData()
std::cerr << "Preloading dictionaries: ";
css::uno::Reference<linguistic2::XSupportedLocales> xSpellLocales(xSpellChecker, css::uno::UNO_QUERY_THROW);
uno::Sequence< css::lang::Locale > aLocales = xSpellLocales->getLocales();
- for (auto &it : std::as_const(aLocales))
+ for (auto& it : aLocales)
{
std::cerr << LanguageTag::convertToBcp47(it) << " ";
css::beans::PropertyValues aNone;
- xSpellChecker->isValid("forcefed", it, aNone);
+ xSpellChecker->isValid(u"forcefed"_ustr, it, aNone);
}
std::cerr << "\n";
@@ -6283,7 +7568,7 @@ static void preloadData()
// will cheaply load this missing "others" locale library. Appending an Asian locale in
// LOK_ALLOWLIST_LANGUAGES env-var also works but at the cost of loading that dictionary.
css::uno::Reference< css::i18n::XCalendar4 > xCal = css::i18n::LocaleCalendar2::create(comphelper::getProcessComponentContext());
- css::lang::Locale aAsianLocale = {"hi", "IN", ""};
+ css::lang::Locale aAsianLocale = { u"hi"_ustr, u"IN"_ustr, {} };
xCal->loadDefaultCalendar(aAsianLocale);
// preload all available thesauri
@@ -6291,27 +7576,39 @@ static void preloadData()
css::uno::Reference<linguistic2::XSupportedLocales> xThesLocales(xSpellChecker, css::uno::UNO_QUERY_THROW);
aLocales = xThesLocales->getLocales();
std::cerr << "Preloading thesauri: ";
- for (auto &it : std::as_const(aLocales))
+ for (auto& it : aLocales)
{
std::cerr << LanguageTag::convertToBcp47(it) << " ";
css::beans::PropertyValues aNone;
- xThesaurus->queryMeanings("forcefed", it, aNone);
+ xThesaurus->queryMeanings(u"forcefed"_ustr, it, aNone);
}
std::cerr << "\n";
+ std::cerr << "Preloading breakiterator: ";
+ if (aLocales.getLength())
+ {
+ css::uno::Reference< css::i18n::XBreakIterator > xBreakIterator = css::i18n::BreakIterator::create(xContext);
+ css::i18n::LineBreakUserOptions aUserOptions;
+ css::i18n::LineBreakHyphenationOptions aHyphOptions( LinguMgr::GetHyphenator(), css::uno::Sequence<beans::PropertyValue>(), 1 );
+ xBreakIterator->getLineBreak("", /*nMaxBreakPos*/0, aLocales[0], /*nMinBreakPos*/0, aHyphOptions, aUserOptions);
+ }
+
css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = css::ui::GlobalAcceleratorConfiguration::create(
comphelper::getProcessComponentContext());
xGlobalCfg->getAllKeyEvents();
std::cerr << "Preload icons\n";
ImageTree &images = ImageTree::get();
- images.getImageUrl("forcefed.png", "style", "FO_oo");
+ images.getImageUrl(u"forcefed.png"_ustr, u"style"_ustr, u"FO_oo"_ustr);
+
+ std::cerr << "Preload short cut accelerators\n";
+ preLoadShortCutAccelerators();
std::cerr << "Preload languages\n";
// force load language singleton
SvtLanguageTable::HasLanguageType(LANGUAGE_SYSTEM);
- (void)LanguageTag::isValidBcp47("foo", nullptr);
+ (void)LanguageTag::isValidBcp47(u"foo"_ustr, nullptr);
std::cerr << "Preload fonts\n";
@@ -6324,7 +7621,7 @@ static void preloadData()
aLocales = xSpell->getLocales();
}
- for (const auto& aLocale : std::as_const(aLocales))
+ for (const auto& aLocale : aLocales)
{
//TODO: Add more types and cache more aggressively. For now this initializes the fontcache.
using namespace ::com::sun::star::i18n::ScriptType;
@@ -6338,19 +7635,15 @@ static void preloadData()
}
std::cerr << "Preload config\n";
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
static SvtOptionsDialogOptions aDialogOptions;
static SvtCTLOptions aSvtCTLOptions;
- static SvtAccessibilityOptions aSvtAccessibilityOptions;
static svtools::ColorConfig aColorConfig;
static SvtMiscOptions aSvtMiscOptions;
- static SvtSlideSorterBarOptions aSvtSlideSorterBarOptions;
static SvtCommandOptions aSvtCommandOptions;
- static SvtCompatibilityOptions aSvtCompatibilityOptions;
- static SvtFilterOptions aSvtFilterOptions;
static SvtLinguConfig aSvtLinguConfig;
static SvtModuleOptions aSvtModuleOptions;
static SvtPathOptions aSvtPathOptions;
@@ -6363,12 +7656,29 @@ static void preloadData()
static MiscSettings aMiscSettings;
static HelpSettings aHelpSettings;
static AllSettings aAllSettings;
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
#pragma GCC diagnostic pop
#endif
+ static constexpr OUString preloadComponents[] = {
+ u"private:factory/swriter"_ustr,
+ u"private:factory/scalc"_ustr,
+ u"private:factory/simpress"_ustr,
+ u"private:factory/sdraw"_ustr
+ };
+ // getting the remote LibreOffice service manager
+ uno::Reference<frame::XDesktop2> xCompLoader(frame::Desktop::create(xContext));
+
+ // Preload and close each of the main components once to initialize global state
+ uno::Sequence<css::beans::PropertyValue> szEmptyArgs(0);
+ for (const auto& component : preloadComponents)
+ {
+ auto xComp = xCompLoader->loadComponentFromURL(component, "_blank", 0, szEmptyArgs);
+ xComp->dispose();
+ }
+
// Set user profile's path back to the original one
- rtl::Bootstrap::set("UserInstallation", sUserPath);
+ rtl::Bootstrap::set(u"UserInstallation"_ustr, sUserPath);
}
namespace {
@@ -6381,11 +7691,46 @@ static void activateNotebookbar(std::u16string_view rApp)
if (aAppNode.isValid())
{
- aAppNode.setNodeValue("Active", makeAny(OUString("notebookbar_online.ui")));
+ static constexpr OUString sNoteBookbarName(u"notebookbar_online.ui"_ustr);
+ aAppNode.setNodeValue(u"Active"_ustr, Any(sNoteBookbarName));
+
+ const utl::OConfigurationNode aImplsNode = aAppNode.openNode(u"Modes"_ustr);
+ const Sequence<OUString> aModeNodeNames( aImplsNode.getNodeNames() );
+
+ for (const auto& rModeNodeName : aModeNodeNames)
+ {
+ const utl::OConfigurationNode aImplNode(aImplsNode.openNode(rModeNodeName));
+ if (!aImplNode.isValid())
+ continue;
+
+ OUString aCommandArg = comphelper::getString(aImplNode.getNodeValue(u"CommandArg"_ustr));
+ if (aCommandArg == "notebookbar.ui")
+ aImplNode.setNodeValue(u"CommandArg"_ustr, Any(sNoteBookbarName));
+ }
+
aAppNode.commit();
}
}
+void setHelpRootURL()
+{
+ const char* pHelpRootURL = ::getenv("LOK_HELP_URL");
+ if (pHelpRootURL)
+ {
+ OUString aHelpRootURL = OStringToOUString(pHelpRootURL, RTL_TEXTENCODING_UTF8);
+ try
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Help::HelpRootURL::set(aHelpRootURL, batch);
+ batch->commit();
+ }
+ catch (uno::Exception const& rException)
+ {
+ SAL_WARN("lok", "Failed to set the help root URL: " << rException.Message);
+ }
+ }
+}
+
void setCertificateDir()
{
const char* pEnvVarString = ::getenv("LO_CERTIFICATE_DATABASE_PATH");
@@ -6406,6 +7751,102 @@ void setCertificateDir()
}
}
+void setDeeplConfig()
+{
+ const char* pAPIUrlString = ::getenv("DEEPL_API_URL");
+ const char* pAuthKeyString = ::getenv("DEEPL_AUTH_KEY");
+ if (pAPIUrlString && pAuthKeyString)
+ {
+ OUString aAPIUrl = OStringToOUString(pAPIUrlString, RTL_TEXTENCODING_UTF8);
+ OUString aAuthKey = OStringToOUString(pAuthKeyString, RTL_TEXTENCODING_UTF8);
+ try
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Linguistic::Translation::Deepl::ApiURL::set(aAPIUrl, batch);
+ officecfg::Office::Linguistic::Translation::Deepl::AuthKey::set(aAuthKey, batch);
+ batch->commit();
+ }
+ catch(uno::Exception const& rException)
+ {
+ SAL_WARN("lok", "Failed to set Deepl API settings: " << rException.Message);
+ }
+ }
+}
+
+void setLanguageToolConfig()
+{
+ const char* pEnabled = ::getenv("LANGUAGETOOL_ENABLED");
+ const char* pBaseUrlString = ::getenv("LANGUAGETOOL_BASEURL");
+
+ if (pEnabled && pBaseUrlString)
+ {
+ const char* pUsername = ::getenv("LANGUAGETOOL_USERNAME");
+ const char* pApikey = ::getenv("LANGUAGETOOL_APIKEY");
+ const char* pSSLVerification = ::getenv("LANGUAGETOOL_SSL_VERIFICATION");
+ const char* pRestProtocol = ::getenv("LANGUAGETOOL_RESTPROTOCOL");
+
+ OUString aEnabled = OStringToOUString(pEnabled, RTL_TEXTENCODING_UTF8);
+ if (aEnabled != "true")
+ return;
+ OUString aBaseUrl = OStringToOUString(pBaseUrlString, RTL_TEXTENCODING_UTF8);
+ try
+ {
+ using LanguageToolCfg = officecfg::Office::Linguistic::GrammarChecking::LanguageTool;
+ auto batch(comphelper::ConfigurationChanges::create());
+
+ LanguageToolCfg::BaseURL::set(aBaseUrl, batch);
+ LanguageToolCfg::IsEnabled::set(true, batch);
+ if (pSSLVerification)
+ {
+ OUString aSSLVerification = OStringToOUString(pSSLVerification, RTL_TEXTENCODING_UTF8);
+ LanguageToolCfg::SSLCertVerify::set(aSSLVerification == "true", batch);
+ }
+ if (pRestProtocol)
+ {
+ OUString aRestProtocol = OStringToOUString(pRestProtocol, RTL_TEXTENCODING_UTF8);
+ LanguageToolCfg::RestProtocol::set(aRestProtocol, batch);
+ }
+ if (pUsername && pApikey)
+ {
+ OUString aUsername = OStringToOUString(pUsername, RTL_TEXTENCODING_UTF8);
+ OUString aApiKey = OStringToOUString(pApikey, RTL_TEXTENCODING_UTF8);
+ LanguageToolCfg::Username::set(aUsername, batch);
+ LanguageToolCfg::ApiKey::set(aApiKey, batch);
+ }
+ batch->commit();
+
+ css::uno::Reference<css::linguistic2::XLinguServiceManager2> xLangSrv =
+ css::linguistic2::LinguServiceManager::create(xContext);
+ if (xLangSrv.is())
+ {
+ css::uno::Reference<css::linguistic2::XSpellChecker> xSpell = xLangSrv->getSpellChecker();
+ if (xSpell.is())
+ {
+ Sequence<OUString> aEmpty;
+ Sequence<css::lang::Locale> aLocales = xSpell->getLocales();
+
+ uno::Reference<linguistic2::XProofreader> xGC(
+ xContext->getServiceManager()->createInstanceWithContext(u"org.openoffice.lingu.LanguageToolGrammarChecker"_ustr, xContext),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<linguistic2::XSupportedLocales> xSuppLoc(xGC, uno::UNO_QUERY_THROW);
+
+ for (int itLocale = 0; itLocale < aLocales.getLength(); itLocale++)
+ {
+ // turn off spell checker if LanguageTool supports the locale already
+ if (xSuppLoc->hasLocale(aLocales[itLocale]))
+ xLangSrv->setConfiguredServices(
+ SN_SPELLCHECKER, aLocales[itLocale], aEmpty);
+ }
+ }
+ }
+ }
+ catch(uno::Exception const& rException)
+ {
+ SAL_WARN("lok", "Failed to set LanguageTool API settings: " << rException.Message);
+ }
+ }
+}
+
}
static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char* pUserProfileUrl)
@@ -6446,9 +7887,22 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
}
}
+ char* pAllowlist = ::getenv("LOK_HOST_ALLOWLIST");
+ if (pAllowlist)
+ {
+ HostFilter::setAllowedHostsRegex(pAllowlist);
+ }
+
// What stage are we at ?
if (pThis == nullptr)
+ {
eStage = PRE_INIT;
+ if (lok_preinit_2_called)
+ {
+ SAL_INFO("lok", "Create libreoffice object");
+ gImpl = new LibLibreOffice_Impl();
+ }
+ }
else if (bPreInited)
eStage = SECOND_INIT;
else
@@ -6469,8 +7923,19 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
comphelper::ProfileZone aZone("lok-init");
if (eStage == PRE_INIT)
+ {
rtl_alloc_preInit(true);
+ // Set the default timezone to the TZ envar, if set.
+ const char* tz = ::getenv("TZ");
+ SfxLokHelper::setDefaultTimezone(!!tz, tz ? OStringToOUString(tz, RTL_TEXTENCODING_UTF8)
+ : OUString());
+#ifdef UNX
+ if (urandom < 0)
+ urandom = open("/dev/urandom", O_RDONLY);
+#endif
+ }
+
if (eStage != SECOND_INIT)
comphelper::LibreOfficeKit::setActive();
@@ -6492,7 +7957,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
else
SAL_WARN("lok", "resolving <" << url << "> failed with " << +e);
}
- rtl::Bootstrap::set("UserInstallation", url);
+ rtl::Bootstrap::set(u"UserInstallation"_ustr, url);
if (eStage == SECOND_INIT)
utl::Bootstrap::reloadData();
}
@@ -6504,7 +7969,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
}
else
{
-#ifdef ANDROID
+#if defined ANDROID || defined EMSCRIPTEN
aAppPath = OUString::fromUtf8(lo_get_app_data_dir()) + "/program";
#else
// Fun conversion dance back and forth between URLs and system paths...
@@ -6577,7 +8042,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
return false;
// Force headless -- this is only for bitmap rendering.
- rtl::Bootstrap::set("SAL_USE_VCLPLUGIN", "svp");
+ rtl::Bootstrap::set(u"SAL_USE_VCLPLUGIN"_ustr, u"svp"_ustr);
// We specifically need to make sure we have the "headless"
// command arg set (various code specifically checks via
@@ -6615,12 +8080,12 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
// pre-load all component libraries.
if (!xContext.is())
- throw css::uno::DeploymentException("preInit: XComponentContext is not created");
+ throw css::uno::DeploymentException(u"preInit: XComponentContext is not created"_ustr);
css::uno::Reference< css::uno::XInterface > xService;
- xContext->getValueByName("/singletons/com.sun.star.lang.theServiceManager") >>= xService;
+ xContext->getValueByName(u"/singletons/com.sun.star.lang.theServiceManager"_ustr) >>= xService;
if (!xService.is())
- throw css::uno::DeploymentException("preInit: XMultiComponentFactory is not created");
+ throw css::uno::DeploymentException(u"preInit: XMultiComponentFactory is not created"_ustr);
css::uno::Reference<css::lang::XInitialization> aService(
xService, css::uno::UNO_QUERY_THROW);
@@ -6633,7 +8098,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
// 3) InitVCL()
{
comphelper::ProfileZone aInit("preload");
- aService->initialize({css::uno::makeAny<OUString>("preload")});
+ aService->initialize({css::uno::Any(u"preload"_ustr)});
}
{ // Force load some modules
comphelper::ProfileZone aInit("preload modules");
@@ -6647,7 +8112,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
Application::ReleaseSolarMutex();
}
- setLanguageAndLocale("en-US");
+ setLanguageAndLocale(u"en-US"_ustr);
}
if (eStage != PRE_INIT)
@@ -6657,6 +8122,14 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
OUString aNewTemp;
osl::FileBase::getTempDirURL(aNewTemp);
aOptions.SetTempPath(aNewTemp);
+ {
+ const char *pWorkPath = getenv("LOK_WORKDIR");
+ if (pWorkPath)
+ {
+ OString sWorkPath(pWorkPath);
+ aOptions.SetWorkPath(OStringToOUString(sWorkPath, RTL_TEXTENCODING_UTF8));
+ }
+ }
desktop::Desktop::CreateTemporaryDirectory();
// The RequestHandler is specifically set to be ready when all the other
@@ -6702,8 +8175,8 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
comphelper::ThreadPool::getSharedOptimalPool().shutdown();
}
-// Turn off quick editing on IOS and ANDROID
-#if defined IOS || defined ANDROID
+// Turn off quick editing on iOS, Android and Emscripten
+#if defined IOS || defined ANDROID || defined __EMSCRIPTEN__
if (officecfg::Office::Impress::Misc::TextObject::QuickEditing::get())
{
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
@@ -6712,10 +8185,21 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
}
#endif
+
+ setHelpRootURL();
setCertificateDir();
+ setDeeplConfig();
+ setLanguageToolConfig();
if (bNotebookbar)
{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::UI::ToolbarMode::ActiveWriter::set(u"notebookbar_online.ui"_ustr, batch);
+ officecfg::Office::UI::ToolbarMode::ActiveCalc::set(u"notebookbar_online.ui"_ustr, batch);
+ officecfg::Office::UI::ToolbarMode::ActiveImpress::set(u"notebookbar_online.ui"_ustr, batch);
+ officecfg::Office::UI::ToolbarMode::ActiveDraw::set(u"notebookbar_online.ui"_ustr, batch);
+ batch->commit();
+
activateNotebookbar(u"Writer");
activateNotebookbar(u"Calc");
activateNotebookbar(u"Impress");
@@ -6732,11 +8216,18 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
SAL_JNI_EXPORT
LibreOfficeKit *libreofficekit_hook_2(const char* install_path, const char* user_profile_url)
{
- if (!gImpl)
+ static bool alreadyCalled = false;
+
+ if ((!lok_preinit_2_called && !gImpl) || (lok_preinit_2_called && !alreadyCalled))
{
- SAL_INFO("lok", "Create libreoffice object");
+ alreadyCalled = true;
+
+ if (!lok_preinit_2_called)
+ {
+ SAL_INFO("lok", "Create libreoffice object");
+ gImpl = new LibLibreOffice_Impl();
+ }
- gImpl = new LibLibreOffice_Impl();
if (!lo_initialize(gImpl, install_path, user_profile_url))
{
lo_destroy(gImpl);
@@ -6757,6 +8248,16 @@ int lok_preinit(const char* install_path, const char* user_profile_url)
return lo_initialize(nullptr, install_path, user_profile_url);
}
+SAL_JNI_EXPORT
+int lok_preinit_2(const char* install_path, const char* user_profile_url, LibreOfficeKit** kit)
+{
+ lok_preinit_2_called = true;
+ int result = lo_initialize(nullptr, install_path, user_profile_url);
+ if (kit != nullptr)
+ *kit = gImpl;
+ return result;
+}
+
static void lo_destroy(LibreOfficeKit* pThis)
{
SolarMutexClearableGuard aGuard;
@@ -6792,26 +8293,6 @@ static void lo_destroy(LibreOfficeKit* pThis)
SAL_INFO("lok", "LO Destroy Done");
}
-#ifdef IOS
-
-// Used by the unmaintained LibreOfficeLight app. Once that has been retired, get rid of this, too.
-
-__attribute__((visibility("default")))
-void temporaryHackToInvokeCallbackHandlers(LibreOfficeKitDocument* pThis)
-{
- SolarMutexGuard aGuard;
- LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
-
- int nOrigViewId = doc_getView(pThis);
-
- if (nOrigViewId >= 0 && pDocument->mpCallbackFlushHandlers[nOrigViewId])
- {
- pDocument->mpCallbackFlushHandlers[nOrigViewId]->Invoke();
- }
-}
-
-#endif
-
} // extern "C"
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/lib/lokclipboard.cxx b/desktop/source/lib/lokclipboard.cxx
index b4de36c56578..f7d52ba466e2 100644
--- a/desktop/source/lib/lokclipboard.cxx
+++ b/desktop/source/lib/lokclipboard.cxx
@@ -10,9 +10,11 @@
#include "lokclipboard.hxx"
#include <unordered_map>
#include <vcl/lazydelete.hxx>
+#include <vcl/svapp.hxx>
#include <sfx2/lokhelper.hxx>
#include <sal/log.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
using namespace css;
using namespace css::uno;
@@ -75,7 +77,7 @@ LOKClipboard::LOKClipboard()
Sequence<OUString> LOKClipboard::getSupportedServiceNames_static()
{
- Sequence<OUString> aRet{ "com.sun.star.datatransfer.clipboard.SystemClipboard" };
+ Sequence<OUString> aRet{ "com.sun.star.datatransfer.clipboard.LokClipboard" };
return aRet;
}
@@ -129,8 +131,7 @@ void LOKClipboard::removeClipboardListener(
const Reference<datatransfer::clipboard::XClipboardListener>& listener)
{
osl::ClearableMutexGuard aGuard(m_aMutex);
- m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), listener),
- m_aListeners.end());
+ std::erase(m_aListeners, listener);
}
LOKTransferable::LOKTransferable(const OUString& sMimeType,
const css::uno::Sequence<sal_Int8>& aSequence)
@@ -227,4 +228,16 @@ sal_Bool SAL_CALL LOKTransferable::isDataFlavorSupported(const datatransfer::Dat
!= std::cend(m_aFlavors);
}
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+desktop_LOKClipboard_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const& /*args*/)
+{
+ SolarMutexGuard aGuard;
+
+ cppu::OWeakObject* pClipboard = LOKClipboardFactory::getClipboardForCurView().get();
+
+ pClipboard->acquire();
+ return pClipboard;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx
index 6b94ee907318..a05091cedf5e 100644
--- a/desktop/source/lib/lokinteractionhandler.cxx
+++ b/desktop/source/lib/lokinteractionhandler.cxx
@@ -22,6 +22,8 @@
#include <comphelper/processfactory.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/document/BrokenPackageRequest.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/task/XInteractionAbort.hpp>
#include <com/sun/star/task/XInteractionApprove.hpp>
#include <com/sun/star/task/XInteractionPassword2.hpp>
@@ -45,6 +47,7 @@
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/lokhelper.hxx>
#include <sfx2/viewsh.hxx>
+#include <utility>
#include <vcl/svapp.hxx>
#include <tools/json_writer.hxx>
@@ -52,12 +55,12 @@
using namespace com::sun::star;
LOKInteractionHandler::LOKInteractionHandler(
- const OString& rCommand,
+ OString command,
desktop::LibLibreOffice_Impl *const pLOKit,
desktop::LibLODocument_Impl *const pLOKDocument)
: m_pLOKit(pLOKit)
, m_pLOKDocument(pLOKDocument)
- , m_command(rCommand)
+ , m_command(std::move(command))
, m_usePassword(false)
{
assert(m_pLOKit);
@@ -119,9 +122,9 @@ void LOKInteractionHandler::postError(css::task::InteractionClassification class
std::size_t nView = SfxViewShell::Current() ? SfxLokHelper::getView() : 0;
if (m_pLOKDocument && m_pLOKDocument->mpCallbackFlushHandlers.count(nView))
- m_pLOKDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_ERROR, aJson.extractAsOString().getStr());
+ m_pLOKDocument->mpCallbackFlushHandlers[nView]->queue(LOK_CALLBACK_ERROR, aJson.finishAndGetAsOString());
else if (m_pLOKit->mpCallback)
- m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aJson.extractAsOString().getStr(), m_pLOKit->mpCallbackData);
+ m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aJson.finishAndGetAsOString().getStr(), m_pLOKit->mpCallbackData);
}
namespace {
@@ -349,6 +352,43 @@ bool LOKInteractionHandler::handleMacroConfirmationRequest(const uno::Reference<
return false;
}
+bool LOKInteractionHandler::handlePackageReparationRequest(const uno::Reference<task::XInteractionRequest>& xRequest)
+{
+ uno::Any const request(xRequest->getRequest());
+
+ document::BrokenPackageRequest aBrokenPackageRequest;
+ if (request >>= aBrokenPackageRequest)
+ {
+ auto xInteraction(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr));
+
+ if (xInteraction.is())
+ xInteraction->handleInteractionRequest(xRequest);
+
+ return true;
+ }
+ return false;
+}
+
+bool LOKInteractionHandler::handleLoadReadOnlyRequest(const uno::Reference<task::XInteractionRequest>& xRequest)
+{
+ uno::Any const request(xRequest->getRequest());
+
+ OUString aFileName;
+ beans::NamedValue aLoadReadOnlyRequest;
+ if ((request >>= aLoadReadOnlyRequest) &&
+ aLoadReadOnlyRequest.Name == "LoadReadOnlyRequest" &&
+ (aLoadReadOnlyRequest.Value >>= aFileName))
+ {
+ auto xInteraction(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr));
+
+ if (xInteraction.is())
+ xInteraction->handleInteractionRequest(xRequest);
+
+ return true;
+ }
+ return false;
+}
+
bool LOKInteractionHandler::handleFilterOptionsRequest(const uno::Reference<task::XInteractionRequest>& xRequest)
{
document::FilterOptionsRequest aFilterOptionsRequest;
@@ -388,6 +428,12 @@ sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(
if (handleMacroConfirmationRequest(xRequest))
return true;
+ if (handlePackageReparationRequest(xRequest))
+ return true;
+
+ if (handleLoadReadOnlyRequest(xRequest))
+ return true;
+
// TODO: perform more interactions 'for real' like the above
selectApproved(rContinuations);
diff --git a/desktop/source/lib/lokinteractionhandler.hxx b/desktop/source/lib/lokinteractionhandler.hxx
index 108343ec22e3..c3641db0762f 100644
--- a/desktop/source/lib/lokinteractionhandler.hxx
+++ b/desktop/source/lib/lokinteractionhandler.hxx
@@ -21,7 +21,7 @@
#include <osl/conditn.hxx>
#include <cppuhelper/implbase.hxx>
-#include <vcl/errcode.hxx>
+#include <comphelper/errcode.hxx>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
@@ -77,12 +77,15 @@ private:
static bool handleMacroConfirmationRequest(const css::uno::Reference<css::task::XInteractionRequest>& xRequest);
static bool handleFilterOptionsRequest(const ::com::sun::star::uno::Reference<::com::sun::star::task::XInteractionRequest>& Request);
+ static bool handlePackageReparationRequest(const css::uno::Reference<css::task::XInteractionRequest>& xRequest);
+
+ static bool handleLoadReadOnlyRequest(const css::uno::Reference<css::task::XInteractionRequest>& xRequest);
public:
void SetPassword(char const* pPassword);
explicit LOKInteractionHandler(
- const OString& rCommand,
+ OString command,
desktop::LibLibreOffice_Impl *,
desktop::LibLODocument_Impl *pLOKDocumt = nullptr);
diff --git a/desktop/source/migration/migration.cxx b/desktop/source/migration/migration.cxx
index 7d3b272973be..d6b52c806367 100644
--- a/desktop/source/migration/migration.cxx
+++ b/desktop/source/migration/migration.cxx
@@ -34,14 +34,16 @@
#include <unotools/bootstrap.hxx>
#include <rtl/uri.hxx>
#include <i18nlangtag/lang.h>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <tools/urlobj.hxx>
+#include <officecfg/Office/UI.hxx>
#include <osl/file.hxx>
#include <osl/security.hxx>
#include <unotools/configmgr.hxx>
#include <com/sun/star/configuration/Update.hpp>
#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/task/XJob.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
@@ -68,9 +70,9 @@ using namespace com::sun::star;
namespace desktop
{
-constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL = u"CommandURL";
-constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER = u"ItemDescriptorContainer";
-constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL = u"Label";
+constexpr OUString ITEM_DESCRIPTOR_COMMANDURL = u"CommandURL"_ustr;
+constexpr OUString ITEM_DESCRIPTOR_CONTAINER = u"ItemDescriptorContainer"_ustr;
+constexpr OUString ITEM_DESCRIPTOR_LABEL = u"Label"_ustr;
static OUString mapModuleShortNameToIdentifier(std::u16string_view sShortName)
{
@@ -188,8 +190,8 @@ bool MigrationImpl::doMigration()
copyFiles();
- static const OUStringLiteral sMenubarResourceURL(u"private:resource/menubar/menubar");
- static const OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/");
+ static constexpr OUString sMenubarResourceURL(u"private:resource/menubar/menubar"_ustr);
+ static constexpr OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/");
for (MigrationModuleInfo & i : vModulesInfo) {
OUString sModuleIdentifier = mapModuleShortNameToIdentifier(i.sModuleShortName);
if (sModuleIdentifier.isEmpty())
@@ -197,7 +199,7 @@ bool MigrationImpl::doMigration()
OUString aOldCfgDataPath = m_aInfo.userdata + "/user/config/soffice.cfg/modules/" + i.sModuleShortName;
- uno::Sequence< uno::Any > lArgs {uno::makeAny(aOldCfgDataPath), uno::makeAny(embed::ElementModes::READ)};
+ uno::Sequence< uno::Any > lArgs {uno::Any(aOldCfgDataPath), uno::Any(embed::ElementModes::READ)};
uno::Reference< uno::XComponentContext > xContext(comphelper::getProcessComponentContext());
uno::Reference< lang::XSingleServiceFactory > xStorageFactory(embed::FileSystemStorageFactory::create(xContext));
@@ -261,7 +263,7 @@ void MigrationImpl::setMigrationCompleted()
{
try {
uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
- aPropertySet->setPropertyValue("MigrationCompleted", uno::makeAny(true));
+ aPropertySet->setPropertyValue("MigrationCompleted", uno::Any(true));
uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
} catch (...) {
// fail silently
@@ -305,8 +307,8 @@ void MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigr
uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_SET_THROW);
const uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames();
- static const OUStringLiteral aVersionIdentifiers( u"VersionIdentifiers" );
- static const OUStringLiteral aPriorityIdentifier( u"Priority" );
+ static constexpr OUStringLiteral aVersionIdentifiers( u"VersionIdentifiers" );
+ static constexpr OUStringLiteral aPriorityIdentifier( u"Priority" );
for (OUString const & supportedVersion :seqSupportedVersions) {
sal_Int32 nPriority( 0 );
@@ -318,7 +320,7 @@ void MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigr
supported_migration aSupportedMigration;
aSupportedMigration.name = supportedVersion;
aSupportedMigration.nPriority = nPriority;
- for (OUString const & s : std::as_const(seqVersions))
+ for (OUString const& s : seqVersions)
aSupportedMigration.supported_versions.push_back(s.trim());
insertSorted( rAvailableMigrations, aSupportedMigration );
SAL_INFO( "desktop.migration", " available migration '" << aSupportedMigration.name << "'" );
@@ -345,31 +347,31 @@ migrations_vr MigrationImpl::readMigrationSteps(const OUString& rMigrationName)
// read included files from current step description
if (tmpAccess->getByName("IncludedFiles") >>= tmpSeq) {
- for (const OUString& rSeqEntry : std::as_const(tmpSeq))
+ for (const OUString& rSeqEntry : tmpSeq)
tmpStep.includeFiles.push_back(rSeqEntry);
}
// excluded files...
if (tmpAccess->getByName("ExcludedFiles") >>= tmpSeq) {
- for (const OUString& rSeqEntry : std::as_const(tmpSeq))
+ for (const OUString& rSeqEntry : tmpSeq)
tmpStep.excludeFiles.push_back(rSeqEntry);
}
// included nodes...
if (tmpAccess->getByName("IncludedNodes") >>= tmpSeq) {
- for (const OUString& rSeqEntry : std::as_const(tmpSeq))
+ for (const OUString& rSeqEntry : tmpSeq)
tmpStep.includeConfig.push_back(rSeqEntry);
}
// excluded nodes...
if (tmpAccess->getByName("ExcludedNodes") >>= tmpSeq) {
- for (const OUString& rSeqEntry : std::as_const(tmpSeq))
+ for (const OUString& rSeqEntry : tmpSeq)
tmpStep.excludeConfig.push_back(rSeqEntry);
}
// excluded extensions...
if (tmpAccess->getByName("ExcludedExtensions") >>= tmpSeq) {
- for (const OUString& rSeqEntry : std::as_const(tmpSeq))
+ for (const OUString& rSeqEntry : tmpSeq)
tmpStep.excludeExtensions.push_back(rSeqEntry);
}
@@ -429,7 +431,7 @@ OUString MigrationImpl::preXDGConfigDir(const OUString& rConfigDir)
void MigrationImpl::setInstallInfoIfExist(
install_info& aInfo,
- const OUString& rConfigDir,
+ std::u16string_view rConfigDir,
const OUString& rVersion)
{
OUString url(INetURLObject(rConfigDir).GetMainURL(INetURLObject::DecodeMechanism::NONE));
@@ -470,11 +472,11 @@ install_info MigrationImpl::findInstallation(const strings_v& rVersions)
( aInfo.userdata.isEmpty() ||
aProfileName.equalsIgnoreAsciiCase(
utl::ConfigManager::getProductName() ) ) ) {
- setInstallInfoIfExist(aInfo, aTopConfigDir + aProfileName, aVersion);
+ setInstallInfoIfExist(aInfo, Concat2View(aTopConfigDir + aProfileName), aVersion);
#if defined UNX && ! defined MACOSX
//try preXDG path if the new one does not exist
if ( aInfo.userdata.isEmpty())
- setInstallInfoIfExist(aInfo, aPreXDGTopConfigDir + aProfileName, aVersion);
+ setInstallInfoIfExist(aInfo, Concat2View(aPreXDGTopConfigDir + aProfileName), aVersion);
#endif
}
}
@@ -616,6 +618,55 @@ bool getComponent(OUString const & path, OUString * component)
return true;
}
+void renameMigratedSetElementTo(
+ css::uno::Reference<css::container::XNameContainer> const & set, OUString const & currentName,
+ OUString const & migratedName)
+{
+ // To avoid unexpected data loss, the code is careful to only rename from currentName to
+ // migratedName in the expected case where the currentName element exists and the migratedName
+ // element doesn't exist:
+ bool const hasCurrent = set->hasByName(currentName);
+ bool const hasMigrated = set->hasByName(migratedName);
+ if (hasCurrent && !hasMigrated) {
+ auto const elem = set->getByName(currentName);
+ set->removeByName(currentName);
+ set->insertByName(migratedName, elem);
+ } else {
+ SAL_INFO_IF(!hasCurrent, "desktop.migration", "unexpectedly missing " << currentName);
+ SAL_INFO_IF(hasMigrated, "desktop.migration", "unexpectedly present " << migratedName);
+ }
+}
+
+void renameMigratedSetElementBack(
+ css::uno::Reference<css::container::XNameContainer> const & set, OUString const & currentName,
+ OUString const & migratedName)
+{
+ // To avoid unexpected data loss, the code is careful to ensure that in the end a currentName
+ // element exists, creating it from a template if the migratedName element had unexpectedly gone
+ // missing:
+ bool const hasMigrated = set->hasByName(migratedName);
+ css::uno::Any elem;
+ if (hasMigrated) {
+ elem = set->getByName(migratedName);
+ set->removeByName(migratedName);
+ } else {
+ SAL_INFO("desktop.migration", "unexpected loss of " << migratedName);
+ elem <<= css::uno::Reference<css::lang::XSingleServiceFactory>(
+ set, css::uno::UNO_QUERY_THROW)->createInstance();
+ }
+ if (set->hasByName(currentName)) {
+ SAL_INFO("desktop.migration", "unexpected reappearance of " << currentName);
+ if (hasMigrated) {
+ SAL_INFO(
+ "desktop.migration",
+ "reappeared " << currentName << " overwritten with " << migratedName);
+ set->replaceByName(currentName, elem);
+ }
+ } else {
+ set->insertByName(currentName, elem);
+ }
+}
+
}
void MigrationImpl::copyConfig()
@@ -646,6 +697,30 @@ void MigrationImpl::copyConfig()
regFile.close();
}
+ // If the to-be-migrated data contains modifications of
+ // /org.openoffice.Office.UI/ColorScheme/ColorSchemes set elements named after the migrated
+ // product name, those modifications must instead be made to the corresponding set elements
+ // named after the current product name. However, if the current configuration data does not
+ // contain those old-named set elements at all, their modification data would silently be
+ // ignored by css.configuration.XUpdate::insertModificationXcuFile. So temporarily rename any
+ // new-named set elements to their old-named counterparts here, and rename them back again down
+ // below after importing the migrated data:
+ OUString sProductName = utl::ConfigManager::getProductName();
+ OUString sProductNameDark = sProductName + " Dark";
+ OUString sMigratedProductName = m_aInfo.productname;
+ // remove version number from the end of product name if there’s one
+ if (isdigit(sMigratedProductName[sMigratedProductName.getLength() - 1]))
+ sMigratedProductName = (sMigratedProductName.copy(0, m_aInfo.productname.getLength() - 1)).trim();
+ OUString sMigratedProductNameDark = sMigratedProductName + " Dark";
+ auto const tempRename = sMigratedProductName != sProductName;
+ if (tempRename) {
+ auto const batch = comphelper::ConfigurationChanges::create();
+ auto const schemes = officecfg::Office::UI::ColorScheme::ColorSchemes::get(batch);
+ renameMigratedSetElementTo(schemes, sProductName, sMigratedProductName);
+ renameMigratedSetElementTo(schemes, sProductNameDark, sMigratedProductNameDark);
+ batch->commit();
+ }
+
for (auto const& comp : comps)
{
if (!comp.second.includedPaths.empty()) {
@@ -653,8 +728,8 @@ void MigrationImpl::copyConfig()
// shared registrymodifications.xcu does not exists
// the configuration is split in many registry files
// determine the file names from the first element in included paths
- OUStringBuffer buf(m_aInfo.userdata);
- buf.append("/user/registry/data");
+ OUStringBuffer buf(m_aInfo.userdata
+ + "/user/registry/data");
sal_Int32 n = 0;
do {
OUString seg(comp.first.getToken(0, '.', n));
@@ -666,8 +741,7 @@ void MigrationImpl::copyConfig()
SAL_INFO( "desktop.migration", "configuration migration component " << comp.first << " ignored (cannot be encoded as file path)" );
goto next;
}
- buf.append('/');
- buf.append(enc);
+ buf.append("/" + enc);
} while (n >= 0);
buf.append(".xcu");
regFilePath = buf.makeStringAndClear();
@@ -678,12 +752,44 @@ void MigrationImpl::copyConfig()
regFilePath,
comphelper::containerToSequence(comp.second.includedPaths),
comphelper::containerToSequence(comp.second.excludedPaths));
+
} else {
SAL_INFO( "desktop.migration", "configuration migration component " << comp.first << " ignored (only excludes, no includes)" );
}
next:
;
}
+ if (tempRename) {
+ auto const batch = comphelper::ConfigurationChanges::create();
+ auto const schemes = officecfg::Office::UI::ColorScheme::ColorSchemes::get(batch);
+ renameMigratedSetElementBack(schemes, sProductName, sMigratedProductName);
+ renameMigratedSetElementBack(schemes, sProductNameDark, sMigratedProductNameDark);
+ batch->commit();
+ }
+ // checking the migrated (product name related) color scheme name, and replace it to the current version scheme name
+ try
+ {
+ OUString sMigratedColorScheme;
+ uno::Reference<XPropertySet> aPropertySet(
+ getConfigAccess("org.openoffice.Office.UI/ColorScheme", true), uno::UNO_QUERY_THROW);
+ if (aPropertySet->getPropertyValue("CurrentColorScheme") >>= sMigratedColorScheme)
+ {
+ if (sMigratedColorScheme.equals(sMigratedProductName))
+ {
+ aPropertySet->setPropertyValue("CurrentColorScheme",
+ uno::Any(sProductName));
+ uno::Reference<XChangesBatch>(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
+ }
+ else if (sMigratedColorScheme.equals(sMigratedProductNameDark))
+ {
+ aPropertySet->setPropertyValue("CurrentColorScheme",
+ uno::Any(sProductNameDark));
+ uno::Reference<XChangesBatch>(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
+ }
+ }
+ } catch (const Exception&) {
+ // fail silently...
+ }
}
uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const char* pPath, bool bUpdate)
@@ -703,7 +809,7 @@ uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const char* pPath,
comphelper::getProcessComponentContext()));
// access the provider
- uno::Sequence< uno::Any > theArgs {uno::makeAny(sConfigURL)};
+ uno::Sequence< uno::Any > theArgs {uno::Any(sConfigURL)};
xNameAccess.set(
theConfigProvider->createInstanceWithArguments(
sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW );
@@ -753,9 +859,9 @@ void MigrationImpl::runServices()
uno::Sequence< uno::Any > seqArguments(3);
auto pseqArguments = seqArguments.getArray();
pseqArguments[0] <<= NamedValue("Productname",
- uno::makeAny(m_aInfo.productname));
+ uno::Any(m_aInfo.productname));
pseqArguments[1] <<= NamedValue("UserData",
- uno::makeAny(m_aInfo.userdata));
+ uno::Any(m_aInfo.userdata));
// create an instance of every migration service
@@ -775,7 +881,7 @@ void MigrationImpl::runServices()
seqExtDenyList = comphelper::arrayToSequence< OUString >(
rMigration.excludeExtensions.data(), nSize );
pseqArguments[2] <<= NamedValue("ExtensionDenyList",
- uno::makeAny( seqExtDenyList ));
+ uno::Any( seqExtDenyList ));
xMigrationJob.set(
xContext->getServiceManager()->createInstanceWithArgumentsAndContext(rMigration.service, seqArguments, xContext),
@@ -799,11 +905,11 @@ void MigrationImpl::runServices()
std::vector< MigrationModuleInfo > MigrationImpl::detectUIChangesForAllModules() const
{
std::vector< MigrationModuleInfo > vModulesInfo;
- static const OUStringLiteral MENUBAR(u"menubar");
- static const OUStringLiteral TOOLBAR(u"toolbar");
+ static constexpr OUStringLiteral MENUBAR(u"menubar");
+ static constexpr OUStringLiteral TOOLBAR(u"toolbar");
- uno::Sequence< uno::Any > lArgs {uno::makeAny(m_aInfo.userdata + "/user/config/soffice.cfg/modules"),
- uno::makeAny(embed::ElementModes::READ)};
+ uno::Sequence< uno::Any > lArgs {uno::Any(m_aInfo.userdata + "/user/config/soffice.cfg/modules"),
+ uno::Any(embed::ElementModes::READ)};
uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
embed::FileSystemStorageFactory::create(comphelper::getProcessComponentContext()));
@@ -839,9 +945,9 @@ std::vector< MigrationModuleInfo > MigrationImpl::detectUIChangesForAllModules()
aModuleInfo.sModuleShortName = sModuleShortName;
sal_Int32 nIndex = sToolbarName.lastIndexOf('.');
if (nIndex > 0) {
- OUString sExtension(sToolbarName.copy(nIndex));
+ std::u16string_view sExtension(sToolbarName.subView(nIndex));
OUString sToolbarResourceName(sToolbarName.copy(0, nIndex));
- if (!sToolbarResourceName.isEmpty() && sExtension == ".xml")
+ if (!sToolbarResourceName.isEmpty() && sExtension == u".xml")
aModuleInfo.m_vToolbars.push_back(sToolbarResourceName);
}
}
@@ -860,7 +966,7 @@ void MigrationImpl::compareOldAndNewConfig(const OUString& sParent,
const uno::Reference< container::XIndexContainer >& xIndexNew,
const OUString& sResourceURL)
{
- static const OUStringLiteral MENU_SEPARATOR(u" | ");
+ static constexpr OUStringLiteral MENU_SEPARATOR(u" | ");
std::vector< MigrationItem > vOldItems;
std::vector< MigrationItem > vNewItems;
@@ -871,7 +977,7 @@ void MigrationImpl::compareOldAndNewConfig(const OUString& sParent,
for (int n=0; n<nOldCount; ++n) {
MigrationItem aMigrationItem;
if (xIndexOld->getByIndex(n) >>= aProps) {
- for(beans::PropertyValue const & prop : std::as_const(aProps)) {
+ for(beans::PropertyValue const & prop : aProps) {
if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
prop.Value >>= aMigrationItem.m_sCommandURL;
else if ( prop.Name == ITEM_DESCRIPTOR_CONTAINER )
@@ -886,7 +992,7 @@ void MigrationImpl::compareOldAndNewConfig(const OUString& sParent,
for (int n=0; n<nNewCount; ++n) {
MigrationItem aMigrationItem;
if (xIndexNew->getByIndex(n) >>= aProps) {
- for(beans::PropertyValue const & prop : std::as_const(aProps)) {
+ for(beans::PropertyValue const & prop : aProps) {
if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
prop.Value >>= aMigrationItem.m_sCommandURL;
else if ( prop.Name == ITEM_DESCRIPTOR_CONTAINER )
@@ -941,8 +1047,8 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat
OUString sParentNodeName = elem.m_sParentNodeName;
sal_Int32 nIndex = 0;
do {
- OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim();
- if (sToken.isEmpty())
+ std::u16string_view sToken( o3tl::trim(o3tl::getToken(sParentNodeName, 0, '|', nIndex)) );
+ if (sToken.empty())
break;
sal_Int32 nCount = xTemp->getCount();
@@ -953,7 +1059,7 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat
uno::Sequence< beans::PropertyValue > aPropSeq;
xTemp->getByIndex(i) >>= aPropSeq;
- for (beans::PropertyValue const & prop : std::as_const(aPropSeq)) {
+ for (beans::PropertyValue const & prop : aPropSeq) {
OUString sPropName = prop.Name;
if ( sPropName == ITEM_DESCRIPTOR_COMMANDURL )
prop.Value >>= sCommandURL;
@@ -974,13 +1080,13 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat
if (nIndex == -1) {
auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(elem.m_sCommandURL, sModuleIdentifier);
uno::Sequence< beans::PropertyValue > aPropSeq {
- beans::PropertyValue(ITEM_DESCRIPTOR_COMMANDURL, 0, uno::makeAny(elem.m_sCommandURL), beans::PropertyState_DIRECT_VALUE),
- beans::PropertyValue(ITEM_DESCRIPTOR_LABEL, 0, uno::makeAny(vcl::CommandInfoProvider::GetLabelForCommand(aProperties)), beans::PropertyState_DIRECT_VALUE),
- beans::PropertyValue(ITEM_DESCRIPTOR_CONTAINER, 0, uno::makeAny(elem.m_xPopupMenu), beans::PropertyState_DIRECT_VALUE)
+ beans::PropertyValue(ITEM_DESCRIPTOR_COMMANDURL, 0, uno::Any(elem.m_sCommandURL), beans::PropertyState_DIRECT_VALUE),
+ beans::PropertyValue(ITEM_DESCRIPTOR_LABEL, 0, uno::Any(vcl::CommandInfoProvider::GetLabelForCommand(aProperties)), beans::PropertyState_DIRECT_VALUE),
+ beans::PropertyValue(ITEM_DESCRIPTOR_CONTAINER, 0, uno::Any(elem.m_xPopupMenu), beans::PropertyState_DIRECT_VALUE)
};
if (elem.m_sPrevSibling.isEmpty())
- xTemp->insertByIndex(0, uno::makeAny(aPropSeq));
+ xTemp->insertByIndex(0, uno::Any(aPropSeq));
else {
sal_Int32 nCount = xTemp->getCount();
sal_Int32 i = 0;
@@ -988,7 +1094,7 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat
OUString sCmd;
uno::Sequence< beans::PropertyValue > aTempPropSeq;
xTemp->getByIndex(i) >>= aTempPropSeq;
- for (beans::PropertyValue const & prop : std::as_const(aTempPropSeq)) {
+ for (beans::PropertyValue const & prop : aTempPropSeq) {
if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL ) {
prop.Value >>= sCmd;
break;
@@ -999,7 +1105,7 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat
break;
}
- xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq));
+ xTemp->insertByIndex(i+1, uno::Any(aPropSeq));
}
}
}
@@ -1048,7 +1154,7 @@ uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSett
if (newProp.Name == sModuleShortName) {
uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq;
newProp.Value >>= lToolbarSettingsSeq;
- for (auto const & prop : std::as_const(lToolbarSettingsSeq)) {
+ for (auto const & prop : lToolbarSettingsSeq) {
if (prop.Name == sToolbarName) {
prop.Value >>= xNewToolbarSettings;
break;
@@ -1070,8 +1176,8 @@ void NewVersionUIInfo::init(const std::vector< MigrationModuleInfo >& vModulesIn
m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size());
auto p_lNewVersionToolbarSettingsSeq = m_lNewVersionToolbarSettingsSeq.getArray();
- static const OUStringLiteral sMenubarResourceURL(u"private:resource/menubar/menubar");
- static const OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/");
+ static constexpr OUStringLiteral sMenubarResourceURL(u"private:resource/menubar/menubar");
+ static constexpr OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/");
uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = ui::theModuleUIConfigurationManagerSupplier::get( ::comphelper::getProcessComponentContext() );
diff --git a/desktop/source/migration/migration_impl.hxx b/desktop/source/migration/migration_impl.hxx
index cf2d201d22e6..6b0923d292da 100644
--- a/desktop/source/migration/migration_impl.hxx
+++ b/desktop/source/migration/migration_impl.hxx
@@ -21,6 +21,7 @@
#include <memory>
#include <string_view>
#include <unordered_map>
+#include <utility>
#include <vector>
#include <o3tl/string_view.hxx>
@@ -86,12 +87,12 @@ struct MigrationItem
{
}
- MigrationItem(const OUString& sParentNodeName,
- const OUString& sPrevSibling,
- const OUString& sCommandURL,
- const css::uno::Reference< css::container::XIndexContainer > & xPopupMenu)
- : m_sParentNodeName(sParentNodeName), m_sPrevSibling(sPrevSibling),
- m_sCommandURL(sCommandURL), m_xPopupMenu(xPopupMenu)
+ MigrationItem(OUString sParentNodeName,
+ OUString sPrevSibling,
+ OUString sCommandURL,
+ css::uno::Reference< css::container::XIndexContainer > xPopupMenu)
+ : m_sParentNodeName(std::move(sParentNodeName)), m_sPrevSibling(std::move(sPrevSibling)),
+ m_sCommandURL(std::move(sCommandURL)), m_xPopupMenu(std::move(xPopupMenu))
{
}
@@ -159,7 +160,7 @@ private:
#if defined UNX && ! defined MACOSX
static OUString preXDGConfigDir(const OUString& rConfigDir);
#endif
- static void setInstallInfoIfExist(install_info& aInfo, const OUString& rConfigDir, const OUString& rVersion);
+ static void setInstallInfoIfExist(install_info& aInfo, std::u16string_view rConfigDir, const OUString& rVersion);
static install_info findInstallation(const strings_v& rVersions);
strings_vr compileFileList();
diff --git a/desktop/source/migration/services/basicmigration.cxx b/desktop/source/migration/services/basicmigration.cxx
index 8076dada5cb0..94e8677de786 100644
--- a/desktop/source/migration/services/basicmigration.cxx
+++ b/desktop/source/migration/services/basicmigration.cxx
@@ -108,7 +108,7 @@ namespace migration
TStringVectorPtr aFileList = getFiles( m_sSourceDir );
for (auto const& elem : *aFileList)
{
- OUString sLocalName = elem.copy( m_sSourceDir.getLength() );
+ std::u16string_view sLocalName = elem.subView( m_sSourceDir.getLength() );
OUString sTargetName = sTargetDir + sLocalName;
INetURLObject aURL( sTargetName );
aURL.removeSegment();
diff --git a/desktop/source/migration/services/jvmfwk.cxx b/desktop/source/migration/services/jvmfwk.cxx
index 65eff6767459..892c651f29de 100644
--- a/desktop/source/migration/services/jvmfwk.cxx
+++ b/desktop/source/migration/services/jvmfwk.cxx
@@ -40,7 +40,7 @@
#include <osl/diagnose.h>
-constexpr OUStringLiteral SERVICE_NAME = u"com.sun.star.migration.Java";
+constexpr OUString SERVICE_NAME = u"com.sun.star.migration.Java"_ustr;
#define IMPL_NAME "com.sun.star.comp.desktop.migration.Java"
#define ENABLE_JAVA 1
diff --git a/desktop/source/migration/services/oo3extensionmigration.cxx b/desktop/source/migration/services/oo3extensionmigration.cxx
index a3f9e02b6157..d8e90abe416f 100644
--- a/desktop/source/migration/services/oo3extensionmigration.cxx
+++ b/desktop/source/migration/services/oo3extensionmigration.cxx
@@ -21,7 +21,7 @@
#include "oo3extensionmigration.hxx"
#include <sal/log.hxx>
#include <osl/file.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <unotools/bootstrap.hxx>
#include <unotools/textsearch.hxx>
#include <comphelper/sequence.hxx>
@@ -30,7 +30,6 @@
#include <com/sun/star/task/XInteractionApprove.hpp>
#include <com/sun/star/ucb/CommandAbortedException.hpp>
-#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <com/sun/star/xml/xpath/XPathAPI.hpp>
#include <com/sun/star/xml/xpath/XPathException.hpp>
diff --git a/desktop/source/migration/services/wordbookmigration.cxx b/desktop/source/migration/services/wordbookmigration.cxx
index 83f687703e9f..a3fff8823925 100644
--- a/desktop/source/migration/services/wordbookmigration.cxx
+++ b/desktop/source/migration/services/wordbookmigration.cxx
@@ -138,7 +138,7 @@ static bool IsUserWordbook( const OUString& rFile )
{
if (IsUserWordbook(elem) )
{
- OUString sSourceLocalName = elem.copy( m_sSourceDir.getLength() );
+ std::u16string_view sSourceLocalName = elem.subView( m_sSourceDir.getLength() );
OUString sTargetName = sTargetDir + sSourceLocalName;
INetURLObject aURL( sTargetName );
aURL.removeSegment();
diff --git a/desktop/source/minidump/minidump.cxx b/desktop/source/minidump/minidump.cxx
index d61922cdaac6..90d23f51acf3 100644
--- a/desktop/source/minidump/minidump.cxx
+++ b/desktop/source/minidump/minidump.cxx
@@ -8,6 +8,7 @@
*/
#include <desktop/minidump.hxx>
+#include <sal/log.hxx>
#include <map>
#include <fstream>
@@ -16,6 +17,8 @@
#include <curl/curl.h>
+#include <systools/curlinit.hxx>
+
#ifdef _WIN32
#include <memory>
#include <windows.h>
@@ -94,6 +97,8 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s
if (!curl)
return false;
+ ::InitCurl_easy(curl);
+
std::string proxy, proxy_user_pwd, ca_certificate_file, file, url, version;
getProperty("Proxy", proxy, parameters);
@@ -131,27 +136,21 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s
if (!ca_certificate_file.empty())
curl_easy_setopt(curl, CURLOPT_CAINFO, ca_certificate_file.c_str());
- curl_httppost* formpost = nullptr;
- curl_httppost* lastptr = nullptr;
+ curl_mime* mime = curl_mime_init(curl);
std::string additional_data = generate_json(parameters);
- curl_formadd(&formpost, &lastptr,
- CURLFORM_COPYNAME, "AdditionalData",
- CURLFORM_COPYCONTENTS, additional_data.c_str(),
- CURLFORM_END);
+ curl_mimepart* part = curl_mime_addpart(mime);
+ curl_mime_name(part, "AdditionalData");
+ curl_mime_data(part, additional_data.c_str(), CURL_ZERO_TERMINATED);
- curl_formadd(&formpost, &lastptr,
- CURLFORM_COPYNAME, "Version",
- CURLFORM_COPYCONTENTS, version.c_str(),
- CURLFORM_END);
+ part = curl_mime_addpart(mime);
+ curl_mime_name(part, "Version");
+ curl_mime_data(part, version.c_str(), CURL_ZERO_TERMINATED);
- std::string response_body;
- long response_code;
- curl_formadd(&formpost, &lastptr,
- CURLFORM_COPYNAME, "upload_file_minidump",
- CURLFORM_FILE, file.c_str(),
- CURLFORM_END);
+ part = curl_mime_addpart(mime);
+ curl_mime_name(part, "upload_file_minidump");
+ curl_mime_filedata(part, file.c_str());
- curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+ curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
// Disable 100-continue header.
@@ -161,6 +160,7 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
+ std::string response_body;
curl_easy_setopt(curl, CURLOPT_WRITEDATA,
static_cast<void *>(&response_body));
@@ -168,18 +168,14 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
CURLcode cc = curl_easy_perform(curl);
+ long response_code;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
-#ifndef NDEBUG
- if (cc != CURLE_OK)
- fprintf(stderr, "Failed to send http request to %s, error: %s\n",
- url.c_str(),
- curl_easy_strerror(cc));
-#endif
+ SAL_WARN_IF(cc != CURLE_OK, "desktop",
+ "Failed to send http request to " <<
+ url.c_str() <<
+ ", error: " <<
+ curl_easy_strerror(cc));
- if (formpost != nullptr)
- {
- curl_formfree(formpost);
- }
if (headerlist != nullptr)
{
curl_slist_free_all(headerlist);
@@ -188,7 +184,13 @@ static bool uploadContent(std::map<std::string, std::string>& parameters, std::s
response = response_body;
if( CURLE_OK != cc )
+ {
+ if (response.empty())
+ {
+ response = curl_easy_strerror(cc);
+ }
return false;
+ }
return true;
}
diff --git a/desktop/source/offacc/acceptor.cxx b/desktop/source/offacc/acceptor.cxx
index 7697c18b422f..9598466d9c5b 100644
--- a/desktop/source/offacc/acceptor.cxx
+++ b/desktop/source/offacc/acceptor.cxx
@@ -23,9 +23,11 @@
#include <com/sun/star/bridge/BridgeFactory.hpp>
#include <com/sun/star/connection/Acceptor.hpp>
#include <com/sun/star/uno/XNamingService.hpp>
+#include <officecfg/Office/Security.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <sal/log.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
+#include <o3tl/string_view.hxx>
using namespace css::bridge;
using namespace css::connection;
@@ -62,7 +64,7 @@ Acceptor::~Acceptor()
m_rAcceptor->stopAccepting();
oslThread t;
{
- osl::MutexGuard g(m_aMutex);
+ std::unique_lock g(m_aMutex);
t = m_thread;
}
//prevent locking if the thread is still waiting
@@ -74,7 +76,7 @@ Acceptor::~Acceptor()
// Make the final state of m_bridges visible to this thread (since
// m_thread is joined, the code that follows is the only one left
// accessing m_bridges):
- osl::MutexGuard g(m_aMutex);
+ std::unique_lock g(m_aMutex);
}
for (;;) {
css::uno::Reference< css::bridge::XBridge > b(m_bridges.remove());
@@ -117,7 +119,7 @@ void Acceptor::run()
// the bridge, it will be destructed.
Reference< XBridge > rBridge = m_rBridgeFactory->createBridge(
"", m_aProtocol, rConnection, rInstanceProvider);
- osl::MutexGuard g(m_aMutex);
+ std::unique_lock g(m_aMutex);
m_bridges.add(rBridge);
} catch (const Exception&) {
TOOLS_WARN_EXCEPTION("desktop.offacc", "");
@@ -132,7 +134,7 @@ void Acceptor::run()
void Acceptor::initialize( const Sequence<Any>& aArguments )
{
// prevent multiple initialization
- osl::MutexGuard aGuard( m_aMutex );
+ std::unique_lock aGuard( m_aMutex );
SAL_INFO( "desktop.offacc", "Acceptor::initialize()" );
bool bOk = false;
@@ -151,7 +153,7 @@ void Acceptor::initialize( const Sequence<Any>& aArguments )
if (nIndex1 < 0)
throw IllegalArgumentException(
"Invalid accept-string format", m_rContext, 1);
- m_aConnectString = m_aAcceptString.copy( 0 , nIndex1 ).trim();
+ m_aConnectString = o3tl::trim(m_aAcceptString.subView( 0 , nIndex1 ));
nIndex1++;
sal_Int32 nIndex2 = m_aAcceptString.indexOf( ';' , nIndex1 );
if (nIndex2 < 0) nIndex2 = m_aAcceptString.getLength();
@@ -239,6 +241,12 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
desktop_Acceptor_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
+ if (!officecfg::Office::Security::Net::AllowInsecureUNORemoteProtocol::get())
+ {
+ // this is not allowed to throw
+ SAL_WARN("desktop", "UNO Remote Protocol is disabled by configuration");
+ return nullptr;
+ }
return cppu::acquire(new desktop::Acceptor(context));
}
diff --git a/desktop/source/offacc/acceptor.hxx b/desktop/source/offacc/acceptor.hxx
index 36b3e181cc93..9e210459a544 100644
--- a/desktop/source/offacc/acceptor.hxx
+++ b/desktop/source/offacc/acceptor.hxx
@@ -30,10 +30,11 @@
#include <cppuhelper/implbase.hxx>
#include <comphelper/weakbag.hxx>
-#include <osl/mutex.hxx>
#include <osl/conditn.hxx>
#include <osl/thread.hxx>
+#include <mutex>
+
namespace com::sun::star::uno { class XComponentContext; }
namespace desktop {
@@ -42,7 +43,7 @@ class Acceptor
: public ::cppu::WeakImplHelper<css::lang::XServiceInfo, css::lang::XInitialization>
{
private:
- osl::Mutex m_aMutex;
+ std::mutex m_aMutex;
oslThread m_thread;
comphelper::WeakBag< css::bridge::XBridge > m_bridges;
diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
index a28b94b5888d..0ecb328b7c69 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_app.cxx
+++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx
@@ -24,6 +24,8 @@
#include <dp_identifier.hxx>
#include <tools/extendapplicationenvironment.hxx>
#include <rtl/bootstrap.hxx>
+#include <rtl/textenc.h>
+#include <rtl/ustring.hxx>
#include <osl/process.h>
#include <osl/conditn.hxx>
#include <unotools/tempfile.hxx>
@@ -48,6 +50,8 @@
#if defined(UNX)
#include <unistd.h>
#endif
+#include <iostream>
+#include <utility>
#include <vector>
@@ -61,7 +65,7 @@ namespace {
struct ExtensionName
{
OUString m_str;
- explicit ExtensionName( OUString const & str ) : m_str( str ) {}
+ explicit ExtensionName( OUString str ) : m_str(std::move( str )) {}
bool operator () ( Reference<deployment::XPackage> const & e ) const
{
return m_str == dp_misc::getIdentifier(e)
@@ -88,7 +92,7 @@ u"\n"
" remove remove extensions by identifier\n"
" reinstall expert feature: reinstall all deployed extensions\n"
" list list information about deployed extensions\n"
-" gui raise Extension Manager Graphical User Interface (GUI)\n"
+" gui raise Extensions dialog\n"
"\n"
"options:\n"
" -h, --help this help\n"
@@ -106,8 +110,8 @@ u"\n"
" --deployment-context expert feature: explicit deployment context\n"
" <context>\n"
"\n"
-"To learn more about the Extension Manager and extensions, see:\n"
-"http://wiki.openoffice.org/wiki/Documentation/DevGuide/Extensions/Extensions\n\n";
+"To learn more about extensions, see:\n"
+"https://wiki.documentfoundation.org/Documentation/DevGuide/Extensions\n\n";
const OptionInfo s_option_infos [] = {
@@ -124,6 +128,21 @@ const OptionInfo s_option_infos [] = {
{ nullptr, 0, '\0', false }
};
+void logFatal(
+ comphelper::EventLogger const * logger, sal_Int32 level, OUString const & message,
+ OUString const & argument)
+{
+ if (logger == nullptr) {
+ // Best effort; potentially loses data due to conversion failures (stray surrogate halves)
+ // and embedded null characters:
+ std::cerr
+ << OUStringToOString(message.replaceFirst("$1$", argument), RTL_TEXTENCODING_UTF8)
+ << '\n';
+ } else {
+ logger->log(level, message, argument);
+ }
+}
+
class DialogClosedListenerImpl :
public ::cppu::WeakImplHelper< ui::dialogs::XDialogClosedListener >
{
@@ -197,7 +216,7 @@ extern "C" int unopkg_main()
Reference<XLogHandler> xFileHandler;
Reference<XLogHandler> xConsoleHandler;
std::unique_ptr<comphelper::EventLogger> logger;
- std::unique_ptr<utl::TempFile> pUserProfileTempDir;
+ std::unique_ptr<utl::TempFileNamed> pUserProfileTempDir;
OptionInfo const * info_shared = getOptionInfo(
s_option_infos, "shared" );
@@ -271,7 +290,7 @@ extern "C" int unopkg_main()
if (cmdArg[ 0 ] == '-')
{
// is option:
- dp_misc::writeConsoleError(OUStringConcatenation(
+ dp_misc::writeConsoleError(Concat2View(
"\nERROR: unexpected option " +
cmdArg +
"!\n Use " APP_NAME " " +
@@ -295,7 +314,7 @@ extern "C" int unopkg_main()
// tdf#129917 Use temp user profile when installing shared extensions
if (option_shared)
{
- pUserProfileTempDir.reset(new utl::TempFile(nullptr, true));
+ pUserProfileTempDir.reset(new utl::TempFileNamed(nullptr, true));
pUserProfileTempDir->EnableKillingFile();
}
@@ -406,7 +425,7 @@ extern "C" int unopkg_main()
{
beans::NamedValue nvSuppress(
"SUPPRESS_LICENSE", option_suppressLicense ?
- makeAny(OUString("1")):makeAny(OUString("0")));
+ Any(OUString("1")):Any(OUString("0")));
xExtensionManager->addExtension(
cmdPackage, Sequence<beans::NamedValue>(&nvSuppress, 1),
repository, Reference<task::XAbortChannel>(), xCmdEnv);
@@ -478,7 +497,7 @@ extern "C" int unopkg_main()
vec_packages.size(), false);
dp_misc::writeConsole(
- OUStringConcatenation("All deployed " + repository + " extensions:\n\n"));
+ Concat2View("All deployed " + repository + " extensions:\n\n"));
}
else
{
@@ -597,32 +616,33 @@ extern "C" int unopkg_main()
}
catch (const ucb::CommandFailedException &e)
{
- logger->log(LogLevel::SEVERE, "Exception occurred: $1$", e.Message);
+ logFatal(logger.get(), LogLevel::SEVERE, "Exception occurred: $1$", e.Message);
}
catch (const ucb::CommandAbortedException &)
{
- logger->log(LogLevel::SEVERE, "$1$ aborted.", APP_NAME);
+ logFatal(logger.get(), LogLevel::SEVERE, "$1$ aborted.", APP_NAME);
bShowFailedMsg = false;
}
catch (const deployment::DeploymentException & exc)
{
- logger->log(LogLevel::SEVERE, "Exception occurred: $1$", exc.Message);
- logger->log(LogLevel::INFO, " Cause: $1$", comphelper::anyToString(exc.Cause));
+ logFatal(logger.get(), LogLevel::SEVERE, "Exception occurred: $1$", exc.Message);
+ logFatal(
+ logger.get(), LogLevel::INFO, " Cause: $1$", comphelper::anyToString(exc.Cause));
}
catch (const LockFileException & e)
{
// No logger since it requires UNO which we don't have here
- dp_misc::writeConsoleError(OUStringConcatenation(e.Message + "\n"));
+ dp_misc::writeConsoleError(Concat2View(e.Message + "\n"));
bShowFailedMsg = false;
}
catch (const css::uno::Exception & e ) {
Any exc( ::cppu::getCaughtException() );
- logger->log(LogLevel::SEVERE, "Exception occurred: $1$", e.Message);
- logger->log(LogLevel::INFO, " Cause: $1$", comphelper::anyToString(exc));
+ logFatal(logger.get(), LogLevel::SEVERE, "Exception occurred: $1$", e.Message);
+ logFatal(logger.get(), LogLevel::INFO, " Cause: $1$", comphelper::anyToString(exc));
}
if (bShowFailedMsg)
- logger->log(LogLevel::SEVERE, "$1$ failed.", APP_NAME);
+ logFatal(logger.get(), LogLevel::SEVERE, "$1$ failed.", APP_NAME);
dp_misc::disposeBridges(xLocalComponentContext);
if (xLocalComponentContext.is()) {
css::uno::Reference<css::lang::XComponent>(
diff --git a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
index cca5b7ae3365..581922a3c365 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
+++ b/desktop/source/pkgchk/unopkg/unopkg_cmdenv.cxx
@@ -29,7 +29,7 @@
#include <rtl/ustrbuf.hxx>
#include <cppuhelper/implbase.hxx>
#include <comphelper/anytostring.hxx>
-#include <tools/diagnose_ex.h>
+#include <comphelper/diagnose_ex.hxx>
#include <unotools/configmgr.hxx>
#include <com/sun/star/lang/WrappedTargetException.hpp>
#include <com/sun/star/task/XInteractionAbort.hpp>
@@ -142,9 +142,9 @@ void CommandEnvironmentImpl::printLicense(
OUString sNewLine("\n");
- dp_misc::writeConsole(OUStringConcatenation(sNewLine + sNewLine + s1 + sNewLine + sNewLine));
- dp_misc::writeConsole(OUStringConcatenation(sLicense + sNewLine + sNewLine));
- dp_misc::writeConsole(OUStringConcatenation(s2 + sNewLine));
+ dp_misc::writeConsole(Concat2View(sNewLine + sNewLine + s1 + sNewLine + sNewLine));
+ dp_misc::writeConsole(Concat2View(sLicense + sNewLine + sNewLine));
+ dp_misc::writeConsole(Concat2View(s2 + sNewLine));
dp_misc::writeConsole(s3);
//the user may enter "yes" or "no", we compare in a case insensitive way
@@ -171,7 +171,7 @@ void CommandEnvironmentImpl::printLicense(
}
else
{
- dp_misc::writeConsole(OUStringConcatenation(sNewLine + sNewLine + s4 + sNewLine));
+ dp_misc::writeConsole(Concat2View(sNewLine + sNewLine + s4 + sNewLine));
}
}
while(true);
@@ -257,7 +257,7 @@ void CommandEnvironmentImpl::handle(
{
OUString sMsg(DpResId(RID_STR_UNSUPPORTED_PLATFORM));
sMsg = sMsg.replaceAll("%Name", platExc.package->getDisplayName());
- dp_misc::writeConsole(OUStringConcatenation("\n" + sMsg + "\n\n"));
+ dp_misc::writeConsole(Concat2View("\n" + sMsg + "\n\n"));
approve = true;
}
else {
@@ -275,7 +275,7 @@ void CommandEnvironmentImpl::handle(
if (abort && m_option_verbose)
{
OUString msg = ::comphelper::anyToString(request);
- dp_misc::writeConsoleError(OUStringConcatenation("\nERROR: " + msg + "\n"));
+ dp_misc::writeConsoleError(Concat2View("\nERROR: " + msg + "\n"));
}
// select:
@@ -324,13 +324,10 @@ void CommandEnvironmentImpl::update_( Any const & Status )
return;
}
else {
- OUStringBuffer buf;
- buf.append( "WARNING: " );
+ OUStringBuffer buf( "WARNING: " );
deployment::DeploymentException dp_exc;
if (Status >>= dp_exc) {
- buf.append( dp_exc.Message );
- buf.append( ", Cause: " );
- buf.append( ::comphelper::anyToString(dp_exc.Cause) );
+ buf.append( dp_exc.Message + ", Cause: " + ::comphelper::anyToString(dp_exc.Cause) );
}
else {
buf.append( ::comphelper::anyToString(Status) );
@@ -348,9 +345,9 @@ void CommandEnvironmentImpl::update_( Any const & Status )
}
if (bUseErr)
- dp_misc::writeConsoleError(OUStringConcatenation(msg + "\n"));
+ dp_misc::writeConsoleError(Concat2View(msg + "\n"));
else
- dp_misc::writeConsole(OUStringConcatenation(msg + "\n"));
+ dp_misc::writeConsole(Concat2View(msg + "\n"));
}
diff --git a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
index 402833aa5019..ba49544f0fec 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
+++ b/desktop/source/pkgchk/unopkg/unopkg_misc.cxx
@@ -55,14 +55,11 @@ namespace unopkg {
OUString toString( OptionInfo const * info )
{
assert(info != nullptr);
- OUStringBuffer buf;
- buf.append("--");
+ OUStringBuffer buf("--");
buf.appendAscii(info->m_name);
if (info->m_short_option != '\0')
{
- buf.append(" (short -" );
- buf.append(info->m_short_option );
- buf.append(")");
+ buf.append(" (short -" + OUStringChar(info->m_short_option) + ")");
}
if (info->m_has_argument)
buf.append(" <argument>" );
@@ -229,7 +226,7 @@ void printf_line(
std::u16string_view name, std::u16string_view value, sal_Int32 level )
{
printf_space( level );
- dp_misc::writeConsole(OUStringConcatenation(OUString::Concat(name) + ": " + value + "\n"));
+ dp_misc::writeConsole(Concat2View(OUString::Concat(name) + ": " + value + "\n"));
}
@@ -352,14 +349,13 @@ Reference<XComponentContext> connectToOffice(
bool verbose )
{
OUString pipeId( ::dp_misc::generateRandomPipeId() );
- OUString acceptArg = "--accept=pipe,name=" + pipeId + ";urp;";
- Sequence<OUString> args { "--nologo", "--nodefault", acceptArg };
+ Sequence<OUString> args { "--nologo", "--nodefault", "--accept=pipe,name=" + pipeId + ";urp;" };
OUString appURL( getExecutableDir() + "/soffice" );
if (verbose)
{
- dp_misc::writeConsole(OUStringConcatenation(
+ dp_misc::writeConsole(Concat2View(
"Raising process: " + appURL +
"\nArguments: --nologo --nodefault " + args[2] +
"\n"));
diff --git a/desktop/source/pkgchk/unopkg/unopkg_shared.h b/desktop/source/pkgchk/unopkg/unopkg_shared.h
index 9db42e908619..21d0f6a92856 100644
--- a/desktop/source/pkgchk/unopkg/unopkg_shared.h
+++ b/desktop/source/pkgchk/unopkg/unopkg_shared.h
@@ -23,6 +23,7 @@
#include <osl/diagnose.h>
#include <rtl/ustring.hxx>
+#include <utility>
#include <vector>
#define APP_NAME "unopkg"
@@ -39,8 +40,8 @@ struct OptionInfo
struct LockFileException
{
- explicit LockFileException(OUString const & sMessage) :
- Message(sMessage) {}
+ explicit LockFileException(OUString sMessage) :
+ Message(std::move(sMessage)) {}
OUString Message;
};
diff --git a/desktop/source/splash/splash.cxx b/desktop/source/splash/splash.cxx
index 2389e14f4d11..01a2ed3f0bf8 100644
--- a/desktop/source/splash/splash.cxx
+++ b/desktop/source/splash/splash.cxx
@@ -29,10 +29,12 @@
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <rtl/bootstrap.hxx>
-#include <rtl/strbuf.hxx>
#include <rtl/math.hxx>
#include <vcl/introwin.hxx>
#include <vcl/virdev.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <mutex>
#define NOT_LOADED (tools::Long(-1))
#define NOT_LOADED_COLOR (Color(ColorTransparency, 0xffffffff))
@@ -73,8 +75,6 @@ private:
void SetScreenBitmap(BitmapEx &rBitmap);
static void determineProgressRatioValues( double& rXRelPos, double& rYRelPos, double& rRelWidth, double& rRelHeight );
- static osl::Mutex _aMutex;
-
BitmapEx _aIntroBmp;
Color _cProgressFrameColor;
Color _cProgressBarColor;
@@ -243,7 +243,8 @@ void SAL_CALL SplashScreen::setValue(sal_Int32 nValue)
void SAL_CALL
SplashScreen::initialize( const css::uno::Sequence< css::uno::Any>& aArguments )
{
- osl::MutexGuard aGuard( _aMutex );
+ static std::mutex aMutex;
+ std::lock_guard aGuard( aMutex );
if (!aArguments.hasElements())
return;
@@ -367,16 +368,16 @@ void SplashScreen::loadConfig()
{
sal_uInt8 nRed = 0;
sal_Int32 idx = 0;
- sal_Int32 temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
+ sal_Int32 temp = o3tl::toInt32(o3tl::getToken(sProgressFrameColor, 0, ',', idx ));
if ( idx != -1 )
{
nRed = static_cast< sal_uInt8 >( temp );
- temp = sProgressFrameColor.getToken( 0, ',', idx ).toInt32();
+ temp = o3tl::toInt32(o3tl::getToken(sProgressFrameColor, 0, ',', idx ));
}
if ( idx != -1 )
{
sal_uInt8 nGreen = static_cast< sal_uInt8 >( temp );
- sal_uInt8 nBlue = static_cast< sal_uInt8 >( sProgressFrameColor.getToken( 0, ',', idx ).toInt32() );
+ sal_uInt8 nBlue = static_cast< sal_uInt8 >( o3tl::toInt32(o3tl::getToken(sProgressFrameColor, 0, ',', idx )) );
_cProgressFrameColor = Color( nRed, nGreen, nBlue );
}
}
@@ -385,16 +386,16 @@ void SplashScreen::loadConfig()
{
sal_uInt8 nRed = 0;
sal_Int32 idx = 0;
- sal_Int32 temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
+ sal_Int32 temp = o3tl::toInt32(o3tl::getToken(sProgressBarColor, 0, ',', idx ));
if ( idx != -1 )
{
nRed = static_cast< sal_uInt8 >( temp );
- temp = sProgressBarColor.getToken( 0, ',', idx ).toInt32();
+ temp = o3tl::toInt32(o3tl::getToken(sProgressBarColor, 0, ',', idx ));
}
if ( idx != -1 )
{
sal_uInt8 nGreen = static_cast< sal_uInt8 >( temp );
- sal_uInt8 nBlue = static_cast< sal_uInt8 >( sProgressBarColor.getToken( 0, ',', idx ).toInt32() );
+ sal_uInt8 nBlue = static_cast< sal_uInt8 >( o3tl::toInt32(o3tl::getToken(sProgressBarColor, 0, ',', idx )) );
_cProgressBarColor = Color( nRed, nGreen, nBlue );
}
}
@@ -403,16 +404,16 @@ void SplashScreen::loadConfig()
{
sal_uInt8 nRed = 0;
sal_Int32 idx = 0;
- sal_Int32 temp = sProgressTextColor.getToken( 0, ',', idx ).toInt32();
+ sal_Int32 temp = o3tl::toInt32(o3tl::getToken(sProgressTextColor, 0, ',', idx ));
if ( idx != -1 )
{
nRed = static_cast< sal_uInt8 >( temp );
- temp = sProgressTextColor.getToken( 0, ',', idx ).toInt32();
+ temp = o3tl::toInt32(o3tl::getToken(sProgressTextColor, 0, ',', idx ));
}
if ( idx != -1 )
{
sal_uInt8 nGreen = static_cast< sal_uInt8 >( temp );
- sal_uInt8 nBlue = static_cast< sal_uInt8 >( sProgressTextColor.getToken( 0, ',', idx ).toInt32() );
+ sal_uInt8 nBlue = static_cast< sal_uInt8 >( o3tl::toInt32(o3tl::getToken(sProgressTextColor, 0, ',', idx )) );
_cProgressTextColor = Color( nRed, nGreen, nBlue );
}
}
@@ -430,11 +431,11 @@ void SplashScreen::loadConfig()
if ( !sSize.isEmpty() )
{
sal_Int32 idx = 0;
- sal_Int32 temp = sSize.getToken( 0, ',', idx ).toInt32();
+ sal_Int32 temp = o3tl::toInt32(o3tl::getToken(sSize, 0, ',', idx ));
if ( idx != -1 )
{
_barwidth = temp;
- _barheight = sSize.getToken( 0, ',', idx ).toInt32();
+ _barheight = o3tl::toInt32(o3tl::getToken(sSize, 0, ',', idx ));
}
}
@@ -444,11 +445,11 @@ void SplashScreen::loadConfig()
if ( !sPosition.isEmpty() )
{
sal_Int32 idx = 0;
- sal_Int32 temp = sPosition.getToken( 0, ',', idx ).toInt32();
+ sal_Int32 temp = o3tl::toInt32(o3tl::getToken(sPosition, 0, ',', idx ));
if ( idx != -1 )
{
_tlx = temp;
- _tly = sPosition.getToken( 0, ',', idx ).toInt32();
+ _tly = o3tl::toInt32(o3tl::getToken(sPosition, 0, ',', idx ));
}
}
}
@@ -463,31 +464,21 @@ void SplashScreen::SetScreenBitmap(BitmapEx &rBitmap)
if ( nCount > 0 )
{
// retrieve size from first screen
- tools::Rectangle aScreenArea = Application::GetScreenPosSizePixel(static_cast<unsigned int>(0));
+ AbsoluteScreenPixelRectangle aScreenArea = Application::GetScreenPosSizePixel(static_cast<unsigned int>(0));
nWidth = aScreenArea.GetWidth();
nHeight = aScreenArea.GetHeight();
}
// create file name from screen resolution information
- OStringBuffer aStrBuf( 128 );
- aStrBuf.append( "intro_" );
+ OUString aResBuf = "_" + OUString::number(nWidth) + "x" + OUString::number(nHeight);
if ( !_sAppName.isEmpty() )
- {
- aStrBuf.append( OUStringToOString(_sAppName, RTL_TEXTENCODING_UTF8) );
- aStrBuf.append( "_" );
- }
- OString aResBuf = OString::number( nWidth ) + "x" + OString::number( nHeight );
-
- aStrBuf.append( aResBuf.getStr() );
- if (Application::LoadBrandBitmap (aStrBuf.makeStringAndClear().getStr(), rBitmap))
- return;
+ if (Application::LoadBrandBitmap(Concat2View("intro_" + _sAppName + aResBuf), rBitmap))
+ return;
- aStrBuf.append( "intro_" );
- aStrBuf.append( aResBuf.getStr() );
- if (Application::LoadBrandBitmap (aResBuf.getStr(), rBitmap))
+ if (Application::LoadBrandBitmap(Concat2View("intro" + aResBuf), rBitmap))
return;
- (void)Application::LoadBrandBitmap ("intro", rBitmap);
+ (void)Application::LoadBrandBitmap (u"intro", rBitmap);
}
void SplashScreen::determineProgressRatioValues(
@@ -501,7 +492,7 @@ void SplashScreen::determineProgressRatioValues(
if ( nCount > 0 )
{
// retrieve size from first screen
- tools::Rectangle aScreenArea = Application::GetScreenPosSizePixel(static_cast<unsigned int>(0));
+ AbsoluteScreenPixelRectangle aScreenArea = Application::GetScreenPosSizePixel(static_cast<unsigned int>(0));
sal_Int32 nWidth = aScreenArea.GetWidth();
sal_Int32 nHeight = aScreenArea.GetHeight();
nScreenRatio = nHeight ? sal_Int32( rtl::math::round( double( nWidth ) / double( nHeight ), 2 ) * 100 ) : 0;
@@ -534,22 +525,22 @@ void SplashScreen::determineProgressRatioValues(
if ( !sFullScreenProgressPos.isEmpty() )
{
sal_Int32 idx = 0;
- double temp = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
+ double temp = o3tl::toDouble(o3tl::getToken(sFullScreenProgressPos, 0, ',', idx ));
if ( idx != -1 )
{
rXRelPos = temp;
- rYRelPos = sFullScreenProgressPos.getToken( 0, ',', idx ).toDouble();
+ rYRelPos = o3tl::toDouble(o3tl::getToken(sFullScreenProgressPos, 0, ',', idx ));
}
}
if ( !sFullScreenProgressSize.isEmpty() )
{
sal_Int32 idx = 0;
- double temp = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
+ double temp = o3tl::toDouble(o3tl::getToken(sFullScreenProgressSize, 0, ',', idx ));
if ( idx != -1 )
{
rRelWidth = temp;
- rRelHeight = sFullScreenProgressSize.getToken( 0, ',', idx ).toDouble();
+ rRelHeight = o3tl::toDouble(o3tl::getToken(sFullScreenProgressSize, 0, ',', idx ));
}
}
}
@@ -616,10 +607,6 @@ void SplashScreenWindow::Paint(vcl::RenderContext& rRenderContext, const tools::
rRenderContext.DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev->GetOutputSizePixel(), *_vdev);
}
-
-// get service instance...
-osl::Mutex SplashScreen::_aMutex;
-
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
diff --git a/desktop/test/deployment/active/active_python.py b/desktop/test/deployment/active/active_python.py
index 7f6e5bbd44c4..1d6a32749a80 100644
--- a/desktop/test/deployment/active/active_python.py
+++ b/desktop/test/deployment/active/active_python.py
@@ -16,10 +16,8 @@
# the License at http://www.apache.org/licenses/LICENSE-2.0 .
#
-import uno
import unohelper
-from com.sun.star.awt import Rectangle
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
from com.sun.star.awt.MessageBoxType import INFOBOX
from com.sun.star.frame import XDispatch, XDispatchProvider
diff --git a/desktop/test/deployment/crashextension/Addons.xcu b/desktop/test/deployment/crashextension/Addons.xcu
new file mode 100644
index 000000000000..019a068e72aa
--- /dev/null
+++ b/desktop/test/deployment/crashextension/Addons.xcu
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+
+<o:items xmlns:o="http://openoffice.org/2001/registry">
+ <item o:path="/org.openoffice.Office.Addons">
+ <node o:name="AddonUI">
+ <node o:name="Images">
+ <node o:name="org.libreoffice.test.desktop.deployment.crashextension.imageCrash" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.libreoffice.test.desktop.deployment.crashextension:</value>
+ </prop>
+ <node o:name="UserDefinedImages">
+ <prop o:name="ImageSmallURL">
+ <value>%origin%/crash.png</value>
+ </prop>
+ <prop o:name="ImageBigURL">
+ <value>%origin%/crash.png</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ <node o:name="OfficeToolbarMerging">
+ <node o:name="org.libreoffice.test.desktop.deployment.crashextension.toolbarmerge" o:op="replace">
+ <node o:name="T1" o:op="replace">
+ <prop o:name="MergeToolBar">
+ <value>standardbar</value>
+ </prop>
+ <prop o:name="MergePoint">
+ <value>.uno:HelpIndex</value>
+ </prop>
+ <prop o:name="MergeCommand">
+ <value>AddAfter</value>
+ </prop>
+ <prop o:name="MergeFallback">
+ <value>AddLast</value>
+ </prop>
+ <prop o:name="MergeContext">
+ <value/>
+ </prop>
+ <node o:name="ToolBarItems">
+ <node o:name="B1" o:op="replace">
+ <prop o:name="URL">
+ <value>vnd.org.libreoffice.test.desktop.deployment.crashextension:</value>
+ </prop>
+ <prop o:name="Title">
+ <value xml:lang="en-US">Crash LibreOffice</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </node>
+ </item>
+</o:items>
diff --git a/desktop/test/deployment/crashextension/META-INF/manifest.xml b/desktop/test/deployment/crashextension/META-INF/manifest.xml
new file mode 100644
index 000000000000..cbb801947363
--- /dev/null
+++ b/desktop/test/deployment/crashextension/META-INF/manifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+
+<m:manifest xmlns:m="http://openoffice.org/2001/manifest">
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="Addons.xcu"/>
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="ProtocolHandler.xcu"/>
+ <m:file-entry m:media-type="application/vnd.sun.star.configuration-data"
+ m:full-path="ToolbarMerge.xcu"/>
+ <m:file-entry
+ m:media-type="application/vnd.sun.star.uno-components;platform=@PLATFORM@"
+ m:full-path="platform.components"/>
+</m:manifest>
diff --git a/desktop/test/deployment/crashextension/ProtocolHandler.xcu b/desktop/test/deployment/crashextension/ProtocolHandler.xcu
new file mode 100644
index 000000000000..f4011743bf5e
--- /dev/null
+++ b/desktop/test/deployment/crashextension/ProtocolHandler.xcu
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+
+<o:component-data xmlns:o="http://openoffice.org/2001/registry"
+ o:package="org.openoffice.Office" o:name="ProtocolHandler">
+ <node o:name="HandlerSet">
+ <node o:name="org.libreoffice.test.desktop.deployment.crashextension" o:op="replace">
+ <prop o:name="Protocols">
+ <value>vnd.org.libreoffice.test.desktop.deployment.crashextension:*</value>
+ </prop>
+ </node>
+ </node>
+</o:component-data>
diff --git a/desktop/test/deployment/crashextension/crash.png b/desktop/test/deployment/crashextension/crash.png
new file mode 100644
index 000000000000..693df038c355
--- /dev/null
+++ b/desktop/test/deployment/crashextension/crash.png
Binary files differ
diff --git a/desktop/test/deployment/crashextension/crashextension.component b/desktop/test/deployment/crashextension/crashextension.component
new file mode 100644
index 000000000000..2597e444a8ea
--- /dev/null
+++ b/desktop/test/deployment/crashextension/crashextension.component
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="org.libreoffice.test.desktop.deployment.crashextension.impl">
+ <service name="org.libreoffice.test.desktop.deployment.crashextension"/>
+ </implementation>
+</component>
diff --git a/desktop/test/deployment/crashextension/crashextension.cxx b/desktop/test/deployment/crashextension/crashextension.cxx
new file mode 100644
index 000000000000..2e64f3af024b
--- /dev/null
+++ b/desktop/test/deployment/crashextension/crashextension.cxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cassert>
+#include <cstddef>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/DispatchDescriptor.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <rtl/ustring.hxx>
+#include <uno/lbnames.h>
+
+namespace
+{
+class Provider : public cppu::WeakImplHelper3<css::lang::XServiceInfo,
+ css::frame::XDispatchProvider, css::frame::XDispatch>
+{
+public:
+ Provider(const Provider&) = delete;
+ const Provider& operator=(const Provider&) = delete;
+
+ static css::uno::Reference<css::uno::XInterface>
+ SAL_CALL static_create(css::uno::Reference<css::uno::XComponentContext> const& xContext)
+ {
+ return static_cast<cppu::OWeakObject*>(new Provider(xContext));
+ }
+
+ static rtl::OUString SAL_CALL static_getImplementationName();
+
+ static css::uno::Sequence<rtl::OUString> SAL_CALL static_getSupportedServiceNames();
+
+private:
+ explicit Provider(css::uno::Reference<css::uno::XComponentContext> const& context)
+ : context_(context)
+ {
+ assert(context.is());
+ }
+
+ virtual ~Provider() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName() override
+ {
+ return static_getImplementationName();
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const& ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<rtl::OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return static_getSupportedServiceNames();
+ }
+
+ virtual css::uno::Reference<css::frame::XDispatch>
+ SAL_CALL queryDispatch(css::util::URL const&, rtl::OUString const&, sal_Int32) override;
+
+ virtual css::uno::Sequence<css::uno::Reference<css::frame::XDispatch>> SAL_CALL
+ queryDispatches(css::uno::Sequence<css::frame::DispatchDescriptor> const& Requests) override;
+
+ virtual void SAL_CALL dispatch(css::util::URL const&,
+ css::uno::Sequence<css::beans::PropertyValue> const&) override;
+
+ virtual void SAL_CALL addStatusListener(css::uno::Reference<css::frame::XStatusListener> const&,
+ css::util::URL const&) override
+ {
+ }
+
+ virtual void SAL_CALL removeStatusListener(
+ css::uno::Reference<css::frame::XStatusListener> const&, css::util::URL const&) override
+ {
+ }
+
+ css::uno::Reference<css::uno::XComponentContext> context_;
+};
+
+rtl::OUString Provider::static_getImplementationName()
+{
+ return rtl::OUString("org.libreoffice.test.desktop.deployment.crashextension.impl");
+}
+
+css::uno::Sequence<rtl::OUString> Provider::static_getSupportedServiceNames()
+{
+ rtl::OUString name("org.libreoffice.test.desktop.deployment.crashextension");
+ return css::uno::Sequence<rtl::OUString>(&name, 1);
+}
+
+css::uno::Reference<css::frame::XDispatch> Provider::queryDispatch(css::util::URL const&,
+ rtl::OUString const&, sal_Int32)
+{
+ return this;
+}
+
+css::uno::Sequence<css::uno::Reference<css::frame::XDispatch>>
+Provider::queryDispatches(css::uno::Sequence<css::frame::DispatchDescriptor> const& Requests)
+{
+ css::uno::Sequence<css::uno::Reference<css::frame::XDispatch>> s(Requests.getLength());
+ for (sal_Int32 i = 0; i < s.getLength(); ++i)
+ {
+ s[i]
+ = queryDispatch(Requests[i].FeatureURL, Requests[i].FrameName, Requests[i].SearchFlags);
+ }
+ return s;
+}
+
+void Provider::dispatch(css::util::URL const&, css::uno::Sequence<css::beans::PropertyValue> const&)
+{
+ // Crash LibreOffice
+ *((char*)NULL) = 0;
+}
+
+cppu::ImplementationEntry const services[]
+ = { { &Provider::static_create, &Provider::static_getImplementationName,
+ &Provider::static_getSupportedServiceNames, &cppu::createSingleComponentFactory, NULL,
+ 0 },
+ { NULL, NULL, NULL, NULL, NULL, 0 } };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT void*
+component_getFactory(char const* pImplName, void* pServiceManager, void* pRegistryKey)
+{
+ return cppu::component_getFactoryHelper(pImplName, pServiceManager, pRegistryKey, services);
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT void
+component_getImplementationEnvironment(char const** ppEnvTypeName, uno_Environment**)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/desktop/test/deployment/crashextension/description.xml b/desktop/test/deployment/crashextension/description.xml
new file mode 100644
index 000000000000..3084b17ae4a2
--- /dev/null
+++ b/desktop/test/deployment/crashextension/description.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+
+<d:description xmlns:d="http://openoffice.org/extensions/description/2006">
+ <d:identifier
+ value="org.libreoffice.test.desktop.deployment.crashextension"/>
+ <d:version value="1.0"/>
+ <d:display-name>
+ <d:name lang="en">Crash LibreOffice</d:name>
+ </d:display-name>
+ <d:dependencies>
+ <d:OpenOffice.org-minimal-version d:name="OpenOffice.org 3.4" value="3.4"/>
+ </d:dependencies>
+</d:description>
diff --git a/desktop/test/deployment/locationtest/LocationTest.idl b/desktop/test/deployment/locationtest/LocationTest.idl
index 9e7881ce1347..75421e245507 100644
--- a/desktop/test/deployment/locationtest/LocationTest.idl
+++ b/desktop/test/deployment/locationtest/LocationTest.idl
@@ -17,11 +17,6 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef _com_sun_star_comp_smoketest_LocationTest_idl_
-#define _com_sun_star_comp_smoketest_LocationTest_idl_
-
-#include <com/sun/star/lang/XServiceInfo.idl>
-
module com { module sun { module star { module comp { module smoketest {
// example service, XServiceInfo is implemented here for demonstration
@@ -29,6 +24,4 @@ module com { module sun { module star { module comp { module smoketest {
service TestExtension: ::com::sun::star::lang::XServiceInfo;
};};};};};
-#endif
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/test/deployment/passive/passive_python.py b/desktop/test/deployment/passive/passive_python.py
index f16797e50175..58fe5d2266b6 100644
--- a/desktop/test/deployment/passive/passive_python.py
+++ b/desktop/test/deployment/passive/passive_python.py
@@ -16,10 +16,8 @@
# the License at http://www.apache.org/licenses/LICENSE-2.0 .
#
-import uno
import unohelper
-from com.sun.star.awt import Rectangle
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
from com.sun.star.awt.MessageBoxType import INFOBOX
from com.sun.star.frame import XDispatch, XDispatchProvider
diff --git a/desktop/test/deployment/update/platform/linux_loongarch64.oxt b/desktop/test/deployment/update/platform/linux_loongarch64.oxt
new file mode 100644
index 000000000000..3353ea1f0334
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_loongarch64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_riscv64.oxt b/desktop/test/deployment/update/platform/linux_riscv64.oxt
new file mode 100644
index 000000000000..3268e59a3a4a
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_riscv64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_s390.oxt b/desktop/test/deployment/update/platform/linux_s390.oxt
deleted file mode 100644
index 199702ebf056..000000000000
--- a/desktop/test/deployment/update/platform/linux_s390.oxt
+++ /dev/null
Binary files differ
diff --git a/desktop/test/deployment/update/platform/linux_sparc64.oxt b/desktop/test/deployment/update/platform/linux_sparc64.oxt
new file mode 100644
index 000000000000..4bd1afdd6508
--- /dev/null
+++ b/desktop/test/deployment/update/platform/linux_sparc64.oxt
Binary files differ
diff --git a/desktop/test/deployment/update/platform/readme.txt b/desktop/test/deployment/update/platform/readme.txt
index 30c028f9931d..222895ad73c9 100644
--- a/desktop/test/deployment/update/platform/readme.txt
+++ b/desktop/test/deployment/update/platform/readme.txt
@@ -12,7 +12,6 @@ linux_mips_el.oxt: linux_mips_el
linux_mips64_el.oxt: linux_mips64_el
linux_powerpc64.oxt: linux_powerpc64
linux_powerpc.oxt: linux_powerpc
-linux_s390.oxt: linux_s390
linux_s390x.oxt: linux_s390x
linux_sparc.oxt: linux_sparc
linux_x86.oxt: linux_x86
diff --git a/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
index 87b2540e44e9..bd5a1ac5f896 100644
--- a/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
+++ b/desktop/test/deployment/update/updateinfocreation/build/TestExtension.idl
@@ -17,11 +17,6 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef _com_sun_star_comp_smoketest_TestExtension_idl_
-#define _com_sun_star_comp_smoketest_TestExtension_idl_
-
-#include <com/sun/star/lang/XServiceInfo.idl>
-
module com { module sun { module star { module comp { module smoketest {
// example service, XServiceInfo is implemented here for demonstration
@@ -29,6 +24,4 @@ module com { module sun { module star { module comp { module smoketest {
service TestExtension: css::lang::XServiceInfo;
};};};};};
-#endif
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/uiconfig/ui/dependenciesdialog.ui b/desktop/uiconfig/ui/dependenciesdialog.ui
index c4e56d2bd7e5..d4f2fd6419b1 100644
--- a/desktop/uiconfig/ui/dependenciesdialog.ui
+++ b/desktop/uiconfig/ui/dependenciesdialog.ui
@@ -72,8 +72,12 @@
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="dependenciesdialog|label1">The extension cannot be installed as the following system dependencies are not fulfilled:</property>
<property name="wrap">True</property>
- <property name="max_width_chars">60</property>
+ <property name="width-chars">50</property>
+ <property name="max_width_chars">50</property>
<property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="depListTreeview"/>
+ </accessibility>
</object>
<packing>
<property name="expand">False</property>
@@ -98,6 +102,9 @@
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
+ <accessibility>
+ <relation type="labelled-by" target="label1"/>
+ </accessibility>
<child internal-child="selection">
<object class="GtkTreeSelection" id="Macro Library List-selection2"/>
</child>
diff --git a/desktop/uiconfig/ui/extensionmanager.ui b/desktop/uiconfig/ui/extensionmanager.ui
index d6bb9c982b4d..215536e179ab 100644
--- a/desktop/uiconfig/ui/extensionmanager.ui
+++ b/desktop/uiconfig/ui/extensionmanager.ui
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.36.0 -->
+<!-- Generated with glade 3.38.2 -->
<interface domain="dkt">
<requires lib="gtk+" version="3.20"/>
<object class="GtkDialog" id="ExtensionManagerDialog">
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <property name="title" translatable="yes" context="extensionmanager|ExtensionManagerDialog">Extension Manager</property>
- <property name="default_width">0</property>
- <property name="default_height">0</property>
- <property name="type_hint">dialog</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="extensionmanager|ExtensionManagerDialog">Extensions</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
- <property name="can_focus">False</property>
+ <property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
<child>
<object class="GtkButton" id="help">
<property name="label" translatable="yes" context="stock">_Help</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
@@ -37,8 +37,8 @@
<object class="GtkButton" id="close">
<property name="label" translatable="yes" context="stock">_Close</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
@@ -51,39 +51,39 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="pack_type">end</property>
+ <property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
<child>
- <!-- n-columns=1 n-rows=1 -->
+ <!-- n-columns=3 n-rows=1 -->
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="column_spacing">12</property>
+ <property name="can-focus">False</property>
<property name="margin-start">12</property>
<property name="margin-top">6</property>
+ <property name="column-spacing">12</property>
<child>
<object class="GtkCheckButton" id="shared">
<property name="label" translatable="yes" context="extensionmanager|shared">Installed for all users</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
<property name="active">True</property>
- <property name="draw_indicator">True</property>
+ <property name="draw-indicator">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="shared-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|shared">Filter extensions available for all users of this computer.</property>
@@ -91,19 +91,19 @@
</child>
</object>
<packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="user">
<property name="label" translatable="yes" context="extensionmanager|user">Installed for current user</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
<property name="active">True</property>
- <property name="draw_indicator">True</property>
+ <property name="draw-indicator">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="user-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|user">Filter extensions only available for the currently logged in user.</property>
@@ -111,19 +111,19 @@
</child>
</object>
<packing>
- <property name="left_attach">2</property>
- <property name="top_attach">0</property>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="bundled">
<property name="label" translatable="yes" context="extensionmanager|bundled">Bundled with %PRODUCTNAME</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
<property name="active">True</property>
- <property name="draw_indicator">True</property>
+ <property name="draw-indicator">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="bundled-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|bundled">Bundled extensions are installed by the system administrator using the operating system specific installer packages. These can not be installed, updated or removed here.</property>
@@ -131,8 +131,8 @@
</child>
</object>
<packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
</packing>
</child>
</object>
@@ -140,7 +140,7 @@
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can-focus">False</property>
<property name="label" translatable="yes" context="extensionmanager|label1">Display Extensions</property>
<attributes>
<attribute name="weight" value="bold"/>
@@ -155,21 +155,34 @@
</packing>
</child>
<child>
+ <object class="GtkEntry" id="search">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="placeholder-text" translatable="yes" context="extensionmanager|search">Search...</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkScrolledWindow" id="scroll">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="shadow_type">in</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can-focus">False</property>
<child>
<object class="GtkDrawingArea" id="extensions">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="can-focus">True</property>
<property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
@@ -186,22 +199,22 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButtonBox">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can-focus">False</property>
<property name="spacing">6</property>
- <property name="layout_style">start</property>
+ <property name="layout-style">start</property>
<child>
<object class="GtkButton" id="optionsbtn">
<property name="label" translatable="yes" context="extensionmanager|optionsbtn">_Options</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="optionsbtn-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|optionsbtn">Select an installed extension, then click to open the Options dialog for the extension.</property>
@@ -218,9 +231,9 @@
<object class="GtkButton" id="updatebtn">
<property name="label" translatable="yes" context="extensionmanager|updatebtn">Check for _Updates</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="updatebtn-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|updatebtn">Click to check for online updates of all installed extensions. To check for updates of the selected extension only, choose the Update command from the context menu. The check for availability of updates starts immediately.</property>
@@ -238,11 +251,11 @@
<object class="GtkButton" id="addbtn">
<property name="label" translatable="yes" context="extensionmanager|addbtn">_Add</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="has_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="addbtn-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|addbtn">Click Add to add an extension.</property>
@@ -260,9 +273,9 @@
<object class="GtkButton" id="removebtn">
<property name="label" translatable="yes" context="extensionmanager|removebtn">_Remove</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="removebtn-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|removebtn">Select the extension that you want to remove, and then click Remove.</property>
@@ -280,9 +293,9 @@
<object class="GtkButton" id="enablebtn">
<property name="label" translatable="yes" context="extensionmanager|enablebtn">_Enable</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
</object>
<packing>
<property name="expand">True</property>
@@ -295,58 +308,58 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
- <!-- n-columns=1 n-rows=1 -->
+ <!-- n-columns=3 n-rows=2 -->
<object class="GtkGrid" id="grid3">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="column_spacing">6</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">6</property>
<child>
<object class="GtkLabel" id="progressft">
- <property name="can_focus">False</property>
- <property name="no_show_all">True</property>
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
<property name="label" translatable="yes" context="extensionmanager|progressft">Adding %EXTENSION_NAME</property>
<property name="justify">right</property>
</object>
<packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cancel">
<property name="label" translatable="yes" context="stock">_Cancel</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="no_show_all">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="no-show-all">True</property>
<property name="use-underline">True</property>
</object>
<packing>
- <property name="left_attach">2</property>
- <property name="top_attach">0</property>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progressbar">
- <property name="can_focus">False</property>
- <property name="no_show_all">True</property>
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
</object>
<packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLinkButton" id="getextensions">
<property name="label" translatable="yes" context="extensionmanager|getextensions">Get more extensions online...</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
<property name="relief">none</property>
<property name="xalign">0</property>
<child internal-child="accessible">
@@ -356,8 +369,8 @@
</child>
</object>
<packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
<property name="width">3</property>
</packing>
</child>
@@ -365,7 +378,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
</object>
@@ -381,12 +394,9 @@
<action-widget response="-11">help</action-widget>
<action-widget response="-6">close</action-widget>
</action-widgets>
- <child type="titlebar">
- <placeholder/>
- </child>
<child internal-child="accessible">
<object class="AtkObject" id="ExtensionManagerDialog-atkobject">
- <property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|ExtensionManagerDialog">The Extension Manager adds, removes, disables, enables, and updates %PRODUCTNAME extensions.</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extensionmanager|extended_tip|ExtensionManagerDialog">The Extension Manager adds, removes, disables, enables, and updates extensions.</property>
</object>
</child>
</object>
diff --git a/desktop/uiconfig/ui/updateinstalldialog.ui b/desktop/uiconfig/ui/updateinstalldialog.ui
index 6ef80d393df2..15e7bcc398f3 100644
--- a/desktop/uiconfig/ui/updateinstalldialog.ui
+++ b/desktop/uiconfig/ui/updateinstalldialog.ui
@@ -175,7 +175,7 @@
</child>
<child internal-child="accessible">
<object class="AtkObject" id="UpdateInstallDialog-atkobject">
- <property name="AtkObject::accessible-description" translatable="yes" context="updateinstalldialog|extended_tip|UpdateInstallDialog">Click the Check for Updates button in the Extension Manager to check for online updates for all installed extensions. To check for online updates for only the selected extension, right-click to open the context menu, then choose Update.</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="updateinstalldialog|extended_tip|UpdateInstallDialog">Click the Check for Updates button in the Extensions dialog to check for online updates for all installed extensions. To check for online updates for only the selected extension, right-click to open the context menu, then choose Update.</property>
</object>
</child>
</object>
diff --git a/desktop/unx/source/splashx.c b/desktop/unx/source/splashx.c
index afd137d06876..4dc50a740695 100644
--- a/desktop/unx/source/splashx.c
+++ b/desktop/unx/source/splashx.c
@@ -16,9 +16,7 @@
#include <X11/Xatom.h>
#include <X11/Xutil.h>
-#ifdef USE_XINERAMA
#include <X11/extensions/Xinerama.h>
-#endif
#include <osl/endian.h>
#include <fcntl.h>
@@ -406,10 +404,8 @@ static int splash_init_display( struct splash* splash, int argc, char** argv )
{
char *display_name = NULL;
int i;
-#ifdef USE_XINERAMA
int n_xinerama_screens = 1;
XineramaScreenInfo* p_screens = NULL;
-#endif
for ( i = 0; i < argc; i++ )
{
@@ -442,7 +438,6 @@ static int splash_init_display( struct splash* splash, int argc, char** argv )
splash->display_x_pos = 0;
splash->display_y_pos = 0;
-#ifdef USE_XINERAMA
p_screens = XineramaQueryScreens( splash->display, &n_xinerama_screens );
if( p_screens )
{
@@ -459,7 +454,6 @@ static int splash_init_display( struct splash* splash, int argc, char** argv )
}
XFree( p_screens );
}
-#endif
return 1;
}
@@ -812,6 +806,6 @@ struct splash* splash_create(rtl_uString* pAppPath, int argc, char** argv)
}
-#endif // ENABLE_QUICKSTART_LIBPNG
+#endif // defined(ENABLE_QUICKSTART_LIBPNG) && HAVE_FEATURE_UI
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
index a83db69e5c66..0bb009d9c598 100644
--- a/desktop/unx/source/start.c
+++ b/desktop/unx/source/start.c
@@ -471,13 +471,14 @@ static sal_Bool send_args(int fd, rtl_uString const *pCwdPath)
}
nLen = rtl_string_getLength(pOut) + 1;
- bResult = (write(fd, rtl_string_getStr(pOut), nLen) == (ssize_t) nLen);
+ ssize_t n = write(fd, rtl_string_getStr(pOut), nLen);
+ bResult = (n >= 0 && (size_t) n == nLen);
if ( bResult )
{
char resp[SAL_N_ELEMENTS("InternalIPC::ProcessingDone")];
- ssize_t n = read(fd, resp, SAL_N_ELEMENTS(resp));
- bResult = n == (ssize_t) SAL_N_ELEMENTS(resp)
+ n = read(fd, resp, SAL_N_ELEMENTS(resp));
+ bResult = n == SAL_N_ELEMENTS(resp)
&& (memcmp(
resp, "InternalIPC::ProcessingDone",
SAL_N_ELEMENTS(resp))
@@ -583,14 +584,8 @@ static void exec_pagein (Args *args)
static void extend_library_path(const char *new_element)
{
rtl_uString *pEnvName=NULL, *pOrigEnvVar=NULL, *pNewEnvVar=NULL;
- const char *pathname;
-#ifdef AIX
- pathname = "LIBPATH";
-#else
- pathname = "LD_LIBRARY_PATH";
-#endif
- rtl_uString_newFromAscii(&pEnvName, pathname);
+ rtl_uString_newFromAscii(&pEnvName, "LD_LIBRARY_PATH");
rtl_uString_newFromAscii(&pNewEnvVar, new_element);
osl_getEnvironment(pEnvName, &pOrigEnvVar);
@@ -721,8 +716,23 @@ static void sigterm_handler(int ignored)
(void) ignored;
if (g_pProcess) {
- osl_terminateProcess(g_pProcess); // forward signal to soffice.bin
- osl_joinProcess(g_pProcess);
+ int SigTermSucceded = 0;
+ oslProcessInfo info;
+ info.Size = sizeof(oslProcessInfo);
+
+ // forward SIGTERM to soffice.bin and give it a chance to semi-gracefully exit
+ // enough to remove named pipe
+ if (osl_getProcessInfo(g_pProcess, osl_Process_IDENTIFIER, &info) == osl_Process_E_None) {
+ TimeValue delay = { 1, 0 }; // 1 sec
+ SigTermSucceded = kill(info.Ident, SIGTERM) == 0 &&
+ osl_joinProcessWithTimeout(g_pProcess, &delay) == osl_Process_E_None;
+ }
+
+ // didn't work, SIGKILL instead
+ if (!SigTermSucceded) {
+ osl_terminateProcess(g_pProcess); // uses SIGKILL to terminate soffice.bin
+ osl_joinProcess(g_pProcess);
+ }
}
_exit(255);
diff --git a/desktop/win32/source/applauncher/launcher.cxx b/desktop/win32/source/applauncher/launcher.cxx
index bf80dba2cc5a..1ec8caf13555 100644
--- a/desktop/win32/source/applauncher/launcher.cxx
+++ b/desktop/win32/source/applauncher/launcher.cxx
@@ -19,17 +19,17 @@
#include "launcher.hxx"
+#include <filesystem>
#include <stdlib.h>
#include <malloc.h>
+#include <systools/win32/extended_max_path.hxx>
+
extern "C" int APIENTRY wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{
// Retrieve startup info
- STARTUPINFOW aStartupInfo;
-
- ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) );
- aStartupInfo.cb = sizeof( aStartupInfo );
+ STARTUPINFOW aStartupInfo{ sizeof(aStartupInfo) };
GetStartupInfoW( &aStartupInfo );
// Retrieve command line
@@ -42,20 +42,15 @@ extern "C" int APIENTRY wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
// Calculate application name
- WCHAR szApplicationName[MAX_PATH];
- WCHAR szDrive[MAX_PATH];
- WCHAR szDir[MAX_PATH];
- WCHAR szFileName[MAX_PATH];
- WCHAR szExt[MAX_PATH];
-
- GetModuleFileNameW( nullptr, szApplicationName, MAX_PATH );
- _wsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt );
- _wmakepath( szApplicationName, szDrive, szDir, L"soffice", L".exe" );
+ WCHAR szThisAppName[EXTENDED_MAX_PATH];
+ GetModuleFileNameW(nullptr, szThisAppName, std::size(szThisAppName));
+ std::filesystem::path soffice_exe(szThisAppName);
+ soffice_exe.replace_filename(L"soffice.exe");
PROCESS_INFORMATION aProcessInfo;
bool fSuccess = CreateProcessW(
- szApplicationName,
+ soffice_exe.c_str(),
lpCommandLine,
nullptr,
nullptr,
diff --git a/desktop/win32/source/loader.cxx b/desktop/win32/source/loader.cxx
index d30f0ef90896..ca74c13ab92d 100644
--- a/desktop/win32/source/loader.cxx
+++ b/desktop/win32/source/loader.cxx
@@ -18,12 +18,16 @@
*/
#include "loader.hxx"
+#include <algorithm>
#include <cassert>
-#include <systools/win32/uwinapi.h>
+#include <numeric>
#include <stdlib.h>
#include <string>
+#include <string_view>
#include <vector>
#include <desktop/exithelper.h>
+#include <systools/win32/extended_max_path.hxx>
+#include <systools/win32/uwinapi.h>
#include <tools/pathutils.hxx>
#include <fstream>
@@ -43,75 +47,114 @@ void fail()
TerminateProcess(GetCurrentProcess(), 255);
}
-LPWSTR* GetCommandArgs(int* pArgc) { return CommandLineToArgvW(GetCommandLineW(), pArgc); }
+struct CommandArgs
+{
+ LPWSTR* argv;
+ int argc;
+ CommandArgs() { argv = CommandLineToArgvW(GetCommandLineW(), &argc); }
+ ~CommandArgs() { LocalFree(argv); }
+ auto begin() const { return argv; }
+ auto end() const { return begin() + argc; }
+};
// tdf#120249: quotes in arguments need to be escaped; backslashes before quotes need doubling. See
// https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw
-std::wstring EscapeArg(LPCWSTR sArg)
+std::wstring EscapeArg(std::wstring_view sArg)
{
- const size_t nOrigSize = wcslen(sArg);
- LPCWSTR const end = sArg + nOrigSize;
std::wstring sResult(L"\"");
-
- LPCWSTR lastPosQuote = sArg;
- LPCWSTR posQuote;
- while ((posQuote = std::find(lastPosQuote, end, L'"')) != end)
+ for (size_t lastPosQuote = 0; lastPosQuote <= sArg.size();)
{
- LPCWSTR posBackslash = posQuote;
- while (posBackslash != lastPosQuote && *(posBackslash - 1) == L'\\')
+ const size_t posQuote = std::min(sArg.find(L'"', lastPosQuote), sArg.size());
+ size_t posBackslash = posQuote;
+ while (posBackslash != lastPosQuote && sArg[posBackslash - 1] == L'\\')
--posBackslash;
+ // 2n+1 '\' to escape internal '"'; 2n '\' before closing '"'
+ const size_t nEscapes = (posQuote - posBackslash) * 2 + (posQuote < sArg.size() ? 1 : 0);
- sResult.append(lastPosQuote, posBackslash);
- sResult.append((posQuote - posBackslash) * 2 + 1, L'\\'); // 2n+1 '\' to escape the '"'
+ sResult.append(sArg.begin() + lastPosQuote, sArg.begin() + posBackslash);
+ sResult.append(nEscapes, L'\\');
sResult.append(1, L'"');
lastPosQuote = posQuote + 1;
}
-
- LPCWSTR posTrailingBackslashSeq = end;
- while (posTrailingBackslashSeq != lastPosQuote && *(posTrailingBackslashSeq - 1) == L'\\')
- --posTrailingBackslashSeq;
- sResult.append(lastPosQuote, posTrailingBackslashSeq);
- sResult.append((end - posTrailingBackslashSeq) * 2, L'\\'); // 2n '\' before closing '"'
- sResult.append(1, L'"');
-
return sResult;
}
-void AddEscapedArg(LPCWSTR sArg, std::vector<std::wstring>& aEscapedArgs,
- std::size_t& iLengthAccumulator)
+std::wstring getCWDarg()
{
- std::wstring sEscapedArg = EscapeArg(sArg);
- aEscapedArgs.push_back(sEscapedArg);
- iLengthAccumulator += sEscapedArg.length() + 1; // a space between args
-}
+ std::wstring s(L" \"-env:OOO_CWD=");
-bool HasWildCard(LPCWSTR sArg)
-{
- while (*sArg != L'\0')
+ DWORD cwdLen = GetCurrentDirectoryW(0, nullptr);
+ std::vector<WCHAR> cwd(cwdLen);
+ cwdLen = GetCurrentDirectoryW(cwdLen, cwd.data());
+ if (cwdLen == 0 || cwdLen >= cwd.size())
{
- if (*sArg == L'*' || *sArg == L'?')
- return true;
- sArg++;
+ s += L'0';
}
- return false;
-}
+ else
+ {
+ s += L'2';
+ size_t n = 0; // number of trailing backslashes
+ for (auto* p = cwd.data(); *p; ++p)
+ {
+ WCHAR c = *p;
+ if (c == L'$')
+ {
+ s += L"\\$";
+ n = 0;
+ }
+ else if (c == L'\\')
+ {
+ s += L"\\\\";
+ n += 2;
+ }
+ else
+ {
+ s += c;
+ n = 0;
+ }
+ }
+ // The command line will continue with a double quote, so double any
+ // preceding backslashes as required by Windows:
+ s.append(n, L'\\');
+ }
+ s += L'"';
+ return s;
}
-namespace desktop_win32 {
+WCHAR* commandLineAppend(WCHAR* buffer, std::wstring_view text)
+{
+ auto ret = std::copy_n(text.begin(), text.size(), buffer);
+ *ret = 0; // trailing null
+ return ret;
+}
-void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory) {
- if (!GetModuleFileNameW(nullptr, iniDirectory, MAX_PATH)) {
- fail();
- }
- WCHAR * iniDirEnd = tools::filename(iniDirectory);
- WCHAR name[MAX_PATH + MY_LENGTH(L".bin")];
- // hopefully std::size_t is large enough to not overflow
- WCHAR * nameEnd = name;
- for (WCHAR * p = iniDirEnd; *p != L'\0'; ++p) {
- *nameEnd++ = *p;
+// Set the PATH environment variable in the current (loader) process, so that a
+// following CreateProcess has the necessary environment:
+// returns a pair of strings { binPath, iniDirectory }
+// * binPath is the full path to the "bin" file corresponding to the current executable.
+// * iniDirectory is the full directory path (ending in "\") to the "ini" file corresponding to the
+// current executable.
+[[nodiscard]] std::pair<std::wstring, std::wstring> extendLoaderEnvironment()
+{
+ std::vector<wchar_t> executable_path(EXTENDED_MAX_PATH);
+ DWORD exe_len;
+ for (;;)
+ {
+ exe_len = GetModuleFileNameW(nullptr, executable_path.data(), executable_path.size());
+ if (!exe_len)
+ fail();
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ executable_path.resize(exe_len + 4); // to accommodate a possible ".bin" in the end
+ break;
+ }
+ executable_path.resize(executable_path.size() * 2);
}
- if (!(nameEnd - name >= 4 && nameEnd[-4] == L'.' &&
+ WCHAR* iniDirEnd = tools::filename(executable_path.data());
+ std::wstring_view iniDirView(executable_path.data(), iniDirEnd);
+ WCHAR* nameEnd = executable_path.data() + exe_len;
+ if (!(nameEnd - iniDirEnd >= 4 && nameEnd[-4] == L'.' &&
(((nameEnd[-3] == L'E' || nameEnd[-3] == L'e') &&
(nameEnd[-2] == L'X' || nameEnd[-2] == L'x') &&
(nameEnd[-1] == L'E' || nameEnd[-1] == L'e')) ||
@@ -125,44 +168,41 @@ void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory) {
nameEnd[-3] = 'b';
nameEnd[-2] = 'i';
nameEnd[-1] = 'n';
- tools::buildPath(binPath, iniDirectory, iniDirEnd, name, nameEnd - name);
- *iniDirEnd = L'\0';
- std::size_t const maxEnv = 32767;
- WCHAR env[maxEnv];
- DWORD n = GetEnvironmentVariableW(L"PATH", env, maxEnv);
- if ((n >= maxEnv || n == 0) && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ std::wstring_view nameView(iniDirEnd, nameEnd);
+
+ WCHAR env[32767];
+ DWORD n = GetEnvironmentVariableW(L"PATH", env, std::size(env));
+ if ((n >= std::size(env) || n == 0) && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
fail();
}
+ std::wstring_view envView(env, n);
// must be first in PATH to override other entries
- assert(*(iniDirEnd - 1) == L'\\'); // hence -1 below
- if (wcsncmp(env, iniDirectory, iniDirEnd - iniDirectory - 1) != 0
- || env[iniDirEnd - iniDirectory - 1] != L';')
+ assert(iniDirView.back() == L'\\'); // hence -1 below
+ std::wstring_view iniDirView1(iniDirView.substr(0, iniDirView.size() - 1));
+ if (!envView.starts_with(iniDirView1) || env[iniDirView1.size()] != L';')
{
- WCHAR pad[MAX_PATH + maxEnv];
- // hopefully std::size_t is large enough to not overflow
- WCHAR * p = commandLineAppend(pad, iniDirectory, iniDirEnd - iniDirectory - 1);
+ std::wstring pad(iniDirView1);
if (n != 0) {
- *p++ = L';';
- for (DWORD i = 0; i <= n; ++i) {
- *p++ = env[i];
- }
- } else {
- *p++ = L'\0';
+ pad += L';';
+ pad += envView;
}
- if (!SetEnvironmentVariableW(L"PATH", pad)) {
+ if (!SetEnvironmentVariableW(L"PATH", pad.data())) {
fail();
}
}
+
+ return { tools::buildPath(iniDirView, nameView), std::wstring(iniDirView) };
}
+}
+
+namespace desktop_win32 {
+
int officeloader_impl(bool bAllowConsole)
{
- WCHAR szTargetFileName[MAX_PATH] = {};
- WCHAR szIniDirectory[MAX_PATH];
- STARTUPINFOW aStartupInfo;
-
- desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
+ const auto& [szTargetFileName, szIniDirectory] = extendLoaderEnvironment();
+ STARTUPINFOW aStartupInfo;
ZeroMemory(&aStartupInfo, sizeof(aStartupInfo));
aStartupInfo.cb = sizeof(aStartupInfo);
@@ -173,39 +213,46 @@ int officeloader_impl(bool bAllowConsole)
DWORD dwExitCode = DWORD(-1);
bool fSuccess = false;
- LPWSTR lpCommandLine = nullptr;
bool bFirst = true;
- WCHAR cwd[MAX_PATH];
- DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
- if (cwdLen >= MAX_PATH)
- {
- cwdLen = 0;
- }
- std::vector<std::wstring> aEscapedArgs;
- // read limit values from bootstrap.ini
+ // read limit values from fundamental.override.ini
unsigned int nMaxMemoryInMB = 0;
bool bExcludeChildProcesses = true;
+ bool fallbackForMaxMemoryInMB = true;
+ bool fallbackForExcludeChildProcesses = true;
- const WCHAR* szIniFile = L"\\bootstrap.ini";
- const size_t nDirLen = wcslen(szIniDirectory);
- if (wcslen(szIniFile) + nDirLen < MAX_PATH)
+ try
{
- WCHAR szBootstrapIni[MAX_PATH];
- wcscpy(szBootstrapIni, szIniDirectory);
- wcscpy(&szBootstrapIni[nDirLen], szIniFile);
-
+ boost::property_tree::ptree pt;
+ std::ifstream aFile(szIniDirectory + L"\\fundamental.override.ini");
+ boost::property_tree::ini_parser::read_ini(aFile, pt);
+ nMaxMemoryInMB = pt.get("Bootstrap.LimitMaximumMemoryInMB", nMaxMemoryInMB);
+ fallbackForMaxMemoryInMB = !pt.get_child_optional("Bootstrap.LimitMaximumMemoryInMB");
+ bExcludeChildProcesses = pt.get("Bootstrap.ExcludeChildProcessesFromLimit", bExcludeChildProcesses);
+ fallbackForExcludeChildProcesses
+ = !pt.get_child_optional("Bootstrap.ExcludeChildProcessesFromLimit");
+ }
+ catch (...)
+ {
+ nMaxMemoryInMB = 0;
+ }
+ // For backwards compatibility, for now also try to read the values from bootstrap.ini if
+ // fundamental.override.ini does not provide them:
+ if (fallbackForMaxMemoryInMB || fallbackForExcludeChildProcesses) {
try
{
boost::property_tree::ptree pt;
- std::ifstream aFile(szBootstrapIni);
+ std::ifstream aFile(szIniDirectory + L"\\bootstrap.ini");
boost::property_tree::ini_parser::read_ini(aFile, pt);
- nMaxMemoryInMB = pt.get("Win32.LimitMaximumMemoryInMB", nMaxMemoryInMB);
- bExcludeChildProcesses = pt.get("Win32.ExcludeChildProcessesFromLimit", bExcludeChildProcesses);
+ if (fallbackForMaxMemoryInMB) {
+ nMaxMemoryInMB = pt.get("Win32.LimitMaximumMemoryInMB", nMaxMemoryInMB);
+ }
+ if (fallbackForExcludeChildProcesses) {
+ bExcludeChildProcesses = pt.get("Win32.ExcludeChildProcessesFromLimit", bExcludeChildProcesses);
+ }
}
catch (...)
{
- nMaxMemoryInMB = 0;
}
}
@@ -224,117 +271,75 @@ int officeloader_impl(bool bAllowConsole)
sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
}
- do
+ std::vector<std::wstring> aEscapedArgs;
+ bool bHeadlessMode = false;
+ for (std::wstring_view arg : CommandArgs())
{
- if (bFirst)
+ // Check command line arguments for "--headless" parameter. We only set the environment
+ // variable "ATTACHED_PARENT_PROCESSID" for the headless mode as self-destruction of the
+ // soffice.bin process can lead to certain side-effects (log-off can result in data-loss,
+ // ".lock" is not deleted). See 138244 for more information.
+ if (arg == L"-headless" || arg == L"--headless")
+ bHeadlessMode = true;
+ // check for wildcards in arguments - Windows does not expand automatically
+ else if (arg.find_first_of(L"*?") != std::wstring_view::npos)
{
- int argc = 0;
- LPWSTR* argv = GetCommandArgs(&argc);
- std::size_t n = 0;
- for (int i = 0; i < argc; ++i)
+ WIN32_FIND_DATAW aFindData;
+ HANDLE h = FindFirstFileW(arg.data(), &aFindData);
+ if (h != INVALID_HANDLE_VALUE)
{
- // check for wildCards in arguments- windows does not expand automatically
- if (HasWildCard(argv[i]))
+ const int nPathSize = 32 * 1024;
+ wchar_t drive[3];
+ wchar_t dir[nPathSize];
+ wchar_t path[nPathSize];
+ _wsplitpath_s(arg.data(), drive, std::size(drive), dir, std::size(dir), nullptr, 0,
+ nullptr, 0);
+ do
{
- WIN32_FIND_DATAW aFindData;
- HANDLE h = FindFirstFileW(argv[i], &aFindData);
- if (h == INVALID_HANDLE_VALUE)
- {
- AddEscapedArg(argv[i], aEscapedArgs, n);
- }
- else
- {
- const int nPathSize = 32 * 1024;
- wchar_t drive[nPathSize];
- wchar_t dir[nPathSize];
- wchar_t path[nPathSize];
- _wsplitpath_s(argv[i], drive, nPathSize, dir, nPathSize, nullptr, 0,
- nullptr, 0);
- _wmakepath_s(path, nPathSize, drive, dir, aFindData.cFileName, nullptr);
- AddEscapedArg(path, aEscapedArgs, n);
-
- while (FindNextFileW(h, &aFindData))
- {
- _wmakepath_s(path, nPathSize, drive, dir, aFindData.cFileName, nullptr);
- AddEscapedArg(path, aEscapedArgs, n);
- }
- FindClose(h);
- }
- }
- else
- {
- AddEscapedArg(argv[i], aEscapedArgs, n);
- }
- }
- LocalFree(argv);
- n += MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1;
- // 4 * cwdLen: each char preceded by backslash, each trailing
- // backslash doubled
- lpCommandLine = new WCHAR[n];
- }
- WCHAR* p = desktop_win32::commandLineAppend(lpCommandLine, aEscapedArgs[0].c_str(),
- aEscapedArgs[0].length());
- for (size_t i = 1; i < aEscapedArgs.size(); ++i)
- {
- const std::wstring& rArg = aEscapedArgs[i];
- if (bFirst || EXITHELPER_NORMAL_RESTART == dwExitCode
- || wcsncmp(rArg.c_str(), MY_STRING(L"\"-env:")) == 0)
- {
- p = desktop_win32::commandLineAppend(p, MY_STRING(L" "));
- p = desktop_win32::commandLineAppend(p, rArg.c_str(), rArg.length());
+ _wmakepath_s(path, std::size(path), drive, dir, aFindData.cFileName, nullptr);
+ aEscapedArgs.push_back(EscapeArg(path));
+ } while (FindNextFileW(h, &aFindData));
+ FindClose(h);
+ continue;
}
}
- p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD="));
- if (cwdLen == 0)
- {
- p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
- }
- else
- {
- p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
- p = desktop_win32::commandLineAppendEncoded(p, cwd);
- }
- desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
- bFirst = false;
+ aEscapedArgs.push_back(EscapeArg(arg));
+ }
+ size_t n = std::accumulate(aEscapedArgs.begin(), aEscapedArgs.end(), aEscapedArgs.size(),
+ [](size_t a, const std::wstring& s) { return a + s.size(); });
+ std::wstring sCWDarg = getCWDarg();
+ n += sCWDarg.size() + 1;
+ LPWSTR lpCommandLine = new WCHAR[n];
+ if (bHeadlessMode)
+ {
WCHAR szParentProcessId[64]; // This is more than large enough for a 128 bit decimal value
- bool bHeadlessMode(false);
+ if (_ltow(static_cast<long>(GetCurrentProcessId()), szParentProcessId, 10))
+ SetEnvironmentVariableW(L"ATTACHED_PARENT_PROCESSID", szParentProcessId);
+ }
+ do
+ {
+ WCHAR* p = commandLineAppend(lpCommandLine, aEscapedArgs[0]);
+ for (size_t i = 1; i < aEscapedArgs.size(); ++i)
{
- // Check command line arguments for "--headless" parameter. We only
- // set the environment variable "ATTACHED_PARENT_PROCESSID" for the headless
- // mode as self-destruction of the soffice.bin process can lead to
- // certain side-effects (log-off can result in data-loss, ".lock" is not deleted.
- // See 138244 for more information.
- int argc2;
- LPWSTR* argv2 = GetCommandArgs(&argc2);
-
- if (argc2 > 1)
+ const std::wstring& rArg = aEscapedArgs[i];
+ if (bFirst || EXITHELPER_NORMAL_RESTART == dwExitCode || rArg.starts_with(L"\"-env:"))
{
- int n;
-
- for (n = 1; n < argc2; n++)
- {
- if (0 == wcsnicmp(argv2[n], L"-headless", 9)
- || 0 == wcsnicmp(argv2[n], L"--headless", 10))
- {
- bHeadlessMode = true;
- }
- }
+ p = commandLineAppend(p, L" ");
+ p = commandLineAppend(p, rArg);
}
-
- LocalFree(argv2);
}
- if (_ltow(static_cast<long>(GetCurrentProcessId()), szParentProcessId, 10) && bHeadlessMode)
- SetEnvironmentVariableW(L"ATTACHED_PARENT_PROCESSID", szParentProcessId);
+ commandLineAppend(p, sCWDarg);
+ bFirst = false;
PROCESS_INFORMATION aProcessInfo;
- fSuccess = CreateProcessW(szTargetFileName, lpCommandLine, nullptr, nullptr, TRUE,
- bAllowConsole ? 0 : DETACHED_PROCESS, nullptr, szIniDirectory,
- &aStartupInfo, &aProcessInfo);
+ fSuccess = CreateProcessW(szTargetFileName.data(), lpCommandLine, nullptr, nullptr, TRUE,
+ bAllowConsole ? 0 : DETACHED_PROCESS, nullptr,
+ szIniDirectory.data(), &aStartupInfo, &aProcessInfo);
if (fSuccess)
{
@@ -379,9 +384,7 @@ int officeloader_impl(bool bAllowConsole)
int unopkgloader_impl(bool bAllowConsole)
{
- WCHAR szTargetFileName[MAX_PATH];
- WCHAR szIniDirectory[MAX_PATH];
- desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory);
+ const auto& [szTargetFileName, szIniDirectory] = extendLoaderEnvironment();
STARTUPINFOW aStartupInfo{};
aStartupInfo.cb = sizeof(aStartupInfo);
@@ -389,63 +392,32 @@ int unopkgloader_impl(bool bAllowConsole)
DWORD dwExitCode = DWORD(-1);
- size_t iniDirLen = wcslen(szIniDirectory);
- WCHAR cwd[MAX_PATH];
- DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd);
- if (cwdLen >= MAX_PATH) {
- cwdLen = 0;
- }
- WCHAR redirect[MAX_PATH];
+ std::wstring sCWDarg = getCWDarg();
DWORD dummy;
- bool hasRedirect =
- tools::buildPath(
- redirect, szIniDirectory, szIniDirectory + iniDirLen,
- MY_STRING(L"redirect.ini")) != nullptr &&
- (GetBinaryTypeW(redirect, &dummy) || // cheaper check for file existence?
+ std::wstring redirect = tools::buildPath(szIniDirectory, L"redirect.ini");
+ bool hasRedirect = !redirect.empty() &&
+ (GetBinaryTypeW(redirect.data(), &dummy) || // cheaper check for file existence?
GetLastError() != ERROR_FILE_NOT_FOUND);
LPWSTR cl1 = GetCommandLineW();
- WCHAR* cl2 = new WCHAR[
- wcslen(cl1) +
- (hasRedirect
- ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") +
- iniDirLen + MY_LENGTH(L"redirect.ini\""))
- : 0) +
- MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1];
- // 4 * cwdLen: each char preceded by backslash, each trailing backslash
- // doubled
- WCHAR* p = desktop_win32::commandLineAppend(cl2, cl1);
- if (hasRedirect) {
- p = desktop_win32::commandLineAppend(
- p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:"));
- p = desktop_win32::commandLineAppend(p, szIniDirectory);
- p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\""));
- }
- p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD="));
- if (cwdLen == 0) {
- p = desktop_win32::commandLineAppend(p, MY_STRING(L"0"));
- }
- else {
- p = desktop_win32::commandLineAppend(p, MY_STRING(L"2"));
- p = desktop_win32::commandLineAppendEncoded(p, cwd);
- }
- desktop_win32::commandLineAppend(p, MY_STRING(L"\""));
+ std::wstring cl2 = cl1;
+ if (hasRedirect)
+ cl2 += L" \"-env:INIFILENAME=vnd.sun.star.pathname:" + redirect + L"\"";
+ cl2 += sCWDarg;
PROCESS_INFORMATION aProcessInfo;
bool fSuccess = CreateProcessW(
- szTargetFileName,
- cl2,
+ szTargetFileName.data(),
+ cl2.data(),
nullptr,
nullptr,
TRUE,
bAllowConsole ? 0 : DETACHED_PROCESS,
nullptr,
- szIniDirectory,
+ szIniDirectory.data(),
&aStartupInfo,
&aProcessInfo);
- delete[] cl2;
-
if (fSuccess)
{
DWORD dwWaitResult;
diff --git a/desktop/win32/source/loader.hxx b/desktop/win32/source/loader.hxx
index 66b0ed8e53a1..784926a78080 100644
--- a/desktop/win32/source/loader.hxx
+++ b/desktop/win32/source/loader.hxx
@@ -19,65 +19,11 @@
#pragma once
-#include <cstddef>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <string.h>
-
-#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
-#define MY_STRING(s) (s), MY_LENGTH(s)
namespace desktop_win32 {
-inline WCHAR * commandLineAppend(
- WCHAR * buffer, WCHAR const * text, std::size_t length)
-{
- wcsncpy(buffer, text, length + 1); // trailing null
- return buffer + length;
-}
-
-inline WCHAR * commandLineAppend(WCHAR * buffer, WCHAR const * text) {
- return commandLineAppend(buffer, text, wcslen(text));
-}
-
-inline WCHAR * commandLineAppendEncoded(WCHAR * buffer, WCHAR const * text) {
- std::size_t n = 0;
- for (;;) {
- WCHAR c = *text++;
- if (c == L'\0') {
- break;
- } else if (c == L'$') {
- buffer = commandLineAppend(buffer, MY_STRING(L"\\$"));
- n = 0;
- } else if (c == L'\\') {
- buffer = commandLineAppend(buffer, MY_STRING(L"\\\\"));
- n += 2;
- } else {
- *buffer++ = c;
- n = 0;
- }
- }
- // The command line will continue with a double quote, so double any
- // preceding backslashes as required by Windows:
- for (std::size_t i = 0; i < n; ++i) {
- *buffer++ = L'\\';
- }
- *buffer = L'\0';
- return buffer;
-}
-
-// Set the PATH environment variable in the current (loader) process, so that a
-// following CreateProcess has the necessary environment:
-// @param binPath
-// Must point to an array of size at least MAX_PATH. Is filled with the null
-// terminated full path to the "bin" file corresponding to the current
-// executable.
-// @param iniDirectory
-// Must point to an array of size at least MAX_PATH. Is filled with the null
-// terminated full directory path (ending in "\") to the "ini" file
-// corresponding to the current executable.
-void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory);
-
// Implementation of the process guarding soffice.bin
int officeloader_impl(bool bAllowConsole);
diff --git a/desktop/win32/source/unoinfo.cxx b/desktop/win32/source/unoinfo.cxx
index 14cee8819dde..e44881faab12 100644
--- a/desktop/win32/source/unoinfo.cxx
+++ b/desktop/win32/source/unoinfo.cxx
@@ -25,19 +25,18 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <systools/win32/extended_max_path.hxx>
#include <tools/pathutils.hxx>
-#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
-#define MY_STRING(s) (s), MY_LENGTH(s)
-
namespace {
-wchar_t * getBrandPath(wchar_t * path) {
- DWORD n = GetModuleFileNameW(nullptr, path, MAX_PATH);
- if (n == 0 || n >= MAX_PATH) {
+template<size_t N> std::wstring_view getBrandPath(wchar_t (&path)[N])
+{
+ DWORD n = GetModuleFileNameW(nullptr, path, N);
+ if (n == 0 || n >= N) {
exit(EXIT_FAILURE);
}
- return tools::filename(path);
+ return { path, tools::filename(path) };
}
void writeNull() {
@@ -46,18 +45,13 @@ void writeNull() {
}
}
-void writePath(
- wchar_t const * frontBegin, wchar_t const * frontEnd,
- wchar_t const * backBegin, std::size_t backLength)
+void writePath(std::wstring_view front, std::wstring_view back)
{
- wchar_t path[MAX_PATH];
- wchar_t * end = tools::buildPath(
- path, frontBegin, frontEnd, backBegin, backLength);
- if (end == nullptr) {
+ std::wstring path = tools::buildPath(front, back);
+ if (path.empty()) {
exit(EXIT_FAILURE);
}
- std::size_t n = (end - path) * sizeof (wchar_t);
- if (fwrite(path, 1, n, stdout) != n) {
+ if (fwrite(path.data(), sizeof (wchar_t), path.size(), stdout) != path.size()) {
exit(EXIT_FAILURE);
}
}
@@ -65,19 +59,18 @@ void writePath(
}
int wmain(int argc, wchar_t ** argv, wchar_t **) {
+ wchar_t path_buf[EXTENDED_MAX_PATH];
if (argc == 2 && wcscmp(argv[1], L"c++") == 0) {
- wchar_t path[MAX_PATH];
- wchar_t * pathEnd = getBrandPath(path);
- writePath(path, pathEnd, MY_STRING(L""));
+ auto path = getBrandPath(path_buf);
+ writePath(path, L"");
} else if (argc == 2 && wcscmp(argv[1], L"java") == 0) {
if (fwrite("1", 1, 1, stdout) != 1) {
exit(EXIT_FAILURE);
}
- wchar_t path[MAX_PATH];
- wchar_t * pathEnd = getBrandPath(path);
- writePath(path, pathEnd, MY_STRING(L"classes\\libreoffice.jar"));
+ auto path = getBrandPath(path_buf);
+ writePath(path, L"classes\\libreoffice.jar");
writeNull();
- writePath(path, pathEnd, MY_STRING(L""));
+ writePath(path, L"");
} else {
exit(EXIT_FAILURE);
}