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 "../misc/WinImplHelper.hxx"
25 #include <com/sun/star/awt/XWindow.hpp>
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
28 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
29 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
30 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
32 #include <cppuhelper/interfacecontainer.h>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <osl/mutex.hxx>
36 #include <osl/file.hxx>
37 #include <officecfg/Office/Common.hxx>
47 css::uno::Sequence
< OUString
> VistaFilePicker_getSupportedServiceNames()
49 css::uno::Sequence
< OUString
> aRet(2);
50 aRet
[0] = "com.sun.star.ui.dialogs.FilePicker";
51 aRet
[1] = "com.sun.star.ui.dialogs.SystemFilePicker";
56 VistaFilePicker::VistaFilePicker(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
57 : TVistaFilePickerBase (m_aMutex
)
59 , m_rDialog (new VistaFilePickerImpl())
60 , m_aAsyncExecute (m_rDialog
)
61 , m_nFilePickerThreadId (0 )
62 , m_bInitialized (false )
66 VistaFilePicker::~VistaFilePicker()
70 void SAL_CALL
VistaFilePicker::addFilePickerListener(const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
72 RequestRef
rRequest(new Request());
73 rRequest
->setRequest (VistaFilePickerImpl::E_ADD_PICKER_LISTENER
);
74 rRequest
->setArgument(PROP_PICKER_LISTENER
, xListener
);
76 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
79 void SAL_CALL
VistaFilePicker::removeFilePickerListener(const css::uno::Reference
< css::ui::dialogs::XFilePickerListener
>& xListener
)
81 RequestRef
rRequest(new Request());
82 rRequest
->setRequest (VistaFilePickerImpl::E_REMOVE_PICKER_LISTENER
);
83 rRequest
->setArgument(PROP_PICKER_LISTENER
, xListener
);
85 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
88 void VistaFilePicker::disposing(const css::lang::EventObject
& /*aEvent*/)
92 void SAL_CALL
VistaFilePicker::setMultiSelectionMode(sal_Bool bMode
)
96 RequestRef
rRequest(new Request());
97 rRequest
->setRequest (VistaFilePickerImpl::E_SET_MULTISELECTION_MODE
);
98 rRequest
->setArgument(PROP_MULTISELECTION_MODE
, bMode
);
100 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
103 void SAL_CALL
VistaFilePicker::setTitle(const OUString
& sTitle
)
107 RequestRef
rRequest(new Request());
108 rRequest
->setRequest (VistaFilePickerImpl::E_SET_TITLE
);
109 rRequest
->setArgument(PROP_TITLE
, sTitle
);
111 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
114 void SAL_CALL
VistaFilePicker::appendFilter(const OUString
& sTitle
,
115 const OUString
& sFilter
)
117 RequestRef
rRequest(new Request());
118 rRequest
->setRequest (VistaFilePickerImpl::E_APPEND_FILTER
);
119 rRequest
->setArgument(PROP_FILTER_TITLE
, sTitle
);
120 rRequest
->setArgument(PROP_FILTER_VALUE
, sFilter
);
122 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
125 void SAL_CALL
VistaFilePicker::setCurrentFilter(const OUString
& sTitle
)
127 RequestRef
rRequest(new Request());
128 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CURRENT_FILTER
);
129 rRequest
->setArgument(PROP_FILTER_TITLE
, sTitle
);
131 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
134 OUString SAL_CALL
VistaFilePicker::getCurrentFilter()
136 RequestRef
rRequest(new Request());
137 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CURRENT_FILTER
);
139 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
141 const OUString sTitle
= rRequest
->getArgumentOrDefault(PROP_FILTER_TITLE
, OUString());
145 void SAL_CALL
VistaFilePicker::appendFilterGroup(const OUString
& /*sGroupTitle*/,
146 const css::uno::Sequence
< css::beans::StringPair
>& rFilters
)
148 RequestRef
rRequest(new Request());
149 rRequest
->setRequest (VistaFilePickerImpl::E_APPEND_FILTERGROUP
);
150 rRequest
->setArgument(PROP_FILTER_GROUP
, rFilters
);
152 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
155 void SAL_CALL
VistaFilePicker::setDefaultName(const OUString
& sName
)
159 RequestRef
rRequest(new Request());
160 rRequest
->setRequest (VistaFilePickerImpl::E_SET_DEFAULT_NAME
);
161 rRequest
->setArgument(PROP_FILENAME
, sName
);
163 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
166 void SAL_CALL
VistaFilePicker::setDisplayDirectory(const OUString
& sDirectory
)
170 bool bChanged
= officecfg::Office::Common::Path::Info::WorkPathChanged::get(
171 comphelper::getComponentContext(m_xSMGR
));
174 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(
175 comphelper::ConfigurationChanges::create(
176 comphelper::getComponentContext(m_xSMGR
)));
177 officecfg::Office::Common::Path::Info::WorkPathChanged::set(
182 RequestRef
rRequest(new Request());
183 rRequest
->setRequest (VistaFilePickerImpl::E_SET_DIRECTORY
);
184 rRequest
->setArgument(PROP_DIRECTORY
, sDirectory
);
185 rRequest
->setArgument(PROP_FORCE
, bChanged
);
187 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
190 OUString SAL_CALL
VistaFilePicker::getDisplayDirectory()
194 RequestRef
rRequest(new Request());
195 rRequest
->setRequest (VistaFilePickerImpl::E_GET_DIRECTORY
);
196 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
197 const OUString sDirectory
= rRequest
->getArgumentOrDefault(PROP_DIRECTORY
, OUString());
202 // @deprecated can't be supported any longer ... see IDL description for further details
203 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getFiles()
205 css::uno::Sequence
< OUString
> lFiles
= getSelectedFiles();
206 // multiselection doesn't really work
207 // so just retrieve the first url
208 if (lFiles
.getLength() > 1)
210 m_lLastFiles
= lFiles
;
214 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getSelectedFiles()
216 RequestRef
rRequest(new Request());
217 rRequest
->setRequest (VistaFilePickerImpl::E_GET_SELECTED_FILES
);
219 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
221 const css::uno::Sequence
< OUString
> lFiles
= rRequest
->getArgumentOrDefault(PROP_SELECTED_FILES
, css::uno::Sequence
< OUString
>());
222 m_lLastFiles
= lFiles
;
226 void VistaFilePicker::ensureInit()
228 bool bInitialized(false);
230 osl::MutexGuard
aGuard(m_aMutex
);
231 bInitialized
= m_bInitialized
;
236 css::uno::Sequence
< css::uno::Any
> aInitArguments(1);
237 aInitArguments
[0] <<= css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
;
238 initialize(aInitArguments
);
242 ::sal_Int16 SAL_CALL
VistaFilePicker::execute()
246 RequestRef
rRequest(new Request());
247 rRequest
->setRequest (VistaFilePickerImpl::E_SHOW_DIALOG_MODAL
);
249 // if we want to show a modal window, the calling thread needs to process messages
250 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::PROCESS_MESSAGES
);
252 const bool bOK
= rRequest
->getArgumentOrDefault(PROP_DIALOG_SHOW_RESULT
, false );
253 m_lLastFiles
= rRequest
->getArgumentOrDefault(PROP_SELECTED_FILES
, css::uno::Sequence
< OUString
>());
255 ::sal_Int16 nResult
= css::ui::dialogs::ExecutableDialogResults::CANCEL
;
257 nResult
= css::ui::dialogs::ExecutableDialogResults::OK
;
263 void SAL_CALL
VistaFilePicker::setValue( ::sal_Int16 nControlId
,
264 ::sal_Int16 nControlAction
,
265 const css::uno::Any
& aValue
)
267 RequestRef
rRequest(new Request());
268 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CONTROL_VALUE
);
269 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
270 rRequest
->setArgument(PROP_CONTROL_ACTION
, nControlAction
);
271 rRequest
->setArgument(PROP_CONTROL_VALUE
, aValue
);
273 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
276 css::uno::Any SAL_CALL
VistaFilePicker::getValue(::sal_Int16 nControlId
,
277 ::sal_Int16 nControlAction
)
279 RequestRef
rRequest(new Request());
280 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CONTROL_VALUE
);
281 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
282 rRequest
->setArgument(PROP_CONTROL_ACTION
, nControlAction
);
284 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
285 return rRequest
->getValue(PROP_CONTROL_VALUE
);
288 void SAL_CALL
VistaFilePicker::enableControl(::sal_Int16 nControlId
,
291 RequestRef
rRequest(new Request());
292 rRequest
->setRequest (VistaFilePickerImpl::E_ENABLE_CONTROL
);
293 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
294 rRequest
->setArgument(PROP_CONTROL_ENABLE
, bEnable
);
296 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
299 void SAL_CALL
VistaFilePicker::setLabel( ::sal_Int16 nControlId
,
300 const OUString
& sLabel
)
302 RequestRef
rRequest(new Request());
303 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CONTROL_LABEL
);
304 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
305 rRequest
->setArgument(PROP_CONTROL_LABEL
, sLabel
);
307 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
310 OUString SAL_CALL
VistaFilePicker::getLabel(::sal_Int16 nControlId
)
312 RequestRef
rRequest(new Request());
313 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CONTROL_LABEL
);
314 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
316 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
317 const OUString sLabel
= rRequest
->getArgumentOrDefault(PROP_CONTROL_LABEL
, OUString());
321 css::uno::Sequence
< ::sal_Int16
> SAL_CALL
VistaFilePicker::getSupportedImageFormats()
323 return css::uno::Sequence
< sal_Int16
>();
326 sal_Int32 SAL_CALL
VistaFilePicker::getTargetColorDepth()
331 sal_Int32 SAL_CALL
VistaFilePicker::getAvailableWidth()
336 sal_Int32 SAL_CALL
VistaFilePicker::getAvailableHeight()
341 void SAL_CALL
VistaFilePicker::setImage( sal_Int16
/*nImageFormat*/,
342 const css::uno::Any
& /*aImage */)
346 sal_Bool SAL_CALL
VistaFilePicker::setShowState(sal_Bool
/*bShowState*/)
351 sal_Bool SAL_CALL
VistaFilePicker::getShowState()
356 void SAL_CALL
VistaFilePicker::initialize(const css::uno::Sequence
< css::uno::Any
>& lArguments
)
358 if (lArguments
.getLength() < 1)
359 throw css::lang::IllegalArgumentException(
360 "XInitialization::initialize() called without arguments.",
361 static_cast< css::ui::dialogs::XFilePicker2
* >( this ),
364 sal_Int32 nTemplate
= -1;
365 lArguments
[0] >>= nTemplate
;
367 bool bFileOpenDialog
= true;
368 ::sal_Int32 nFeatures
= 0;
372 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
:
374 bFileOpenDialog
= true;
378 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE
:
380 bFileOpenDialog
= false;
384 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD
:
386 bFileOpenDialog
= false;
387 nFeatures
|= FEATURE_AUTOEXTENSION
;
388 nFeatures
|= FEATURE_PASSWORD
;
389 nFeatures
|= FEATURE_GPGPASSWORD
;
393 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS
:
395 bFileOpenDialog
= false;
396 nFeatures
|= FEATURE_AUTOEXTENSION
;
397 nFeatures
|= FEATURE_PASSWORD
;
398 nFeatures
|= FEATURE_FILTEROPTIONS
;
399 nFeatures
|= FEATURE_GPGPASSWORD
;
403 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION
:
405 bFileOpenDialog
= false;
406 nFeatures
|= FEATURE_AUTOEXTENSION
;
407 nFeatures
|= FEATURE_SELECTION
;
411 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE
:
413 bFileOpenDialog
= false;
414 nFeatures
|= FEATURE_AUTOEXTENSION
;
415 nFeatures
|= FEATURE_TEMPLATE
;
419 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE
:
421 bFileOpenDialog
= true;
422 nFeatures
|= FEATURE_LINK
;
423 nFeatures
|= FEATURE_PREVIEW
;
424 nFeatures
|= FEATURE_IMAGETEMPLATE
;
428 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR
:
430 bFileOpenDialog
= true;
431 nFeatures
|= FEATURE_LINK
;
432 nFeatures
|= FEATURE_PREVIEW
;
433 nFeatures
|= FEATURE_IMAGEANCHOR
;
437 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY
:
439 bFileOpenDialog
= true;
440 nFeatures
|= FEATURE_PLAY
;
444 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY
:
446 bFileOpenDialog
= true;
447 nFeatures
|= FEATURE_LINK
;
448 nFeatures
|= FEATURE_PLAY
;
452 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION
:
454 bFileOpenDialog
= true;
455 nFeatures
|= FEATURE_READONLY
;
456 nFeatures
|= FEATURE_VERSION
;
460 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
:
462 bFileOpenDialog
= true;
463 nFeatures
|= FEATURE_LINK
;
464 nFeatures
|= FEATURE_PREVIEW
;
468 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
:
470 bFileOpenDialog
= false;
471 nFeatures
|= FEATURE_AUTOEXTENSION
;
475 case css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW
:
477 bFileOpenDialog
= true;
478 nFeatures
|= FEATURE_PREVIEW
;
482 css::uno::Reference
<css::awt::XWindow
> xParentWindow
;
483 if(lArguments
.getLength() > 1)
485 lArguments
[1] >>= xParentWindow
;
487 RequestRef
rRequest(new Request());
489 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_OPEN_DIALOG
);
491 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_SAVE_DIALOG
);
492 rRequest
->setArgument(PROP_FEATURES
, nFeatures
);
493 rRequest
->setArgument(PROP_TEMPLATE_DESCR
, nTemplate
);
494 if(xParentWindow
.is())
495 rRequest
->setArgument(PROP_PARENT_WINDOW
, xParentWindow
);
496 if ( ! m_aAsyncExecute
.isRunning())
497 m_aAsyncExecute
.create();
498 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
501 osl::MutexGuard
aGuard(m_aMutex
);
502 m_bInitialized
= true;
506 void SAL_CALL
VistaFilePicker::cancel()
512 OUString SAL_CALL
VistaFilePicker::getImplementationName()
514 return OUString("com.sun.star.comp.fpicker.VistaFileDialog");
517 sal_Bool SAL_CALL
VistaFilePicker::supportsService(const OUString
& sServiceName
)
519 return cppu::supportsService(this, sServiceName
);
522 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getSupportedServiceNames()
524 return VistaFilePicker_getSupportedServiceNames();
529 } // namespace fpicker
531 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */