[Libreoffice-commits] core.git: vcl/unx

Jan-Marek Glogowski glogow at fbihome.de
Wed Nov 20 05:25:51 PST 2013


 vcl/unx/kde4/KDE4FilePicker.cxx |  164 +++++++++++++++++++++++++++++++++++++++-
 vcl/unx/kde4/KDE4FilePicker.hxx |   73 +++++++++++++++++
 vcl/unx/kde4/KDESalInstance.cxx |    4 
 vcl/unx/kde4/KDEXLib.cxx        |   25 ++++++
 vcl/unx/kde4/KDEXLib.hxx        |   10 ++
 5 files changed, 272 insertions(+), 4 deletions(-)

New commits:
commit fa8b5ae8e24fe26de7b26eff8a4a523ab22408fa
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Thu Nov 14 11:29:15 2013 +0100

    Redirect file picker UI processing to GUI thread.
    
    If a KDE4FilePicker is opened via an remote UNO call, e.g. via
    a RPC Java call, a JVM is started in a new thread to handle the
    call.
    
    This was creating the KDE4FilePicker in the non-UI JVM process,
    which crashes LibreOffice.
    
    Therefore we redirect the processing of all FilePicker calls to
    the main thread.
    
    This fixes fdo#71145.
    
    Change-Id: If6ec2d205af5a883df35fddb44a12ac43e3560f0
    Reviewed-on: https://gerrit.libreoffice.org/6683
    Tested-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 6688c6d..ee4a6e3 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -134,10 +134,73 @@ KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
     setMultiSelectionMode( false );
     //default mode
     _dialog->setOperationMode(KFileDialog::Opening);
+
+    // XExecutableDialog functions
+    connect( this, SIGNAL( setTitleSignal( const OUString & ) ),
+             this, SLOT( setTitleSlot( const OUString & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( executeSignal() ),
+             this, SLOT( executeSlot() ), Qt::BlockingQueuedConnection );
+
+    // XFilePicker functions
+    connect( this, SIGNAL( setMultiSelectionModeSignal( sal_Bool ) ),
+             this, SLOT( setMultiSelectionModeSlot( sal_Bool ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( setDefaultNameSignal( const OUString & ) ),
+             this, SLOT( setDefaultNameSlot( const OUString & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( setDisplayDirectorySignal( const OUString & ) ),
+             this, SLOT( setDisplayDirectorySlot( const OUString & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( getDisplayDirectorySignal() ),
+             this, SLOT( getDisplayDirectorySlot() ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( getFilesSignal() ),
+             this, SLOT( getFilesSlot() ), Qt::BlockingQueuedConnection );
+
+    // XFilterManager functions
+    connect( this, SIGNAL( appendFilterSignal( const OUString &, const OUString & ) ),
+             this, SLOT( appendFilterSlot( const OUString &, const OUString & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( setCurrentFilterSignal( const OUString & ) ),
+             this, SLOT( setCurrentFilterSlot( const OUString & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( getCurrentFilterSignal() ),
+             this, SLOT( getCurrentFilterSlot() ), Qt::BlockingQueuedConnection );
+
+    // XFilterGroupManager functions
+    connect( this, SIGNAL( appendFilterGroupSignal( const OUString &, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > & ) ),
+             this, SLOT( appendFilterGroupSlot( const OUString &, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > & ) ), Qt::BlockingQueuedConnection );
+
+    // XFilePickerControlAccess functions
+    connect( this, SIGNAL( setValueSignal( sal_Int16, sal_Int16, const ::com::sun::star::uno::Any & ) ),
+             this, SLOT( setValueSlot( sal_Int16, sal_Int16, const ::com::sun::star::uno::Any & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( getValueSignal( sal_Int16, sal_Int16 ) ),
+             this, SLOT( getValueSlot( sal_Int16, sal_Int16 ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( enableControlSignal( sal_Int16, sal_Bool ) ),
+             this, SLOT( enableControlSlot( sal_Int16, sal_Bool ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( setLabelSignal( sal_Int16, const OUString & ) ),
+             this, SLOT( setLabelSlot( sal_Int16, const OUString & ) ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( getLabelSignal( sal_Int16 ) ),
+             this, SLOT( getLabelSlot( sal_Int16 ) ), Qt::BlockingQueuedConnection );
+
+    // XFilePicker2 functions
+    connect( this, SIGNAL( getSelectedFilesSignal() ),
+             this, SLOT( getSelectedFilesSlot() ), Qt::BlockingQueuedConnection );
+
+    // XInitialization
+    connect( this, SIGNAL( initializeSignal( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > & ) ),
+             this, SLOT( initializeSlot( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > & ) ), Qt::BlockingQueuedConnection );
+
+    // Destructor proxy
+    connect( this, SIGNAL( cleanupProxySignal() ), this, SLOT( cleanupProxy() ), Qt::BlockingQueuedConnection );
+    connect( this, SIGNAL( checkProtocolSignal() ), this, SLOT( checkProtocol() ), Qt::BlockingQueuedConnection );
 }
 
 KDE4FilePicker::~KDE4FilePicker()
 {
+    cleanupProxy();
+}
+
+void KDE4FilePicker::cleanupProxy()
+{
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser aReleaser;
+        return Q_EMIT cleanupProxySignal();
+    }
     delete _resMgr;
     delete _dialog;
 }
@@ -159,12 +222,22 @@ void SAL_CALL KDE4FilePicker::removeFilePickerListener( const uno::Reference<XFi
 void SAL_CALL KDE4FilePicker::setTitle( const OUString &title )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser aReleaser;
+        return Q_EMIT setTitleSignal( title );
+    }
+
     _dialog->setCaption(toQString(title));
 }
 
 sal_Int16 SAL_CALL KDE4FilePicker::execute()
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser aReleaser;
+        return Q_EMIT executeSignal();
+    }
+
     //get the window id of the main OO window to set it for the dialog as a parent
     Window *pParentWin = Application::GetDefDialogParent();
     if ( pParentWin )
@@ -211,6 +284,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
 void SAL_CALL KDE4FilePicker::setMultiSelectionMode( sal_Bool multiSelect )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT setMultiSelectionModeSignal( multiSelect );
+    }
+
     if( allowRemoteUrls )
     {
         if (multiSelect)
@@ -230,6 +308,11 @@ void SAL_CALL KDE4FilePicker::setMultiSelectionMode( sal_Bool multiSelect )
 void SAL_CALL KDE4FilePicker::setDefaultName( const OUString &name )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT setDefaultNameSignal( name );
+    }
+
     const QString url = toQString(name);
     _dialog->setSelection(url);
 }
@@ -237,6 +320,11 @@ void SAL_CALL KDE4FilePicker::setDefaultName( const OUString &name )
 void SAL_CALL KDE4FilePicker::setDisplayDirectory( const OUString &dir )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT setDisplayDirectorySignal( dir );
+    }
+
     const QString url = toQString(dir);
     _dialog->setUrl(KUrl(url));
 }
@@ -244,6 +332,11 @@ void SAL_CALL KDE4FilePicker::setDisplayDirectory( const OUString &dir )
 OUString SAL_CALL KDE4FilePicker::getDisplayDirectory()
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT getDisplayDirectorySignal();
+    }
+
     QString dir = _dialog->baseUrl().url();
     return toOUString(dir);
 }
@@ -251,6 +344,11 @@ OUString SAL_CALL KDE4FilePicker::getDisplayDirectory()
 uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getFiles()
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT getFilesSignal();
+    }
+
     KUrl::List urls = _dialog->selectedUrls();
     uno::Sequence< OUString > seq( urls.size());
     int i = 0;
@@ -262,12 +360,22 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getFiles()
 uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSelectedFiles()
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT getSelectedFilesSignal();
+    }
+
     return getFiles();
 }
 
 void SAL_CALL KDE4FilePicker::appendFilter( const OUString &title, const OUString &filter )
     throw( lang::IllegalArgumentException, uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT appendFilterSignal( title, filter );
+    }
+
     QString t = toQString(title);
     QString f = toQString(filter);
 
@@ -290,6 +398,11 @@ void SAL_CALL KDE4FilePicker::appendFilter( const OUString &title, const OUStrin
 void SAL_CALL KDE4FilePicker::setCurrentFilter( const OUString &title )
     throw( lang::IllegalArgumentException, uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT setCurrentFilterSignal( title );
+    }
+
     QString t = toQString(title);
     t.replace("/", "\\/");
     _dialog->filterWidget()->setCurrentFilter(t);
@@ -298,6 +411,11 @@ void SAL_CALL KDE4FilePicker::setCurrentFilter( const OUString &title )
 OUString SAL_CALL KDE4FilePicker::getCurrentFilter()
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT getCurrentFilterSignal();
+    }
+
     // _dialog->currentFilter() wouldn't quite work, because it returns only e.g. "*.doc",
     // without the description, and there may be several filters with the same pattern
     QString filter = _dialog->filterWidget()->currentText();
@@ -311,9 +429,14 @@ OUString SAL_CALL KDE4FilePicker::getCurrentFilter()
     return toOUString(filter);
 }
 
-void SAL_CALL KDE4FilePicker::appendFilterGroup( const OUString& , const uno::Sequence<beans::StringPair>& filters)
+void SAL_CALL KDE4FilePicker::appendFilterGroup( const OUString& rGroupTitle, const uno::Sequence<beans::StringPair>& filters)
     throw( lang::IllegalArgumentException, uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT appendFilterGroupSignal( rGroupTitle, filters );
+    }
+
     const sal_uInt16 length = filters.getLength();
     for (sal_uInt16 i = 0; i < length; ++i)
     {
@@ -322,9 +445,14 @@ void SAL_CALL KDE4FilePicker::appendFilterGroup( const OUString& , const uno::Se
     }
 }
 
-void SAL_CALL KDE4FilePicker::setValue( sal_Int16 controlId, sal_Int16, const uno::Any &value )
+void SAL_CALL KDE4FilePicker::setValue( sal_Int16 controlId, sal_Int16 nControlAction, const uno::Any &value )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT setValueSignal( controlId, nControlAction, value );
+    }
+
     QWidget* widget = _customWidgets[controlId];
 
     if (widget)
@@ -359,9 +487,14 @@ void SAL_CALL KDE4FilePicker::setValue( sal_Int16 controlId, sal_Int16, const un
     }
 }
 
-uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 )
+uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 nControlAction )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT getValueSignal( controlId, nControlAction );
+    }
+
     uno::Any res(false);
 
     QWidget* widget = _customWidgets[controlId];
@@ -407,6 +540,11 @@ uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 )
 void SAL_CALL KDE4FilePicker::enableControl( sal_Int16 controlId, sal_Bool enable )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT enableControlSignal( controlId, enable );
+    }
+
     QWidget* widget = _customWidgets[controlId];
 
     if (widget)
@@ -418,6 +556,11 @@ void SAL_CALL KDE4FilePicker::enableControl( sal_Int16 controlId, sal_Bool enabl
 void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &label )
     throw( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT setLabelSignal( controlId, label );
+    }
+
     QWidget* widget = _customWidgets[controlId];
 
     if (widget)
@@ -452,6 +595,11 @@ void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &lab
 OUString SAL_CALL KDE4FilePicker::getLabel(sal_Int16 controlId)
     throw ( uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT getLabelSignal( controlId );
+    }
+
     QWidget* widget = _customWidgets[controlId];
     QString label;
 
@@ -580,6 +728,11 @@ void KDE4FilePicker::addCustomControl(sal_Int16 controlId)
 void SAL_CALL KDE4FilePicker::initialize( const uno::Sequence<uno::Any> &args )
     throw( uno::Exception, uno::RuntimeException )
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT initializeSignal( args );
+    }
+
     _filter.clear();
 
     // parameter checking
@@ -715,6 +868,11 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSupportedServiceNames()
 
 void KDE4FilePicker::checkProtocol()
 {
+    if( qApp->thread() != QThread::currentThread() ) {
+        SalYieldMutexReleaser release;
+        return Q_EMIT checkProtocolSignal();
+    }
+
     // There's no libreoffice.desktop :(, so find a matching one.
     KService::List services = KServiceTypeTrader::self()->query( "Application", "Exec =~ 'libreoffice %U'" );
     QStringList protocols;
diff --git a/vcl/unx/kde4/KDE4FilePicker.hxx b/vcl/unx/kde4/KDE4FilePicker.hxx
index 41d3cd2..69e7eb2 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -146,6 +146,78 @@ public:
     virtual sal_Bool SAL_CALL supportsService( const OUString &rServiceName ) throw( ::com::sun::star::uno::RuntimeException );
     virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
 
+private Q_SLOTS:
+    // XExecutableDialog functions
+    void setTitleSlot( const OUString &rTitle ) throw( ::com::sun::star::uno::RuntimeException ) { return setTitle( rTitle ); }
+    sal_Int16 executeSlot() throw( ::com::sun::star::uno::RuntimeException ) { return execute(); }
+
+    // XFilePicker functions
+    void setMultiSelectionModeSlot( sal_Bool bMode ) throw( ::com::sun::star::uno::RuntimeException ) { return setMultiSelectionMode( bMode ); }
+    void setDefaultNameSlot( const OUString &rName ) throw( ::com::sun::star::uno::RuntimeException ) { return setDefaultName( rName ); }
+    void setDisplayDirectorySlot( const OUString &rDirectory ) throw( ::com::sun::star::uno::RuntimeException ) { return setDisplayDirectory( rDirectory ); }
+    OUString getDisplayDirectorySlot() throw( ::com::sun::star::uno::RuntimeException ) { return getDisplayDirectory(); }
+    ::com::sun::star::uno::Sequence< OUString > getFilesSlot() throw( ::com::sun::star::uno::RuntimeException ) { return getFiles(); }
+
+    // XFilterManager functions
+    void appendFilterSlot( const OUString &rTitle, const OUString &rFilter ) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) { return appendFilter( rTitle, rFilter ); }
+    void setCurrentFilterSlot( const OUString &rTitle ) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) { return setCurrentFilter( rTitle ); }
+    OUString getCurrentFilterSlot() throw( ::com::sun::star::uno::RuntimeException ) { return getCurrentFilter(); }
+
+    // XFilterGroupManager functions
+    void appendFilterGroupSlot( const OUString &rGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > &rFilters ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { return appendFilterGroup( rGroupTitle, rFilters ); }
+
+    // XFilePickerControlAccess functions
+    void setValueSlot( sal_Int16 nControlId, sal_Int16 nControlAction, const ::com::sun::star::uno::Any &rValue ) throw (::com::sun::star::uno::RuntimeException) { return setValue( nControlId, nControlAction, rValue ); }
+    ::com::sun::star::uno::Any getValueSlot( sal_Int16 nControlId, sal_Int16 nControlAction ) throw (::com::sun::star::uno::RuntimeException) { return getValue( nControlId, nControlAction ); }
+    void enableControlSlot( sal_Int16 nControlId, sal_Bool bEnable ) throw( ::com::sun::star::uno::RuntimeException ) { return enableControl( nControlId, bEnable ); }
+    void setLabelSlot( sal_Int16 nControlId, const OUString &rLabel ) throw (::com::sun::star::uno::RuntimeException) { return setLabel( nControlId, rLabel ); }
+    OUString getLabelSlot( sal_Int16 nControlId ) throw (::com::sun::star::uno::RuntimeException) { return getLabel( nControlId ); }
+
+    // XFilePicker2 functions
+    ::com::sun::star::uno::Sequence< OUString > getSelectedFilesSlot() throw (::com::sun::star::uno::RuntimeException) { return getSelectedFiles(); }
+
+    // XInitialization
+    void initializeSlot( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > &rArguments ) throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException ) { return initialize( rArguments ); }
+
+Q_SIGNALS:
+    // XExecutableDialog functions
+    void setTitleSignal( const OUString &rTitle );
+    sal_Int16 executeSignal();
+
+    // XFilePicker functions
+    void setMultiSelectionModeSignal( sal_Bool bMode );
+    void setDefaultNameSignal( const OUString &rName );
+    void setDisplayDirectorySignal( const OUString &rDirectory );
+    OUString getDisplayDirectorySignal();
+    ::com::sun::star::uno::Sequence< OUString > getFilesSignal();
+
+    // XFilterManager functions
+    void appendFilterSignal( const OUString &rTitle, const OUString &rFilter );
+    void setCurrentFilterSignal( const OUString &rTitle );
+    OUString getCurrentFilterSignal();
+
+    // XFilterGroupManager functions
+    void appendFilterGroupSignal( const OUString &rGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > &rFilters );
+
+    // XFilePickerControlAccess functions
+    void setValueSignal( sal_Int16 nControlId, sal_Int16 nControlAction, const ::com::sun::star::uno::Any &rValue );
+    ::com::sun::star::uno::Any getValueSignal( sal_Int16 nControlId, sal_Int16 nControlAction );
+    void enableControlSignal( sal_Int16 nControlId, sal_Bool bEnable );
+    void setLabelSignal( sal_Int16 nControlId, const OUString &rLabel );
+    OUString getLabelSignal( sal_Int16 nControlId );
+
+    // XFilePicker2 functions
+    ::com::sun::star::uno::Sequence< OUString > getSelectedFilesSignal() ;
+
+    // XInitialization
+    void initializeSignal( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > &rArguments );
+
+    // Destructor proxy
+    void cleanupProxySignal();
+
+    // KDE protocol lookup
+    void checkProtocolSignal();
+
 private:
     // prevent copy and assignment
     KDE4FilePicker( const KDE4FilePicker& );
@@ -155,6 +227,7 @@ private:
     void addCustomControl(sal_Int16 controlId);
 
 private Q_SLOTS:
+    void cleanupProxy();
     void checkProtocol();
 
 };
diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx
index 775727c..224ac3a 100644
--- a/vcl/unx/kde4/KDESalInstance.cxx
+++ b/vcl/unx/kde4/KDESalInstance.cxx
@@ -22,6 +22,8 @@
 
 #include "KDESalFrame.hxx"
 
+#include "KDEXLib.hxx"
+
 using namespace com::sun::star;
 
 SalFrame* KDESalInstance::CreateFrame( SalFrame *pParent, sal_uLong nState )
@@ -33,7 +35,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
         const uno::Reference< uno::XComponentContext >& xMSF )
 {
     return uno::Reference< ui::dialogs::XFilePicker2 >(
-                new KDE4FilePicker( xMSF ) );
+        static_cast<KDEXLib*>( mpXLib )->createFilePicker(xMSF) );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index c50bd77..8e0eb67 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -19,6 +19,9 @@
 
 #include "VCLKDEApplication.hxx"
 
+#include "KDE4FilePicker.hxx"
+#include "KDESalInstance.hxx"
+
 #include <kapplication.h>
 #include <klocale.h>
 #include <kaboutdata.h>
@@ -66,14 +69,24 @@ KDEXLib::KDEXLib() :
     // the timers created here means they belong to the main thread
     connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated()));
     connect( &userEventTimer, SIGNAL( timeout()), this, SLOT( userEventActivated()));
+
     // QTimer::start() can be called only in its (here main) thread, so this will
     // forward between threads if needed
     connect( this, SIGNAL( startTimeoutTimerSignal()), this, SLOT( startTimeoutTimer()), Qt::QueuedConnection );
     connect( this, SIGNAL( startUserEventTimerSignal()), this, SLOT( startUserEventTimer()), Qt::QueuedConnection );
+
     // this one needs to be blocking, so that the handling in main thread is processed before
     // the thread emitting the signal continues
     connect( this, SIGNAL( processYieldSignal( bool, bool )), this, SLOT( processYield( bool, bool )),
         Qt::BlockingQueuedConnection );
+
+    // Create the File picker in the main / GUI thread and block the calling thread until
+    // the FilePicker is created.
+    connect( this, SIGNAL( createFilePickerSignal( const com::sun::star::uno::Reference<
+                                                   com::sun::star::uno::XComponentContext >&) ),
+             this, SLOT( createFilePicker( const com::sun::star::uno::Reference<
+                                                 com::sun::star::uno::XComponentContext >&) ),
+             Qt::BlockingQueuedConnection );
 }
 
 KDEXLib::~KDEXLib()
@@ -395,6 +408,18 @@ void KDEXLib::doStartup()
     }
 }
 
+using namespace com::sun::star;
+
+uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
+        const uno::Reference< uno::XComponentContext >& xMSF )
+{
+    if( qApp->thread() != QThread::currentThread()) {
+        SalYieldMutexReleaser aReleaser;
+        return Q_EMIT createFilePickerSignal( xMSF );
+    }
+    return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
+}
+
 #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 1e3adc9..d9bd4d6 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -27,6 +27,8 @@
 #include <qsocketnotifier.h>
 #include <qtimer.h>
 
+#include <unx/salinst.h>
+
 class VCLKDEApplication;
 
 class KDEXLib : public QObject, public SalXLib
@@ -65,6 +67,9 @@ class KDEXLib : public QObject, public SalXLib
         void startTimeoutTimerSignal();
         void startUserEventTimerSignal();
         void processYieldSignal( bool bWait, bool bHandleAllCurrentEvents );
+        com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
+            createFilePickerSignal( const com::sun::star::uno::Reference<
+                                          com::sun::star::uno::XComponentContext >& );
 
     public:
         KDEXLib();
@@ -80,6 +85,11 @@ class KDEXLib : public QObject, public SalXLib
         virtual void PostUserEvent();
 
         void doStartup();
+
+    public Q_SLOTS:
+        virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
+            createFilePicker( const com::sun::star::uno::Reference<
+                                  com::sun::star::uno::XComponentContext >& );
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list