LibreOffice Module fpicker (master)  1
VistaFilePickerImpl.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "VistaFilePickerImpl.hxx"
21 
22 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
23 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
24 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
25 #include <com/sun/star/beans/StringPair.hpp>
26 #include <com/sun/star/awt/XWindow.hpp>
27 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
28 #include <com/sun/star/lang/SystemDependent.hpp>
29 #include <comphelper/sequence.hxx>
30 #include <fpicker/strings.hrc>
31 #include <fpsofficeResMgr.hxx>
32 #include <osl/file.hxx>
33 #include <osl/mutex.hxx>
34 #include <rtl/process.h>
36 #include "WinImplHelper.hxx"
37 
38 #include <shlguid.h>
39 #include <shlobj.h>
40 
41 static bool is_current_process_window(HWND hwnd)
42 {
43  DWORD pid;
44  GetWindowThreadProcessId(hwnd, &pid);
45  return (pid == GetCurrentProcessId());
46 }
47 
48 static HWND choose_parent_window()
49 {
50  HWND hwnd_parent = GetForegroundWindow();
51  if (!is_current_process_window(hwnd_parent))
52  hwnd_parent = GetDesktopWindow();
53  return hwnd_parent;
54 }
55 
56 namespace {
57 
58 bool createFolderItem(OUString const & url, ComPtr<IShellItem> & folder) {
59  OUString path;
60  if (osl::FileBase::getSystemPathFromFileURL(url, path)
61  != osl::FileBase::E_None)
62  {
63  return false;
64  }
65  HRESULT res = SHCreateItemFromParsingName(
66  o3tl::toW(path.getStr()), nullptr,
67  IID_PPV_ARGS(&folder));
68  return SUCCEEDED(res);
69 }
70 
71 }
72 
73 namespace fpicker{
74 namespace win32{
75 namespace vista{
76 
77 
78 // types, const etcpp.
79 
80 
81 const ::sal_Int16 INVALID_CONTROL_ID = -1;
82 const ::sal_Int16 INVALID_CONTROL_ACTION = -1;
83 
84 // Guids used for IFileDialog::SetClientGuid
85 const GUID CLIENTID_FILEDIALOG_SIMPLE = {0xB8628FD3, 0xA3F5, 0x4845, 0x9B, 0x62, 0xD5, 0x1E, 0xDF, 0x97, 0xC4, 0x83};
86 const GUID CLIENTID_FILEDIALOG_OPTIONS = {0x93ED486F, 0x0D04, 0x4807, 0x8C, 0x44, 0xAC, 0x26, 0xCB, 0x6C, 0x5D, 0x36};
87 const GUID CLIENTID_FILESAVE_PASSWORD = {0xC12D4F4C, 0x4D41, 0x4D4F, 0x97, 0xEF, 0x87, 0xF9, 0x8D, 0xB6, 0x1E, 0xA6};
88 const GUID CLIENTID_FILESAVE_SELECTION = {0x5B2482B3, 0x0358, 0x4E09, 0xAA, 0x64, 0x2B, 0x76, 0xB2, 0xA0, 0xDD, 0xFE};
89 const GUID CLIENTID_FILESAVE_TEMPLATE = {0x9996D877, 0x20D5, 0x424B, 0x9C, 0x2E, 0xD3, 0xB6, 0x31, 0xEC, 0xF7, 0xCE};
90 const GUID CLIENTID_FILEOPEN_LINK_TEMPLATE = {0x32237796, 0x1509, 0x49D1, 0xBB, 0x7E, 0x63, 0xAD, 0x36, 0xAE, 0x86, 0x8C};
91 const GUID CLIENTID_FILEOPEN_LINK_ANCHOR = {0xBE3188CB, 0x399A, 0x45AE, 0x8F, 0x78, 0x75, 0x17, 0xAF, 0x26, 0x81, 0xEA};
92 const GUID CLIENTID_FILEOPEN_PLAY = {0x32CFB147, 0xF5AE, 0x4F90, 0xA1, 0xF1, 0x81, 0x20, 0x72, 0xBB, 0x2F, 0xC5};
93 const GUID CLIENTID_FILEOPEN_LINK = {0x39AC4BAE, 0x7D2D, 0x46BC, 0xBE, 0x2E, 0xF8, 0x8C, 0xB5, 0x65, 0x5E, 0x6A};
94 
95 
96 static OUString lcl_getURLFromShellItem (IShellItem* pItem)
97 {
98  LPWSTR pStr = nullptr;
99  OUString sURL;
100  HRESULT hr;
101 
102  hr = pItem->GetDisplayName ( SIGDN_FILESYSPATH, &pStr );
103  if (SUCCEEDED(hr))
104  {
105  ::osl::FileBase::getFileURLFromSystemPath( OUString(o3tl::toU(pStr)), sURL );
106  goto cleanup;
107  }
108 
109  hr = pItem->GetDisplayName ( SIGDN_URL, &pStr );
110  if (SUCCEEDED(hr))
111  {
112  sURL = o3tl::toU(pStr);
113  goto cleanup;
114  }
115 
116  hr = pItem->GetDisplayName ( SIGDN_PARENTRELATIVEPARSING, &pStr );
117  if (SUCCEEDED(hr))
118  {
119  GUID known_folder_id;
120  std::wstring aStr = pStr;
121  CoTaskMemFree (pStr);
122 
123  if (0 == aStr.compare(0, 3, L"::{"))
124  aStr = aStr.substr(2);
125  hr = IIDFromString(aStr.c_str(), &known_folder_id);
126  if (SUCCEEDED(hr))
127  {
128  hr = SHGetKnownFolderPath(known_folder_id, 0, nullptr, &pStr);
129  if (SUCCEEDED(hr))
130  {
131  ::osl::FileBase::getFileURLFromSystemPath(OUString(o3tl::toU(pStr)), sURL);
132  goto cleanup;
133  }
134  }
135  }
136 
137  // Default fallback
138  hr = SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &pStr);
139  if (SUCCEEDED(hr))
140  ::osl::FileBase::getFileURLFromSystemPath(OUString(o3tl::toU(pStr)), sURL);
141  else // shouldn't happen...
142  goto bailout;
143 
144 cleanup:
145  CoTaskMemFree (pStr);
146 bailout:
147  return sURL;
148 }
149 
150 // Vista file picker shows the filter mask next to filter name in the list; so we need to remove the
151 // mask from the filter name to avoid duplicating masks
152 static OUString lcl_AdjustFilterName(const OUString& sName)
153 {
154  const sal_Int32 idx = sName.indexOf("(.");
155  return (idx > 0) ? sName.copy(0, idx).trim() : sName;
156 }
157 
158 // rvStrings holds the OUStrings, pointers to which data are stored in returned COMDLG_FILTERSPEC
159 static ::std::vector<COMDLG_FILTERSPEC> lcl_buildFilterList(CFilterContainer& rContainer,
160  std::vector<OUString>& rvStrings)
161 {
162  ::std::vector< COMDLG_FILTERSPEC > lList ;
164 
165  rContainer.beginEnumFilter( );
166  while( rContainer.getNextFilter(aFilter) )
167  {
168  COMDLG_FILTERSPEC aSpec;
169 
170  rvStrings.push_back(lcl_AdjustFilterName(aFilter.first)); // to avoid dangling pointer
171  aSpec.pszName = o3tl::toW(rvStrings.back().getStr());
172  aSpec.pszSpec = o3tl::toW(aFilter.second.getStr());
173 
174  lList.push_back(aSpec);
175  }
176 
177  return lList;
178 }
179 
180 
182  : m_iDialogOpen ()
183  , m_iDialogSave ()
184  , m_iFolderPicker()
185  , m_hLastResult ()
186  , m_lFilters ()
187  , m_iEventHandler(new VistaFilePickerEventHandler(this))
188  , m_bInExecute (false)
189  , m_bWasExecuted (false)
190  , m_hParentWindow(choose_parent_window())
191  , m_sDirectory ()
192  , m_sFilename ()
193  , mnNbCallCoInitializeExForReinit(0)
194 {
195 }
196 
197 
199 {
200 }
201 
202 
204 {
205  // SYNCHRONIZED->
206  osl::MutexGuard aLock(m_aMutex);
207 
208  // TRICKY .-)
209  // osl::Thread class initializes COm already in MTA mode because it's needed
210  // by VCL and UNO so. There is no way to change that from outside...
211  // but we need a STA environment...
212  m_hLastResult = o3tl::safeCoInitializeEx(COINIT_APARTMENTTHREADED, mnNbCallCoInitializeExForReinit);
213 }
214 
215 
217 {
218  try
219  {
220  switch(rRequest->getRequest())
221  {
222  case E_ADD_PICKER_LISTENER :
224  break;
225 
228  break;
229 
230  case E_APPEND_FILTER :
231  impl_sta_appendFilter(rRequest);
232  break;
233 
234  case E_APPEND_FILTERGROUP :
235  impl_sta_appendFilterGroup(rRequest);
236  break;
237 
238  case E_SET_CURRENT_FILTER :
239  impl_sta_setCurrentFilter(rRequest);
240  break;
241 
242  case E_GET_CURRENT_FILTER :
243  impl_sta_getCurrentFilter(rRequest);
244  break;
245 
246  case E_CREATE_OPEN_DIALOG :
247  impl_sta_CreateOpenDialog(rRequest);
248  break;
249 
250  case E_CREATE_SAVE_DIALOG :
251  impl_sta_CreateSaveDialog(rRequest);
252  break;
253 
255  impl_sta_CreateFolderPicker(rRequest);
256  break;
257 
260  break;
261 
262  case E_SET_TITLE :
263  impl_sta_SetTitle(rRequest);
264  break;
265 
266  case E_SET_FILENAME:
267  impl_sta_SetFileName(rRequest);
268  break;
269 
270  case E_SET_DIRECTORY :
271  impl_sta_SetDirectory(rRequest);
272  break;
273 
274  case E_GET_DIRECTORY :
275  impl_sta_GetDirectory(rRequest);
276  break;
277 
278  case E_SET_DEFAULT_NAME :
279  impl_sta_SetDefaultName(rRequest);
280  break;
281 
282  case E_GET_SELECTED_FILES :
283  impl_sta_getSelectedFiles(rRequest);
284  break;
285 
286  case E_SHOW_DIALOG_MODAL :
287  impl_sta_ShowDialogModal(rRequest);
288  break;
289 
290  case E_SET_CONTROL_VALUE :
291  impl_sta_SetControlValue(rRequest);
292  break;
293 
294  case E_GET_CONTROL_VALUE :
295  impl_sta_GetControlValue(rRequest);
296  break;
297 
298  case E_SET_CONTROL_LABEL :
299  impl_sta_SetControlLabel(rRequest);
300  break;
301 
302  case E_GET_CONTROL_LABEL :
303  impl_sta_GetControlLabel(rRequest);
304  break;
305 
306  case E_ENABLE_CONTROL :
307  impl_sta_EnableControl(rRequest);
308  break;
309 
310  // no default: let the compiler detect changes on enum ERequest !
311  }
312  }
313  catch(...)
314  {}
315 }
316 
317 
319 {
320  o3tl::safeCoUninitializeReinit(COINIT_MULTITHREADED, mnNbCallCoInitializeExForReinit);
321 }
322 
323 
325 {
326  // SYNCHRONIZED outside !
327  const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
328  if ( ! xListener.is())
329  return;
330 
331  // SYNCHRONIZED->
332  osl::ClearableMutexGuard aLock(m_aMutex);
334  aLock.clear();
335  // <- SYNCHRONIZED
336 
337  VistaFilePickerEventHandler* pHandlerImpl = static_cast<VistaFilePickerEventHandler*>(iHandler.get());
338  if (pHandlerImpl)
339  pHandlerImpl->addFilePickerListener(xListener);
340 }
341 
342 
344 {
345  // SYNCHRONIZED outside !
346  const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
347  if ( ! xListener.is())
348  return;
349 
350  // SYNCHRONIZED->
351  osl::ClearableMutexGuard aLock(m_aMutex);
353  aLock.clear();
354  // <- SYNCHRONIZED
355 
356  VistaFilePickerEventHandler* pHandlerImpl = static_cast<VistaFilePickerEventHandler*>(iHandler.get());
357  if (pHandlerImpl)
358  pHandlerImpl->removeFilePickerListener(xListener);
359 }
360 
361 
363 {
364  const OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, OUString());
365  const OUString sFilter = rRequest->getArgumentOrDefault(PROP_FILTER_VALUE, OUString());
366 
367  // SYNCHRONIZED->
368  osl::MutexGuard aLock(m_aMutex);
369 
370  m_lFilters.addFilter(sTitle, sFilter);
371 }
372 
373 
375 {
376  const css::uno::Sequence< css::beans::StringPair > aFilterGroup =
377  rRequest->getArgumentOrDefault(PROP_FILTER_GROUP, css::uno::Sequence< css::beans::StringPair >());
378 
379  // SYNCHRONIZED->
380  osl::MutexGuard aLock(m_aMutex);
381 
382  if ( m_lFilters.numFilter() > 0 && aFilterGroup.getLength() > 0 )
384 
385  ::sal_Int32 c = aFilterGroup.getLength();
386  ::sal_Int32 i = 0;
387  for (i=0; i<c; ++i)
388  {
389  const css::beans::StringPair& rFilter = aFilterGroup[i];
390  m_lFilters.addFilter(rFilter.First, rFilter.Second);
391  }
392 }
393 
394 
396 {
397  const OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, OUString());
398 
399  // SYNCHRONIZED->
400  osl::MutexGuard aLock(m_aMutex);
401 
403 }
404 
405 
407 {
409  UINT nIndex = UINT_MAX;
410  HRESULT hResult = iDialog->GetFileTypeIndex(&nIndex);
411  if (
412  ( FAILED(hResult) ) ||
413  ( nIndex == UINT_MAX ) // COM dialog sometimes return S_OK for empty filter lists .-(
414  )
415  return;
416 
417  // SYNCHRONIZED->
418  osl::MutexGuard aLock(m_aMutex);
419 
420  OUString sTitle;
421  ::sal_Int32 nRealIndex = nIndex-1; // COM dialog base on 1 ... filter container on 0 .-)
422  if (
423  (nRealIndex >= 0 ) &&
424  (m_lFilters.getFilterNameByIndex(nRealIndex, sTitle))
425  )
426  rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
427  else if ( nRealIndex == -1 ) // Dialog not visible yet
428  {
429  sTitle = m_lFilters.getCurrentFilter();
430  rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
431  }
432  // <- SYNCHRONIZED
433 }
434 
435 
436 void VistaFilePickerImpl::impl_sta_CreateDialog(const RequestRef& rRequest, PickerDialog eType, DWORD nOrFlags)
437 {
438  // SYNCHRONIZED->
439  osl::ClearableMutexGuard aLock(m_aMutex);
440 
441  TFileDialog iDialog;
442 
443  switch (eType)
444  {
447  if (FAILED(m_hLastResult))
448  return;
449  m_iDialogOpen.query(&iDialog);
450  break;
451 
454  if (FAILED(m_hLastResult))
455  return;
456  m_iDialogSave.query(&iDialog);
457  break;
458 
461  if (FAILED(m_hLastResult))
462  return;
463  m_iFolderPicker.query(&iDialog);
464  break;
465  }
466 
468 
469  aLock.clear();
470  // <- SYNCHRONIZED
471 
472  DWORD nFlags = 0;
473  iDialog->GetOptions ( &nFlags );
474 
475  nFlags &= ~FOS_FORCESHOWHIDDEN;
476  nFlags |= FOS_PATHMUSTEXIST;
477  nFlags |= FOS_DONTADDTORECENT;
478  nFlags |= nOrFlags;
479 
480  iDialog->SetOptions ( nFlags );
481 
482  css::uno::Reference<css::awt::XWindow> xWindow = rRequest->getArgumentOrDefault(PROP_PARENT_WINDOW, css::uno::Reference<css::awt::XWindow>());
483  if(xWindow.is())
484  {
485  css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysDepWin(xWindow,css::uno::UNO_QUERY);
486  if(xSysDepWin.is()) {
487  css::uno::Sequence<sal_Int8> aProcessIdent(16);
488  rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
489  css::uno::Any aAny = xSysDepWin->getWindowHandle(aProcessIdent,css::lang::SystemDependent::SYSTEM_WIN32);
490  sal_Int64 tmp = 0;
491  aAny >>= tmp;
492  if(tmp != 0)
493  m_hParentWindow = reinterpret_cast<HWND>(tmp);
494  }
495  }
496 
497  ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, ::sal_Int32(0));
498  ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, ::sal_Int32(0));
499  impl_sta_enableFeatures(nFeatures, nTemplate);
500 
501  VistaFilePickerEventHandler* pHandlerImpl = static_cast<VistaFilePickerEventHandler*>(iHandler.get());
502  if (pHandlerImpl)
503  pHandlerImpl->startListening(iDialog);
504 }
505 
506 
508 {
509  DWORD nFlags = 0;
510  nFlags |= FOS_FILEMUSTEXIST;
511  nFlags |= FOS_OVERWRITEPROMPT;
512 
514 }
515 
516 
518 {
519  DWORD nFlags = 0;
520  nFlags |= FOS_FILEMUSTEXIST;
521  nFlags |= FOS_OVERWRITEPROMPT;
522 
524 }
525 
526 
528 {
529  DWORD nFlags = 0;
530  nFlags |= FOS_PICKFOLDERS;
531 
532  impl_sta_CreateDialog(rRequest, PickerDialog::Folder, nFlags);
533 }
534 
535 
536 const ::sal_Int32 GROUP_VERSION = 1;
537 const ::sal_Int32 GROUP_TEMPLATE = 2;
538 const ::sal_Int32 GROUP_IMAGETEMPLATE = 3;
539 const ::sal_Int32 GROUP_CHECKBOXES = 4;
540 const ::sal_Int32 GROUP_IMAGEANCHOR = 5;
541 
542 
543 static void setLabelToControl(TFileDialogCustomize iCustom, sal_uInt16 nControlId)
544 {
545  OUString aLabel = CResourceProvider::getResString(nControlId);
546  aLabel = SOfficeToWindowsLabel(aLabel);
547  iCustom->SetControlLabel(nControlId, o3tl::toW(aLabel.getStr()) );
548 }
549 
550 
551 void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate)
552 {
553  GUID aGUID = {};
554  switch (nTemplate)
555  {
556  case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE :
557  case css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW :
558  case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE :
560  break;
561 
562  case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION :
563  case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS :
565  break;
566 
567  case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD :
569  break;
570 
571  case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION :
572  case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION :
574  break;
575 
576  case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE :
578  break;
579 
580  case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE :
582  break;
583 
584  case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR :
586  break;
587 
588  case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY :
589  case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY :
590  aGUID = CLIENTID_FILEOPEN_PLAY;
591  break;
592 
593  case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW :
594  aGUID = CLIENTID_FILEOPEN_LINK;
595  break;
596  }
598  iDialog->SetClientGuid ( aGUID );
599 
601 
602  if ((nFeatures & FEATURE_VERSION) == FEATURE_VERSION)
603  {
604  iCustom->StartVisualGroup (GROUP_VERSION, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_VERSION).replaceFirst("~","").getStr()));
605  iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION);
606  iCustom->EndVisualGroup ();
607  iCustom->MakeProminent (GROUP_VERSION);
608  }
609 
610  if ((nFeatures & FEATURE_TEMPLATE) == FEATURE_TEMPLATE)
611  {
612  iCustom->StartVisualGroup (GROUP_TEMPLATE, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_TEMPLATES).replaceFirst("~","").getStr()));
613  iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE);
614  iCustom->EndVisualGroup ();
615  iCustom->MakeProminent (GROUP_TEMPLATE);
616  }
617 
618  if ((nFeatures & FEATURE_IMAGETEMPLATE) == FEATURE_IMAGETEMPLATE)
619  {
620  iCustom->StartVisualGroup (GROUP_IMAGETEMPLATE, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_IMAGE_TEMPLATE).replaceFirst("~","").getStr()));
621  iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE);
622  iCustom->EndVisualGroup ();
623  iCustom->MakeProminent (GROUP_IMAGETEMPLATE);
624  }
625 
626  if ((nFeatures & FEATURE_IMAGEANCHOR) == FEATURE_IMAGEANCHOR)
627  {
628  iCustom->StartVisualGroup (GROUP_IMAGEANCHOR, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_IMAGE_ANCHOR).replaceFirst("~","").getStr()));
629  iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR);
630  iCustom->EndVisualGroup ();
631  iCustom->MakeProminent (GROUP_IMAGEANCHOR);
632  }
633 
634  iCustom->StartVisualGroup (GROUP_CHECKBOXES, L"");
635 
636  sal_uInt16 nControlId(0);
637  if ((nFeatures & FEATURE_AUTOEXTENSION) == FEATURE_AUTOEXTENSION)
638  {
639  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION;
640  iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_AUTO_EXTENSION).replaceFirst("~","").getStr()), true);
641  setLabelToControl(iCustom, nControlId);
642  }
643 
644  if ((nFeatures & FEATURE_PASSWORD) == FEATURE_PASSWORD)
645  {
646  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD;
647  iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_PASSWORD).replaceFirst("~","").getStr()), false);
648  setLabelToControl(iCustom, nControlId);
649  }
650 
651  if ((nFeatures & FEATURE_GPGPASSWORD) == FEATURE_GPGPASSWORD)
652  {
653  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION;
654  iCustom->AddCheckButton (nControlId, L"GpgPassword", false);
655  setLabelToControl(iCustom, nControlId);
656  }
657 
658  if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
659  {
660  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
661  iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_READONLY).replaceFirst("~","").getStr()), false);
662  setLabelToControl(iCustom, nControlId);
663  }
664 
665  if ((nFeatures & FEATURE_FILTEROPTIONS) == FEATURE_FILTEROPTIONS)
666  {
667  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS;
668  iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_FILTER_OPTIONS).replaceFirst("~","").getStr()), false);
669  setLabelToControl(iCustom, nControlId);
670  }
671 
672  if ((nFeatures & FEATURE_LINK) == FEATURE_LINK)
673  {
674  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK;
675  iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_INSERT_AS_LINK).replaceFirst("~","").getStr()), false);
676  setLabelToControl(iCustom, nControlId);
677  }
678 
679  if ((nFeatures & FEATURE_SELECTION) == FEATURE_SELECTION)
680  {
681  nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION;
682  iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_SELECTION).replaceFirst("~","").getStr()), false);
683  setLabelToControl(iCustom, nControlId);
684  }
685 
686  /* can be ignored ... new COM dialog supports preview native now !
687  if ((nFeatures & FEATURE_PREVIEW) == FEATURE_PREVIEW)
688  iCustom->AddCheckButton (css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, L"Preview", false);
689  */
690 
691  iCustom->EndVisualGroup();
692 
693  if ((nFeatures & FEATURE_PLAY) == FEATURE_PLAY)
694  iCustom->AddPushButton (css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_PLAY).replaceFirst("~","").getStr()));
695 
696 }
697 
698 
700 {
701  const bool bMultiSelection = rRequest->getArgumentOrDefault(PROP_MULTISELECTION_MODE, true);
702 
703  // SYNCHRONIZED->
704  osl::ClearableMutexGuard aLock(m_aMutex);
706  aLock.clear();
707  // <- SYNCHRONIZED
708 
709  DWORD nFlags = 0;
710  m_hLastResult = iDialog->GetOptions ( &nFlags );
711 
712  if (bMultiSelection)
713  nFlags |= FOS_ALLOWMULTISELECT;
714  else
715  nFlags &= ~FOS_ALLOWMULTISELECT;
716 
717  iDialog->SetOptions ( nFlags );
718 }
719 
720 
722 {
723  OUString sTitle = rRequest->getArgumentOrDefault(PROP_TITLE, OUString());
724 
725  // SYNCHRONIZED->
726  osl::ClearableMutexGuard aLock(m_aMutex);
728  aLock.clear();
729  // <- SYNCHRONIZED
730 
731  iDialog->SetTitle(o3tl::toW(sTitle.getStr()));
732 }
733 
734 
736 {
737  OUString sFileName = rRequest->getArgumentOrDefault(PROP_FILENAME, OUString());
738 
739  // SYNCHRONIZED->
740  osl::ClearableMutexGuard aLock(m_aMutex);
742  aLock.clear();
743  // <- SYNCHRONIZED
744 
745  iDialog->SetFileName(o3tl::toW(sFileName.getStr()));
746 }
747 
748 
750 {
751  OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, OUString());
752 
753  if( !m_bInExecute)
754  {
755  // Vista stores last used folders for file dialogs
756  // so we don't want the application to change the folder
757  // in most cases.
758  // Store the requested folder in the meantime and decide later
759  // what to do
760  m_sDirectory = sDirectory;
761  }
762 
763  // SYNCHRONIZED->
764  osl::ClearableMutexGuard aLock(m_aMutex);
766  aLock.clear();
767  // <- SYNCHRONIZED
768 
769  ComPtr< IShellItem > pFolder;
770  if ( !createFolderItem(sDirectory, pFolder) )
771  return;
772 
773  iDialog->SetFolder(pFolder);
774 }
775 
777 {
779  ComPtr< IShellItem > pFolder;
780  HRESULT hResult = iDialog->GetFolder( &pFolder );
781  if ( FAILED(hResult) )
782  return OUString();
783  return lcl_getURLFromShellItem(pFolder);
784 }
785 
787 {
788  const OUString sFolder = m_sDirectory.isEmpty() ? GetDirectory() : m_sDirectory;
789  if (!sFolder.isEmpty())
790  rRequest->setArgument(PROP_DIRECTORY, sFolder);
791 }
792 
794 {
795  OUString sFilename = rRequest->getArgumentOrDefault(PROP_FILENAME, OUString());
797 
799  if ( ! iCustom.is())
800  return;
801 
802  // if we have the autoextension check box set, remove (or change ???) the extension of the filename
803  // so that the autoextension mechanism can do its job
804  BOOL bValue = FALSE;
805  HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
806  if ( FAILED(hResult) )
807  return;
808  if ( bValue )
809  {
810  sal_Int32 nSepPos = sFilename.lastIndexOf( '.' );
811  if ( -1 != nSepPos )
812  sFilename = sFilename.copy(0, nSepPos);
813  }
814 
815  iDialog->SetFileName (o3tl::toW(sFilename.getStr()));
816  m_sFilename = sFilename;
817 }
818 
819 
821 {
822  // SYNCHRONIZED->
823  osl::ClearableMutexGuard aLock(m_aMutex);
824 
825  std::vector<OUString> vStrings; // to hold the adjusted filter names, pointers to which will be
826  // stored in lFilters
827  ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters, vStrings);
828  OUString sCurrentFilter = m_lFilters.getCurrentFilter();
829  sal_Int32 nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter);
832 
833  aLock.clear();
834  // <- SYNCHRONIZED
835 
836  if (lFilters.empty())
837  return;
838 
839  COMDLG_FILTERSPEC *pFilt = lFilters.data();
840  iDialog->SetFileTypes(lFilters.size(), pFilt/*&lFilters[0]*/);
841  iDialog->SetFileTypeIndex(nCurrentFilter + 1);
842 
843  BOOL bValue = FALSE;
844  HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
845  if ( FAILED(hResult) )
846  return;
847 
848  if ( bValue )
849  {
850  PCWSTR lpFilterExt = lFilters[0].pszSpec;
851 
852  lpFilterExt = wcsrchr( lpFilterExt, '.' );
853  if ( lpFilterExt )
854  lpFilterExt++;
855  iDialog->SetDefaultExtension( lpFilterExt );
856  }
857 
858 }
859 
860 
862 {
863  // SYNCHRONIZED->
864  osl::ClearableMutexGuard aLock(m_aMutex);
865 
869  bool bInExecute = m_bInExecute;
870 
871  aLock.clear();
872  // <- SYNCHRONIZED
873 
874  // ask dialog for results
875  // Note : we must differ between single/multi selection !
876  // Note further: we must react different if dialog is in execute or not .-(
877  ComPtr< IShellItem > iItem;
879  HRESULT hResult = E_FAIL;
880 
881  if (iOpen.is())
882  {
883  if (bInExecute)
884  hResult = iOpen->GetSelectedItems(&iItems);
885  else
886  {
887  hResult = iOpen->GetResults(&iItems);
888  if (FAILED(hResult))
889  hResult = iOpen->GetResult(&iItem);
890  }
891  }
892  else if (iSave.is())
893  {
894  if (bInExecute)
895  hResult = iSave->GetCurrentSelection(&iItem);
896  else
897  hResult = iSave->GetResult(&iItem);
898  }
899  else if (iPick.is())
900  {
901  if (bInExecute)
902  hResult = iPick->GetCurrentSelection(&iItem);
903  else
904  {
905  hResult = iPick->GetResult(&iItem);
906  }
907  }
908 
909  if (FAILED(hResult))
910  return;
911 
912  // convert and pack results
913  std::vector< OUString > lFiles;
914  if (iItem.is())
915  {
916  const OUString sURL = lcl_getURLFromShellItem(iItem);
917  if (sURL.getLength() > 0)
918  lFiles.push_back(sURL);
919  }
920 
921  if (iItems.is())
922  {
923  DWORD nCount;
924  hResult = iItems->GetCount(&nCount);
925  if ( SUCCEEDED(hResult) )
926  {
927  for (DWORD i=0; i<nCount; ++i)
928  {
929  hResult = iItems->GetItemAt(i, &iItem);
930  if ( SUCCEEDED(hResult) )
931  {
932  const OUString sURL = lcl_getURLFromShellItem(iItem);
933  if (sURL.getLength() > 0)
934  lFiles.push_back(sURL);
935  }
936  }
937  }
938  }
939 
940  rRequest->setArgument(PROP_SELECTED_FILES, comphelper::containerToSequence(lFiles));
941 }
942 
943 
945 {
947 
948  // SYNCHRONIZED->
949  ::osl::ResettableMutexGuard aLock(m_aMutex);
950 
955 
956  // it's important to know if we are showing the dialog.
957  // Some dialog interface methods can't be called then or some
958  // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles())
959  m_bInExecute = true;
960 
961  m_bWasExecuted = true;
962 
963  aLock.clear();
964  // <- SYNCHRONIZED
965 
966  // we set the directory only if we have a save dialog and a filename
967  // for the other cases, the file dialog remembers its last location
968  // according to its client guid.
969  if( m_sDirectory.getLength())
970  {
971  ComPtr< IShellItem > pFolder;
972  if ( createFolderItem(m_sDirectory, pFolder) )
973  {
974  if (m_sFilename.getLength())
975  {
976  OUString aFileURL(m_sDirectory);
977  sal_Int32 nIndex = aFileURL.lastIndexOf('/');
978  if (nIndex != aFileURL.getLength()-1)
979  aFileURL += "/";
980  aFileURL += m_sFilename;
981 
983 
984  BOOL bValue = FALSE;
985  HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
986  if ( bValue )
987  {
988  UINT nFileType;
989  hResult = iDialog->GetFileTypeIndex(&nFileType);
990  if ( SUCCEEDED(hResult) && nFileType > 0 )
991  {
992  // COM dialog base on 1 ... filter container on 0 .-)
993  ::size_t nRealIndex = nFileType-1;
994  OUString sFilter;
995  if (m_lFilters.getFilterByIndex(nRealIndex, sFilter))
996  {
997  const sal_Int32 idx = sFilter.indexOf('.');
998  if (idx >= 0)
999  aFileURL += sFilter.copy(idx);
1000  }
1001  }
1002  }
1003 
1004  // Check existence of file. Set folder only for this special case
1005  OUString aSystemPath;
1006  osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData );
1007 
1008  WIN32_FIND_DATAW aFindFileData;
1009  HANDLE hFind = FindFirstFileW( o3tl::toW(aSystemPath.getStr()), &aFindFileData );
1010  if (hFind != INVALID_HANDLE_VALUE)
1011  iDialog->SetFolder(pFolder);
1012  else
1013  hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
1014 
1015  FindClose( hFind );
1016  }
1017  else
1018  iDialog->AddPlace(pFolder, FDAP_TOP);
1019  }
1020  }
1021 
1022 
1023  HRESULT hResult = E_FAIL;
1024  try
1025  {
1026  // show dialog and wait for user decision
1027  if (iOpen.is())
1028  hResult = iOpen->Show( m_hParentWindow ); // parent window needed
1029  else
1030  if (iSave.is())
1031  hResult = iSave->Show( m_hParentWindow ); // parent window needed
1032  else
1033  if (iPick.is())
1034  hResult = iPick->Show( m_hParentWindow ); // parent window needed
1035  }
1036  catch(...)
1037  {}
1038 
1039  // SYNCHRONIZED->
1040  aLock.reset();
1041  m_bInExecute = false;
1042  aLock.clear();
1043  // <- SYNCHRONIZED
1044 
1045  if ( FAILED(hResult) )
1046  return;
1047 
1048  impl_sta_getSelectedFiles(rRequest);
1049  rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, true);
1050 }
1051 
1052 
1054 {
1055  TFileDialog iDialog;
1056 
1057  // SYNCHRONIZED->
1058  osl::MutexGuard aLock(m_aMutex);
1059 
1060  if (m_iDialogOpen.is())
1061  m_iDialogOpen.query(&iDialog);
1062  if (m_iDialogSave.is())
1063  m_iDialogSave.query(&iDialog);
1064  if (m_iFolderPicker.is())
1065  m_iFolderPicker.query(&iDialog);
1066 
1067  return iDialog;
1068 }
1069 
1070 
1072 {
1073  TFileDialogCustomize iCustom;
1074 
1075  // SYNCHRONIZED->
1076  osl::MutexGuard aLock(m_aMutex);
1077 
1078  if (m_iDialogOpen.is())
1079  m_iDialogOpen.query(&iCustom);
1080  else if (m_iDialogSave.is())
1081  m_iDialogSave.query(&iCustom);
1082  else if (m_iFolderPicker.is())
1083  m_iFolderPicker.query(&iCustom);
1084 
1085  return iCustom;
1086 }
1087 
1088 
1090  ::sal_Int16 nControlId)
1091 {
1092  (void)iCustom->SetSelectedControlItem(nControlId, 1000); // Don't care if this fails (useless?)
1093  DWORD i = 0;
1094  HRESULT hResult = S_OK;
1095  while ( SUCCEEDED(hResult) )
1096  hResult = iCustom->RemoveControlItem(nControlId, i++);
1097 }
1098 
1099 
1101 {
1102  ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1103  ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1104  css::uno::Any aValue = rRequest->getValue(PROP_CONTROL_VALUE);
1105 
1106  // don't check for right values here ...
1107  // most parameters are optional !
1108 
1110  if ( ! iCustom.is())
1111  return;
1112 
1113  switch (nId)
1114  {
1115  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
1116  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1117  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1118  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1119  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1120  //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1121  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1122  {
1123  bool bValue = false;
1124  aValue >>= bValue;
1125  iCustom->SetCheckButtonState(nId, bValue);
1126  }
1127  break;
1128 
1129  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION :
1130  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
1131  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
1132  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR :
1133  {
1134  HRESULT hResult;
1135  switch (nAction)
1136  {
1137  case css::ui::dialogs::ControlActions::DELETE_ITEMS :
1138  {
1139  hResult = iCustom->RemoveAllControlItems(nId);
1140  if ( FAILED(hResult) )
1141  lcl_removeControlItemsWorkaround(iCustom, nId);
1142  }
1143  break;
1144 
1145  case css::ui::dialogs::ControlActions::ADD_ITEMS :
1146  {
1147  aValue >>= m_lItems;
1148  for (::sal_Int32 i=0; i<m_lItems.getLength(); ++i)
1149  {
1150  const OUString& sItem = m_lItems[i];
1151  hResult = iCustom->AddControlItem(nId, i, o3tl::toW(sItem.getStr()));
1152  }
1153  }
1154  break;
1155 
1156  case css::ui::dialogs::ControlActions::SET_SELECT_ITEM :
1157  {
1158  ::sal_Int32 nItem = 0;
1159  aValue >>= nItem;
1160  hResult = iCustom->SetSelectedControlItem(nId, nItem);
1161  }
1162  break;
1163  }
1164  }
1165  break;
1166 
1167  case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
1168  {
1169  }
1170  break;
1171  }
1172 }
1173 
1174 
1176 {
1177  ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1178 
1179  // don't check for right values here ...
1180  // most parameters are optional !
1181 
1183  if ( ! iCustom.is())
1184  return;
1185 
1186  css::uno::Any aValue;
1187  if( m_bWasExecuted )
1188  switch (nId)
1189  {
1190  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1191  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION :
1192  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1193  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1194  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1195  //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1196  case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1197  {
1198  BOOL bValue = FALSE;
1199  HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue);
1200  if ( SUCCEEDED(hResult) )
1201  aValue <<= bool(bValue);
1202  }
1203  break;
1204  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION:
1205  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE:
1206  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE:
1207  case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR:
1208  {
1209  DWORD bValue = 0;
1210  HRESULT hResult = iCustom->GetSelectedControlItem(nId, &bValue);
1211  if ( SUCCEEDED(hResult) )
1212  {
1213  const OUString& sItem = m_lItems[bValue];
1214  aValue <<= OUString(sItem.getStr());
1215  }
1216  }
1217  break;
1218  }
1219 
1220  if (aValue.hasValue())
1221  rRequest->setArgument(PROP_CONTROL_VALUE, aValue);
1222 }
1223 
1224 
1226 {
1227  ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1228  OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, OUString() );
1229 
1230  // don't check for right values here ...
1231  // most parameters are optional !
1232 
1234  if ( ! iCustom.is())
1235  return;
1236  iCustom->SetControlLabel (nId, o3tl::toW(sLabel.getStr()));
1237 }
1238 
1239 
1241 {
1242 }
1243 
1244 
1246 {
1247  ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1248  bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, true);
1249 
1250  // don't check for right values here ...
1251  // most parameters are optional !
1252 
1254  if ( ! iCustom.is())
1255  return;
1256 
1257  CDCONTROLSTATEF eState = CDCS_VISIBLE;
1258  if (bEnabled)
1259  eState |= CDCS_ENABLED;
1260  else
1261  eState |= CDCS_INACTIVE;
1262 
1263  iCustom->SetControlState(nId, eState);
1264 }
1265 
1266 void VistaFilePickerImpl::impl_SetDefaultExtension( const OUString& currentFilter )
1267 {
1269  if (currentFilter.getLength())
1270  {
1271  OUString FilterExt;
1272  m_lFilters.getFilterByName(currentFilter, FilterExt);
1273 
1274  sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
1275  const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
1276 
1277  sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
1278  if (posOfSemiColon < 0)
1279  posOfSemiColon = FilterExt.getLength() - 1;
1280 
1281  FilterExt = OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
1282  iDialog->SetDefaultExtension ( o3tl::toW(FilterExt.getStr()) );
1283  }
1284 }
1285 
1287 {
1288  // SYNCHRONIZED->
1289  osl::ClearableMutexGuard aLock(m_aMutex);
1290 
1291  const OUString sFilter = m_lFilters.getCurrentFilter ();
1292  OUString sExt ;
1293  if (!m_lFilters.getFilterByName(sFilter, sExt))
1294  return;
1295 
1297 
1298  aLock.clear();
1299  // <- SYNCHRONIZED
1300 
1301  PCWSTR pExt = nullptr;
1302  if ( bChecked )
1303  {
1304  pExt = o3tl::toW(sExt.getStr());
1305  pExt = wcsrchr( pExt, '.' );
1306  if ( pExt )
1307  pExt++;
1308  }
1309  iDialog->SetDefaultExtension( pExt );
1310 }
1311 
1312 bool VistaFilePickerImpl::onFileTypeChanged( UINT /*nTypeIndex*/ )
1313 {
1314  return true;
1315 }
1316 
1318 {
1320 }
1321 
1322 } // namespace vista
1323 } // namespace win32
1324 } // namespace fpicker
1325 
1326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void impl_sta_SetTitle(const RequestRef &rRequest)
implementation of request E_SET_TITLE
TFileDialogCustomize impl_getCustomizeInterface()
returns an interface, which can be used to customize the internally used COM dialog.
sal_Int32 nIndex
const OUString PROP_FILTER_VALUE("filter_value")
void impl_sta_SetDirectory(const RequestRef &rRequest)
implementation of request E_SET_DIRECTORY
sal_Int32 getFilterPos(const OUString &aName) const
const ::sal_Int32 GROUP_VERSION
const GUID CLIENTID_FILEOPEN_LINK_ANCHOR
EXTERN_C BOOL BOOL const wchar_t *pProgramPath HRESULT hr
void impl_SetDefaultExtension(const OUString &currentFilter)
virtual void onAutoExtensionChanged(bool bChecked) override
void impl_sta_SetControlValue(const RequestRef &rRequest)
implementation of request E_SET_CONTROL_VALUE
HRESULT create()
Definition: comptr.hxx:82
const OUString PROP_CONTROL_ACTION("control_action")
HRESULT m_hLastResult
knows the return state of the last COM call
static OUString lcl_AdjustFilterName(const OUString &sName)
const ::sal_Int32 FEATURE_SELECTION
const ::sal_Int32 FEATURE_GPGPASSWORD
const ::sal_Int32 FEATURE_VERSION
void setCurrentFilter(const OUString &aName)
const OUString PROP_FEATURES("features")
void impl_sta_SetMultiSelectionMode(const RequestRef &rRequest)
implementation of request E_SET_MULTISELECTION_MODE
sal_Int16 nId
const ::sal_Int32 GROUP_TEMPLATE
OUString SOfficeToWindowsLabel(const OUString &aSOLabel)
mutable::osl::Mutex m_aMutex
static bool is_current_process_window(HWND hwnd)
tDoubleVectorPair cleanup(const css::uno::Sequence< double > &rXValues, const css::uno::Sequence< double > &rYValues, Pred aPred)
const ::sal_Int16 INVALID_CONTROL_ID
TFileOpenDialog m_iDialogOpen
COM object representing a file open dialog.
bool getNextFilter(FILTER_ENTRY_T &nextFilterEntry)
NSString * getResString(sal_Int32 aId)
void impl_sta_SetControlLabel(const RequestRef &rRequest)
implementation of request E_SET_CONTROL_LABEL
const ::sal_Int16 INVALID_CONTROL_ACTION
sal_uInt16 sal_Unicode
const ::sal_Int32 FEATURE_IMAGEANCHOR
TFileDialogEvents m_iEventHandler
help us to handle dialog events and provide them to interested office listener.
void impl_sta_CreateFolderPicker(const RequestRef &rRequest)
implementation of request E_CREATE_FOLDER_PICKER
const wchar_t *typedef BOOL
int nCount
void impl_sta_setCurrentFilter(const RequestRef &rRequest)
implementation of request E_SET_CURRENT_FILTER
static::std::vector< COMDLG_FILTERSPEC > lcl_buildFilterList(CFilterContainer &rContainer, std::vector< OUString > &rvStrings)
const OUString PROP_CONTROL_ENABLE("control_enable")
TFolderPickerDialog m_iFolderPicker
COM object representing a folder picker dialog.
const OUString PROP_CONTROL_LABEL("control_label")
bool is()
Definition: comptr.hxx:201
void impl_sta_SetDefaultName(const RequestRef &rRequest)
implementation of request E_SET_DEFAULT_NAME
const ::sal_Int32 FEATURE_PASSWORD
const OUString PROP_PARENT_WINDOW("ParentWindow")
const ::sal_Int32 FEATURE_IMAGETEMPLATE
void impl_sta_addFilePickerListener(const RequestRef &rRequest)
implementation of request E_ADD_FILEPICKER_LISTENER
int i
sal_Int16 nControlId
static void setLabelToControl(TFileDialogCustomize iCustom, sal_uInt16 nControlId)
const OUString PROP_TITLE("title")
Mutex aLock
const ::sal_Int32 GROUP_CHECKBOXES
void impl_sta_getCurrentFilter(const RequestRef &rRequest)
implementation of request E_GET_CURRENT_FILTER
const ::sal_Int32 FEATURE_LINK
virtual void removeFilePickerListener(const css::uno::Reference< css::ui::dialogs::XFilePickerListener > &xListener)
HRESULT query(T_QUERYINTERFACE **pQuery)
Definition: comptr.hxx:178
const ::sal_Int32 FEATURE_READONLY
const OUString STRING_SEPARATOR("------------------------------------------")
void impl_sta_EnableControl(const RequestRef &rRequest)
implementation of request E_ENABLE_CONTROL
void impl_sta_appendFilterGroup(const RequestRef &rRequest)
implementation of request E_APPEND_FILTERGROUP
void impl_sta_removeFilePickerListener(const RequestRef &rRequest)
implementation of request E_REMOVE_FILEPICKER_LISTENER
const OUString PROP_DIRECTORY("directory")
const OUString PROP_FILTER_TITLE("filter_title")
static HWND choose_parent_window()
void impl_sta_enableFeatures(::sal_Int32 nFeatures,::sal_Int32 nTemplate)
create all needed (optional!) UI controls addressed by the field nFeatures.
bool getFilterNameByIndex(sal_Int32 aIndex, OUString &theName) const
virtual void doRequest(const RequestRef &rRequest) override
bool getFilterByIndex(sal_Int32 aIndex, OUString &theFilter) const
OUString getCurrentFilter() const
OUString FpsResId(const char *pId)
bool getFilterByName(const OUString &aName, OUString &theFilter) const
void impl_sta_appendFilter(const RequestRef &rRequest)
implementation of request E_APPEND_FILTER
const ::sal_Int32 FEATURE_FILTEROPTIONS
const sal_uInt16 idx[]
static void lcl_removeControlItemsWorkaround(const TFileDialogCustomize &iCustom,::sal_Int16 nControlId)
const ::sal_Int32 FEATURE_TEMPLATE
void impl_sta_setFiltersOnDialog()
fill filter list of internal used dialog.
void impl_sta_GetDirectory(const RequestRef &rRequest)
implementation of request E_GET_DIRECTORY
const ::sal_Int32 FEATURE_AUTOEXTENSION
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
void impl_sta_SetFileName(const RequestRef &rRequest)
implementation of request E_SET_FILENAME
T_INTERFACE * get() const
Definition: comptr.hxx:144
void startListening(const TFileDialog &pBroadcaster)
start listening for file picker events on the given file open dialog COM object.
const GUID CLIENTID_FILEOPEN_LINK_TEMPLATE
OUString aLabel
std::shared_ptr< Request > RequestRef
std::pair< OUString, OUString > FILTER_ENTRY_T
void impl_sta_GetControlValue(const RequestRef &rRequest)
implementation of request E_GET_CONTROL_VALUE
#define FALSE
bool addFilter(const OUString &aName, const OUString &aFilter, bool bAllowDuplicates=false)
const ::sal_Int32 FEATURE_PLAY
const OUString PROP_CONTROL_VALUE("control_value")
sal_Int32 numFilter()
const OUString PROP_SELECTED_FILES("selected_files")
void impl_sta_CreateDialog(const RequestRef &rRequest, PickerDialog eType, DWORD nOrFlags)
virtual void addFilePickerListener(const css::uno::Reference< css::ui::dialogs::XFilePickerListener > &xListener)
void impl_sta_ShowDialogModal(const RequestRef &rRequest)
implementation of request E_SHOW_DIALOG_MODAL
virtual bool onFileTypeChanged(UINT nTypeIndex) override
const char * pExt
const OUString PROP_TEMPLATE_DESCR("templatedescription")
void impl_sta_getSelectedFiles(const RequestRef &rRequest)
implementation of request E_GET_SELECTED_FILES
const OUString PROP_DIALOG_SHOW_RESULT("dialog_show_result")
static OUString lcl_getURLFromShellItem(IShellItem *pItem)
aStr
void impl_sta_CreateSaveDialog(const RequestRef &rRequest)
implementation of request E_CREATE_SAVE_DIALOG
static void impl_sta_GetControlLabel(const RequestRef &rRequest)
implementation of request E_GET_CONTROL_LABEL
const OUString PROP_MULTISELECTION_MODE("multiselection_mode")
const OUString PROP_FILENAME("filename")
void impl_sta_CreateOpenDialog(const RequestRef &rRequest)
implementation of request E_CREATE_OPEN_DIALOG
TFileSaveDialog m_iDialogSave
COM object representing a file save dialog.
const OUString PROP_FILTER_GROUP("filter-group")
const ::sal_Int32 GROUP_IMAGEANCHOR
const ::sal_Int32 GROUP_IMAGETEMPLATE
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo