1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "VistaFilePicker.hxx"
22 #include "WinImplHelper.hxx"
23 #include "FPServiceInfo.hxx"
26 #include <com/sun/star/awt/XWindow.hpp>
27 #include <com/sun/star/lang/DisposedException.hpp>
28 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
29 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
30 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
31 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
33 #include <cppuhelper/interfacecontainer.h>
34 #include <cppuhelper/supportsservice.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <osl/mutex.hxx>
37 #include <osl/file.hxx>
38 #include <officecfg/Office/Common.hxx>
48 css::uno::Sequence
< OUString
> VistaFilePicker_getSupportedServiceNames()
51 "com.sun.star.ui.dialogs.FilePicker",
52 "com.sun.star.ui.dialogs.SystemFilePicker",
53 "com.sun.star.ui.dialogs.SystemFolderPicker" };
57 VistaFilePicker::VistaFilePicker(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
, bool bFolderPicker
)
58 : TVistaFilePickerBase (m_aMutex
)
60 , m_rDialog (new VistaFilePickerImpl())
61 , m_aAsyncExecute (m_rDialog
)
62 , m_nFilePickerThreadId (0 )
63 , m_bInitialized (false )
64 , m_bFolderPicker (bFolderPicker
)
68 VistaFilePicker::~VistaFilePicker()
72 void SAL_CALL
VistaFilePicker::addFilePickerListener(const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
74 RequestRef
rRequest(new Request());
75 rRequest
->setRequest (VistaFilePickerImpl::E_ADD_PICKER_LISTENER
);
76 rRequest
->setArgument(PROP_PICKER_LISTENER
, xListener
);
78 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
81 void SAL_CALL
VistaFilePicker::removeFilePickerListener(const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
83 RequestRef
rRequest(new Request());
84 rRequest
->setRequest (VistaFilePickerImpl::E_REMOVE_PICKER_LISTENER
);
85 rRequest
->setArgument(PROP_PICKER_LISTENER
, xListener
);
87 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
90 void VistaFilePicker::disposing(const css::lang::EventObject
& /*aEvent*/)
94 void SAL_CALL
VistaFilePicker::setMultiSelectionMode(sal_Bool bMode
)
98 RequestRef
rRequest(new Request());
99 rRequest
->setRequest (VistaFilePickerImpl::E_SET_MULTISELECTION_MODE
);
100 rRequest
->setArgument(PROP_MULTISELECTION_MODE
, bMode
);
102 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
105 void SAL_CALL
VistaFilePicker::setTitle(const OUString
& sTitle
)
109 RequestRef
rRequest(new Request());
110 rRequest
->setRequest (VistaFilePickerImpl::E_SET_TITLE
);
111 rRequest
->setArgument(PROP_TITLE
, sTitle
);
113 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
116 void SAL_CALL
VistaFilePicker::appendFilter(const OUString
& sTitle
,
117 const OUString
& sFilter
)
119 RequestRef
rRequest(new Request());
120 rRequest
->setRequest (VistaFilePickerImpl::E_APPEND_FILTER
);
121 rRequest
->setArgument(PROP_FILTER_TITLE
, sTitle
);
122 rRequest
->setArgument(PROP_FILTER_VALUE
, sFilter
);
124 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
127 void SAL_CALL
VistaFilePicker::setCurrentFilter(const OUString
& sTitle
)
129 RequestRef
rRequest(new Request());
130 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CURRENT_FILTER
);
131 rRequest
->setArgument(PROP_FILTER_TITLE
, sTitle
);
133 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
136 OUString SAL_CALL
VistaFilePicker::getCurrentFilter()
138 RequestRef
rRequest(new Request());
139 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CURRENT_FILTER
);
141 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
143 const OUString sTitle
= rRequest
->getArgumentOrDefault(PROP_FILTER_TITLE
, OUString());
147 void SAL_CALL
VistaFilePicker::appendFilterGroup(const OUString
& /*sGroupTitle*/,
148 const css::uno::Sequence
< css::beans::StringPair
>& rFilters
)
150 RequestRef
rRequest(new Request());
151 rRequest
->setRequest (VistaFilePickerImpl::E_APPEND_FILTERGROUP
);
152 rRequest
->setArgument(PROP_FILTER_GROUP
, rFilters
);
154 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
157 void SAL_CALL
VistaFilePicker::setDefaultName(const OUString
& sName
)
161 RequestRef
rRequest(new Request());
162 rRequest
->setRequest (VistaFilePickerImpl::E_SET_DEFAULT_NAME
);
163 rRequest
->setArgument(PROP_FILENAME
, sName
);
165 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
168 void SAL_CALL
VistaFilePicker::setDisplayDirectory(const OUString
& sDirectory
)
172 RequestRef
rRequest(new Request());
173 rRequest
->setRequest (VistaFilePickerImpl::E_SET_DIRECTORY
);
174 rRequest
->setArgument(PROP_DIRECTORY
, sDirectory
);
176 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
179 OUString SAL_CALL
VistaFilePicker::getDisplayDirectory()
183 RequestRef
rRequest(new Request());
184 rRequest
->setRequest (VistaFilePickerImpl::E_GET_DIRECTORY
);
185 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
186 const OUString sDirectory
= rRequest
->getArgumentOrDefault(PROP_DIRECTORY
, OUString());
191 // @deprecated can't be supported any longer ... see IDL description for further details
192 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getFiles()
194 css::uno::Sequence
< OUString
> lFiles
= getSelectedFiles();
195 // multiselection doesn't really work
196 // so just retrieve the first url
197 if (lFiles
.getLength() > 1)
199 m_lLastFiles
= lFiles
;
203 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getSelectedFiles()
205 RequestRef
rRequest(new Request());
206 rRequest
->setRequest (VistaFilePickerImpl::E_GET_SELECTED_FILES
);
208 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
210 const css::uno::Sequence
< OUString
> lFiles
= rRequest
->getArgumentOrDefault(PROP_SELECTED_FILES
, css::uno::Sequence
< OUString
>());
211 m_lLastFiles
= lFiles
;
215 void VistaFilePicker::ensureInit()
217 bool bInitialized(false);
219 osl::MutexGuard
aGuard(m_aMutex
);
220 bInitialized
= m_bInitialized
;
227 RequestRef
rRequest(new Request());
228 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_FOLDER_PICKER
);
229 if ( ! m_aAsyncExecute
.isRunning())
230 m_aAsyncExecute
.create();
231 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
233 osl::MutexGuard
aGuard(m_aMutex
);
234 m_bInitialized
= true;
239 css::uno::Sequence
< css::uno::Any
> aInitArguments(1);
240 aInitArguments
[0] <<= css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
;
241 initialize(aInitArguments
);
246 ::sal_Int16 SAL_CALL
VistaFilePicker::execute()
250 RequestRef
rRequest(new Request());
251 rRequest
->setRequest (VistaFilePickerImpl::E_SHOW_DIALOG_MODAL
);
253 // if we want to show a modal window, the calling thread needs to process messages
254 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::PROCESS_MESSAGES
);
256 const bool bOK
= rRequest
->getArgumentOrDefault(PROP_DIALOG_SHOW_RESULT
, false );
257 m_lLastFiles
= rRequest
->getArgumentOrDefault(PROP_SELECTED_FILES
, css::uno::Sequence
< OUString
>());
259 ::sal_Int16 nResult
= css::ui::dialogs::ExecutableDialogResults::CANCEL
;
261 nResult
= css::ui::dialogs::ExecutableDialogResults::OK
;
267 void SAL_CALL
VistaFilePicker::setValue( ::sal_Int16 nControlId
,
268 ::sal_Int16 nControlAction
,
269 const css::uno::Any
& aValue
)
271 RequestRef
rRequest(new Request());
272 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CONTROL_VALUE
);
273 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
274 rRequest
->setArgument(PROP_CONTROL_ACTION
, nControlAction
);
275 rRequest
->setArgument(PROP_CONTROL_VALUE
, aValue
);
277 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
280 css::uno::Any SAL_CALL
VistaFilePicker::getValue(::sal_Int16 nControlId
,
281 ::sal_Int16 nControlAction
)
283 RequestRef
rRequest(new Request());
284 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CONTROL_VALUE
);
285 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
286 rRequest
->setArgument(PROP_CONTROL_ACTION
, nControlAction
);
288 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
289 return rRequest
->getValue(PROP_CONTROL_VALUE
);
292 void SAL_CALL
VistaFilePicker::enableControl(::sal_Int16 nControlId
,
295 RequestRef
rRequest(new Request());
296 rRequest
->setRequest (VistaFilePickerImpl::E_ENABLE_CONTROL
);
297 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
298 rRequest
->setArgument(PROP_CONTROL_ENABLE
, bEnable
);
300 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
303 void SAL_CALL
VistaFilePicker::setLabel( ::sal_Int16 nControlId
,
304 const OUString
& sLabel
)
306 RequestRef
rRequest(new Request());
307 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CONTROL_LABEL
);
308 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
309 rRequest
->setArgument(PROP_CONTROL_LABEL
, sLabel
);
311 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
314 OUString SAL_CALL
VistaFilePicker::getLabel(::sal_Int16 nControlId
)
316 RequestRef
rRequest(new Request());
317 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CONTROL_LABEL
);
318 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
320 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
321 const OUString sLabel
= rRequest
->getArgumentOrDefault(PROP_CONTROL_LABEL
, OUString());
325 css::uno::Sequence
< ::sal_Int16
> SAL_CALL
VistaFilePicker::getSupportedImageFormats()
327 return css::uno::Sequence
< sal_Int16
>();
330 sal_Int32 SAL_CALL
VistaFilePicker::getTargetColorDepth()
335 sal_Int32 SAL_CALL
VistaFilePicker::getAvailableWidth()
340 sal_Int32 SAL_CALL
VistaFilePicker::getAvailableHeight()
345 void SAL_CALL
VistaFilePicker::setImage( sal_Int16
/*nImageFormat*/,
346 const css::uno::Any
& /*aImage */)
350 sal_Bool SAL_CALL
VistaFilePicker::setShowState(sal_Bool
/*bShowState*/)
355 sal_Bool SAL_CALL
VistaFilePicker::getShowState()
360 void SAL_CALL
VistaFilePicker::initialize(const css::uno::Sequence
< css::uno::Any
>& lArguments
)
362 if (lArguments
.getLength() < 1)
363 throw css::lang::IllegalArgumentException(
364 "XInitialization::initialize() called without arguments.",
365 static_cast< css::ui::dialogs::XFilePicker2
* >( this ),
368 sal_Int32 nTemplate
= -1;
369 lArguments
[0] >>= nTemplate
;
371 bool bFileOpenDialog
= true;
372 ::sal_Int32 nFeatures
= 0;
376 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
:
378 bFileOpenDialog
= true;
382 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE
:
384 bFileOpenDialog
= false;
388 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD
:
390 bFileOpenDialog
= false;
391 nFeatures
|= FEATURE_AUTOEXTENSION
;
392 nFeatures
|= FEATURE_PASSWORD
;
393 nFeatures
|= FEATURE_GPGPASSWORD
;
397 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS
:
399 bFileOpenDialog
= false;
400 nFeatures
|= FEATURE_AUTOEXTENSION
;
401 nFeatures
|= FEATURE_PASSWORD
;
402 nFeatures
|= FEATURE_FILTEROPTIONS
;
403 nFeatures
|= FEATURE_GPGPASSWORD
;
407 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION
:
409 bFileOpenDialog
= false;
410 nFeatures
|= FEATURE_AUTOEXTENSION
;
411 nFeatures
|= FEATURE_SELECTION
;
415 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE
:
417 bFileOpenDialog
= false;
418 nFeatures
|= FEATURE_AUTOEXTENSION
;
419 nFeatures
|= FEATURE_TEMPLATE
;
423 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE
:
425 bFileOpenDialog
= true;
426 nFeatures
|= FEATURE_LINK
;
427 nFeatures
|= FEATURE_PREVIEW
;
428 nFeatures
|= FEATURE_IMAGETEMPLATE
;
432 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR
:
434 bFileOpenDialog
= true;
435 nFeatures
|= FEATURE_LINK
;
436 nFeatures
|= FEATURE_PREVIEW
;
437 nFeatures
|= FEATURE_IMAGEANCHOR
;
441 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY
:
443 bFileOpenDialog
= true;
444 nFeatures
|= FEATURE_PLAY
;
448 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY
:
450 bFileOpenDialog
= true;
451 nFeatures
|= FEATURE_LINK
;
452 nFeatures
|= FEATURE_PLAY
;
456 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION
:
458 bFileOpenDialog
= true;
459 nFeatures
|= FEATURE_READONLY
;
460 nFeatures
|= FEATURE_VERSION
;
464 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
:
466 bFileOpenDialog
= true;
467 nFeatures
|= FEATURE_LINK
;
468 nFeatures
|= FEATURE_PREVIEW
;
472 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
:
474 bFileOpenDialog
= false;
475 nFeatures
|= FEATURE_AUTOEXTENSION
;
479 case css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW
:
481 bFileOpenDialog
= true;
482 nFeatures
|= FEATURE_PREVIEW
;
486 css::uno::Reference
<css::awt::XWindow
> xParentWindow
;
487 if(lArguments
.getLength() > 1)
489 lArguments
[1] >>= xParentWindow
;
491 RequestRef
rRequest(new Request());
493 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_OPEN_DIALOG
);
495 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_SAVE_DIALOG
);
496 rRequest
->setArgument(PROP_FEATURES
, nFeatures
);
497 rRequest
->setArgument(PROP_TEMPLATE_DESCR
, nTemplate
);
498 if(xParentWindow
.is())
499 rRequest
->setArgument(PROP_PARENT_WINDOW
, xParentWindow
);
500 if ( ! m_aAsyncExecute
.isRunning())
501 m_aAsyncExecute
.create();
502 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
505 osl::MutexGuard
aGuard(m_aMutex
);
506 m_bInitialized
= true;
510 void SAL_CALL
VistaFilePicker::cancel()
514 OUString SAL_CALL
VistaFilePicker::getDirectory()
517 css::uno::Sequence
< OUString
> aFileSeq
= getSelectedFiles();
518 assert(aFileSeq
.getLength() <= 1);
519 return aFileSeq
.getLength() ? aFileSeq
[0] : OUString();
522 void SAL_CALL
VistaFilePicker::setDescription( const OUString
& aDescription
)
524 setTitle(aDescription
);
529 OUString SAL_CALL
VistaFilePicker::getImplementationName()
532 return FOLDER_PICKER_IMPL_NAME
;
534 return FILE_PICKER_IMPL_NAME
;
537 sal_Bool SAL_CALL
VistaFilePicker::supportsService(const OUString
& sServiceName
)
539 return cppu::supportsService(this, sServiceName
);
542 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getSupportedServiceNames()
544 return VistaFilePicker_getSupportedServiceNames();
549 } // namespace fpicker
551 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */