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.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 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.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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 1167 void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/) 1168 { 1169 } 1170 1171 //------------------------------------------------------------------------------- 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 //------------------------------------------------------------------------------- 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 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 //------------------------------------------------------------------------------- 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 1262 bool VistaFilePickerImpl::onFileTypeChanged( UINT /*nTypeIndex*/ ) 1263 { 1264 return true; 1265 } 1266 1267 } // namespace vista 1268 } // namespace win32 1269 } // namespace fpicker 1270