[Libreoffice-commits] core.git: Branch 'private/jmux/libreoffice-4-1+fixes' - 39 commits - desktop/source framework/uiconfig helpcontent2 offapi/com officecfg/registry sc/inc sc/source sc/uiconfig sd/uiconfig svx/source sw/inc sw/qa sw/source sw/uiconfig translations unoxml/source vcl/CustomTarget_kde4_moc.mk vcl/source vcl/unx xmloff/source

Jan-Marek Glogowski glogow at fbihome.de
Mon Mar 3 03:34:28 PST 2014


Rebased ref, commits from common ancestor:
commit c00aeced3c69f28ff02edee2813d58bd8c7f5c43
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Feb 27 08:54:57 2014 +0000

    fdo#45935: try hard to paint a frame for menus
    
    Current Oxygen theme doesn't draw frames for menus, but uses shaped
    and "colored" background images. This workaround paints the window
    and menu frame for menus. Any frame seems to be better then no frame
    at all.
    
    Change-Id: I4d553ea58cac2729826f8395cb2597fa200187b6
    (cherry picked from commit e72849cd435cc50a744dcbcfb422f5600dd0cce9)

diff --git a/vcl/unx/kde4/KDEData.cxx b/vcl/unx/kde4/KDEData.cxx
index 196f186..ccbbd99 100644
--- a/vcl/unx/kde4/KDEData.cxx
+++ b/vcl/unx/kde4/KDEData.cxx
@@ -17,10 +17,18 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#define Region QtXRegion
+
+#include <QStyle>
+#include <kapplication.h>
+
+#undef Region
+
 #include "KDEData.hxx"
 
 #include "KDEXLib.hxx"
 
+
 KDEData::~KDEData()
 {
 }
@@ -39,6 +47,15 @@ void KDEData::initNWF()
     pSVData->maNWFData.mbDockingAreaSeparateTB = true;
     // no borders for menu, theming does that
     pSVData->maNWFData.mbFlatMenu = true;
+
+    // Styled menus need additional space
+    QStyle *style = kapp->style();
+    pSVData->maNWFData.mnMenuFormatBorderX =
+       style->pixelMetric( QStyle::PM_MenuPanelWidth ) +
+       style->pixelMetric( QStyle::PM_MenuHMargin );
+    pSVData->maNWFData.mnMenuFormatBorderY =
+       style->pixelMetric( QStyle::PM_MenuPanelWidth ) +
+       style->pixelMetric( QStyle::PM_MenuVMargin );
 }
 
 void KDEData::deInitNWF()
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 690179a..6e20ef1 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -80,7 +80,7 @@ QRect region2QRect( const Rectangle& rControlRegion )
 }
 
 KDESalGraphics::KDESalGraphics() :
-    m_image(0)
+    m_image(NULL)
 {
 }
 
@@ -132,13 +132,7 @@ sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart
     if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) )
         return true;
 
-    if ( (type == CTRL_PROGRESS)    && (part == PART_ENTIRE_CONTROL) ) return true;
-
-    return false;
-
-    if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true;
-    if ( (type == CTRL_TAB_PANE) && (part == PART_ENTIRE_CONTROL) ) return true;
-    // no CTRL_TAB_BODY for KDE
+    if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true;
 
     return false;
 }
@@ -365,8 +359,10 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
         {
             QStyleOptionMenuItem option;
             draw( QStyle::PE_PanelMenu, &option, m_image, vclStateValue2StateFlag( nControlState, value ));
+            // Try hard to get any frame!
             QStyleOptionFrame frame;
             draw( QStyle::PE_FrameMenu, &frame, m_image, vclStateValue2StateFlag( nControlState, value ));
+            draw( QStyle::PE_FrameWindow, &frame, m_image, vclStateValue2StateFlag( nControlState, value ));
             lastPopupRect = widgetRect;
         }
         else
commit 02d9df47f1c1ee9bc813da6d0c4a0a06dab99c4f
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 fdb8fdd..690179a 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;
 
@@ -171,21 +173,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 ) )
@@ -558,7 +545,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)
@@ -861,7 +848,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 f320d24..990fad7 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -59,7 +59,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
     connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated()));
@@ -82,6 +82,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()
@@ -405,6 +408,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 f265d05fbbe968f095f29a59739d831e2396ed90
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Feb 26 18:19:11 2014 +0000

    KDE4: sleep in yield for native file picker
    
    As it seems to be the only way to poll the clipboard, reintroduce
    
     m_pApplication->clipboard()->setProperty(
        "useEventLoopWhenWaiting", true );
    
    To prevent crashes, disable event processing in the Qt thread while
    the dialog is open.
    
    Instead this applies the same workaround as the Windows backend to
    sleep a ms, which keeps the FP dialogs more usable, but feels like
    a horrible workaround.
    
    This is still slower then running processEvent in Yield but still
    much better then the current situation.
    
    (cherry picked from commit 380f3b4b6cbbe8e82b58ddf55e95c5005307b51f)
    
    Conflicts:
    
    	vcl/unx/kde4/KDE4FilePicker.cxx
    	vcl/unx/kde4/KDE4FilePicker.hxx
    
    Change-Id: I10c422f1c0d7448d4a7ad28e57a32ed2cb42f48f

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 1712a72..cd52c67 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -37,6 +37,7 @@
 
 #include "KDE4FilePicker.hxx"
 #include "FPServiceInfo.hxx"
+#include "KDEXLib.hxx"
 
 /* ********* Hack, but needed because of conflicting types... */
 #define Region QtXRegion
@@ -102,9 +103,10 @@ QString toQString(const OUString& s)
 // KDE4FilePicker
 //////////////////////////////////////////////////////////////////////////
 
-KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
+KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>&, KDEXLib *xlib )
     : KDE4FilePicker_Base(_helperMutex)
     , _resMgr( ResMgr::CreateResMgr("fps_office") )
+    , _mXLib( xlib )
 {
     _extraControls = new QWidget();
     _layout = new QGridLayout(_extraControls);
@@ -237,8 +239,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
     _dialog->filterWidget()->setEditable(false);
 
     // We're entering a nested loop.
-    // Release the yield mutex to prevent deadlocks.
+    // Prevent yield calls, which would crash LO.
+
+    _mXLib->freezeYield( true );
     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 8b7b53e..508fea8 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -40,6 +40,7 @@
 class KFileDialog;
 class QWidget;
 class QLayout;
+class KDEXLib;
 
 class ResMgr;
 
@@ -80,8 +81,10 @@ protected:
     //layout for extra custom controls
     QLayout* _layout;
 
+    KDEXLib* _mXLib;
+
 public:
-    KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& );
+    KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&, KDEXLib* );
     virtual ~KDE4FilePicker();
 
     // XFilePickerNotifier
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 38b3307..f320d24 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -58,7 +58,8 @@
 KDEXLib::KDEXLib() :
     SalXLib(),  m_bStartupDone(false), m_pApplication(0),
     m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
-    eventLoopType( LibreOfficeEventLoop )
+    eventLoopType( LibreOfficeEventLoop ),
+    m_bYieldFrozen( false )
 {
     // the timers created here means they belong to the main thread
     connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated()));
@@ -213,6 +214,7 @@ 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
@@ -272,6 +274,17 @@ 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()) {
@@ -389,7 +402,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
         SalYieldMutexReleaser aReleaser;
         return Q_EMIT createFilePickerSignal( xMSF );
     }
-    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
+    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) );
 }
 
 #include "KDEXLib.moc"
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index d9bd4d6..d07b9f6 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -52,6 +52,7 @@ class KDEXLib : public QObject, public SalXLib
         QTimer timeoutTimer;
         QTimer userEventTimer;
         enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
+        bool m_bYieldFrozen;
 
     private:
         void setupEventLoop();
@@ -84,6 +85,7 @@ 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 b9b56fd56825d7a7e55d7f85d6b76a2c38ac2b3d
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 c11deb60cabfa8e7ee511b94abb0e19601b42fe6)

diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index cf72dcd..fdb8fdd 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -837,12 +837,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 065a2c3356ca629a63f74d86dabd2cf8a054f1a2
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 7b083444942b1d5890b51a1f4a8560ba4e411e46)

diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 67d7a4d..38b3307 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
@@ -193,12 +187,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 )
@@ -229,21 +217,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
@@ -254,15 +227,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 a9ef5b02a27c4d4d2f01a1e8c741d2ce7693d459
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Mon Jun 10 15:26:40 2013 +0200

    fix and simplify getting files from the KDE4 file dialog
    
    - Fix multiple selection handling.
    - The "double click selection KDE4 bug" does not exist (anymore?) as far
      as I can tell.
    - Apparently it's not true that multiselect needs the first item in the list
      to be the directory.
    - KFileDialog can already give full URLs.
    
    (cherry picked from commit 03f666103d80f7a0c79150dae2367079b80e50a6)
    
    Conflicts:
    
    	vcl/unx/kde4/KDE4FilePicker.cxx
    
    Change-Id: I5bb651902fb6c1d75af40b78bf32c79b004b7358

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index c36b9cc..1712a72 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -310,48 +310,11 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getFiles()
         return Q_EMIT getFilesSignal();
     }
 
-    QStringList rawFiles = _dialog->selectedFiles();
-    QStringList files;
-
-    // Workaround for the double click selection KDE4 bug
-    // kde file picker returns the file and directories for selectedFiles()
-    // when a file is double clicked
-    // make a true list of files
-    const QString dir = KUrl(rawFiles[0]).directory();
-
-    bool singleFile = true;
-    if (rawFiles.size() > 1)
-    {
-        singleFile = false;
-        //for multi file sequences, oo expects the first param to be the directory
-        //can't treat all cases like multi file because in some instances (inserting image)
-        //oo WANTS only one entry in the final list
-        files.append(dir);
-    }
-
-    for (sal_uInt16 i = 0; i < rawFiles.size(); ++i)
-    {
-        // if the raw file is not the base directory (see above kde bug)
-        // we add the file to list of avail files
-        if ((dir + "/") != ( rawFiles[i]))
-        {
-            QString filename = KUrl(rawFiles[i]).fileName();
-
-            if (singleFile)
-                filename.prepend(dir + "/");
-            files.append(filename);
-        }
-    }
-
-    // add all files and leading directory to outgoing OO sequence
-    uno::Sequence< OUString > seq(files.size());
-    for (int i = 0; i < files.size(); ++i)
-    {
-        OUString aFile(toOUString(files[i])), aURL;
-        osl_getFileURLFromSystemPath(aFile.pData, &aURL.pData );
-        seq[i] = aURL;
-    }
-
+    KUrl::List urls = _dialog->selectedUrls();
+    uno::Sequence< OUString > seq( urls.size());
+    int i = 0;
+    foreach( const KUrl& url, urls )
+        seq[ i++ ]= toOUString( url.url());
     return seq;
 }
 
