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