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