Rebased ref, commits from common ancestor: commit fc66ef9fc9e0c00fe7f7a62889b201b3479c02ce Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Wed Jul 8 17:59:14 2015 +0000
KDE4: Switch default image color to transparent... and just fill the painted image once at the beginning. Change-Id: I39c03b2ca779381920e2597b4bea7973fea6ae2a diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx index a05f358..d1998d9 100644 --- a/vcl/unx/kde4/KDESalGraphics.cxx +++ b/vcl/unx/kde4/KDESalGraphics.cxx @@ -233,13 +233,39 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, { m_image.reset(new QImage( widgetRect.width(), widgetRect.height(), QImage::Format_ARGB32 ) ); } - m_image->fill(KApplication::palette().color(QPalette::Window).rgb()); + + // Default image color - just once + switch (type) + { + case CTRL_MENU_POPUP: + if( part == PART_MENU_ITEM_CHECK_MARK || part == PART_MENU_ITEM_RADIO_MARK ) + { + // it is necessary to fill the background transparently first, as this + // is painted after menuitem highlight, otherwise there would be a grey area + m_image->fill( Qt::transparent ); + break; + } + // fallthrough QPalette::Window + case CTRL_MENUBAR: + case CTRL_WINDOW_BACKGROUND: + m_image->fill( KApplication::palette().color(QPalette::Window).rgb() ); + break; + case CTRL_SCROLLBAR: + if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ)) + { + m_image->fill( KApplication::palette().color(QPalette::Window).rgb() ); + break; + } + // fallthrough Qt::transparent + default: + m_image->fill( Qt::transparent ); + break; + } QRegion* clipRegion = nullptr; if (type == CTRL_PUSHBUTTON) { - m_image->fill( Qt::transparent ); QStyleOptionButton option; draw( QStyle::CE_PushButton, &option, m_image.get(), vclStateValue2StateFlag(nControlState, value) ); @@ -314,15 +340,12 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, ? QStyleOptionMenuItem::NonExclusive : QStyleOptionMenuItem::Exclusive; option.checked = bool( nControlState & ControlState::PRESSED ); // widgetRect is now the rectangle for the checkbox/radiobutton itself, but Qt - // paints the whole menu item, so translate position (and it'll be clipped); - // it is also necessary to fill the background transparently first, as this - // is painted after menuitem highlight, otherwise there would be a grey area + // paints the whole menu item, so translate position (and it'll be clipped) assert( value.getType() == CTRL_MENU_POPUP ); const MenupopupValue* menuVal = static_cast<const MenupopupValue*>(&value); QRect menuItemRect( region2QRect( menuVal->maItemRect )); QRect rect( menuItemRect.topLeft() - widgetRect.topLeft(), widgetRect.size().expandedTo( menuItemRect.size())); - m_image->fill( Qt::transparent ); draw( QStyle::CE_MenuItem, &option, m_image.get(), vclStateValue2StateFlag(nControlState, value), rect ); } @@ -341,7 +364,6 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) ) { - m_image->fill( Qt::transparent ); QStyleOptionToolButton option; option.arrowType = Qt::NoArrow; @@ -409,7 +431,6 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, vclStateValue2StateFlag(nControlState, value) ); break; case PART_BUTTON_DOWN: - m_image->fill( Qt::transparent ); option.subControls = QStyle::SC_ComboBoxArrow; draw( QStyle::CC_ComboBox, &option, m_image.get(), vclStateValue2StateFlag(nControlState, value) ); @@ -418,7 +439,6 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else if (type == CTRL_LISTNODE) { - m_image->fill( Qt::transparent ); QStyleOption option; option.state = QStyle::State_Item | QStyle::State_Children; @@ -430,7 +450,6 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else if (type == CTRL_CHECKBOX) { - m_image->fill( Qt::transparent ); QStyleOptionButton option; draw( QStyle::CE_CheckBox, &option, m_image.get(), vclStateValue2StateFlag(nControlState, value) ); @@ -499,7 +518,6 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else if (type == CTRL_RADIOBUTTON) { - m_image->fill( Qt::transparent ); QStyleOptionButton option; draw( QStyle::CE_RadioButton, &option, m_image.get(), vclStateValue2StateFlag(nControlState, value) ); @@ -521,7 +539,7 @@ bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else if (type == CTRL_WINDOW_BACKGROUND) { - m_image->fill(KApplication::palette().color(QPalette::Window).rgb()); + // Nothing to do - see "Default image color" switch ^^ } else if (type == CTRL_FIXEDLINE) { commit 31cedc16f3788b86b50a8d59e0ff85b95992d579 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Dec 11 21:57:44 2015 +0100 KDE5 Change-Id: I8ccdf61dd210e77dd78ac685863092dd37c90a59 diff --git a/Repository.mk b/Repository.mk index 5c468b2..b7e2da3 100644 --- a/Repository.mk +++ b/Repository.mk @@ -256,8 +256,10 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,gnome, \ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,kde, \ $(if $(ENABLE_KDE4),kde4be1) \ + $(if $(ENABLE_KDE5),kde5be1) \ $(if $(USING_X11), \ $(if $(ENABLE_KDE4),vclplug_kde4) \ + $(if $(ENABLE_KDE5),vclplug_kde5) \ ) \ )) diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index fe614db3..61b1b2c 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -2982,6 +2982,39 @@ endef endif # ENABLE_KDE4 +ifeq ($(ENABLE_KDE5),TRUE) + +define gb_LinkTarget__use_kde5 +$(call gb_LinkTarget_set_include,$(1),\ + $(subst -isystem/,-isystem /,$(filter -I% -isystem%,$(subst -isystem /,-isystem/,$(KF5_CFLAGS)))) \ + $$(INCLUDE) \ +) + +$(call gb_LinkTarget_add_defs,$(1),\ + $(filter-out -I% -isystem%,$(subst -isystem /,-isystem/,$(KF5_CFLAGS))) \ +) + +$(call gb_LinkTarget_add_libs,$(1),\ + $(KF5_LIBS) \ +) + +ifeq ($(COM),GCC) +$(call gb_LinkTarget_add_cxxflags,$(1),\ + -Wno-shadow \ +) +endif + +endef + +else # !ENABLE_KDE5 + +define gb_LinkTarget__use_kde5 + +endef + +endif # ENABLE_KDE5 + + ifeq ($(ENABLE_TDE),TRUE) define gb_LinkTarget__use_tde diff --git a/config_host.mk.in b/config_host.mk.in index 0fc29b6..1729019 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -144,6 +144,7 @@ export ENABLE_GTK_PRINT=@ENABLE_GTK_PRINT@ export ENABLE_HEADLESS=@ENABLE_HEADLESS@ export ENABLE_JAVA=@ENABLE_JAVA@ export ENABLE_KDE4=@ENABLE_KDE4@ +export ENABLE_KDE5=@ENABLE_KDE5@ export ENABLE_LIBLANGTAG=@ENABLE_LIBLANGTAG@ export ENABLE_LPSOLVE=@ENABLE_LPSOLVE@ export ENABLE_LTO=@ENABLE_LTO@ @@ -306,6 +307,11 @@ export KDE4_LIBS=$(gb_SPACE)@KDE4_LIBS@ export KDE4_GLIB_CFLAGS=$(gb_SPACE)@KDE4_GLIB_CFLAGS@ export KDE4_GLIB_LIBS=$(gb_SPACE)@KDE4_GLIB_LIBS@ export KDE4_HAVE_GLIB=@KDE4_HAVE_GLIB@ +export KF5_CFLAGS=$(gb_SPACE)@KF5_CFLAGS@ +export KF5_LIBS=$(gb_SPACE)@KF5_LIBS@ +export KF5_GLIB_CFLAGS=$(gb_SPACE)@KF5_GLIB_CFLAGS@ +export KF5_GLIB_LIBS=$(gb_SPACE)@KF5_GLIB_LIBS@ +export KF5_HAVE_GLIB=@KF5_HAVE_GLIB@ export KRB5_LIBS=@KRB5_LIBS@ export LCMS2_CFLAGS=$(gb_SPACE)@LCMS2_CFLAGS@ export LCMS2_LIBS=$(gb_SPACE)@LCMS2_LIBS@ @@ -397,6 +403,7 @@ export MINGW_SHARED_LIBSTDCPP=@MINGW_SHARED_LIBSTDCPP@ export MINGW_SYSROOT=@MINGW_SYSROOT@ export ML_EXE=@ML_EXE@ export MOC4=@MOC4@ +export MOC5=@MOC5@ export MPL_SUBSET=@MPL_SUBSET@ export MSM_PATH=@MSM_PATH@ export MSPUB_CFLAGS=$(gb_SPACE)@MSPUB_CFLAGS@ diff --git a/config_host/config_kde5.h.in b/config_host/config_kde5.h.in new file mode 100644 index 0000000..01fa9d2 --- /dev/null +++ b/config_host/config_kde5.h.in @@ -0,0 +1,10 @@ +/* +Settings for KDE5 integration. +*/ + +#ifndef CONFIG_KDE5_H +#define CONFIG_KDE5_H + +#define KF5_HAVE_GLIB 0 + +#endif diff --git a/config_host/config_vclplug.h.in b/config_host/config_vclplug.h.in index ae17474..75558b5 100644 --- a/config_host/config_vclplug.h.in +++ b/config_host/config_vclplug.h.in @@ -9,6 +9,7 @@ Settings about which X11 desktops have support enabled. #define ENABLE_GTK 0 #define ENABLE_KDE4 0 +#define ENABLE_KDE5 0 #define ENABLE_TDE 0 #define ENABLE_GIO 0 diff --git a/configure.ac b/configure.ac index fa441c3..6d80f45 100644 --- a/configure.ac +++ b/configure.ac @@ -641,6 +641,7 @@ linux-gnu*|k*bsd*-gnu*) build_gstreamer_0_10=yes test_tde=yes test_kde4=yes + test_kde5=yes test_freetype=yes _os=Linux ;; @@ -737,6 +738,7 @@ freebsd*) build_gstreamer_0_10=yes test_tde=yes test_kde4=yes + test_kde5=yes test_freetype=yes AC_MSG_CHECKING([the FreeBSD operating system release]) if test -n "$with_os_version"; then @@ -766,6 +768,7 @@ freebsd*) build_gstreamer_0_10=yes test_tde=no test_kde4=yes + test_kde5=yes test_freetype=yes PTHREAD_LIBS="-pthread -lpthread" _os=NetBSD @@ -793,6 +796,7 @@ dragonfly*) build_gstreamer_0_10=yes test_tde=yes test_kde4=yes + test_kde5=yes test_freetype=yes PTHREAD_LIBS="-pthread" _os=DragonFly @@ -814,6 +818,7 @@ linux-android*) test_gtk=no test_tde=no test_kde4=no + test_kde5=no test_randr=no test_xrender=no _os=Android @@ -1248,6 +1253,12 @@ AC_ARG_ENABLE(kde4, KDE4 are available.]), ,) +AC_ARG_ENABLE(kde5, + AS_HELP_STRING([--enable-kde5], + [Determines whether to use Qt5/KF5 vclplug on platforms where Qt5 and + KF5 are available.]), +,) + AC_ARG_ENABLE(randr, AS_HELP_STRING([--disable-randr], [Disable RandR support in the vcl project.]), @@ -4777,6 +4788,7 @@ if test "$USING_X11" != TRUE; then build_gstreamer_0_10=no test_tde=no test_kde4=no + test_kde5=no enable_cairo_canvas=no fi @@ -10032,6 +10044,14 @@ if test "x$enable_kde4" = "xyes"; then fi AC_SUBST(ENABLE_KDE4) +ENABLE_KDE5="" +if test "x$enable_kde5" = "xyes"; then + ENABLE_KDE5="TRUE" + AC_DEFINE(ENABLE_KDE5) + R="$R kde5" +fi +AC_SUBST(ENABLE_KDE5) + ENABLE_HEADLESS="" if test "x$with_x" = "xno" -o "$CXX" = "emcc"; then ENABLE_HEADLESS="TRUE" @@ -11258,6 +11278,243 @@ AC_SUBST(KDE4_GLIB_LIBS) AC_SUBST(KDE4_HAVE_GLIB) dnl =================================================================== +dnl KDE5 Integration +dnl =================================================================== + +KF5_CFLAGS="" +KF5_LIBS="" +QMAKE5="qmake" +KF5_CONFIG="kf5-config" +MOC5="moc" +KF5_GLIB_CFLAGS="" +KF5_GLIB_LIBS="" +KF5_HAVE_GLIB="" +if test "$test_kde5" = "yes" -a "$ENABLE_KDE5" = "TRUE"; then + qt5_incdirs="$QT5INC /usr/include/qt5 /usr/include $x_includes" + qt5_libdirs="$QT5LIB /usr/lib/qt5 /usr/lib $x_libraries" + + kf5_incdirs="$KF5INC /usr/include /usr/include/KF5 $x_includes" + kf5_libdirs="$KF5LIB /usr/lib /usr/lib/kf5 /usr/lib/kf5/devel $x_libraries" + + if test -n "$supports_multilib"; then + qt5_libdirs="$qt5_libdirs /usr/lib64/qt5 /usr/lib64/qt /usr/lib64" + kf5_libdirs="$kf5_libdirs /usr/lib64 /usr/lib64/kf5 /usr/lib64/kf5/devel" + fi + + qt5_test_include="QtWidgets/qapplication.h" + qt5_test_library="libQt5Widgets.so" + kf5_test_include="kcoreaddons_version.h" + kf5_test_library="libKF5CoreAddons.so" + + dnl Check for qmake + AC_PATH_PROGS( QMAKE5, [qmake-qt5 qmake], no, [$QT5DIR/bin:$PATH] ) + if test "$QMAKE5" != "no"; then + qt5_incdirs="`$QMAKE5 -query QT_INSTALL_HEADERS` $qt5_incdirs" + qt5_libdirs="`$QMAKE5 -query QT_INSTALL_LIBS` $qt5_libdirs" + fi + + AC_MSG_CHECKING([for Qt5 headers]) + qt5_incdir="no" + for inc_dir in $qt5_incdirs; do + if test -r "$inc_dir/$qt5_test_include"; then + qt5_incdir="$inc_dir" + break + fi + done + AC_MSG_RESULT([$qt5_incdir]) + if test "x$qt5_incdir" = "xno"; then + AC_MSG_ERROR([Qt5 headers not found. Please specify the root of your Qt5 installation by exporting QT5DIR before running "configure".]) + fi + + AC_MSG_CHECKING([for Qt5 libraries]) + qt5_libdir="no" + for lib_dir in $qt5_libdirs; do + if test -r "$lib_dir/$qt5_test_library"; then + qt5_libdir="$lib_dir" + break + fi + done + AC_MSG_RESULT([$qt5_libdir]) + if test "x$qt5_libdir" = "xno"; then + AC_MSG_ERROR([Qt5 libraries not found. Please specify the root of your Qt5 installation by exporting QT5DIR before running "configure".]) + fi + kf5_libdirs="$qt5_libdir $kf5_libdirs" + + dnl Check for Meta Object Compiler + + AC_PATH_PROGS( MOC5, [moc-qt5 moc], no, [`dirname $qt5_libdir`/bin:$QT5DIR/bin:$PATH] ) + if test "$MOC5" = "no"; then + AC_MSG_ERROR([Qt Meta Object Compiler not found. Please specify +the root of your Qt installation by exporting QT5DIR before running "configure".]) + fi + + dnl kf5 KDE4 support compatibility installed + AC_PATH_PROG( KF5_CONFIG, $KF5_CONFIG, no, ) + if test "$KF5_CONFIG" != "no"; then + kf5_incdirs="`$KF5_CONFIG --path include` $kf5_incdirs" + kf5_libdirs="`$KF5_CONFIG --path lib` $kf5_libdirs" + fi + + dnl Check for KF5 headers + AC_MSG_CHECKING([for KF5 headers]) + kf5_incdir="no" + for kf5_check in $kf5_incdirs; do + if test -r "$kf5_check/$kf5_test_include"; then + kf5_incdir="$kf5_check" + break + fi + done + AC_MSG_RESULT([$kf5_incdir]) + if test "x$kf5_incdir" = "xno"; then + AC_MSG_ERROR([KF5 headers not found. Please specify the root of your KF5 installation by exporting KF5DIR before running "configure".]) + fi + + dnl Check for KF5 libraries + AC_MSG_CHECKING([for KF5 libraries]) + kf5_libdir="no" + for kf5_check in $kf5_libdirs; do + if test -r "$kf5_check/$kf5_test_library"; then + kf5_libdir="$kf5_check" + break + fi + done + + AC_MSG_RESULT([$kf5_libdir]) + if test "x$kf5_libdir" = "xno"; then + AC_MSG_ERROR([KF5 libraries not found. Please specify the root of your KF5 installation by exporting KF5DIR before running "configure".]) + fi + + 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=$(printf '%s' "$KF5_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") + + AC_LANG_PUSH([C++]) + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $KF5_CFLAGS" + AC_MSG_CHECKING([whether KDE is >= 5.0]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <kcoreaddons_version.h> + +int main(int argc, char **argv) { + if (KCOREADDONS_VERSION_MAJOR == 5 && KCOREADDONS_VERSION_MINOR >= 0) return 0; + else return 1; +} + ]])],[AC_MSG_RESULT([yes])],[AC_MSG_ERROR([KDE version too old])],[]) + CXXFLAGS=$save_CXXFLAGS + AC_LANG_POP([C++]) + + # Glib is needed for properly handling Qt event loop with Qt's Glib integration enabled. + # Sets also KF5_GLIB_CFLAGS/KF5_GLIB_LIBS if successful. + PKG_CHECK_MODULES(KF5_GLIB,[glib-2.0 >= 2.4], + [ + KF5_HAVE_GLIB=1 + AC_DEFINE(KF5_HAVE_GLIB,1) + KF5_GLIB_CFLAGS=$(printf '%s' "$KF5_GLIB_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") + FilterLibs "${KF5_GLIB_LIBS}" + KF5_GLIB_LIBS="${filteredlibs}" + + qt4_fix_warning= + + AC_LANG_PUSH([C++]) + # tst_exclude_socket_notifiers.moc:70:28: runtime error: member access within address 0x60d00000bb20 which does not point to an object of type 'QObjectData' + # 0x60d00000bb20: note: object is of type 'QObjectPrivate' + # 02 00 80 3a 90 8a 4e d2 3a 00 00 00 f0 b4 b9 a7 ff 7f 00 00 00 00 00 00 00 00 00 00 20 d8 4e d2 + # ^~~~~~~~~~~~~~~~~~~~~~~ + # vptr for 'QObjectPrivate' + save_CXX=$CXX + CXX=$(printf %s "$CXX" \ + | sed -e 's/-fno-sanitize-recover\(=[[0-9A-Za-z,_-]]*\)*//') + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $KF5_CFLAGS" + save_LIBS=$LIBS + LIBS="$LIBS $KF5_LIBS" + AC_MSG_CHECKING([whether Qt has fixed ExcludeSocketNotifiers]) + + # Prepare meta object data + TSTBASE="tst_exclude_socket_notifiers" + TSTMOC="${SRC_ROOT}/vcl/unx/kde5/${TSTBASE}" + ln -fs "${TSTMOC}.hxx" + $MOC5 "${TSTBASE}.hxx" -o "${TSTBASE}.moc" + + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <cstdlib> +#include "tst_exclude_socket_notifiers.moc" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + exit(tst_processEventsExcludeSocket()); + return 0; +} + ]])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_WARN([native KF5 file pickers will be disabled at runtime]) + if test -z "$qt5_fix_warning"; then + add_warning "native KF5 file pickers will be disabled at runtime, Qt5 fixes needed" + fi + qt5_fix_warning=1 + add_warning " https://bugreports.qt-project.org/browse/QTBUG-37380 (needed)" + ]) + + # Remove meta object data + rm -f "${TSTBASE}."* + + AC_MSG_CHECKING([whether Qt avoids QClipboard recursion caused by posted events]) + + # Prepare meta object data + TSTBASE="tst_exclude_posted_events" + TSTMOC="${SRC_ROOT}/vcl/unx/kde5/${TSTBASE}" + ln -fs "${TSTMOC}.hxx" + $MOC5 "${TSTBASE}.hxx" -o "${TSTBASE}.moc" + + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <cstdlib> +#include "tst_exclude_posted_events.moc" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + exit(tst_excludePostedEvents()); + return 0; +} + ]])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_WARN([native KF5 file pickers will be disabled at runtime]) + if test -z "$qt5_fix_warning"; then + add_warning "native KF5 file pickers will be disabled at runtime, Qt5 fixes needed" + fi + qt5_fix_warning=1 + add_warning " https://bugreports.qt-project.org/browse/QTBUG-34614 (needed)" + ]) + + # Remove meta object data + rm -f "${TSTBASE}."* + + if test -n "$qt5_fix_warning"; then + add_warning " https://bugreports.qt-project.org/browse/QTBUG-38585 (recommended)" + fi + + LIBS=$save_LIBS + CXXFLAGS=$save_CXXFLAGS + CXX=$save_CXX + AC_LANG_POP([C++]) + ], + AC_MSG_WARN([[No Glib found, KF5 support will not use native file pickers!]])) +fi +AC_SUBST(KF5_CFLAGS) +AC_SUBST(KF5_LIBS) +AC_SUBST(MOC5) +AC_SUBST(KF5_GLIB_CFLAGS) +AC_SUBST(KF5_GLIB_LIBS) +AC_SUBST(KF5_HAVE_GLIB) + +dnl =================================================================== dnl Test whether to include Evolution 2 support dnl =================================================================== AC_MSG_CHECKING([whether to enable evolution 2 support]) @@ -12908,6 +13165,7 @@ AC_CONFIG_HEADERS([config_host/config_locales.h]) AC_CONFIG_HEADERS([config_host/config_mpl.h]) AC_CONFIG_HEADERS([config_host/config_orcus.h]) AC_CONFIG_HEADERS([config_host/config_kde4.h]) +AC_CONFIG_HEADERS([config_host/config_kde5.h]) AC_CONFIG_HEADERS([config_host/config_oox.h]) AC_CONFIG_HEADERS([config_host/config_opengl.h]) AC_CONFIG_HEADERS([config_host/config_options.h]) diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index 86cc379..55cc9b2 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -22,6 +22,7 @@ $(eval $(call gb_Library_add_defs,cui,\ $(if $(filter TRUE,$(ENABLE_GTK)),-DENABLE_GTK) \ $(if $(filter TRUE,$(ENABLE_TDE)),-DENABLE_TDE) \ $(if $(filter TRUE,$(ENABLE_KDE4)),-DENABLE_KDE4) \ + $(if $(filter TRUE,$(ENABLE_KDE5)),-DENABLE_KDE5) \ )) $(eval $(call gb_Library_use_custom_headers,cui,\ diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx index dfb517f..9268a0a 100644 --- a/cui/source/options/optgdlg.cxx +++ b/cui/source/options/optgdlg.cxx @@ -198,7 +198,15 @@ namespace { const OUString &rDesktopEnvironment = Application::GetDesktopEnvironment(); - if ( rDesktopEnvironment.equalsIgnoreAsciiCase("kde4") ) + if ( rDesktopEnvironment.equalsIgnoreAsciiCase("kde5") ) + { + #if ENABLE_KDE5 + return OUString("com.sun.star.ui.dialogs.KDE5FilePicker" ); + #else + return OUString(); + #endif + } + else if ( rDesktopEnvironment.equalsIgnoreAsciiCase("kde4") ) { #if ENABLE_KDE4 return OUString("com.sun.star.ui.dialogs.KDE4FilePicker" ); diff --git a/scp2/InstallScript_setup_osl.mk b/scp2/InstallScript_setup_osl.mk index 593b1af..ca9f4cf 100644 --- a/scp2/InstallScript_setup_osl.mk +++ b/scp2/InstallScript_setup_osl.mk @@ -36,7 +36,7 @@ $(eval $(call gb_InstallScript_use_modules,setup_osl,\ $(if $(filter TRUE,$(ENABLE_EVOAB2) $(ENABLE_GIO) $(ENABLE_GTK) $(ENABLE_GTK3)),\ scp2/gnome \ ) \ - $(if $(filter TRUE,$(ENABLE_KDE4)),\ + $(if $(filter TRUE,$(ENABLE_KDE4) $(ENABLE_KDE5)),\ scp2/kde \ ) \ $(if $(filter TRUE,$(ENABLE_ONLINE_UPDATE)),\ diff --git a/scp2/Module_scp2.mk b/scp2/Module_scp2.mk index 5acaa0c..6320483 100644 --- a/scp2/Module_scp2.mk +++ b/scp2/Module_scp2.mk @@ -42,7 +42,7 @@ $(eval $(call gb_Module_add_targets,scp2,\ $(if $(filter TRUE,$(ENABLE_EVOAB2) $(ENABLE_GIO) $(ENABLE_GTK) $(ENABLE_GTK3)),\ InstallModule_gnome \ ) \ - $(if $(filter TRUE,$(ENABLE_KDE4)),\ + $(if $(filter TRUE,$(ENABLE_KDE4) $(ENABLE_KDE5)),\ InstallModule_kde \ ) \ $(if $(filter TRUE,$(ENABLE_TDE)),\ diff --git a/shell/Library_kde5be.mk b/shell/Library_kde5be.mk new file mode 100644 index 0000000..b9c7c90 --- /dev/null +++ b/shell/Library_kde5be.mk @@ -0,0 +1,32 @@ +# -*- 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_Library_Library,kde5be1)) + +$(eval $(call gb_Library_use_sdk_api,kde5be1)) + +$(eval $(call gb_Library_use_externals,kde5be1,\ + boost_headers \ + kde5 \ +)) + +$(eval $(call gb_Library_use_libraries,kde5be1,\ + cppu \ + cppuhelper \ + sal \ +)) + +$(eval $(call gb_Library_set_componentfile,kde5be1,shell/source/backends/kde5be/kde5be1)) + +$(eval $(call gb_Library_add_exception_objects,kde5be1,\ + shell/source/backends/kde5be/kde5access \ + shell/source/backends/kde5be/kde5backend \ +)) + +# vim: set shiftwidth=4 tabstop=4 noexpandtab: diff --git a/shell/Module_shell.mk b/shell/Module_shell.mk index d0a3318..d0c1925 100644 --- a/shell/Module_shell.mk +++ b/shell/Module_shell.mk @@ -36,6 +36,12 @@ $(eval $(call gb_Module_add_targets,shell,\ )) endif +ifeq ($(ENABLE_KDE5),TRUE) +$(eval $(call gb_Module_add_targets,shell,\ + Library_kde5be \ +)) +endif + ifeq ($(ENABLE_TDE),TRUE) $(eval $(call gb_Module_add_targets,shell,\ Library_tdebe \ diff --git a/shell/source/backends/kde4be/kde4access.cxx b/shell/source/backends/kde4be/kde4access.cxx index bebb528..b67d5aa 100644 --- a/shell/source/backends/kde4be/kde4access.cxx +++ b/shell/source/backends/kde4be/kde4access.cxx @@ -19,11 +19,13 @@ #include "sal/config.h" -#include "QFont" -#include "QString" -#include "kemailsettings.h" -#include "kglobalsettings.h" -#include "kprotocolmanager.h" +#include "kde4access.hxx" + +#include <QtGui/QFont> +#include <QtCore/QString> +#include <kemailsettings.h> +#include <kglobalsettings.h> +#include <kprotocolmanager.h> #include "com/sun/star/uno/Any.hxx" #include "cppu/unotype.hxx" @@ -32,8 +34,6 @@ #include "rtl/string.h" #include "rtl/ustring.hxx" -#include "kde4access.hxx" - #define SPACE ' ' #define COMMA ',' #define SEMI_COLON ';' diff --git a/shell/source/backends/kde5be/kde5access.cxx b/shell/source/backends/kde5be/kde5access.cxx new file mode 100644 index 0000000..a6391eb --- /dev/null +++ b/shell/source/backends/kde5be/kde5access.cxx @@ -0,0 +1,309 @@ +/* -*- 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 "sal/config.h" + +#include "kde5access.hxx" + +#include <QtGui/QFont> +#include <QtCore/QString> +#include <QtGui/QFontDatabase> +#include <QtCore/QStandardPaths> +#include <QtCore/QDir> +#include <QtCore/QUrl> + +#include <kprotocolmanager.h> + +#include <kemailsettings.h> +// #include <kglobalsettings.h> +// #include <kprotocolmanager.h> + +#include "com/sun/star/uno/Any.hxx" +#include "cppu/unotype.hxx" +#include "osl/diagnose.h" +#include "osl/file.h" +#include "rtl/string.h" +#include "rtl/ustring.hxx" + +#define SPACE ' ' +#define COMMA ',' +#define SEMI_COLON ';' + +namespace kde5access { + +namespace { + +namespace uno = css::uno ; + +} + +css::beans::Optional< css::uno::Any > getValue(OUString const & id) { + if ( id == "ExternalMailer" ) { + KEMailSettings aEmailSettings; + QString aClientProgram; + OUString sClientProgram; + + aClientProgram = aEmailSettings.getSetting( KEMailSettings::ClientProgram ); + if ( aClientProgram.isEmpty() ) + aClientProgram = "kmail"; + else + aClientProgram = aClientProgram.section(SPACE, 0, 0); + sClientProgram = reinterpret_cast<const sal_Unicode *>(aClientProgram.utf16()); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sClientProgram ) ); + } else if (id == "SourceViewFontHeight") + { + QFont aFixedFont; + short nFontHeight; + + aFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); + nFontHeight = aFixedFont.pointSize(); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( nFontHeight ) ); + } else if (id == "SourceViewFontName") + { + QFont aFixedFont; + QString aFontName; + OUString sFontName; + + aFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); + aFontName = aFixedFont.family(); + sFontName = reinterpret_cast<const sal_Unicode *>(aFontName.utf16()); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sFontName ) ); + } else if (id == "EnableATToolSupport") + { + /* does not make much sense without an accessibility bridge */ + bool ATToolSupport = false; + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( OUString::boolean( ATToolSupport ) ) ); + } else if (id == "WorkPathVariable") + { + QString aDocumentsDir( QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) ); + if (aDocumentsDir.isEmpty() ) aDocumentsDir = QDir::homePath(); + OUString sDocumentsDir; + OUString sDocumentsURL; + if ( aDocumentsDir.endsWith(QChar('/')) ) + aDocumentsDir.truncate ( aDocumentsDir.length() - 1 ); + sDocumentsDir = reinterpret_cast<const sal_Unicode *>(aDocumentsDir.utf16()); + osl_getFileURLFromSystemPath( sDocumentsDir.pData, &sDocumentsURL.pData ); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sDocumentsURL ) ); + } else if (id == "ooInetFTPProxyName") + { + QString aFTPProxy; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + aFTPProxy = KProtocolManager::proxyFor( "FTP" ); + break; + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables +// In such cases, the proxy address is not stored in KDE, but determined dynamically. +// The proxy address may depend on the requested address, on the time of the day, on the speed of the wind... +// The best we can do here is to ask the current value for a given address. + aFTPProxy = KProtocolManager::proxyForUrl( QUrl("ftp://ftp.libreoffice.org") ); + break; + default: // No proxy is used + break; + } + if ( !aFTPProxy.isEmpty() ) + { + QUrl aProxy(aFTPProxy); + OUString sProxy = reinterpret_cast<const sal_Unicode *>(aProxy.host().utf16()); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sProxy ) ); + } + } else if (id == "ooInetFTPProxyPort") + { + QString aFTPProxy; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + aFTPProxy = KProtocolManager::proxyFor( "FTP" ); + break; + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables +// In such cases, the proxy address is not stored in KDE, but determined dynamically. +// The proxy address may depend on the requested address, on the time of the day, on the speed of the wind... +// The best we can do here is to ask the current value for a given address. + aFTPProxy = KProtocolManager::proxyForUrl( QUrl("ftp://ftp.libreoffice.org") ); + break; + default: // No proxy is used + break; + } + if ( !aFTPProxy.isEmpty() ) + { + QUrl aProxy(aFTPProxy); + sal_Int32 nPort = aProxy.port(); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( nPort ) ); + } + } else if (id == "ooInetHTTPProxyName") + { + QString aHTTPProxy; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + aHTTPProxy = KProtocolManager::proxyFor( "HTTP" ); + break; + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables +// In such cases, the proxy address is not stored in KDE, but determined dynamically. +// The proxy address may depend on the requested address, on the time of the day, on the speed of the wind... +// The best we can do here is to ask the current value for a given address. + aHTTPProxy = KProtocolManager::proxyForUrl( QUrl("http://http.libreoffice.org") ); + break; + default: // No proxy is used + break; + } + if ( !aHTTPProxy.isEmpty() ) + { + QUrl aProxy(aHTTPProxy); + OUString sProxy = reinterpret_cast<const sal_Unicode *>(aProxy.host().utf16()); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sProxy ) ); + } + } else if (id == "ooInetHTTPProxyPort") + { + QString aHTTPProxy; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + aHTTPProxy = KProtocolManager::proxyFor( "HTTP" ); + break; + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables +// In such cases, the proxy address is not stored in KDE, but determined dynamically. +// The proxy address may depend on the requested address, on the time of the day, on the speed of the wind... +// The best we can do here is to ask the current value for a given address. + aHTTPProxy = KProtocolManager::proxyForUrl( QUrl("http://http.libreoffice.org") ); + break; + default: // No proxy is used + break; + } + if ( !aHTTPProxy.isEmpty() ) + { + QUrl aProxy(aHTTPProxy); + sal_Int32 nPort = aProxy.port(); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( nPort ) ); + } + } else if (id == "ooInetHTTPSProxyName") + { + QString aHTTPSProxy; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + aHTTPSProxy = KProtocolManager::proxyFor( "HTTPS" ); + break; + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables +// In such cases, the proxy address is not stored in KDE, but determined dynamically. +// The proxy address may depend on the requested address, on the time of the day, on the speed of the wind... +// The best we can do here is to ask the current value for a given address. + aHTTPSProxy = KProtocolManager::proxyForUrl( QUrl("https://https.libreoffice.org") ); + break; + default: // No proxy is used + break; + } + if ( !aHTTPSProxy.isEmpty() ) + { + QUrl aProxy(aHTTPSProxy); + OUString sProxy = reinterpret_cast<const sal_Unicode *>(aProxy.host().utf16()); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sProxy ) ); + } + } else if (id == "ooInetHTTPSProxyPort") + { + QString aHTTPSProxy; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + aHTTPSProxy = KProtocolManager::proxyFor( "HTTPS" ); + break; + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables +// In such cases, the proxy address is not stored in KDE, but determined dynamically. +// The proxy address may depend on the requested address, on the time of the day, on the speed of the wind... +// The best we can do here is to ask the current value for a given address. + aHTTPSProxy = KProtocolManager::proxyForUrl( QUrl("https://https.libreoffice.org") ); + break; + default: // No proxy is used + break; + } + if ( !aHTTPSProxy.isEmpty() ) + { + QUrl aProxy(aHTTPSProxy); + sal_Int32 nPort = aProxy.port(); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( nPort ) ); + } + } else if ( id == "ooInetNoProxy" ) { + QString aNoProxyFor; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables + aNoProxyFor = KProtocolManager::noProxyFor(); + break; + default: // No proxy is used + break; + } + if ( !aNoProxyFor.isEmpty() ) + { + OUString sNoProxyFor; + + aNoProxyFor = aNoProxyFor.replace( COMMA, SEMI_COLON ); + sNoProxyFor = reinterpret_cast<const sal_Unicode *>(aNoProxyFor.utf16()); + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( sNoProxyFor ) ); + } + } else if ( id == "ooInetProxyType" ) { + int nProxyType; + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::ManualProxy: // Proxies are manually configured + case KProtocolManager::PACProxy: // A proxy configuration URL has been given + case KProtocolManager::WPADProxy: // A proxy should be automatically discovered + case KProtocolManager::EnvVarProxy: // Use the proxy values set through environment variables + nProxyType = 1; + break; + default: // No proxy is used + nProxyType = 0; + } + return css::beans::Optional< css::uno::Any >( + true, uno::makeAny( (sal_Int32) nProxyType ) ); + } else { + OSL_ASSERT(false); // this cannot happen + } + return css::beans::Optional< css::uno::Any >(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/backends/kde5be/kde5access.hxx b/shell/source/backends/kde5be/kde5access.hxx new file mode 100644 index 0000000..fbb4a3b --- /dev/null +++ b/shell/source/backends/kde5be/kde5access.hxx @@ -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 . + */ + +#ifndef INCLUDED_SHELL_SOURCE_BACKENDS_KDE5BE_KDE5ACCESS_HXX +#define INCLUDED_SHELL_SOURCE_BACKENDS_KDE5BE_KDE5ACCESS_HXX + +#include "sal/config.h" + +#include "com/sun/star/beans/Optional.hpp" + +namespace com { namespace sun { namespace star { namespace uno { + class Any; +} } } } + +namespace kde5access { + +css::beans::Optional< css::uno::Any > getValue(OUString const & id); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/backends/kde5be/kde5backend.cxx b/shell/source/backends/kde5be/kde5backend.cxx new file mode 100644 index 0000000..a32dbc1 --- /dev/null +++ b/shell/source/backends/kde5be/kde5backend.cxx @@ -0,0 +1,209 @@ +/* -*- 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 "sal/config.h" + +#include <QtWidgets/QApplication> + +#include "boost/noncopyable.hpp" +#include "com/sun/star/beans/Optional.hpp" +#include "com/sun/star/beans/PropertyVetoException.hpp" +#include "com/sun/star/beans/UnknownPropertyException.hpp" +#include "com/sun/star/beans/XPropertyChangeListener.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/beans/XPropertySetInfo.hpp" +#include "com/sun/star/beans/XVetoableChangeListener.hpp" +#include "com/sun/star/lang/IllegalArgumentException.hpp" +#include "com/sun/star/lang/WrappedTargetException.hpp" +#include "com/sun/star/lang/XMultiComponentFactory.hpp" +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XCurrentContext.hpp" +#include "cppuhelper/factory.hxx" +#include <cppuhelper/implbase.hxx> +#include "cppuhelper/implementationentry.hxx" +#include "cppuhelper/weak.hxx" +#include "rtl/string.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include "uno/current_context.hxx" + +#include "kde5access.hxx" + +namespace { + +OUString SAL_CALL getServiceImplementationName() { + return OUString( + "com.sun.star.comp.configuration.backend.KDE5Backend"); +} + +css::uno::Sequence< OUString > SAL_CALL getServiceSupportedServiceNames() { + OUString name( + "com.sun.star.configuration.backend.KDE5Backend"); + return css::uno::Sequence< OUString >(&name, 1); +} + +class Service: + public cppu::WeakImplHelper< + css::lang::XServiceInfo, css::beans::XPropertySet >, + private boost::noncopyable +{ +public: + Service(); + +private: + virtual ~Service() {} + + virtual OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException, std::exception) override + { return getServiceImplementationName(); } + + virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) + throw (css::uno::RuntimeException, std::exception) override + { return ServiceName == getSupportedServiceNames()[0]; } + + virtual css::uno::Sequence< OUString > SAL_CALL + getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception) override + { return getServiceSupportedServiceNames(); } + + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() throw (css::uno::RuntimeException, std::exception) override + { return css::uno::Reference< css::beans::XPropertySetInfo >(); } + + virtual void SAL_CALL setPropertyValue( + OUString const &, css::uno::Any const &) + throw ( + css::beans::UnknownPropertyException, + css::beans::PropertyVetoException, + css::lang::IllegalArgumentException, + css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override; + + virtual css::uno::Any SAL_CALL getPropertyValue( + OUString const & PropertyName) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override; + + virtual void SAL_CALL addPropertyChangeListener( + OUString const &, + css::uno::Reference< css::beans::XPropertyChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override + {} + + virtual void SAL_CALL removePropertyChangeListener( + OUString const &, + css::uno::Reference< css::beans::XPropertyChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override + {} + + virtual void SAL_CALL addVetoableChangeListener( + OUString const &, + css::uno::Reference< css::beans::XVetoableChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override + {} + + virtual void SAL_CALL removeVetoableChangeListener( + OUString const &, + css::uno::Reference< css::beans::XVetoableChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override + {} + + bool enabled_; +}; + +Service::Service(): enabled_(false) { + css::uno::Reference< css::uno::XCurrentContext > context( + css::uno::getCurrentContext()); + if (context.is()) { + OUString desktop; + context->getValueByName("system.desktop-environment") >>= desktop; + enabled_ = desktop == "KDE5" && qApp != nullptr; + } +} + +void Service::setPropertyValue(OUString const &, css::uno::Any const &) + throw ( + css::beans::UnknownPropertyException, css::beans::PropertyVetoException, + css::lang::IllegalArgumentException, css::lang::WrappedTargetException, + css::uno::RuntimeException, std::exception) +{ + throw css::lang::IllegalArgumentException( + OUString("setPropertyValue not supported"), + static_cast< cppu::OWeakObject * >(this), -1); +} + +css::uno::Any Service::getPropertyValue(OUString const & PropertyName) + throw ( + css::beans::UnknownPropertyException, css::lang::WrappedTargetException, + css::uno::RuntimeException, std::exception) +{ + if (PropertyName == "EnableATToolSupport" || PropertyName == "ExternalMailer" || PropertyName == "SourceViewFontHeight" + || PropertyName == "SourceViewFontName" || PropertyName == "WorkPathVariable" || PropertyName == "ooInetFTPProxyName" + || PropertyName == "ooInetFTPProxyPort" || PropertyName == "ooInetHTTPProxyName" || PropertyName == "ooInetHTTPProxyPort" + || PropertyName == "ooInetHTTPSProxyName" || PropertyName == "ooInetHTTPSProxyPort" || PropertyName == "ooInetNoProxy" + || PropertyName == "ooInetProxyType" || PropertyName == "TemplatePathVariable" ) + { + return css::uno::makeAny( + enabled_ + ? kde5access::getValue(PropertyName) + : css::beans::Optional< css::uno::Any >()); + } else if (PropertyName == "givenname" || PropertyName == "sn") { + return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); + //TODO: obtain values from KDE? + } + throw css::beans::UnknownPropertyException( + PropertyName, static_cast< cppu::OWeakObject * >(this)); +} + +css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( + css::uno::Reference< css::uno::XComponentContext > const &) +{ + return static_cast< cppu::OWeakObject * >(new Service); +} + +static cppu::ImplementationEntry const services[] = { + { &createInstance, &getServiceImplementationName, + &getServiceSupportedServiceNames, &cppu::createSingleComponentFactory, nullptr, + 0 }, + { nullptr, nullptr, nullptr, nullptr, nullptr, 0 } +}; + +} + +extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL kde5be1_component_getFactory( + char const * pImplName, void * pServiceManager, void * pRegistryKey) +{ + return cppu::component_getFactoryHelper( + pImplName, pServiceManager, pRegistryKey, services); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/shell/source/backends/kde5be/kde5be1.component b/shell/source/backends/kde5be/kde5be1.component new file mode 100644 index 0000000..7411187 --- /dev/null +++ b/shell/source/backends/kde5be/kde5be1.component @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + --> + +<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@" + prefix="kde5be1" xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.configuration.backend.KDE5Backend"> + <service name="com.sun.star.configuration.backend.KDE5Backend"/> + </implementation> +</component> diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk index b90fb7f..99924fb 100644 --- a/solenv/gbuild/CppunitTest.mk +++ b/solenv/gbuild/CppunitTest.mk @@ -182,6 +182,7 @@ $(call gb_CppunitTest_get_target,$(1)) : $(if $(filter $(2),$(true)),, \ $(if $(ENABLE_GTK),$(call gb_Library_get_target,vclplug_gtk)) \ $(if $(ENABLE_GTK3),$(call gb_Library_get_target,vclplug_gtk3)) \ $(if $(ENABLE_KDE4),$(call gb_Library_get_target,vclplug_kde4)) \ + $(if $(ENABLE_KDE5),$(call gb_Library_get_target,vclplug_kde5)) \ $(if $(ENABLE_TDE),$(call gb_Library_get_target,vclplug_tde))) endif diff --git a/sysui/CustomTarget_share.mk b/sysui/CustomTarget_share.mk index c81edd5..8cc67e4 100644 --- a/sysui/CustomTarget_share.mk +++ b/sysui/CustomTarget_share.mk @@ -16,6 +16,8 @@ else ifeq ($(ENABLE_TDE),TRUE) brand_URIPARAM := --urls else ifeq ($(ENABLE_KDE4),TRUE) brand_URIPARAM := --urls +else ifeq ($(ENABLE_KDE5),TRUE) + brand_URIPARAM := --urls else brand_URIPARAM := endif diff --git a/vcl/CustomTarget_kde5_moc.mk b/vcl/CustomTarget_kde5_moc.mk new file mode 100644 index 0000000..93810d9 --- /dev/null +++ b/vcl/CustomTarget_kde5_moc.mk @@ -0,0 +1,24 @@ +# -*- 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/kde5)) + +$(call gb_CustomTarget_get_target,vcl/unx/kde5) : \ + $(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/KDEXLib.moc \ + $(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/KDE5FilePicker.moc \ + $(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/tst_exclude_socket_notifiers.moc \ + $(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/tst_exclude_posted_events.moc + +$(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/%.moc : \ + $(SRCDIR)/vcl/unx/kde5/%.hxx \ + | $(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/.dir + $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),MOC,1) + $(MOC5) $< -o $@ + +# vim: set noet sw=4: diff --git a/vcl/Library_vclplug_kde5.mk b/vcl/Library_vclplug_kde5.mk new file mode 100644 index 0000000..b3d02fd --- /dev/null +++ b/vcl/Library_vclplug_kde5.mk @@ -0,0 +1,98 @@ +# -*- 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_kde5)) + +$(eval $(call gb_Library_use_custom_headers,vclplug_kde5,vcl/unx/kde5)) + +$(eval $(call gb_Library_set_include,vclplug_kde5,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_Library_add_defs,vclplug_kde5,\ + -DVCLPLUG_KDE5_IMPLEMENTATION \ +)) + +$(eval $(call gb_Library_use_sdk_api,vclplug_kde5)) + +$(eval $(call gb_Library_use_libraries,vclplug_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_kde5,\ + boost_headers \ + icuuc \ + kde5 \ + glew \ +)) + +$(eval $(call gb_Library_add_libs,vclplug_kde5,\ + -lX11 \ + -lXext \ + -lSM \ + -lICE \ +)) + +ifneq ($(KF5_HAVE_GLIB),) +$(eval $(call gb_Library_add_defs,vclplug_kde5,\ + $(KF5_GLIB_CFLAGS) \ +)) + +$(eval $(call gb_Library_add_libs,vclplug_kde5,\ + $(KF5_GLIB_LIBS) \ +)) +endif + + +$(eval $(call gb_Library_add_exception_objects,vclplug_kde5,\ + vcl/unx/kde5/KDEData \ + vcl/unx/kde5/KDE5FilePicker \ + vcl/unx/kde5/KDESalDisplay \ + vcl/unx/kde5/KDESalFrame \ + vcl/unx/kde5/KDESalGraphics \ + vcl/unx/kde5/KDESalInstance \ + vcl/unx/kde5/KDEXLib \ + vcl/unx/kde5/main \ + vcl/unx/kde5/VCLKDEApplication \ +)) + +ifeq ($(OS),LINUX) +$(eval $(call gb_Library_add_libs,vclplug_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 1480504..82c076e 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -79,6 +79,12 @@ $(eval $(call gb_Module_add_targets,vcl,\ Library_vclplug_kde4 \ )) endif +ifneq ($(ENABLE_KDE5),) +$(eval $(call gb_Module_add_targets,vcl,\ + CustomTarget_kde5_moc \ + Library_vclplug_kde5 \ +)) +endif endif ifeq ($(OS),MACOSX) diff --git a/vcl/inc/generic/gendata.hxx b/vcl/inc/generic/gendata.hxx index b2223b5..1a843e3 100644 --- a/vcl/inc/generic/gendata.hxx +++ b/vcl/inc/generic/gendata.hxx @@ -20,7 +20,7 @@ enum SalGenericDataType { SAL_DATA_GTK, SAL_DATA_GTK3, SAL_DATA_TDE3, SAL_DATA_KDE3, SAL_DATA_KDE4, SAL_DATA_UNX, SAL_DATA_SVP, SAL_DATA_ANDROID, SAL_DATA_IOS, - SAL_DATA_HEADLESS }; + SAL_DATA_HEADLESS, SAL_DATA_KDE5 }; class VCL_DLLPUBLIC SalGenericData : public SalData { diff --git a/vcl/inc/vclpluginapi.h b/vcl/inc/vclpluginapi.h index 86fbf17..d274b0b 100644 --- a/vcl/inc/vclpluginapi.h +++ b/vcl/inc/vclpluginapi.h @@ -53,6 +53,12 @@ #define VCLPLUG_KDE4_PUBLIC SAL_DLLPUBLIC_IMPORT #endif +#if defined VCLPLUG_KDE5_IMPLEMENTATION +#define VCLPLUG_KDE5_PUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define VCLPLUG_KDE5_PUBLIC SAL_DLLPUBLIC_IMPORT +#endif + #if defined VCLPLUG_SVP_IMPLEMENTATION #define VCLPLUG_SVP_PUBLIC SAL_DLLPUBLIC_EXPORT #else diff --git a/vcl/unx/generic/plugadapt/salplug.cxx b/vcl/unx/generic/plugadapt/salplug.cxx index c51d1ec..78d1fb6 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 == "tde" || rModuleBase == "kde" || rModuleBase == "kde4" ) + if( rModuleBase == "gtk" || rModuleBase == "gtk3" || rModuleBase == "tde" || rModuleBase == "kde" || rModuleBase == "kde4" || rModuleBase == "kde5" ) { pCloseModule = nullptr; } @@ -168,6 +168,9 @@ static SalInstance* autodetect_plugin() static const char* const pTDEFallbackList[] = { "tde", +#if ENABLE_KDE5 && 0 + "kde5", +#endif #if ENABLE_KDE4 "kde4", #endif @@ -176,6 +179,9 @@ static SalInstance* autodetect_plugin() static const char* const pKDEFallbackList[] = { +#if ENABLE_KDE5 && 0 + "kde5", +#endif #if ENABLE_KDE4 "kde4", #endif diff --git a/vcl/unx/kde5/FPServiceInfo.hxx b/vcl/unx/kde5/FPServiceInfo.hxx new file mode 100644 index 0000000..7c67a3b --- /dev/null +++ b/vcl/unx/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.KDE5FilePicker" + +// the implementation names +#define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.KDE5FilePicker" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kde5/KDE5FilePicker.cxx b/vcl/unx/kde5/KDE5FilePicker.cxx new file mode 100644 index 0000000..1c32c3e --- /dev/null +++ b/vcl/unx/kde5/KDE5FilePicker.cxx @@ -0,0 +1,816 @@ +/* -*- 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 "KDE5FilePicker.hxx" + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.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 <vcl/fpicker.hrc> +#include <vcl/svapp.hxx> +#include <vcl/sysdata.hxx> +#include <vcl/syswin.hxx> + +#include "osl/file.h" + +#include "FPServiceInfo.hxx" +#include "VCLKDEApplication.hxx" +/* +#include <kfilefiltercombo.h> +#include <kfilewidget.h> +#include <kdiroperator.h> +#include <kservicetypetrader.h> +#include <kmessagebox.h> +*/ + +#include <kwindowsystem.h> + +// #include <QtCore/QDebug> +#include <QtCore/QUrl> +#include <QtGui/QClipboard> +#include <QtWidgets/QCheckBox> +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QGridLayout> +#include <QtWidgets/QWidget> +#include <QtCore/QThread> + +#undef Region + +#include "generic/geninst.h" + +#include "svids.hrc" + +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; + +// 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 KDE_VERSION_MAJOR == 4 && KDE_VERSION_MINOR >= 2 +//#define ALLOW_REMOTE_URLS 1 +//#else +#define ALLOW_REMOTE_URLS 0 +//#endif + +// 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.KDE5FilePicker"; + return aRet; + } +} + +OUString toOUString(const QString& s) +{ + // QString stores UTF16, just like OUString + return OUString(reinterpret_cast<const sal_Unicode*>(s.data()), s.length()); +} + +QString toQString(const OUString& s) +{ + return QString::fromUtf16( + reinterpret_cast<ushort const *>(s.getStr()), s.getLength()); +} + +// KDE5FilePicker + +KDE5FilePicker::KDE5FilePicker( const uno::Reference<uno::XComponentContext>& ) + : KDE5FilePicker_Base(_helperMutex) + , allowRemoteUrls( false ) +{ + _extraControls = new QWidget(); + _layout = new QGridLayout(_extraControls); + + _dialog = new QFileDialog(nullptr, QString(""), QString("~")); +// _extraControls); +#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 KDE code. + connect( fileWidget->dirOperator(), SIGNAL( finishedLoading()), SLOT( checkProtocol())); + } +#endif + + setMultiSelectionMode( false ); + + // XExecutableDialog functions + connect( this, SIGNAL( setTitleSignal( const OUString & ) ), + this, SLOT( setTitleSlot( const OUString & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( executeSignal() ), + this, SLOT( executeSlot() ), Qt::BlockingQueuedConnection ); + + // XFilePicker functions + connect( this, SIGNAL( setMultiSelectionModeSignal( bool ) ), + this, SLOT( setMultiSelectionModeSlot( bool ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( setDefaultNameSignal( const OUString & ) ), + this, SLOT( setDefaultNameSlot( const OUString & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( setDisplayDirectorySignal( const OUString & ) ), + this, SLOT( setDisplayDirectorySlot( const OUString & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( getDisplayDirectorySignal() ), + this, SLOT( getDisplayDirectorySlot() ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( getFilesSignal() ), + this, SLOT( getFilesSlot() ), Qt::BlockingQueuedConnection ); + + // XFilterManager functions + connect( this, SIGNAL( appendFilterSignal( const OUString &, const OUString & ) ), + this, SLOT( appendFilterSlot( const OUString &, const OUString & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( setCurrentFilterSignal( const OUString & ) ), + this, SLOT( setCurrentFilterSlot( const OUString & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( getCurrentFilterSignal() ), + this, SLOT( getCurrentFilterSlot() ), Qt::BlockingQueuedConnection ); + + // XFilterGroupManager functions + connect( this, SIGNAL( appendFilterGroupSignal( const OUString &, const css::uno::Sequence< css::beans::StringPair > & ) ), + this, SLOT( appendFilterGroupSlot( const OUString &, const css::uno::Sequence< css::beans::StringPair > & ) ), Qt::BlockingQueuedConnection ); + + // XFilePickerControlAccess functions + connect( this, SIGNAL( setValueSignal( sal_Int16, sal_Int16, const css::uno::Any & ) ), + this, SLOT( setValueSlot( sal_Int16, sal_Int16, const css::uno::Any & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( getValueSignal( sal_Int16, sal_Int16 ) ), + this, SLOT( getValueSlot( sal_Int16, sal_Int16 ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( enableControlSignal( sal_Int16, bool ) ), + this, SLOT( enableControlSlot( sal_Int16, bool ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( setLabelSignal( sal_Int16, const OUString & ) ), + this, SLOT( setLabelSlot( sal_Int16, const OUString & ) ), Qt::BlockingQueuedConnection ); + connect( this, SIGNAL( getLabelSignal( sal_Int16 ) ), + this, SLOT( getLabelSlot( sal_Int16 ) ), Qt::BlockingQueuedConnection ); + + // XFilePicker2 functions + connect( this, SIGNAL( getSelectedFilesSignal() ), + this, SLOT( getSelectedFilesSlot() ), Qt::BlockingQueuedConnection ); + + // XInitialization + connect( this, SIGNAL( initializeSignal( const css::uno::Sequence< css::uno::Any > & ) ), + this, SLOT( initializeSlot( const css::uno::Sequence< css::uno::Any > & ) ), Qt::BlockingQueuedConnection ); + + // Destructor proxy + connect( this, SIGNAL( cleanupProxySignal() ), this, SLOT( cleanupProxy() ), Qt::BlockingQueuedConnection ); + + connect( this, SIGNAL( checkProtocolSignal() ), this, SLOT( checkProtocol() ), Qt::BlockingQueuedConnection ); + + // XFilePickerListener notifications + connect( _dialog, SIGNAL( filterChanged(const QString&) ), this, SLOT( filterChanged(const QString&) )); + connect( _dialog, SIGNAL( selectionChanged() ), this, SLOT( selectionChanged() )); +} + +KDE5FilePicker::~KDE5FilePicker() +{ + cleanupProxy(); +} + +void KDE5FilePicker::cleanupProxy() +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser aReleaser; + return Q_EMIT cleanupProxySignal(); + } + delete _dialog; +} + +void SAL_CALL KDE5FilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener ) + throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + m_xListener = xListener; +} + +void SAL_CALL KDE5FilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& ) + throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + m_xListener.clear(); +} + +void SAL_CALL KDE5FilePicker::setTitle( const OUString &title ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser aReleaser; + return Q_EMIT setTitleSignal( title ); + } + + _dialog->setWindowTitle(toQString(title)); +} + +sal_Int16 SAL_CALL KDE5FilePicker::execute() + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser aReleaser; + return Q_EMIT executeSignal(); + } + + //get the window id of the main OO window to set it for the dialog as a parent + vcl::Window *pParentWin = Application::GetDefDialogParent(); + if ( pParentWin ) + { + const SystemEnvData* pSysData = static_cast<SystemWindow *>(pParentWin)->GetSystemData(); + if ( pSysData ) + { + KWindowSystem::setMainWindow( _dialog, pSysData->aWindow); // unx only + } + } +/* + _dialog->clearFilter(); + _dialog->setFilter(_filter); + + if(!_currentFilter.isNull()) + _dialog->filterWidget()->setCurrentItem(_currentFilter); + _dialog->filterWidget()->setEditable(false); +*/ + + VCLKDEApplication::preDialogSetup(); + //block and wait for user input + int result = _dialog->exec(); + VCLKDEApplication::postDialogCleanup(); + if( result == QFileDialog::Accepted ) + return ExecutableDialogResults::OK; + + return ExecutableDialogResults::CANCEL; +} + +void SAL_CALL KDE5FilePicker::setMultiSelectionMode( sal_Bool multiSelect ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT setMultiSelectionModeSignal( multiSelect ); + } + + if (multiSelect) + _dialog->setFileMode(QFileDialog::ExistingFiles); + else + _dialog->setFileMode(QFileDialog::ExistingFile); +} + +void SAL_CALL KDE5FilePicker::setDefaultName( const OUString &name ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT setDefaultNameSignal( name ); + } + + _dialog->selectUrl(QUrl(toQString(name))); +} + +void SAL_CALL KDE5FilePicker::setDisplayDirectory( const OUString &dir ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT setDisplayDirectorySignal( dir ); + } + + _dialog->selectUrl(QUrl(toQString(dir))); +} + +OUString SAL_CALL KDE5FilePicker::getDisplayDirectory() + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT getDisplayDirectorySignal(); + } + + return toOUString(_dialog->directoryUrl().url()); +} + +uno::Sequence< OUString > SAL_CALL KDE5FilePicker::getFiles() + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT getFilesSignal(); + } + uno::Sequence< OUString > seq = getSelectedFiles(); + if (seq.getLength() > 1) + seq.realloc(1); + return seq; +} + +uno::Sequence< OUString > SAL_CALL KDE5FilePicker::getSelectedFiles() + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT getSelectedFilesSignal(); + } + const QList<QUrl> urls = _dialog->selectedUrls(); + uno::Sequence< OUString > seq( urls.size() ); + int i = 0; + foreach( const QUrl& url, urls ) + seq[ i++ ]= toOUString( url.url()); + return seq; +} + +void SAL_CALL KDE5FilePicker::appendFilter( const OUString &title, const OUString &filter ) + throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT appendFilterSignal( title, filter ); + } + + QString t = toQString(title); + QString f = toQString(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 << QString("%1 (%2)").arg(f).arg(t); +} + +void SAL_CALL KDE5FilePicker::setCurrentFilter( const OUString &title ) + throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT setCurrentFilterSignal( title ); + } + + _currentFilter = toQString(title); +} + +OUString SAL_CALL KDE5FilePicker::getCurrentFilter() + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT getCurrentFilterSignal(); + } + + // _dialog->currentFilter() wouldn't quite work, because it returns only e.g. "*.doc", + // without the description, and there may be several filters with the same pattern + QString filter = _dialog->selectedNameFilter(); + filter = filter.mid( filter.indexOf( '|' ) + 1 ); // convert from the pattern|description format if needed + filter.replace( "\\/", "/" ); + + //default if not found + if (filter.isNull()) + filter = "ODF Text Document (.odt)"; + + return toOUString(filter); +} + +void SAL_CALL KDE5FilePicker::appendFilterGroup( const OUString& rGroupTitle, const uno::Sequence<beans::StringPair>& filters) + throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT appendFilterGroupSignal( rGroupTitle, 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 KDE5FilePicker::setValue( sal_Int16 controlId, sal_Int16 nControlAction, const uno::Any &value ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT setValueSignal( controlId, nControlAction, value ); + } + + if (_customWidgets.contains( controlId )) { + QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId )); + if (cb) + cb->setChecked(value.get<bool>()); + } + else + OSL_TRACE( "set label on unknown control %d", controlId ); +} + +uno::Any SAL_CALL KDE5FilePicker::getValue( sal_Int16 controlId, sal_Int16 nControlAction ) + throw( uno::RuntimeException, std::exception ) +{ + 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 ); + + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT getValueSignal( controlId, nControlAction ); + } + + uno::Any res(false); + if (_customWidgets.contains( controlId )) { + QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId )); + if (cb) + res = uno::Any(cb->isChecked()); + } + else + OSL_TRACE( "get value on unknown control %d", controlId ); + + return res; +} + +void SAL_CALL KDE5FilePicker::enableControl( sal_Int16 controlId, sal_Bool enable ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT enableControlSignal( controlId, enable ); + } + + if (_customWidgets.contains( controlId )) + _customWidgets.value( controlId )->setEnabled( enable ); + else + OSL_TRACE("enable unknown control %d", controlId ); +} + +void SAL_CALL KDE5FilePicker::setLabel( sal_Int16 controlId, const OUString &label ) + throw( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT setLabelSignal( controlId, label ); + } + + if (_customWidgets.contains( controlId )) { + QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId )); + if (cb) + cb->setText( toQString(label) ); + } + else + OSL_TRACE( "set label on unknown control %d", controlId ); +} + +OUString SAL_CALL KDE5FilePicker::getLabel(sal_Int16 controlId) + throw ( uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT getLabelSignal( controlId ); + } + + QString label; + if (_customWidgets.contains( controlId )) { + QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId )); + if (cb) + label = cb->text(); + } + else + OSL_TRACE( "get label on unknown control %d", controlId ); + + return toOUString(label); +} + +QString KDE5FilePicker::getResString( sal_Int16 aRedId ) +{ + QString aResString; + + if( aRedId < 0 ) + return aResString; + + try + { + aResString = toQString(ResId(aRedId, *ImplGetResMgr()).toString()); + } + catch(...) + { + } + + return aResString.replace('~', '&'); +} + +void KDE5FilePicker::addCustomControl(sal_Int16 controlId) +{ + QWidget* widget = nullptr; + sal_Int32 resId = -1; + + 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 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: + { + widget = new QCheckBox(getResString(resId), _extraControls); + + // the checkbox is created even for CHECKBOX_AUTOEXTENSION to simplify + // code, but the checkbox is hidden and ignored + if( controlId == CHECKBOX_AUTOEXTENSION ) + widget->hide(); + + 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; + } + + if (widget) + { + _layout->addWidget(widget); + _customWidgets.insert(controlId, widget); + } +} + +void SAL_CALL KDE5FilePicker::initialize( const uno::Sequence<uno::Any> &args ) + throw( uno::Exception, uno::RuntimeException, std::exception ) +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT initializeSignal( args ); + } + + _filters.clear(); + _currentFilter.clear(); + + // 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; + + //default is opening + QFileDialog::AcceptMode operationMode = QFileDialog::AcceptOpen; + + switch ( templateId ) + { + case FILEOPEN_SIMPLE: + break; + + case FILESAVE_SIMPLE: + operationMode = QFileDialog::AcceptSave; + break; + + case FILESAVE_AUTOEXTENSION: + operationMode = QFileDialog::AcceptSave; + addCustomControl( CHECKBOX_AUTOEXTENSION ); + break; + + case FILESAVE_AUTOEXTENSION_PASSWORD: + { + operationMode = QFileDialog::AcceptSave; + addCustomControl( CHECKBOX_PASSWORD ); + break; + } + case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS: + { + operationMode = QFileDialog::AcceptSave; + addCustomControl( CHECKBOX_AUTOEXTENSION ); + addCustomControl( CHECKBOX_PASSWORD ); + addCustomControl( CHECKBOX_FILTEROPTIONS ); + break; + } + case FILESAVE_AUTOEXTENSION_SELECTION: + operationMode = QFileDialog::AcceptSave; + addCustomControl( CHECKBOX_AUTOEXTENSION ); + addCustomControl( CHECKBOX_SELECTION ); + break; + + case FILESAVE_AUTOEXTENSION_TEMPLATE: + operationMode = QFileDialog::AcceptSave; + 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_READONLY_VERSION: + addCustomControl( CHECKBOX_READONLY ); + addCustomControl( LISTBOX_VERSION ); + break; + + case FILEOPEN_LINK_PREVIEW: + addCustomControl( CHECKBOX_LINK ); + addCustomControl( CHECKBOX_PREVIEW ); + break; + + default: + throw lang::IllegalArgumentException( + OUString( "Unknown template" ), + static_cast< XFilePicker2* >( this ), + 1 ); + } + + _dialog->setAcceptMode( operationMode ); + + sal_Int16 resId = -1; + switch (_dialog->acceptMode()) + { + case QFileDialog::AcceptOpen: + resId = STR_FPICKER_OPEN; + break; + case QFileDialog::AcceptSave: + resId = STR_FPICKER_SAVE; + _dialog->setConfirmOverwrite( true ); + break; + default: + break; + } + + _dialog->setWindowTitle(getResString(resId)); +} + +void SAL_CALL KDE5FilePicker::cancel() + throw ( uno::RuntimeException, std::exception ) +{ + +} + +void SAL_CALL KDE5FilePicker::disposing( const lang::EventObject &rEvent ) + throw( uno::RuntimeException ) +{ + uno::Reference<XFilePickerListener> xFilePickerListener( rEvent.Source, uno::UNO_QUERY ); + + if ( xFilePickerListener.is() ) + { + removeFilePickerListener( xFilePickerListener ); + } +} + +OUString SAL_CALL KDE5FilePicker::getImplementationName() + throw( uno::RuntimeException, std::exception ) +{ + return OUString( FILE_PICKER_IMPL_NAME ); +} + +sal_Bool SAL_CALL KDE5FilePicker::supportsService( const OUString& ServiceName ) + throw( uno::RuntimeException, std::exception ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL KDE5FilePicker::getSupportedServiceNames() + throw( uno::RuntimeException, std::exception ) +{ + return FilePicker_getSupportedServiceNames(); +} + +void KDE5FilePicker::checkProtocol() +{ + if( qApp->thread() != QThread::currentThread() ) { + SalYieldMutexReleaser release; + return Q_EMIT checkProtocolSignal(); + } + + // 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-KDE-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::filterChanged(const QString &) +{ + FilePickerEvent aEvent; + aEvent.ElementId = LISTBOX_FILTER; + OSL_TRACE( "filter changed" ); + if (m_xListener.is()) + m_xListener->controlStateChanged( aEvent ); +} + +void KDE5FilePicker::selectionChanged() +{ + FilePickerEvent aEvent; + OSL_TRACE( "file selection changed" ); + if (m_xListener.is()) + m_xListener->fileSelectionChanged( aEvent ); +} + +#include "KDE5FilePicker.moc" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kde5/KDE5FilePicker.hxx b/vcl/unx/kde5/KDE5FilePicker.hxx new file mode 100644 index 0000000..ab71a1e --- /dev/null +++ b/vcl/unx/kde5/KDE5FilePicker.hxx @@ -0,0 +1,237 @@ +/* -*- 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 <QtCore/QObject> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QHash> + +class QFileDialog; +class QWidget; +class QLayout; + +typedef ::cppu::WeakComponentImplHelper +< css::ui::dialogs::XFilePicker3 +, css::ui::dialogs::XFilePickerControlAccess +// TODO css::ui::dialogs::XFilePreview +, css::lang::XInitialization +, css::lang::XServiceInfo +> KDE5FilePicker_Base; + +class KDE5FilePicker + : public QObject + , public KDE5FilePicker_Base +{ + Q_OBJECT +protected: + + css::uno::Reference< css::ui::dialogs::XFilePickerListener > m_xListener; + + //the dialog to display + QFileDialog* _dialog; + + osl::Mutex _helperMutex; + + //running filter string to add to dialog + QStringList _filters; + // 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 + QLayout* _layout; + + bool allowRemoteUrls; + +public: + explicit KDE5FilePicker( const css::uno::Reference< css::uno::XComponentContext >& ); + virtual ~KDE5FilePicker(); + + // XFilePickerNotifier + virtual void SAL_CALL addFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) throw( css::uno::RuntimeException, std::exception ) override; + virtual void SAL_CALL removeFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) throw( css::uno::RuntimeException, std::exception ) override; + + // XExecutableDialog functions + virtual void SAL_CALL setTitle( const OUString &rTitle ) throw( css::uno::RuntimeException, std::exception ) override; + virtual sal_Int16 SAL_CALL execute() throw( css::uno::RuntimeException, std::exception ) override; + + // XFilePicker functions + virtual void SAL_CALL setMultiSelectionMode( sal_Bool bMode ) throw( css::uno::RuntimeException, std::exception ) override; + virtual void SAL_CALL setDefaultName( const OUString &rName ) throw( css::uno::RuntimeException, std::exception ) override; + virtual void SAL_CALL setDisplayDirectory( const OUString &rDirectory ) throw( css::uno::RuntimeException, std::exception ) override; + virtual OUString SAL_CALL getDisplayDirectory() throw( css::uno::RuntimeException, std::exception ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getFiles() throw( css::uno::RuntimeException, std::exception ) override; + + // XFilterManager functions + virtual void SAL_CALL appendFilter( const OUString &rTitle, const OUString &rFilter ) throw( css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception ) override; + virtual void SAL_CALL setCurrentFilter( const OUString &rTitle ) throw( css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception ) override; + virtual OUString SAL_CALL getCurrentFilter() throw( css::uno::RuntimeException, std::exception ) override; + + // XFilterGroupManager functions + virtual void SAL_CALL appendFilterGroup( const OUString &rGroupTitle, const css::uno::Sequence< css::beans::StringPair > &rFilters ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) override; + + // XFilePickerControlAccess functions + virtual void SAL_CALL setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const css::uno::Any &rValue ) throw (css::uno::RuntimeException, std::exception) override; + virtual css::uno::Any SAL_CALL getValue( sal_Int16 nControlId, sal_Int16 nControlAction ) throw (css::uno::RuntimeException, std::exception) override; + virtual void SAL_CALL enableControl( sal_Int16 nControlId, sal_Bool bEnable ) throw( css::uno::RuntimeException, std::exception ) override; + virtual void SAL_CALL setLabel( sal_Int16 nControlId, const OUString &rLabel ) throw (css::uno::RuntimeException, std::exception) override; + virtual OUString SAL_CALL getLabel( sal_Int16 nControlId ) throw (css::uno::RuntimeException, std::exception) override; + + /* TODO XFilePreview + + virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedImageFormats( ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getTargetColorDepth( ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAvailableWidth( ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAvailableHeight( ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const css::uno::Any &rImage ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getShowState( ) throw (css::uno::RuntimeException); + */ + + // XFilePicker2 functions + virtual css::uno::Sequence< OUString > SAL_CALL getSelectedFiles() + throw (css::uno::RuntimeException, std::exception) override; + + // XInitialization + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any > &rArguments ) throw( css::uno::Exception, css::uno::RuntimeException, std::exception ) override; + + // XCancellable + virtual void SAL_CALL cancel( ) throw( css::uno::RuntimeException, std::exception ) override; + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject &rEvent ) throw( css::uno::RuntimeException ); + using cppu::WeakComponentImplHelperBase::disposing; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw( css::uno::RuntimeException, std::exception ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString &rServiceName ) throw( css::uno::RuntimeException, std::exception ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( css::uno::RuntimeException, std::exception ) override; + +private Q_SLOTS: + // XExecutableDialog functions + void setTitleSlot( const OUString &rTitle ) throw( css::uno::RuntimeException ) { return setTitle( rTitle ); } + sal_Int16 executeSlot() throw( css::uno::RuntimeException ) { return execute(); } + + // XFilePicker functions + void setMultiSelectionModeSlot( bool bMode ) throw( css::uno::RuntimeException ) { return setMultiSelectionMode( bMode ); } + void setDefaultNameSlot( const OUString &rName ) throw( css::uno::RuntimeException ) { return setDefaultName( rName ); } + void setDisplayDirectorySlot( const OUString &rDirectory ) throw( css::uno::RuntimeException ) { return setDisplayDirectory( rDirectory ); } + OUString getDisplayDirectorySlot() throw( css::uno::RuntimeException ) { return getDisplayDirectory(); } + css::uno::Sequence< OUString > getFilesSlot() throw( css::uno::RuntimeException ) { return getFiles(); } + + // XFilterManager functions + void appendFilterSlot( const OUString &rTitle, const OUString &rFilter ) throw( css::lang::IllegalArgumentException, css::uno::RuntimeException ) { return appendFilter( rTitle, rFilter ); } + void setCurrentFilterSlot( const OUString &rTitle ) throw( css::lang::IllegalArgumentException, css::uno::RuntimeException ) { return setCurrentFilter( rTitle ); } + OUString getCurrentFilterSlot() throw( css::uno::RuntimeException ) { return getCurrentFilter(); } + + // XFilterGroupManager functions + void appendFilterGroupSlot( const OUString &rGroupTitle, const css::uno::Sequence< css::beans::StringPair > &rFilters ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException) { return appendFilterGroup( rGroupTitle, rFilters ); } + + // XFilePickerControlAccess functions + void setValueSlot( sal_Int16 nControlId, sal_Int16 nControlAction, const css::uno::Any &rValue ) throw (css::uno::RuntimeException) { return setValue( nControlId, nControlAction, rValue ); } + css::uno::Any getValueSlot( sal_Int16 nControlId, sal_Int16 nControlAction ) throw (css::uno::RuntimeException) { return getValue( nControlId, nControlAction ); } + void enableControlSlot( sal_Int16 nControlId, bool bEnable ) throw( css::uno::RuntimeException ) { return enableControl( nControlId, bEnable ); } + void setLabelSlot( sal_Int16 nControlId, const OUString &rLabel ) throw (css::uno::RuntimeException) { return setLabel( nControlId, rLabel ); } + OUString getLabelSlot( sal_Int16 nControlId ) throw (css::uno::RuntimeException) { return getLabel( nControlId ); } + + // XFilePicker2 functions + css::uno::Sequence< OUString > getSelectedFilesSlot() throw (css::uno::RuntimeException) { return getSelectedFiles(); } + + // XInitialization + void initializeSlot( const css::uno::Sequence< css::uno::Any > &rArguments ) throw( css::uno::Exception, css::uno::RuntimeException ) { return initialize( rArguments ); } + +Q_SIGNALS: + // XExecutableDialog functions + void setTitleSignal( const OUString &rTitle ); + sal_Int16 executeSignal(); + + // XFilePicker functions + void setMultiSelectionModeSignal( bool bMode ); + void setDefaultNameSignal( const OUString &rName ); ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits