Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / fpicker / source / win32 / VistaFilePicker.cxx
bloba7ded90f6d601cc0e3e804deacefd4e9a4a13ea2
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 "VistaFilePicker.hxx"
22 #include "WinImplHelper.hxx"
23 #include "FPServiceInfo.hxx"
24 #include "shared.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>
40 #include <shlobj.h>
42 namespace fpicker{
43 namespace win32{
44 namespace vista{
46 namespace
48 css::uno::Sequence< OUString > VistaFilePicker_getSupportedServiceNames()
50 return {
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 )
59 , m_xSMGR (xSMGR )
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)
96 ensureInit();
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)
107 ensureInit();
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());
144 return sTitle;
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 )
159 ensureInit();
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)
170 ensureInit();
172 bool bChanged = officecfg::Office::Common::Path::Info::WorkPathChanged::get(
173 comphelper::getComponentContext(m_xSMGR));
174 if (bChanged )
176 std::shared_ptr< comphelper::ConfigurationChanges > batch(
177 comphelper::ConfigurationChanges::create(
178 comphelper::getComponentContext(m_xSMGR)));
179 officecfg::Office::Common::Path::Info::WorkPathChanged::set(
180 false, batch);
181 batch->commit();
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()
194 ensureInit();
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());
201 return sDirectory;
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)
211 lFiles.realloc(1);
212 m_lLastFiles = lFiles;
213 return 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;
225 return lFiles;
228 void VistaFilePicker::ensureInit()
230 bool bInitialized(false);
232 osl::MutexGuard aGuard(m_aMutex);
233 bInitialized = m_bInitialized;
236 if ( !bInitialized )
238 if (m_bFolderPicker)
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;
250 else
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()
261 ensureInit();
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;
273 if (bOK)
274 nResult = css::ui::dialogs::ExecutableDialogResults::OK;
275 return nResult;
278 // XFilePicker
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,
306 sal_Bool bEnable )
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());
335 return sLabel;
338 css::uno::Sequence< ::sal_Int16 > SAL_CALL VistaFilePicker::getSupportedImageFormats()
340 return css::uno::Sequence< sal_Int16 >();
343 sal_Int32 SAL_CALL VistaFilePicker::getTargetColorDepth()
345 return 0;
348 sal_Int32 SAL_CALL VistaFilePicker::getAvailableWidth()
350 return 0;
353 sal_Int32 SAL_CALL VistaFilePicker::getAvailableHeight()
355 return 0;
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*/)
365 return false;
368 sal_Bool SAL_CALL VistaFilePicker::getShowState()
370 return false;
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;
387 switch(nTemplate)
389 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE :
391 bFileOpenDialog = true;
393 break;
395 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE :
397 bFileOpenDialog = false;
399 break;
401 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD :
403 bFileOpenDialog = false;
404 nFeatures |= FEATURE_AUTOEXTENSION;
405 nFeatures |= FEATURE_PASSWORD;
406 nFeatures |= FEATURE_GPGPASSWORD;
408 break;
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;
418 break;
420 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION :
422 bFileOpenDialog = false;
423 nFeatures |= FEATURE_AUTOEXTENSION;
424 nFeatures |= FEATURE_SELECTION;
426 break;
428 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE :
430 bFileOpenDialog = false;
431 nFeatures |= FEATURE_AUTOEXTENSION;
432 nFeatures |= FEATURE_TEMPLATE;
434 break;
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;
443 break;
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;
452 break;
454 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY :
456 bFileOpenDialog = true;
457 nFeatures |= FEATURE_PLAY;
459 break;
461 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY :
463 bFileOpenDialog = true;
464 nFeatures |= FEATURE_LINK;
465 nFeatures |= FEATURE_PLAY;
467 break;
469 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION :
471 bFileOpenDialog = true;
472 nFeatures |= FEATURE_READONLY;
473 nFeatures |= FEATURE_VERSION;
475 break;
477 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW :
479 bFileOpenDialog = true;
480 nFeatures |= FEATURE_LINK;
481 nFeatures |= FEATURE_PREVIEW;
483 break;
485 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION :
487 bFileOpenDialog = false;
488 nFeatures |= FEATURE_AUTOEXTENSION;
490 break;
492 case css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW :
494 bFileOpenDialog = true;
495 nFeatures |= FEATURE_PREVIEW;
497 break;
499 css::uno::Reference<css::awt::XWindow> xParentWindow;
500 if(lArguments.getLength() > 1)
502 lArguments[1] >>= xParentWindow;
504 RequestRef rRequest(new Request());
505 if (bFileOpenDialog)
506 rRequest->setRequest (VistaFilePickerImpl::E_CREATE_OPEN_DIALOG);
507 else
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()
529 ensureInit();
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);
540 // XServiceInfo
542 OUString SAL_CALL VistaFilePicker::getImplementationName()
544 if (m_bFolderPicker)
545 return FOLDER_PICKER_IMPL_NAME;
546 else
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();
560 } // namespace vista
561 } // namespace win32
562 } // namespace fpicker
564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */