1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 //-----------------------------------------------------------------------------
25 // includes
26 //-----------------------------------------------------------------------------
27 
28 #include "VistaFilePickerImpl.hxx"
29 
30 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
31 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
32 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
33 #include <com/sun/star/beans/StringPair.hpp>
34 #include <comphelper/sequenceasvector.hxx>
35 #include <osl/file.hxx>
36 #include <osl/mutex.hxx>
37 #ifdef __MINGW32__
38 #include <limits.h>
39 #endif
40 #include "..\misc\WinImplHelper.hxx"
41 
42 #include <Shlguid.h>
43 
44  inline bool is_current_process_window(HWND hwnd)
45 {
46     DWORD pid;
47     GetWindowThreadProcessId(hwnd, &pid);
48     return (pid == GetCurrentProcessId());
49 }
50 
51 HWND choose_parent_window()
52 {
53     HWND hwnd_parent = GetForegroundWindow();
54     if (!is_current_process_window(hwnd_parent))
55        hwnd_parent = GetDesktopWindow();
56     return hwnd_parent;
57 }
58 
59 //-----------------------------------------------------------------------------
60 // namespace
61 //-----------------------------------------------------------------------------
62 
63 namespace fpicker{
64 namespace win32{
65 namespace vista{
66 
67 namespace css = ::com::sun::star;
68 
69 //-----------------------------------------------------------------------------
70 // types, const etcpp.
71 //-----------------------------------------------------------------------------
72 
73 
74 static const ::sal_Int16 INVALID_CONTROL_ID     = -1;
75 static const ::sal_Int16 INVALID_CONTROL_ACTION = -1;
76 
77 typedef ::comphelper::SequenceAsVector< ::rtl::OUString > TStringList;
78 
79 // Guids used for IFileDialog::SetClientGuid
80 static const GUID CLIENTID_FILEDIALOG_SIMPLE		= {0xB8628FD3, 0xA3F5, 0x4845, 0x9B, 0x62, 0xD5, 0x1E, 0xDF, 0x97, 0xC4, 0x83};
81 static const GUID CLIENTID_FILEDIALOG_OPTIONS		= {0x93ED486F, 0x0D04, 0x4807, 0x8C, 0x44, 0xAC, 0x26, 0xCB, 0x6C, 0x5D, 0x36};
82 static const GUID CLIENTID_FILESAVE					= {0x3B2E2261, 0x402D, 0x4049, 0xB0, 0xC0, 0x91, 0x13, 0xF8, 0x6E, 0x84, 0x7C};
83 static const GUID CLIENTID_FILESAVE_PASSWORD		= {0xC12D4F4C, 0x4D41, 0x4D4F, 0x97, 0xEF, 0x87, 0xF9, 0x8D, 0xB6, 0x1E, 0xA6};
84 static const GUID CLIENTID_FILESAVE_SELECTION		= {0x5B2482B3, 0x0358, 0x4E09, 0xAA, 0x64, 0x2B, 0x76, 0xB2, 0xA0, 0xDD, 0xFE};
85 static const GUID CLIENTID_FILESAVE_TEMPLATE		= {0x9996D877, 0x20D5, 0x424B, 0x9C, 0x2E, 0xD3, 0xB6, 0x31, 0xEC, 0xF7, 0xCE};
86 static const GUID CLIENTID_FILEOPEN_LINK_TEMPLATE	= {0x32237796, 0x1509, 0x49D1, 0xBB, 0x7E, 0x63, 0xAD, 0x36, 0xAE, 0x86, 0x8C};
87 static const GUID CLIENTID_FILEOPEN_PLAY			= {0x32CFB147, 0xF5AE, 0x4F90, 0xA1, 0xF1, 0x81, 0x20, 0x72, 0xBB, 0x2F, 0xC5};
88 static const GUID CLIENTID_FILEOPEN_LINK			= {0x39AC4BAE, 0x7D2D, 0x46BC, 0xBE, 0x2E, 0xF8, 0x8C, 0xB5, 0x65, 0x5E, 0x6A};
89 
90 //-----------------------------------------------------------------------------
91 ::rtl::OUString lcl_getURLFromShellItem (IShellItem* pItem)
92 {
93     LPOLESTR pStr = NULL;
94 	::rtl::OUString sURL;
95 
96 	SIGDN   eConversion = SIGDN_FILESYSPATH;
97     HRESULT hr          = pItem->GetDisplayName ( eConversion, &pStr );
98 
99     if ( FAILED(hr) )
100 	{
101 		eConversion = SIGDN_URL;
102 		hr          = pItem->GetDisplayName ( eConversion, &pStr );
103 
104 		if ( FAILED(hr) )
105 			return ::rtl::OUString();
106 
107 		sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr));
108 	}
109 	else
110 	{
111 		::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL );
112 	}
113 
114     CoTaskMemFree (pStr);
115     return sURL;
116 }
117 
118 //-----------------------------------------------------------------------------------------
119 ::std::vector< COMDLG_FILTERSPEC > lcl_buildFilterList(CFilterContainer& rContainer)
120 {
121     const sal_Int32                          c      = rContainer.numFilter();
122           sal_Int32                          i      = 0;
123           ::std::vector< COMDLG_FILTERSPEC > lList  ;
124           CFilterContainer::FILTER_ENTRY_T   aFilter;
125 
126     rContainer.beginEnumFilter( );
127 	while( rContainer.getNextFilter(aFilter) )
128     {
129         COMDLG_FILTERSPEC aSpec;
130 
131 		aSpec.pszName = reinterpret_cast<LPCTSTR>(aFilter.first.getStr()) ;
132 		aSpec.pszSpec = reinterpret_cast<LPCTSTR>(aFilter.second.getStr());
133 
134         lList.push_back(aSpec);
135     }
136 
137     return lList;
138 }
139 
140 //-----------------------------------------------------------------------------------------
141 VistaFilePickerImpl::VistaFilePickerImpl()
142     : m_iDialogOpen  ()
143     , m_iDialogSave  ()
144     , m_hLastResult  ()
145     , m_lFilters     ()
146     , m_lLastFiles   ()
147     , m_iEventHandler(new VistaFilePickerEventHandler(this))
148     , m_bInExecute   (sal_False)
149     , m_bWasExecuted (sal_False)
150 	, m_sDirectory   ()
151 	, m_sFilename    ()
152 {
153 	m_hParentWindow = choose_parent_window();
154 }
155 
156 //-------------------------------------------------------------------------------
157 VistaFilePickerImpl::~VistaFilePickerImpl()
158 {
159 }
160 
161 //-------------------------------------------------------------------------------
162 void VistaFilePickerImpl::before()
163 {
164     // SYNCHRONIZED->
165     ::osl::ResettableMutexGuard aLock(m_aMutex);
166 
167     // TRICKY .-)
168     // osl::Thread class initializes COm already in MTA mode because it's needed
169     // by VCL and UNO so. There is no way to change that from outside ...
170     // but we need a STA environment ...
171     // So we make it by try-and-error ...
172     // If first CoInitialize will fail .. we unitialize COM initialize it new .-)
173 
174     m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
175     if ( FAILED(m_hLastResult) )
176     {
177         CoUninitialize();
178         m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
179     }
180 }
181 
182 //-------------------------------------------------------------------------------
183 void VistaFilePickerImpl::doRequest(const RequestRef& rRequest)
184 {
185     try
186     {
187         switch(rRequest->getRequest())
188         {
189             case E_ADD_PICKER_LISTENER :
190                     impl_sta_addFilePickerListener(rRequest);
191                     break;
192 
193             case E_REMOVE_PICKER_LISTENER :
194                     impl_sta_removeFilePickerListener(rRequest);
195                     break;
196 
197             case E_APPEND_FILTER :
198                     impl_sta_appendFilter(rRequest);
199                     break;
200 
201 			case E_APPEND_FILTERGROUP :
202 					impl_sta_appendFilterGroup(rRequest);
203 					break;
204 
205 			case E_SET_CURRENT_FILTER :
206                     impl_sta_setCurrentFilter(rRequest);
207                     break;
208 
209             case E_GET_CURRENT_FILTER :
210                     impl_sta_getCurrentFilter(rRequest);
211                     break;
212 
213             case E_CREATE_OPEN_DIALOG :
214                     impl_sta_CreateOpenDialog(rRequest);
215                     break;
216 
217             case E_CREATE_SAVE_DIALOG :
218                     impl_sta_CreateSaveDialog(rRequest);
219                     break;
220 
221             case E_SET_MULTISELECTION_MODE :
222                     impl_sta_SetMultiSelectionMode(rRequest);
223                     break;
224 
225             case E_SET_TITLE :
226                     impl_sta_SetTitle(rRequest);
227                     break;
228 
229 			case E_SET_FILENAME:
230 				impl_sta_SetFileName(rRequest);
231 				break;
232 
233             case E_SET_DIRECTORY :
234                     impl_sta_SetDirectory(rRequest);
235                     break;
236 
237 			case E_GET_DIRECTORY :
238 					impl_sta_GetDirectory(rRequest);
239 					break;
240 
241 			case E_SET_DEFAULT_NAME :
242 					impl_sta_SetDefaultName(rRequest);
243 					break;
244 
245             case E_GET_SELECTED_FILES :
246                     impl_sta_getSelectedFiles(rRequest);
247                     break;
248 
249             case E_SHOW_DIALOG_MODAL :
250                     impl_sta_ShowDialogModal(rRequest);
251                     break;
252 
253             case E_SET_CONTROL_VALUE :
254                     impl_sta_SetControlValue(rRequest);
255                     break;
256 
257             case E_GET_CONTROL_VALUE :
258                     impl_sta_GetControlValue(rRequest);
259                     break;
260 
261             case E_SET_CONTROL_LABEL :
262                     impl_sta_SetControlLabel(rRequest);
263                     break;
264 
265             case E_GET_CONTROL_LABEL :
266                     impl_sta_GetControlLabel(rRequest);
267                     break;
268 
269             case E_ENABLE_CONTROL :
270                     impl_sta_EnableControl(rRequest);
271                     break;
272 
273             // no default: let the compiler detect changes on enum ERequest !
274         }
275     }
276     catch(...)
277     {}
278 }
279 
280 //-------------------------------------------------------------------------------
281 void VistaFilePickerImpl::after()
282 {
283     CoUninitialize();
284 }
285 
286 //-------------------------------------------------------------------------------
287 void VistaFilePickerImpl::impl_sta_addFilePickerListener(const RequestRef& rRequest)
288 {
289     // SYNCHRONIZED outside !
290     const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
291     if ( ! xListener.is())
292         return;
293 
294     // SYNCHRONIZED->
295     ::osl::ResettableMutexGuard aLock(m_aMutex);
296     TFileDialogEvents iHandler = m_iEventHandler;
297     aLock.clear();
298     // <- SYNCHRONIZED
299 
300     VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
301     if (pHandlerImpl)
302         pHandlerImpl->addFilePickerListener(xListener);
303 }
304 
305 //-------------------------------------------------------------------------------
306 void VistaFilePickerImpl::impl_sta_removeFilePickerListener(const RequestRef& rRequest)
307 {
308     // SYNCHRONIZED outside !
309     const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
310     if ( ! xListener.is())
311         return;
312 
313     // SYNCHRONIZED->
314     ::osl::ResettableMutexGuard aLock(m_aMutex);
315     TFileDialogEvents iHandler = m_iEventHandler;
316     aLock.clear();
317     // <- SYNCHRONIZED
318 
319     VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
320     if (pHandlerImpl)
321         pHandlerImpl->removeFilePickerListener(xListener);
322 }
323 
324 //-------------------------------------------------------------------------------
325 void VistaFilePickerImpl::impl_sta_appendFilter(const RequestRef& rRequest)
326 {
327     const ::rtl::OUString sTitle  = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString());
328     const ::rtl::OUString sFilter = rRequest->getArgumentOrDefault(PROP_FILTER_VALUE, ::rtl::OUString());
329 
330     // SYNCHRONIZED->
331     ::osl::ResettableMutexGuard aLock(m_aMutex);
332 
333     m_lFilters.addFilter(sTitle, sFilter);
334 }
335 
336 //-------------------------------------------------------------------------------
337 void VistaFilePickerImpl::impl_sta_appendFilterGroup(const RequestRef& rRequest)
338 {
339 	const css::uno::Sequence< css::beans::StringPair > aFilterGroup  =
340 		rRequest->getArgumentOrDefault(PROP_FILTER_GROUP, css::uno::Sequence< css::beans::StringPair >());
341 
342     // SYNCHRONIZED->
343 	::rtl::OUString aEmpty;
344     ::osl::ResettableMutexGuard aLock(m_aMutex);
345 
346     if ( m_lFilters.numFilter() > 0 && aFilterGroup.getLength() > 0 )
347 		m_lFilters.addFilter( STRING_SEPARATOR, aEmpty, sal_True );
348 
349 	::sal_Int32 c = aFilterGroup.getLength();
350     ::sal_Int32 i = 0;
351     for (i=0; i<c; ++i)
352     {
353         const css::beans::StringPair& rFilter = aFilterGroup[i];
354         m_lFilters.addFilter(rFilter.First, rFilter.Second);
355     }
356 }
357 
358 //-------------------------------------------------------------------------------
359 void VistaFilePickerImpl::impl_sta_setCurrentFilter(const RequestRef& rRequest)
360 {
361     const ::rtl::OUString sTitle  = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString());
362 
363     // SYNCHRONIZED->
364     ::osl::ResettableMutexGuard aLock(m_aMutex);
365 
366     m_lFilters.setCurrentFilter(sTitle);
367 }
368 
369 //-------------------------------------------------------------------------------
370 void VistaFilePickerImpl::impl_sta_getCurrentFilter(const RequestRef& rRequest)
371 {
372     TFileDialog iDialog = impl_getBaseDialogInterface();
373     UINT        nIndex  = UINT_MAX;
374     HRESULT     hResult = iDialog->GetFileTypeIndex(&nIndex);
375     if (
376         ( FAILED(hResult)    ) ||
377         ( nIndex == UINT_MAX )      // COM dialog sometimes return S_OK for empty filter lists .-(
378        )
379         return;
380 
381     // SYNCHRONIZED->
382     ::osl::ResettableMutexGuard aLock(m_aMutex);
383 
384     ::rtl::OUString sTitle;
385     ::sal_Int32     nRealIndex = (nIndex-1); // COM dialog base on 1 ... filter container on 0 .-)
386     if (
387         (nRealIndex >= 0                         ) &&
388         (m_lFilters.getFilter(nRealIndex, sTitle))
389        )
390         rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
391 	else if ( nRealIndex == -1 ) // Dialog not visible yet
392 	{
393 		sTitle = m_lFilters.getCurrentFilter();
394         rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
395 	}
396 
397     aLock.clear();
398     // <- SYNCHRONIZED
399 }
400 
401 //-------------------------------------------------------------------------------
402 void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest)
403 {
404     // SYNCHRONIZED->
405     ::osl::ResettableMutexGuard aLock(m_aMutex);
406 
407     m_hLastResult = m_iDialogOpen.create();
408     if (FAILED(m_hLastResult))
409         return;
410 
411     TFileDialog iDialog;
412 #ifdef __MINGW32__
413     m_iDialogOpen->QueryInterface(IID_IFileDialog, (void **)(&iDialog));
414 #else
415     m_iDialogOpen.query(&iDialog);
416 #endif
417 
418     TFileDialogEvents iHandler = m_iEventHandler;
419 
420     aLock.clear();
421     // <- SYNCHRONIZED
422 
423 	DWORD nFlags = 0;
424     iDialog->GetOptions ( &nFlags );
425 
426     nFlags &= ~FOS_FORCESHOWHIDDEN;
427     nFlags |=  FOS_PATHMUSTEXIST;
428     nFlags |=  FOS_FILEMUSTEXIST;
429     nFlags |=  FOS_OVERWRITEPROMPT;
430     nFlags |=  FOS_DONTADDTORECENT;
431 
432     iDialog->SetOptions ( nFlags );
433 
434     ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0);
435 	::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0);
436     impl_sta_enableFeatures(nFeatures, nTemplate);
437 
438     VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
439     if (pHandlerImpl)
440         pHandlerImpl->startListening(iDialog);
441 }
442 
443 //-------------------------------------------------------------------------------
444 void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest)
445 {
446     // SYNCHRONIZED->
447     ::osl::ResettableMutexGuard aLock(m_aMutex);
448 
449     m_hLastResult = m_iDialogSave.create();
450     if (FAILED(m_hLastResult))
451         return;
452 
453     TFileDialogEvents  iHandler = m_iEventHandler;
454     TFileDialog        iDialog;
455 #ifdef __MINGW32__
456     m_iDialogSave->QueryInterface(IID_IFileDialog, (void **)(&iDialog));
457 #else
458     m_iDialogSave.query(&iDialog);
459 #endif
460 
461     aLock.clear();
462     // <- SYNCHRONIZED
463 
464 	DWORD nFlags = 0;
465     iDialog->GetOptions ( &nFlags );
466 
467     nFlags &= ~FOS_FORCESHOWHIDDEN;
468     nFlags |=  FOS_PATHMUSTEXIST;
469     nFlags |=  FOS_FILEMUSTEXIST;
470     nFlags |=  FOS_OVERWRITEPROMPT;
471     nFlags |=  FOS_DONTADDTORECENT;
472 
473     iDialog->SetOptions ( nFlags );
474 
475     ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0);
476 	::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0);
477     impl_sta_enableFeatures(nFeatures, nTemplate);
478 
479     VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
480     if (pHandlerImpl)
481         pHandlerImpl->startListening(iDialog);
482 }
483 
484 //-------------------------------------------------------------------------------
485 static const ::sal_Int32 GROUP_VERSION         =   1;
486 static const ::sal_Int32 GROUP_TEMPLATE        =   2;
487 static const ::sal_Int32 GROUP_IMAGETEMPLATE   =   3;
488 static const ::sal_Int32 GROUP_CHECKBOXES      =   4;
489 
490 //-------------------------------------------------------------------------------
491 static void setLabelToControl(CResourceProvider& rResourceProvider, TFileDialogCustomize iCustom, sal_uInt16 nControlId)
492 {
493     ::rtl::OUString aLabel = rResourceProvider.getResString(nControlId);
494     aLabel = SOfficeToWindowsLabel(aLabel);
495     iCustom->SetControlLabel(nControlId, reinterpret_cast<LPCWSTR>(aLabel.getStr()) );
496 }
497 
498 //-------------------------------------------------------------------------------
499 void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate)
500 {
501 	GUID aGUID = {};
502 	switch (nTemplate)
503 	{
504         case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE :
505         case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE :
506 			aGUID = CLIENTID_FILEDIALOG_SIMPLE;
507 			break;
508 
509 		case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION :
510         case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS :
511 			aGUID = CLIENTID_FILEDIALOG_OPTIONS;
512 			break;
513 
514 		case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION :
515 			aGUID = CLIENTID_FILESAVE;
516 			break;
517 
518 		case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD :
519 			aGUID = CLIENTID_FILESAVE_PASSWORD;
520 			break;
521 
522         case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION :
523 			aGUID = CLIENTID_FILESAVE_SELECTION;
524 			break;
525 
526         case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE :
527 			aGUID = CLIENTID_FILESAVE_TEMPLATE;
528 			break;
529 
530         case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE :
531 			aGUID = CLIENTID_FILEOPEN_LINK_TEMPLATE;
532 			break;
533 
534         case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY :
535 			aGUID = CLIENTID_FILEOPEN_PLAY;
536 			break;
537 
538         case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW :
539 			aGUID = CLIENTID_FILEOPEN_LINK;
540 			break;
541     }
542 	TFileDialog iDialog = impl_getBaseDialogInterface();
543 	iDialog->SetClientGuid ( aGUID );
544 
545     TFileDialogCustomize iCustom = impl_getCustomizeInterface();
546 
547     if ((nFeatures & FEATURE_VERSION) == FEATURE_VERSION)
548     {
549         iCustom->StartVisualGroup (GROUP_VERSION, L"Version");
550         iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION);
551         iCustom->EndVisualGroup   ();
552         iCustom->MakeProminent    (GROUP_VERSION);
553     }
554 
555     if ((nFeatures & FEATURE_TEMPLATE) == FEATURE_TEMPLATE)
556     {
557         iCustom->StartVisualGroup (GROUP_TEMPLATE, L"Template");
558         iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE);
559         iCustom->EndVisualGroup   ();
560         iCustom->MakeProminent    (GROUP_TEMPLATE);
561     }
562 
563     if ((nFeatures & FEATURE_IMAGETEMPLATE) == FEATURE_IMAGETEMPLATE)
564     {
565         iCustom->StartVisualGroup (GROUP_IMAGETEMPLATE, L"Style");
566         iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE);
567         iCustom->EndVisualGroup   ();
568         iCustom->MakeProminent    (GROUP_IMAGETEMPLATE);
569     }
570 
571 	iCustom->StartVisualGroup (GROUP_CHECKBOXES, L"");
572 
573     sal_uInt16 nControlId(0);
574     if ((nFeatures & FEATURE_AUTOEXTENSION) == FEATURE_AUTOEXTENSION)
575     {
576         nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION;
577         iCustom->AddCheckButton (nControlId, L"Auto Extension", true);
578         setLabelToControl(m_ResProvider, iCustom, nControlId);
579     }
580 
581     if ((nFeatures & FEATURE_PASSWORD) == FEATURE_PASSWORD)
582     {
583         nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD;
584         iCustom->AddCheckButton (nControlId, L"Password", false);
585         setLabelToControl(m_ResProvider, iCustom, nControlId);
586     }
587 
588     if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
589     {
590         nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
591         iCustom->AddCheckButton (nControlId, L"Readonly", false);
592         setLabelToControl(m_ResProvider, iCustom, nControlId);
593     }
594 
595     if ((nFeatures & FEATURE_FILTEROPTIONS) == FEATURE_FILTEROPTIONS)
596     {
597         nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS;
598         iCustom->AddCheckButton (nControlId, L"Filter Options", false);
599         setLabelToControl(m_ResProvider, iCustom, nControlId);
600     }
601 
602     if ((nFeatures & FEATURE_LINK) == FEATURE_LINK)
603     {
604         nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK;
605         iCustom->AddCheckButton (nControlId, L"Link", false);
606         setLabelToControl(m_ResProvider, iCustom, nControlId);
607     }
608 
609     if ((nFeatures & FEATURE_SELECTION) == FEATURE_SELECTION)
610     {
611         nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION;
612         iCustom->AddCheckButton (nControlId, L"Selection", false);
613         setLabelToControl(m_ResProvider, iCustom, nControlId);
614     }
615 
616     /* can be ignored ... new COM dialog supports preview native now  !
617     if ((nFeatures & FEATURE_PREVIEW) == FEATURE_PREVIEW)
618         iCustom->AddCheckButton (css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, L"Preview", false);
619     */
620 
621 	iCustom->EndVisualGroup();
622 
623     if ((nFeatures & FEATURE_PLAY) == FEATURE_PLAY)
624         iCustom->AddPushButton (css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, L"Play");
625 
626 }
627 
628 //-------------------------------------------------------------------------------
629 void VistaFilePickerImpl::impl_sta_SetMultiSelectionMode(const RequestRef& rRequest)
630 {
631     const ::sal_Bool bMultiSelection = rRequest->getArgumentOrDefault(PROP_MULTISELECTION_MODE, (::sal_Bool)sal_True);
632 
633     // SYNCHRONIZED->
634     ::osl::ResettableMutexGuard aLock(m_aMutex);
635     TFileDialog iDialog = impl_getBaseDialogInterface();
636     aLock.clear();
637     // <- SYNCHRONIZED
638 
639 	DWORD nFlags = 0;
640     m_hLastResult = iDialog->GetOptions ( &nFlags );
641 
642     if (bMultiSelection)
643         nFlags |=  FOS_ALLOWMULTISELECT;
644     else
645         nFlags &= ~FOS_ALLOWMULTISELECT;
646 
647     iDialog->SetOptions ( nFlags );
648 }
649 
650 //-------------------------------------------------------------------------------
651 void VistaFilePickerImpl::impl_sta_SetTitle(const RequestRef& rRequest)
652 {
653     ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_TITLE, ::rtl::OUString());
654 
655     // SYNCHRONIZED->
656     ::osl::ResettableMutexGuard aLock(m_aMutex);
657     TFileDialog iDialog = impl_getBaseDialogInterface();
658     aLock.clear();
659     // <- SYNCHRONIZED
660 
661     iDialog->SetTitle(reinterpret_cast<LPCTSTR>(sTitle.getStr()));
662 }
663 
664 //-------------------------------------------------------------------------------
665 void VistaFilePickerImpl::impl_sta_SetFileName(const RequestRef& rRequest)
666 {
667     ::rtl::OUString sFileName = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString());
668 
669     // SYNCHRONIZED->
670     ::osl::ResettableMutexGuard aLock(m_aMutex);
671     TFileDialog iDialog = impl_getBaseDialogInterface();
672     aLock.clear();
673     // <- SYNCHRONIZED
674 
675     iDialog->SetFileName(reinterpret_cast<LPCTSTR>(sFileName.getStr()));
676 }
677 
678 //-------------------------------------------------------------------------------
679 void VistaFilePickerImpl::impl_sta_SetDirectory(const RequestRef& rRequest)
680 {
681     ::rtl::OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, ::rtl::OUString());
682     bool            bForce     = rRequest->getArgumentOrDefault(PROP_FORCE, false);
683 
684 	if( !m_bInExecute)
685 	{
686 		// Vista stores last used folders for file dialogs
687 		// so we don't want the application to change the folder
688 		// in most cases.
689 		// Store the requested folder in the mean time and decide later
690 		// what to do
691 		m_sDirectory = sDirectory;
692 	}
693 
694     // SYNCHRONIZED->
695     ::osl::ResettableMutexGuard aLock(m_aMutex);
696     TFileDialog iDialog = impl_getBaseDialogInterface();
697     aLock.clear();
698     // <- SYNCHRONIZED
699 
700     ComPtr< IShellItem > pFolder;
701 #ifdef __MINGW32__
702     HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(sDirectory.getStr()), NULL, IID_IShellItem, reinterpret_cast<void**>(&pFolder) );
703 #else
704     HRESULT hResult = SHCreateItemFromParsingName ( sDirectory, NULL, IID_PPV_ARGS(&pFolder) );
705 #endif
706     if ( FAILED(hResult) )
707         return;
708 
709     if ( m_bInExecute || bForce )
710         iDialog->SetFolder(pFolder);
711     else
712     {
713         // Use set default folder as Microsoft recommends in the IFileDialog documentation.
714         iDialog->SetDefaultFolder(pFolder);
715     }
716 }
717 
718 void VistaFilePickerImpl::impl_sta_GetDirectory(const RequestRef& rRequest)
719 {
720     TFileDialog iDialog = impl_getBaseDialogInterface();
721     ComPtr< IShellItem > pFolder;
722 	HRESULT hResult = iDialog->GetFolder( &pFolder );
723 	if ( FAILED(hResult) )
724         return;
725 	::rtl::OUString sFolder = lcl_getURLFromShellItem ( pFolder );
726 	if( sFolder.getLength())
727 		rRequest->setArgument( PROP_DIRECTORY, sFolder );
728 }
729 
730 //-------------------------------------------------------------------------------
731 void VistaFilePickerImpl::impl_sta_SetDefaultName(const RequestRef& rRequest)
732 {
733 	::rtl::OUString sFilename = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString());
734 	TFileDialog iDialog = impl_getBaseDialogInterface();
735 
736     TFileDialogCustomize iCustom = impl_getCustomizeInterface();
737     if ( ! iCustom.is())
738         return;
739 
740     // if we have the autoextension check box set, remove (or change ???) the extension of the filename
741     // so that the autoextension mechanism can do its job
742     BOOL bValue = FALSE;
743     HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
744     if ( bValue )
745     {
746         sal_Int32 nSepPos = sFilename.lastIndexOf( '.' );
747         if ( -1 != nSepPos )
748             sFilename = sFilename.copy(0, nSepPos);
749     }
750 
751 	iDialog->SetFileName ( reinterpret_cast<LPCTSTR>(sFilename.getStr()));
752 	m_sFilename = sFilename;
753 }
754 
755 //-------------------------------------------------------------------------------
756 void VistaFilePickerImpl::impl_sta_setFiltersOnDialog()
757 {
758     // SYNCHRONIZED->
759     ::osl::ResettableMutexGuard aLock(m_aMutex);
760 
761     ::std::vector< COMDLG_FILTERSPEC > lFilters       = lcl_buildFilterList(m_lFilters);
762     ::rtl::OUString                    sCurrentFilter = m_lFilters.getCurrentFilter();
763     sal_Int32                          nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter);
764     TFileDialog                        iDialog        = impl_getBaseDialogInterface();
765 	TFileDialogCustomize               iCustomize     = impl_getCustomizeInterface();
766 
767     aLock.clear();
768     // <- SYNCHRONIZED
769 
770 	COMDLG_FILTERSPEC	*pFilt = &lFilters[0];
771     iDialog->SetFileTypes(lFilters.size(), pFilt/*&lFilters[0]*/);
772     iDialog->SetFileTypeIndex(nCurrentFilter + 1);
773 
774 	BOOL bValue = FALSE;
775 	HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
776 
777 	if ( bValue )
778 	{
779 		LPCWSTR lpFilterExt = lFilters[0].pszSpec;
780 
781 		lpFilterExt = wcsrchr( lpFilterExt, '.' );
782 		if ( lpFilterExt )
783 			lpFilterExt++;
784 		iDialog->SetDefaultExtension( lpFilterExt );
785 	}
786 
787 }
788 
789 //-------------------------------------------------------------------------------
790 void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest)
791 {
792     // SYNCHRONIZED->
793     ::osl::ResettableMutexGuard aLock(m_aMutex);
794 
795     TFileOpenDialog iOpen      = m_iDialogOpen;
796     TFileSaveDialog iSave      = m_iDialogSave;
797     ::sal_Bool      bInExecute = m_bInExecute;
798 
799     aLock.clear();
800     // <- SYNCHRONIZED
801 
802     // ask dialog for results
803     // Note        : we must differ between single/multi selection !
804     // Note further: we must react different if dialog is in execute or not .-(
805     ComPtr< IShellItem >      iItem;
806     ComPtr< IShellItemArray > iItems;
807     HRESULT                   hResult = E_FAIL;
808 
809     if (iOpen.is())
810     {
811         if (bInExecute)
812             hResult = iOpen->GetSelectedItems(&iItems);
813         else
814         {
815             hResult = iOpen->GetResults(&iItems);
816             if (FAILED(hResult))
817                 hResult = iOpen->GetResult(&iItem);
818         }
819     }
820     else
821     if (iSave.is())
822     {
823         if (bInExecute)
824             hResult = iSave->GetCurrentSelection(&iItem);
825         else
826             hResult = iSave->GetResult(&iItem);
827     }
828 
829     if (FAILED(hResult))
830         return;
831 
832     // convert and pack results
833     TStringList lFiles;
834     if (iItem.is())
835     {
836         const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
837         if (sURL.getLength() > 0)
838             lFiles.push_back(sURL);
839     }
840 
841     if (iItems.is())
842     {
843         DWORD nCount;
844         hResult = iItems->GetCount(&nCount);
845         if ( SUCCEEDED(hResult) )
846         {
847             for (DWORD i=0; i<nCount; ++i)
848             {
849                 hResult = iItems->GetItemAt(i, &iItem);
850                 if ( SUCCEEDED(hResult) )
851                 {
852                     const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
853                     if (sURL.getLength() > 0)
854                         lFiles.push_back(sURL);
855                 }
856             }
857         }
858     }
859 
860     rRequest->setArgument(PROP_SELECTED_FILES, lFiles.getAsConstList());
861 }
862 
863 //-------------------------------------------------------------------------------
864 void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest)
865 {
866     impl_sta_setFiltersOnDialog();
867 
868     // SYNCHRONIZED->
869     ::osl::ResettableMutexGuard aLock(m_aMutex);
870 
871     TFileDialog iDialog = impl_getBaseDialogInterface();
872     TFileOpenDialog iOpen = m_iDialogOpen;
873     TFileSaveDialog iSave = m_iDialogSave;
874 
875 	// it's important to know if we are showing the dialog.
876     // Some dialog interface methods cant be called then or some
877     // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles())
878     m_bInExecute = sal_True;
879 
880     m_bWasExecuted = sal_True;
881 
882     aLock.clear();
883     // <- SYNCHRONIZED
884 
885 	// we set the directory only if we have a save dialog and a filename
886 	// for the other cases, the file dialog remembers its last location
887 	// according to its client guid.
888 	if( m_sDirectory.getLength())
889 	{
890 		ComPtr< IShellItem > pFolder;
891 		#ifdef __MINGW32__
892 			HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(m_sDirectory.getStr()), NULL, IID_IShellItem, reinterpret_cast<void**>(&pFolder) );
893 		#else
894 			HRESULT hResult = SHCreateItemFromParsingName ( m_sDirectory, NULL, IID_PPV_ARGS(&pFolder) );
895 		#endif
896 		if ( SUCCEEDED(hResult) )
897         {
898 		    if (m_sFilename.getLength())
899             {
900                 ::rtl::OUString aFileURL(m_sDirectory);
901                 sal_Int32 nIndex = aFileURL.lastIndexOf('/');
902                 if (nIndex != aFileURL.getLength()-1)
903                     aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/"));
904                 aFileURL += m_sFilename;
905 
906                 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
907 
908                 BOOL bValue = FALSE;
909                 HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
910                 if ( bValue )
911                 {
912                     ::rtl::OUString aExt;
913                     UINT nFileType;
914                     hResult = iDialog->GetFileTypeIndex(&nFileType);
915 		            if ( SUCCEEDED(hResult) )
916                     {
917                         ::sal_Int32 nRealIndex = (nFileType-1); // COM dialog base on 1 ... filter container on 0 .-)
918                         ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters);
919 		                LPCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec;
920 
921 		                lpFilterExt = wcsrchr( lpFilterExt, '.' );
922 		                if ( lpFilterExt )
923                             aFileURL += reinterpret_cast<const sal_Unicode*>(lpFilterExt);
924                     }
925                 }
926 
927                 // Check existence of file. Set folder only for this special case
928                 ::rtl::OUString aSystemPath;
929                 osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData );
930 
931 			    WIN32_FIND_DATA	aFindFileData;
932                 HANDLE	hFind = FindFirstFile( reinterpret_cast<LPCWSTR>(aSystemPath.getStr()), &aFindFileData );
933                 if (hFind != INVALID_HANDLE_VALUE)
934                     iDialog->SetFolder(pFolder);
935                 else
936                     hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
937 
938                 FindClose( hFind );
939             }
940 			else
941 				hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
942 		}
943 	}
944 
945 
946     HRESULT hResult = E_FAIL;
947     try
948     {
949         // show dialog and wait for user decision
950         if (iOpen.is())
951             hResult = iOpen->Show( m_hParentWindow ); // parent window needed
952         else
953         if (iSave.is())
954             hResult = iSave->Show( m_hParentWindow ); // parent window needed
955     }
956     catch(...)
957     {}
958 
959     // SYNCHRONIZED->
960     aLock.reset();
961     m_bInExecute = sal_False;
962     aLock.clear();
963     // <- SYNCHRONIZED
964 
965     if ( FAILED(hResult) )
966         return;
967 
968     impl_sta_getSelectedFiles(rRequest);
969     rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, sal_True);
970 }
971 
972 //-------------------------------------------------------------------------------
973 TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface()
974 {
975     TFileDialog iDialog;
976 
977     // SYNCHRONIZED->
978     ::osl::ResettableMutexGuard aLock(m_aMutex);
979 
980     if (m_iDialogOpen.is())
981 #ifdef __MINGW32__
982         m_iDialogOpen->QueryInterface(IID_IFileDialog, (void**)(&iDialog));
983 #else
984         m_iDialogOpen.query(&iDialog);
985 #endif
986     if (m_iDialogSave.is())
987 #ifdef __MINGW32__
988         m_iDialogSave->QueryInterface(IID_IFileDialog, (void**)(&iDialog));
989 #else
990         m_iDialogSave.query(&iDialog);
991 #endif
992 
993     return iDialog;
994 }
995 
996 //-------------------------------------------------------------------------------
997 TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface()
998 {
999     TFileDialogCustomize iCustom;
1000 
1001     // SYNCHRONIZED->
1002     ::osl::ResettableMutexGuard aLock(m_aMutex);
1003 
1004     if (m_iDialogOpen.is())
1005 #ifdef __MINGW32__
1006         m_iDialogOpen->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom));
1007 #else
1008         m_iDialogOpen.query(&iCustom);
1009 #endif
1010     else
1011     if (m_iDialogSave.is())
1012 #ifdef __MINGW32__
1013         m_iDialogSave->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom));
1014 #else
1015         m_iDialogSave.query(&iCustom);
1016 #endif
1017 
1018     return iCustom;
1019 }
1020 
1021 //-------------------------------------------------------------------------------
1022 void lcl_removeControlItemsWorkaround(const TFileDialogCustomize& iCustom   ,
1023                                             ::sal_Int16           nControlId)
1024 {
1025     ::sal_Int32 i       = 0;
1026     HRESULT   hResult;
1027 
1028     hResult = iCustom->SetSelectedControlItem(nControlId, 1000);
1029 	hResult = S_OK;
1030     while ( SUCCEEDED(hResult) )
1031         hResult = iCustom->RemoveControlItem(nControlId, i++);
1032 }
1033 
1034 //-------------------------------------------------------------------------------
1035 void VistaFilePickerImpl::impl_sta_SetControlValue(const RequestRef& rRequest)
1036 {
1037     ::sal_Int16   nId     = rRequest->getArgumentOrDefault(PROP_CONTROL_ID    , INVALID_CONTROL_ID    );
1038     ::sal_Int16   nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1039     css::uno::Any aValue  = rRequest->getArgumentOrDefault(PROP_CONTROL_VALUE , css::uno::Any()       );
1040 
1041     // dont check for right values here ...
1042     // most parameters are optional !
1043 
1044     TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1045     if ( ! iCustom.is())
1046         return;
1047 
1048     switch (nId)
1049     {
1050         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
1051         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1052         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1053         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1054         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1055         //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1056         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1057             {
1058                 ::sal_Bool bValue   = sal_False;
1059                            aValue >>= bValue;
1060                 iCustom->SetCheckButtonState(nId, bValue);
1061             }
1062             break;
1063 
1064         case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION :
1065         case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
1066         case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
1067             {
1068                 HRESULT hResult;
1069                 switch (nAction)
1070                 {
1071                     case css::ui::dialogs::ControlActions::DELETE_ITEMS :
1072                         {
1073                             hResult = iCustom->RemoveAllControlItems(nId);
1074                             if ( FAILED(hResult) )
1075                                 lcl_removeControlItemsWorkaround(iCustom, nId);
1076                         }
1077                         break;
1078 
1079                     case css::ui::dialogs::ControlActions::ADD_ITEMS :
1080                         {
1081                             css::uno::Sequence< ::rtl::OUString > lItems;
1082                                                        aValue >>= lItems;
1083                             for (::sal_Int32 i=0; i<lItems.getLength(); ++i)
1084                             {
1085                                 const ::rtl::OUString& sItem = lItems[i];
1086                                 hResult = iCustom->AddControlItem(nId, i, reinterpret_cast<LPCTSTR>(sItem.getStr()));
1087                             }
1088                         }
1089                         break;
1090 
1091                     case css::ui::dialogs::ControlActions::SET_SELECT_ITEM :
1092                         {
1093                             ::sal_Int32 nItem    = 0;
1094                                         aValue >>= nItem;
1095                             hResult = iCustom->SetSelectedControlItem(nId, nItem);
1096                         }
1097                         break;
1098                 }
1099             }
1100             break;
1101 
1102         case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
1103             {
1104             }
1105             break;
1106         }
1107 }
1108 
1109 //-------------------------------------------------------------------------------
1110 void VistaFilePickerImpl::impl_sta_GetControlValue(const RequestRef& rRequest)
1111 {
1112     ::sal_Int16 nId     = rRequest->getArgumentOrDefault(PROP_CONTROL_ID    , INVALID_CONTROL_ID    );
1113     ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1114 
1115     // dont check for right values here ...
1116     // most parameters are optional !
1117 
1118     TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1119     if ( ! iCustom.is())
1120         return;
1121 
1122     css::uno::Any aValue;
1123     if( m_bWasExecuted )
1124     switch (nId)
1125     {
1126         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1127         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1128         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1129         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1130         //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1131         case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1132             {
1133                 BOOL    bValue  = FALSE;
1134                 HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue);
1135                 if ( SUCCEEDED(hResult) )
1136                     aValue = css::uno::makeAny((sal_Bool)bValue);
1137             }
1138             break;
1139     }
1140 
1141     if (aValue.hasValue())
1142         rRequest->setArgument(PROP_CONTROL_VALUE, aValue);
1143 }
1144 
1145 //-------------------------------------------------------------------------------
1146 void VistaFilePickerImpl::impl_sta_SetControlLabel(const RequestRef& rRequest)
1147 {
1148 	::sal_Int16     nId    = rRequest->getArgumentOrDefault(PROP_CONTROL_ID   , INVALID_CONTROL_ID  );
1149 	::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString() );
1150 
1151     // dont check for right values here ...
1152     // most parameters are optional !
1153 
1154     TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1155     if ( ! iCustom.is())
1156         return;
1157 	iCustom->SetControlLabel ( nId, reinterpret_cast<LPCTSTR>(sLabel.getStr()));
1158 }
1159 
1160 //-------------------------------------------------------------------------------
1161 void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/)
1162 {
1163 }
1164 
1165 //-------------------------------------------------------------------------------
1166 void VistaFilePickerImpl::impl_sta_EnableControl(const RequestRef& rRequest)
1167 {
1168     ::sal_Int16 nId      = rRequest->getArgumentOrDefault(PROP_CONTROL_ID    , INVALID_CONTROL_ID  );
1169     ::sal_Bool  bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, (::sal_Bool)sal_True);
1170 
1171     // dont check for right values here ...
1172     // most parameters are optional !
1173 
1174     TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1175     if ( ! iCustom.is())
1176         return;
1177 
1178     CDCONTROLSTATEF eState = CDCS_VISIBLE;
1179     if (bEnabled)
1180         eState |= CDCS_ENABLED;
1181     else
1182         eState |= CDCS_INACTIVE;
1183 
1184     iCustom->SetControlState(nId, eState);
1185 }
1186 //-------------------------------------------------------------------------------
1187 void VistaFilePickerImpl::impl_SetDefaultExtension( const rtl::OUString& currentFilter )
1188 {
1189    TFileDialog iDialog = impl_getBaseDialogInterface();
1190    if (currentFilter.getLength())
1191    {
1192 		rtl::OUString FilterExt;
1193 		m_lFilters.getFilter(currentFilter, FilterExt);
1194 
1195 		sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
1196 		const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
1197 
1198 		sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
1199 		if (posOfSemiColon < 0)
1200 			posOfSemiColon = FilterExt.getLength() - 1;
1201 
1202 		FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
1203 		iDialog->SetDefaultExtension ( reinterpret_cast<LPCTSTR>(FilterExt.getStr()) );
1204    }
1205 }
1206 
1207 static void impl_refreshFileDialog( TFileDialog iDialog )
1208 {
1209 	if ( SUCCEEDED(iDialog->SetFileName(L"")) &&
1210 	     SUCCEEDED(iDialog->SetFileName(L"*.*")) )
1211 	{
1212 		IOleWindow* iOleWindow;
1213 #ifdef __MINGW32__
1214 		if (SUCCEEDED(iDialog->QueryInterface(IID_IOleWindow, reinterpret_cast<void**>(&iOleWindow))))
1215 #else
1216 		if (SUCCEEDED(iDialog->QueryInterface(IID_PPV_ARGS(&iOleWindow))))
1217 #endif
1218 		{
1219 			HWND hwnd;
1220 			if (SUCCEEDED(iOleWindow->GetWindow(&hwnd)))
1221 			{
1222 				PostMessage(hwnd, WM_COMMAND, IDOK, 0);
1223 			}
1224 			iOleWindow->Release();
1225 		}
1226 	}
1227 }
1228 
1229 //-------------------------------------------------------------------------------
1230 void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked)
1231 {
1232     // SYNCHRONIZED->
1233     ::osl::ResettableMutexGuard aLock(m_aMutex);
1234 
1235 	const ::rtl::OUString sFilter = m_lFilters.getCurrentFilter ();
1236 		  ::rtl::OUString sExt    ;
1237 	if ( !m_lFilters.getFilter (sFilter, sExt))
1238 		return;
1239 
1240     TFileDialog iDialog = impl_getBaseDialogInterface();
1241 
1242     aLock.clear();
1243     // <- SYNCHRONIZED
1244 
1245 	LPCWSTR pExt = 0;
1246 	if ( bChecked )
1247 	{
1248 		pExt = reinterpret_cast<LPCTSTR>(sExt.getStr());
1249 		pExt = wcsrchr( pExt, '.' );
1250 		if ( pExt )
1251 			pExt++;
1252 	}
1253 	iDialog->SetDefaultExtension( pExt );
1254 }
1255 
1256 bool VistaFilePickerImpl::onFileTypeChanged( UINT /*nTypeIndex*/ )
1257 {
1258 	return true;
1259 }
1260 
1261 } // namespace vista
1262 } // namespace win32
1263 } // namespace fpicker
1264