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 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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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, 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) ) 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 LPCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec; 923 924 lpFilterExt = wcsrchr( lpFilterExt, '.' ); 925 if ( lpFilterExt ) 926 aFileURL += reinterpret_cast<const sal_Unicode*>(lpFilterExt); 927 } 928 } 929 930 // Check existence of file. Set folder only for this special case 931 ::rtl::OUString aSystemPath; 932 osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData ); 933 934 WIN32_FIND_DATA aFindFileData; 935 HANDLE hFind = FindFirstFile( reinterpret_cast<LPCWSTR>(aSystemPath.getStr()), &aFindFileData ); 936 if (hFind != INVALID_HANDLE_VALUE) 937 iDialog->SetFolder(pFolder); 938 else 939 hResult = iDialog->AddPlace(pFolder, FDAP_TOP); 940 941 FindClose( hFind ); 942 } 943 else 944 hResult = iDialog->AddPlace(pFolder, FDAP_TOP); 945 } 946 } 947 948 949 HRESULT hResult = E_FAIL; 950 try 951 { 952 // show dialog and wait for user decision 953 if (iOpen.is()) 954 hResult = iOpen->Show( m_hParentWindow ); // parent window needed 955 else 956 if (iSave.is()) 957 hResult = iSave->Show( m_hParentWindow ); // parent window needed 958 } 959 catch(...) 960 {} 961 962 // SYNCHRONIZED-> 963 aLock.reset(); 964 m_bInExecute = sal_False; 965 aLock.clear(); 966 // <- SYNCHRONIZED 967 968 if ( FAILED(hResult) ) 969 return; 970 971 impl_sta_getSelectedFiles(rRequest); 972 rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, sal_True); 973 } 974 975 //------------------------------------------------------------------------------- 976 TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface() 977 { 978 TFileDialog iDialog; 979 980 // SYNCHRONIZED-> 981 ::osl::ResettableMutexGuard aLock(m_aMutex); 982 983 if (m_iDialogOpen.is()) 984 #ifdef __MINGW32__ 985 m_iDialogOpen->QueryInterface(IID_IFileDialog, (void**)(&iDialog)); 986 #else 987 m_iDialogOpen.query(&iDialog); 988 #endif 989 if (m_iDialogSave.is()) 990 #ifdef __MINGW32__ 991 m_iDialogSave->QueryInterface(IID_IFileDialog, (void**)(&iDialog)); 992 #else 993 m_iDialogSave.query(&iDialog); 994 #endif 995 996 return iDialog; 997 } 998 999 //------------------------------------------------------------------------------- 1000 TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface() 1001 { 1002 TFileDialogCustomize iCustom; 1003 1004 // SYNCHRONIZED-> 1005 ::osl::ResettableMutexGuard aLock(m_aMutex); 1006 1007 if (m_iDialogOpen.is()) 1008 #ifdef __MINGW32__ 1009 m_iDialogOpen->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom)); 1010 #else 1011 m_iDialogOpen.query(&iCustom); 1012 #endif 1013 else 1014 if (m_iDialogSave.is()) 1015 #ifdef __MINGW32__ 1016 m_iDialogSave->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom)); 1017 #else 1018 m_iDialogSave.query(&iCustom); 1019 #endif 1020 1021 return iCustom; 1022 } 1023 1024 //------------------------------------------------------------------------------- 1025 void lcl_removeControlItemsWorkaround(const TFileDialogCustomize& iCustom , 1026 ::sal_Int16 nControlId) 1027 { 1028 ::sal_Int32 i = 0; 1029 HRESULT hResult; 1030 1031 hResult = iCustom->SetSelectedControlItem(nControlId, 1000); 1032 hResult = S_OK; 1033 while ( SUCCEEDED(hResult) ) 1034 hResult = iCustom->RemoveControlItem(nControlId, i++); 1035 } 1036 1037 //------------------------------------------------------------------------------- 1038 void VistaFilePickerImpl::impl_sta_SetControlValue(const RequestRef& rRequest) 1039 { 1040 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); 1041 ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION); 1042 css::uno::Any aValue = rRequest->getArgumentOrDefault(PROP_CONTROL_VALUE , css::uno::Any() ); 1043 1044 // dont check for right values here ... 1045 // most parameters are optional ! 1046 1047 TFileDialogCustomize iCustom = impl_getCustomizeInterface(); 1048 if ( ! iCustom.is()) 1049 return; 1050 1051 switch (nId) 1052 { 1053 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION : 1054 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD : 1055 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY : 1056 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS : 1057 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK : 1058 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now ! 1059 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION : 1060 { 1061 ::sal_Bool bValue = sal_False; 1062 aValue >>= bValue; 1063 iCustom->SetCheckButtonState(nId, bValue); 1064 } 1065 break; 1066 1067 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION : 1068 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE : 1069 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE : 1070 { 1071 HRESULT hResult; 1072 switch (nAction) 1073 { 1074 case css::ui::dialogs::ControlActions::DELETE_ITEMS : 1075 { 1076 hResult = iCustom->RemoveAllControlItems(nId); 1077 if ( FAILED(hResult) ) 1078 lcl_removeControlItemsWorkaround(iCustom, nId); 1079 } 1080 break; 1081 1082 case css::ui::dialogs::ControlActions::ADD_ITEMS : 1083 { 1084 css::uno::Sequence< ::rtl::OUString > lItems; 1085 aValue >>= lItems; 1086 for (::sal_Int32 i=0; i<lItems.getLength(); ++i) 1087 { 1088 const ::rtl::OUString& sItem = lItems[i]; 1089 hResult = iCustom->AddControlItem(nId, i, reinterpret_cast<LPCTSTR>(sItem.getStr())); 1090 } 1091 } 1092 break; 1093 1094 case css::ui::dialogs::ControlActions::SET_SELECT_ITEM : 1095 { 1096 ::sal_Int32 nItem = 0; 1097 aValue >>= nItem; 1098 hResult = iCustom->SetSelectedControlItem(nId, nItem); 1099 } 1100 break; 1101 } 1102 } 1103 break; 1104 1105 case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY : 1106 { 1107 } 1108 break; 1109 } 1110 } 1111 1112 //------------------------------------------------------------------------------- 1113 void VistaFilePickerImpl::impl_sta_GetControlValue(const RequestRef& rRequest) 1114 { 1115 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); 1116 ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION); 1117 1118 // dont check for right values here ... 1119 // most parameters are optional ! 1120 1121 TFileDialogCustomize iCustom = impl_getCustomizeInterface(); 1122 if ( ! iCustom.is()) 1123 return; 1124 1125 css::uno::Any aValue; 1126 if( m_bWasExecuted ) 1127 switch (nId) 1128 { 1129 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD : 1130 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY : 1131 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS : 1132 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK : 1133 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now ! 1134 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION : 1135 { 1136 BOOL bValue = FALSE; 1137 HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue); 1138 if ( SUCCEEDED(hResult) ) 1139 aValue = css::uno::makeAny((sal_Bool)bValue); 1140 } 1141 break; 1142 } 1143 1144 if (aValue.hasValue()) 1145 rRequest->setArgument(PROP_CONTROL_VALUE, aValue); 1146 } 1147 1148 //------------------------------------------------------------------------------- 1149 void VistaFilePickerImpl::impl_sta_SetControlLabel(const RequestRef& rRequest) 1150 { 1151 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); 1152 ::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString() ); 1153 1154 // dont check for right values here ... 1155 // most parameters are optional ! 1156 1157 TFileDialogCustomize iCustom = impl_getCustomizeInterface(); 1158 if ( ! iCustom.is()) 1159 return; 1160 iCustom->SetControlLabel ( nId, reinterpret_cast<LPCTSTR>(sLabel.getStr())); 1161 } 1162 1163 //------------------------------------------------------------------------------- 1164 void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/) 1165 { 1166 } 1167 1168 //------------------------------------------------------------------------------- 1169 void VistaFilePickerImpl::impl_sta_EnableControl(const RequestRef& rRequest) 1170 { 1171 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); 1172 ::sal_Bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, (::sal_Bool)sal_True); 1173 1174 // dont check for right values here ... 1175 // most parameters are optional ! 1176 1177 TFileDialogCustomize iCustom = impl_getCustomizeInterface(); 1178 if ( ! iCustom.is()) 1179 return; 1180 1181 CDCONTROLSTATEF eState = CDCS_VISIBLE; 1182 if (bEnabled) 1183 eState |= CDCS_ENABLED; 1184 else 1185 eState |= CDCS_INACTIVE; 1186 1187 iCustom->SetControlState(nId, eState); 1188 } 1189 //------------------------------------------------------------------------------- 1190 void VistaFilePickerImpl::impl_SetDefaultExtension( const rtl::OUString& currentFilter ) 1191 { 1192 TFileDialog iDialog = impl_getBaseDialogInterface(); 1193 if (currentFilter.getLength()) 1194 { 1195 rtl::OUString FilterExt; 1196 m_lFilters.getFilter(currentFilter, FilterExt); 1197 1198 sal_Int32 posOfPoint = FilterExt.indexOf(L'.'); 1199 const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1; 1200 1201 sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1; 1202 if (posOfSemiColon < 0) 1203 posOfSemiColon = FilterExt.getLength() - 1; 1204 1205 FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint); 1206 iDialog->SetDefaultExtension ( reinterpret_cast<LPCTSTR>(FilterExt.getStr()) ); 1207 } 1208 } 1209 1210 static void impl_refreshFileDialog( TFileDialog iDialog ) 1211 { 1212 if ( SUCCEEDED(iDialog->SetFileName(L"")) && 1213 SUCCEEDED(iDialog->SetFileName(L"*.*")) ) 1214 { 1215 IOleWindow* iOleWindow; 1216 #ifdef __MINGW32__ 1217 if (SUCCEEDED(iDialog->QueryInterface(IID_IOleWindow, reinterpret_cast<void**>(&iOleWindow)))) 1218 #else 1219 if (SUCCEEDED(iDialog->QueryInterface(IID_PPV_ARGS(&iOleWindow)))) 1220 #endif 1221 { 1222 HWND hwnd; 1223 if (SUCCEEDED(iOleWindow->GetWindow(&hwnd))) 1224 { 1225 PostMessage(hwnd, WM_COMMAND, IDOK, 0); 1226 } 1227 iOleWindow->Release(); 1228 } 1229 } 1230 } 1231 1232 //------------------------------------------------------------------------------- 1233 void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked) 1234 { 1235 // SYNCHRONIZED-> 1236 ::osl::ResettableMutexGuard aLock(m_aMutex); 1237 1238 const ::rtl::OUString sFilter = m_lFilters.getCurrentFilter (); 1239 ::rtl::OUString sExt ; 1240 if ( !m_lFilters.getFilter (sFilter, sExt)) 1241 return; 1242 1243 TFileDialog iDialog = impl_getBaseDialogInterface(); 1244 1245 aLock.clear(); 1246 // <- SYNCHRONIZED 1247 1248 LPCWSTR pExt = 0; 1249 if ( bChecked ) 1250 { 1251 pExt = reinterpret_cast<LPCTSTR>(sExt.getStr()); 1252 pExt = wcsrchr( pExt, '.' ); 1253 if ( pExt ) 1254 pExt++; 1255 } 1256 iDialog->SetDefaultExtension( pExt ); 1257 } 1258 1259 bool VistaFilePickerImpl::onFileTypeChanged( UINT /*nTypeIndex*/ ) 1260 { 1261 return true; 1262 } 1263 1264 } // namespace vista 1265 } // namespace win32 1266 } // namespace fpicker 1267