[Libreoffice-commits] core.git: Branch 'private/jmux/libreoffice-4-2+kde4' - 36 commits - chart2/source configure.ac drawinglayer/source editeng/source framework/source include/editeng include/oox include/rtl include/svl include/svx oox/CustomTarget_generated.mk oox/source sc/inc sc/Library_sc.mk sc/source sd/source svl/source svx/source swext/mediawiki sw/qa sw/source vcl/CustomTarget_kde4_moc.mk vcl/Library_vclplug_kde4.mk vcl/source vcl/unx writerfilter/source

Jan-Marek Glogowski glogow at fbihome.de
Fri Mar 21 17:48:06 PDT 2014


Rebased ref, commits from common ancestor:
commit 0d7b23340efceb25f5ce24ec2ba2e9549f61ad77
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Mar 14 21:02:16 2014 +0100

    fdo#67011 KDE4: prevent blocking in Display::Yield
    
    SalX11Display registers a Yield handler, which splits check and
    and processing into two functions, which both lock the yield mutex.
    
    Normally this no problem, but during a Drag'n'Drop operation the
    D'n'D thread also checks and processes XEvents (for D'n'D). So the
    XNextEvent in Display::Yield will actually block, if the seen XEvent
    was for D'n'D and was already processed.
    
    (cherry picked from commit 6c7374f071d998f726cd4a5b67baf54e357d096b)
    
    Change-Id: I9f8d96d4f9986997cbe150a2b66bc767b4bbc2f1

diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index 21440fc..650b266 100644
--- a/vcl/unx/kde4/KDESalDisplay.cxx
+++ b/vcl/unx/kde4/KDESalDisplay.cxx
@@ -51,6 +51,10 @@ void SalKDEDisplay::Yield()
     if( DispatchInternalEvent() )
         return;
 
+    // Prevent blocking from Drag'n'Drop events, which may have already have processed the event
+    if (XEventsQueued( pDisp_, QueuedAfterReading ) == 0)
+        return;
+
     DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() ==
                 osl::Thread::getCurrentIdentifier(),
                 "will crash soon since solar mutex not locked in SalKDEDisplay::Yield" );
commit b1a24ea93842b09e0fb85d6b26218ba358c0da3d
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Mon Mar 10 14:54:58 2014 +0000

    Revert "fdo#67011: Run Display::Yield through KDEXLib::Yield."
    
    This reverts commit 95f60222e75486336b6569afa8f34d60b51c94ad.
    (cherry picked from commit 69e7f4491ec78384c46653d3cd8870c97cc9218a)

diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index ee330e7..21440fc 100644
--- a/vcl/unx/kde4/KDESalDisplay.cxx
+++ b/vcl/unx/kde4/KDESalDisplay.cxx
@@ -25,8 +25,6 @@
 #include <assert.h>
 #include <unx/saldata.hxx>
 
-#include <qthread.h>
-
 SalKDEDisplay* SalKDEDisplay::selfptr = NULL;
 
 SalKDEDisplay::SalKDEDisplay( Display* pDisp )
@@ -50,26 +48,18 @@ SalKDEDisplay::~SalKDEDisplay()
 
 void SalKDEDisplay::Yield()
 {
-    // We yield the display throught the main Qt thread.
-    // Actually this Yield may call the Display::Yield, which results in an
-    // unlimited cycle.
-    static bool break_cyclic_yield_recursion = false;
-    bool is_qt_gui_thread = ( qApp->thread() == QThread::currentThread() );
-
-    if( DispatchInternalEvent() || break_cyclic_yield_recursion )
+    if( DispatchInternalEvent() )
         return;
 
-    if( is_qt_gui_thread )
-        break_cyclic_yield_recursion = true;
-
     DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() ==
                 osl::Thread::getCurrentIdentifier(),
                 "will crash soon since solar mutex not locked in SalKDEDisplay::Yield" );
 
-    static_cast<KDEXLib*>(GetXLib())->Yield( true, false );
-
-    if( is_qt_gui_thread )
-        break_cyclic_yield_recursion = false;
+    XEvent event;
+    XNextEvent( pDisp_, &event );
+    if( checkDirectInputEvent( &event ))
+        return;
+    qApp->x11ProcessEvent( &event );
 }
 
 // HACK: When using Qt event loop, input methods (japanese, etc.) will get broken because
commit 9cfca06edd8559b06f2089528c274c119321d5d5
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Mon Mar 10 15:05:22 2014 +0000

    KDE4: add Qt4 glib ExcludeSocket runtime check
    
    Add a runtime check and configure warning to disable KDE4 native
    file pickers, if the Qt4 glib dispatcher doesn't honor the
    QEventLoop::ExcludeSocketNotifiers flag.
    
    This way polling the QClipboard using the event loop won't
    crash LibreOffice with recursive paint events,
    
    See https://bugreports.qt-project.org/browse/QTBUG-37380
    
    Change-Id: I5cad30ead74571e49a075c084cca7a19acff7523
    (cherry picked from commit cc8d566d74a2e0b969b92d9cf22cc95a3bf31a98)

diff --git a/configure.ac b/configure.ac
index 50f1162..f36cbaf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11126,7 +11126,7 @@ if test "$test_kde4" = "yes" -a "$ENABLE_KDE4" = "TRUE"; then
     fi
 
     qt_test_include="Qt/qobject.h"
-    qt_test_library="libQtCore.so"
+    qt_test_library="libQtNetwork.so"
     kde_test_include="kwindowsystem.h"
     kde_test_library="libsolid.so"
 
@@ -11213,8 +11213,9 @@ the root of your Qt installation by exporting QT4DIR before running "configure".
         AC_MSG_ERROR([KDE4 libraries not found.  Please specify the root of your KDE4 installation by exporting KDE4DIR before running "configure".])
     fi
 
-    KDE4_CFLAGS="`pkg-config --cflags QtCore` `pkg-config --cflags QtGui` -I$kde_incdir -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT"
-    KDE4_LIBS="-L$kde_libdir -L$qt_lib_dir -lkio -lkfile -lkdeui -lkdecore -lQtCore -lQtGui"
+    PKG_CHECK_MODULES([QT4],[QtNetwork QtGui])
+    KDE4_CFLAGS="-I$kde_incdir $QT4_CFLAGS -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT"
+    KDE4_LIBS="-L$kde_libdir -lkio -lkfile -lkdeui -lkdecore -L$qt_lib_dir $QT4_LIBS"
     KDE4_CFLAGS=$(printf '%s' "$KDE4_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
 
     AC_LANG_PUSH([C++])
@@ -11236,11 +11237,47 @@ int main(int argc, char **argv) {
     # Sets also KDE_GLIB_CFLAGS/KDE_GLIB_LIBS if successful.
     PKG_CHECK_MODULES(KDE_GLIB,[glib-2.0 >= 2.4],
         [
-        KDE_HAVE_GLIB=1
-        AC_DEFINE(KDE_HAVE_GLIB,1)
-        KDE_GLIB_CFLAGS=$(printf '%s' "$KDE_GLIB_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
+            KDE_HAVE_GLIB=1
+            AC_DEFINE(KDE_HAVE_GLIB,1)
+            KDE_GLIB_CFLAGS=$(printf '%s' "$KDE_GLIB_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
+
+            AC_LANG_PUSH([C++])
+            save_CXXFLAGS=$CXXFLAGS
+            CXXFLAGS="$CXXFLAGS $KDE4_CFLAGS"
+            save_LIBS=$LIBS
+            LIBS="$LIBS $KDE4_LIBS"
+            AC_MSG_CHECKING([whether Qt has fixed ExcludeSocketNotifiers])
+
+            # Prepare meta object data
+            TSTBASE="tst_exclude_socket_notifiers"
+            TSTMOC="${SRC_ROOT}/vcl/unx/kde4/${TSTBASE}"
+            ln -fs "${TSTMOC}.hxx"
+            $MOC4 "${TSTBASE}.hxx" -o "${TSTBASE}.moc"
+
+            AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#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 KDE4 file pickers will be disabled at runtime - fix your Qt4 library!])
+            ])
+
+            # Remove meta object data
+            rm -f "${TSTBASE}."*
+
+            LIBS=$save_LIBS
+            CXXFLAGS=$save_CXXFLAGS
+            AC_LANG_POP([C++])
         ],
-        AC_MSG_WARN([[No Glib found, KDE4 support will not integrate with Qt's Glib event loop support]]))
+        AC_MSG_WARN([[No Glib found, KDE4 support will not use native file pickers!]]))
 fi
 AC_SUBST(KDE4_CFLAGS)
 AC_SUBST(KDE4_LIBS)
diff --git a/vcl/CustomTarget_kde4_moc.mk b/vcl/CustomTarget_kde4_moc.mk
index 0846b0b..9e41754 100644
--- a/vcl/CustomTarget_kde4_moc.mk
+++ b/vcl/CustomTarget_kde4_moc.mk
@@ -11,7 +11,8 @@ $(eval $(call gb_CustomTarget_CustomTarget,vcl/unx/kde4))
 
 $(call gb_CustomTarget_get_target,vcl/unx/kde4) : \
 	$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDEXLib.moc \
-	$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDE4FilePicker.moc
+	$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDE4FilePicker.moc \
+	$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/tst_exclude_socket_notifiers.moc
 
 $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/%.moc : \
 		$(SRCDIR)/vcl/unx/kde4/%.hxx \
diff --git a/vcl/Library_vclplug_kde4.mk b/vcl/Library_vclplug_kde4.mk
index c72fe00..18ffa02 100644
--- a/vcl/Library_vclplug_kde4.mk
+++ b/vcl/Library_vclplug_kde4.mk
@@ -76,7 +76,7 @@ endif
 
 $(eval $(call gb_Library_add_exception_objects,vclplug_kde4,\
     vcl/unx/kde4/KDEData \
-	vcl/unx/kde4/KDE4FilePicker \
+    vcl/unx/kde4/KDE4FilePicker \
     vcl/unx/kde4/KDESalDisplay \
     vcl/unx/kde4/KDESalFrame \
     vcl/unx/kde4/KDESalGraphics \
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index b3fde26..1cb1460 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -261,8 +261,12 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
     _dialog->filterWidget()->setEditable(false);
 
     // We're entering a nested loop.
-    // Release the yield mutex to prevent deadlocks.
-    int result = _dialog->exec();
+    int result;
+    {
+        // Release the yield mutex to prevent deadlocks.
+        SalYieldMutexReleaser aReleaser;
+        result = _dialog->exec();
+    }
 
     // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
     // (such as the auto-extension flag), but that doesn't update KGlobal::config()
diff --git a/vcl/unx/kde4/KDEData.cxx b/vcl/unx/kde4/KDEData.cxx
index ccbbd99..0e87c62 100644
--- a/vcl/unx/kde4/KDEData.cxx
+++ b/vcl/unx/kde4/KDEData.cxx
@@ -27,6 +27,7 @@
 #include "KDEData.hxx"
 
 #include "KDEXLib.hxx"
+#include "KDESalDisplay.hxx"
 
 
 KDEData::~KDEData()
@@ -37,6 +38,7 @@ void KDEData::Init()
 {
     pXLib_ = new KDEXLib();
     pXLib_->Init();
+    SetDisplay( SalKDEDisplay::self() );
 }
 
 void KDEData::initNWF()
diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx
index 9670172..023d790 100644
--- a/vcl/unx/kde4/KDESalInstance.cxx
+++ b/vcl/unx/kde4/KDESalInstance.cxx
@@ -32,10 +32,14 @@ SalFrame* KDESalInstance::CreateFrame( SalFrame *pParent, sal_uLong nState )
 }
 
 uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
-        const uno::Reference< uno::XComponentContext >& xMSF )
+    const uno::Reference< uno::XComponentContext >& xMSF )
 {
-    return uno::Reference< ui::dialogs::XFilePicker2 >(
-        static_cast<KDEXLib*>( mpXLib )->createFilePicker(xMSF) );
+    KDEXLib* kdeXLib = static_cast<KDEXLib*>( mpXLib );
+    if (kdeXLib->haveQt4SocketExcludeFix())
+        return uno::Reference< ui::dialogs::XFilePicker2 >(
+            kdeXLib->createFilePicker(xMSF) );
+    else
+        return X11SalInstance::createFilePicker( xMSF );
 }
 
 int KDESalInstance::getFrameWidth()
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 5c4cd10..820d39a 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -19,7 +19,6 @@
 
 #include "VCLKDEApplication.hxx"
 
-#include "KDE4FilePicker.hxx"
 #include "KDESalInstance.hxx"
 
 #include <kapplication.h>
@@ -45,15 +44,17 @@
 
 #include <config_kde4.h>
 
+#if KDE_HAVE_GLIB
+#include "KDE4FilePicker.hxx"
+#include "tst_exclude_socket_notifiers.moc"
+#endif
+
 KDEXLib::KDEXLib() :
     SalXLib(),  m_bStartupDone(false), m_pApplication(0),
     m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
-    m_frameWidth( -1 ), m_isGlibEventLoopType(false)
+    m_frameWidth( -1 ), m_isGlibEventLoopType(false),
+    m_haveQt4SocketExcludeFix(false)
 {
-#if KDE_HAVE_GLIB
-    m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
-#endif
-
     // the timers created here means they belong to the main thread.
     // As the timeoutTimer runs the LO event queue, which may block on a dialog,
     // the timer has to use a Qt::QueuedConnection, otherwise the nested event
@@ -168,6 +169,14 @@ void KDEXLib::Init()
     m_pApplication = new VCLKDEApplication();
     kapp->disableSessionManagement();
     KApplication::setQuitOnLastWindowClosed(false);
+
+#if KDE_HAVE_GLIB
+    m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
+    if (m_isGlibEventLoopType && (0 == tst_processEventsExcludeSocket()))
+        // See http://bugreports.qt.nokia.com/browse/QTBUG-37380
+        m_haveQt4SocketExcludeFix = true;
+#endif
+
     setupEventLoop();
 
     Display* pDisp = QX11Info::display();
@@ -188,9 +197,8 @@ void KDEXLib::Init()
 #include <glib.h>
 
 static GPollFunc old_gpoll = NULL;
-static gint gpoll_wrapper( GPollFD*, guint, gint );
 
-gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
+static gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
 {
     SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
     return old_gpoll( ufds, nfds, timeout );
@@ -215,6 +223,8 @@ void KDEXLib::setupEventLoop()
     {
         old_gpoll = g_main_context_get_poll_func( NULL );
         g_main_context_set_poll_func( NULL, gpoll_wrapper );
+        if( m_haveQt4SocketExcludeFix )
+            m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true );
         return;
     }
 #endif
@@ -367,11 +377,15 @@ using namespace com::sun::star;
 uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
         const uno::Reference< uno::XComponentContext >& xMSF )
 {
+#if KDE_HAVE_GLIB
     if( qApp->thread() != QThread::currentThread()) {
         SalYieldMutexReleaser aReleaser;
         return Q_EMIT createFilePickerSignal( xMSF );
     }
     return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
+#else
+    return NULL;
+#endif
 }
 
 #define Region QtXRegion
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index f26948d..a88258c 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -53,6 +53,7 @@ class KDEXLib : public QObject, public SalXLib
         QTimer userEventTimer;
         int m_frameWidth;
         bool m_isGlibEventLoopType;
+        bool m_haveQt4SocketExcludeFix;
 
     private:
         void setupEventLoop();
@@ -87,6 +88,7 @@ class KDEXLib : public QObject, public SalXLib
         virtual void PostUserEvent();
 
         void doStartup();
+        bool haveQt4SocketExcludeFix() { return m_haveQt4SocketExcludeFix; }
 
     public Q_SLOTS:
         com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
diff --git a/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx b/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
new file mode 100644
index 0000000..0c874fd
--- /dev/null
+++ b/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
@@ -0,0 +1,126 @@
+/* -*- 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 .
+ *
+ * This code is based on the SocketEventsTester from the Qt4 test suite.
+ */
+
+#pragma once
+
+#include <qcoreapplication.h>
+#include <qeventloop.h>
+#include <qthread.h>
+#include <qtimer.h>
+#include <QtNetwork/qtcpserver.h>
+#include <QtNetwork/qtcpsocket.h>
+
+class SocketEventsTester: public QObject
+{
+    Q_OBJECT
+public:
+    SocketEventsTester()
+    {
+        socket = 0;
+        server = 0;
+        dataSent = false;
+        testResult = false;
+        dataArrived = false;
+    }
+    ~SocketEventsTester()
+    {
+        delete socket;
+        delete server;
+    }
+    bool init()
+    {
+        bool ret = false;
+        server = new QTcpServer();
+        socket = new QTcpSocket();
+        connect(server, SIGNAL(newConnection()), this, SLOT(sendHello()));
+        connect(socket, SIGNAL(readyRead()), this, SLOT(sendAck()), Qt::DirectConnection);
+        if((ret = server->listen(QHostAddress::LocalHost, 0))) {
+            socket->connectToHost(server->serverAddress(), server->serverPort());
+            socket->waitForConnected();
+        }
+        return ret;
+    }
+
+    QTcpSocket *socket;
+    QTcpServer *server;
+    bool dataSent;
+    bool testResult;
+    bool dataArrived;
+public slots:
+    void sendAck()
+    {
+        dataArrived = true;
+    }
+    void sendHello()
+    {
+        char data[10] ="HELLO";
+        qint64 size = sizeof(data);
+
+        QTcpSocket *serverSocket = server->nextPendingConnection();
+        serverSocket->write(data, size);
+        dataSent = serverSocket->waitForBytesWritten(-1);
+        QEventLoop loop;
+        //allow the TCP/IP stack time to loopback the data, so our socket is ready to read
+        QTimer::singleShot(200, &loop, SLOT(quit()));
+        loop.exec(QEventLoop::ExcludeSocketNotifiers);
+        testResult = dataArrived;
+        //check the deferred event is processed
+        QTimer::singleShot(200, &loop, SLOT(quit()));
+        loop.exec();
+        serverSocket->close();
+        QThread::currentThread()->exit(0);
+    }
+};
+
+class SocketTestThread : public QThread
+{
+    Q_OBJECT
+public:
+    SocketTestThread():QThread(0),testResult(false){};
+    void run()
+    {
+        SocketEventsTester *tester = new SocketEventsTester();
+        if (tester->init())
+            exec();
+        dataSent = tester->dataSent;
+        testResult = tester->testResult;
+        dataArrived = tester->dataArrived;
+        delete tester;
+    }
+    bool dataSent;
+    bool testResult;
+    bool dataArrived;
+};
+
+#define QVERIFY(a) \
+    if (!a) return 1;
+
+static int tst_processEventsExcludeSocket()
+{
+    SocketTestThread thread;
+    thread.start();
+    QVERIFY(thread.wait());
+    QVERIFY(thread.dataSent);
+    QVERIFY(!thread.testResult);
+    QVERIFY(thread.dataArrived);
+    return 0;
+}
+
commit cba0fe149ead417017cfe6b1d7c4311ca906c314
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Mar 14 15:16:11 2014 +0100

    KDE4: change eventLoopType enum to glib bool
    
    Just check for glib; it's the default in later Qt4 versions on unix.
    
    Change-Id: Ia99466e9010eb835bea0c3c4420da3c8b3cd4671
    (cherry picked from commit 516a8dedac9c3cb77cd26a740cf793b1cab920d0)

diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index e936c69..5c4cd10 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -45,21 +45,15 @@
 
 #include <config_kde4.h>
 
-#if KDE_HAVE_GLIB
-#define GLIB_EVENT_LOOP_SUPPORT 1
-#else
-#define GLIB_EVENT_LOOP_SUPPORT 0
-#endif
-
-#if GLIB_EVENT_LOOP_SUPPORT
-#include <glib-2.0/glib.h>
-#endif
-
 KDEXLib::KDEXLib() :
     SalXLib(),  m_bStartupDone(false), m_pApplication(0),
     m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
-    eventLoopType( LibreOfficeEventLoop ), m_frameWidth( -1 )
+    m_frameWidth( -1 ), m_isGlibEventLoopType(false)
 {
+#if KDE_HAVE_GLIB
+    m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
+#endif
+
     // the timers created here means they belong to the main thread.
     // As the timeoutTimer runs the LO event queue, which may block on a dialog,
     // the timer has to use a Qt::QueuedConnection, otherwise the nested event
@@ -190,9 +184,17 @@ void KDEXLib::Init()
 // needs to be unlocked shortly before entering the main sleep (e.g. select()) and locked
 // immediatelly after. So we need to know which event loop implementation is used and
 // hook accordingly.
-#if GLIB_EVENT_LOOP_SUPPORT
+#if KDE_HAVE_GLIB
+#include <glib.h>
+
 static GPollFunc old_gpoll = NULL;
 static gint gpoll_wrapper( GPollFD*, guint, gint );
+
+gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
+{
+    SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
+    return old_gpoll( ufds, nfds, timeout );
+}
 #endif
 
 static bool ( *old_qt_event_filter )( void* );
@@ -208,35 +210,19 @@ static bool qt_event_filter( void* m )
 void KDEXLib::setupEventLoop()
 {
     old_qt_event_filter = QAbstractEventDispatcher::instance()->setEventFilter( qt_event_filter );
-#if GLIB_EVENT_LOOP_SUPPORT
-// Glib is simple, it has g_main_context_set_poll_func() for wrapping the sleep call.
-// The catch is that Qt has a bug that allows triggering timers even when they should
-// not be, leading to crashes caused by QClipboard re-entering the event loop.
-// (http://bugreports.qt.nokia.com/browse/QTBUG-14461), so enable only with Qt>=4.8.0,
-// where it is fixed.
-#if QT_VERSION >= QT_VERSION_CHECK( 4, 8, 0 )
-    if( QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" ))
+#if KDE_HAVE_GLIB
+    if( m_isGlibEventLoopType )
     {
-        eventLoopType = GlibEventLoop;
         old_gpoll = g_main_context_get_poll_func( NULL );
         g_main_context_set_poll_func( NULL, gpoll_wrapper );
         return;
     }
 #endif
-#endif
-}
-
-#if GLIB_EVENT_LOOP_SUPPORT
-gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
-{
-    SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
-    return old_gpoll( ufds, nfds, timeout );
 }
-#endif
 
 void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle )
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
         return SalXLib::Insert( fd, data, pending, queued, handle );
     SocketData sdata;
     sdata.data = data;
@@ -251,7 +237,7 @@ void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, Y
 
 void KDEXLib::Remove( int fd )
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
         return SalXLib::Remove( fd );
     SocketData sdata = socketData.take( fd );// according to SalXLib::Remove() this should be safe
     delete sdata.notifier;
@@ -265,7 +251,7 @@ void KDEXLib::socketNotifierActivated( int fd )
 
 void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
     {
         if( qApp->thread() == QThread::currentThread())
         {
@@ -307,7 +293,7 @@ void KDEXLib::processYield( bool bWait, bool bHandleAllCurrentEvents )
 
 void KDEXLib::StartTimer( sal_uLong nMS )
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
         return SalXLib::StartTimer( nMS );
     timeoutTimer.setInterval( nMS );
     // QTimer's can be started only in their thread (main thread here)
@@ -324,7 +310,7 @@ void KDEXLib::startTimeoutTimer()
 
 void KDEXLib::StopTimer()
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
         return SalXLib::StopTimer();
     timeoutTimer.stop();
 }
@@ -338,14 +324,14 @@ void KDEXLib::timeoutActivated()
 
 void KDEXLib::Wakeup()
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
         return SalXLib::Wakeup();
     QAbstractEventDispatcher::instance( qApp->thread())->wakeUp(); // main thread event loop
 }
 
 void KDEXLib::PostUserEvent()
 {
-    if( eventLoopType == LibreOfficeEventLoop )
+    if( !m_isGlibEventLoopType )
         return SalXLib::PostUserEvent();
     if( qApp->thread() == QThread::currentThread())
         startUserEventTimer();
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index 1d307a0..f26948d 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -51,8 +51,8 @@ class KDEXLib : public QObject, public SalXLib
         QHash< int, SocketData > socketData; // key is fd
         QTimer timeoutTimer;
         QTimer userEventTimer;
-        enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
         int m_frameWidth;
+        bool m_isGlibEventLoopType;
 
     private:
         void setupEventLoop();
commit 890860dfbff08c31349eedb019d62381010556ac
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Feb 26 17:02:38 2014 +0200

    KDE4: Drop Qt 4.9 support
    
    I don't think there will ever be any 4.9 release, so drop all the
    unused code.
    
    Change-Id: I4b72de96e6064240582cd83d4e45547096a2efb0
    (cherry picked from commit 7dd973344a8e2c09ac52aa02739b6b921f6df87e)

diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index e08856e..e936c69 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -45,12 +45,6 @@
 
 #include <config_kde4.h>
 
-#if QT_VERSION >= QT_VERSION_CHECK( 4, 9, 0 )
-#define QT_UNIX_EVENT_LOOP_SUPPORT 1
-#else
-#define QT_UNIX_EVENT_LOOP_SUPPORT 0
-#endif
-
 #if KDE_HAVE_GLIB
 #define GLIB_EVENT_LOOP_SUPPORT 1
 #else
@@ -200,12 +194,6 @@ void KDEXLib::Init()
 static GPollFunc old_gpoll = NULL;
 static gint gpoll_wrapper( GPollFD*, guint, gint );
 #endif
-#if QT_UNIX_EVENT_LOOP_SUPPORT
-static int (*qt_select)(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
-   const struct timeval *orig_timeout);
-static int lo_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
-   const struct timeval *orig_timeout);
-#endif
 
 static bool ( *old_qt_event_filter )( void* );
 static bool qt_event_filter( void* m )
@@ -236,21 +224,6 @@ void KDEXLib::setupEventLoop()
     }
 #endif
 #endif
-#if QT_UNIX_EVENT_LOOP_SUPPORT
-// When Qt does not use Glib support, it uses its own Unix event dispatcher.
-// That one has aboutToBlock() and awake() signals, but they are broken (either
-// functionality or semantics), as e.g. awake() is not emitted right after the dispatcher
-// is woken up from sleep again, but only later (which is too late for re-acquiring SolarMutex).
-// This should be fixed with Qt-4.8.0 (?) where support for adding custom select() function
-// has been added too (http://bugreports.qt.nokia.com/browse/QTBUG-16934).
-    if( QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherUNIX" ))
-    {
-        eventLoopType = QtUnixEventLoop;
-        QInternal::callFunction( QInternal::GetUnixSelectFunction, reinterpret_cast< void** >( &qt_select ));
-        QInternal::callFunction( QInternal::SetUnixSelectFunction, reinterpret_cast< void** >( lo_select ));
-        return;
-    }
-#endif
 }
 
 #if GLIB_EVENT_LOOP_SUPPORT
@@ -261,15 +234,6 @@ gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
 }
 #endif
 
-#if QT_UNIX_EVENT_LOOP_SUPPORT
-int lo_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
-   const struct timeval *orig_timeout)
-{
-    SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
-    return qt_select( nfds, fdread, fdwrite, fdexcept, orig_timeout );
-}
-#endif
-
 void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle )
 {
     if( eventLoopType == LibreOfficeEventLoop )
commit 98049435d7c4c9e9b03a3284da7e839da474ccdb
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Mar 13 21:55:31 2014 +0100

    Revert "Rewrite Qt4 based nested yield mutex locking."
    
    This reverts the unx/kde4/KDEXLib.cxx part of
    
    commit 13a34f4c6307d1bd2443cbf3fbd83bfdd8cdbafb.
    
    Conflicts:
    
    	vcl/unx/kde4/KDE4FilePicker.cxx
    	vcl/unx/kde4/KDEXLib.cxx
    
    Change-Id: Ica8a0f678f080ae7d763bb7da7761d20ceec328c
    (cherry picked from commit daf011870efae282244c0298494820d9a0c6d3bc)

diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 6bd6c1a..e08856e 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -301,9 +301,6 @@ void KDEXLib::socketNotifierActivated( int fd )
 
 void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
 {
-    // Nested yield loop counter.
-    static int loop_depth = 0;
-
     if( eventLoopType == LibreOfficeEventLoop )
     {
         if( qApp->thread() == QThread::currentThread())
@@ -317,21 +314,13 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
 
     // if we are the main thread (which is where the event processing is done),
     // good, just do it
-    if( qApp->thread() == QThread::currentThread()) {
-        // Release the yield lock before entering a nested loop.
-        if (loop_depth > 0)
-            SalYieldMutexReleaser aReleaser;
-        loop_depth++;
+    if( qApp->thread() == QThread::currentThread())
         processYield( bWait, bHandleAllCurrentEvents );
-        loop_depth--;
-    }
-    else {
+    else
+    {
         // we were called from another thread;
         // release the yield lock to prevent deadlock.
         SalYieldMutexReleaser aReleaser;
-
-        // if this deadlocks, event processing needs to go into a separate
-        // thread or some other solution needs to be found
         Q_EMIT processYieldSignal( bWait, bHandleAllCurrentEvents );
     }
 }
commit 54232567ea4470087f8a827eb8840ad8ea0cadee
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Mon Mar 10 14:57:10 2014 +0000

    Revert "KDE4: sleep in yield for native file picker"
    
    This reverts commit 380f3b4b6cbbe8e82b58ddf55e95c5005307b51f.
    
    Conflicts:
    
    	vcl/unx/kde4/KDEXLib.cxx
    	vcl/unx/kde4/KDEXLib.hxx
    
    Change-Id: I8a201c89be63cebab7401124002261be23e049c7
    (cherry picked from commit 52a2bde753fdf62cd8bb8498ef92abcce86e6c12)

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 405eafe..b3fde26 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -38,7 +38,6 @@
 
 #include "KDE4FilePicker.hxx"
 #include "FPServiceInfo.hxx"
-#include "KDEXLib.hxx"
 
 /* ********* Hack, but needed because of conflicting types... */
 #define Region QtXRegion
@@ -114,11 +113,10 @@ QString toQString(const OUString& s)
 // KDE4FilePicker
 //////////////////////////////////////////////////////////////////////////
 
-KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>&, KDEXLib *xlib )
+KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
     : KDE4FilePicker_Base(_helperMutex)
     , _resMgr( ResMgr::CreateResMgr("fps_office") )
     , allowRemoteUrls( false )
-    , _mXLib( xlib )
 {
     _extraControls = new QWidget();
     _layout = new QGridLayout(_extraControls);
@@ -263,11 +261,8 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
     _dialog->filterWidget()->setEditable(false);
 
     // We're entering a nested loop.
-    // Prevent yield calls, which would crash LO.
-
-    _mXLib->freezeYield( true );
+    // Release the yield mutex to prevent deadlocks.
     int result = _dialog->exec();
-    _mXLib->freezeYield( false );
 
     // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
     // (such as the auto-extension flag), but that doesn't update KGlobal::config()
diff --git a/vcl/unx/kde4/KDE4FilePicker.hxx b/vcl/unx/kde4/KDE4FilePicker.hxx
index 81acf0c..6dc97df 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -40,7 +40,6 @@
 class KFileDialog;
 class QWidget;
 class QLayout;
-class KDEXLib;
 
 class ResMgr;
 
@@ -83,10 +82,8 @@ protected:
 
     bool allowRemoteUrls;
 
-    KDEXLib* _mXLib;
-
 public:
-    KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&, KDEXLib* );
+    KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& );
     virtual ~KDE4FilePicker();
 
     // XFilePickerNotifier
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index f8923c3..6bd6c1a 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -64,8 +64,7 @@
 KDEXLib::KDEXLib() :
     SalXLib(),  m_bStartupDone(false), m_pApplication(0),
     m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
-    eventLoopType( LibreOfficeEventLoop ),
-    m_bYieldFrozen( false ), m_frameWidth( -1 )
+    eventLoopType( LibreOfficeEventLoop ), m_frameWidth( -1 )
 {
     // the timers created here means they belong to the main thread.
     // As the timeoutTimer runs the LO event queue, which may block on a dialog,
@@ -233,7 +232,6 @@ void KDEXLib::setupEventLoop()
         eventLoopType = GlibEventLoop;
         old_gpoll = g_main_context_get_poll_func( NULL );
         g_main_context_set_poll_func( NULL, gpoll_wrapper );
-        m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true );
         return;
     }
 #endif
@@ -317,17 +315,6 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
         return SalXLib::Yield( bWait, bHandleAllCurrentEvents );
     }
 
-    if( m_bYieldFrozen ) {
-        if( qApp->thread() != QThread::currentThread() ) {
-            QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread() );
-            if( dispatcher->hasPendingEvents() ) {
-                struct timespec delay = {0, ( 1000000 )};
-                nanosleep(&delay, NULL);
-            }
-        }
-        return;
-    }
-
     // if we are the main thread (which is where the event processing is done),
     // good, just do it
     if( qApp->thread() == QThread::currentThread()) {
@@ -445,7 +432,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
         SalYieldMutexReleaser aReleaser;
         return Q_EMIT createFilePickerSignal( xMSF );
     }
-    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) );
+    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
 }
 
 #define Region QtXRegion
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index dd7f83f..1d307a0 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -52,7 +52,6 @@ class KDEXLib : public QObject, public SalXLib
         QTimer timeoutTimer;
         QTimer userEventTimer;
         enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
-        bool m_bYieldFrozen;
         int m_frameWidth;
 
     private:
@@ -87,7 +86,6 @@ class KDEXLib : public QObject, public SalXLib
         virtual void Wakeup();
         virtual void PostUserEvent();
 
-        void freezeYield(bool freeze) { m_bYieldFrozen = freeze; }
         void doStartup();
 
     public Q_SLOTS:
commit 3a4dab90e1b50c96b10c83f272c338b989f05b7b
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Feb 27 08:51:00 2014 +0000

    KDE4: Report correct check and radio item sizes
    
    Use the correct sizs from the current style.
    
    Change-Id: I7e163bdc8d467baf2d6e3d0d2bc3e1da7558cf42
    (cherry picked from commit ab1f5eab4830f00dbbd7c883b98b59975ecd3bb1)

diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index b1a0efe..6e20ef1 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -820,12 +820,26 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
             break;
         }
         case CTRL_MENU_POPUP:
-            if (part == PART_MENU_ITEM_CHECK_MARK || part == PART_MENU_ITEM_RADIO_MARK)
-            { // core uses this to detect radio/checkbox sizes, so just set a square
-                contentRect.setWidth(contentRect.height());
+        {
+            int h, w;
+            switch ( part ) {
+            case PART_MENU_ITEM_CHECK_MARK:
+                h = kapp->style()->pixelMetric(QStyle::PM_IndicatorHeight);
+                w = kapp->style()->pixelMetric(QStyle::PM_IndicatorWidth);
+                retVal = true;
+                break;
+            case PART_MENU_ITEM_RADIO_MARK:
+                h = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight);
+                w = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth);
                 retVal = true;
+                break;
+            }
+            if (retVal) {
+                contentRect = QRect(0, 0, w, h);
+                boundingRect = contentRect;
             }
             break;
+        }
         case CTRL_FRAME:
         {
             if( part == PART_BORDER )
commit 73c5ac0edb4d7b4d6ba441b2a338f49d8f8d9a42
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Feb 27 20:34:00 2014 +0000

    KDE4: evaluate frameWidth in the Qt thread
    
    When opening a document via Java UNO without a running LO instance, one
    gets the following Qt error messages:
    
    CE>  QObject: Cannot create children for a parent that is in a different thread.
    CE>  (Parent is Oxygen::WidgetStateEngine(0x8deb878), parent's thread is QThread(0x8d6cf70), current thread is QThread(0xa8fa7fc8)
    CE>  QObject::installEventFilter(): Cannot filter events for objects in a different thread.
    CE>  QObject::installEventFilter(): Cannot filter events for objects in a different thread.
    CE>  QObject::installEventFilter(): Cannot filter events for objects in a different thread.
    
    This happens, because the Java UNO call is processed in the first /
    Qt thread while document loading happens in a second thread.
    
    Document loading actually just calls getNativeControlRegion, which
    should not involve any drawing. But the KDE4 backend does some style
    processing to get the correct frame width (QWidget::ensurePolished(),
    which uses GUI based events and need to be processed in the Qt
    thread.
    
    Change-Id: I344d5089d958963c48a9a8a84bfa9fe8f092b75a
    (cherry picked from commit 7163d64b90ac4d4259b1d0379cfca348dd30601c)

diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 967864f..b1a0efe 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -31,10 +31,12 @@
 #undef Region
 
 #include "KDESalGraphics.hxx"
+#include "KDESalInstance.hxx"
 
 #include <vcl/settings.hxx>
 #include <vcl/decoview.hxx>
 #include <rtl/ustrbuf.hxx>
+#include <unx/saldata.hxx>
 
 using namespace ::rtl;
 
@@ -165,21 +167,6 @@ namespace
         kapp->style()->drawComplexControl(element, option, &painter);
     }
 
-    int getFrameWidth()
-    {
-        static int s_nFrameWidth = -1;
-        if( s_nFrameWidth < 0 )
-        {
-            // fill in a default
-            QFrame aFrame( NULL );
-            aFrame.setFrameRect( QRect(0, 0, 100, 30) );
-            aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
-            aFrame.ensurePolished();
-            s_nFrameWidth = aFrame.frameWidth();
-        }
-        return s_nFrameWidth;
-    }
-
     void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state)
     {
     #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
@@ -554,7 +541,7 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
                        vclStateValue2StateFlag(nControlState, value) );
 
         // draw just the border, see http://qa.openoffice.org/issues/show_bug.cgi?id=107945
-        int fw = getFrameWidth();
+        int fw = static_cast< KDESalInstance* >(GetSalData()->m_pInstance)->getFrameWidth();
         clipRegion = new QRegion( QRegion( widgetRect ).subtracted( widgetRect.adjusted( fw, fw, -fw, -fw )));
     }
     else if (type == CTRL_WINDOW_BACKGROUND)
@@ -843,7 +830,7 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
         {
             if( part == PART_BORDER )
             {
-                int nFrameWidth = getFrameWidth();
+                int nFrameWidth = static_cast< KDESalInstance* >(GetSalData()->m_pInstance)->getFrameWidth();
                 sal_uInt16 nStyle = val.getNumericVal();
                 if( nStyle & FRAME_DRAW_NODRAW )
                 {
diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx
index 224ac3a..9670172 100644
--- a/vcl/unx/kde4/KDESalInstance.cxx
+++ b/vcl/unx/kde4/KDESalInstance.cxx
@@ -38,4 +38,9 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
         static_cast<KDEXLib*>( mpXLib )->createFilePicker(xMSF) );
 }
 
+int KDESalInstance::getFrameWidth()
+{
+    return static_cast<KDEXLib*>( mpXLib )->getFrameWidth();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDESalInstance.hxx b/vcl/unx/kde4/KDESalInstance.hxx
index 3c07f52..f73af0d 100644
--- a/vcl/unx/kde4/KDESalInstance.hxx
+++ b/vcl/unx/kde4/KDESalInstance.hxx
@@ -36,6 +36,7 @@ class KDESalInstance : public X11SalInstance
         virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
             createFilePicker( const com::sun::star::uno::Reference<
                                   com::sun::star::uno::XComponentContext >& );
+        int getFrameWidth();
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 4a9b70b..f8923c3 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -65,7 +65,7 @@ KDEXLib::KDEXLib() :
     SalXLib(),  m_bStartupDone(false), m_pApplication(0),
     m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
     eventLoopType( LibreOfficeEventLoop ),
-    m_bYieldFrozen( false )
+    m_bYieldFrozen( false ), m_frameWidth( -1 )
 {
     // the timers created here means they belong to the main thread.
     // As the timeoutTimer runs the LO event queue, which may block on a dialog,
@@ -92,6 +92,9 @@ KDEXLib::KDEXLib() :
              this, SLOT( createFilePicker( const com::sun::star::uno::Reference<
                                                  com::sun::star::uno::XComponentContext >&) ),
              Qt::BlockingQueuedConnection );
+
+    connect( this, SIGNAL( getFrameWidthSignal() ),
+             this, SLOT( getFrameWidth() ), Qt::BlockingQueuedConnection );
 }
 
 KDEXLib::~KDEXLib()
@@ -445,6 +448,27 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
     return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) );
 }
 
+#define Region QtXRegion
+#include <qframe.h>
+#undef Region
+
+int KDEXLib::getFrameWidth()
+{
+    if( m_frameWidth >= 0 )
+        return m_frameWidth;
+    if( qApp->thread() != QThread::currentThread()) {
+        SalYieldMutexReleaser aReleaser;
+        return Q_EMIT getFrameWidthSignal();
+    }
+
+    // fill in a default
+    QFrame aFrame( NULL );
+    aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+    aFrame.ensurePolished();
+    m_frameWidth = aFrame.frameWidth();
+    return m_frameWidth;
+}
+
 #include "KDEXLib.moc"
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index d07b9f6..dd7f83f 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -53,6 +53,7 @@ class KDEXLib : public QObject, public SalXLib
         QTimer userEventTimer;
         enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
         bool m_bYieldFrozen;
+        int m_frameWidth;
 
     private:
         void setupEventLoop();
@@ -71,6 +72,7 @@ class KDEXLib : public QObject, public SalXLib
         com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
             createFilePickerSignal( const com::sun::star::uno::Reference<
                                           com::sun::star::uno::XComponentContext >& );
+        int getFrameWidthSignal();
 
     public:
         KDEXLib();
@@ -89,9 +91,10 @@ class KDEXLib : public QObject, public SalXLib
         void doStartup();
 
     public Q_SLOTS:
-        virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
+        com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
             createFilePicker( const com::sun::star::uno::Reference<
                                   com::sun::star::uno::XComponentContext >& );
+        int getFrameWidth();
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3d53b2730eeabd06dfd6ad183c1d12b15836b777
Author: Oliver-Rainer Wittmann <orw at apache.org>
Date:   Fri Mar 21 12:32:09 2014 +0000

    Resolves: fdo#75728 #i124474# on change of User Field via UNO-API...
    
    trigger update to get dependent Input Fields updated.
    
    (cherry picked from commit 40c8121fbeb89403418a90c77b88d13ad268d347)
    Signed-off-by: Andras Timar <andras.timar at collabora.com>
    
    Change-Id: I0ead765729c93992103baca53924b7a127936b38

diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index f49595c..ccca8f4 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -583,18 +583,29 @@ throw (beans::UnknownPropertyException, beans::PropertyVetoException,
                 }
             }
         }
-        if( bSetValue )
+        if ( bSetValue )
         {
             // nothing special to be done here for the properties
             // UNO_NAME_DATA_BASE_NAME and UNO_NAME_DATA_BASE_URL.
             // We just call PutValue (empty string is allowed).
             // Thus the last property set will be used as Data Source.
 
-            sal_uInt16 nMId = GetFieldTypeMId( rPropertyName, *pType  );
-            if( USHRT_MAX != nMId )
-                pType->PutValue( rValue, nMId );
+            const sal_uInt16 nMemberValueId = GetFieldTypeMId( rPropertyName, *pType );
+            if ( USHRT_MAX != nMemberValueId )
+            {
+                pType->PutValue( rValue, nMemberValueId );
+                if ( pType->Which() == RES_USERFLD )
+                {
+                    // trigger update of User field in order to get depending Input Fields updated.
+                    pType->UpdateFlds();
+                }
+            }
             else
-                throw beans::UnknownPropertyException(OUString( "Unknown property: " ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
+            {
+                throw beans::UnknownPropertyException(
+                    OUString( "Unknown property: " ) + rPropertyName,
+                    static_cast< cppu::OWeakObject * >( this ) );
+            }
         }
     }
     else if (!pType && m_pImpl->m_pDoc &&
commit fc70d91713332676dd2b8aa77d67684258493b15
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Mar 21 15:33:53 2014 +0000

    coverity#705966 Dereference before null check
    
    Change-Id: I74507ce67f928bdeb626d4070dbd2a45cc126521
    (cherry picked from commit 511d8bbbec6bc95d92a3ac6bbac4c68622738706)
    Reviewed-on: https://gerrit.libreoffice.org/8698
    Reviewed-by: Norbert Thiebaud <nthiebaud at gmail.com>
    Tested-by: Norbert Thiebaud <nthiebaud at gmail.com>

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 9880b7b..868e970 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -2413,7 +2413,7 @@ bool GetSfntTable( TrueTypeFont* ttf, int nSubtableIndex,
         return false;
     *pRawLength = ttf->tlens[ nSubtableIndex ];
     *ppRawBytes = ttf->tables[ nSubtableIndex ];
-    bool bOk = (*pRawLength > 0) && (ppRawBytes != NULL);
+    bool bOk = (*pRawLength > 0) && (*ppRawBytes != NULL);
     return bOk;
 }
 
commit b22fbeb70719110eb7b8774fe96092e66861460a
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Mar 21 11:12:44 2014 +0000

    coverity#736084 Missing break in switch
    
    Change-Id: I3c7a032441402455d0a6ed28fc2cd5ce958ead04
    (cherry picked from commit 5c291a0287af46558d3ef96d18b114c371ddd31b)
    Reviewed-on: https://gerrit.libreoffice.org/8690
    Reviewed-by: Matúš Kukan <matus.kukan at collabora.com>
    Tested-by: Matúš Kukan <matus.kukan at collabora.com>

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 54b6927..5078491 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -2666,11 +2666,13 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
                 RTFValue::Pointer_t pValue(new RTFValue(1));
                 m_aStates.top().aTableRowSprms.set(NS_sprm::LN_TCantSplit, pValue);
             }
+            break;
         case RTF_SECTUNLOCKED:
             {
                 RTFValue::Pointer_t pValue(new RTFValue(!nParam));
                 m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
             }
+            break;
         case RTF_PGNDEC:
         case RTF_PGNUCRM:
         case RTF_PGNLCRM:
commit 08f4cb8af496adcbd4bd3dae5af040a614208c70
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Mar 20 21:17:44 2014 +0000

    Don't duplicate relationship sequences while walking them.
    
    Change-Id: If938f2f401af82d5d0122cbd0a78214829d1277c
    Reviewed-on: https://gerrit.libreoffice.org/8685
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 90a9072..4890f31 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -206,13 +206,13 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
 
         for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
         {
-            uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
+            const uno::Sequence< beans::StringPair > &aSeq = aSeqs[j];
 
             bool bExternalTarget = false;
             OUString sMyTarget;
             for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
             {
-                beans::StringPair aPair = aSeq[i];
+                const beans::StringPair &aPair = aSeq[i];
 
                 if (aPair.First.compareTo(sType) == 0 &&
                     ( aPair.Second.compareTo(sStreamType) == 0 ||
commit 895c13faf15b4ebf45be23c461f49a8ab0fd4e09
Author: Julien Nabet <serval2412 at yahoo.fr>
Date:   Sat Feb 22 09:06:05 2014 +0100

    Resolves: fdo#75308 Asterisk at the beginning of Paragraph without "Nowiki"
    
    The fix of fdo#74875 brings a huge regression since nowiki must be used
    With this patch, fdo#74875 is still ok hopefully.
    
    Change-Id: Ic6ed34630b40b09ab4f63166cbb1985b6313d168
    Reviewed-on: https://gerrit.libreoffice.org/8167
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/swext/mediawiki/src/filter/odt2mediawiki.xsl b/swext/mediawiki/src/filter/odt2mediawiki.xsl
index 1b14aa1..64474b3 100644
--- a/swext/mediawiki/src/filter/odt2mediawiki.xsl
+++ b/swext/mediawiki/src/filter/odt2mediawiki.xsl
@@ -1129,21 +1129,12 @@
 		<param name="text"/>
 		
 		<choose>
-			<when test="contains($text, '<') or contains($text, '[') or starts-with($text, '----') or starts-with($text, '=') or starts-with($text, '*')  or starts-with($text, ';')  or starts-with($text, '#')">
-				<choose>
-					<when test="contains($text, '</nowiki>')">
-				                <text><nowiki></text>
-						<call-template name="render-escaped-text">
-							<with-param name="text" select="$text"/>
-						</call-template>
-				                <text></nowiki></text>			
-					</when>
-					<otherwise>
-						<call-template name="render-encoded-text">
-							<with-param name="text" select="$text"/>
-						</call-template>
-					</otherwise>
-				</choose>
+			<when test="contains($text, '[[') or starts-with($text, '----') or starts-with($text, '=') or starts-with($text, '*')  or starts-with($text, ';')  or starts-with($text, '#')">
+				<text><nowiki></text>
+					<call-template name="render-encoded-text">
+						<with-param name="text" select="$text"/>
+					</call-template>
+				<text></nowiki></text>			
 			</when>
 			<otherwise>
 				<call-template name="render-encoded-text">
commit 76ac4d0e2c34d3fd2ba9cc7825c7cff25d463c1d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Mar 18 21:45:15 2014 -0400

    fdo#75260: Align exterior borders of a table correctly for double lines.
    
    This fixes double border drawing problem with table objects in Draw and
    Impress.
    
    Change-Id: I76527d610b74018b5e056ff72cc9e37e9f9c6f03
    (cherry picked from commit 8ff746e1ad4950124e09da2dc913d8d64c726c90)
    Reviewed-on: https://gerrit.libreoffice.org/8651
    Reviewed-by: Fridrich Strba <fridrich at documentfoundation.org>
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>

diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
index 683ec24..05ba404 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -298,8 +298,13 @@ namespace drawinglayer
             if(!getLeftLine().isEmpty())
             {
                 // create left line from top to bottom
-                const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0));
-                const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(0.0, 1.0));
+                basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0));
+                basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(0.0, 1.0));
+
+                // Move the left border to the left.
+                double fOffset = getChangedValue(getLeftLine().GetDistance(), getInTwips());
+                aStart += basegfx::B2DPoint(-fOffset,-fOffset);
+                aEnd += basegfx::B2DPoint(-fOffset,fOffset);
 
                 if(!aStart.equal(aEnd))
                 {
@@ -391,8 +396,13 @@ namespace drawinglayer
             if(!getTopLine().isEmpty())
             {
                 // create top line from left to right
-                const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0));
-                const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 0.0));
+                basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0));
+                basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 0.0));
+
+                // Move the top border up a bit.
+                double fOffset = getChangedValue(getTopLine().GetDistance(), getInTwips());
+                aStart += basegfx::B2DPoint(-fOffset,-fOffset);
+                aEnd += basegfx::B2DPoint(fOffset,-fOffset);
 
                 if(!aStart.equal(aEnd))
                 {
commit 0fbd73b8f02926664c9d04fc596f482f5977ae59
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Mar 18 16:59:20 2014 -0400

    fdo#75260: Apply the same fix from writer table to character bordering.
    
    And mirror the right and bottom borders while I'm at it. I guess it was
    originally meant to.
    
    Change-Id: I408b077c1524d19bbadd6f0b284ce204064eb735
    (cherry picked from commit 2cd1673f41cb5bd8502a9a48a5721244660fe3a0)
    Reviewed-on: https://gerrit.libreoffice.org/8650
    Reviewed-by: Fridrich Strba <fridrich at documentfoundation.org>
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index ee0047e..3e4ed87 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5050,23 +5050,25 @@ void PaintCharacterBorder(
 
     // Init borders, after this initialization top, bottom, right and left means the
     // absolute position
-    const boost::optional<editeng::SvxBorderLine> aTopBorder =
+    boost::optional<editeng::SvxBorderLine> aTopBorder =
         (bTop ? rFont.GetAbsTopBorder(bVerticalLayout) : boost::none);
-    const boost::optional<editeng::SvxBorderLine> aBottomBorder =
+    boost::optional<editeng::SvxBorderLine> aBottomBorder =
         (bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout) : boost::none);
-    const boost::optional<editeng::SvxBorderLine> aLeftBorder =
+    boost::optional<editeng::SvxBorderLine> aLeftBorder =
         (bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout) : boost::none);
-    const boost::optional<editeng::SvxBorderLine> aRightBorder =
+    boost::optional<editeng::SvxBorderLine> aRightBorder =
         (bRight ? rFont.GetAbsRightBorder(bVerticalLayout) : boost::none);
 
     if( aTopBorder )
     {
+        sal_uInt16 nOffset = aTopBorder->GetDistance();
+
         Point aLeftTop(
-            aAlignedRect.Left(),
-            aAlignedRect.Top());
+            aAlignedRect.Left() - nOffset,
+            aAlignedRect.Top() - nOffset);
         Point aRightBottom(
-            aAlignedRect.Right(),
-            aAlignedRect.Top() + aTopBorder.get().GetScaledWidth());
+            aAlignedRect.Right() + nOffset,
+            aAlignedRect.Top() - nOffset + aTopBorder->GetScaledWidth());
 
         lcl_MakeBorderLine(
             SwRect(aLeftTop, aRightBottom),
@@ -5078,6 +5080,8 @@ void PaintCharacterBorder(
 
     if( aBottomBorder )
     {
+        aBottomBorder->SetMirrorWidths(true);
+
         Point aLeftTop(
             aAlignedRect.Left(),
             aAlignedRect.Bottom() - aBottomBorder.get().GetScaledWidth());
@@ -5095,12 +5099,14 @@ void PaintCharacterBorder(
 
     if( aLeftBorder )
     {
+        sal_uInt16 nOffset = aLeftBorder->GetDistance();
+
         Point aLeftTop(
-            aAlignedRect.Left(),
-            aAlignedRect.Top());
+            aAlignedRect.Left() - nOffset,
+            aAlignedRect.Top() - nOffset);
         Point aRightBottom(
-            aAlignedRect.Left() + aLeftBorder.get().GetScaledWidth(),
-            aAlignedRect.Bottom());
+            aAlignedRect.Left() - nOffset + aLeftBorder->GetScaledWidth(),
+            aAlignedRect.Bottom() + nOffset);
 
         lcl_MakeBorderLine(
             SwRect(aLeftTop, aRightBottom),
@@ -5112,6 +5118,8 @@ void PaintCharacterBorder(
 
     if( aRightBorder )
     {
+        aRightBorder->SetMirrorWidths(true);
+
         Point aLeftTop(
             aAlignedRect.Right() - aRightBorder.get().GetScaledWidth(),
             aAlignedRect.Top());
commit 4d2ff40bf36f52c3fdd61311159a4ace5e631298
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Mar 18 16:29:53 2014 -0400

    fdo#75260: Apply the same fix from writer table to paragraph bordering.
    
    Change-Id: Icb11a2e2f802cbf2af2362315f3acbc66f15334d
    (cherry picked from commit 961da51ae28b46c96344be20abd1b5172a3faa3f)
    Reviewed-on: https://gerrit.libreoffice.org/8649
    Reviewed-by: Fridrich Strba <fridrich at documentfoundation.org>
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index c2719ddb..ee0047e 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4899,6 +4899,16 @@ static void lcl_PaintLeftRightLine( const bool         _bLeft,
     {
         (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ) ) -
                                        (aRect.*_rRectFn->fnGetWidth)() );
+
+        // Shift the left border to the left.
+        Point aCurPos = aRect.Pos();
+        sal_uInt16 nOffset = pLeftRightBorder->GetDistance();
+        aCurPos.X() -= nOffset;
+        aCurPos.Y() -= nOffset;
+        aRect.Pos(aCurPos);
+        Size aCurSize = aRect.SSize();
+        aCurSize.Height() += nOffset * 2;
+        aRect.SSize(aCurSize);
     }
     else
     {
@@ -4965,6 +4975,16 @@ static void lcl_PaintTopBottomLine( const bool         _bTop,
     {
         (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ) ) -
                                         (aRect.*_rRectFn->fnGetHeight)() );
+
+        // Push the top border up a bit.
+        sal_uInt16 nOffset = pTopBottomBorder->GetDistance();
+        Point aCurPos = aRect.Pos();
+        aCurPos.X() -= nOffset;
+        aCurPos.Y() -= nOffset;
+        aRect.Pos(aCurPos);
+        Size aCurSize = aRect.SSize();
+        aCurSize.Width() += nOffset * 2;
+        aRect.SSize(aCurSize);
     }
     else
     {
commit bb75460ad23edcf23cded63e554c611bded2dd04
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Mar 20 09:54:35 2014 -0400

    Disable kernel pre-compilation for now.
    
    Change-Id: I8ba765a4d89618f301572c5fd9931f86d87af10d
    (cherry picked from commit 5d4f525da7f560f85c2ce18f1ca1570d3cc53a50)
    (cherry picked from commit e0d936ef7b7fd6b57cdd5ccadddcbd84bd4bb359)
    Reviewed-on: https://gerrit.libreoffice.org/8680
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 8548867..2d696c3 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -34,6 +34,8 @@
 
 #include "formularesult.hxx"
 
+#define ENABLE_THREADED_OPENCL_KERNEL_COMPILATION 0
+
 namespace sc {
 
 class CLBuildKernelThread;
@@ -78,8 +80,10 @@ struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable
         ScDocument& rDoc, const ScAddress& rPos, formula::FormulaGrammar::Grammar eGram );
     void compileOpenCLKernel();
 
+#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
     static int snCount;
     static rtl::Reference<sc::CLBuildKernelThread> sxCompilationThread;
+#endif
 };
 
 inline void intrusive_ptr_add_ref(const ScFormulaCellGroup *p)
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 395adfd..eb40441 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -55,8 +55,6 @@
 
 #include <boost/scoped_ptr.hpp>
 
-#define ENABLE_THREADED_OPENCL_KERNEL_COMPILATION 1
-
 using namespace formula;
 
 #ifdef USE_MEMPOOL
@@ -388,6 +386,7 @@ void adjustDBRange(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldD
 
 }
 
+#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
 //  The mutex to synchronize access to the OpenCL compilation thread.
 static osl::Mutex& getOpenCLCompilationThreadMutex()
 {
@@ -407,6 +406,7 @@ static osl::Mutex& getOpenCLCompilationThreadMutex()
 
 int ScFormulaCellGroup::snCount = 0;
 rtl::Reference<sc::CLBuildKernelThread> ScFormulaCellGroup::sxCompilationThread;
+#endif
 
 ScFormulaCellGroup::ScFormulaCellGroup() :
     mnRefCount(0),
@@ -420,6 +420,7 @@ ScFormulaCellGroup::ScFormulaCellGroup() :
     meCalcState(sc::GroupCalcEnabled),
     meKernelState(sc::OpenCLKernelNone)
 {
+#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
     if (ScInterpreter::GetGlobalConfig().mbOpenCLEnabled)
     {
         osl::MutexGuard aGuard(getOpenCLCompilationThreadMutex());
@@ -430,10 +431,12 @@ ScFormulaCellGroup::ScFormulaCellGroup() :
             sxCompilationThread->launch();
         }
     }
+#endif
 }
 
 ScFormulaCellGroup::~ScFormulaCellGroup()
 {
+#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
     if (ScInterpreter::GetGlobalConfig().mbOpenCLEnabled)
     {
         osl::MutexGuard aGuard(getOpenCLCompilationThreadMutex());
@@ -446,17 +449,20 @@ ScFormulaCellGroup::~ScFormulaCellGroup()
                 sxCompilationThread.clear();
             }
     }
+#endif
     delete mpCode;
     delete mpCompiledFormula;
 }
 
 void ScFormulaCellGroup::scheduleCompilation()
 {
+#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
     meKernelState = sc::OpenCLKernelCompilationScheduled;
     sc::CLBuildKernelWorkItem aWorkItem;
     aWorkItem.meWhatToDo = sc::CLBuildKernelWorkItem::COMPILE;
     aWorkItem.mxGroup = this;
     sxCompilationThread->push(aWorkItem);
+#endif
 }
 
 void ScFormulaCellGroup::setCode( const ScTokenArray& rCode )
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 0f6fb22..ec5c4bf 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -3426,6 +3426,7 @@ bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc,
     DynamicKernel *pKernel = NULL;
     boost::scoped_ptr<DynamicKernel> pLocalKernel;
 
+#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
     if (xGroup->meKernelState == sc::OpenCLKernelCompilationScheduled ||
         xGroup->meKernelState == sc::OpenCLKernelBinaryCreated)
     {
@@ -3443,6 +3444,10 @@ bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc,
         pKernel = static_cast<DynamicKernel*>(createCompiledFormula(rDoc, rTopPos, *xGroup, rCode));
         pLocalKernel.reset(pKernel); // to be deleted when done.
     }
+#else
+    pKernel = static_cast<DynamicKernel*>(createCompiledFormula(rDoc, rTopPos, *xGroup, rCode));
+    pLocalKernel.reset(pKernel); // to be deleted when done.
+#endif
 
     if (!pKernel)
         return false;
commit 827d7dbf3b75e61f63c769ce41634e890a608455
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Fri Mar 14 09:42:02 2014 +0100

    fdo#51819: autorecovery: fix saving password in protected documents.
    
    Thanks to sayt at mailinator.com for the idea.
    
    Change-Id: Ib79abafe3d4d3ba21f7914aeb284d86ce662824c
    (cherry picked from commit ef87ff6680f79362a431db6e7ef2f40cfc576219)
    Reviewed-on: https://gerrit.libreoffice.org/8633
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/framework/source/services/autorecovery.cxx b/framework/source/services/autorecovery.cxx
index 8a32d78..3a18af4 100644
--- a/framework/source/services/autorecovery.cxx
+++ b/framework/source/services/autorecovery.cxx
@@ -2305,9 +2305,11 @@ void AutoRecovery::implts_saveOneDoc(const OUString&
     // if the document was loaded with a password, it should be
     // stored with password
     utl::MediaDescriptor lNewArgs;
-    OUString sPassword = lOldArgs.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PASSWORD(), OUString());
-    if (!sPassword.isEmpty())
-        lNewArgs[utl::MediaDescriptor::PROP_PASSWORD()] <<= sPassword;
+    css::uno::Sequence< css::beans::NamedValue > aEncryptionData =
+        lOldArgs.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ENCRYPTIONDATA(),
+                css::uno::Sequence< css::beans::NamedValue >());
+    if (aEncryptionData.getLength() > 0)
+        lNewArgs[utl::MediaDescriptor::PROP_ENCRYPTIONDATA()] <<= aEncryptionData;
 
     // Further it must be saved using the default file format of that application.
     // Otherwhise we will some data lost.
commit 853660dbf4dc350e7a9096e2367c7f10cfcc3ac6
Author: Noel Grandin <noel at peralex.com>
Date:   Tue Mar 18 13:42:37 2014 +0200

    make "rest" param in endsWithIgnoreAsciiCase default to zero
    
    so it matches all of the other endsWith* methods
    
    Change-Id: If6a37056b1225675848434bfb3520e6c496f22e5
    (cherry picked from commit e80b9f344aeb88bdbb42d846c0a094d86ee327dc)
    Signed-off-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx
index 826727f..995ef17 100644
--- a/include/rtl/ustring.hxx
+++ b/include/rtl/ustring.hxx
@@ -1095,7 +1095,7 @@ public:
 
       @since LibreOffice 3.6
     */
-    bool endsWithIgnoreAsciiCase(OUString const & str, OUString * rest) const
+    bool endsWithIgnoreAsciiCase(OUString const & str, OUString * rest = 0) const
     {
         bool b =  str.getLength() <= getLength()
             && matchIgnoreAsciiCase(str, getLength() - str.getLength());
commit d5580b252ad4cfea10422c044366c3c6c1ebed83
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Wed Mar 19 04:50:20 2014 +0100

    the type in the Any is a util::Date and not a DateTime, fdo#74549
    
    Either that was always broken or it is a recent regression that
    operator>>= does not convert from Date to DateTime.
    
    Change-Id: Ic948224c139ed84b3fe006385fcafd6ce16c30f1
    (cherry picked from commit 22c7da0ca5438b69165609db2a1ef219aa167dc2)
    Reviewed-on: https://gerrit.libreoffice.org/8652
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/chart2/source/tools/NumberFormatterWrapper.cxx b/chart2/source/tools/NumberFormatterWrapper.cxx
index 1501532..4994215 100644
--- a/chart2/source/tools/NumberFormatterWrapper.cxx
+++ b/chart2/source/tools/NumberFormatterWrapper.cxx
@@ -26,7 +26,7 @@
 #include <svl/zformat.hxx>
 #include <tools/color.hxx>
 #include <i18nlangtag/mslangid.hxx>
-#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/Date.hpp>
 
 namespace chart
 {
@@ -79,7 +79,7 @@ Date NumberFormatterWrapper::getNullDate() const
     sal_uInt16 nYear = 1899,nDay = 30,nMonth = 12;
     Date aRet(nDay,nMonth,nYear);
 
-    util::DateTime aUtilDate;
+    util::Date aUtilDate;
     if( m_aNullDate.hasValue() && (m_aNullDate >>= aUtilDate) )
     {
         aRet = Date(aUtilDate.Day,aUtilDate.Month,aUtilDate.Year);
@@ -114,7 +114,7 @@ OUString NumberFormatterWrapper::getFormattedString( sal_Int32 nNumberFormatKey,
             nMonth = pDate->GetMonth();
             nDay = pDate->GetDay();
         } // if ( pDate )
-        util::DateTime aNewNullDate;
+        util::Date aNewNullDate;
         m_aNullDate >>= aNewNullDate;
         m_pNumberFormatter->ChangeNullDate(aNewNullDate.Day,aNewNullDate.Month,aNewNullDate.Year);
     }
commit 71d8e5770a332c8ba26048b69dd172704fb703df
Author: Luboš Luňák <l.lunak at centrum.cz>
Date:   Tue Mar 18 18:57:05 2014 +0100

    workaround for rounding errors when handling merged cells (fdo#38414)
    
    Change-Id: I4d36e4b86c77a7356a8c221cbfc5735e925392ba
    Reviewed-on: https://gerrit.libreoffice.org/8648
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>

diff --git a/sw/source/core/table/swnewtable.cxx b/sw/source/core/table/swnewtable.cxx
index c41aedf..34b9c38 100644
--- a/sw/source/core/table/swnewtable.cxx
+++ b/sw/source/core/table/swnewtable.cxx
@@ -200,10 +200,20 @@ static SwTableBox* lcl_LeftBorder2Box( long nLeft, const SwTableLine* pLine )
     {
         SwTableBox* pBox = pLine->GetTabBoxes()[nCurrBox];
         OSL_ENSURE( pBox, "Missing table box" );
-        if( nCurrLeft >= nLeft && pBox->GetFrmFmt()->GetFrmSize().GetWidth() )
+        if( pBox->GetFrmFmt()->GetFrmSize().GetWidth() )
         {
-            OSL_ENSURE( nCurrLeft == nLeft, "Wrong box found" );
-            return pBox;
+            if( nCurrLeft == nLeft )
+                return pBox;
+            // HACK: It appears that rounding errors may result in positions not matching
+            // exactly, so allow a little tolerance. This happens at least with merged cells
+            // in the doc from fdo#38414 .
+            if( abs( nCurrLeft - nLeft ) <= ( nLeft / 1000 ))
+                return pBox;
+            if( nCurrLeft >= nLeft )
+            {
+                SAL_WARN( "sw.core", "Possibly wrong box found" );
+                return pBox;
+            }
         }
         nCurrLeft += pBox->GetFrmFmt()->GetFrmSize().GetWidth();
     }
commit 7dca4fda3ede573eef6582e71facc95b3f79be55
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 17 19:11:35 2014 -0400

    fdo#75260: Improve double line drawing for writer table.
    
    (cherry picked from commit 1c6fb266567c8e397e3c65663b21f0fa50696aa5)
    (cherry picked from commit 77b6c1602aaa0bd059077765e7fabb53d9e6ddeb)
    (cherry picked from commit 32391d25293935fbbf0075e3ccf68625951427f0)
    (cherry picked from commit 24b4fbfa39f212c769bf4d966258a8fb4c98c201)
    (cherry picked from commit 07909e0045d9f94329861fe2e7b3403a5c4befed)
    (cherry picked from commit 335470edf00cabb47abb9d7dcc4dd3a5a0e79616)
    
    Change-Id: Id350531f09b3ded66fd05ea7ebeefe8771260b62
    Reviewed-on: https://gerrit.libreoffice.org/8635
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>

diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 67efa09..7b9348d 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -183,37 +183,33 @@ primitive2d::Primitive2DReference makeSolidLinePrimitive(
 
                     xRetval.realloc(2);
 
-                    {
-                        // "inside" line
-                        double fWidth = getLeftWidth();
-                        basegfx::BColor aColor = getRGBColorLeft();
-                        bool bIsHairline = lcl_UseHairline(
-                                fWidth, getStart(), getEnd(), rViewInformation);
-                        fWidth = lcl_GetCorrectedWidth(fWidth,
-                                    getStart(), getEnd(), rViewInformation);
-
-                        if (bIsHairline)
-                            xRetval[0] = makeHairLinePrimitive(getStart(), getEnd(), aVector, aColor, 0.0);
-                        else
-                            xRetval[0] = makeSolidLinePrimitive(
-                                aClipRegion, aTmpStart, aTmpEnd, aVector, aColor, fWidth, 0.0);
-                    }
+                    double fLeftWidth = getLeftWidth();
+                    bool bLeftHairline = lcl_UseHairline(fLeftWidth, getStart(), getEnd(), rViewInformation);
+                    if (bLeftHairline)
+                        fLeftWidth = 0.0;
 
-                    {
-                        // "outside" line
-                        double fWidth = getRightWidth();
-                        basegfx::BColor aColor = getRGBColorRight();
-                        bool bIsHairline = lcl_UseHairline(
-                                fWidth, getStart(), getEnd(), rViewInformation);
-                        fWidth = lcl_GetCorrectedWidth(fWidth,
-                                    getStart(), getEnd(), rViewInformation);
-
-                        if (bIsHairline)
-                            xRetval[1] = makeHairLinePrimitive(getStart(), getEnd(), aVector, aColor, mfDistance);
-                        else
-                            xRetval[1] = makeSolidLinePrimitive(
-                                aClipRegion, aTmpStart, aTmpEnd, aVector, aColor, fWidth, mfDistance);
-                    }
+                    double fRightWidth = getRightWidth();
+                    bool bRightHairline = lcl_UseHairline(fRightWidth, getStart(), getEnd(), rViewInformation);
+                    if (bRightHairline)
+                        fRightWidth = 0.0;
+
+                    // "inside" line
+
+                    if (bLeftHairline)
+                        xRetval[0] = makeHairLinePrimitive(
+                            getStart(), getEnd(), aVector, getRGBColorLeft(), 0.0);
+                    else
+                        xRetval[0] = makeSolidLinePrimitive(
+                            aClipRegion, aTmpStart, aTmpEnd, aVector, getRGBColorLeft(), fLeftWidth, -fLeftWidth/2.0);
+
+                    // "outside" line
+
+                    if (bRightHairline)
+                        xRetval[1] = makeHairLinePrimitive(
+                            getStart(), getEnd(), aVector, getRGBColorRight(), fLeftWidth+mfDistance);
+                    else
+                        xRetval[1] = makeSolidLinePrimitive(
+                            aClipRegion, aTmpStart, aTmpEnd, aVector, getRGBColorRight(), fRightWidth, mfDistance+fRightWidth/2.0);
                 }
                 else
                 {
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index afae83e..7086438 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -124,14 +124,15 @@ public:
     inline const Color& GetColorSecn() const { return maColorSecn; }
     inline const Color& GetColorGap() const { return maColorGap; }
     inline bool         UseGapColor() const { return mbUseGapColor; }
-    inline double       Prim() const { return mnPrim; }
-    inline double       Dist() const { return mnDist; }
-    inline double       Secn() const { return mnSecn; }
-    double Scale() const;
+    inline double       Prim() const { return mfPrim; }
+    inline double       Dist() const { return mfDist; }
+    inline double       Secn() const { return mfSecn; }
+    double PatternScale() const;
+    void SetPatternScale( double fScale );
     inline editeng::SvxBorderStyle Type() const { return mnType; }
 
     /** Returns the total width of this frame style. */
-    inline double       GetWidth() const { return mnPrim + mnDist + mnSecn; }
+    inline double       GetWidth() const { return mfPrim + mfDist + mfSecn; }
 
     /** Sets the frame style to invisible state. */
     void                Clear();
@@ -165,10 +166,10 @@ private:
     Color               maColorGap;
     bool                mbUseGapColor;
     RefMode             meRefMode;  /// Reference point handling for this frame border.
-    double              mnPrim;     /// Width of primary (single, left, or top) line.
-    double              mnDist;     /// Distance between primary and secondary line.
-    double              mnSecn;     /// Width of secondary (right or bottom) line.
-    double              mfScale;
+    double              mfPrim;     /// Width of primary (single, left, or top) line.
+    double              mfDist;     /// Distance between primary and secondary line.
+    double              mfSecn;     /// Width of secondary (right or bottom) line.
+    double mfPatternScale; /// Scale used for line pattern spacing.
     editeng::SvxBorderStyle      mnType;
 };
 
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 8268374..28383a9 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -1126,7 +1126,7 @@ void lclDrawDiagFrameBorders(
 
 Style::Style() :
     meRefMode(REFMODE_CENTERED),
-    mfScale(1.0),
+    mfPatternScale(1.0),
     mnType(table::BorderLineStyle::SOLID)
 {
     Clear();
@@ -1134,7 +1134,7 @@ Style::Style() :
 
 Style::Style( double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
     meRefMode(REFMODE_CENTERED),
-    mfScale(1.0),
+    mfPatternScale(1.0),
     mnType(nType)
 {
     Clear();
@@ -1144,7 +1144,7 @@ Style::Style( double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
 Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
               double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
     meRefMode(REFMODE_CENTERED),
-    mfScale(1.0),
+    mfPatternScale(1.0),
     mnType(nType)
 {
     Set( rColorPrim, rColorSecn, rColorGap, bUseGapColor, nP, nD, nS );
@@ -1152,21 +1152,26 @@ Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rCo
 
 Style::Style( const editeng::SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWidth ) :
     meRefMode(REFMODE_CENTERED),
-    mfScale(fScale)
+    mfPatternScale(fScale)
 {
     Set( rBorder, fScale, nMaxWidth );
 }
 
 Style::Style( const editeng::SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWidth ) :
     meRefMode(REFMODE_CENTERED),
-    mfScale(fScale)
+    mfPatternScale(fScale)
 {
     Set( pBorder, fScale, nMaxWidth );
 }
 
-double Style::Scale() const
+double Style::PatternScale() const
 {
-    return mfScale;
+    return mfPatternScale;
+}
+
+void Style::SetPatternScale( double fScale )
+{
+    mfPatternScale = fScale;
 }
 
 void Style::Clear()
@@ -1183,9 +1188,9 @@ void Style::Set( double nP, double nD, double nS )
         >0  0   >0      nP      0       0
         >0  >0  >0      nP      nD      nS
      */
-    mnPrim = rtl::math::round(nP ? nP : nS, 2);
-    mnDist = rtl::math::round((nP && nS) ? nD : 0, 2);
-    mnSecn = rtl::math::round((nP && nD) ? nS : 0, 2);
+    mfPrim = rtl::math::round(nP ? nP : nS, 2);
+    mfDist = rtl::math::round((nP && nS) ? nD : 0, 2);
+    mfSecn = rtl::math::round((nP && nD) ? nS : 0, 2);
 }
 
 void Style::Set( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS )
@@ -1219,29 +1224,29 @@ void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWid
         // Enlarge the style if distance is too small due to rounding losses.
         double nPixWidth = SCALEVALUE( nPrim + nDist + nSecn );
         if( nPixWidth > GetWidth() )
-            mnDist = nPixWidth - mnPrim - mnSecn;
+            mfDist = nPixWidth - mfPrim - mfSecn;
         // Shrink the style if it is too thick for the control.
         while( GetWidth() > nMaxWidth )
         {
             // First decrease space between lines.
-            if( mnDist )
-                --mnDist;
+            if( mfDist )
+                --mfDist;
             // Still too thick? Decrease the line widths.
             if( GetWidth() > nMaxWidth )
             {
-                if( rtl::math::approxEqual(mnPrim, 0.0) && rtl::math::approxEqual(mnPrim, mnSecn) )
+                if( rtl::math::approxEqual(mfPrim, 0.0) && rtl::math::approxEqual(mfPrim, mfSecn) )
                 {
                     // Both lines equal - decrease both to keep symmetry.
-                    --mnPrim;
-                    --mnSecn;
+                    --mfPrim;
+                    --mfSecn;
                 }
                 else
                 {
                     // Decrease each line for itself
-                    if( mnPrim )
-                        --mnPrim;
-                    if( (GetWidth() > nMaxWidth) && !rtl::math::approxEqual(mnSecn, 0.0) )
-                        --mnSecn;
+                    if( mfPrim )
+                        --mfPrim;
+                    if( (GetWidth() > nMaxWidth) && !rtl::math::approxEqual(mfSecn, 0.0) )
+                        --mfSecn;
                 }
             }
         }
@@ -1261,8 +1266,8 @@ void Style::Set( const SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWid
 
 Style& Style::MirrorSelf()
 {
-    if( mnSecn )
-        std::swap( mnPrim, mnSecn );
+    if( mfSecn )
+        std::swap( mfPrim, mfSecn );
     if( meRefMode != REFMODE_CENTERED )
         meRefMode = (meRefMode == REFMODE_BEGIN) ? REFMODE_END : REFMODE_BEGIN;
     return *this;
@@ -1429,7 +1434,7 @@ drawinglayer::primitive2d::Primitive2DSequence CreateClippedBorderPrimitives (
         rBorder.GetColorSecn().getBColor(),
         rBorder.GetColorPrim().getBColor(),
         rBorder.GetColorGap().getBColor(),
-        rBorder.UseGapColor(), rBorder.Type(), rBorder.Scale() );
+        rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale() );
 
     return aSequence;
 }
@@ -1457,7 +1462,7 @@ drawinglayer::primitive2d::Primitive2DSequence CreateBorderPrimitives(
         rBorder.GetColorSecn().getBColor(),
         rBorder.GetColorPrim().getBColor(),
         rBorder.GetColorGap().getBColor(),
-        rBorder.UseGapColor(), rBorder.Type(), rBorder.Scale() );
+        rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale() );
 
     return aSequence;
 }
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index e6b9a66..c2719ddb 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2451,9 +2451,6 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
     // #i16816# tagged pdf support
     SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev );
 
-    const SwFrm* pTmpFrm = &mrTabFrm;
-    const bool bVert = pTmpFrm->IsVertical();
-
     SwLineEntryMapConstIter aIter = maHoriLines.begin();
     bool bHori = true;
 
@@ -2471,17 +2468,6 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
         rDev.SetDrawMode( 0 );
     }
 
-    // set clip region:
-    rDev.Push( PUSH_CLIPREGION );
-    Size aSize( rRect.SSize() );
-    // Hack! Necessary, because the layout is not pixel aligned!
-    aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH;
-    rDev.SetClipRegion(Region(Rectangle(rRect.Pos(), aSize)));
-
-    // The following stuff is necessary to have the new table borders fit
-    // into a ::SwAlignRect adjusted world.
-    const SwTwips nTwipXCorr =  bVert ? 0 : std::max( 0L, nHalfPixelSzW - 2 );    // 1 < 2 < 3 ;-)
-    const SwTwips nTwipYCorr = !bVert ? 0 : std::max( 0L, nHalfPixelSzW - 2 );    // 1 < 2 < 3 ;-)
     const SwFrm* pUpper = mrTabFrm.GetUpper();
     SwRect aUpper( pUpper->Prt() );
     aUpper.Pos() += pUpper->Frm().Pos();
@@ -2593,25 +2579,6 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
             else
                 pTmpColor = pHCColor;
 
-            // The line sizes stored in the line style have to be adjusted as
-            // well.  This will guarantee that lines with the same twip size
-            // will have the same pixel size.
-            for ( int i = 0; i < 7; ++i )
-            {
-                sal_uInt16 nPrim = aStyles[ i ].Prim();
-                sal_uInt16 nDist = aStyles[ i ].Dist();
-                sal_uInt16 nSecn = aStyles[ i ].Secn();
-
-                if (nPrim > 0)
-                    nPrim = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) );
-                if (nDist > 0)
-                    nDist = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) );
-                if (nSecn > 0)
-                    nSecn = (sal_uInt16)( std::max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) );
-
-                aStyles[ i ].Set( nPrim, nDist, nSecn );
-            }
-
             // The (twip) positions will be adjusted to meet these requirements:
             // 1. The y coordinates are located in the middle of the pixel grid
             // 2. The x coordinated are located at the beginning of the pixel grid
@@ -2669,12 +2636,6 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
                 aPaintEnd.Y()   += static_cast<long>(offsetEnd   + 0.5);
             }
 
-            aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel
-            aPaintEnd.X()   -= nTwipXCorr;
-            aPaintStart.Y() -= nTwipYCorr;
-            aPaintEnd.Y()   -= nTwipYCorr;
-
-            // Here comes the painting stuff: Thank you, DR, great job!!!
             if (bHori)
             {
                 mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
@@ -2711,7 +2672,6 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
     }
 
     // restore output device:
-    rDev.Pop();
     rDev.SetDrawMode( nOldDrawMode );
 }
 
@@ -2835,13 +2795,17 @@ void calcOffsetForDoubleLine( SwLineEntryMap& rLines )
             for (size_t i = 0; itSet != itSetEnd; ++itSet, ++i)
             {
                 SwLineEntry aLine = *itSet;
-                aLine.mnOffset = static_cast<SwTwips>(aLine.maAttribute.Dist());
-                aLine.mbOffsetPerp = true;
-
-                if (i == 0)
-                    aLine.mbOffsetStart = true;
-                if (i == nEntryCount - 1)
-                    aLine.mbOffsetEnd = true;
+                if (aLine.maAttribute.Secn())
+                {
+                    // Apply offset only for double lines.
+                    aLine.mnOffset = static_cast<SwTwips>(aLine.maAttribute.Dist());
+                    aLine.mbOffsetPerp = true;
+
+                    if (i == 0)
+                        aLine.mbOffsetStart = true;
+                    if (i == nEntryCount - 1)
+                        aLine.mbOffsetEnd = true;
+                }
 
                 aNewSet.insert(aLine);
             }
@@ -2903,10 +2867,14 @@ void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
     const Fraction& rFracX = rMapMode.GetScaleX();
     const Fraction& rFracY = rMapMode.GetScaleY();
 
-    svx::frame::Style aL(rBoxItem.GetLeft(), rFracX);
-    svx::frame::Style aR(rBoxItem.GetRight(), rFracY);
-    svx::frame::Style aT(rBoxItem.GetTop(), rFracX);
-    svx::frame::Style aB(rBoxItem.GetBottom(), rFracY);
+    svx::frame::Style aL(rBoxItem.GetLeft());
+    aL.SetPatternScale(rFracY);
+    svx::frame::Style aR(rBoxItem.GetRight());
+    aR.SetPatternScale(rFracY);
+    svx::frame::Style aT(rBoxItem.GetTop());
+    aT.SetPatternScale(rFracX);
+    svx::frame::Style aB(rBoxItem.GetBottom());
+    aB.SetPatternScale(rFracX);
 
     aR.MirrorSelf();
     aB.MirrorSelf();
commit e1823627f35e4419880769fdd05acddbd0a9c25c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 17 19:41:07 2014 -0400

    fdo#76195: Set the border type to NONE to ensure it won't be drawn.
    
    We can no longer rely on the width being zero for no border condition.
    
    Change-Id: I02c5c825661b4a0aa4190306e8276bdfd8bff944
    (cherry picked from commit d2eb2c5a02718b83475bc718e117eb6255cbac98)
    Reviewed-on: https://gerrit.libreoffice.org/8636
    Tested-by: Michael Stahl <mstahl at redhat.com>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 5557547..e6b9a66 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -108,13 +108,6 @@ using ::drawinglayer::primitive2d::BorderLinePrimitive2D;
 using ::std::pair;
 using ::std::make_pair;
 
-//subsidiary lines enabled?
-#define IS_SUBS_TABLE \
-    (pGlobalShell->GetViewOptions()->IsTable() && \
-    !pGlobalShell->GetViewOptions()->IsPagePreview()&&\
-    !pGlobalShell->GetViewOptions()->IsReadonly()&&\
-    !pGlobalShell->GetViewOptions()->IsFormView() &&\
-     SwViewOption::IsTableBoundaries())
 //other subsidiary lines enabled?
 #define IS_SUBS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
         !pGlobalShell->GetViewOptions()->IsReadonly() && \
@@ -260,6 +253,27 @@ static sal_Bool bTableHack = sal_False;
 //To optimize the expensive RetouchColor determination
 Color aGlobalRetoucheColor;
 
+namespace {
+
+bool isTableBoundariesEnabled()
+{
+    if (!pGlobalShell->GetViewOptions()->IsTable())
+        return false;
+
+    if (pGlobalShell->GetViewOptions()->IsPagePreview())
+        return false;
+
+    if (pGlobalShell->GetViewOptions()->IsReadonly())
+        return false;
+
+    if (pGlobalShell->GetViewOptions()->IsFormView())
+        return false;
+
+    return SwViewOption::IsTableBoundaries();
+}
+
+}
+
 // Set borders alignment statics.
 // adjustment for 'small' twip-to-pixel relations:
 // For 'small' twip-to-pixel relations (less then 2:1)
@@ -2571,8 +2585,10 @@ void SwTabFrmPainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
             const Color* pTmpColor = 0;
             if (0 == aStyles[ 0 ].GetWidth())
             {
-                if (IS_SUBS_TABLE && pGlobalShell->GetWin())
+                if (isTableBoundariesEnabled() && pGlobalShell->GetWin())
                     aStyles[ 0 ].Set( rCol, rCol, rCol, false, 1, 0, 0 );
+                else
+                    aStyles[0].SetType(table::BorderLineStyle::NONE);
             }
             else
                 pTmpColor = pHCColor;
@@ -4320,12 +4336,8 @@ void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
                 PaintShadow( rRect, aRect, rAttrs );
             }
 
-            if (pViewOption->IsTableBoundaries())
-            {
-                // fdo#75118 Paint border lines only when it's enabled.
-                SwTabFrmPainter aHelper(*this);
-                aHelper.PaintLines(*pGlobalShell->GetOut(), rRect);
-            }
+            SwTabFrmPainter aHelper(*this);
+            aHelper.PaintLines(*pGlobalShell->GetOut(), rRect);
         }
         // <-- collapsing
 
@@ -6623,7 +6635,7 @@ void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
 
 void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
 {
-    if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS )
+    if ( IS_SUBS || isTableBoundariesEnabled() || IS_SUBS_SECTION || IS_SUBS_FLYS )
     {
         SwRect aRect( rRect );
         // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of
commit e6006b5c91c8f6852a1b8b1b7ed1c5e7b4975a68
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Mar 14 12:11:13 2014 +0100

    RTF import: 3 drawing-object fixes:
    
    This bring back the fdo#fdo42407 bugdoc to the state where it was around
    4.0.
    
    - fix dobxpage before dptxbx
    
    The problem was that dobxpage arrived first, set HoriOrientRelation to
    FRAME, then dptxbx tried to apply defaults, which overwrote the already
    set HoriOrientRelation. Fix this by only applying properties which are
    not set yet.
    
    (cherry picked from commit 7c53577f325e5260c538f9ca42cda54ca1a24b7a)
    
    - anchor drawing objects at-character by default
    
    (cherry picked from commit d05b67a7b9448c67c3a923ecb33dac74b52dd192)
    
    - fix ordering of old-style dhght in case of equal values
    
    Commit 1eaab77c718ffa254068ae6032862dfb5a03db67 (fdo#60722 import
    RTF_SHPZ, 2013-03-06) changed how we handle z-order, in case two shapes
    have the same value. Turns out for drawing-objects the order is the
    opposite in this situation.
    
    So fix this by adding a new mode, that keeps the original testcase happy
    without breaking older documents.
    
    (cherry picked from commit e4fe3610eb17c441217c80536f0acf4123abd683)
    
    Change-Id: Ib2d284cefc3c0dce40ac2e516ba260d6cd04ce43
    Reviewed-on: https://gerrit.libreoffice.org/8621
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/sw/qa/extras/rtfimport/data/do-dhgt-old.rtf b/sw/qa/extras/rtfimport/data/do-dhgt-old.rtf
new file mode 100644
index 0000000..07da38f
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/do-dhgt-old.rtf
@@ -0,0 +1,10 @@
+{\rtf1
+{\colortbl\red255\green255\blue255; \red0\green0\blue0; }
+{\*\do\dobxpage\dobypara\dodhgt8192\dptxbx\dptxbxmar0
+{\dptxbxtext\ltrpar\f4\fs20\cf1\vertalc\qc\ltrch a\par}
+\dpx8594\dpy3486\dpxsize1179\dpysize221\dplinehollow0}
+{\*\do\dobxpage\dobypara\dodhgt8192\dprect\dproundr\dpx9807\dpy3968\dpxsize1644\dpysize566\dplinecor255\dplinecog255\dplinecob255\dpfillbgcr0\dpfillbgcg0\dpfillbgcb0\dpfillpat1\dplinehollow0}
+{\*\do\dobxpage\dobypara\dodhgt8192\dptxbx\dptxbxmar0
+{\dptxbxtext\ltrpar\f2\fs20\cf0\vertalc\i\b\qc\ltrch b\par}
+\dpx9864\dpy4138\dpxsize1530\dpysize226\dplinehollow0}
+}
diff --git a/sw/qa/extras/rtfimport/data/dprect-anchor.rtf b/sw/qa/extras/rtfimport/data/dprect-anchor.rtf
new file mode 100644
index 0000000..ac5675e
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/dprect-anchor.rtf
@@ -0,0 +1,4 @@
+{\rtf1
+{\colortbl\red255\green255\blue255; \red0\green0\blue0; }
+{\*\do\dobxpage\dobypara\dodhgt8192\dprect\dproundr\dpx9807\dpy3968\dpxsize1644\dpysize566\dplinecor255\dplinecog255\dplinecob255\dpfillbgcr0\dpfillbgcg0\dpfillbgcb0\dpfillpat1\dplinehollow0}
+}
diff --git a/sw/qa/extras/rtfimport/data/dptxbx-relation.rtf b/sw/qa/extras/rtfimport/data/dptxbx-relation.rtf
new file mode 100644
index 0000000..82f0741
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/dptxbx-relation.rtf
@@ -0,0 +1,5 @@
+{\rtf1
+{\*\do\dobxpage\dobypara\dodhgt8192\dptxbx\dptxbxmar0
+{\dptxbxtext\ltrpar\f4\fs20\cf1\vertalc\qc\ltrch To:\par}
+\dpx941\dpy2114\dpxsize1349\dpysize221\dplinehollow0}
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index a8d8fd7..8d24829 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1007,6 +1007,23 @@ DECLARE_RTFIMPORT_TEST(testFdo60722, "fdo60722.rtf")
     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), getProperty<sal_uInt32>(xShape, "LineColor"));
 }
 
+DECLARE_RTFIMPORT_TEST(testDoDhgtOld, "do-dhgt-old.rtf")
+{
+    // The file contains 3 shapes which have the same dhgt (z-order).
+    // Test that the order is 1) a 2) black rectangle 3) b, and not something else
+    uno::Reference<text::XText> xShape(getShape(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xShape, "ZOrder"));
+    CPPUNIT_ASSERT_EQUAL(OUString("a"), xShape->getString());
+
+    xShape.set(getShape(2), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty<sal_Int32>(xShape, "ZOrder"));
+    CPPUNIT_ASSERT_EQUAL(COL_BLACK, getProperty<sal_uInt32>(xShape, "FillColor"));
+
+    xShape.set(getShape(3), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getProperty<sal_Int32>(xShape, "ZOrder"));
+    CPPUNIT_ASSERT_EQUAL(OUString("b"), xShape->getString());
+}
+
 DECLARE_RTFIMPORT_TEST(testFdo61909, "fdo61909.rtf")
 {
     uno::Reference<text::XTextRange> xTextRange = getRun(getParagraph(1), 1);
@@ -1576,6 +1593,18 @@ DECLARE_RTFIMPORT_TEST(testFdo69289, "fdo69289.rtf")
     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), "TableColumnSeparators").getLength());
 }
 
+DECLARE_RTFIMPORT_TEST(testDptxbxRelation, "dptxbx-relation.rtf")
+{
+    // This was FRAME, not PAGE_FRAME, even if dobxpage is in the document.
+    CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(getShape(1), "HoriOrientRelation"));
+}
+
+DECLARE_RTFIMPORT_TEST(testDprectAnchor, "dprect-anchor.rtf")
+{
+    // This was at-page, which is not something Word supports, so clearly an import error.
+    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty<text::TextContentAnchorType>(getShape(1), "AnchorType"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/GraphicHelpers.cxx b/writerfilter/source/dmapper/GraphicHelpers.cxx
index d2e64d2..98afc62 100644
--- a/writerfilter/source/dmapper/GraphicHelpers.cxx
+++ b/writerfilter/source/dmapper/GraphicHelpers.cxx
@@ -268,14 +268,18 @@ void GraphicZOrderHelper::addItem( uno::Reference< beans::XPropertySet > props,
 // The relativeHeight value in .docx is an arbitrary number, where only the relative ordering matters.
 // But in Writer, the z-order is index in 0..(numitems-1) range, so whenever a new item needs to be
 // added in the proper z-order, it is necessary to find the proper index.
-sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight )
+sal_Int32 GraphicZOrderHelper::findZOrder( sal_Int32 relativeHeight, bool bOldStyle )
 {
     Items::const_iterator it = items.begin();
     while( it != items.end())
     {
         // std::map is iterated sorted by key
-        // if there is an item that has the same z-order, we belong under it
-        if( it->first >= relativeHeight )
+
+        // Old-style ordering differs in what should happen when there is already an item with the same z-order:
+        // we belong under it in case of new-style, but we belong below it in case of old-style.
+        bool bCond = bOldStyle ? (it->first > relativeHeight) : (it->first >= relativeHeight);
+
+        if( bCond )
             break; // this is the first one higher, we belong right before it
         else
             ++it;
diff --git a/writerfilter/source/dmapper/GraphicHelpers.hxx b/writerfilter/source/dmapper/GraphicHelpers.hxx
index e3e4be6..e977404 100644
--- a/writerfilter/source/dmapper/GraphicHelpers.hxx
+++ b/writerfilter/source/dmapper/GraphicHelpers.hxx
@@ -74,7 +74,7 @@ class WRITERFILTER_DLLPRIVATE GraphicZOrderHelper
 {
 public:
     void addItem( uno::Reference< beans::XPropertySet > props, sal_Int32 relativeHeight );
-    sal_Int32 findZOrder( sal_Int32 relativeHeight );
+    sal_Int32 findZOrder( sal_Int32 relativeHeight, bool bOldStyle = false );
 private:
     typedef std::map< sal_Int32, uno::Reference< beans::XPropertySet > > Items;
     Items items;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list