summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2018-01-10 17:50:43 +0100
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2018-01-23 13:38:46 +0100
commitecb5fcff336c8b0e5ad2503f0880c439a6c323a5 (patch)
tree74842b234a07f1c07340bdb50fcda97d1ee6bd8c
parentf811979b0865b15272ce4a62df3ebd0fa8896b55 (diff)
Introduce gtk3_kde5 vcl plugin
This is a hybrid plugin which mostly wraps the GTK3 vclplug. Only the file and folder picker are replaced by KDE dialogs. This gives us a well-maintained GTK LO base with basic KDE integration with minimum effort. To prevent issues with nested event loops, the KDE dialogs are launched from a separate process, the new lo_kde5filepicker helper executable. A trivial stdin/stdout IPC mechanism transfers the data between LO and the Qt/KDE helper. The usage of an external process also allows us to copy'n'paste between LO and the KDE file dialog without freezing the UI, as would happen when one would do this in-process. This is in general also the architecture applied by the kmozillahelper, which is used to integrate KDE file dialogs into Firefox. While the KDE dialog is shown, the GTK3 main window is disabled and close requests are ignored. The KDE dialog in turn also sets the LO window as transient parent. Together, this makes the illusion perfect and the KDE dialog behaves like a modal dialog. This works properly also with multiple LO main windows, and only individual windows will get blocked as one would expect. Functionality wise, most of the features of the KDE4 dialog are supported. You can pick files and folders, and save files under a new name. Some custom checkbox widgets are supported, but lists, buttons and preview widgets are not yet implemented. Also, loading remote files via KIO is not possible yet. Change-Id: I1a97cf7c272307a19ace4222d5f12253bc722829 Reviewed-on: https://gerrit.libreoffice.org/47718 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r--Repository.mk6
-rw-r--r--config_host.mk.in1
-rw-r--r--config_host/config_gtk3_kde5.h.in10
-rw-r--r--config_host/config_vclplug.h.in1
-rw-r--r--configure.ac31
-rw-r--r--vcl/CustomTarget_gtk3_kde5_moc.mk22
-rw-r--r--vcl/Executable_lo_kde5filepicker.mk99
-rw-r--r--vcl/Library_vclplug_gtk3_kde5.mk128
-rw-r--r--vcl/Module_vcl.mk7
-rw-r--r--vcl/unx/generic/plugadapt/salplug.cxx5
-rw-r--r--vcl/unx/gtk3_kde5/FPServiceInfo.hxx28
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkaction.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkbridge.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkcomponent.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkeditabletext.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkfactory.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkhypertext.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkimage.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atklistener.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkregistry.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkselection.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktable.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktext.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktextattributes.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkutil.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkvalue.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwindow.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwrapper.cxx12
-rw-r--r--vcl/unx/gtk3_kde5/filepicker_ipc_commands.hxx170
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_a11y.cxx38
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_cairo.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx456
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx139
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx201
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx109
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.cxx88
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.hxx61
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gloactiongroup.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_glomenu.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gtkframe.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx55
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gtkobject.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gtksalmenu.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_gtksys.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_hudawareness.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_printwrapper.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_salnativewidgets-gtk.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/gtk3_kde5_salprn-gtk.cxx22
-rw-r--r--vcl/unx/gtk3_kde5/kde5_filepicker.cxx283
-rw-r--r--vcl/unx/gtk3_kde5/kde5_filepicker.hxx113
-rw-r--r--vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx223
-rw-r--r--vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx45
-rw-r--r--vcl/unx/gtk3_kde5/kde5_lo_filepicker_main.cxx39
54 files changed, 2821 insertions, 5 deletions
diff --git a/Repository.mk b/Repository.mk
index 5e23d0d352cd..aa67702d1ce0 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -302,8 +302,14 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,kde, \
$(if $(ENABLE_KDE4),vclplug_kde4) \
$(if $(ENABLE_KDE5),vclplug_kde5) \
$(if $(ENABLE_QT5),vclplug_qt5) \
+ $(if $(ENABLE_GTK3_KDE5),vclplug_gtk3_kde5) \
) \
))
+ifneq ($(ENABLE_GTK3_KDE5),)
+$(eval $(call gb_Helper_register_executables_for_install,OOO,kde, \
+ lo_kde5filepicker \
+))
+endif
$(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,math, \
sm \
diff --git a/config_host.mk.in b/config_host.mk.in
index d5630a5b4537..8ce71275ca5c 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -158,6 +158,7 @@ export ENABLE_PDFIMPORT=@ENABLE_PDFIMPORT@
export ENABLE_PDFIUM=@ENABLE_PDFIUM@
export ENABLE_QT5=@ENABLE_QT5@
export ENABLE_KDE5=@ENABLE_KDE5@
+export ENABLE_GTK3_KDE5=@ENABLE_GTK3_KDE5@
export ENABLE_RANDR=@ENABLE_RANDR@
export ENABLE_RELEASE_BUILD=@ENABLE_RELEASE_BUILD@
export ENABLE_REPORTBUILDER=@ENABLE_REPORTBUILDER@
diff --git a/config_host/config_gtk3_kde5.h.in b/config_host/config_gtk3_kde5.h.in
new file mode 100644
index 000000000000..06c672d4bb69
--- /dev/null
+++ b/config_host/config_gtk3_kde5.h.in
@@ -0,0 +1,10 @@
+/*
+Settings for GTK3/KDE5 integration.
+*/
+
+#ifndef CONFIG_GTK3_KDE5_H
+#define CONFIG_GTK3_KDE5_H
+
+#define ENABLE_GTK3_KDE5 0
+
+#endif
diff --git a/config_host/config_vclplug.h.in b/config_host/config_vclplug.h.in
index b7b9624cdf79..be9c136245ee 100644
--- a/config_host/config_vclplug.h.in
+++ b/config_host/config_vclplug.h.in
@@ -10,5 +10,6 @@ Settings about which X11 desktops have support enabled.
#define ENABLE_GTK 0
#define ENABLE_KDE4 0
#define ENABLE_KDE5 0
+#define ENABLE_GTK3_KDE5 0
#endif
diff --git a/configure.ac b/configure.ac
index ce9b28feba0f..80ec735478a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -595,6 +595,7 @@ linux-gnu*|k*bsd*-gnu*)
test_kde4=yes
test_kde5=yes
test_qt5=yes
+ test_gtk3_kde5=yes
if test "$enable_fuzzers" != yes; then
test_freetype=yes
test_fontconfig=yes
@@ -691,6 +692,7 @@ freebsd*)
test_kde4=yes
test_kde5=yes
test_qt5=yes
+ test_gtk3_kde5=yes
test_freetype=yes
AC_MSG_CHECKING([the FreeBSD operating system release])
if test -n "$with_os_version"; then
@@ -721,6 +723,7 @@ freebsd*)
test_kde4=yes
test_kde5=yes
test_qt5=yes
+ test_gtk3_kde5=yes
test_freetype=yes
PTHREAD_LIBS="-pthread -lpthread"
_os=NetBSD
@@ -748,6 +751,7 @@ dragonfly*)
test_kde4=yes
test_kde5=yes
test_qt5=yes
+ test_gtk3_kde5=yes
test_freetype=yes
PTHREAD_LIBS="-pthread"
_os=DragonFly
@@ -773,6 +777,7 @@ linux-android*)
test_kde4=no
test_kde5=no
test_qt5=no
+ test_gtk3_kde5=no
test_randr=no
test_xrender=no
_os=Android
@@ -1227,6 +1232,12 @@ AC_ARG_ENABLE(kde5,
KF5 are available.]),
,)
+AC_ARG_ENABLE(gtk3_kde5,
+ AS_HELP_STRING([--enable-gtk3-kde5],
+ [Determines whether to use Gtk3 vclplug with KDE file dialogs on
+ platforms where Gtk3, Qt5 and Plasma is available.]),
+,)
+
libo_FUZZ_ARG_ENABLE(gui,
AS_HELP_STRING([--disable-gui],
[Disable use of X11 or Wayland to reduce dependencies. Not related to the --headless
@@ -4542,6 +4553,7 @@ if test "$USING_X11" != TRUE; then
test_kde4=no
test_kde5=no
test_qt5=no
+ test_gtk3_kde5=no
enable_cairo_canvas=no
fi
@@ -9797,6 +9809,14 @@ if test "x$enable_kde5" = "xyes"; then
fi
AC_SUBST(ENABLE_KDE5)
+ENABLE_GTK3_KDE5=""
+if test "x$enable_gtk3_kde5" = "xyes"; then
+ ENABLE_GTK3_KDE5="TRUE"
+ AC_DEFINE(ENABLE_GTK3_KDE5)
+ R="$R gtk3_kde5"
+fi
+AC_SUBST(ENABLE_GTK3_KDE5)
+
build_vcl_plugins="$R"
if test -z "$build_vcl_plugins"; then
build_vcl_plugins="none"
@@ -10804,7 +10824,8 @@ QT5_GLIB_CFLAGS=""
QT5_GLIB_LIBS=""
QT5_HAVE_GLIB=""
if test \( "$test_kde5" = "yes" -a "$ENABLE_KDE5" = "TRUE" \) -o \
- \( "$test_qt5" = "yes" -a "$ENABLE_QT5" = "TRUE" \)
+ \( "$test_qt5" = "yes" -a "$ENABLE_QT5" = "TRUE" \) -o \
+ \( "$test_gtk3_kde5" = "yes" -a "$ENABLE_GTK3_KDE5" = "TRUE" \)
then
qt5_incdirs="$QT5INC /usr/include/qt5 /usr/include $x_includes"
qt5_libdirs="$QT5LIB /usr/lib/qt5 /usr/lib $x_libraries"
@@ -10892,7 +10913,8 @@ KF5_CFLAGS=""
KF5_LIBS=""
KF5_CONFIG="kf5-config"
if test \( "$test_kde5" = "yes" -a "$ENABLE_KDE5" = "TRUE" \) -o \
- \( "$test_kf5" = "yes" -a "$ENABLE_KF5" = "TRUE" \)
+ \( "$test_kf5" = "yes" -a "$ENABLE_KF5" = "TRUE" \) -o \
+ \( "$test_gtk3_kde5" = "yes" -a "$ENABLE_GTK3_KDE5" = "TRUE" \)
then
kf5_incdirs="$KF5INC /usr/include/ $x_includes"
kf5_libdirs="$KF5LIB /usr/lib /usr/lib/kf5 /usr/lib/kf5/devel $x_libraries"
@@ -10942,8 +10964,8 @@ then
PKG_CHECK_MODULES(KF5_XCB,[xcb],,[AC_MSG_ERROR([XCB not installed])])
- KF5_CFLAGS="-I$kf5_incdir -I$kf5_incdir/KCoreAddons -I$kf5_incdir/KI18n -I$kf5_incdir/KConfigCore -I$kf5_incdir/KWindowSystem -I$kf5_incdir/KIOCore -I$qt5_incdir -I$qt5_incdir/QtCore -I$qt5_incdir/QtGui -I$qt5_incdir/QtWidgets -I$qt5_incdir/QtNetwork -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT $KF5_XCB_CFLAGS"
- KF5_LIBS="-L$kf5_libdir -lKF5CoreAddons -lKF5I18n -lKF5ConfigCore -lKF5WindowSystem -lKF5KIOCore -L$qt5_libdir -lQt5Core -lQt5Gui -lQt5Widgets -lQt5Network -lQt5X11Extras $KF5_XCB_LIBS"
+ KF5_CFLAGS="-I$kf5_incdir -I$kf5_incdir/KCoreAddons -I$kf5_incdir/KI18n -I$kf5_incdir/KConfigCore -I$kf5_incdir/KWindowSystem -I$kf5_incdir/KIOCore -I$kf5_incdir/KIOWidgets -I$kf5_incdir/KIOFileWidgets -I$qt5_incdir -I$qt5_incdir/QtCore -I$qt5_incdir/QtGui -I$qt5_incdir/QtWidgets -I$qt5_incdir/QtNetwork -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT $KF5_XCB_CFLAGS"
+ KF5_LIBS="-L$kf5_libdir -lKF5CoreAddons -lKF5I18n -lKF5ConfigCore -lKF5WindowSystem -lKF5KIOCore -lKF5KIOWidgets -lKF5KIOFileWidgets -L$qt5_libdir -lQt5Core -lQt5Gui -lQt5Widgets -lQt5Network -lQt5X11Extras $KF5_XCB_LIBS"
KF5_CFLAGS=$(printf '%s' "$KF5_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
AC_LANG_PUSH([C++])
@@ -12513,6 +12535,7 @@ AC_CONFIG_HEADERS([config_host/config_mpl.h])
AC_CONFIG_HEADERS([config_host/config_kde4.h])
AC_CONFIG_HEADERS([config_host/config_qt5.h])
AC_CONFIG_HEADERS([config_host/config_kde5.h])
+AC_CONFIG_HEADERS([config_host/config_gtk3_kde5.h])
AC_CONFIG_HEADERS([config_host/config_oox.h])
AC_CONFIG_HEADERS([config_host/config_options.h])
AC_CONFIG_HEADERS([config_host/config_options_calc.h])
diff --git a/vcl/CustomTarget_gtk3_kde5_moc.mk b/vcl/CustomTarget_gtk3_kde5_moc.mk
new file mode 100644
index 000000000000..42f7edbe5105
--- /dev/null
+++ b/vcl/CustomTarget_gtk3_kde5_moc.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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_CustomTarget_CustomTarget,vcl/unx/gtk3_kde5))
+
+$(call gb_CustomTarget_get_target,vcl/unx/gtk3_kde5) : \
+ $(call gb_CustomTarget_get_workdir,vcl/unx/gtk3_kde5)/kde5_filepicker.moc \
+ $(call gb_CustomTarget_get_workdir,vcl/unx/gtk3_kde5)/kde5_filepicker_ipc.moc \
+
+$(call gb_CustomTarget_get_workdir,vcl/unx/gtk3_kde5)/%.moc : \
+ $(SRCDIR)/vcl/unx/gtk3_kde5/%.hxx \
+ | $(call gb_CustomTarget_get_workdir,vcl/unx/gtk3_kde5)/.dir
+ $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),MOC,1)
+ $(MOC5) $< -o $@
+
+# vim: set noet sw=4:
diff --git a/vcl/Executable_lo_kde5filepicker.mk b/vcl/Executable_lo_kde5filepicker.mk
new file mode 100644
index 000000000000..2eee2cd8711b
--- /dev/null
+++ b/vcl/Executable_lo_kde5filepicker.mk
@@ -0,0 +1,99 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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 .
+#
+
+$(eval $(call gb_Executable_Executable,lo_kde5filepicker))
+
+# FIXME: how to find the moc files automatically?!
+$(eval $(call gb_Executable_set_include,lo_kde5filepicker,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/vcl/inc \
+ -I$(WORKDIR)/CustomTarget/vcl/unx/gtk3_kde5 \
+))
+
+$(eval $(call gb_Executable_add_cxxflags,lo_kde5filepicker,\
+ $$(INCLUDE) \
+ $$(BOOST_CXXFLAGS) \
+))
+
+$(eval $(call gb_Executable_use_custom_headers,lo_kde5filepicker,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_Executable_use_sdk_api,lo_kde5filepicker))
+
+$(eval $(call gb_Executable_add_libs,lo_kde5filepicker,\
+ -lX11 \
+ -lXext \
+ -lSM \
+ -lICE \
+))
+
+$(eval $(call gb_Executable_use_libraries,lo_kde5filepicker,\
+ vclplug_gen \
+ vcl \
+ tl \
+ utl \
+ sot \
+ ucbhelper \
+ basegfx \
+ comphelper \
+ cppuhelper \
+ i18nlangtag \
+ i18nutil \
+ $(if $(ENABLE_JAVA), \
+ jvmaccess) \
+ cppu \
+ sal \
+))
+
+$(eval $(call gb_Executable_use_externals,lo_kde5filepicker,\
+ boost_headers \
+ epoxy \
+ kde5 \
+ dbus \
+))
+
+$(eval $(call gb_Executable_add_defs,lo_kde5filepicker,\
+ $(QT5_CFLAGS) \
+ $(QT5_GLIB_CFLAGS) \
+ $(KF5_CFLAGS) \
+))
+$(eval $(call gb_Executable_add_libs,lo_kde5filepicker,\
+ $(QT5_LIBS) \
+ $(QT5_GLIB_LIBS) \
+ $(KF5_LIBS) \
+ $(BOOST_PROCESS_LIB) \
+ $(BOOST_FILESYSTEM_LIB) \
+))
+
+$(eval $(call gb_Executable_add_exception_objects,lo_kde5filepicker,\
+ vcl/unx/gtk3_kde5/kde5_lo_filepicker_main \
+ vcl/unx/gtk3_kde5/kde5_filepicker \
+ vcl/unx/gtk3_kde5/kde5_filepicker_ipc \
+))
+
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Executable_add_libs,lo_kde5filepicker,\
+ -lm \
+ -ldl \
+ -lpthread \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vclplug_gtk3_kde5.mk b/vcl/Library_vclplug_gtk3_kde5.mk
new file mode 100644
index 000000000000..eaff74cad35c
--- /dev/null
+++ b/vcl/Library_vclplug_gtk3_kde5.mk
@@ -0,0 +1,128 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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 .
+#
+
+$(eval $(call gb_Library_Library,vclplug_gtk3_kde5))
+
+# Silence deprecation warnings wholesale as long as vcl/unx/gtk3/*.cxx just
+# forward to vcl/unx/gtk/*.cxx:
+$(eval $(call gb_Library_add_cxxflags,vclplug_gtk3_kde5, \
+ -Wno-deprecated-declarations \
+))
+
+$(eval $(call gb_Library_set_include,vclplug_gtk3_kde5,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/vcl/inc \
+ -I$(SRCDIR)/vcl/unx \
+ -I$(SRCDIR)/vcl/unx/gtk3 \
+))
+
+$(eval $(call gb_Library_add_cxxflags,vclplug_gtk3_kde5,\
+ $$(INCLUDE) \
+ $$(GTK3_CFLAGS) \
+))
+
+$(eval $(call gb_Library_add_defs,vclplug_gtk3_kde5,\
+ -DVCLPLUG_GTK_IMPLEMENTATION -DVCLPLUG_GTK3_KDE5_IMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_use_custom_headers,vclplug_gtk3_kde5,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_Library_use_sdk_api,vclplug_gtk3_kde5))
+
+$(eval $(call gb_Library_add_libs,vclplug_gtk3_kde5,\
+ $(GTK3_LIBS) \
+ $(GTHREAD_LIBS) \
+ -lX11 \
+ -lXext \
+ -lSM \
+ -lICE \
+))
+
+$(eval $(call gb_Library_use_libraries,vclplug_gtk3_kde5,\
+ vclplug_gen \
+ vcl \
+ tl \
+ utl \
+ sot \
+ ucbhelper \
+ basegfx \
+ comphelper \
+ cppuhelper \
+ i18nlangtag \
+ i18nutil \
+ $(if $(ENABLE_JAVA), \
+ jvmaccess) \
+ cppu \
+ sal \
+))
+
+$(eval $(call gb_Library_use_externals,vclplug_gtk3_kde5,\
+ boost_headers \
+ boost_filesystem \
+ epoxy \
+ dbus \
+))
+
+$(eval $(call gb_Library_add_exception_objects,vclplug_gtk3_kde5,\
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkaction \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkbridge \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkcomponent \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkeditabletext \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkfactory \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkhypertext \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkimage \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atklistener \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkregistry \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkselection \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktable \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktextattributes \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktext \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkutil \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkvalue \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwindow \
+ vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwrapper \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gtksys \
+ vcl/unx/gtk3_kde5/gtk3_kde5_filepicker \
+ vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc \
+ vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker \
+ vcl/unx/gtk3_kde5/gtk3_kde5_cairo \
+ vcl/unx/gtk3_kde5/gtk3_kde5_printwrapper \
+ vcl/unx/gtk3_kde5/gtk3_kde5_salnativewidgets-gtk \
+ vcl/unx/gtk3_kde5/gtk3_kde5_salprn-gtk \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gtkframe \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gtkobject \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gtksalmenu \
+ vcl/unx/gtk3_kde5/gtk3_kde5_glomenu \
+ vcl/unx/gtk3_kde5/gtk3_kde5_gloactiongroup \
+ vcl/unx/gtk3_kde5/gtk3_kde5_hudawareness \
+))
+
+ifeq ($(OS),LINUX)
+$(eval $(call gb_Library_add_libs,vclplug_gtk3_kde5,\
+ -lm \
+ -ldl \
+ -lpthread \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index bf83a8a442c3..7d3bfb5d77b3 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -94,6 +94,13 @@ $(eval $(call gb_Module_add_targets,vcl,\
Library_vclplug_qt5 \
))
endif
+ifneq ($(ENABLE_GTK3_KDE5),)
+$(eval $(call gb_Module_add_targets,vcl,\
+ CustomTarget_gtk3_kde5_moc \
+ Library_vclplug_gtk3_kde5 \
+ Executable_lo_kde5filepicker \
+))
+endif
endif
ifeq ($(OS),MACOSX)
diff --git a/vcl/unx/generic/plugadapt/salplug.cxx b/vcl/unx/generic/plugadapt/salplug.cxx
index c76077a776b4..b7ed29a22f5d 100644
--- a/vcl/unx/generic/plugadapt/salplug.cxx
+++ b/vcl/unx/generic/plugadapt/salplug.cxx
@@ -99,7 +99,7 @@ static SalInstance* tryInstance( const OUString& rModuleBase, bool bForce = fals
* #i109007# KDE3 seems to have the same problem.
* And same applies for KDE4.
*/
- if( rModuleBase == "gtk" || rModuleBase == "gtk3" || rModuleBase == "kde4" )
+ if( rModuleBase == "gtk" || rModuleBase == "gtk3" || rModuleBase == "kde4" || rModuleBase == "gtk3_kde5")
{
pCloseModule = nullptr;
}
@@ -163,6 +163,9 @@ static SalInstance* autodetect_plugin()
{
static const char* const pKDEFallbackList[] =
{
+#if ENABLE_GTK3_KDE5
+ "gtk3_kde5",
+#endif
#if ENABLE_KDE4
"kde4",
#endif
diff --git a/vcl/unx/gtk3_kde5/FPServiceInfo.hxx b/vcl/unx/gtk3_kde5/FPServiceInfo.hxx
new file mode 100644
index 000000000000..1fbb8fd276b2
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/FPServiceInfo.hxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+// the service names
+#define FILE_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.Gtk3KDE5FilePicker"
+
+// the implementation names
+#define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.Gtk3KDE5FilePicker"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkaction.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkaction.cxx
new file mode 100644
index 000000000000..a3fa632d08a1
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkaction.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkaction.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkbridge.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkbridge.cxx
new file mode 100644
index 000000000000..d8e087956067
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkbridge.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkbridge.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkcomponent.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkcomponent.cxx
new file mode 100644
index 000000000000..e4eabec20fb8
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkcomponent.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkcomponent.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkeditabletext.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkeditabletext.cxx
new file mode 100644
index 000000000000..ea3f0895fb8e
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkeditabletext.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkeditabletext.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkfactory.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkfactory.cxx
new file mode 100644
index 000000000000..c60db2fcc074
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkfactory.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkfactory.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkhypertext.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkhypertext.cxx
new file mode 100644
index 000000000000..bb9749c36af3
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkhypertext.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkhypertext.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkimage.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkimage.cxx
new file mode 100644
index 000000000000..4e2c77e9f2b1
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkimage.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkimage.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atklistener.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atklistener.cxx
new file mode 100644
index 000000000000..eca1cd7ec1d0
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atklistener.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atklistener.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkregistry.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkregistry.cxx
new file mode 100644
index 000000000000..126e97a808ae
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkregistry.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkregistry.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkselection.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkselection.cxx
new file mode 100644
index 000000000000..f67b665304d7
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkselection.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkselection.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktable.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktable.cxx
new file mode 100644
index 000000000000..d886ac07296a
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktable.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atktable.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktext.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktext.cxx
new file mode 100644
index 000000000000..e4bbd5a38980
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktext.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atktext.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktextattributes.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktextattributes.cxx
new file mode 100644
index 000000000000..b0edad06a65c
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atktextattributes.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atktextattributes.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkutil.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkutil.cxx
new file mode 100644
index 000000000000..8c1eeaf9882b
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkutil.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkutil.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkvalue.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkvalue.cxx
new file mode 100644
index 000000000000..30057943bc44
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkvalue.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkvalue.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwindow.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwindow.cxx
new file mode 100644
index 000000000000..cd8479cd4df7
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwindow.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkwindow.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwrapper.cxx b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwrapper.cxx
new file mode 100644
index 000000000000..3b07e9536d77
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/a11y/gtk3_kde5_atkwrapper.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "../../gtk/a11y/atkwrapper.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/filepicker_ipc_commands.hxx b/vcl/unx/gtk3_kde5/filepicker_ipc_commands.hxx
new file mode 100644
index 000000000000..3aef6da858b1
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/filepicker_ipc_commands.hxx
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <iostream>
+#include <vector>
+
+#include <sal/types.h>
+#include <com/sun/star/uno/Sequence.hxx>
+
+// #define DEBUG_FILEPICKER_IPC
+
+namespace rtl
+{
+class OUString;
+}
+class QString;
+
+enum class Commands : uint16_t
+{
+ SetTitle,
+ SetWinId,
+ Execute,
+ SetMultiSelectionMode,
+ SetDefaultName,
+ SetDisplayDirectory,
+ GetDisplayDirectory,
+ GetSelectedFiles,
+ AppendFilter,
+ SetCurrentFilter,
+ GetCurrentFilter,
+ SetValue,
+ GetValue,
+ EnableControl,
+ SetLabel,
+ GetLabel,
+ AddCheckBox,
+ Initialize,
+ Quit,
+ EnablePickFolderMode,
+};
+
+inline std::vector<char> readIpcStringArg(std::istream& stream)
+{
+ uint32_t length = 0;
+ stream >> length;
+ stream.ignore(); // skip space separator
+ std::vector<char> buffer(length, '\0');
+ stream.read(buffer.data(), length);
+ return buffer;
+}
+
+void readIpcArg(std::istream& stream, rtl::OUString& string);
+void readIpcArg(std::istream& stream, QString& string);
+void readIpcArg(std::istream& stream, css::uno::Sequence<rtl::OUString>& seq);
+
+inline void readIpcArg(std::istream& stream, Commands& value)
+{
+ uint16_t v = 0;
+ stream >> v;
+ stream.ignore(); // skip space
+ value = static_cast<Commands>(v);
+}
+
+inline void readIpcArg(std::istream& stream, sal_Bool& value)
+{
+ bool v = false;
+ stream >> v;
+ value = v;
+ stream.ignore(); // skip space
+}
+
+inline void readIpcArg(std::istream& stream, bool& value)
+{
+ stream >> value;
+ stream.ignore(); // skip space
+}
+
+inline void readIpcArg(std::istream& stream, sal_Int16& value)
+{
+ stream >> value;
+ stream.ignore(); // skip space
+}
+
+inline void readIpcArg(std::istream& stream, sal_uIntPtr& value)
+{
+ stream >> value;
+ stream.ignore(); // skip space
+}
+
+inline void readIpcArgs(std::istream& /*stream*/)
+{
+ // end of arguments, nothing to do
+}
+
+template <typename T, typename... Args>
+inline void readIpcArgs(std::istream& stream, T& arg, Args&... args)
+{
+ readIpcArg(stream, arg);
+ readIpcArgs(stream, args...);
+}
+
+void sendIpcArg(std::ostream& stream, const rtl::OUString& string);
+void sendIpcArg(std::ostream& stream, const QString& string);
+
+inline void sendIpcStringArg(std::ostream& stream, uint32_t length, const char* string)
+{
+ stream << length << ' ';
+ stream.write(string, length);
+ stream << ' ';
+}
+
+inline void sendIpcArg(std::ostream& stream, Commands value)
+{
+ stream << static_cast<uint16_t>(value) << ' ';
+}
+
+inline void sendIpcArg(std::ostream& stream, sal_Bool value)
+{
+ stream << static_cast<bool>(value) << ' ';
+}
+
+inline void sendIpcArg(std::ostream& stream, bool value) { stream << value << ' '; }
+
+inline void sendIpcArg(std::ostream& stream, sal_Int16 value) { stream << value << ' '; }
+
+inline void sendIpcArg(std::ostream& stream, sal_uIntPtr value) { stream << value << ' '; }
+
+inline void sendIpcArgsImpl(std::ostream& stream)
+{
+ // end of arguments, flush stream
+ stream << std::endl;
+}
+
+template <typename T, typename... Args>
+inline void sendIpcArgsImpl(std::ostream& stream, const T& arg, const Args&... args)
+{
+ sendIpcArg(stream, arg);
+ sendIpcArgsImpl(stream, args...);
+}
+
+template <typename T, typename... Args>
+inline void sendIpcArgs(std::ostream& stream, const T& arg, const Args&... args)
+{
+ sendIpcArgsImpl(stream, arg, args...);
+#ifdef DEBUG_FILEPICKER_IPC
+ std::cerr << "IPC MSG: ";
+ sendIpcArgsImpl(std::cerr, arg, args...);
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_a11y.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_a11y.cxx
new file mode 100644
index 000000000000..02fd47a60d63
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_a11y.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/a11y/gtk3atkaction.cxx"
+#include "../gtk3/a11y/gtk3atkbridge.cxx"
+#include "../gtk3/a11y/gtk3atkcomponent.cxx"
+#include "../gtk3/a11y/gtk3atkeditabletext.cxx"
+#include "../gtk3/a11y/gtk3atkfactory.cxx"
+#include "../gtk3/a11y/gtk3atkhypertext.cxx"
+#include "../gtk3/a11y/gtk3atkimage.cxx"
+#include "../gtk3/a11y/gtk3atklistener.cxx"
+#include "../gtk3/a11y/gtk3atkregistry.cxx"
+#include "../gtk3/a11y/gtk3atkselection.cxx"
+#include "../gtk3/a11y/gtk3atktable.cxx"
+#include "../gtk3/a11y/gtk3atktextattributes.cxx"
+#include "../gtk3/a11y/gtk3atktext.cxx"
+#include "../gtk3/a11y/gtk3atkutil.cxx"
+#include "../gtk3/a11y/gtk3atkvalue.cxx"
+#include "../gtk3/a11y/gtk3atkwindow.cxx"
+#include "../gtk3/a11y/gtk3atkwrapper.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_cairo.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_cairo.cxx
new file mode 100644
index 000000000000..fc271f160e7f
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_cairo.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/cairo_gtk3_cairo.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx
new file mode 100644
index 000000000000..28c0af2047aa
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.cxx
@@ -0,0 +1,456 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "gtk3_kde5_filepicker.hxx"
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ControlActions.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <osl/mutex.hxx>
+
+#include <fpicker/strings.hrc>
+
+#include "FPServiceInfo.hxx"
+
+#undef Region
+
+#include "unx/geninst.h"
+
+#include "strings.hrc"
+
+#include <future>
+
+#include <boost/filesystem/path.hpp>
+#include <boost/process/environment.hpp>
+#include <boost/process/search_path.hpp>
+#include <boost/process/io.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
+using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
+using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+namespace bp = boost::process;
+namespace bf = boost::filesystem;
+
+// helper functions
+
+namespace
+{
+uno::Sequence<OUString> SAL_CALL FilePicker_getSupportedServiceNames()
+{
+ uno::Sequence<OUString> aRet(3);
+ aRet[0] = "com.sun.star.ui.dialogs.FilePicker";
+ aRet[1] = "com.sun.star.ui.dialogs.SystemFilePicker";
+ aRet[2] = "com.sun.star.ui.dialogs.Gtk3KDE5FilePicker";
+ return aRet;
+}
+}
+
+// Gtk3KDE5FilePicker
+
+Gtk3KDE5FilePicker::Gtk3KDE5FilePicker(const uno::Reference<uno::XComponentContext>&)
+ : Gtk3KDE5FilePicker_Base(_helperMutex)
+{
+ setMultiSelectionMode(false);
+}
+
+Gtk3KDE5FilePicker::~Gtk3KDE5FilePicker() = default;
+
+void SAL_CALL
+Gtk3KDE5FilePicker::addFilePickerListener(const uno::Reference<XFilePickerListener>& xListener)
+{
+ SolarMutexGuard aGuard;
+ m_xListener = xListener;
+}
+
+void SAL_CALL
+Gtk3KDE5FilePicker::removeFilePickerListener(const uno::Reference<XFilePickerListener>&)
+{
+ SolarMutexGuard aGuard;
+ m_xListener.clear();
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::setTitle(const OUString& title)
+{
+ m_ipc.sendCommand(Commands::SetTitle, title);
+}
+
+sal_Int16 SAL_CALL Gtk3KDE5FilePicker::execute() { return m_ipc.execute(); }
+
+void SAL_CALL Gtk3KDE5FilePicker::setMultiSelectionMode(sal_Bool multiSelect)
+{
+ m_ipc.sendCommand(Commands::SetMultiSelectionMode, multiSelect);
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::setDefaultName(const OUString& name)
+{
+ m_ipc.sendCommand(Commands::SetDefaultName, name);
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::setDisplayDirectory(const OUString& dir)
+{
+ m_ipc.sendCommand(Commands::SetDisplayDirectory, dir);
+}
+
+OUString SAL_CALL Gtk3KDE5FilePicker::getDisplayDirectory()
+{
+ auto id = m_ipc.sendCommand(Commands::GetDisplayDirectory);
+ OUString dir;
+ m_ipc.readResponse(id, dir);
+ return dir;
+}
+
+uno::Sequence<OUString> SAL_CALL Gtk3KDE5FilePicker::getFiles()
+{
+ uno::Sequence<OUString> seq = getSelectedFiles();
+ if (seq.getLength() > 1)
+ seq.realloc(1);
+ return seq;
+}
+
+uno::Sequence<OUString> SAL_CALL Gtk3KDE5FilePicker::getSelectedFiles()
+{
+ auto id = m_ipc.sendCommand(Commands::GetSelectedFiles);
+ uno::Sequence<OUString> seq;
+ m_ipc.readResponse(id, seq);
+ return seq;
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::appendFilter(const OUString& title, const OUString& filter)
+{
+ m_ipc.sendCommand(Commands::AppendFilter, title, filter);
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::setCurrentFilter(const OUString& title)
+{
+ m_ipc.sendCommand(Commands::SetCurrentFilter, title);
+}
+
+OUString SAL_CALL Gtk3KDE5FilePicker::getCurrentFilter()
+{
+ auto id = m_ipc.sendCommand(Commands::GetCurrentFilter);
+ OUString filter;
+ m_ipc.readResponse(id, filter);
+ return filter;
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::appendFilterGroup(const OUString& /*rGroupTitle*/,
+ const uno::Sequence<beans::StringPair>& filters)
+{
+ const sal_uInt16 length = filters.getLength();
+ for (sal_uInt16 i = 0; i < length; ++i)
+ {
+ beans::StringPair aPair = filters[i];
+ appendFilter(aPair.First, aPair.Second);
+ }
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::setValue(sal_Int16 controlId, sal_Int16 nControlAction,
+ const uno::Any& value)
+{
+ if (value.has<sal_Bool>())
+ {
+ m_ipc.sendCommand(Commands::SetValue, controlId, nControlAction, value.get<sal_Bool>());
+ }
+ else
+ {
+ OSL_TRACE("set value of unhandled type %d", controlId);
+ }
+}
+
+uno::Any SAL_CALL Gtk3KDE5FilePicker::getValue(sal_Int16 controlId, sal_Int16 nControlAction)
+{
+ if (CHECKBOX_AUTOEXTENSION == controlId)
+ // We ignore this one and rely on QFileDialog to provide the function.
+ // Always return false, to pretend we do not support this, otherwise
+ // LO core would try to be smart and cut the extension in some places,
+ // interfering with QFileDialog's handling of it. QFileDialog also
+ // saves the value of the setting, so LO core is not needed for that either.
+ return uno::Any(false);
+
+ auto id = m_ipc.sendCommand(Commands::GetValue, controlId, nControlAction);
+
+ sal_Bool value = false;
+ m_ipc.readResponse(id, value);
+
+ return uno::Any(value);
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::enableControl(sal_Int16 controlId, sal_Bool enable)
+{
+ m_ipc.sendCommand(Commands::EnableControl, controlId, enable);
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::setLabel(sal_Int16 controlId, const OUString& label)
+{
+ m_ipc.sendCommand(Commands::SetLabel, controlId, label);
+}
+
+OUString SAL_CALL Gtk3KDE5FilePicker::getLabel(sal_Int16 controlId)
+{
+ auto id = m_ipc.sendCommand(Commands::GetLabel, controlId);
+ OUString label;
+ m_ipc.readResponse(id, label);
+ return label;
+}
+
+void Gtk3KDE5FilePicker::addCustomControl(sal_Int16 controlId)
+{
+ const char* resId = nullptr;
+
+ switch (controlId)
+ {
+ case CHECKBOX_AUTOEXTENSION:
+ resId = STR_FPICKER_AUTO_EXTENSION;
+ break;
+ case CHECKBOX_PASSWORD:
+ resId = STR_FPICKER_PASSWORD;
+ break;
+ case CHECKBOX_FILTEROPTIONS:
+ resId = STR_FPICKER_FILTER_OPTIONS;
+ break;
+ case CHECKBOX_READONLY:
+ resId = STR_FPICKER_READONLY;
+ break;
+ case CHECKBOX_LINK:
+ resId = STR_FPICKER_INSERT_AS_LINK;
+ break;
+ case CHECKBOX_PREVIEW:
+ resId = STR_FPICKER_SHOW_PREVIEW;
+ break;
+ case CHECKBOX_SELECTION:
+ resId = STR_FPICKER_SELECTION;
+ break;
+ case CHECKBOX_GPGENCRYPTION:
+ resId = STR_FPICKER_GPGENCRYPT;
+ break;
+ case PUSHBUTTON_PLAY:
+ resId = STR_FPICKER_PLAY;
+ break;
+ case LISTBOX_VERSION:
+ resId = STR_FPICKER_VERSION;
+ break;
+ case LISTBOX_TEMPLATE:
+ resId = STR_FPICKER_TEMPLATES;
+ break;
+ case LISTBOX_IMAGE_TEMPLATE:
+ resId = STR_FPICKER_IMAGE_TEMPLATE;
+ break;
+ case LISTBOX_VERSION_LABEL:
+ case LISTBOX_TEMPLATE_LABEL:
+ case LISTBOX_IMAGE_TEMPLATE_LABEL:
+ case LISTBOX_FILTER_SELECTOR:
+ break;
+ }
+
+ switch (controlId)
+ {
+ case CHECKBOX_AUTOEXTENSION:
+ case CHECKBOX_PASSWORD:
+ case CHECKBOX_FILTEROPTIONS:
+ case CHECKBOX_READONLY:
+ case CHECKBOX_LINK:
+ case CHECKBOX_PREVIEW:
+ case CHECKBOX_SELECTION:
+ case CHECKBOX_GPGENCRYPTION:
+ {
+ // the checkbox is created even for CHECKBOX_AUTOEXTENSION to simplify
+ // code, but the checkbox is hidden and ignored
+ sal_Bool hidden = controlId == CHECKBOX_AUTOEXTENSION;
+
+ m_ipc.sendCommand(Commands::AddCheckBox, controlId, hidden, getResString(resId));
+
+ break;
+ }
+ case PUSHBUTTON_PLAY:
+ case LISTBOX_VERSION:
+ case LISTBOX_TEMPLATE:
+ case LISTBOX_IMAGE_TEMPLATE:
+ case LISTBOX_VERSION_LABEL:
+ case LISTBOX_TEMPLATE_LABEL:
+ case LISTBOX_IMAGE_TEMPLATE_LABEL:
+ case LISTBOX_FILTER_SELECTOR:
+ break;
+ }
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::initialize(const uno::Sequence<uno::Any>& args)
+{
+ // parameter checking
+ uno::Any arg;
+ if (args.getLength() == 0)
+ {
+ throw lang::IllegalArgumentException(OUString("no arguments"),
+ static_cast<XFilePicker2*>(this), 1);
+ }
+
+ arg = args[0];
+
+ if ((arg.getValueType() != cppu::UnoType<sal_Int16>::get())
+ && (arg.getValueType() != cppu::UnoType<sal_Int8>::get()))
+ {
+ throw lang::IllegalArgumentException(OUString("invalid argument type"),
+ static_cast<XFilePicker2*>(this), 1);
+ }
+
+ sal_Int16 templateId = -1;
+ arg >>= templateId;
+
+ sal_Bool saveDialog = false;
+ switch (templateId)
+ {
+ case FILEOPEN_SIMPLE:
+ break;
+
+ case FILESAVE_SIMPLE:
+ saveDialog = true;
+ break;
+
+ case FILESAVE_AUTOEXTENSION:
+ saveDialog = true;
+ addCustomControl(CHECKBOX_AUTOEXTENSION);
+ break;
+
+ case FILESAVE_AUTOEXTENSION_PASSWORD:
+ {
+ saveDialog = true;
+ addCustomControl(CHECKBOX_PASSWORD);
+ addCustomControl(CHECKBOX_GPGENCRYPTION);
+ break;
+ }
+ case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
+ {
+ saveDialog = true;
+ addCustomControl(CHECKBOX_AUTOEXTENSION);
+ addCustomControl(CHECKBOX_PASSWORD);
+ addCustomControl(CHECKBOX_GPGENCRYPTION);
+ addCustomControl(CHECKBOX_FILTEROPTIONS);
+ break;
+ }
+ case FILESAVE_AUTOEXTENSION_SELECTION:
+ saveDialog = true;
+ addCustomControl(CHECKBOX_AUTOEXTENSION);
+ addCustomControl(CHECKBOX_SELECTION);
+ break;
+
+ case FILESAVE_AUTOEXTENSION_TEMPLATE:
+ saveDialog = true;
+ addCustomControl(CHECKBOX_AUTOEXTENSION);
+ addCustomControl(LISTBOX_TEMPLATE);
+ break;
+
+ case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
+ addCustomControl(CHECKBOX_LINK);
+ addCustomControl(CHECKBOX_PREVIEW);
+ addCustomControl(LISTBOX_IMAGE_TEMPLATE);
+ break;
+
+ case FILEOPEN_PLAY:
+ addCustomControl(PUSHBUTTON_PLAY);
+ break;
+
+ case FILEOPEN_LINK_PLAY:
+ addCustomControl(CHECKBOX_LINK);
+ addCustomControl(PUSHBUTTON_PLAY);
+ break;
+
+ case FILEOPEN_READONLY_VERSION:
+ addCustomControl(CHECKBOX_READONLY);
+ addCustomControl(LISTBOX_VERSION);
+ break;
+
+ case FILEOPEN_LINK_PREVIEW:
+ addCustomControl(CHECKBOX_LINK);
+ addCustomControl(CHECKBOX_PREVIEW);
+ break;
+
+ case FILEOPEN_PREVIEW:
+ addCustomControl(CHECKBOX_PREVIEW);
+ break;
+
+ default:
+ OSL_TRACE("Unknown templates %d", templateId);
+ return;
+ }
+
+ setTitle(getResString(saveDialog ? STR_FPICKER_SAVE : STR_FPICKER_OPEN));
+
+ m_ipc.sendCommand(Commands::Initialize, saveDialog);
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::cancel()
+{
+ // TODO
+}
+
+void SAL_CALL Gtk3KDE5FilePicker::disposing(const lang::EventObject& rEvent)
+{
+ uno::Reference<XFilePickerListener> xFilePickerListener(rEvent.Source, uno::UNO_QUERY);
+
+ if (xFilePickerListener.is())
+ {
+ removeFilePickerListener(xFilePickerListener);
+ }
+}
+
+OUString SAL_CALL Gtk3KDE5FilePicker::getImplementationName()
+{
+ return OUString(FILE_PICKER_IMPL_NAME);
+}
+
+sal_Bool SAL_CALL Gtk3KDE5FilePicker::supportsService(const OUString& ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL Gtk3KDE5FilePicker::getSupportedServiceNames()
+{
+ return FilePicker_getSupportedServiceNames();
+}
+
+void Gtk3KDE5FilePicker::filterChanged()
+{
+ FilePickerEvent aEvent;
+ aEvent.ElementId = LISTBOX_FILTER;
+ OSL_TRACE("filter changed");
+ if (m_xListener.is())
+ m_xListener->controlStateChanged(aEvent);
+}
+
+void Gtk3KDE5FilePicker::selectionChanged()
+{
+ FilePickerEvent aEvent;
+ OSL_TRACE("file selection changed");
+ if (m_xListener.is())
+ m_xListener->fileSelectionChanged(aEvent);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx
new file mode 100644
index 000000000000..506bc3bb5afc
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker.hxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <cppuhelper/compbase.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <osl/conditn.hxx>
+#include <osl/mutex.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+#include <boost/process/child.hpp>
+#include <boost/process/pipe.hpp>
+
+#include "gtk3_kde5_filepicker_ipc.hxx"
+
+#include <functional>
+
+typedef ::cppu::WeakComponentImplHelper<css::ui::dialogs::XFilePicker3,
+ css::ui::dialogs::XFilePickerControlAccess
+ // TODO css::ui::dialogs::XFilePreview
+ ,
+ css::lang::XInitialization, css::lang::XServiceInfo>
+ Gtk3KDE5FilePicker_Base;
+
+class Gtk3KDE5FilePicker : public Gtk3KDE5FilePicker_Base
+{
+protected:
+ css::uno::Reference<css::ui::dialogs::XFilePickerListener> m_xListener;
+
+ osl::Mutex _helperMutex;
+ Gtk3KDE5FilePickerIpc m_ipc;
+
+public:
+ explicit Gtk3KDE5FilePicker(const css::uno::Reference<css::uno::XComponentContext>&);
+ virtual ~Gtk3KDE5FilePicker();
+
+ // XFilePickerNotifier
+ virtual void SAL_CALL addFilePickerListener(
+ const css::uno::Reference<css::ui::dialogs::XFilePickerListener>& xListener) override;
+ virtual void SAL_CALL removeFilePickerListener(
+ const css::uno::Reference<css::ui::dialogs::XFilePickerListener>& xListener) override;
+
+ // XExecutableDialog functions
+ virtual void SAL_CALL setTitle(const OUString& rTitle) override;
+ virtual sal_Int16 SAL_CALL execute() override;
+
+ // XFilePicker functions
+ virtual void SAL_CALL setMultiSelectionMode(sal_Bool bMode) override;
+ virtual void SAL_CALL setDefaultName(const OUString& rName) override;
+ virtual void SAL_CALL setDisplayDirectory(const OUString& rDirectory) override;
+ virtual OUString SAL_CALL getDisplayDirectory() override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getFiles() override;
+
+ // XFilterManager functions
+ virtual void SAL_CALL appendFilter(const OUString& rTitle, const OUString& rFilter) override;
+ virtual void SAL_CALL setCurrentFilter(const OUString& rTitle) override;
+ virtual OUString SAL_CALL getCurrentFilter() override;
+
+ // XFilterGroupManager functions
+ virtual void SAL_CALL
+ appendFilterGroup(const OUString& rGroupTitle,
+ const css::uno::Sequence<css::beans::StringPair>& rFilters) override;
+
+ // XFilePickerControlAccess functions
+ virtual void SAL_CALL setValue(sal_Int16 nControlId, sal_Int16 nControlAction,
+ const css::uno::Any& rValue) override;
+ virtual css::uno::Any SAL_CALL getValue(sal_Int16 nControlId,
+ sal_Int16 nControlAction) override;
+ virtual void SAL_CALL enableControl(sal_Int16 nControlId, sal_Bool bEnable) override;
+ virtual void SAL_CALL setLabel(sal_Int16 nControlId, const OUString& rLabel) override;
+ virtual OUString SAL_CALL getLabel(sal_Int16 nControlId) override;
+
+ /* TODO XFilePreview
+
+ virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedImageFormats( );
+ virtual sal_Int32 SAL_CALL getTargetColorDepth( );
+ virtual sal_Int32 SAL_CALL getAvailableWidth( );
+ virtual sal_Int32 SAL_CALL getAvailableHeight( );
+ virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const css::uno::Any &rImage );
+ virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState );
+ virtual sal_Bool SAL_CALL getShowState( );
+ */
+
+ // XFilePicker2 functions
+ virtual css::uno::Sequence<OUString> SAL_CALL getSelectedFiles() override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
+
+ // XCancellable
+ virtual void SAL_CALL cancel() override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent);
+ using cppu::WeakComponentImplHelperBase::disposing;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+private:
+ Gtk3KDE5FilePicker(const Gtk3KDE5FilePicker&) = delete;
+ Gtk3KDE5FilePicker& operator=(const Gtk3KDE5FilePicker&) = delete;
+
+ //add a custom control widget to the file dialog
+ void addCustomControl(sal_Int16 controlId);
+
+ // emit XFilePickerListener controlStateChanged event
+ void filterChanged();
+ // emit XFilePickerListener fileSelectionChanged event
+ void selectionChanged();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx
new file mode 100644
index 000000000000..983617cbf58e
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "gtk3_kde5_filepicker_ipc.hxx"
+
+#undef Region
+
+#include "unx/geninst.h"
+
+#include "strings.hrc"
+
+#include <future>
+
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <vcl/svapp.hxx>
+#include <vcl/sysdata.hxx>
+#include <vcl/syswin.hxx>
+
+#include <osl/file.h>
+#include <osl/process.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <unx/gtk/gtkdata.hxx>
+
+#include <boost/filesystem/path.hpp>
+#include <boost/process/environment.hpp>
+#include <boost/process/search_path.hpp>
+#include <boost/process/io.hpp>
+
+using namespace ::com::sun::star::ui::dialogs;
+
+namespace bp = boost::process;
+namespace bf = boost::filesystem;
+
+// helper functions
+
+namespace
+{
+bf::path applicationDirPath()
+{
+ OUString applicationFilePath;
+ osl_getExecutableFile(&applicationFilePath.pData);
+ OUString applicationSystemPath;
+ osl_getSystemPathFromFileURL(applicationFilePath.pData, &applicationSystemPath.pData);
+ auto sysPath = applicationSystemPath.toUtf8();
+ auto ret = bf::path(sysPath.getStr(), sysPath.getStr() + sysPath.getLength());
+ ret.remove_filename();
+ return ret;
+}
+
+bf::path findPickerExecutable()
+{
+ auto paths = boost::this_process::path();
+ paths.insert(paths.begin(), applicationDirPath());
+ auto ret = bp::search_path("lo_kde5filepicker", paths);
+ if (ret.empty())
+ throw bp::process_error(std::make_error_code(std::errc::no_such_file_or_directory),
+ "could not find lo_kde5filepicker executable");
+ return ret;
+}
+}
+
+void readIpcArg(std::istream& stream, OUString& str)
+{
+ const auto buffer = readIpcStringArg(stream);
+ str = OUString::fromUtf8(OString(buffer.data(), buffer.size()));
+}
+
+void readIpcArg(std::istream& stream, css::uno::Sequence<OUString>& seq)
+{
+ uint32_t numFiles = 0;
+ stream >> numFiles;
+ stream.ignore(); // skip space;
+ seq.realloc(numFiles);
+ for (size_t i = 0; i < numFiles; ++i)
+ {
+ readIpcArg(stream, seq[i]);
+ }
+}
+
+void sendIpcArg(std::ostream& stream, const OUString& string)
+{
+ const auto utf8 = string.toUtf8();
+ sendIpcStringArg(stream, utf8.getLength(), utf8.getStr());
+}
+
+OUString getResString(const char* pResId)
+{
+ if (pResId == nullptr)
+ return {};
+
+ return VclResId(pResId);
+}
+
+// Gtk3KDE5FilePicker
+
+Gtk3KDE5FilePickerIpc::Gtk3KDE5FilePickerIpc()
+ // workaround: specify some non-empty argument, otherwise the Qt app will see argc == 0
+ : m_process(findPickerExecutable(), "dummy", bp::std_out > m_stdout, bp::std_in < m_stdin)
+{
+}
+
+Gtk3KDE5FilePickerIpc::~Gtk3KDE5FilePickerIpc()
+{
+ sendCommand(Commands::Quit);
+ if (m_process.running())
+ m_process.wait_for(std::chrono::milliseconds(100));
+}
+
+sal_Int16 SAL_CALL Gtk3KDE5FilePickerIpc::execute()
+{
+ auto restoreMainWindow = blockMainWindow();
+
+ auto id = sendCommand(Commands::Execute);
+ sal_Bool accepted = false;
+ readResponse(id, accepted);
+
+ if (restoreMainWindow)
+ restoreMainWindow();
+
+ return accepted ? ExecutableDialogResults::OK : ExecutableDialogResults::CANCEL;
+}
+
+static gboolean ignoreDeleteEvent(GtkWidget* /*widget*/, GdkEvent* /*event*/,
+ gpointer /*user_data*/)
+{
+ return true;
+}
+
+std::function<void()> SAL_CALL Gtk3KDE5FilePickerIpc::blockMainWindow()
+{
+ vcl::Window* pParentWin = Application::GetDefDialogParent();
+ if (!pParentWin)
+ return {};
+
+ const SystemEnvData* pSysData = static_cast<SystemWindow*>(pParentWin)->GetSystemData();
+ if (!pSysData)
+ return {};
+
+ sendCommand(Commands::SetWinId, pSysData->aWindow);
+
+ auto* pMainWindow = reinterpret_cast<GtkWidget*>(pSysData->pWidget);
+ if (!pMainWindow)
+ return {};
+
+ SolarMutexGuard guard;
+ auto deleteEventSignalId = g_signal_lookup("delete_event", gtk_widget_get_type());
+
+ // disable the mainwindow
+ gtk_widget_set_sensitive(pMainWindow, false);
+
+ // block the GtkSalFrame delete_event handler
+ auto blockedHandler = g_signal_handler_find(
+ pMainWindow, static_cast<GSignalMatchType>(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
+ deleteEventSignalId, 0, nullptr, nullptr, pSysData->pSalFrame);
+ g_signal_handler_block(pMainWindow, blockedHandler);
+
+ // prevent the window from being closed
+ auto ignoreDeleteEventHandler
+ = g_signal_connect(pMainWindow, "delete_event", G_CALLBACK(ignoreDeleteEvent), nullptr);
+
+ return [pMainWindow, ignoreDeleteEventHandler, blockedHandler] {
+ SolarMutexGuard cleanupGuard;
+ // re-enable window
+ gtk_widget_set_sensitive(pMainWindow, true);
+
+ // allow it to be closed again
+ g_signal_handler_disconnect(pMainWindow, ignoreDeleteEventHandler);
+
+ // unblock the GtkSalFrame handler
+ g_signal_handler_unblock(pMainWindow, blockedHandler);
+ };
+}
+
+void SAL_CALL Gtk3KDE5FilePickerIpc::await(const std::future<void>& future)
+{
+ while (future.wait_for(std::chrono::milliseconds(1)) != std::future_status::ready)
+ {
+ GetGtkSalData()->Yield(false, true);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx
new file mode 100644
index 000000000000..c7b13cd4573f
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <cppuhelper/compbase.hxx>
+
+#include <osl/conditn.hxx>
+#include <osl/mutex.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+#include <boost/process/child.hpp>
+#include <boost/process/pipe.hpp>
+
+#include "filepicker_ipc_commands.hxx"
+
+#include <functional>
+#include <future>
+#include <mutex>
+#include <thread>
+
+void readIpcArg(std::istream& stream, OUString& str);
+
+void readIpcArg(std::istream& stream, css::uno::Sequence<OUString>& seq);
+
+void sendIpcArg(std::ostream& stream, const OUString& string);
+
+OUString getResString(const char* pResId);
+
+class Gtk3KDE5FilePickerIpc
+{
+protected:
+ boost::process::ipstream m_stdout;
+ boost::process::opstream m_stdin;
+ boost::process::child m_process;
+ // simple multiplexing: every command gets it's own ID that can be used to
+ // read the corresponding response
+ uint64_t m_msgId = 1;
+ std::mutex m_mutex;
+ uint64_t m_incomingResponse = 0;
+
+public:
+ explicit Gtk3KDE5FilePickerIpc();
+ ~Gtk3KDE5FilePickerIpc();
+
+ sal_Int16 SAL_CALL execute();
+
+ template <typename... Args> uint64_t sendCommand(Commands command, const Args&... args)
+ {
+ auto id = m_msgId;
+ ++m_msgId;
+ sendIpcArgs(m_stdin, id, command, args...);
+ return id;
+ }
+
+ template <typename... Args> void readResponse(uint64_t id, Args&... args)
+ {
+ // read synchronously from a background thread and run the eventloop until the value becomes available
+ // this allows us to keep the GUI responsive and also enables access to the LO clipboard
+ await(std::async(std::launch::async, [&]() {
+ while (true)
+ {
+ // only let one thread read at any given time
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ // check if we need to read (and potentially wait) a response ID
+ if (m_incomingResponse == 0)
+ readIpcArgs(m_stdout, m_incomingResponse);
+
+ if (m_incomingResponse == id)
+ {
+ // the response we are waiting for came in
+ readIpcArgs(m_stdout, args...);
+ m_incomingResponse = 0;
+ break;
+ }
+ else
+ {
+ // the next response answers some other request, yield
+ std::this_thread::yield();
+ }
+ }
+ }));
+ }
+
+private:
+ std::function<void()> SAL_CALL blockMainWindow();
+
+ static void SAL_CALL await(const std::future<void>& future);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.cxx
new file mode 100644
index 000000000000..ad89374b47c7
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "gtk3_kde5_folderpicker.hxx"
+
+#include <com/sun/star/awt/Toolkit.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <vcl/svapp.hxx>
+
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+// constructor
+
+Gtk3KDE5FolderPicker::Gtk3KDE5FolderPicker(
+ const uno::Reference<uno::XComponentContext>& /*xContext*/)
+{
+ m_ipc.sendCommand(Commands::EnablePickFolderMode);
+ setTitle(getResString(STR_FPICKER_FOLDER_DEFAULT_TITLE));
+}
+
+Gtk3KDE5FolderPicker::~Gtk3KDE5FolderPicker() = default;
+
+void SAL_CALL Gtk3KDE5FolderPicker::setDisplayDirectory(const OUString& aDirectory)
+{
+ m_ipc.sendCommand(Commands::SetDisplayDirectory, aDirectory);
+}
+
+OUString SAL_CALL Gtk3KDE5FolderPicker::getDisplayDirectory()
+{
+ auto id = m_ipc.sendCommand(Commands::GetDisplayDirectory);
+ OUString ret;
+ m_ipc.readResponse(id, ret);
+ return ret;
+}
+
+OUString SAL_CALL Gtk3KDE5FolderPicker::getDirectory()
+{
+ auto id = m_ipc.sendCommand(Commands::GetSelectedFiles);
+ uno::Sequence<OUString> seq;
+ m_ipc.readResponse(id, seq);
+ return seq.hasElements() ? seq[0] : OUString();
+}
+
+void SAL_CALL Gtk3KDE5FolderPicker::setDescription(const OUString& /*rDescription*/) {}
+
+// XExecutableDialog functions
+
+void SAL_CALL Gtk3KDE5FolderPicker::setTitle(const OUString& aTitle)
+{
+ m_ipc.sendCommand(Commands::SetTitle, aTitle);
+}
+
+sal_Int16 SAL_CALL Gtk3KDE5FolderPicker::execute() { return m_ipc.execute(); }
+
+// XCancellable
+
+void SAL_CALL Gtk3KDE5FolderPicker::cancel()
+{
+ // TODO
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.hxx b/vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.hxx
new file mode 100644
index 000000000000..c6a6c4edfb73
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_folderpicker.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <list>
+#include <memory>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include "gtk3_kde5_filepicker_ipc.hxx"
+
+class Gtk3KDE5FolderPicker : public cppu::WeakImplHelper<css::ui::dialogs::XFolderPicker2>
+{
+protected:
+ Gtk3KDE5FilePickerIpc m_ipc;
+
+public:
+ // constructor
+ explicit Gtk3KDE5FolderPicker(
+ const css::uno::Reference<css::uno::XComponentContext>& xServiceMgr);
+ virtual ~Gtk3KDE5FolderPicker();
+
+ // XExecutableDialog functions
+ virtual void SAL_CALL setTitle(const OUString& aTitle) override;
+ virtual sal_Int16 SAL_CALL execute() override;
+
+ // XFolderPicker functions
+ virtual void SAL_CALL setDisplayDirectory(const OUString& rDirectory) override;
+ virtual OUString SAL_CALL getDisplayDirectory() override;
+ virtual OUString SAL_CALL getDirectory() override;
+ virtual void SAL_CALL setDescription(const OUString& rDescription) override;
+
+ // XCancellable
+ virtual void SAL_CALL cancel() override;
+
+private:
+ Gtk3KDE5FolderPicker(const Gtk3KDE5FolderPicker&) = delete;
+ Gtk3KDE5FolderPicker& operator=(const Gtk3KDE5FolderPicker&) = delete;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gloactiongroup.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gloactiongroup.cxx
new file mode 100644
index 000000000000..fa71136f9a28
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gloactiongroup.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gloactiongroup.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_glomenu.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_glomenu.cxx
new file mode 100644
index 000000000000..de79c14c1403
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_glomenu.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3glomenu.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata.cxx
new file mode 100644
index 000000000000..200a74131860
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkdata.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtkdata.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtkframe.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkframe.cxx
new file mode 100644
index 000000000000..0b2eb38dcec4
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkframe.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtkframe.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx
new file mode 100644
index 000000000000..bed2c049aa3a
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkinst.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtkinst.cxx"
+
+#include "gtk3_kde5_filepicker.hxx"
+#include "gtk3_kde5_folderpicker.hxx"
+
+#include <boost/process/exception.hpp>
+
+uno::Reference<ui::dialogs::XFilePicker2>
+GtkInstance::createFilePicker(const uno::Reference<uno::XComponentContext>& xMSF)
+{
+ try
+ {
+ return uno::Reference<ui::dialogs::XFilePicker2>(new Gtk3KDE5FilePicker(xMSF));
+ }
+ catch (const boost::process::process_error& error)
+ {
+ OSL_FAIL(error.what());
+ return { nullptr };
+ }
+}
+
+uno::Reference<ui::dialogs::XFolderPicker2>
+GtkInstance::createFolderPicker(const uno::Reference<uno::XComponentContext>& xMSF)
+{
+ try
+ {
+ return uno::Reference<ui::dialogs::XFolderPicker2>(new Gtk3KDE5FolderPicker(xMSF));
+ }
+ catch (const boost::process::process_error& error)
+ {
+ OSL_FAIL(error.what());
+ return { nullptr };
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtkobject.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkobject.cxx
new file mode 100644
index 000000000000..a2eb6b9e1631
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtkobject.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtkobject.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtksalmenu.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtksalmenu.cxx
new file mode 100644
index 000000000000..9eb1c7975800
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtksalmenu.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtksalmenu.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_gtksys.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_gtksys.cxx
new file mode 100644
index 000000000000..8f6b38843ec4
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_gtksys.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtksys.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_hudawareness.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_hudawareness.cxx
new file mode 100644
index 000000000000..eb159238983f
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_hudawareness.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3hudawareness.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_printwrapper.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_printwrapper.cxx
new file mode 100644
index 000000000000..33768f8cac73
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_printwrapper.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3gtkprintwrapper.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_salnativewidgets-gtk.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_salnativewidgets-gtk.cxx
new file mode 100644
index 000000000000..108e41d470bc
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_salnativewidgets-gtk.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3salnativewidgets-gtk.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_salprn-gtk.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_salprn-gtk.cxx
new file mode 100644
index 000000000000..a9f8c076fe5c
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_salprn-gtk.cxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "../gtk3/gtk3salprn-gtk.cxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/kde5_filepicker.cxx b/vcl/unx/gtk3_kde5/kde5_filepicker.cxx
new file mode 100644
index 000000000000..db7d04cf7d4a
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/kde5_filepicker.cxx
@@ -0,0 +1,283 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "kde5_filepicker.hxx"
+
+#include <KWindowSystem>
+#include <KFileWidget>
+
+#include <QtCore/QDebug>
+#include <QtCore/QUrl>
+#include <QtGui/QClipboard>
+#include <QtGui/QWindow>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QFileDialog>
+#include <QtWidgets/QFormLayout>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QApplication>
+
+// The dialog should check whether LO also supports the protocol
+// provided by KIO, and KFileWidget::dirOperator() is only 4.3+ .
+// Moreover it's only in this somewhat internal KFileWidget class,
+// which may not necessarily be what QFileDialog::fileWidget() returns,
+// but that's hopefully not a problem in practice.
+//#if Qt_VERSION_MAJOR == 4 && Qt_VERSION_MINOR >= 2
+//#define ALLOW_REMOTE_URLS 1
+//#else
+#define ALLOW_REMOTE_URLS 0
+//#endif
+
+// KDE5FilePicker
+
+KDE5FilePicker::KDE5FilePicker(QObject* parent)
+ : QObject(parent)
+ , _dialog(new QFileDialog(nullptr, {}, QDir::homePath()))
+ , _extraControls(new QWidget)
+ , _layout(new QFormLayout(_extraControls))
+ , _winId(0)
+ , allowRemoteUrls(false)
+{
+#if ALLOW_REMOTE_URLS
+ if (KFileWidget* fileWidget = dynamic_cast<KFileWidget*>(_dialog->fileWidget()))
+ {
+ allowRemoteUrls = true;
+ // Use finishedLoading signal rather than e.g. urlEntered, because if there's a problem
+ // such as the URL being mistyped, there's no way to prevent two message boxes about it,
+ // one from us and one from Qt code.
+ connect(fileWidget->dirOperator(), SIGNAL(finishedLoading()), SLOT(checkProtocol()));
+ }
+#endif
+
+ setMultiSelectionMode(false);
+
+ connect(_dialog, &QFileDialog::filterSelected, this, &KDE5FilePicker::filterChanged);
+ connect(_dialog, &QFileDialog::fileSelected, this, &KDE5FilePicker::selectionChanged);
+
+ qApp->installEventFilter(this);
+}
+
+void KDE5FilePicker::enableFolderMode()
+{
+ _dialog->setOption(QFileDialog::ShowDirsOnly, true);
+ _dialog->setFileMode(QFileDialog::Directory);
+}
+
+KDE5FilePicker::~KDE5FilePicker()
+{
+ delete _extraControls;
+ delete _dialog;
+}
+
+void SAL_CALL KDE5FilePicker::setTitle(const QString& title) { _dialog->setWindowTitle(title); }
+
+bool SAL_CALL KDE5FilePicker::execute()
+{
+ if (!_filters.isEmpty())
+ _dialog->setNameFilters(_filters);
+ if (!_currentFilter.isEmpty())
+ _dialog->selectNameFilter(_currentFilter);
+
+ _dialog->show();
+ //block and wait for user input
+ return _dialog->exec() == QFileDialog::Accepted;
+}
+
+void SAL_CALL KDE5FilePicker::setMultiSelectionMode(bool multiSelect)
+{
+ _dialog->setFileMode(multiSelect ? QFileDialog::ExistingFiles : QFileDialog::ExistingFile);
+}
+
+void SAL_CALL KDE5FilePicker::setDefaultName(const QString& name)
+{
+ _dialog->selectUrl(QUrl(name));
+}
+
+void SAL_CALL KDE5FilePicker::setDisplayDirectory(const QString& dir)
+{
+ _dialog->selectUrl(QUrl(dir));
+}
+
+QString SAL_CALL KDE5FilePicker::getDisplayDirectory() const
+{
+ return _dialog->directoryUrl().url();
+}
+
+QList<QUrl> SAL_CALL KDE5FilePicker::getSelectedFiles() const { return _dialog->selectedUrls(); }
+
+void SAL_CALL KDE5FilePicker::appendFilter(const QString& title, const QString& filter)
+{
+ QString t = title;
+ QString f = filter;
+ // '/' need to be escaped else they are assumed to be mime types by kfiledialog
+ //see the docs
+ t.replace("/", "\\/");
+
+ // openoffice gives us filters separated by ';' qt dialogs just want space separated
+ f.replace(";", " ");
+
+ // make sure "*.*" is not used as "all files"
+ f.replace("*.*", "*");
+
+ _filters << QStringLiteral("%1 (%2)").arg(t, f);
+ _titleToFilters[t] = _filters.constLast();
+}
+
+void SAL_CALL KDE5FilePicker::setCurrentFilter(const QString& title)
+{
+ _currentFilter = _titleToFilters.value(title);
+}
+
+QString SAL_CALL KDE5FilePicker::getCurrentFilter() const
+{
+ QString filter = _titleToFilters.key(_dialog->selectedNameFilter());
+
+ //default if not found
+ if (filter.isEmpty())
+ filter = "ODF Text Document (.odt)";
+
+ return filter;
+}
+
+void SAL_CALL KDE5FilePicker::setValue(sal_Int16 controlId, sal_Int16 /*nControlAction*/,
+ bool value)
+{
+ if (_customWidgets.contains(controlId))
+ {
+ QCheckBox* cb = dynamic_cast<QCheckBox*>(_customWidgets.value(controlId));
+ if (cb)
+ cb->setChecked(value);
+ }
+ else
+ qWarning() << "set value on unknown control" << controlId;
+}
+
+bool SAL_CALL KDE5FilePicker::getValue(sal_Int16 controlId, sal_Int16 /*nControlAction*/) const
+{
+ bool ret = false;
+ if (_customWidgets.contains(controlId))
+ {
+ QCheckBox* cb = dynamic_cast<QCheckBox*>(_customWidgets.value(controlId));
+ if (cb)
+ ret = cb->isChecked();
+ }
+ else
+ qWarning() << "get value on unknown control" << controlId;
+
+ return ret;
+}
+
+void SAL_CALL KDE5FilePicker::enableControl(sal_Int16 controlId, sal_Bool enable)
+{
+ if (_customWidgets.contains(controlId))
+ _customWidgets.value(controlId)->setEnabled(enable);
+ else
+ qWarning() << "enable on unknown control" << controlId;
+}
+
+void SAL_CALL KDE5FilePicker::setLabel(sal_Int16 controlId, const QString& label)
+{
+ if (_customWidgets.contains(controlId))
+ {
+ QCheckBox* cb = dynamic_cast<QCheckBox*>(_customWidgets.value(controlId));
+ if (cb)
+ cb->setText(label);
+ }
+ else
+ qWarning() << "set label on unknown control" << controlId;
+}
+
+QString SAL_CALL KDE5FilePicker::getLabel(sal_Int16 controlId) const
+{
+ QString label;
+ if (_customWidgets.contains(controlId))
+ {
+ QCheckBox* cb = dynamic_cast<QCheckBox*>(_customWidgets.value(controlId));
+ if (cb)
+ label = cb->text();
+ }
+ else
+ qWarning() << "get label on unknown control" << controlId;
+
+ return label;
+}
+
+void KDE5FilePicker::addCheckBox(sal_Int16 controlId, const QString& label, bool hidden)
+{
+ auto widget = new QCheckBox(_extraControls);
+ widget->setHidden(hidden);
+ if (!hidden)
+ {
+ auto resString = label;
+ resString.replace('~', '&');
+ _layout->addRow(resString, widget);
+ }
+ _customWidgets.insert(controlId, widget);
+}
+
+void SAL_CALL KDE5FilePicker::initialize(bool saveDialog)
+{
+ //default is opening
+ QFileDialog::AcceptMode operationMode
+ = saveDialog ? QFileDialog::AcceptSave : QFileDialog::AcceptOpen;
+
+ _dialog->setAcceptMode(operationMode);
+
+ if (saveDialog)
+ {
+ _dialog->setConfirmOverwrite(true);
+ _dialog->setFileMode(QFileDialog::AnyFile);
+ }
+}
+
+void KDE5FilePicker::checkProtocol()
+{
+ // There's no libreoffice.desktop :(, so find a matching one.
+ /*
+ KService::List services = KServiceTypeTrader::self()->query( "Application", "Exec =~ 'libreoffice %U'" );
+ QStringList protocols;
+ if( !services.isEmpty())
+ protocols = services[ 0 ]->property( "X-Qt-Protocols" ).toStringList();
+ if( protocols.isEmpty()) // incorrect (developer?) installation ?
+ protocols << "file" << "http";
+ if( !protocols.contains( _dialog->baseUrl().protocol()) && !protocols.contains( "KIO" ))
+ KMessageBox::error( _dialog, KIO::buildErrorString( KIO::ERR_UNSUPPORTED_PROTOCOL, _dialog->baseUrl().protocol()));
+*/
+}
+
+void KDE5FilePicker::setWinId(sal_uIntPtr winId) { _winId = winId; }
+
+bool KDE5FilePicker::eventFilter(QObject* o, QEvent* e)
+{
+ if (e->type() == QEvent::Show && o->isWidgetType())
+ {
+ auto* w = static_cast<QWidget*>(o);
+ if (!w->parentWidget() && w->isModal())
+ {
+ KWindowSystem::setMainWindow(w, _winId);
+ if (auto* fileWidget = w->findChild<KFileWidget*>({}, Qt::FindDirectChildrenOnly))
+ fileWidget->setCustomWidget(_extraControls);
+ return false;
+ }
+ }
+ return QObject::eventFilter(o, e);
+}
+
+#include "kde5_filepicker.moc"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/kde5_filepicker.hxx b/vcl/unx/gtk3_kde5/kde5_filepicker.hxx
new file mode 100644
index 000000000000..8b364832c6af
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/kde5_filepicker.hxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QHash>
+
+#include <sal/types.h>
+
+class QFileDialog;
+class QWidget;
+class QFormLayout;
+
+class KDE5FilePicker : public QObject
+{
+ Q_OBJECT
+protected:
+ //the dialog to display
+ QFileDialog* _dialog;
+
+ //running filter string to add to dialog
+ QStringList _filters;
+ // map of filter titles to full filter for selection
+ QHash<QString, QString> _titleToFilters;
+ // string to set the current filter
+ QString _currentFilter;
+
+ //mapping of SAL control ID's to created custom controls
+ QHash<sal_Int16, QWidget*> _customWidgets;
+
+ //widget to contain extra custom controls
+ QWidget* _extraControls;
+
+ //layout for extra custom controls
+ QFormLayout* _layout;
+
+ sal_uIntPtr _winId;
+
+ bool allowRemoteUrls;
+
+public:
+ explicit KDE5FilePicker(QObject* parent = nullptr);
+ ~KDE5FilePicker();
+
+ void enableFolderMode();
+
+ // XExecutableDialog functions
+ void SAL_CALL setTitle(const QString& rTitle);
+ bool SAL_CALL execute();
+
+ // XFilePicker functions
+ void SAL_CALL setMultiSelectionMode(bool bMode);
+ void SAL_CALL setDefaultName(const QString& rName);
+ void SAL_CALL setDisplayDirectory(const QString& rDirectory);
+ QString SAL_CALL getDisplayDirectory() const;
+
+ // XFilterManager functions
+ void SAL_CALL appendFilter(const QString& rTitle, const QString& rFilter);
+ void SAL_CALL setCurrentFilter(const QString& rTitle);
+ QString SAL_CALL getCurrentFilter() const;
+
+ // XFilePickerControlAccess functions
+ void SAL_CALL setValue(sal_Int16 nControlId, sal_Int16 nControlAction, bool rValue);
+ bool SAL_CALL getValue(sal_Int16 nControlId, sal_Int16 nControlAction) const;
+ void SAL_CALL enableControl(sal_Int16 nControlId, sal_Bool bEnable);
+ void SAL_CALL setLabel(sal_Int16 nControlId, const QString& rLabel);
+ QString SAL_CALL getLabel(sal_Int16 nControlId) const;
+
+ // XFilePicker2 functions
+ QList<QUrl> getSelectedFiles() const;
+
+ // XInitialization
+ void initialize(bool saveDialog);
+
+ //add a custom control widget to the file dialog
+ void addCheckBox(sal_Int16 nControlId, const QString& label, bool hidden);
+
+ void setWinId(sal_uIntPtr winId);
+
+private:
+ Q_DISABLE_COPY(KDE5FilePicker)
+
+protected:
+ bool eventFilter(QObject* watched, QEvent* event) override;
+
+private Q_SLOTS:
+ void checkProtocol();
+
+Q_SIGNALS:
+ void filterChanged();
+ void selectionChanged();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx
new file mode 100644
index 000000000000..9911219d010a
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "kde5_filepicker_ipc.hxx"
+
+#include <QSocketNotifier>
+#include <QUrl>
+#include <QThread>
+#include <QApplication>
+#include <QDebug>
+
+#include <iostream>
+
+#include "filepicker_ipc_commands.hxx"
+#include "kde5_filepicker.hxx"
+
+#include <rtl/ustring.h>
+
+void readIpcArg(std::istream& stream, QString& string)
+{
+ const auto buffer = readIpcStringArg(stream);
+ string = QString::fromUtf8(buffer.data(), buffer.size());
+}
+
+void sendIpcArg(std::ostream& stream, const QString& string)
+{
+ const auto utf8 = string.toUtf8();
+ sendIpcStringArg(stream, utf8.size(), utf8.data());
+}
+
+void sendIpcArg(std::ostream& stream, const QList<QUrl>& urls)
+{
+ stream << static_cast<uint32_t>(urls.size()) << ' ';
+ for (const auto& url : urls)
+ {
+ sendIpcArg(stream, url.toString());
+ }
+}
+
+FilePickerIpc::FilePickerIpc(KDE5FilePicker* filePicker, QObject* parent)
+ : QObject(parent)
+ , m_filePicker(filePicker)
+ , m_stdinNotifier(new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this))
+{
+ connect(m_stdinNotifier, &QSocketNotifier::activated, this, &FilePickerIpc::readCommands);
+}
+
+FilePickerIpc::~FilePickerIpc() = default;
+
+void FilePickerIpc::readCommands()
+{
+ while (!std::cin.eof())
+ {
+ readCommand();
+ }
+}
+
+void FilePickerIpc::readCommand()
+{
+ uint64_t messageId = 0;
+ Commands command;
+ readIpcArgs(std::cin, messageId, command);
+
+ switch (command)
+ {
+ case Commands::SetTitle:
+ {
+ QString title;
+ readIpcArgs(std::cin, title);
+ m_filePicker->setTitle(title);
+ return;
+ }
+ case Commands::SetWinId:
+ {
+ sal_uIntPtr winId = 0;
+ readIpcArgs(std::cin, winId);
+ m_filePicker->setWinId(winId);
+ return;
+ }
+ case Commands::Execute:
+ {
+ sendIpcArgs(std::cout, messageId, m_filePicker->execute());
+ return;
+ }
+ case Commands::SetMultiSelectionMode:
+ {
+ bool multiSelection = false;
+ readIpcArgs(std::cin, multiSelection);
+ m_filePicker->setMultiSelectionMode(multiSelection);
+ return;
+ }
+ case Commands::SetDefaultName:
+ {
+ QString name;
+ readIpcArgs(std::cin, name);
+ m_filePicker->setDefaultName(name);
+ return;
+ }
+ case Commands::SetDisplayDirectory:
+ {
+ QString dir;
+ readIpcArgs(std::cin, dir);
+ m_filePicker->setDisplayDirectory(dir);
+ return;
+ }
+ case Commands::GetDisplayDirectory:
+ {
+ sendIpcArgs(std::cout, messageId, m_filePicker->getDisplayDirectory());
+ return;
+ }
+ case Commands::GetSelectedFiles:
+ {
+ sendIpcArgs(std::cout, messageId, m_filePicker->getSelectedFiles());
+ return;
+ }
+ case Commands::AppendFilter:
+ {
+ QString title, filter;
+ readIpcArgs(std::cin, title, filter);
+ m_filePicker->appendFilter(title, filter);
+ return;
+ }
+ case Commands::SetCurrentFilter:
+ {
+ QString title;
+ readIpcArgs(std::cin, title);
+ m_filePicker->setCurrentFilter(title);
+ return;
+ }
+ case Commands::GetCurrentFilter:
+ {
+ sendIpcArgs(std::cout, messageId, m_filePicker->getCurrentFilter());
+ return;
+ }
+ case Commands::SetValue:
+ {
+ sal_Int16 controlId = 0;
+ sal_Int16 nControlAction = 0;
+ bool value = false;
+ readIpcArgs(std::cin, controlId, nControlAction, value);
+ m_filePicker->setValue(controlId, nControlAction, value);
+ return;
+ }
+ case Commands::GetValue:
+ {
+ sal_Int16 controlId = 0;
+ sal_Int16 nControlAction = 0;
+ readIpcArgs(std::cin, controlId, nControlAction);
+ sendIpcArgs(std::cout, messageId, m_filePicker->getValue(controlId, nControlAction));
+ return;
+ }
+ case Commands::EnableControl:
+ {
+ sal_Int16 controlId = 0;
+ bool enabled = false;
+ readIpcArgs(std::cin, controlId, enabled);
+ m_filePicker->enableControl(controlId, enabled);
+ return;
+ }
+ case Commands::SetLabel:
+ {
+ sal_Int16 controlId = 0;
+ QString label;
+ readIpcArgs(std::cin, controlId, label);
+ m_filePicker->setLabel(controlId, label);
+ return;
+ }
+ case Commands::GetLabel:
+ {
+ sal_Int16 controlId = 0;
+ readIpcArgs(std::cin, controlId);
+ sendIpcArgs(std::cout, messageId, m_filePicker->getLabel(controlId));
+ return;
+ }
+ case Commands::AddCheckBox:
+ {
+ sal_Int16 controlId = 0;
+ bool hidden = false;
+ QString label;
+ readIpcArgs(std::cin, controlId, hidden, label);
+ m_filePicker->addCheckBox(controlId, label, hidden);
+ return;
+ }
+ case Commands::Initialize:
+ {
+ bool saveDialog = false;
+ readIpcArgs(std::cin, saveDialog);
+ m_filePicker->initialize(saveDialog);
+ return;
+ }
+ case Commands::EnablePickFolderMode:
+ {
+ m_filePicker->enableFolderMode();
+ return;
+ }
+ case Commands::Quit:
+ {
+ qApp->quit();
+ return;
+ }
+ }
+ qWarning() << "unhandled command " << static_cast<uint16_t>(command);
+}
+
+#include "kde5_filepicker_ipc.moc"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx
new file mode 100644
index 000000000000..8a282675b5e2
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#pragma once
+
+#include <QObject>
+
+class KDE5FilePicker;
+class WinIdEmbedder;
+class QSocketNotifier;
+
+class FilePickerIpc : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FilePickerIpc(KDE5FilePicker* filePicker, QObject* parent = nullptr);
+ ~FilePickerIpc();
+
+private Q_SLOTS:
+ void readCommands();
+
+private:
+ void readCommand();
+
+ KDE5FilePicker* m_filePicker = nullptr;
+ QSocketNotifier* m_stdinNotifier = nullptr;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3_kde5/kde5_lo_filepicker_main.cxx b/vcl/unx/gtk3_kde5/kde5_lo_filepicker_main.cxx
new file mode 100644
index 000000000000..43d92aba614a
--- /dev/null
+++ b/vcl/unx/gtk3_kde5/kde5_lo_filepicker_main.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+#include "kde5_filepicker.hxx"
+#include "kde5_filepicker_ipc.hxx"
+
+#include <QApplication>
+
+#include <iostream>
+
+int main(int argc, char** argv)
+{
+ QApplication::setApplicationName(QStringLiteral("lo_kde5filepicker"));
+ QApplication app(argc, argv);
+ app.setQuitOnLastWindowClosed(false);
+
+ KDE5FilePicker filePicker;
+ FilePickerIpc ipc(&filePicker);
+
+ return app.exec();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */