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
is_current_process_window(HWND hwnd)44 inline bool is_current_process_window(HWND hwnd)
45 {
46 DWORD pid;
47 GetWindowThreadProcessId(hwnd, &pid);
48 return (pid == GetCurrentProcessId());
49 }
50
choose_parent_window()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 //-----------------------------------------------------------------------------
lcl_getURLFromShellItem(IShellItem * pItem)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 //-----------------------------------------------------------------------------------------
lcl_buildFilterList(CFilterContainer & rContainer)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 //-----------------------------------------------------------------------------------------
VistaFilePickerImpl()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 //-------------------------------------------------------------------------------
~VistaFilePickerImpl()157 VistaFilePickerImpl::~VistaFilePickerImpl()
158 {
159 }
160
161 //-------------------------------------------------------------------------------
before()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 //-------------------------------------------------------------------------------
doRequest(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
after()281 void VistaFilePickerImpl::after()
282 {
283 CoUninitialize();
284 }
285
286 //-------------------------------------------------------------------------------
impl_sta_addFilePickerListener(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_removeFilePickerListener(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_appendFilter(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_appendFilterGroup(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_setCurrentFilter(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_getCurrentFilter(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_CreateOpenDialog(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_CreateSaveDialog(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
setLabelToControl(CResourceProvider & rResourceProvider,TFileDialogCustomize iCustom,sal_uInt16 nControlId)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 //-------------------------------------------------------------------------------
impl_sta_enableFeatures(::sal_Int32 nFeatures,::sal_Int32 nTemplate)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 //-------------------------------------------------------------------------------
impl_sta_SetMultiSelectionMode(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_SetTitle(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_SetFileName(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_SetDirectory(const RequestRef & rRequest)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.getStr(), 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
impl_sta_GetDirectory(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_SetDefaultName(const RequestRef & rRequest)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 //-------------------------------------------------------------------------------
impl_sta_setFiltersOnDialog()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 if (lFilters.empty())
771 return;
772
773 COMDLG_FILTERSPEC *pFilt = &lFilters[0];
774 iDialog->SetFileTypes(lFilters.size(), pFilt/*&lFilters[0]*/);
775 iDialog->SetFileTypeIndex(nCurrentFilter + 1);
776
777 BOOL bValue = FALSE;
778 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
779
780 if ( bValue )
781 {
782 LPCWSTR lpFilterExt = lFilters[0].pszSpec;
783
784 lpFilterExt = wcsrchr( lpFilterExt, '.' );
785 if ( lpFilterExt )
786 lpFilterExt++;
787 iDialog->SetDefaultExtension( lpFilterExt );
788 }
789
790 }
791
792 //-------------------------------------------------------------------------------
impl_sta_getSelectedFiles(const RequestRef & rRequest)793 void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest)
794 {
795 // SYNCHRONIZED->
796 ::osl::ResettableMutexGuard aLock(m_aMutex);
797
798 TFileOpenDialog iOpen = m_iDialogOpen;
799 TFileSaveDialog iSave = m_iDialogSave;
800 ::sal_Bool bInExecute = m_bInExecute;
801
802 aLock.clear();
803 // <- SYNCHRONIZED
804
805 // ask dialog for results
806 // Note : we must differ between single/multi selection !
807 // Note further: we must react different if dialog is in execute or not .-(
808 ComPtr< IShellItem > iItem;
809 ComPtr< IShellItemArray > iItems;
810 HRESULT hResult = E_FAIL;
811
812 if (iOpen.is())
813 {
814 if (bInExecute)
815 hResult = iOpen->GetSelectedItems(&iItems);
816 else
817 {
818 hResult = iOpen->GetResults(&iItems);
819 if (FAILED(hResult))
820 hResult = iOpen->GetResult(&iItem);
821 }
822 }
823 else
824 if (iSave.is())
825 {
826 if (bInExecute)
827 hResult = iSave->GetCurrentSelection(&iItem);
828 else
829 hResult = iSave->GetResult(&iItem);
830 }
831
832 if (FAILED(hResult))
833 return;
834
835 // convert and pack results
836 TStringList lFiles;
837 if (iItem.is())
838 {
839 const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
840 if (sURL.getLength() > 0)
841 lFiles.push_back(sURL);
842 }
843
844 if (iItems.is())
845 {
846 DWORD nCount;
847 hResult = iItems->GetCount(&nCount);
848 if ( SUCCEEDED(hResult) )
849 {
850 for (DWORD i=0; i<nCount; ++i)
851 {
852 hResult = iItems->GetItemAt(i, &iItem);
853 if ( SUCCEEDED(hResult) )
854 {
855 const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
856 if (sURL.getLength() > 0)
857 lFiles.push_back(sURL);
858 }
859 }
860 }
861 }
862
863 rRequest->setArgument(PROP_SELECTED_FILES, lFiles.getAsConstList());
864 }
865
866 //-------------------------------------------------------------------------------
impl_sta_ShowDialogModal(const RequestRef & rRequest)867 void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest)
868 {
869 impl_sta_setFiltersOnDialog();
870
871 // SYNCHRONIZED->
872 ::osl::ResettableMutexGuard aLock(m_aMutex);
873
874 TFileDialog iDialog = impl_getBaseDialogInterface();
875 TFileOpenDialog iOpen = m_iDialogOpen;
876 TFileSaveDialog iSave = m_iDialogSave;
877
878 // it's important to know if we are showing the dialog.
879 // Some dialog interface methods cant be called then or some
880 // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles())
881 m_bInExecute = sal_True;
882
883 m_bWasExecuted = sal_True;
884
885 aLock.clear();
886 // <- SYNCHRONIZED
887
888 // we set the directory only if we have a save dialog and a filename
889 // for the other cases, the file dialog remembers its last location
890 // according to its client guid.
891 if( m_sDirectory.getLength())
892 {
893 ComPtr< IShellItem > pFolder;
894 #ifdef __MINGW32__
895 HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(m_sDirectory.getStr()), NULL, IID_IShellItem, reinterpret_cast<void**>(&pFolder) );
896 #else
897 HRESULT hResult = SHCreateItemFromParsingName( m_sDirectory.getStr(), NULL, IID_PPV_ARGS(&pFolder) );
898 #endif
899 if ( SUCCEEDED(hResult) )
900 {
901 if (m_sFilename.getLength())
902 {
903 ::rtl::OUString aFileURL(m_sDirectory);
904 sal_Int32 nIndex = aFileURL.lastIndexOf('/');
905 if (nIndex != aFileURL.getLength()-1)
906 aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/"));
907 aFileURL += m_sFilename;
908
909 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
910
911 BOOL bValue = FALSE;
912 HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
913 if ( bValue )
914 {
915 ::rtl::OUString aExt;
916 UINT nFileType;
917 hResult = iDialog->GetFileTypeIndex(&nFileType);
918 if ( SUCCEEDED(hResult) && nFileType > 0 )
919 {
920 ::sal_Int32 nRealIndex = (nFileType-1); // COM dialog base on 1 ... filter container on 0 .-)
921 ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters);
922 if ( nRealIndex < lFilters.size() )
923 {
924 LPCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec;
925
926 lpFilterExt = wcsrchr( lpFilterExt, '.' );
927 if ( lpFilterExt )
928 aFileURL += reinterpret_cast<const sal_Unicode*>(lpFilterExt);
929 }
930 }
931 }
932
933 // Check existence of file. Set folder only for this special case
934 ::rtl::OUString aSystemPath;
935 osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData );
936
937 WIN32_FIND_DATA aFindFileData;
938 HANDLE hFind = FindFirstFile( reinterpret_cast<LPCWSTR>(aSystemPath.getStr()), &aFindFileData );
939 if (hFind != INVALID_HANDLE_VALUE)
940 iDialog->SetFolder(pFolder);
941 else
942 hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
943
944 FindClose( hFind );
945 }
946 else
947 hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
948 }
949 }
950
951
952 HRESULT hResult = E_FAIL;
953 try
954 {
955 // show dialog and wait for user decision
956 if (iOpen.is())
957 hResult = iOpen->Show( m_hParentWindow ); // parent window needed
958 else
959 if (iSave.is())
960 hResult = iSave->Show( m_hParentWindow ); // parent window needed
961 }
962 catch(...)
963 {}
964
965 // SYNCHRONIZED->
966 aLock.reset();
967 m_bInExecute = sal_False;
968 aLock.clear();
969 // <- SYNCHRONIZED
970
971 if ( FAILED(hResult) )
972 return;
973
974 impl_sta_getSelectedFiles(rRequest);
975 rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, sal_True);
976 }
977
978 //-------------------------------------------------------------------------------
impl_getBaseDialogInterface()979 TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface()
980 {
981 TFileDialog iDialog;
982
983 // SYNCHRONIZED->
984 ::osl::ResettableMutexGuard aLock(m_aMutex);
985
986 if (m_iDialogOpen.is())
987 #ifdef __MINGW32__
988 m_iDialogOpen->QueryInterface(IID_IFileDialog, (void**)(&iDialog));
989 #else
990 m_iDialogOpen.query(&iDialog);
991 #endif
992 if (m_iDialogSave.is())
993 #ifdef __MINGW32__
994 m_iDialogSave->QueryInterface(IID_IFileDialog, (void**)(&iDialog));
995 #else
996 m_iDialogSave.query(&iDialog);
997 #endif
998
999 return iDialog;
1000 }
1001
1002 //-------------------------------------------------------------------------------
impl_getCustomizeInterface()1003 TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface()
1004 {
1005 TFileDialogCustomize iCustom;
1006
1007 // SYNCHRONIZED->
1008 ::osl::ResettableMutexGuard aLock(m_aMutex);
1009
1010 if (m_iDialogOpen.is())
1011 #ifdef __MINGW32__
1012 m_iDialogOpen->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom));
1013 #else
1014 m_iDialogOpen.query(&iCustom);
1015 #endif
1016 else
1017 if (m_iDialogSave.is())
1018 #ifdef __MINGW32__
1019 m_iDialogSave->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom));
1020 #else
1021 m_iDialogSave.query(&iCustom);
1022 #endif
1023
1024 return iCustom;
1025 }
1026
1027 //-------------------------------------------------------------------------------
lcl_removeControlItemsWorkaround(const TFileDialogCustomize & iCustom,::sal_Int16 nControlId)1028 void lcl_removeControlItemsWorkaround(const TFileDialogCustomize& iCustom ,
1029 ::sal_Int16 nControlId)
1030 {
1031 ::sal_Int32 i = 0;
1032 HRESULT hResult;
1033
1034 hResult = iCustom->SetSelectedControlItem(nControlId, 1000);
1035 hResult = S_OK;
1036 while ( SUCCEEDED(hResult) )
1037 hResult = iCustom->RemoveControlItem(nControlId, i++);
1038 }
1039
1040 //-------------------------------------------------------------------------------
impl_sta_SetControlValue(const RequestRef & rRequest)1041 void VistaFilePickerImpl::impl_sta_SetControlValue(const RequestRef& rRequest)
1042 {
1043 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1044 ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1045 css::uno::Any aValue = rRequest->getArgumentOrDefault(PROP_CONTROL_VALUE , css::uno::Any() );
1046
1047 // dont check for right values here ...
1048 // most parameters are optional !
1049
1050 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1051 if ( ! iCustom.is())
1052 return;
1053
1054 switch (nId)
1055 {
1056 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
1057 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1058 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1059 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1060 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1061 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1062 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1063 {
1064 ::sal_Bool bValue = sal_False;
1065 aValue >>= bValue;
1066 iCustom->SetCheckButtonState(nId, bValue);
1067 }
1068 break;
1069
1070 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION :
1071 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
1072 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
1073 {
1074 HRESULT hResult;
1075 switch (nAction)
1076 {
1077 case css::ui::dialogs::ControlActions::DELETE_ITEMS :
1078 {
1079 hResult = iCustom->RemoveAllControlItems(nId);
1080 if ( FAILED(hResult) )
1081 lcl_removeControlItemsWorkaround(iCustom, nId);
1082 }
1083 break;
1084
1085 case css::ui::dialogs::ControlActions::ADD_ITEMS :
1086 {
1087 css::uno::Sequence< ::rtl::OUString > lItems;
1088 aValue >>= lItems;
1089 for (::sal_Int32 i=0; i<lItems.getLength(); ++i)
1090 {
1091 const ::rtl::OUString& sItem = lItems[i];
1092 hResult = iCustom->AddControlItem(nId, i, reinterpret_cast<LPCTSTR>(sItem.getStr()));
1093 }
1094 }
1095 break;
1096
1097 case css::ui::dialogs::ControlActions::SET_SELECT_ITEM :
1098 {
1099 ::sal_Int32 nItem = 0;
1100 aValue >>= nItem;
1101 hResult = iCustom->SetSelectedControlItem(nId, nItem);
1102 }
1103 break;
1104 }
1105 }
1106 break;
1107
1108 case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
1109 {
1110 }
1111 break;
1112 }
1113 }
1114
1115 //-------------------------------------------------------------------------------
impl_sta_GetControlValue(const RequestRef & rRequest)1116 void VistaFilePickerImpl::impl_sta_GetControlValue(const RequestRef& rRequest)
1117 {
1118 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1119 ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1120
1121 // dont check for right values here ...
1122 // most parameters are optional !
1123
1124 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1125 if ( ! iCustom.is())
1126 return;
1127
1128 css::uno::Any aValue;
1129 if( m_bWasExecuted )
1130 switch (nId)
1131 {
1132 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1133 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1134 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1135 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1136 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1137 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1138 {
1139 BOOL bValue = FALSE;
1140 HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue);
1141 if ( SUCCEEDED(hResult) )
1142 aValue = css::uno::makeAny((sal_Bool)bValue);
1143 }
1144 break;
1145 }
1146
1147 if (aValue.hasValue())
1148 rRequest->setArgument(PROP_CONTROL_VALUE, aValue);
1149 }
1150
1151 //-------------------------------------------------------------------------------
impl_sta_SetControlLabel(const RequestRef & rRequest)1152 void VistaFilePickerImpl::impl_sta_SetControlLabel(const RequestRef& rRequest)
1153 {
1154 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1155 ::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString() );
1156
1157 // dont check for right values here ...
1158 // most parameters are optional !
1159
1160 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1161 if ( ! iCustom.is())
1162 return;
1163 iCustom->SetControlLabel ( nId, reinterpret_cast<LPCTSTR>(sLabel.getStr()));
1164 }
1165
1166 //-------------------------------------------------------------------------------
impl_sta_GetControlLabel(const RequestRef &)1167 void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/)
1168 {
1169 }
1170
1171 //-------------------------------------------------------------------------------
impl_sta_EnableControl(const RequestRef & rRequest)1172 void VistaFilePickerImpl::impl_sta_EnableControl(const RequestRef& rRequest)
1173 {
1174 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1175 ::sal_Bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, (::sal_Bool)sal_True);
1176
1177 // dont check for right values here ...
1178 // most parameters are optional !
1179
1180 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1181 if ( ! iCustom.is())
1182 return;
1183
1184 CDCONTROLSTATEF eState = CDCS_VISIBLE;
1185 if (bEnabled)
1186 eState |= CDCS_ENABLED;
1187 else
1188 eState |= CDCS_INACTIVE;
1189
1190 iCustom->SetControlState(nId, eState);
1191 }
1192 //-------------------------------------------------------------------------------
impl_SetDefaultExtension(const rtl::OUString & currentFilter)1193 void VistaFilePickerImpl::impl_SetDefaultExtension( const rtl::OUString& currentFilter )
1194 {
1195 TFileDialog iDialog = impl_getBaseDialogInterface();
1196 if (currentFilter.getLength())
1197 {
1198 rtl::OUString FilterExt;
1199 m_lFilters.getFilter(currentFilter, FilterExt);
1200
1201 sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
1202 const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
1203
1204 sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
1205 if (posOfSemiColon < 0)
1206 posOfSemiColon = FilterExt.getLength() - 1;
1207
1208 FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
1209 iDialog->SetDefaultExtension ( reinterpret_cast<LPCTSTR>(FilterExt.getStr()) );
1210 }
1211 }
1212
impl_refreshFileDialog(TFileDialog iDialog)1213 static void impl_refreshFileDialog( TFileDialog iDialog )
1214 {
1215 if ( SUCCEEDED(iDialog->SetFileName(L"")) &&
1216 SUCCEEDED(iDialog->SetFileName(L"*.*")) )
1217 {
1218 IOleWindow* iOleWindow;
1219 #ifdef __MINGW32__
1220 if (SUCCEEDED(iDialog->QueryInterface(IID_IOleWindow, reinterpret_cast<void**>(&iOleWindow))))
1221 #else
1222 if (SUCCEEDED(iDialog->QueryInterface(IID_PPV_ARGS(&iOleWindow))))
1223 #endif
1224 {
1225 HWND hwnd;
1226 if (SUCCEEDED(iOleWindow->GetWindow(&hwnd)))
1227 {
1228 PostMessage(hwnd, WM_COMMAND, IDOK, 0);
1229 }
1230 iOleWindow->Release();
1231 }
1232 }
1233 }
1234
1235 //-------------------------------------------------------------------------------
onAutoExtensionChanged(bool bChecked)1236 void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked)
1237 {
1238 // SYNCHRONIZED->
1239 ::osl::ResettableMutexGuard aLock(m_aMutex);
1240
1241 const ::rtl::OUString sFilter = m_lFilters.getCurrentFilter ();
1242 ::rtl::OUString sExt ;
1243 if ( !m_lFilters.getFilter (sFilter, sExt))
1244 return;
1245
1246 TFileDialog iDialog = impl_getBaseDialogInterface();
1247
1248 aLock.clear();
1249 // <- SYNCHRONIZED
1250
1251 LPCWSTR pExt = 0;
1252 if ( bChecked )
1253 {
1254 pExt = reinterpret_cast<LPCTSTR>(sExt.getStr());
1255 pExt = wcsrchr( pExt, '.' );
1256 if ( pExt )
1257 pExt++;
1258 }
1259 iDialog->SetDefaultExtension( pExt );
1260 }
1261
onFileTypeChanged(UINT)1262 bool VistaFilePickerImpl::onFileTypeChanged( UINT /*nTypeIndex*/ )
1263 {
1264 return true;
1265 }
1266
1267 } // namespace vista
1268 } // namespace win32
1269 } // namespace fpicker
1270