commit 794a202119d240f62be05cc12a82298fc3a02c57
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Feb 19 08:45:05 2014 +0000

    Fix minimal VCL menu item height with icons
    
    Don't reset the calculated minimal menu item height to the icon
    height, if the minimal height is already larger then the icon height.
    
    Change-Id: Ifcd6c750352c4d3f754a693df7254a4654a8afe6
    (cherry picked from commit 56bea42176e5f0b850da0bab410dda560fc89255)

diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 2d39189..89871c7 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2385,7 +2385,8 @@ Size Menu::ImplCalcSize( Window* pWin )
     const StyleSettings& rSettings = pWin->GetSettings().GetStyleSettings();
     if ( rSettings.GetUseImagesInMenus() )
     {
-        nMinMenuItemHeight = 16;
+        if ( 16 > nMinMenuItemHeight )
+            nMinMenuItemHeight = 16;
         for ( size_t i = pItemList->size(); i; )
         {
             MenuItemData* pData = pItemList->GetDataFromPos( --i );
commit 453663accb41f06d9acdf94155a11c3ff9b52235
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Dec 22 17:42:20 2013 +0100

    Export MailMerge cancel functionality via UNO.
    
    If you start a mail merge jobs via UNO, there is no way to cancel
    it. But the functionality is already implemented and used by the
    LO internal mail merge dialogs.
    
    This patch adds an optional XCancellable interface to the MailMerge
    service and implements it in the SwXMailMerge class.
    
    As the XJob::execute function already uses the SolarMutex to
    prevent parallel runs, XCancellable::cancel can be implemented by
    storing the SwNewDBMgr in the private variable m_pMgr, protected by
    a mutex.
    
    The bCancel member has to be converted from a bitfield value to a
    real boolean, because otherwise all bitfield values would have to
    be protected by a mutex. Bitfield assignments aren't atomic as you
    always have to replace at least a byte.
    
    Reviewed-on: https://gerrit.libreoffice.org/7190
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit 1a12777f46954045afbe8fffa6dd199b4b338762)
    
    Conflicts:
    
    	sw/inc/dbmgr.hxx
    	sw/source/ui/inc/unomailmerge.hxx
    
    Change-Id: I007cc23fdf04ccfca7d3cd6180b0e17e99f53061

diff --git a/offapi/com/sun/star/text/MailMerge.idl b/offapi/com/sun/star/text/MailMerge.idl
index e6545e7..820e273 100644
--- a/offapi/com/sun/star/text/MailMerge.idl
+++ b/offapi/com/sun/star/text/MailMerge.idl
@@ -26,6 +26,7 @@
 #include <com/sun/star/beans/XPropertySet.idl>
 #include <com/sun/star/text/XMailMergeBroadcaster.idl>
 #include <com/sun/star/sdb/DataAccessDescriptor.idl>
+#include <com/sun/star/util/XCancellable.idl>
 
 
  module com {  module sun {  module star {  module text {
@@ -51,6 +52,12 @@ published service MailMerge
      */
     interface com::sun::star::task::XJob;
 
+    /** interface to cancel the current mail merge job.
+
+        @since LibreOffice 4.3
+     */
+    [optional] interface com::sun::star::util::XCancellable;
+
     /** interface to access the services properties.
      */
     interface com::sun::star::beans::XPropertySet;
diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index d696cee..9290533 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -191,10 +191,9 @@ friend class SwConnectionDisposedListener_Impl;
     String              sEMailAddrFld;      ///< Mailing: Column name of email address.
     String              sSubject;           ///< Mailing: Subject
     String              sAttached;          ///< Mailing: Attached Files.
+    sal_Bool            bCancel;            ///< Mail merge canceled.
     sal_Bool            bInitDBFields : 1;
     sal_Bool            bSingleJobs : 1;    ///< Printing job when called from Basic.
-    sal_Bool            bCancel : 1;        ///< Mail merge save canceled.
-
     sal_Bool            bInMerge    : 1;    ///< merge process active
     sal_Bool            bMergeSilent : 1;   ///< suppress display of dialogs/boxes (used when called over API)
     sal_Bool            bMergeLock : 1;     /**< prevent update of database fields while document is
@@ -234,6 +233,7 @@ public:
     /// Merging of data records into fields.
     sal_Bool            MergeNew( const SwMergeDescriptor& rMergeDesc );
     sal_Bool            Merge(SwWrtShell* pSh);
+    void                MergeCancel();
 
     /// Initialize data fields that lack name of database.
     inline sal_Bool     IsInitDBFields() const  { return bInitDBFields; }
diff --git a/sw/source/ui/dbui/dbmgr.cxx b/sw/source/ui/dbui/dbmgr.cxx
index 70a8532..36bbfaf 100644
--- a/sw/source/ui/dbui/dbmgr.cxx
+++ b/sw/source/ui/dbui/dbmgr.cxx
@@ -1355,10 +1355,15 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
     return bNoError;
 }
 
+void SwNewDBMgr::MergeCancel()
+{
+    bCancel = sal_True;
+}
+
 IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
 {
     pButton->GetParent()->Hide();
-    bCancel = sal_True;
+    MergeCancel();
     return 0;
 }
 IMPL_LINK_INLINE_END( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
diff --git a/sw/source/ui/inc/unomailmerge.hxx b/sw/source/ui/inc/unomailmerge.hxx
index 3a0e4aa..491b517 100644
--- a/sw/source/ui/inc/unomailmerge.hxx
+++ b/sw/source/ui/inc/unomailmerge.hxx
@@ -21,7 +21,7 @@
 #define _UNOMAILMERGE_HXX_
 
 #include <functional>
-#include <cppuhelper/implbase5.hxx> // WeakImplHelper4
+#include <cppuhelper/implbase6.hxx>
 #include <cppuhelper/interfacecontainer.hxx>    // OMultiTypeInterfaceContainerHelperVar
 #include <unotools/configitem.hxx>  // !! needed for OMultiTypeInterfaceContainerHelperVar !!
 
@@ -32,6 +32,7 @@
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
 #include <com/sun/star/text/XMailMergeBroadcaster.hpp>
+#include <com/sun/star/util/XCancellable.hpp>
 #include <svl/itemprop.hxx>
 #include <sfx2/objsh.hxx>
 
@@ -78,16 +79,22 @@ typedef cppu::OMultiTypeInterfaceContainerHelperVar
 
 ////////////////////////////////////////////////////////////
 
+class SwNewDBMgr;
+class MailMergeExecuteFinalizer;
+
 class SwXMailMerge :
-    public cppu::WeakImplHelper5
+    public cppu::WeakImplHelper6
     <
         com::sun::star::task::XJob,
+        com::sun::star::util::XCancellable,
         com::sun::star::beans::XPropertySet,
         com::sun::star::text::XMailMergeBroadcaster,
         com::sun::star::lang::XComponent,
         com::sun::star::lang::XServiceInfo
     >
 {
+    friend class MailMergeExecuteFinalizer;
+
     cppu::OInterfaceContainerHelper     aEvtListeners;
     cppu::OInterfaceContainerHelper     aMergeListeners;
     OPropertyListenerContainerHelper    aPropListeners;
@@ -135,6 +142,7 @@ class SwXMailMerge :
     com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aSaveFilterData;
 
     sal_Bool        bDisposing;
+    SwNewDBMgr     *m_pMgr;
 
     void    launchEvent( const com::sun::star::beans::PropertyChangeEvent &rEvt ) const;
 
@@ -152,6 +160,9 @@ public:
     // XJob
     virtual ::com::sun::star::uno::Any SAL_CALL execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
 
+    // XCancellable
+    virtual void SAL_CALL cancel() throw (com::sun::star::uno::RuntimeException);
+
     // XPropertySet
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw (::com::sun::star::uno::RuntimeException);
     virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
diff --git a/sw/source/ui/uno/unomailmerge.cxx b/sw/source/ui/uno/unomailmerge.cxx
index 1a67f4e..9bfab27 100644
--- a/sw/source/ui/uno/unomailmerge.cxx
+++ b/sw/source/ui/uno/unomailmerge.cxx
@@ -404,7 +404,8 @@ SwXMailMerge::SwXMailMerge() :
     bSendAsHTML(sal_False),
     bSendAsAttachment(sal_False),
     bSaveAsSingleFile(sal_False),
-    bDisposing(sal_False)
+    bDisposing(sal_False),
+    m_pMgr(0)
 {
     // create empty document
     // like in: SwModule::InsertEnv (appenv.cxx)
@@ -433,11 +434,31 @@ SwXMailMerge::~SwXMailMerge()
     }
 }
 
+// Guarantee object consistence in case of an exception
+class MailMergeExecuteFinalizer {
+public:
+    MailMergeExecuteFinalizer(SwXMailMerge *mailmerge) {
+        OSL_ENSURE( mailmerge, "mailmerge object missing" );
+        this->m_aMailMerge = mailmerge;
+    }
+    ~MailMergeExecuteFinalizer() {
+        osl::MutexGuard pMgrGuard( GetMailMergeMutex() );
+        m_aMailMerge->m_pMgr = 0;
+    }
+
+private:
+    // Disallow copy
+    MailMergeExecuteFinalizer(const MailMergeExecuteFinalizer&) {}
+
+    SwXMailMerge *m_aMailMerge;
+};
+
 uno::Any SAL_CALL SwXMailMerge::execute(
         const uno::Sequence< beans::NamedValue >& rArguments )
     throw (IllegalArgumentException, Exception, RuntimeException)
 {
     SolarMutexGuard aGuard;
+    MailMergeExecuteFinalizer aFinalizer(this);
 
     //
     // get property values to be used
@@ -678,6 +699,7 @@ uno::Any SAL_CALL SwXMailMerge::execute(
     //force layout creation
     rSh.CalcLayout();
     OSL_ENSURE( pMgr, "database manager missing" );
+    m_pMgr = pMgr;
 
     SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor );
 
@@ -822,6 +844,15 @@ uno::Any SAL_CALL SwXMailMerge::execute(
     return makeAny( sal_True );
 }
 
+void SAL_CALL SwXMailMerge::cancel() throw (com::sun::star::uno::RuntimeException)
+{
+    // Cancel may be called from a second thread, so this protects from m_pMgr
+    /// cleanup in the execute function.
+    osl::MutexGuard pMgrGuard( GetMailMergeMutex() );
+    if (m_pMgr)
+        m_pMgr->MergeCancel();
+}
+
 void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const
 {
     cppu::OInterfaceIteratorHelper aIt( ((SwXMailMerge *) this)->aMergeListeners );
commit 132ca96d11b87a906c698fc163ffc4ab09f3ecde
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Dec 26 23:15:24 2013 +0100

    Copy mail merge source instead of loading
    
    Currently a mail merge loads the styles from the source document
    and also loads the original source per mail merge dataset.
    
    The new code is based on the MergeDocuments function and swaps the
    loading with an internal document copy to improve mail merge
    throughtput.
    
    For a mail merge with 99 datasets and a two pages document,
    callgrind shows an improvement from routhly 44 to 31 billion
    inclusive instructions for the single SwXMailMerge::execute call.
    
    Reviewed-on: https://gerrit.libreoffice.org/7433
    Tested-by: Michael Stahl <mstahl at redhat.com>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit 8d11531565d746dd6a7938c4f3536ad34698092d)
    
    Conflicts:
    
    	sw/source/ui/dbui/dbmgr.cxx
    
    Change-Id: I6929ba371f81c3ea1f26ea3a25e7751bc53256e3

diff --git a/sw/source/ui/dbui/dbmgr.cxx b/sw/source/ui/dbui/dbmgr.cxx
index d94838c..70a8532 100644
--- a/sw/source/ui/dbui/dbmgr.cxx
+++ b/sw/source/ui/dbui/dbmgr.cxx
@@ -870,11 +870,8 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
         pSfxDispatcher->Execute( pSourceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD);
         if( !pSourceDocSh->IsModified() )
         {
-            SfxMedium* pOrig = pSourceDocSh->GetMedium();
-            String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ));
-            const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter(
-                                                    sSourceDocumentURL, ::aEmptyStr );
-            const SfxFilter* pStoreToFilter = pSfxFlt;
+            const SfxFilter* pStoreToFilter = SwIoSystem::GetFileFilter(
+                pSourceDocSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), ::aEmptyStr );
             SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
             const String* pStoreToFilterOptions = 0;
 
@@ -923,14 +920,7 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                 pTargetView->AttrChangedNotify( &pTargetView->GetWrtShell() );
                 pTargetShell = pTargetView->GetWrtShellPtr();
                 //copy the styles from the source to the target document
-                SwgReaderOption aOpt;
-                aOpt.SetTxtFmts( sal_True );
-                aOpt.SetFrmFmts( sal_True );
-                aOpt.SetPageDescs( sal_True );
-                aOpt.SetNumRules( sal_True );
-                aOpt.SetMerge( sal_False );
-                pTargetView->GetDocShell()->LoadStylesFromFile(
-                        sSourceDocumentURL, aOpt, sal_True );
+                pTargetView->GetDocShell()->_LoadStyles( *pSourceDocSh, sal_True );
                 //determine the page style and number used at the start of the source document
                 pSourceShell->SttEndDoc(sal_True);
                 nStartingPageNo = pSourceShell->GetVirtPageNum();
@@ -1027,13 +1017,19 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                         for (sal_uInt16 i = 0; i < 10; i++)
                             Application::Reschedule();
 
-                        // Create and save new document
                         // The SfxObjectShell will be closed explicitly later but it is more safe to use SfxObjectShellLock here
-                        SfxObjectShellLock xWorkDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL ));
-                        SfxMedium* pWorkMed = new SfxMedium( sSourceDocumentURL, STREAM_STD_READ );
-                        pWorkMed->SetFilter( pSfxFlt );
+                        SfxObjectShellLock xWorkDocSh;
+                        // copy the source document
+                        if( 1 == nDocNo && (bAsSingleFile || rMergeDescriptor.bCreateSingleFile) )
+                        {
+                            uno::Reference< util::XCloneable > xClone( pSourceDocSh->GetModel(), uno::UNO_QUERY);
+                            uno::Reference< lang::XUnoTunnel > xWorkDocShell( xClone->createClone(), uno::UNO_QUERY);
+                            SwXTextDocument* pWorkModel = reinterpret_cast<SwXTextDocument*>(xWorkDocShell->getSomething(SwXTextDocument::getUnoTunnelId()));
+                            xWorkDocSh = pWorkModel->GetDocShell();
+                        }
+                        else
+                            xWorkDocSh = pSourceDocSh->GetDoc()->CreateCopy( true );
 
-                        if (xWorkDocSh->DoLoad(pWorkMed))
                         {
                             //create a view frame for the document
                             SfxViewFrame* pWorkFrame = SfxViewFrame::LoadHiddenDocument( *xWorkDocSh, 0 );
commit 22142e34eefcadebbc4daaa93aba7c29342b7796
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Feb 6 16:05:37 2014 +0000

    fdo#72187 Implement KDE4 picker notifications
    
    This notifies the XFilePickerListener of filter changes and file
    selection changes.
    
    (cherry picked from commit a8d102c2406b8c027afb32d61271e0a2c301f133)
    
    Conflicts:
    
    	vcl/unx/kde4/KDE4FilePicker.cxx
    
    Change-Id: I749c5f7420f020a3a2fbb764acb5c45d40972cf1

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 33d6ac7..c36b9cc 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -167,6 +167,10 @@ KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
 
     // Destructor proxy
     connect( this, SIGNAL( cleanupProxySignal() ), this, SLOT( cleanupProxy() ), Qt::BlockingQueuedConnection );
+
+    // XFilePickerListener notifications
+    connect( _dialog, SIGNAL( filterChanged(const QString&) ), this, SLOT( filterChanged(const QString&) ));
+    connect( _dialog, SIGNAL( selectionChanged() ), this, SLOT( selectionChanged() ));
 }
 
 KDE4FilePicker::~KDE4FilePicker()
@@ -777,6 +781,23 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSupportedServiceNames()
     return FilePicker_getSupportedServiceNames();
 }
 
+void KDE4FilePicker::filterChanged(const QString &)
+{
+    FilePickerEvent aEvent;
+    aEvent.ElementId = LISTBOX_FILTER;
+    OSL_TRACE( "filter changed" );
+    if (m_xListener.is())
+        m_xListener->controlStateChanged( aEvent );
+}
+
+void KDE4FilePicker::selectionChanged()
+{
+    FilePickerEvent aEvent;
+    OSL_TRACE( "file selection changed" );
+    if (m_xListener.is())
+        m_xListener->fileSelectionChanged( aEvent );
+}
+
 #include "KDE4FilePicker.moc"
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDE4FilePicker.hxx b/vcl/unx/kde4/KDE4FilePicker.hxx
index af2564a..8b7b53e 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -224,6 +224,10 @@ private:
 private Q_SLOTS:
     void cleanupProxy();
 
+    // emit XFilePickerListener controlStateChanged event
+    void filterChanged(const QString &filter);
+    // emit XFilePickerListener fileSelectionChanged event
+    void selectionChanged();
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 24fb4fd3b05a999dd9ac5a12bf0d2f503d4c83d6
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Feb 6 15:32:42 2014 +0000

    Simplify control item switch statements
    
    Just check the dynamic_cast result to verify check boxes.
    
    Change-Id: I5f370e337e12719eb7ef0dd3512a0f46c76a981e
    (cherry picked from commit 24e8b90d8a2864cfb60d3a5046be39410efe5c51)

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index ecb4219..33d6ac7 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -447,86 +447,39 @@ void SAL_CALL KDE4FilePicker::setValue( sal_Int16 controlId, sal_Int16 nControlA
         return Q_EMIT setValueSignal( controlId, nControlAction, value );
     }
 
-    QWidget* widget = _customWidgets[controlId];
-
-    if (widget)
-    {
-        switch (controlId)
-        {
-            case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION:
-            // we actually rely on KFileDialog and ignore CHECKBOX_AUTOEXTENSION completely,
-            // otherwise the checkbox would be duplicated
-                break;
-            case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD:
-            case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS:
-            case ExtendedFilePickerElementIds::CHECKBOX_READONLY:
-            case ExtendedFilePickerElementIds::CHECKBOX_LINK:
-            case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
-            case ExtendedFilePickerElementIds::CHECKBOX_SELECTION:
-            {
-                QCheckBox* cb = dynamic_cast<QCheckBox*>(widget);
-                cb->setChecked(value.get<bool>());
-                break;
-            }
-            case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR:
-                break;
-        }
+    if (_customWidgets.contains( controlId )) {
+        QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
+        if (cb)
+            cb->setChecked(value.get<bool>());
     }
+    else
+        OSL_TRACE( "set label on unknown control %d", controlId );
 }
 
 uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 nControlAction )
     throw( uno::RuntimeException )
 {
+    if (CHECKBOX_AUTOEXTENSION == controlId)
+        // We ignore this one and rely on KFileDialog to provide the function.
+        // Always return false, to pretend we do not support this, otherwise
+        // LO core would try to be smart and cut the extension in some places,
+        // interfering with KFileDialog's handling of it. KFileDialog also
+        // saves the value of the setting, so LO core is not needed for that either.
+        return uno::Any( false );
+
     if( qApp->thread() != QThread::currentThread() ) {
         SalYieldMutexReleaser release;
         return Q_EMIT getValueSignal( controlId, nControlAction );
     }
 
     uno::Any res(false);
-
-    QWidget* widget = _customWidgets[controlId];
-
-    if (widget)
-    {
-        switch (controlId)
-        {
-            case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION:
-            // We ignore this one and rely on KFileDialog to provide the function.
-            // Always return false, to pretend we do not support this, otherwise
-            // LO core would try to be smart and cut the extension in some places,
-            // interfering with KFileDialog's handling of it. KFileDialog also
-            // saves the value of the setting, so LO core is not needed for that either.
-                res = uno::Any( false );
-                break;
-            case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD:
-            case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS:
-            case ExtendedFilePickerElementIds::CHECKBOX_READONLY:
-            case ExtendedFilePickerElementIds::CHECKBOX_LINK:
-            case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
-            case ExtendedFilePickerElementIds::CHECKBOX_SELECTION:
-            {
-                QCheckBox* cb = dynamic_cast<QCheckBox*>(widget);
-                res = uno::Any(cb->isChecked());
-                break;
-            }
-            case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR:
-                break;
-        }
+    if (_customWidgets.contains( controlId )) {
+        QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
+        if (cb)
+            res = uno::Any(cb->isChecked());
     }
+    else
+        OSL_TRACE( "get value on unknown control %d", controlId );
 
     return res;
 }
@@ -539,12 +492,10 @@ void SAL_CALL KDE4FilePicker::enableControl( sal_Int16 controlId, sal_Bool enabl
         return Q_EMIT enableControlSignal( controlId, enable );
     }
 
-    QWidget* widget = _customWidgets[controlId];
-
-    if (widget)
-    {
-        widget->setEnabled(enable);
-    }
+    if (_customWidgets.contains( controlId ))
+        _customWidgets.value( controlId )->setEnabled( enable );
+    else
+        OSL_TRACE("enable unknown control %d", controlId );
 }
 
 void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &label )
@@ -555,35 +506,13 @@ void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &lab
         return Q_EMIT setLabelSignal( controlId, label );
     }
 
-    QWidget* widget = _customWidgets[controlId];
-
-    if (widget)
-    {
-        switch (controlId)
-        {
-            case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION: // ignored
-            case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD:
-            case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS:
-            case ExtendedFilePickerElementIds::CHECKBOX_READONLY:
-            case ExtendedFilePickerElementIds::CHECKBOX_LINK:
-            case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
-            case ExtendedFilePickerElementIds::CHECKBOX_SELECTION:
-            {
-                QCheckBox* cb = dynamic_cast<QCheckBox*>(widget);
-                cb->setText(toQString(label));
-                break;
-            }
-            case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR:
-                break;
-        }
+    if (_customWidgets.contains( controlId )) {
+        QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
+        if (cb)
+            cb->setText( toQString(label) );
     }
+    else
+        OSL_TRACE( "set label on unknown control %d", controlId );
 }
 
 OUString SAL_CALL KDE4FilePicker::getLabel(sal_Int16 controlId)
@@ -594,36 +523,15 @@ OUString SAL_CALL KDE4FilePicker::getLabel(sal_Int16 controlId)
         return Q_EMIT getLabelSignal( controlId );
     }
 
-    QWidget* widget = _customWidgets[controlId];
     QString label;
-
-    if (widget)
-    {
-        switch (controlId)
-        {
-            case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION: // ignored
-            case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD:
-            case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS:
-            case ExtendedFilePickerElementIds::CHECKBOX_READONLY:
-            case ExtendedFilePickerElementIds::CHECKBOX_LINK:
-            case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
-            case ExtendedFilePickerElementIds::CHECKBOX_SELECTION:
-            {
-                QCheckBox* cb = dynamic_cast<QCheckBox*>(widget);
-                label = cb->text();
-                break;
-            }
-            case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
-            case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL:
-            case ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR:
-                break;
-        }
+    if (_customWidgets.contains( controlId )) {
+        QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
+        if (cb)
+            label = cb->text();
     }
+    else
+        OSL_TRACE( "get label on unknown control %d", controlId );
+
     return toOUString(label);
 }
 
@@ -634,55 +542,55 @@ void KDE4FilePicker::addCustomControl(sal_Int16 controlId)
 
     switch (controlId)
     {
-        case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION:
+        case CHECKBOX_AUTOEXTENSION:
             resId = STR_SVT_FILEPICKER_AUTO_EXTENSION;
             break;
-        case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD:
+        case CHECKBOX_PASSWORD:
             resId = STR_SVT_FILEPICKER_PASSWORD;
             break;
-        case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS:
+        case CHECKBOX_FILTEROPTIONS:
             resId = STR_SVT_FILEPICKER_FILTER_OPTIONS;
             break;
-        case ExtendedFilePickerElementIds::CHECKBOX_READONLY:
+        case CHECKBOX_READONLY:
             resId = STR_SVT_FILEPICKER_READONLY;
             break;
-        case ExtendedFilePickerElementIds::CHECKBOX_LINK:
+        case CHECKBOX_LINK:
             resId = STR_SVT_FILEPICKER_INSERT_AS_LINK;
             break;
-        case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
+        case CHECKBOX_PREVIEW:
             resId = STR_SVT_FILEPICKER_SHOW_PREVIEW;
             break;
-        case ExtendedFilePickerElementIds::CHECKBOX_SELECTION:
+        case CHECKBOX_SELECTION:
             resId = STR_SVT_FILEPICKER_SELECTION;
             break;
-        case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
+        case PUSHBUTTON_PLAY:
             resId = STR_SVT_FILEPICKER_PLAY;
             break;
-        case ExtendedFilePickerElementIds::LISTBOX_VERSION:
+        case LISTBOX_VERSION:
             resId = STR_SVT_FILEPICKER_VERSION;
             break;
-        case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
+        case LISTBOX_TEMPLATE:
             resId = STR_SVT_FILEPICKER_TEMPLATES;
             break;
-        case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
+        case LISTBOX_IMAGE_TEMPLATE:
             resId = STR_SVT_FILEPICKER_IMAGE_TEMPLATE;
             break;
-        case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL:
-        case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL:
-        case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL:
-        case ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR:
+        case LISTBOX_VERSION_LABEL:
+        case LISTBOX_TEMPLATE_LABEL:
+        case LISTBOX_IMAGE_TEMPLATE_LABEL:
+        case LISTBOX_FILTER_SELECTOR:
             break;
     }
 
     switch (controlId)
     {
-        case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION:
-        case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD:
-        case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS:
-        case ExtendedFilePickerElementIds::CHECKBOX_READONLY:
-        case ExtendedFilePickerElementIds::CHECKBOX_LINK:
-        case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
-        case ExtendedFilePickerElementIds::CHECKBOX_SELECTION:
+        case CHECKBOX_AUTOEXTENSION:
+        case CHECKBOX_PASSWORD:
+        case CHECKBOX_FILTEROPTIONS:
+        case CHECKBOX_READONLY:
+        case CHECKBOX_LINK:
+        case CHECKBOX_PREVIEW:
+        case CHECKBOX_SELECTION:
         {
             QString label;
 
@@ -694,21 +602,22 @@ void KDE4FilePicker::addCustomControl(sal_Int16 controlId)
             }
 
             widget = new QCheckBox(label, _extraControls);
+
             // the checkbox is created even for CHECKBOX_AUTOEXTENSION to simplify
             // code, but the checkbox is hidden and ignored
-            if( controlId == ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION )
+            if( controlId == CHECKBOX_AUTOEXTENSION )
                 widget->hide();
 
             break;
         }
-        case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
-        case ExtendedFilePickerElementIds::LISTBOX_VERSION:
-        case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
-        case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
-        case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL:
-        case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL:
-        case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL:
-        case ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR:
+        case PUSHBUTTON_PLAY:
+        case LISTBOX_VERSION:
+        case LISTBOX_TEMPLATE:
+        case LISTBOX_IMAGE_TEMPLATE:
+        case LISTBOX_VERSION_LABEL:
+        case LISTBOX_TEMPLATE_LABEL:
+        case LISTBOX_IMAGE_TEMPLATE_LABEL:
+        case LISTBOX_FILTER_SELECTOR:
             break;
     }
 
@@ -765,53 +674,53 @@ void SAL_CALL KDE4FilePicker::initialize( const uno::Sequence<uno::Any> &args )
 
         case FILESAVE_AUTOEXTENSION:
             operationMode = KFileDialog::Saving;
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
+            addCustomControl( CHECKBOX_AUTOEXTENSION );
             break;
 
         case FILESAVE_AUTOEXTENSION_PASSWORD:
         {
             operationMode = KFileDialog::Saving;
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
+            addCustomControl( CHECKBOX_PASSWORD );
             break;
         }
         case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
         {
             operationMode = KFileDialog::Saving;
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD );
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS );
+            addCustomControl( CHECKBOX_AUTOEXTENSION );
+            addCustomControl( CHECKBOX_PASSWORD );
+            addCustomControl( CHECKBOX_FILTEROPTIONS );
             break;
         }
         case FILESAVE_AUTOEXTENSION_SELECTION:
             operationMode = KFileDialog::Saving;
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_SELECTION );
+            addCustomControl( CHECKBOX_AUTOEXTENSION );
+            addCustomControl( CHECKBOX_SELECTION );
             break;
 
         case FILESAVE_AUTOEXTENSION_TEMPLATE:
             operationMode = KFileDialog::Saving;
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION );
-            addCustomControl( ExtendedFilePickerElementIds::LISTBOX_TEMPLATE );
+            addCustomControl( CHECKBOX_AUTOEXTENSION );
+            addCustomControl( LISTBOX_TEMPLATE );
             break;
 
         case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_LINK );
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
-            addCustomControl( ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE );
+            addCustomControl( CHECKBOX_LINK );
+            addCustomControl( CHECKBOX_PREVIEW );
+            addCustomControl( LISTBOX_IMAGE_TEMPLATE );
             break;
 
         case FILEOPEN_PLAY:
-            addCustomControl( ExtendedFilePickerElementIds::PUSHBUTTON_PLAY );
+            addCustomControl( PUSHBUTTON_PLAY );
             break;
 
         case FILEOPEN_READONLY_VERSION:
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_READONLY );
-            addCustomControl( ExtendedFilePickerElementIds::LISTBOX_VERSION );
+            addCustomControl( CHECKBOX_READONLY );
+            addCustomControl( LISTBOX_VERSION );
             break;
 
         case FILEOPEN_LINK_PREVIEW:
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_LINK );
-            addCustomControl( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW );
+            addCustomControl( CHECKBOX_LINK );
+            addCustomControl( CHECKBOX_PREVIEW );
             break;
 
         default:
commit a65c9a018a0c56f3db1ac5fc06e33f31a3b4a629
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Dec 24 19:47:30 2013 +0100

    Rename some mail merge variables
    
    Fixes the variable name typo pSourrceDocSh and renames bLoop to
    bNoError to represent the variables function.
    
    Reviewed-on: https://gerrit.libreoffice.org/7431
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit 5da974369d01760b336de34e68c03d7268d2d330)
    
    Conflicts:
    
    	sw/source/ui/dbui/dbmgr.cxx
    
    Change-Id: Iba688ed0fb40c0c3947da1b21beb00c67a10ff09

diff --git a/sw/source/ui/dbui/dbmgr.cxx b/sw/source/ui/dbui/dbmgr.cxx
index 186789a..d94838c 100644
--- a/sw/source/ui/dbui/dbmgr.cxx
+++ b/sw/source/ui/dbui/dbmgr.cxx
@@ -826,7 +826,7 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
 {
     //check if the doc is synchronized and contains at least one linked section
     bool bSynchronizedDoc = pSourceShell->IsLabelDoc() && pSourceShell->GetSectionFmtCount() > 1;
-    sal_Bool bLoop = sal_True;
+    sal_Bool bNoError = sal_True;
     bool bEMail = rMergeDescriptor.nMergeType == DBMGR_MERGE_MAILING;
     const bool bAsSingleFile = rMergeDescriptor.nMergeType == DBMGR_MERGE_SINGLE_FILE;
 
@@ -864,19 +864,20 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
             aCol >>= xColumnProp;
         }
 
+        // Try saving the source document
         SfxDispatcher* pSfxDispatcher = pSourceShell->GetView().GetViewFrame()->GetDispatcher();
-        SwDocShell* pSourrceDocSh = pSourceShell->GetView().GetDocShell();
-        pSfxDispatcher->Execute( pSourrceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD);
-        // has document been saved successfully?
-        if( !pSourrceDocSh->IsModified() )
+        SwDocShell* pSourceDocSh = pSourceShell->GetView().GetDocShell();
+        pSfxDispatcher->Execute( pSourceDocSh->HasName() ? SID_SAVEDOC : SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD);
+        if( !pSourceDocSh->IsModified() )
         {
-            SfxMedium* pOrig = pSourceShell->GetView().GetDocShell()->GetMedium();
+            SfxMedium* pOrig = pSourceDocSh->GetMedium();
             String sSourceDocumentURL(pOrig->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ));
             const SfxFilter* pSfxFlt = SwIoSystem::GetFileFilter(
                                                     sSourceDocumentURL, ::aEmptyStr );
             const SfxFilter* pStoreToFilter = pSfxFlt;
             SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
             const String* pStoreToFilterOptions = 0;
+
             // if a save_to filter is set then use it - otherwise use the default
             if( bEMail && !rMergeDescriptor.bSendAsAttachment )
             {
@@ -955,14 +956,14 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                 aPrtMonDlg.Show();
 
             // Progress, to prohibit KeyInputs
-            SfxProgress aProgress(pSourrceDocSh, ::aEmptyStr, 1);
+            SfxProgress aProgress(pSourceDocSh, ::aEmptyStr, 1);
 
             // lock all dispatchers
-            SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
+            SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst(pSourceDocSh);
             while (pViewFrm)
             {
                 pViewFrm->GetDispatcher()->Lock(sal_True);
-                pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
+                pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourceDocSh);
             }
             sal_uLong nDocNo = 1;
 
@@ -1010,7 +1011,7 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                     if( !aTempFile->IsValid() )
                     {
                         ErrorHandler::HandleError( ERRCODE_IO_NOTSUPPORTED );
-                        bLoop = sal_False;
+                        bNoError = sal_False;
                         bCancel = sal_True;
                     }
                     else
@@ -1148,7 +1149,7 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                                     // error message ??
                                     ErrorHandler::HandleError( xWorkDocSh->GetError() );
                                     bCancel = sal_True;
-                                    bLoop = sal_False;
+                                    bNoError = sal_False;
                                 }
                                 if( bEMail )
                                 {
@@ -1284,7 +1285,7 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                     {
                         // error message ??
                         ErrorHandler::HandleError( xTargetDocShell->GetError() );
-                        bLoop = sal_False;
+                        bNoError = sal_False;
                     }
                 }
                 else if( pTargetView ) // must be available!
@@ -1338,11 +1339,11 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
                 SWUnoHelper::UCB_DeleteFile( *aFileIter );
 
             // unlock all dispatchers
-            pViewFrm = SfxViewFrame::GetFirst(pSourrceDocSh);
+            pViewFrm = SfxViewFrame::GetFirst(pSourceDocSh);
             while (pViewFrm)
             {
                 pViewFrm->GetDispatcher()->Lock(sal_False);
-                pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourrceDocSh);
+                pViewFrm = SfxViewFrame::GetNext(*pViewFrm, pSourceDocSh);
             }
 
             SW_MOD()->SetView(&pSourceShell->GetView());
@@ -1353,10 +1354,9 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
     {
         xMailDispatcher->stop();
         xMailDispatcher->shutdown();
-
     }
 
-    return bLoop;
+    return bNoError;
 }
 
 IMPL_LINK_INLINE_START( SwNewDBMgr, PrtCancelHdl, Button *, pButton )
commit d44d3d3474c72967ef4e4e8bd617c05a7ab9258b
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jan 10 23:36:52 2014 +0100

    Drop unused nMergeType from SwNewDBMgr
    
    All code uses the nMergeType from the SwMergeDescriptor. Actually
    there is just code setting the nMergeType in the SwNewDBMgr but
    none reading or comparing it.
    
    I don't know if the removed assignments actually should work on a
    SwMergeDescriptor object, so some parts of mail merge may already
    have been broken.
    
    Reviewed-on: https://gerrit.libreoffice.org/7432
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit e3e6ad0e5c36531d8002c24c5e41a99ff597c095)
    
    Conflicts:
    
    	sw/inc/dbmgr.hxx
    
    Change-Id: Ic8c52e6171f122d3837d9f2de81053e30ac8f5b7

diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index 978f779..d696cee 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -191,7 +191,6 @@ friend class SwConnectionDisposedListener_Impl;
     String              sEMailAddrFld;      ///< Mailing: Column name of email address.
     String              sSubject;           ///< Mailing: Subject
     String              sAttached;          ///< Mailing: Attached Files.
-    sal_uInt16          nMergeType;
     sal_Bool            bInitDBFields : 1;
     sal_Bool            bSingleJobs : 1;    ///< Printing job when called from Basic.
     sal_Bool            bCancel : 1;        ///< Mail merge save canceled.
@@ -225,10 +224,6 @@ public:
     SwNewDBMgr();
     ~SwNewDBMgr();
 
-    /// Current merge type. Cf. DBMgrOptions-enum.
-    inline sal_uInt16   GetMergeType() const            { return nMergeType; }
-    inline void     SetMergeType( sal_uInt16 nTyp )     { nMergeType = nTyp; }
-
     /// MailMergeEvent source
     const SwXMailMerge *    GetMailMergeEvtSrc() const  { return pMergeEvtSrc; }
     void SetMailMergeEvtSrc( const SwXMailMerge *pSrc ) { pMergeEvtSrc = pSrc; }
diff --git a/sw/source/ui/dbui/dbmgr.cxx b/sw/source/ui/dbui/dbmgr.cxx
index 3272fd2..186789a 100644
--- a/sw/source/ui/dbui/dbmgr.cxx
+++ b/sw/source/ui/dbui/dbmgr.cxx
@@ -315,8 +315,6 @@ static sal_Bool lcl_GetColumnCnt(SwDSParam* pParam,
  --------------------------------------------------------------------*/
 sal_Bool SwNewDBMgr::MergeNew(const SwMergeDescriptor& rMergeDesc )
 {
-    SetMergeType( rMergeDesc.nMergeType );
-
     OSL_ENSURE(!bInMerge && !pImpl->pMergeData, "merge already activated!");
 
     SwDBData aData;
@@ -708,7 +706,6 @@ sal_Bool SwNewDBMgr::GetColumnNames(ListBox* pListBox,
     Description: CTOR
  --------------------------------------------------------------------*/
 SwNewDBMgr::SwNewDBMgr() :
-            nMergeType(DBMGR_INSERT),
             bInitDBFields(sal_False),
             bInMerge(sal_False),
             bMergeSilent(sal_False),
@@ -1350,8 +1347,6 @@ sal_Bool SwNewDBMgr::MergeMailFiles(SwWrtShell* pSourceShell,
 
             SW_MOD()->SetView(&pSourceShell->GetView());
         }
-
-        nMergeType = DBMGR_INSERT;
     }
 
     if(bEMail)
diff --git a/sw/source/ui/dbui/mmoutputpage.cxx b/sw/source/ui/dbui/mmoutputpage.cxx
index cf3d9b0..f6be127 100644
--- a/sw/source/ui/dbui/mmoutputpage.cxx
+++ b/sw/source/ui/dbui/mmoutputpage.cxx
@@ -910,7 +910,6 @@ IMPL_LINK_NOARG(SwMailMergeOutputPage, PrintHdl_Impl)
     sPages += OUString(" - ");
     sPages += OUString::valueOf(  rEndInfo.nEndPageInTarget );
 
-    SwWrtShell& rSh = pTargetView->GetWrtShell();
     pTargetView->SetMailMergeConfigItem(&rConfigItem, 0, sal_False);
     if(m_pTempPrinter)
     {
@@ -923,7 +922,6 @@ IMPL_LINK_NOARG(SwMailMergeOutputPage, PrintHdl_Impl)
 
     SfxObjectShell* pObjSh = pTargetView->GetViewFrame()->GetObjectShell();
     SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), pObjSh));
-    rSh.GetNewDBMgr()->SetMergeType( DBMGR_MERGE_DOCUMENTS );
     SfxBoolItem aMergeSilent(SID_SILENT, sal_False);
     m_pWizard->enableButtons(WZB_CANCEL, sal_False);
 
diff --git a/sw/source/ui/uiview/view2.cxx b/sw/source/ui/uiview/view2.cxx
index 744428c..17fdfa3 100644
--- a/sw/source/ui/uiview/view2.cxx
+++ b/sw/source/ui/uiview/view2.cxx
@@ -1058,7 +1058,6 @@ void SwView::Execute(SfxRequest &rReq)
                     rSh.EnterStdMode(); // Wechsel in Textshell erzwingen; ist fuer
                                         // das Mischen von DB-Feldern notwendig.
                     AttrChangedNotify( &rSh );
-                    pNewDBMgr->SetMergeType( DBMGR_MERGE );
 
                     Sequence<PropertyValue> aProperties(3);
                     PropertyValue* pValues = aProperties.getArray();
@@ -2384,8 +2383,6 @@ void SwView::GenerateFormLetter(sal_Bool bUseCurrentDocument)
 
         if (pNewDBMgr)
         {
-            pNewDBMgr->SetMergeType( DBMGR_MERGE );
-
             Sequence<PropertyValue> aProperties(3);
             PropertyValue* pValues = aProperties.getArray();
             pValues[0].Name = "DataSourceName";
commit 4042f219bdd2bb2e34bb41400708ea1de33d7e05
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Dec 22 17:37:28 2013 +0100

    Cleanup SwXMailMerge constructor.
    
    Move all fixed initializers into constructor definition.
    
    Reviewed-on: https://gerrit.libreoffice.org/7189
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit a5504e49dba07f7217ad3c0980d8c0f21f9f646c)
    
    Conflicts:
    
    	sw/source/ui/uno/unomailmerge.cxx
    
    Change-Id: I7317deae43abf6a9e865c66969cb39a4b69de826

diff --git a/helpcontent2 b/helpcontent2
index 1acc4c2..2328f3f 160000
--- a/helpcontent2
+++ b/helpcontent2
@@ -1 +1 @@
-Subproject commit 1acc4c2f499813c5b4b88830b8fb111e89d84098
+Subproject commit 2328f3f8efa6622c742b6e5b826376b08cd22d46
diff --git a/sw/source/ui/inc/unomailmerge.hxx b/sw/source/ui/inc/unomailmerge.hxx
index f6ec22f..3a0e4aa 100644
--- a/sw/source/ui/inc/unomailmerge.hxx
+++ b/sw/source/ui/inc/unomailmerge.hxx
@@ -115,7 +115,6 @@ class SwXMailMerge :
     sal_Bool        bSinglePrintJobs;
     sal_Bool        bFileNameFromColumn;
 
-
     OUString                                         sInServerPassword;
     OUString                                         sOutServerPassword;
     OUString                                         sSubject;
@@ -135,11 +134,8 @@ class SwXMailMerge :
     OUString                                         sSaveFilterOptions;
     com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aSaveFilterData;
 
-
-
     sal_Bool        bDisposing;
 
-
     void    launchEvent( const com::sun::star::beans::PropertyChangeEvent &rEvt ) const;
 
     // disallow use of copy-constructor and assignment-operator for now
diff --git a/sw/source/ui/uno/unomailmerge.cxx b/sw/source/ui/uno/unomailmerge.cxx
index 2f3e4ec..1a67f4e 100644
--- a/sw/source/ui/uno/unomailmerge.cxx
+++ b/sw/source/ui/uno/unomailmerge.cxx
@@ -396,29 +396,24 @@ SwXMailMerge::SwXMailMerge() :
     aMergeListeners ( GetMailMergeMutex() ),
     aPropListeners  ( GetMailMergeMutex() ),
     pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_MAILMERGE ) ),
+    nDataCommandType(sdb::CommandType::TABLE),
+    nOutputType(MailMergeType::PRINTER),
+    bEscapeProcessing(sal_True),     //!! allow to process properties like "Filter", "Order", ...
+    bSinglePrintJobs(sal_False),
+    bFileNameFromColumn(sal_False),
     bSendAsHTML(sal_False),
     bSendAsAttachment(sal_False),
-    bSaveAsSingleFile(sal_False)
-
+    bSaveAsSingleFile(sal_False),
+    bDisposing(sal_False)
 {
     // create empty document
     // like in: SwModule::InsertEnv (appenv.cxx)
-    SwDocShell *pDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD );
-    xDocSh = pDocShell;
+    xDocSh = new SwDocShell( SFX_CREATE_MODE_STANDARD );
     xDocSh->DoInitNew( 0 );
     SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 );
     SwView *pView = (SwView*) pFrame->GetViewShell();
-    pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird.
-
-    xModel = pDocShell->GetModel();
-
-    nDataCommandType    = sdb::CommandType::TABLE;
-    nOutputType         = MailMergeType::PRINTER;
-    bEscapeProcessing   = sal_True;     //!! allow to process properties like "Filter", "Order", ...
-    bSinglePrintJobs    = sal_False;
-    bFileNameFromColumn = sal_False;
-
-    bDisposing = sal_False;
+    pView->AttrChangedNotify( &pView->GetWrtShell() ); //So that SelectShell is called.
+    xModel = xDocSh->GetModel();
 }
 
 SwXMailMerge::~SwXMailMerge()
diff --git a/translations b/translations
index 2d162ea..f3f0426 160000
--- a/translations
+++ b/translations
@@ -1 +1 @@
-Subproject commit 2d162eaae8875c3fc36fca0bf075c5796145ab56
+Subproject commit f3f04265562dcd40990cccdd83170c8afffef4ab
commit 68702a890086a792e137ab6e1a016eca7ef69002
Author: Ulrich Kitzinger <ulkitz at hotmail.de>
Date:   Mon Jan 13 11:13:52 2014 +0100

    Let the list of bookmarks in the 'Edit bookmarks' dialog be resizable
    
    Change-Id: I09279f4d35238e6ab2d7b3e27e711dfe7fd74211
    Reviewed-on: https://gerrit.libreoffice.org/7399
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 2f2d9e3799d041381565ac1ef6e7a8c8a065871b)

diff --git a/sw/uiconfig/swriter/ui/insertbookmark.ui b/sw/uiconfig/swriter/ui/insertbookmark.ui
index 6bfbfc7..da54449 100644
--- a/sw/uiconfig/swriter/ui/insertbookmark.ui
+++ b/sw/uiconfig/swriter/ui/insertbookmark.ui
@@ -74,7 +74,7 @@
               <property name="can_focus">True</property>
           </object>
           <packing>
-            <property name="expand">False</property>
+            <property name="expand">True</property>
             <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
commit 3a709ee1fbac2ec51e3cc3e0e6bc164b67e21aeb
Author: Maxim Monastirsky <momonasmon at gmail.com>
Date:   Tue Jan 7 13:03:14 2014 +0200

    fdo#72521 fdo#73103 Fix editable combo-boxes behavior under KDE4
    
    Change-Id: I92a781a1e0f0adcb779155f8c477595e0dd762b1
    Reviewed-on: https://gerrit.libreoffice.org/7287
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    Tested-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit a62a80ac6cc0e337f4ff6d862bccc13c720d41ac)

diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 9caeae9..cf72dcd 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -779,7 +779,11 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
                     break;
                 }
                 case PART_BUTTON_DOWN:
-                    //the entire control can be used as the "down" button
+                    contentRect = kapp->style()->subControlRect(
+                        QStyle::CC_ComboBox, &cbo, QStyle::SC_ComboBoxArrow );
+
+                    contentRect.translate( boundingRect.left(), boundingRect.top() );
+
                     retVal = true;
                     break;
                 case PART_SUB_EDIT:
commit 805484bb94beec9ab336719f20c1dd70d31c69f2
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Jan 9 12:32:59 2014 +0100

    librdf_Repository: make older compilers happy
    
    Change-Id: Ide4df8f621f810b20be811db06d46edd5a9dc5f8
    (cherry picked from commit d3aad81268298c05163136e2e953e1dfe0728d9e)

diff --git a/unoxml/source/rdf/librdf_repository.cxx b/unoxml/source/rdf/librdf_repository.cxx
index 9687ad2..2fdae8a 100644
--- a/unoxml/source/rdf/librdf_repository.cxx
+++ b/unoxml/source/rdf/librdf_repository.cxx
@@ -2128,7 +2128,9 @@ librdf_uri* librdf_TypeConverter::mkURI_Lock( librdf_world* i_pWorld,
 librdf_TypeConverter::extractResource_NoLock(
     const uno::Reference< rdf::XResource > & i_xResource) const
 {
-    if (!i_xResource.is()) return 0;
+    if (!i_xResource.is()) {
+        return ::boost::shared_ptr<Resource>();
+    }
     uno::Reference< rdf::XBlankNode > xBlankNode(i_xResource, uno::UNO_QUERY);
     if (xBlankNode.is()) {
         const OString label(
@@ -2181,7 +2183,9 @@ librdf_node* librdf_TypeConverter::mkResource_Lock( librdf_world* i_pWorld,
 librdf_TypeConverter::extractNode_NoLock(
     const uno::Reference< rdf::XNode > & i_xNode) const
 {
-    if (!i_xNode.is()) return 0;
+    if (!i_xNode.is()) {
+        return ::boost::shared_ptr<Node>();
+    }
     uno::Reference< rdf::XResource > xResource(i_xNode, uno::UNO_QUERY);
     if (xResource.is()) {
         return extractResource_NoLock(xResource);
@@ -2189,7 +2193,9 @@ librdf_TypeConverter::extractNode_NoLock(
     uno::Reference< rdf::XLiteral> xLiteral(i_xNode, uno::UNO_QUERY);
     OSL_ENSURE(xLiteral.is(),
         "mkNode: someone invented a new rdf.XNode and did not tell me");
-    if (!xLiteral.is()) return 0;
+    if (!xLiteral.is()) {
+        return ::boost::shared_ptr<Node>();
+    }
     const OString val(
         OUStringToOString(xLiteral->getValue(),
         RTL_TEXTENCODING_UTF8) );
commit 4aac305041e3dabb94920c6e7618fcd8b059df0e
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Jan 9 00:10:02 2014 +0100

    librdf_Repository: fix missing mutex lock in various destructors
    
    Change-Id: I5756ab6ff6de0b2532bef9866063f361e330a009
    (cherry picked from commit 62fd1aa382c75feaa72f8aa09af4d3fc0b387dcc)

diff --git a/unoxml/source/rdf/librdf_repository.cxx b/unoxml/source/rdf/librdf_repository.cxx
index dd9c5fb..9687ad2 100644
--- a/unoxml/source/rdf/librdf_repository.cxx
+++ b/unoxml/source/rdf/librdf_repository.cxx
@@ -477,7 +477,13 @@ public:
         , m_pStream(i_pStream)
     { };
 
-    virtual ~librdf_GraphResult() {}
+    virtual ~librdf_GraphResult()
+    {
+        ::osl::MutexGuard g(m_rMutex); // lock mutex when destroying members
+        const_cast<boost::shared_ptr<librdf_stream>& >(m_pStream).reset();
+        const_cast<boost::shared_ptr<librdf_node>& >(m_pContext).reset();
+        const_cast<boost::shared_ptr<librdf_query>& >(m_pQuery).reset();
+    }
 
     // ::com::sun::star::container::XEnumeration:
     virtual ::sal_Bool SAL_CALL hasMoreElements()
@@ -584,7 +590,13 @@ public:
         , m_BindingNames(i_rBindingNames)
     { };
 
-    virtual ~librdf_QuerySelectResult() {}
+    virtual ~librdf_QuerySelectResult()
+    {
+        ::osl::MutexGuard g(m_rMutex); // lock mutex when destroying members
+        const_cast<boost::shared_ptr<librdf_query_results>& >(m_pQueryResult)
+            .reset();
+        const_cast<boost::shared_ptr<librdf_query>& >(m_pQuery).reset();
+    }
 
     // ::com::sun::star::container::XEnumeration:
     virtual ::sal_Bool SAL_CALL hasMoreElements()
@@ -864,6 +876,8 @@ librdf_Repository::librdf_Repository(
 
 librdf_Repository::~librdf_Repository()
 {
+    ::osl::MutexGuard g(m_aMutex);
+
     // must destroy these before world!
     m_pModel.reset();
     m_pStorage.reset();
@@ -872,7 +886,6 @@ librdf_Repository::~librdf_Repository()
     //   (via raptor_sax2_finish) call xmlCleanupParser, which will
     //   free libxml2's globals! ARRRGH!!! => never call librdf_free_world
 #if 0
-    ::osl::MutexGuard g(m_aMutex);
     if (!--m_NumInstances) {
         m_pWorld.reset();
     }
commit 1ab5208a57659ea355720064b25572d218791478
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Jan 8 23:43:03 2014 +0100

    fdo#72928: fix deadlocks in librdf_Repository
    
    Refactor to do all calls on parameters before locking the mutex.
    This requires splitting up some librdf_TypeConverter methods into an
    extract function and a make function, with an intermediate
    representation between.
    Also rename some internal functions to make it clear which are called
    with Lock and which with NoLock.
    
    (cherry picked from commit 7db6b2f7968d8063b12312737136f09cb7549805)
    
    Conflicts:
    	unoxml/source/rdf/librdf_repository.cxx
    
    Change-Id: Iddc42461d95351785578ef6a80fbf5d056356c16

diff --git a/unoxml/source/rdf/librdf_repository.cxx b/unoxml/source/rdf/librdf_repository.cxx
index 477b592..dd9c5fb 100644
--- a/unoxml/source/rdf/librdf_repository.cxx
+++ b/unoxml/source/rdf/librdf_repository.cxx
@@ -30,6 +30,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/shared_array.hpp>
 #include <boost/bind.hpp>
+#include <boost/optional.hpp>
 
 #include <libxslt/security.h>
 
@@ -95,7 +96,7 @@ const char s_nsOOo  [] = "http://openoffice.org/2004/office/rdfa/";
 
 ////////////////////////////////////////////////////////////////////////////
 
-//FIXME: this approach is not ideal. can we use blind nodes instead?
+//FIXME: this approach is not ideal. can we use blank nodes instead?
 bool isInternalContext(librdf_node *i_pNode) throw ()
 {
     OSL_ENSURE(i_pNode, "isInternalContext: context null");
@@ -178,6 +179,53 @@ static void safe_librdf_free_uri(librdf_uri *const uri)
 class librdf_TypeConverter
 {
 public:
+
+    // some wrapper classes to temporarily hold values of UNO XNodes
+    struct Node
+    {
+        virtual ~Node() {}
+    };
+    struct Resource : public Node { };
+    struct URI : public Resource
+    {
+        OString const value;
+        URI(OString const& i_rValue)
+            : value(i_rValue)
+        { }
+    };
+    struct BlankNode : public Resource
+    {
+        OString const value;
+        BlankNode(OString const& i_rValue)
+            : value(i_rValue)
+        { }
+    };
+    struct Literal : public Node
+    {
+        OString const value;
+        OString const language;
+        ::boost::optional<OString> const type;
+        Literal(OString const& i_rValue, OString const& i_rLanguage,
+                ::boost::optional<OString> const& i_rType)
+            : value(i_rValue)
+            , language(i_rLanguage)
+            , type(i_rType)
+        { }
+    };
+    struct Statement
+    {
+        ::boost::shared_ptr<Resource> const pSubject;
+        ::boost::shared_ptr<URI> const pPredicate;
+        ::boost::shared_ptr<Node> const pObject;
+        Statement(::boost::shared_ptr<Resource> const& i_pSubject,
+                  ::boost::shared_ptr<URI> const& i_pPredicate,
+                  ::boost::shared_ptr<Node> const& i_pObject)
+            : pSubject(i_pSubject)
+            , pPredicate(i_pPredicate)
+            , pObject(i_pObject)
+        { }
+    };
+
     librdf_TypeConverter(
             uno::Reference< uno::XComponentContext > const & i_xContext,
             librdf_Repository &i_rRep)
@@ -185,17 +233,23 @@ public:
         , m_rRep(i_rRep)
     { };
 
-    librdf_world *createWorld() const;
-    librdf_storage *createStorage(librdf_world *i_pWorld) const;
-    librdf_model *createModel(librdf_world *i_pWorld,
+    librdf_world *createWorld_Lock() const;
+    librdf_storage *createStorage_Lock(librdf_world *i_pWorld) const;
+    librdf_model *createModel_Lock(librdf_world *i_pWorld,
         librdf_storage * i_pStorage) const;
-    librdf_uri* mkURI( librdf_world* i_pWorld,
-        const uno::Reference< rdf::XURI > & i_xURI) const;
-    librdf_node* mkResource( librdf_world* i_pWorld,
+    librdf_uri* mkURI_Lock(librdf_world* i_pWorld,
+        const OString & i_rURI) const;
+    librdf_node* mkResource_Lock(librdf_world* i_pWorld,
+        const Resource * i_pResource) const;
+    librdf_node* mkNode_Lock(librdf_world* i_pWorld,
+        const Node * i_pNode) const;
+    librdf_statement* mkStatement_Lock(librdf_world* i_pWorld,
+        Statement const& i_rStatement) const;
+    ::boost::shared_ptr<Resource> extractResource_NoLock(
         const uno::Reference< rdf::XResource > & i_xResource) const;
-    librdf_node* mkNode( librdf_world* i_pWorld,
+    ::boost::shared_ptr<Node> extractNode_NoLock(
         const uno::Reference< rdf::XNode > & i_xNode) const;
-    librdf_statement* mkStatement( librdf_world* i_pWorld,
+    Statement extractStatement_NoLock(
         const uno::Reference< rdf::XResource > & i_xSubject,
         const uno::Reference< rdf::XURI > & i_xPredicate,
         const uno::Reference< rdf::XNode > & i_xObject) const;
@@ -209,7 +263,7 @@ public:
         const;
 
 private:
-    uno::Reference< uno::XComponentContext > m_xContext;
+    uno::Reference< uno::XComponentContext > const m_xContext;
     librdf_Repository & m_rRep;
 };
 
@@ -323,10 +377,13 @@ public:
         throw (uno::RuntimeException, uno::Exception);
 
     // XNamedGraph forwards ---------------------------------------------
-    const NamedGraphMap_t::iterator SAL_CALL clearGraph(
-            const uno::Reference< rdf::XURI > & i_xName,
+    const NamedGraphMap_t::iterator clearGraph_NoLock(
+            const OUString & i_rGraphName,
             bool i_Internal = false );
-    void addStatementGraph(
+    const NamedGraphMap_t::iterator clearGraph_Lock(
+            const OUString & i_rGraphName,
+            bool i_Internal);
+    void addStatementGraph_NoLock(
             const uno::Reference< rdf::XResource > & i_xSubject,
             const uno::Reference< rdf::XURI > & i_xPredicate,
             const uno::Reference< rdf::XNode > & i_xObject,
@@ -334,14 +391,18 @@ public:
             bool i_Internal = false );
 //        throw (uno::RuntimeException, lang::IllegalArgumentException,
 //            container::NoSuchElementException, rdf::RepositoryException);
-    void removeStatementsGraph(
+    void addStatementGraph_Lock(
+        librdf_TypeConverter::Statement const& i_rStatement,
+        OUString const& i_rGraphName,
+        bool i_Internal);
+    void removeStatementsGraph_NoLock(
             const uno::Reference< rdf::XResource > & i_xSubject,
             const uno::Reference< rdf::XURI > & i_xPredicate,
             const uno::Reference< rdf::XNode > & i_xObject,
             const uno::Reference< rdf::XURI > & i_xName );
 //        throw (uno::RuntimeException, lang::IllegalArgumentException,
 //            container::NoSuchElementException, rdf::RepositoryException);
-    uno::Reference< container::XEnumeration > getStatementsGraph(
+    uno::Reference< container::XEnumeration > getStatementsGraph_NoLock(
             const uno::Reference< rdf::XResource > & i_xSubject,
             const uno::Reference< rdf::XURI > & i_xPredicate,
             const uno::Reference< rdf::XNode > & i_xObject,
@@ -354,7 +415,8 @@ public:
 
 private:
 
-    uno::Reference< uno::XComponentContext > m_xContext;
+    /// this is const, no need to lock m_aMutex to access it
+    uno::Reference< uno::XComponentContext > const m_xContext;
 
     /// librdf global data
     /** N.B.: The redland documentation gives the impression that you can have
@@ -382,7 +444,7 @@ private:
     /// all named graphs
     NamedGraphMap_t m_NamedGraphs;
 
-    /// type conversion helper
+    /// type conversion helper - stateless
     librdf_TypeConverter m_TypeConverter;
 
     /// set of xml:ids of elements with xhtml:content
@@ -438,7 +500,7 @@ private:
     boost::shared_ptr<librdf_node>   const m_pContext;
     boost::shared_ptr<librdf_stream> const m_pStream;
 
-    librdf_node* getContext() const;
+    librdf_node* getContext_Lock() const;
 };
 
 
@@ -450,7 +512,7 @@ librdf_GraphResult::hasMoreElements() throw (uno::RuntimeException)
     return m_pStream.get() && !librdf_stream_end(m_pStream.get());
 }
 
-librdf_node* librdf_GraphResult::getContext() const
+librdf_node* librdf_GraphResult::getContext_Lock() const
 {
     if (!m_pStream.get() || librdf_stream_end(m_pStream.get()))
         return NULL;
@@ -472,7 +534,7 @@ throw (uno::RuntimeException, container::NoSuchElementException,
 {
     ::osl::MutexGuard g(m_rMutex);
     if (!m_pStream.get() || !librdf_stream_end(m_pStream.get())) {
-        librdf_node * pCtxt = getContext();
+        librdf_node * pCtxt = getContext_Lock();
 
         librdf_statement *pStmt( librdf_stream_get_object(m_pStream.get()) );
         if (!pStmt) {
@@ -545,9 +607,9 @@ private:
     ::osl::Mutex & m_rMutex;
     // not that the redland documentation spells this out explicity, but
     // queries must be freed only after all the results are completely read
-    boost::shared_ptr<librdf_query>  m_pQuery;
-    boost::shared_ptr<librdf_query_results> m_pQueryResult;
-    uno::Sequence< OUString > m_BindingNames;
+    boost::shared_ptr<librdf_query> const m_pQuery;
+    boost::shared_ptr<librdf_query_results> const m_pQueryResult;
+    uno::Sequence< OUString > const m_BindingNames;
 };
 
 
@@ -614,6 +676,7 @@ throw (uno::RuntimeException, container::NoSuchElementException,
 uno::Sequence< OUString > SAL_CALL
 librdf_QuerySelectResult::getBindingNames() throw (uno::RuntimeException)
 {
+    // const - no lock needed
     return m_BindingNames;
 }
 
@@ -675,9 +738,9 @@ public:
 private:
 
     /// weak reference: this is needed to check if m_pRep is valid
-    uno::WeakReference< rdf::XRepository > m_wRep;
-    librdf_Repository *m_pRep;
-    uno::Reference< rdf::XURI > m_xName;
+    uno::WeakReference< rdf::XRepository > const m_wRep;
+    librdf_Repository *const m_pRep;
+    uno::Reference< rdf::XURI > const m_xName;
 };
 
 
@@ -717,8 +780,9 @@ throw (uno::RuntimeException,
         throw rdf::RepositoryException(
             "librdf_NamedGraph::clear: repository is gone", *this);
     }
+    const OUString contextU( m_xName->getStringValue() );
     try {
-        m_pRep->clearGraph(m_xName);
+        m_pRep->clearGraph_NoLock(contextU);
     } catch (lang::IllegalArgumentException &) {
         throw uno::RuntimeException();
     }
@@ -736,7 +800,8 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
         throw rdf::RepositoryException(
             "librdf_NamedGraph::addStatement: repository is gone", *this);
     }
-    m_pRep->addStatementGraph(i_xSubject, i_xPredicate, i_xObject, m_xName);
+    m_pRep->addStatementGraph_NoLock(
+            i_xSubject, i_xPredicate, i_xObject, m_xName);
 }
 
 void SAL_CALL librdf_NamedGraph::removeStatements(
@@ -751,7 +816,8 @@ throw (uno::RuntimeException,
         throw rdf::RepositoryException(
             "librdf_NamedGraph::removeStatements: repository is gone", *this);
     }
-    m_pRep->removeStatementsGraph(i_xSubject, i_xPredicate, i_xObject, m_xName);
+    m_pRep->removeStatementsGraph_NoLock(
+            i_xSubject, i_xPredicate, i_xObject, m_xName);
 }
 
 uno::Reference< container::XEnumeration > SAL_CALL
@@ -767,7 +833,7 @@ throw (uno::RuntimeException,
         throw rdf::RepositoryException(
             "librdf_NamedGraph::getStatements: repository is gone", *this);
     }
-    return m_pRep->getStatementsGraph(
+    return m_pRep->getStatementsGraph_NoLock(
             i_xSubject, i_xPredicate, i_xObject, m_xName);
 }
 
@@ -791,7 +857,8 @@ librdf_Repository::librdf_Repository(
 
     ::osl::MutexGuard g(m_aMutex);
     if (!m_NumInstances++) {
-        m_pWorld.reset(m_TypeConverter.createWorld(), safe_librdf_free_world);
+        m_pWorld.reset(m_TypeConverter.createWorld_Lock(),
+                safe_librdf_free_world);
     }
 }
 
@@ -884,7 +951,6 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
     container::ElementExistException, rdf::ParseException,
     rdf::RepositoryException, io::IOException)
 {
-    ::osl::MutexGuard g(m_aMutex);
     if (!i_xInStream.is()) {
         throw lang::IllegalArgumentException(
             "librdf_Repository::importGraph: stream is null", *this, 1);
@@ -915,6 +981,16 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
     }
 
     const OUString contextU( i_xGraphName->getStringValue() );
+
+    uno::Sequence<sal_Int8> buf;
+    uno::Reference<io::XSeekable> xSeekable(i_xInStream, uno::UNO_QUERY);
+    // UGLY: if only redland could read streams...
+    const sal_Int64 sz( xSeekable.is() ? xSeekable->getLength() : 1 << 20 );
+    // exceptions are propagated
+    i_xInStream->readBytes( buf, static_cast<sal_Int32>( sz ) );
+
+    ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked //////
+
     if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) {
         throw container::ElementExistException(
                 "librdf_Repository::importGraph: graph with given URI exists", *this);
@@ -950,12 +1026,6 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
                 "librdf_new_parser failed", *this);
     }
 
-    uno::Sequence<sal_Int8> buf;
-    uno::Reference<io::XSeekable> xSeekable(i_xInStream, uno::UNO_QUERY);
-    // UGLY: if only that redland junk could read streams...
-    const sal_Int64 sz( xSeekable.is() ? xSeekable->getLength() : 1 << 20 );
-    // exceptions are propagated
-    i_xInStream->readBytes( buf, static_cast<sal_Int32>( sz ) );
     const boost::shared_ptr<librdf_stream> pStream(
         librdf_parser_parse_counted_string_as_stream(pParser.get(),
             reinterpret_cast<const unsigned char*>(buf.getConstArray()),
@@ -966,8 +1036,9 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
             "librdf_Repository::importGraph: "
             "librdf_parser_parse_counted_string_as_stream failed", *this);
     }
-    m_NamedGraphs.insert(std::make_pair(contextU,
-        new librdf_NamedGraph(this, i_xGraphName)));
+    rtl::Reference<librdf_NamedGraph> const pGraph(
+        new librdf_NamedGraph(this, i_xGraphName));
+    m_NamedGraphs.insert(std::make_pair(contextU, pGraph));
     if (librdf_model_context_add_statements(m_pModel.get(),
             pContext.get(), pStream.get())) {
         throw rdf::RepositoryException(
@@ -975,7 +1046,7 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
             "librdf_model_context_add_statements failed", *this);
     }
 
-    return getGraph(i_xGraphName);
+    return uno::Reference<rdf::XNamedGraph>(pGraph.get());
 }
 
 void addChaffWhenEncryptedStorage(const uno::Reference< io::XOutputStream > &rStream, unsigned char* pBuffer, size_t length)
@@ -1035,7 +1106,6 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
     container::NoSuchElementException, rdf::RepositoryException,
     io::IOException)
 {
-    ::osl::MutexGuard g(m_aMutex);
     if (!i_xOutStream.is()) {
         throw lang::IllegalArgumentException(
                 "librdf_Repository::exportGraph: stream is null", *this, 1);
@@ -1065,6 +1135,9 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
     }
 
     const OUString contextU( i_xGraphName->getStringValue() );
+
+    ::osl::ClearableMutexGuard g(m_aMutex); // don't call i_x* with mutex locked
+
     if (m_NamedGraphs.find(contextU) == m_NamedGraphs.end()) {
         throw container::NoSuchElementException(
                 "librdf_Repository::exportGraph: "
@@ -1163,6 +1236,9 @@ throw (uno::RuntimeException, lang::IllegalArgumentException,
             "librdf_serializer_serialize_stream_to_counted_string failed",
             *this);
     }
+
+    g.clear(); // release Mutex before calling i_xOutStream methods //////////
+
     addChaffWhenEncryptedStorage(i_xOutStream, pBuf.get(), length);
 }
 
@@ -1184,13 +1260,14 @@ librdf_Repository::getGraph(const uno::Reference< rdf::XURI > & i_xGraphName)
 throw (uno::RuntimeException, lang::IllegalArgumentException,
     rdf::RepositoryException)
 {
-    ::osl::MutexGuard g(m_aMutex);
     if (!i_xGraphName.is()) {
         throw lang::IllegalArgumentException(
                 "librdf_Repository::getGraph: URI is null", *this, 0);
     }
-    const NamedGraphMap_t::iterator iter(
-        m_NamedGraphs.find(i_xGraphName->getStringValue()) );
+    const OUString contextU( i_xGraphName->getStringValue() );
+
+    ::osl::MutexGuard g(m_aMutex);
+    const NamedGraphMap_t::iterator iter( m_NamedGraphs.find(contextU) );
     if (iter != m_NamedGraphs.end()) {
         return uno::Reference<rdf::XNamedGraph>(iter->second.get());
     } else {
@@ -1203,21 +1280,24 @@ librdf_Repository::createGraph(const uno::Reference< rdf::XURI > & i_xGraphName)
 throw (uno::RuntimeException, lang::IllegalArgumentException,
     container::ElementExistException, rdf::RepositoryException)
 {
-    ::osl::MutexGuard g(m_aMutex);
     if (!i_xGraphName.is()) {
         throw lang::IllegalArgumentException(
                 "librdf_Repository::createGraph: URI is null", *this, 0);
     }
-    if (i_xGraphName->getStringValue().matchAsciiL(s_nsOOo, sizeof(s_nsOOo)-1))
+
+    const OUString contextU( i_xGraphName->getStringValue() );
+    if (contextU.matchAsciiL(s_nsOOo, sizeof(s_nsOOo)-1))
     {
         throw lang::IllegalArgumentException(
                 "librdf_Repository::createGraph: URI is reserved", *this, 0);
     }
 
+    ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked //////
+
     // NB: librdf does not have a concept of graphs as such;
     //     a librdf named graph exists iff the model contains a statement with
     //     the graph name as context
-    const OUString contextU( i_xGraphName->getStringValue() );
+
     if (m_NamedGraphs.find(contextU) != m_NamedGraphs.end()) {
         throw container::ElementExistException(
                 "librdf_Repository::createGraph: graph with given URI exists", *this);
@@ -1234,8 +1314,15 @@ librdf_Repository::destroyGraph(
 throw (uno::RuntimeException, lang::IllegalArgumentException,
     container::NoSuchElementException, rdf::RepositoryException)
 {
-    ::osl::MutexGuard g(m_aMutex);
-    const NamedGraphMap_t::iterator iter( clearGraph(i_xGraphName) );
+    if (!i_xGraphName.is()) {
+        throw lang::IllegalArgumentException(
+                "librdf_Repository::destroyGraph: URI is null", *this, 0);
+    }
+    const OUString contextU( i_xGraphName->getStringValue() );
+
+    ::osl::MutexGuard g(m_aMutex); // don't call i_x* with mutex locked //////
+
+    const NamedGraphMap_t::iterator iter( clearGraph_Lock(contextU, false) );
     m_NamedGraphs.erase(iter);
 }
 
@@ -1262,10 +1349,14 @@ throw (uno::RuntimeException, rdf::RepositoryException)

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list