Rebased ref, commits from common ancestor: commit d31f19f0c6f8e0b270f1d94128cb2af146746589 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Sun May 1 10:47:04 2016 +0000
rscpp: make previous FILE_LOCAL functions static This just move the declaration from the shared header to the corresponding cpp files to make them static. Change-Id: I4aed6e23a90d42114d815205db2b741080739ac1 diff --git a/rsc/source/rscpp/cpp.h b/rsc/source/rscpp/cpp.h index 0114c29..98ba207 100644 --- a/rsc/source/rscpp/cpp.h +++ b/rsc/source/rscpp/cpp.h @@ -278,11 +278,7 @@ int outputEval( int c ); /* cpp2.c */ int control( int counter ); -void doinclude( void ); void dodefine( void ); -void doif( int hash ); -int openinclude( char*, int ); -int hasdirectory( char*, char*, int ); int openfile( char* ); /* cpp3.c */ @@ -296,8 +292,6 @@ int readoptions( char* filename, char*** pfargv ); /* cpp4.c */ void checkparm( int c, DEFBUF* dp ); -int expcollect( void ); -void expstuff( DEFBUF* dp ); void stparmscan( int delim ); #if OSL_DEBUG_LEVEL > 1 @@ -311,12 +305,6 @@ void expand( DEFBUF* tokenp ); /* cpp5.c */ int eval( void ); -int evallex( int ); -int *evaleval( int*, int, int ); -int evalchar( int ); -int dosizeof( void ); -int evalnum( int c ); -int bittest( int ); /* cpp6.c */ diff --git a/rsc/source/rscpp/cpp2.c b/rsc/source/rscpp/cpp2.c index 2108f09..c181bef 100644 --- a/rsc/source/rscpp/cpp2.c +++ b/rsc/source/rscpp/cpp2.c @@ -22,6 +22,11 @@ #include "cppdef.h" #include "cpp.h" +static void doinclude( void ); +static void doif( int hash ); +static int openinclude( char*, int ); +static int hasdirectory( char*, char*, int ); + /* * Generate (by hand-inspection) a set of unique values for each control * operator. Note that this is not guaranteed to work for non-Ascii @@ -305,7 +310,7 @@ int control(int counter) * is always suppressed, so we don't need to evaluate anything. This * suppresses unnecessary warnings. */ -FILE_LOCAL void doif(int hash) +static void doif(int hash) { int c; int found; @@ -358,7 +363,7 @@ FILE_LOCAL void doif(int hash) * Note: the November 12 draft forbids '>' in the #include <file> format. * This restriction is unnecessary and not implemented. */ -FILE_LOCAL void doinclude() +static void doinclude() { int c; int delim; @@ -406,7 +411,7 @@ FILE_LOCAL void doinclude() * active files. Returns TRUE if the file was opened, FALSE * if openinclude() fails. No error message is printed. */ -FILE_LOCAL int openinclude(char* filename, int searchlocal) +static int openinclude(char* filename, int searchlocal) { char** incptr; char tmpname[NFWORK]; /* Filename work area */ @@ -500,7 +505,7 @@ FILE_LOCAL int openinclude(char* filename, int searchlocal) * node/device/directory part of the string is copied to result and * hasdirectory returns TRUE. Else, nothing is copied and it returns FALSE. */ -FILE_LOCAL int hasdirectory(char* source, char* result, int max) +static int hasdirectory(char* source, char* result, int max) { #if HOST == SYS_UNIX char* tp; diff --git a/rsc/source/rscpp/cpp3.c b/rsc/source/rscpp/cpp3.c index e836b3d..a24812e 100644 --- a/rsc/source/rscpp/cpp3.c +++ b/rsc/source/rscpp/cpp3.c @@ -369,7 +369,7 @@ int readoptions(char* filename, char*** pfargv) * This routine forces the -D and -U arguments to uppercase. * It is called only on cpp startup by dooptions(). */ -FILE_LOCAL void zap_uc(char* ap) +static void zap_uc(char* ap) { while (*ap != EOS) { diff --git a/rsc/source/rscpp/cpp4.c b/rsc/source/rscpp/cpp4.c index eab7b15..d8e0345 100644 --- a/rsc/source/rscpp/cpp4.c +++ b/rsc/source/rscpp/cpp4.c @@ -22,6 +22,7 @@ #include <ctype.h> #include "cppdef.h" #include "cpp.h" + /* * parm[], parmp, and parlist[] are used to store #define() argument * lists. nargs contains the actual number of parameters stored. @@ -31,6 +32,9 @@ static char* parmp; /* Free space in parm */ static char* parlist[LASTPARM]; /* -> start of each parameter */ static int nargs; /* Parameters for this macro */ +static int expcollect( void ); +static void expstuff( DEFBUF* dp ); + void InitCpp4() { int i; @@ -465,7 +469,7 @@ void expand(DEFBUF* tokenp) /* * Collect the actual parameters for this macro. TRUE if ok. */ -FILE_LOCAL int expcollect() +static int expcollect() { int c; int paren; /* For embedded ()'s */ @@ -533,7 +537,7 @@ FILE_LOCAL int expcollect() /* * Stuff the macro body, replacing formal parameters by actual parameters. */ -FILE_LOCAL void expstuff(DEFBUF* tokenp) +static void expstuff(DEFBUF* tokenp) { int c; /* Current character */ char* inp; /* -> repl string */ diff --git a/rsc/source/rscpp/cpp5.c b/rsc/source/rscpp/cpp5.c index f383ab8..df13120 100644 --- a/rsc/source/rscpp/cpp5.c +++ b/rsc/source/rscpp/cpp5.c @@ -22,6 +22,13 @@ #include "cppdef.h" #include "cpp.h" +static int evallex(int skip); +static int dosizeof(void); +static int bittest(int value); +static int evalnum(int c); +static int evalchar(int skip); +static int *evaleval(int* valp, int op, int skip); + /* * Evaluate an #if expression. */ @@ -370,7 +377,7 @@ again: * evalchar called to evaluate 'x' * evalnum called to evaluate numbers. */ -FILE_LOCAL int evallex(int skip) +static int evallex(int skip) { int c; int c1; @@ -505,7 +512,7 @@ again: * DIG success * OP_FAIL bad parse or something. */ -FILE_LOCAL int dosizeof() +static int dosizeof(void) { int c; TYPES* tp; @@ -621,7 +628,7 @@ FILE_LOCAL int dosizeof() /* * TRUE if value is zero or exactly one bit is set in value. */ -FILE_LOCAL int bittest(int value) +static int bittest(int value) { /* whoaa!! really worried about non 2's complement machines... * but not at all about cross-compiling ? @@ -640,7 +647,7 @@ FILE_LOCAL int bittest(int value) * Expand number for #if lexical analysis. Note: evalnum recognizes * the unsigned suffix, but only returns a signed int value. */ -FILE_LOCAL int evalnum(int c) +static int evalnum(int c) { int value; int base; @@ -679,7 +686,7 @@ FILE_LOCAL int evalnum(int c) /* * Get a character constant */ -FILE_LOCAL int evalchar(int skip) +static int evalchar(int skip) { int c; int value; @@ -785,7 +792,7 @@ FILE_LOCAL int evalchar(int skip) * * evaleval() returns the new pointer to the top of the value stack. */ -FILE_LOCAL int * evaleval(int* valp, int op, int skip) +static int * evaleval(int* valp, int op, int skip) { int v1; int v2 = 0; diff --git a/rsc/source/rscpp/cppdef.h b/rsc/source/rscpp/cppdef.h index 3cf30cf..ffbb57c 100644 --- a/rsc/source/rscpp/cppdef.h +++ b/rsc/source/rscpp/cppdef.h @@ -69,11 +69,6 @@ * This should be defined as "" if cpp is to replace * the "standard" C pre-processor. * - * FILE_LOCAL marks functions which are referenced only in the - * file they reside. Some C compilers allow these - * to be marked "static" even though they are referenced - * by "extern" statements elsewhere. - * * OK_DATE Predefines the compilation date if set TRUE. * Not permitted by the Nov. 12, 1984 Draft Standard. * @@ -176,10 +171,6 @@ #endif -#ifndef FILE_LOCAL -#define FILE_LOCAL /* Others are global */ -#endif - #endif // INCLUDED_RSC_SOURCE_RSCPP_CPPDEF_H /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 9f95a4b24da3cd50eba78ffecaf00c2379d63497 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Fri Apr 22 04:48:08 2016 +0200 Disable font dependent tests when missing fonts A (very) few tests depend on correct MS metric compatible fonts, like Calibri, Arial and Times New Roman, and fail if these are substituted with incompatible fonts. Disable failing asserts, so we'll at least test loading the documents. Change-Id: I4d07ffa7cd0da17f1c6631641853779294426210 diff --git a/configure.ac b/configure.ac index ab64c95..23704c3 100644 --- a/configure.ac +++ b/configure.ac @@ -11689,7 +11689,7 @@ test_font_map() MAPPING="$(echo $1 | $AWK '{print tolower($0)}')"; shift TESTEXPR="${TESTEXPR} -o '${FONTFILE_LOWER}' = '$MAPPING-regular.ttf'" done - if test $TESTEXPR + if eval "test $TESTEXPR" then AC_MSG_RESULT([ok]) else @@ -11717,6 +11717,8 @@ else TEST_FONTS_MISSING=1 else test_font_map 'Calibri' 'Carlito' + test_font_map 'Arial' 'LiberationSans' + test_font_map 'Times New Roman' 'LiberationSerif' if test ${TEST_FONTS_MISSING} -eq 1 then AC_MSG_WARN([Unknown font mappings - unit tests disabled.]) diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index e216721..29c3822 100644 --- a/sc/qa/extras/macros-test.cxx +++ b/sc/qa/extras/macros-test.cxx @@ -21,6 +21,8 @@ #include <basic/sbxdef.hxx> +#include <config_test.h> + #include "docsh.hxx" #include "patattr.hxx" #include "scitems.hxx" @@ -294,7 +296,9 @@ void ScMacrosTest::testVba() osl::FileBase::getSystemPathFromFileURL( sTempDirURL, sTempDir ); sTempDir += OUStringLiteral1<SAL_PATHDELIMITER>(); OUString sTestFileName("My Test WorkBook.xls"); +#if ! TEST_FONTS_MISSING Sequence< uno::Any > aParams; +#endif for ( sal_uInt32 i=0; i<SAL_N_ELEMENTS( testInfo ); ++i ) { OUString aFileName; @@ -308,10 +312,17 @@ void ScMacrosTest::testVba() // time - while processing other StarBasic methods. Application::Reschedule(true); + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + SAL_INFO("sc.qa", "about to invoke vba test in " << aFileName << " with url " << testInfo[i].sMacroUrl); + + bool bWorkbooksHandling = OUString( testInfo[i].sFileBaseName ) == "Workbooks." && !sTempDir.isEmpty() ; + +#if ! TEST_FONTS_MISSING Any aRet; Sequence< sal_Int16 > aOutParamIndex; Sequence< Any > aOutParam; - bool bWorkbooksHandling = OUString( testInfo[i].sFileBaseName ) == "Workbooks." && !sTempDir.isEmpty() ; if ( bWorkbooksHandling ) { @@ -320,11 +331,6 @@ void ScMacrosTest::testVba() aParams[ 1 ] <<= sTestFileName; } - SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); - - CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); - SAL_INFO("sc.qa", "about to invoke vba test in " << aFileName << " with url " << testInfo[i].sMacroUrl); - SfxObjectShell::CallXScript( xComponent, testInfo[i].sMacroUrl, aParams, aRet, aOutParamIndex, aOutParam); @@ -332,6 +338,8 @@ void ScMacrosTest::testVba() aRet >>= aStringRes; SAL_INFO("sc.qa", "value of Ret " << aStringRes); CPPUNIT_ASSERT_MESSAGE( "script reported failure", aStringRes == "OK" ); +#endif + pFoundShell->DoClose(); if ( bWorkbooksHandling ) { diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 847acc1..d1b8ebb 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -81,6 +81,8 @@ #include "helper/shared_test_impl.hxx" #include <algorithm> +#include <config_test.h> + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -1633,8 +1635,10 @@ void ScFiltersTest::testChartImportXLS() const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 0); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj); +#if ! TEST_FONTS_MISSING CPPUNIT_ASSERT_EQUAL(11148L, pOleObj->GetLogicRect().getWidth()); CPPUNIT_ASSERT(8640L > pOleObj->GetLogicRect().getHeight()); +#endif xDocSh->DoClose(); } diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index a47f990..3a84bc4 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -33,6 +33,8 @@ #include <unomodel.hxx> #include <drawdoc.hxx> +#include <config_test.h> + using namespace css; #if !defined(_WIN32) && !defined(MACOSX) @@ -303,6 +305,7 @@ void SdTiledRenderingTest::testPostMouseEvent() // Did we manage to go after the first character? CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), rEditView.GetSelection().nStartPos); +#if ! TEST_FONTS_MISSING vcl::Cursor* pCursor = rEditView.GetCursor(); Point aPosition = pCursor->GetPos(); aPosition.setX(aPosition.getX() - 1000); @@ -311,6 +314,7 @@ void SdTiledRenderingTest::testPostMouseEvent() CPPUNIT_ASSERT(pView->GetTextEditObject()); // The new cursor position must be before the first word. CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), rEditView.GetSelection().nStartPos); +#endif comphelper::LibreOfficeKit::setActive(false); } diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 11a0824..129f674 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -91,6 +91,7 @@ #include <sfx2/classificationhelper.hxx> #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <config_features.h> +#include <config_test.h> static const char* DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/"; @@ -3297,6 +3298,7 @@ void SwUiWriterTest::testTdf77014() load(DATA_DIRECTORY, "tdf77014.odt"); +#if ! TEST_FONTS_MISSING // First paragraph CPPUNIT_ASSERT_EQUAL(OUString("POR_TXT"), parseDump("/root/page/body/txt[4]/Text[1]", "nType")); CPPUNIT_ASSERT_EQUAL(OUString("91"), parseDump("/root/page/body/txt[4]/Text[1]", "nLength")); @@ -3330,6 +3332,7 @@ void SwUiWriterTest::testTdf77014() CPPUNIT_ASSERT_EQUAL(OUString("POR_TXT"), parseDump("/root/page/body/txt[5]/Text[5]", "nType")); CPPUNIT_ASSERT_EQUAL(OUString("1"), parseDump("/root/page/body/txt[5]/Text[5]", "nLength")); +#endif } void SwUiWriterTest::testTdf92648() diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx index 24023a4..74eefe7 100644 --- a/sw/qa/extras/ww8export/ww8export.cxx +++ b/sw/qa/extras/ww8export/ww8export.cxx @@ -36,6 +36,8 @@ #include <view.hxx> #include <wrtsh.hxx> +#include <config_test.h> + class Test : public SwModelTestBase { public: @@ -652,7 +654,7 @@ DECLARE_WW8EXPORT_TEST(testCommentExport, "comment-export.odt") } } -#if !defined(MACOSX) +#if !defined(MACOSX) && ! TEST_FONTS_MISSING DECLARE_WW8EXPORT_TEST(testTableKeep, "tdf91083.odt") { //emulate table "keep with next" -do not split table diff --git a/sw/qa/extras/ww8import/ww8import.cxx b/sw/qa/extras/ww8import/ww8import.cxx index b2e0f0d..7d90e3e 100644 --- a/sw/qa/extras/ww8import/ww8import.cxx +++ b/sw/qa/extras/ww8import/ww8import.cxx @@ -23,6 +23,8 @@ #include <bordertest.hxx> +#include <config_test.h> + #define convertTwipToMm100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L)) class Test : public SwModelTestBase @@ -531,8 +533,10 @@ DECLARE_WW8IMPORT_TEST(testfdo68963, "fdo68963.doc") // The problem was that the text was not displayed. CPPUNIT_ASSERT ( !parseDump("/root/page/body/tab/row[2]/cell[1]/txt/Special", "rText").isEmpty() ); CPPUNIT_ASSERT_EQUAL( OUString("Topic 1"), parseDump("/root/page/body/tab/row[2]/cell[1]/txt/Special", "rText") ); +#if ! TEST_FONTS_MISSING // all crossreference bookmarks should have a target. Shouldn't be any "Reference source not found" in the xml CPPUNIT_ASSERT ( -1 == parseDump("/root/page/body/txt[24]/Special[2]","rText").indexOf("Reference source not found")); +#endif } DECLARE_WW8IMPORT_TEST(testTdf99100, "tdf99100.doc") commit a051ed56a5329462f45c32faa68bd30b65052259 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 858be89..a9366ffb 100644 --- a/Repository.mk +++ b/Repository.mk @@ -261,8 +261,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 713994e..826f3fe 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -2952,6 +2952,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 478b285..84e574a 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -147,6 +147,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@ @@ -308,6 +309,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@ @@ -400,6 +406,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 12d90ee..29f5bca 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 #endif diff --git a/configure.ac b/configure.ac index 0aa00e9..ab64c95 100644 --- a/configure.ac +++ b/configure.ac @@ -646,6 +646,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 ;; @@ -742,6 +743,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 @@ -771,6 +773,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 @@ -798,6 +801,7 @@ dragonfly*) build_gstreamer_0_10=yes test_tde=yes test_kde4=yes + test_kde5=yes test_freetype=yes PTHREAD_LIBS="-pthread" _os=DragonFly @@ -822,6 +826,7 @@ linux-android*) test_gtk=no test_tde=no test_kde4=no + test_kde5=no test_randr=no test_xrender=no _os=Android @@ -1265,6 +1270,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(gui, AS_HELP_STRING([--disable-gui], [Disable X11/Wayland support to reduce dependencies. Maybe useful for @@ -4751,6 +4762,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 @@ -10062,6 +10074,13 @@ 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) build_vcl_plugins="$R" if test -z "$build_vcl_plugins"; then @@ -11242,6 +11261,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]) @@ -12901,6 +13157,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 7bb181d..b6dc5a1 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 396d1ee..99fe567 100644 --- a/cui/source/options/optgdlg.cxx +++ b/cui/source/options/optgdlg.cxx @@ -202,7 +202,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 17661e9..431a9c7 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 5d962b7..b67d5aa 100644 --- a/shell/source/backends/kde4be/kde4access.cxx +++ b/shell/source/backends/kde4be/kde4access.cxx @@ -19,6 +19,8 @@ #include "sal/config.h" +#include "kde4access.hxx" + #include <QtGui/QFont> #include <QtCore/QString> #include <kemailsettings.h> @@ -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 5ab32ca..dc66c19 100644 --- a/solenv/gbuild/CppunitTest.mk +++ b/solenv/gbuild/CppunitTest.mk @@ -188,6 +188,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 03c884c..710aa44 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -81,6 +81,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/unx/gendata.hxx b/vcl/inc/unx/gendata.hxx index b2223b5..1a843e3 100644 --- a/vcl/inc/unx/gendata.hxx +++ b/vcl/inc/unx/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 6852c06..be36527 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..74a9c91 --- /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 "unx/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/. + * ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits