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 bool bChanged
= officecfg::Office::Common::Path::Info::WorkPathChanged::get(
173 comphelper::getComponentContext(m_xSMGR
));
176 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(
177 comphelper::ConfigurationChanges::create(
178 comphelper::getComponentContext(m_xSMGR
)));
179 officecfg::Office::Common::Path::Info::WorkPathChanged::set(
184 RequestRef
rRequest(new Request());
185 rRequest
->setRequest (VistaFilePickerImpl::E_SET_DIRECTORY
);
186 rRequest
->setArgument(PROP_DIRECTORY
, sDirectory
);
187 rRequest
->setArgument(PROP_FORCE
, bChanged
);
189 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
192 OUString SAL_CALL
VistaFilePicker::getDisplayDirectory()
196 RequestRef
rRequest(new Request());
197 rRequest
->setRequest (VistaFilePickerImpl::E_GET_DIRECTORY
);
198 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
199 const OUString sDirectory
= rRequest
->getArgumentOrDefault(PROP_DIRECTORY
, OUString());
204 // @deprecated can't be supported any longer ... see IDL description for further details
205 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getFiles()
207 css::uno::Sequence
< OUString
> lFiles
= getSelectedFiles();
208 // multiselection doesn't really work
209 // so just retrieve the first url
210 if (lFiles
.getLength() > 1)
212 m_lLastFiles
= lFiles
;
216 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getSelectedFiles()
218 RequestRef
rRequest(new Request());
219 rRequest
->setRequest (VistaFilePickerImpl::E_GET_SELECTED_FILES
);
221 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
223 const css::uno::Sequence
< OUString
> lFiles
= rRequest
->getArgumentOrDefault(PROP_SELECTED_FILES
, css::uno::Sequence
< OUString
>());
224 m_lLastFiles
= lFiles
;
228 void VistaFilePicker::ensureInit()
230 bool bInitialized(false);
232 osl::MutexGuard
aGuard(m_aMutex
);
233 bInitialized
= m_bInitialized
;
240 RequestRef
rRequest(new Request());
241 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_FOLDER_PICKER
);
242 if ( ! m_aAsyncExecute
.isRunning())
243 m_aAsyncExecute
.create();
244 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
246 osl::MutexGuard
aGuard(m_aMutex
);
247 m_bInitialized
= true;
252 css::uno::Sequence
< css::uno::Any
> aInitArguments(1);
253 aInitArguments
[0] <<= css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
;
254 initialize(aInitArguments
);
259 ::sal_Int16 SAL_CALL
VistaFilePicker::execute()
263 RequestRef
rRequest(new Request());
264 rRequest
->setRequest (VistaFilePickerImpl::E_SHOW_DIALOG_MODAL
);
266 // if we want to show a modal window, the calling thread needs to process messages
267 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::PROCESS_MESSAGES
);
269 const bool bOK
= rRequest
->getArgumentOrDefault(PROP_DIALOG_SHOW_RESULT
, false );
270 m_lLastFiles
= rRequest
->getArgumentOrDefault(PROP_SELECTED_FILES
, css::uno::Sequence
< OUString
>());
272 ::sal_Int16 nResult
= css::ui::dialogs::ExecutableDialogResults::CANCEL
;
274 nResult
= css::ui::dialogs::ExecutableDialogResults::OK
;
280 void SAL_CALL
VistaFilePicker::setValue( ::sal_Int16 nControlId
,
281 ::sal_Int16 nControlAction
,
282 const css::uno::Any
& aValue
)
284 RequestRef
rRequest(new Request());
285 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CONTROL_VALUE
);
286 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
287 rRequest
->setArgument(PROP_CONTROL_ACTION
, nControlAction
);
288 rRequest
->setArgument(PROP_CONTROL_VALUE
, aValue
);
290 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
293 css::uno::Any SAL_CALL
VistaFilePicker::getValue(::sal_Int16 nControlId
,
294 ::sal_Int16 nControlAction
)
296 RequestRef
rRequest(new Request());
297 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CONTROL_VALUE
);
298 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
299 rRequest
->setArgument(PROP_CONTROL_ACTION
, nControlAction
);
301 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
302 return rRequest
->getValue(PROP_CONTROL_VALUE
);
305 void SAL_CALL
VistaFilePicker::enableControl(::sal_Int16 nControlId
,
308 RequestRef
rRequest(new Request());
309 rRequest
->setRequest (VistaFilePickerImpl::E_ENABLE_CONTROL
);
310 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
311 rRequest
->setArgument(PROP_CONTROL_ENABLE
, bEnable
);
313 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
316 void SAL_CALL
VistaFilePicker::setLabel( ::sal_Int16 nControlId
,
317 const OUString
& sLabel
)
319 RequestRef
rRequest(new Request());
320 rRequest
->setRequest (VistaFilePickerImpl::E_SET_CONTROL_LABEL
);
321 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
322 rRequest
->setArgument(PROP_CONTROL_LABEL
, sLabel
);
324 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
327 OUString SAL_CALL
VistaFilePicker::getLabel(::sal_Int16 nControlId
)
329 RequestRef
rRequest(new Request());
330 rRequest
->setRequest (VistaFilePickerImpl::E_GET_CONTROL_LABEL
);
331 rRequest
->setArgument(PROP_CONTROL_ID
, nControlId
);
333 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::BLOCKED
);
334 const OUString sLabel
= rRequest
->getArgumentOrDefault(PROP_CONTROL_LABEL
, OUString());
338 css::uno::Sequence
< ::sal_Int16
> SAL_CALL
VistaFilePicker::getSupportedImageFormats()
340 return css::uno::Sequence
< sal_Int16
>();
343 sal_Int32 SAL_CALL
VistaFilePicker::getTargetColorDepth()
348 sal_Int32 SAL_CALL
VistaFilePicker::getAvailableWidth()
353 sal_Int32 SAL_CALL
VistaFilePicker::getAvailableHeight()
358 void SAL_CALL
VistaFilePicker::setImage( sal_Int16
/*nImageFormat*/,
359 const css::uno::Any
& /*aImage */)
363 sal_Bool SAL_CALL
VistaFilePicker::setShowState(sal_Bool
/*bShowState*/)
368 sal_Bool SAL_CALL
VistaFilePicker::getShowState()
373 void SAL_CALL
VistaFilePicker::initialize(const css::uno::Sequence
< css::uno::Any
>& lArguments
)
375 if (lArguments
.getLength() < 1)
376 throw css::lang::IllegalArgumentException(
377 "XInitialization::initialize() called without arguments.",
378 static_cast< css::ui::dialogs::XFilePicker2
* >( this ),
381 sal_Int32 nTemplate
= -1;
382 lArguments
[0] >>= nTemplate
;
384 bool bFileOpenDialog
= true;
385 ::sal_Int32 nFeatures
= 0;
389 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
:
391 bFileOpenDialog
= true;
395 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE
:
397 bFileOpenDialog
= false;
401 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD
:
403 bFileOpenDialog
= false;
404 nFeatures
|= FEATURE_AUTOEXTENSION
;
405 nFeatures
|= FEATURE_PASSWORD
;
406 nFeatures
|= FEATURE_GPGPASSWORD
;
410 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS
:
412 bFileOpenDialog
= false;
413 nFeatures
|= FEATURE_AUTOEXTENSION
;
414 nFeatures
|= FEATURE_PASSWORD
;
415 nFeatures
|= FEATURE_FILTEROPTIONS
;
416 nFeatures
|= FEATURE_GPGPASSWORD
;
420 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION
:
422 bFileOpenDialog
= false;
423 nFeatures
|= FEATURE_AUTOEXTENSION
;
424 nFeatures
|= FEATURE_SELECTION
;
428 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE
:
430 bFileOpenDialog
= false;
431 nFeatures
|= FEATURE_AUTOEXTENSION
;
432 nFeatures
|= FEATURE_TEMPLATE
;
436 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE
:
438 bFileOpenDialog
= true;
439 nFeatures
|= FEATURE_LINK
;
440 nFeatures
|= FEATURE_PREVIEW
;
441 nFeatures
|= FEATURE_IMAGETEMPLATE
;
445 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR
:
447 bFileOpenDialog
= true;
448 nFeatures
|= FEATURE_LINK
;
449 nFeatures
|= FEATURE_PREVIEW
;
450 nFeatures
|= FEATURE_IMAGEANCHOR
;
454 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY
:
456 bFileOpenDialog
= true;
457 nFeatures
|= FEATURE_PLAY
;
461 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY
:
463 bFileOpenDialog
= true;
464 nFeatures
|= FEATURE_LINK
;
465 nFeatures
|= FEATURE_PLAY
;
469 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION
:
471 bFileOpenDialog
= true;
472 nFeatures
|= FEATURE_READONLY
;
473 nFeatures
|= FEATURE_VERSION
;
477 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW
:
479 bFileOpenDialog
= true;
480 nFeatures
|= FEATURE_LINK
;
481 nFeatures
|= FEATURE_PREVIEW
;
485 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
:
487 bFileOpenDialog
= false;
488 nFeatures
|= FEATURE_AUTOEXTENSION
;
492 case css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW
:
494 bFileOpenDialog
= true;
495 nFeatures
|= FEATURE_PREVIEW
;
499 css::uno::Reference
<css::awt::XWindow
> xParentWindow
;
500 if(lArguments
.getLength() > 1)
502 lArguments
[1] >>= xParentWindow
;
504 RequestRef
rRequest(new Request());
506 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_OPEN_DIALOG
);
508 rRequest
->setRequest (VistaFilePickerImpl::E_CREATE_SAVE_DIALOG
);
509 rRequest
->setArgument(PROP_FEATURES
, nFeatures
);
510 rRequest
->setArgument(PROP_TEMPLATE_DESCR
, nTemplate
);
511 if(xParentWindow
.is())
512 rRequest
->setArgument(PROP_PARENT_WINDOW
, xParentWindow
);
513 if ( ! m_aAsyncExecute
.isRunning())
514 m_aAsyncExecute
.create();
515 m_aAsyncExecute
.triggerRequestThreadAware(rRequest
, AsyncRequests::NON_BLOCKED
);
518 osl::MutexGuard
aGuard(m_aMutex
);
519 m_bInitialized
= true;
523 void SAL_CALL
VistaFilePicker::cancel()
527 OUString SAL_CALL
VistaFilePicker::getDirectory()
530 css::uno::Sequence
< OUString
> aFileSeq
= getSelectedFiles();
531 assert(aFileSeq
.getLength() <= 1);
532 return aFileSeq
.getLength() ? aFileSeq
[0] : OUString();
535 void SAL_CALL
VistaFilePicker::setDescription( const OUString
& aDescription
)
537 setTitle(aDescription
);
542 OUString SAL_CALL
VistaFilePicker::getImplementationName()
545 return FOLDER_PICKER_IMPL_NAME
;
547 return FILE_PICKER_IMPL_NAME
;
550 sal_Bool SAL_CALL
VistaFilePicker::supportsService(const OUString
& sServiceName
)
552 return cppu::supportsService(this, sServiceName
);
555 css::uno::Sequence
< OUString
> SAL_CALL
VistaFilePicker::getSupportedServiceNames()
557 return VistaFilePicker_getSupportedServiceNames();
562 } // namespace fpicker
564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */