Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / unx / kde4 / KDE4FilePicker.cxx
bloba638955dd6aee1ee3cbae700471d2b22500373bf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/lang/DisposedException.hpp>
21 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 #include <cppuhelper/interfacecontainer.h>
23 #include <cppuhelper/supportsservice.hxx>
24 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
25 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
26 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
27 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
28 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
30 #include <osl/mutex.hxx>
32 #include <vcl/fpicker.hrc>
33 #include <vcl/svapp.hxx>
34 #include <vcl/sysdata.hxx>
35 #include <vcl/syswin.hxx>
37 #include "osl/file.h"
39 #include "KDE4FilePicker.hxx"
40 #include "FPServiceInfo.hxx"
41 #include "VCLKDEApplication.hxx"
43 #include <kfiledialog.h>
44 #include <kwindowsystem.h>
45 #include <kapplication.h>
46 #include <kfilefiltercombo.h>
47 #include <kfilewidget.h>
48 #include <kdiroperator.h>
49 #include <kservicetypetrader.h>
50 #include <kmessagebox.h>
52 #include <qclipboard.h>
53 #include <QWidget>
54 #include <QCheckBox>
55 #include <QGridLayout>
57 #undef Region
59 #include "generic/geninst.h"
61 #include "svids.hrc"
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::ui::dialogs;
65 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
66 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
67 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
68 using namespace ::com::sun::star::lang;
69 using namespace ::com::sun::star::beans;
70 using namespace ::com::sun::star::uno;
72 // The dialog should check whether LO also supports the protocol
73 // provided by KIO, and KFileWidget::dirOperator() is only 4.3+ .
74 // Moreover it's only in this somewhat internal KFileWidget class,
75 // which may not necessarily be what KFileDialog::fileWidget() returns,
76 // but that's hopefully not a problem in practice.
77 #if KDE_VERSION_MAJOR == 4 && KDE_VERSION_MINOR >= 2
78 #define ALLOW_REMOTE_URLS 1
79 #else
80 #define ALLOW_REMOTE_URLS 0
81 #endif
83 // helper functions
85 #include <QDebug>
87 namespace
89 uno::Sequence<OUString> SAL_CALL FilePicker_getSupportedServiceNames()
91 uno::Sequence<OUString> aRet(3);
92 aRet[0] = "com.sun.star.ui.dialogs.FilePicker";
93 aRet[1] = "com.sun.star.ui.dialogs.SystemFilePicker";
94 aRet[2] = "com.sun.star.ui.dialogs.KDE4FilePicker";
95 return aRet;
99 OUString toOUString(const QString& s)
101 // QString stores UTF16, just like OUString
102 return OUString(reinterpret_cast<const sal_Unicode*>(s.data()), s.length());
105 QString toQString(const OUString& s)
107 return QString::fromUtf16(s.getStr(), s.getLength());
110 // KDE4FilePicker
112 KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
113 : KDE4FilePicker_Base(_helperMutex)
114 , allowRemoteUrls( false )
116 _extraControls = new QWidget();
117 _layout = new QGridLayout(_extraControls);
119 _dialog = new KFileDialog(KUrl("~"), QString(""), 0, _extraControls);
120 #if ALLOW_REMOTE_URLS
121 if( KFileWidget* fileWidget = dynamic_cast< KFileWidget* >( _dialog->fileWidget()))
123 allowRemoteUrls = true;
124 // Use finishedLoading signal rather than e.g. urlEntered, because if there's a problem
125 // such as the URL being mistyped, there's no way to prevent two message boxes about it,
126 // one from us and one from KDE code.
127 connect( fileWidget->dirOperator(), SIGNAL( finishedLoading()), SLOT( checkProtocol()));
129 #endif
131 setMultiSelectionMode( false );
133 // XExecutableDialog functions
134 connect( this, SIGNAL( setTitleSignal( const OUString & ) ),
135 this, SLOT( setTitleSlot( const OUString & ) ), Qt::BlockingQueuedConnection );
136 connect( this, SIGNAL( executeSignal() ),
137 this, SLOT( executeSlot() ), Qt::BlockingQueuedConnection );
139 // XFilePicker functions
140 connect( this, SIGNAL( setMultiSelectionModeSignal( bool ) ),
141 this, SLOT( setMultiSelectionModeSlot( bool ) ), Qt::BlockingQueuedConnection );
142 connect( this, SIGNAL( setDefaultNameSignal( const OUString & ) ),
143 this, SLOT( setDefaultNameSlot( const OUString & ) ), Qt::BlockingQueuedConnection );
144 connect( this, SIGNAL( setDisplayDirectorySignal( const OUString & ) ),
145 this, SLOT( setDisplayDirectorySlot( const OUString & ) ), Qt::BlockingQueuedConnection );
146 connect( this, SIGNAL( getDisplayDirectorySignal() ),
147 this, SLOT( getDisplayDirectorySlot() ), Qt::BlockingQueuedConnection );
148 connect( this, SIGNAL( getFilesSignal() ),
149 this, SLOT( getFilesSlot() ), Qt::BlockingQueuedConnection );
151 // XFilterManager functions
152 connect( this, SIGNAL( appendFilterSignal( const OUString &, const OUString & ) ),
153 this, SLOT( appendFilterSlot( const OUString &, const OUString & ) ), Qt::BlockingQueuedConnection );
154 connect( this, SIGNAL( setCurrentFilterSignal( const OUString & ) ),
155 this, SLOT( setCurrentFilterSlot( const OUString & ) ), Qt::BlockingQueuedConnection );
156 connect( this, SIGNAL( getCurrentFilterSignal() ),
157 this, SLOT( getCurrentFilterSlot() ), Qt::BlockingQueuedConnection );
159 // XFilterGroupManager functions
160 connect( this, SIGNAL( appendFilterGroupSignal( const OUString &, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > & ) ),
161 this, SLOT( appendFilterGroupSlot( const OUString &, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair > & ) ), Qt::BlockingQueuedConnection );
163 // XFilePickerControlAccess functions
164 connect( this, SIGNAL( setValueSignal( sal_Int16, sal_Int16, const ::com::sun::star::uno::Any & ) ),
165 this, SLOT( setValueSlot( sal_Int16, sal_Int16, const ::com::sun::star::uno::Any & ) ), Qt::BlockingQueuedConnection );
166 connect( this, SIGNAL( getValueSignal( sal_Int16, sal_Int16 ) ),
167 this, SLOT( getValueSlot( sal_Int16, sal_Int16 ) ), Qt::BlockingQueuedConnection );
168 connect( this, SIGNAL( enableControlSignal( sal_Int16, bool ) ),
169 this, SLOT( enableControlSlot( sal_Int16, bool ) ), Qt::BlockingQueuedConnection );
170 connect( this, SIGNAL( setLabelSignal( sal_Int16, const OUString & ) ),
171 this, SLOT( setLabelSlot( sal_Int16, const OUString & ) ), Qt::BlockingQueuedConnection );
172 connect( this, SIGNAL( getLabelSignal( sal_Int16 ) ),
173 this, SLOT( getLabelSlot( sal_Int16 ) ), Qt::BlockingQueuedConnection );
175 // XFilePicker2 functions
176 connect( this, SIGNAL( getSelectedFilesSignal() ),
177 this, SLOT( getSelectedFilesSlot() ), Qt::BlockingQueuedConnection );
179 // XInitialization
180 connect( this, SIGNAL( initializeSignal( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > & ) ),
181 this, SLOT( initializeSlot( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > & ) ), Qt::BlockingQueuedConnection );
183 // Destructor proxy
184 connect( this, SIGNAL( cleanupProxySignal() ), this, SLOT( cleanupProxy() ), Qt::BlockingQueuedConnection );
186 connect( this, SIGNAL( checkProtocolSignal() ), this, SLOT( checkProtocol() ), Qt::BlockingQueuedConnection );
188 // XFilePickerListener notifications
189 connect( _dialog, SIGNAL( filterChanged(const QString&) ), this, SLOT( filterChanged(const QString&) ));
190 connect( _dialog, SIGNAL( selectionChanged() ), this, SLOT( selectionChanged() ));
193 KDE4FilePicker::~KDE4FilePicker()
195 cleanupProxy();
198 void KDE4FilePicker::cleanupProxy()
200 if( qApp->thread() != QThread::currentThread() ) {
201 SalYieldMutexReleaser aReleaser;
202 return Q_EMIT cleanupProxySignal();
204 delete _dialog;
207 void SAL_CALL KDE4FilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
208 throw( uno::RuntimeException, std::exception )
210 SolarMutexGuard aGuard;
211 m_xListener = xListener;
214 void SAL_CALL KDE4FilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& )
215 throw( uno::RuntimeException, std::exception )
217 SolarMutexGuard aGuard;
218 m_xListener.clear();
221 void SAL_CALL KDE4FilePicker::setTitle( const OUString &title )
222 throw( uno::RuntimeException, std::exception )
224 if( qApp->thread() != QThread::currentThread() ) {
225 SalYieldMutexReleaser aReleaser;
226 return Q_EMIT setTitleSignal( title );
229 _dialog->setCaption(toQString(title));
232 sal_Int16 SAL_CALL KDE4FilePicker::execute()
233 throw( uno::RuntimeException, std::exception )
235 if( qApp->thread() != QThread::currentThread() ) {
236 SalYieldMutexReleaser aReleaser;
237 return Q_EMIT executeSignal();
240 //get the window id of the main OO window to set it for the dialog as a parent
241 vcl::Window *pParentWin = Application::GetDefDialogParent();
242 if ( pParentWin )
244 const SystemEnvData* pSysData = static_cast<SystemWindow *>(pParentWin)->GetSystemData();
245 if ( pSysData )
247 KWindowSystem::setMainWindow( _dialog, pSysData->aWindow); // unx only
251 _dialog->clearFilter();
252 _dialog->setFilter(_filter);
254 if(!_currentFilter.isNull())
255 _dialog->filterWidget()->setCurrentItem(_currentFilter);
257 _dialog->filterWidget()->setEditable(false);
259 VCLKDEApplication::preDialogSetup();
260 //block and wait for user input
261 int result = _dialog->exec();
262 VCLKDEApplication::postDialogCleanup();
263 if( result == KFileDialog::Accepted )
264 return ExecutableDialogResults::OK;
266 return ExecutableDialogResults::CANCEL;
269 void SAL_CALL KDE4FilePicker::setMultiSelectionMode( sal_Bool multiSelect )
270 throw( uno::RuntimeException, std::exception )
272 if( qApp->thread() != QThread::currentThread() ) {
273 SalYieldMutexReleaser release;
274 return Q_EMIT setMultiSelectionModeSignal( multiSelect );
277 if( allowRemoteUrls )
279 if (multiSelect)
280 _dialog->setMode(KFile::Files);
281 else
282 _dialog->setMode(KFile::File);
284 else
286 if (multiSelect)
287 _dialog->setMode(KFile::Files | KFile::LocalOnly);
288 else
289 _dialog->setMode(KFile::File | KFile::LocalOnly);
293 void SAL_CALL KDE4FilePicker::setDefaultName( const OUString &name )
294 throw( uno::RuntimeException, std::exception )
296 if( qApp->thread() != QThread::currentThread() ) {
297 SalYieldMutexReleaser release;
298 return Q_EMIT setDefaultNameSignal( name );
301 const QString url = toQString(name);
302 _dialog->setSelection(url);
305 void SAL_CALL KDE4FilePicker::setDisplayDirectory( const OUString &dir )
306 throw( uno::RuntimeException, std::exception )
308 if( qApp->thread() != QThread::currentThread() ) {
309 SalYieldMutexReleaser release;
310 return Q_EMIT setDisplayDirectorySignal( dir );
313 const QString url = toQString(dir);
314 _dialog->setUrl(KUrl(url));
317 OUString SAL_CALL KDE4FilePicker::getDisplayDirectory()
318 throw( uno::RuntimeException, std::exception )
320 if( qApp->thread() != QThread::currentThread() ) {
321 SalYieldMutexReleaser release;
322 return Q_EMIT getDisplayDirectorySignal();
325 QString dir = _dialog->baseUrl().url();
326 return toOUString(dir);
329 uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getFiles()
330 throw( uno::RuntimeException, std::exception )
332 if( qApp->thread() != QThread::currentThread() ) {
333 SalYieldMutexReleaser release;
334 return Q_EMIT getFilesSignal();
337 KUrl::List urls = _dialog->selectedUrls();
338 uno::Sequence< OUString > seq( urls.size());
339 int i = 0;
340 foreach( const KUrl& url, urls )
341 seq[ i++ ]= toOUString( url.url());
342 return seq;
345 uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSelectedFiles()
346 throw( uno::RuntimeException, std::exception )
348 if( qApp->thread() != QThread::currentThread() ) {
349 SalYieldMutexReleaser release;
350 return Q_EMIT getSelectedFilesSignal();
353 return getFiles();
356 void SAL_CALL KDE4FilePicker::appendFilter( const OUString &title, const OUString &filter )
357 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
359 if( qApp->thread() != QThread::currentThread() ) {
360 SalYieldMutexReleaser release;
361 return Q_EMIT appendFilterSignal( title, filter );
364 QString t = toQString(title);
365 QString f = toQString(filter);
367 if (!_filter.isNull())
368 _filter.append("\n");
370 // '/' need to be escaped else they are assumed to be mime types by kfiledialog
371 //see the docs
372 t.replace("/", "\\/");
374 // openoffice gives us filters separated by ';' qt dialogs just want space separated
375 f.replace(";", " ");
377 // make sure "*.*" is not used as "all files"
378 f.replace("*.*", "*");
380 _filter.append(QString("%1|%2").arg(f).arg(t));
383 void SAL_CALL KDE4FilePicker::setCurrentFilter( const OUString &title )
384 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
386 if( qApp->thread() != QThread::currentThread() ) {
387 SalYieldMutexReleaser release;
388 return Q_EMIT setCurrentFilterSignal( title );
391 _currentFilter = toQString(title);
394 OUString SAL_CALL KDE4FilePicker::getCurrentFilter()
395 throw( uno::RuntimeException, std::exception )
397 if( qApp->thread() != QThread::currentThread() ) {
398 SalYieldMutexReleaser release;
399 return Q_EMIT getCurrentFilterSignal();
402 // _dialog->currentFilter() wouldn't quite work, because it returns only e.g. "*.doc",
403 // without the description, and there may be several filters with the same pattern
404 QString filter = _dialog->filterWidget()->currentText();
405 filter = filter.mid( filter.indexOf( '|' ) + 1 ); // convert from the pattern|description format if needed
406 filter.replace( "\\/", "/" );
408 //default if not found
409 if (filter.isNull())
410 filter = "ODF Text Document (.odt)";
412 return toOUString(filter);
415 void SAL_CALL KDE4FilePicker::appendFilterGroup( const OUString& rGroupTitle, const uno::Sequence<beans::StringPair>& filters)
416 throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
418 if( qApp->thread() != QThread::currentThread() ) {
419 SalYieldMutexReleaser release;
420 return Q_EMIT appendFilterGroupSignal( rGroupTitle, filters );
423 const sal_uInt16 length = filters.getLength();
424 for (sal_uInt16 i = 0; i < length; ++i)
426 beans::StringPair aPair = filters[i];
427 appendFilter( aPair.First, aPair.Second );
431 void SAL_CALL KDE4FilePicker::setValue( sal_Int16 controlId, sal_Int16 nControlAction, const uno::Any &value )
432 throw( uno::RuntimeException, std::exception )
434 if( qApp->thread() != QThread::currentThread() ) {
435 SalYieldMutexReleaser release;
436 return Q_EMIT setValueSignal( controlId, nControlAction, value );
439 if (_customWidgets.contains( controlId )) {
440 QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
441 if (cb)
442 cb->setChecked(value.get<bool>());
444 else
445 OSL_TRACE( "set label on unknown control %d", controlId );
448 uno::Any SAL_CALL KDE4FilePicker::getValue( sal_Int16 controlId, sal_Int16 nControlAction )
449 throw( uno::RuntimeException, std::exception )
451 if (CHECKBOX_AUTOEXTENSION == controlId)
452 // We ignore this one and rely on KFileDialog to provide the function.
453 // Always return false, to pretend we do not support this, otherwise
454 // LO core would try to be smart and cut the extension in some places,
455 // interfering with KFileDialog's handling of it. KFileDialog also
456 // saves the value of the setting, so LO core is not needed for that either.
457 return uno::Any( false );
459 if( qApp->thread() != QThread::currentThread() ) {
460 SalYieldMutexReleaser release;
461 return Q_EMIT getValueSignal( controlId, nControlAction );
464 uno::Any res(false);
465 if (_customWidgets.contains( controlId )) {
466 QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
467 if (cb)
468 res = uno::Any(cb->isChecked());
470 else
471 OSL_TRACE( "get value on unknown control %d", controlId );
473 return res;
476 void SAL_CALL KDE4FilePicker::enableControl( sal_Int16 controlId, sal_Bool enable )
477 throw( uno::RuntimeException, std::exception )
479 if( qApp->thread() != QThread::currentThread() ) {
480 SalYieldMutexReleaser release;
481 return Q_EMIT enableControlSignal( controlId, enable );
484 if (_customWidgets.contains( controlId ))
485 _customWidgets.value( controlId )->setEnabled( enable );
486 else
487 OSL_TRACE("enable unknown control %d", controlId );
490 void SAL_CALL KDE4FilePicker::setLabel( sal_Int16 controlId, const OUString &label )
491 throw( uno::RuntimeException, std::exception )
493 if( qApp->thread() != QThread::currentThread() ) {
494 SalYieldMutexReleaser release;
495 return Q_EMIT setLabelSignal( controlId, label );
498 if (_customWidgets.contains( controlId )) {
499 QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
500 if (cb)
501 cb->setText( toQString(label) );
503 else
504 OSL_TRACE( "set label on unknown control %d", controlId );
507 OUString SAL_CALL KDE4FilePicker::getLabel(sal_Int16 controlId)
508 throw ( uno::RuntimeException, std::exception )
510 if( qApp->thread() != QThread::currentThread() ) {
511 SalYieldMutexReleaser release;
512 return Q_EMIT getLabelSignal( controlId );
515 QString label;
516 if (_customWidgets.contains( controlId )) {
517 QCheckBox* cb = dynamic_cast<QCheckBox*>( _customWidgets.value( controlId ));
518 if (cb)
519 label = cb->text();
521 else
522 OSL_TRACE( "get label on unknown control %d", controlId );
524 return toOUString(label);
527 QString KDE4FilePicker::getResString( sal_Int16 aRedId )
529 QString aResString;
531 if( aRedId < 0 )
532 return aResString;
536 aResString = toQString(ResId(aRedId, *ImplGetResMgr()).toString());
538 catch(...)
542 return aResString.replace('~', '&');
545 void KDE4FilePicker::addCustomControl(sal_Int16 controlId)
547 QWidget* widget = 0;
548 sal_Int32 resId = -1;
550 switch (controlId)
552 case CHECKBOX_AUTOEXTENSION:
553 resId = STR_FPICKER_AUTO_EXTENSION;
554 break;
555 case CHECKBOX_PASSWORD:
556 resId = STR_FPICKER_PASSWORD;
557 break;
558 case CHECKBOX_FILTEROPTIONS:
559 resId = STR_FPICKER_FILTER_OPTIONS;
560 break;
561 case CHECKBOX_READONLY:
562 resId = STR_FPICKER_READONLY;
563 break;
564 case CHECKBOX_LINK:
565 resId = STR_FPICKER_INSERT_AS_LINK;
566 break;
567 case CHECKBOX_PREVIEW:
568 resId = STR_FPICKER_SHOW_PREVIEW;
569 break;
570 case CHECKBOX_SELECTION:
571 resId = STR_FPICKER_SELECTION;
572 break;
573 case PUSHBUTTON_PLAY:
574 resId = STR_FPICKER_PLAY;
575 break;
576 case LISTBOX_VERSION:
577 resId = STR_FPICKER_VERSION;
578 break;
579 case LISTBOX_TEMPLATE:
580 resId = STR_FPICKER_TEMPLATES;
581 break;
582 case LISTBOX_IMAGE_TEMPLATE:
583 resId = STR_FPICKER_IMAGE_TEMPLATE;
584 break;
585 case LISTBOX_VERSION_LABEL:
586 case LISTBOX_TEMPLATE_LABEL:
587 case LISTBOX_IMAGE_TEMPLATE_LABEL:
588 case LISTBOX_FILTER_SELECTOR:
589 break;
592 switch (controlId)
594 case CHECKBOX_AUTOEXTENSION:
595 case CHECKBOX_PASSWORD:
596 case CHECKBOX_FILTEROPTIONS:
597 case CHECKBOX_READONLY:
598 case CHECKBOX_LINK:
599 case CHECKBOX_PREVIEW:
600 case CHECKBOX_SELECTION:
602 widget = new QCheckBox(getResString(resId), _extraControls);
604 // the checkbox is created even for CHECKBOX_AUTOEXTENSION to simplify
605 // code, but the checkbox is hidden and ignored
606 if( controlId == CHECKBOX_AUTOEXTENSION )
607 widget->hide();
609 break;
611 case PUSHBUTTON_PLAY:
612 case LISTBOX_VERSION:
613 case LISTBOX_TEMPLATE:
614 case LISTBOX_IMAGE_TEMPLATE:
615 case LISTBOX_VERSION_LABEL:
616 case LISTBOX_TEMPLATE_LABEL:
617 case LISTBOX_IMAGE_TEMPLATE_LABEL:
618 case LISTBOX_FILTER_SELECTOR:
619 break;
622 if (widget)
624 _layout->addWidget(widget);
625 _customWidgets.insert(controlId, widget);
629 void SAL_CALL KDE4FilePicker::initialize( const uno::Sequence<uno::Any> &args )
630 throw( uno::Exception, uno::RuntimeException, std::exception )
632 if( qApp->thread() != QThread::currentThread() ) {
633 SalYieldMutexReleaser release;
634 return Q_EMIT initializeSignal( args );
637 _filter.clear();
638 _currentFilter.clear();
640 // parameter checking
641 uno::Any arg;
642 if (args.getLength() == 0)
644 throw lang::IllegalArgumentException(
645 OUString( "no arguments" ),
646 static_cast< XFilePicker2* >( this ), 1 );
649 arg = args[0];
651 if (( arg.getValueType() != cppu::UnoType<sal_Int16>::get()) &&
652 ( arg.getValueType() != cppu::UnoType<sal_Int8>::get()))
654 throw lang::IllegalArgumentException(
655 OUString( "invalid argument type" ),
656 static_cast< XFilePicker2* >( this ), 1 );
659 sal_Int16 templateId = -1;
660 arg >>= templateId;
662 //default is opening
663 KFileDialog::OperationMode operationMode = KFileDialog::Opening;
665 switch ( templateId )
667 case FILEOPEN_SIMPLE:
668 break;
670 case FILESAVE_SIMPLE:
671 operationMode = KFileDialog::Saving;
672 break;
674 case FILESAVE_AUTOEXTENSION:
675 operationMode = KFileDialog::Saving;
676 addCustomControl( CHECKBOX_AUTOEXTENSION );
677 break;
679 case FILESAVE_AUTOEXTENSION_PASSWORD:
681 operationMode = KFileDialog::Saving;
682 addCustomControl( CHECKBOX_PASSWORD );
683 break;
685 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
687 operationMode = KFileDialog::Saving;
688 addCustomControl( CHECKBOX_AUTOEXTENSION );
689 addCustomControl( CHECKBOX_PASSWORD );
690 addCustomControl( CHECKBOX_FILTEROPTIONS );
691 break;
693 case FILESAVE_AUTOEXTENSION_SELECTION:
694 operationMode = KFileDialog::Saving;
695 addCustomControl( CHECKBOX_AUTOEXTENSION );
696 addCustomControl( CHECKBOX_SELECTION );
697 break;
699 case FILESAVE_AUTOEXTENSION_TEMPLATE:
700 operationMode = KFileDialog::Saving;
701 addCustomControl( CHECKBOX_AUTOEXTENSION );
702 addCustomControl( LISTBOX_TEMPLATE );
703 break;
705 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
706 addCustomControl( CHECKBOX_LINK );
707 addCustomControl( CHECKBOX_PREVIEW );
708 addCustomControl( LISTBOX_IMAGE_TEMPLATE );
709 break;
711 case FILEOPEN_PLAY:
712 addCustomControl( PUSHBUTTON_PLAY );
713 break;
715 case FILEOPEN_READONLY_VERSION:
716 addCustomControl( CHECKBOX_READONLY );
717 addCustomControl( LISTBOX_VERSION );
718 break;
720 case FILEOPEN_LINK_PREVIEW:
721 addCustomControl( CHECKBOX_LINK );
722 addCustomControl( CHECKBOX_PREVIEW );
723 break;
725 default:
726 throw lang::IllegalArgumentException(
727 OUString( "Unknown template" ),
728 static_cast< XFilePicker2* >( this ),
729 1 );
732 _dialog->setOperationMode( operationMode );
734 sal_Int16 resId = -1;
735 switch (_dialog->operationMode())
737 case KFileDialog::Opening:
738 resId = STR_FPICKER_OPEN;
739 break;
740 case KFileDialog::Saving:
741 resId = STR_FPICKER_SAVE;
742 _dialog->setConfirmOverwrite( true );
743 break;
744 default:
745 break;
748 _dialog->setCaption(getResString(resId));
751 void SAL_CALL KDE4FilePicker::cancel()
752 throw ( uno::RuntimeException, std::exception )
757 void SAL_CALL KDE4FilePicker::disposing( const lang::EventObject &rEvent )
758 throw( uno::RuntimeException )
760 uno::Reference<XFilePickerListener> xFilePickerListener( rEvent.Source, uno::UNO_QUERY );
762 if ( xFilePickerListener.is() )
764 removeFilePickerListener( xFilePickerListener );
768 OUString SAL_CALL KDE4FilePicker::getImplementationName()
769 throw( uno::RuntimeException, std::exception )
771 return OUString( FILE_PICKER_IMPL_NAME );
774 sal_Bool SAL_CALL KDE4FilePicker::supportsService( const OUString& ServiceName )
775 throw( uno::RuntimeException, std::exception )
777 return cppu::supportsService(this, ServiceName);
780 uno::Sequence< OUString > SAL_CALL KDE4FilePicker::getSupportedServiceNames()
781 throw( uno::RuntimeException, std::exception )
783 return FilePicker_getSupportedServiceNames();
786 void KDE4FilePicker::checkProtocol()
788 if( qApp->thread() != QThread::currentThread() ) {
789 SalYieldMutexReleaser release;
790 return Q_EMIT checkProtocolSignal();
793 // There's no libreoffice.desktop :(, so find a matching one.
794 KService::List services = KServiceTypeTrader::self()->query( "Application", "Exec =~ 'libreoffice %U'" );
795 QStringList protocols;
796 if( !services.isEmpty())
797 protocols = services[ 0 ]->property( "X-KDE-Protocols" ).toStringList();
798 if( protocols.isEmpty()) // incorrect (developer?) installation ?
799 protocols << "file" << "http";
800 if( !protocols.contains( _dialog->baseUrl().protocol()) && !protocols.contains( "KIO" ))
801 KMessageBox::error( _dialog, KIO::buildErrorString( KIO::ERR_UNSUPPORTED_PROTOCOL, _dialog->baseUrl().protocol()));
804 void KDE4FilePicker::filterChanged(const QString &)
806 FilePickerEvent aEvent;
807 aEvent.ElementId = LISTBOX_FILTER;
808 OSL_TRACE( "filter changed" );
809 if (m_xListener.is())
810 m_xListener->controlStateChanged( aEvent );
813 void KDE4FilePicker::selectionChanged()
815 FilePickerEvent aEvent;
816 OSL_TRACE( "file selection changed" );
817 if (m_xListener.is())
818 m_xListener->fileSelectionChanged( aEvent );
821 #include "KDE4FilePicker.moc"
823 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */