summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2013-11-14 11:29:15 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2014-08-20 09:44:35 +0200
commit646332b084005ffd1a79ec5ae1a60dd1e8cd5481 (patch)
treead62b83bc127d81b34b5b79c653163bd058d17a7
parent91500c7adb375182bbe6cb0a44d709c0ee3c163c (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. Reviewed-on: https://gerrit.libreoffice.org/6683 Tested-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-by: Michael Meeks <michael.meeks@collabora.com> (cherry picked from commit fa8b5ae8e24fe26de7b26eff8a4a523ab22408fa) Conflicts: vcl/unx/kde4/KDE4FilePicker.cxx vcl/unx/kde4/KDE4FilePicker.hxx Change-Id: If6ec2d205af5a883df35fddb44a12ac43e3560f0
-rw-r--r--vcl/CustomTarget_kde4_moc.mk7
-rw-r--r--vcl/unx/kde4/KDE4FilePicker.cxx161
-rw-r--r--vcl/unx/kde4/KDE4FilePicker.hxx77
-rw-r--r--vcl/unx/kde4/KDESalInstance.cxx4
-rw-r--r--vcl/unx/kde4/KDEXLib.cxx25
-rw-r--r--vcl/unx/kde4/KDEXLib.hxx10
6 files changed, 276 insertions, 8 deletions
diff --git a/vcl/CustomTarget_kde4_moc.mk b/vcl/CustomTarget_kde4_moc.mk
index 679cfbfe922f..0846b0b7f261 100644
--- a/vcl/CustomTarget_kde4_moc.mk
+++ b/vcl/CustomTarget_kde4_moc.mk
@@ -10,10 +10,11 @@
$(eval $(call gb_CustomTarget_CustomTarget,vcl/unx/kde4))
$(call gb_CustomTarget_get_target,vcl/unx/kde4) : \
- $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDEXLib.moc
+ $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDEXLib.moc \
+ $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDE4FilePicker.moc
-$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDEXLib.moc : \
- $(SRCDIR)/vcl/unx/kde4/KDEXLib.hxx \
+$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/%.moc : \
+ $(SRCDIR)/vcl/unx/kde4/%.hxx \
| $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/.dir
$(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),MOC,1)
$(MOC4) $< -o $@
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 4be3b9ae8942..16b68acc139b 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -50,6 +50,7 @@
#include <QWidget>
#include <QCheckBox>
#include <QGridLayout>
+#include <QThread>
#undef Region
@@ -111,10 +112,72 @@ KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
//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 );
}
KDE4FilePicker::~KDE4FilePicker()
{
+ cleanupProxy();
+}
+
+void KDE4FilePicker::cleanupProxy()
+{
+ if( qApp->thread() != QThread::currentThread() ) {
+ SalYieldMutexReleaser aReleaser;
+ return Q_EMIT cleanupProxySignal();
+ }
delete _resMgr;
delete _dialog;
}
@@ -136,12 +199,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 )
@@ -188,6 +261,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 (multiSelect)
_dialog->setMode(KFile::Files | KFile::LocalOnly);
else
@@ -197,6 +275,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);
}
@@ -204,6 +287,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));
}
@@ -211,6 +299,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);
}
@@ -218,6 +311,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();
+ }
+
QStringList rawFiles = _dialog->selectedFiles();
QStringList files;
@@ -266,12 +364,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);
@@ -294,6 +402,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);
@@ -302,6 +415,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();
@@ -315,9 +433,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)
{
@@ -326,9 +449,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)
@@ -363,9 +491,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];
@@ -411,6 +544,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)
@@ -422,6 +560,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)
@@ -456,6 +599,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;
@@ -584,6 +732,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
@@ -725,4 +878,6 @@ uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSupportedServiceNames()
return FilePicker_getSupportedServiceNames();
}
+#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 d45ff44339b6..af2564af6978 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -33,6 +33,7 @@
#include <rtl/ustrbuf.hxx>
+#include <QObject>
#include <QString>
#include <QHash>
@@ -52,8 +53,10 @@ typedef ::cppu::WeakComponentImplHelper5
> KDE4FilePicker_Base;
class KDE4FilePicker
- : public KDE4FilePicker_Base
+ : public QObject
+ , public KDE4FilePicker_Base
{
+ Q_OBJECT
protected:
::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener > m_xListener;
@@ -141,6 +144,75 @@ 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();
+
private:
// prevent copy and assignment
KDE4FilePicker( const KDE4FilePicker& );
@@ -149,6 +221,9 @@ private:
//add a custom control widget to the file dialog
void addCustomControl(sal_Int16 controlId);
+private Q_SLOTS:
+ void cleanupProxy();
+
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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: */