summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2013-11-14 11:29:15 +0100
committerMichael Meeks <michael.meeks@collabora.com>2013-11-20 07:25:32 -0600
commitfa8b5ae8e24fe26de7b26eff8a4a523ab22408fa (patch)
tree8a7075c2818f7537b252a8658a15cef55e1ea6b7 /vcl
parent297e316cac3118b0052aa5a9cdc2008c9aad5549 (diff)
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@collabora.com> Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/unx/kde4/KDE4FilePicker.cxx164
-rw-r--r--vcl/unx/kde4/KDE4FilePicker.hxx73
-rw-r--r--vcl/unx/kde4/KDESalInstance.cxx4
-rw-r--r--vcl/unx/kde4/KDEXLib.cxx25
-rw-r--r--vcl/unx/kde4/KDEXLib.hxx10
5 files changed, 272 insertions, 4 deletions
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 6688c6d6cc6f..ee4a6e335bb1 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 41d3cd28460b..69e7eb26bdda 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 775727c4f776..224ac3a0619e 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 c50bd77dab6b..8e0eb6713228 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 1e3adc9e7a0d..d9bd4d611deb 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: */