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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_fpicker.hxx" 26 27 #include "OfficeFilePicker.hxx" 28 #include "iodlg.hxx" 29 30 #ifndef _LIST_ 31 #include <list> 32 #endif 33 #ifndef _FUNCTIONAL_ 34 #include <functional> 35 #endif 36 #ifndef _ALGORITHM_ 37 #include <algorithm> 38 #endif 39 #include <tools/urlobj.hxx> 40 #include <tools/debug.hxx> 41 #define _SVSTDARR_STRINGSDTOR 42 #include "svl/svstdarr.hxx" 43 #include <com/sun/star/uno/Any.hxx> 44 #include <com/sun/star/ui/dialogs/FilePickerEvent.hpp> 45 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> 46 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 47 #include <com/sun/star/beans/PropertyValue.hpp> 48 #include <com/sun/star/beans/XPropertySet.hpp> 49 #include <com/sun/star/awt/XWindow.hpp> 50 #include <com/sun/star/beans/StringPair.hpp> 51 #include <com/sun/star/uno/Sequence.hxx> 52 #include <com/sun/star/beans/NamedValue.hpp> 53 #include <unotools/ucbhelper.hxx> 54 #include <unotools/pathoptions.hxx> 55 #include <comphelper/sequence.hxx> 56 #include <cppuhelper/typeprovider.hxx> 57 #include "vos/mutex.hxx" 58 #ifndef _SV_APP_HXX 59 #include "vcl/svapp.hxx" 60 #endif 61 62 // define ---------------------------------------------------------------- 63 64 #define MAKE_ANY ::com::sun::star::uno::makeAny 65 66 // using ---------------------------------------------------------------- 67 68 using namespace ::com::sun::star::container; 69 using namespace ::com::sun::star::lang; 70 using namespace ::com::sun::star::ui::dialogs; 71 using namespace ::com::sun::star::uno; 72 using namespace ::com::sun::star::beans; 73 using namespace ::com::sun::star::awt; 74 using namespace ::utl; 75 76 //===================================================================== 77 78 //===================================================================== 79 80 struct FilterEntry 81 { 82 protected: 83 ::rtl::OUString m_sTitle; 84 ::rtl::OUString m_sFilter; 85 86 UnoFilterList m_aSubFilters; 87 88 public: 89 FilterEntry( const ::rtl::OUString& _rTitle, const ::rtl::OUString& _rFilter ) 90 :m_sTitle( _rTitle ) 91 ,m_sFilter( _rFilter ) 92 { 93 } 94 95 FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters ); 96 97 ::rtl::OUString getTitle() const { return m_sTitle; } 98 ::rtl::OUString getFilter() const { return m_sFilter; } 99 100 /// determines if the filter has sub filter (i.e., the filter is a filter group in real) 101 sal_Bool hasSubFilters( ) const; 102 103 /** retrieves the filters belonging to the entry 104 @return 105 the number of sub filters 106 */ 107 sal_Int32 getSubFilters( UnoFilterList& _rSubFilterList ); 108 109 // helpers for iterating the sub filters 110 const UnoFilterEntry* beginSubFilters() const { return m_aSubFilters.getConstArray(); } 111 const UnoFilterEntry* endSubFilters() const { return m_aSubFilters.getConstArray() + m_aSubFilters.getLength(); } 112 }; 113 114 //===================================================================== 115 116 //--------------------------------------------------------------------- 117 FilterEntry::FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters ) 118 :m_sTitle( _rTitle ) 119 ,m_aSubFilters( _rSubFilters ) 120 { 121 } 122 123 //--------------------------------------------------------------------- 124 sal_Bool FilterEntry::hasSubFilters( ) const 125 { 126 return ( 0 < m_aSubFilters.getLength() ); 127 } 128 129 //--------------------------------------------------------------------- 130 sal_Int32 FilterEntry::getSubFilters( UnoFilterList& _rSubFilterList ) 131 { 132 _rSubFilterList = m_aSubFilters; 133 return m_aSubFilters.getLength(); 134 } 135 136 // struct ElementEntry_Impl ---------------------------------------------- 137 138 struct ElementEntry_Impl 139 { 140 sal_Int16 m_nElementID; 141 sal_Int16 m_nControlAction; 142 Any m_aValue; 143 rtl::OUString m_aLabel; 144 sal_Bool m_bEnabled : 1; 145 146 sal_Bool m_bHasValue : 1; 147 sal_Bool m_bHasLabel : 1; 148 sal_Bool m_bHasEnabled : 1; 149 150 ElementEntry_Impl( sal_Int16 nId ); 151 152 void setValue( const Any& rVal ) { m_aValue = rVal; m_bHasValue = sal_True; } 153 void setAction( sal_Int16 nAction ) { m_nControlAction = nAction; } 154 void setLabel( const rtl::OUString& rVal ) { m_aLabel = rVal; m_bHasLabel = sal_True; } 155 void setEnabled( sal_Bool bEnabled ) { m_bEnabled = bEnabled; m_bHasEnabled = sal_True; } 156 }; 157 158 ElementEntry_Impl::ElementEntry_Impl( sal_Int16 nId ) 159 : m_nElementID( nId ) 160 , m_nControlAction( 0 ) 161 , m_bEnabled( sal_False ) 162 , m_bHasValue( sal_False ) 163 , m_bHasLabel( sal_False ) 164 , m_bHasEnabled( sal_False ) 165 {} 166 167 //------------------------------------------------------------------------------------ 168 void SvtFilePicker::prepareExecute() 169 { 170 // set the default directory 171 // --**-- doesn't match the spec yet 172 if ( m_aDisplayDirectory.getLength() > 0 || m_aDefaultName.getLength() > 0 ) 173 { 174 sal_Bool isFileSet = sal_False; 175 if ( m_aDisplayDirectory.getLength() > 0 ) 176 { 177 178 INetURLObject aPath; 179 INetURLObject givenPath( m_aDisplayDirectory ); 180 if (!givenPath.HasError()) 181 aPath = givenPath; 182 else 183 { 184 INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() ); 185 aPath = aStdDirObj; 186 } 187 if ( m_aDefaultName.getLength() > 0 ) 188 { 189 aPath.insertName( m_aDefaultName ); 190 getDialog()->SetHasFilename( true ); 191 } 192 String sPath = aPath.GetMainURL( INetURLObject::NO_DECODE ); 193 getDialog()->SetPath( sPath ); 194 isFileSet = sal_True; 195 } 196 if ( !isFileSet && m_aDefaultName.getLength() > 0 ) 197 { 198 getDialog()->SetPath( m_aDefaultName ); 199 getDialog()->SetHasFilename( true ); 200 } 201 } 202 else 203 { 204 // Default-Standard-Dir setzen 205 INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() ); 206 getDialog()->SetPath( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) ); 207 } 208 209 // set the control values and set the control labels, too 210 if ( m_pElemList && !m_pElemList->empty() ) 211 { 212 ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() ); 213 214 ElementList::iterator aListIter; 215 for ( aListIter = m_pElemList->begin(); 216 aListIter != m_pElemList->end(); ++aListIter ) 217 { 218 ElementEntry_Impl& rEntry = *aListIter; 219 if ( rEntry.m_bHasValue ) 220 aAccess.setValue( rEntry.m_nElementID, rEntry.m_nControlAction, rEntry.m_aValue ); 221 if ( rEntry.m_bHasLabel ) 222 aAccess.setLabel( rEntry.m_nElementID, rEntry.m_aLabel ); 223 if ( rEntry.m_bHasEnabled ) 224 aAccess.enableControl( rEntry.m_nElementID, rEntry.m_bEnabled ); 225 } 226 227 getDialog()->updateListboxLabelSizes(); 228 } 229 230 if ( m_pFilterList && !m_pFilterList->empty() ) 231 { 232 for ( FilterList::iterator aListIter = m_pFilterList->begin(); 233 aListIter != m_pFilterList->end(); 234 ++aListIter 235 ) 236 { 237 if ( aListIter->hasSubFilters() ) 238 { // it's a filter group 239 UnoFilterList aSubFilters; 240 aListIter->getSubFilters( aSubFilters ); 241 242 getDialog()->AddFilterGroup( aListIter->getTitle(), aSubFilters ); 243 } 244 else 245 // it's a single filter 246 getDialog()->AddFilter( aListIter->getTitle(), aListIter->getFilter() ); 247 } 248 } 249 250 // set the default filter 251 if ( m_aCurrentFilter.getLength() > 0 ) 252 getDialog()->SetCurFilter( m_aCurrentFilter ); 253 254 } 255 256 //----------------------------------------------------------------------------- 257 IMPL_LINK( SvtFilePicker, DialogClosedHdl, Dialog*, pDlg ) 258 { 259 if ( m_xDlgClosedListener.is() ) 260 { 261 sal_Int16 nRet = static_cast< sal_Int16 >( pDlg->GetResult() ); 262 ::com::sun::star::ui::dialogs::DialogClosedEvent aEvent( *this, nRet ); 263 m_xDlgClosedListener->dialogClosed( aEvent ); 264 m_xDlgClosedListener.clear(); 265 } 266 return 0; 267 } 268 269 //------------------------------------------------------------------------------------ 270 // SvtFilePicker 271 //------------------------------------------------------------------------------------ 272 273 //------------------------------------------------------------------------------------ 274 WinBits SvtFilePicker::getWinBits( WinBits& rExtraBits ) 275 { 276 // set the winbits for creating the filedialog 277 WinBits nBits = 0L; 278 rExtraBits = 0L; 279 280 // set the standard bits according to the service name 281 if ( m_nServiceType == TemplateDescription::FILEOPEN_SIMPLE ) 282 { 283 nBits = WB_OPEN; 284 } 285 else if ( m_nServiceType == TemplateDescription::FILESAVE_SIMPLE ) 286 { 287 nBits = WB_SAVEAS; 288 } 289 else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION ) 290 { 291 nBits = WB_SAVEAS; 292 rExtraBits = SFX_EXTRA_AUTOEXTENSION; 293 } 294 else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD ) 295 { 296 nBits = WB_SAVEAS | SFXWB_PASSWORD; 297 rExtraBits = SFX_EXTRA_AUTOEXTENSION; 298 } 299 else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS ) 300 { 301 nBits = WB_SAVEAS | SFXWB_PASSWORD; 302 rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_FILTEROPTIONS; 303 } 304 else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE ) 305 { 306 nBits = WB_SAVEAS; 307 rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_TEMPLATES; 308 } 309 else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION ) 310 { 311 nBits = WB_SAVEAS; 312 rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_SELECTION; 313 } 314 315 else if ( m_nServiceType == TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE ) 316 { 317 nBits = WB_OPEN; 318 rExtraBits = SFX_EXTRA_INSERTASLINK | SFX_EXTRA_SHOWPREVIEW | SFX_EXTRA_IMAGE_TEMPLATE; 319 } 320 else if ( m_nServiceType == TemplateDescription::FILEOPEN_PLAY ) 321 { 322 nBits = WB_OPEN; 323 rExtraBits = SFX_EXTRA_PLAYBUTTON; 324 } 325 else if ( m_nServiceType == TemplateDescription::FILEOPEN_READONLY_VERSION ) 326 { 327 nBits = WB_OPEN | SFXWB_READONLY; 328 rExtraBits = SFX_EXTRA_SHOWVERSIONS; 329 } 330 else if ( m_nServiceType == TemplateDescription::FILEOPEN_LINK_PREVIEW ) 331 { 332 nBits = WB_OPEN; 333 rExtraBits = SFX_EXTRA_INSERTASLINK | SFX_EXTRA_SHOWPREVIEW; 334 } 335 if ( m_bMultiSelection && ( ( nBits & WB_OPEN ) == WB_OPEN ) ) 336 nBits |= SFXWB_MULTISELECTION; 337 338 return nBits; 339 } 340 341 //------------------------------------------------------------------------------------ 342 void SvtFilePicker::notify( sal_Int16 _nEventId, sal_Int16 _nControlId ) 343 { 344 if ( !m_xListener.is() ) 345 return; 346 347 FilePickerEvent aEvent( *this, _nControlId ); 348 349 switch ( _nEventId ) 350 { 351 case FILE_SELECTION_CHANGED: 352 m_xListener->fileSelectionChanged( aEvent ); 353 break; 354 case DIRECTORY_CHANGED: 355 m_xListener->directoryChanged( aEvent ); 356 break; 357 case HELP_REQUESTED: 358 m_xListener->helpRequested( aEvent ); 359 break; 360 case CTRL_STATE_CHANGED: 361 m_xListener->controlStateChanged( aEvent ); 362 break; 363 case DIALOG_SIZE_CHANGED: 364 m_xListener->dialogSizeChanged(); 365 break; 366 default: 367 DBG_ERRORFILE( "SvtFilePicker::notify(): Unknown event id!" ); 368 break; 369 } 370 } 371 372 //------------------------------------------------------------------------------------ 373 namespace { 374 //................................................................................ 375 struct FilterTitleMatch : public ::std::unary_function< FilterEntry, bool > 376 { 377 protected: 378 const ::rtl::OUString& rTitle; 379 380 public: 381 FilterTitleMatch( const ::rtl::OUString& _rTitle ) : rTitle( _rTitle ) { } 382 383 //............................................................................ 384 bool operator () ( const FilterEntry& _rEntry ) 385 { 386 sal_Bool bMatch; 387 if ( !_rEntry.hasSubFilters() ) 388 // a real filter 389 bMatch = ( _rEntry.getTitle() == rTitle ); 390 else 391 // a filter group -> search the sub filters 392 bMatch = 393 _rEntry.endSubFilters() != ::std::find_if( 394 _rEntry.beginSubFilters(), 395 _rEntry.endSubFilters(), 396 *this 397 ); 398 399 return bMatch ? true : false; 400 } 401 bool operator () ( const UnoFilterEntry& _rEntry ) 402 { 403 return _rEntry.First == rTitle ? true : false; 404 } 405 }; 406 } 407 408 //------------------------------------------------------------------------------------ 409 sal_Bool SvtFilePicker::FilterNameExists( const ::rtl::OUString& rTitle ) 410 { 411 sal_Bool bRet = sal_False; 412 413 if ( m_pFilterList ) 414 bRet = 415 m_pFilterList->end() != ::std::find_if( 416 m_pFilterList->begin(), 417 m_pFilterList->end(), 418 FilterTitleMatch( rTitle ) 419 ); 420 421 return bRet; 422 } 423 424 //------------------------------------------------------------------------------------ 425 sal_Bool SvtFilePicker::FilterNameExists( const UnoFilterList& _rGroupedFilters ) 426 { 427 sal_Bool bRet = sal_False; 428 429 if ( m_pFilterList ) 430 { 431 const UnoFilterEntry* pStart = _rGroupedFilters.getConstArray(); 432 const UnoFilterEntry* pEnd = pStart + _rGroupedFilters.getLength(); 433 for ( ; pStart != pEnd; ++pStart ) 434 if ( m_pFilterList->end() != ::std::find_if( m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch( pStart->First ) ) ) 435 break; 436 437 bRet = pStart != pEnd; 438 } 439 440 return bRet; 441 } 442 443 //------------------------------------------------------------------------------------ 444 void SvtFilePicker::ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter ) 445 { 446 if ( !m_pFilterList ) 447 { 448 m_pFilterList = new FilterList; 449 450 // set the first filter to the current filter 451 if ( ! m_aCurrentFilter.getLength() ) 452 m_aCurrentFilter = _rInitialCurrentFilter; 453 } 454 } 455 456 //------------------------------------------------------------------------------------ 457 // class SvtFilePicker 458 //------------------------------------------------------------------------------------ 459 SvtFilePicker::SvtFilePicker( const Reference < XMultiServiceFactory >& xFactory ) 460 :OCommonPicker( xFactory ) 461 ,m_pFilterList ( NULL ) 462 ,m_pElemList ( NULL ) 463 ,m_bMultiSelection ( sal_False ) 464 ,m_nServiceType ( TemplateDescription::FILEOPEN_SIMPLE ) 465 { 466 } 467 468 SvtFilePicker::~SvtFilePicker() 469 { 470 if ( m_pFilterList && !m_pFilterList->empty() ) 471 m_pFilterList->erase( m_pFilterList->begin(), m_pFilterList->end() ); 472 delete m_pFilterList; 473 474 if ( m_pElemList && !m_pElemList->empty() ) 475 m_pElemList->erase( m_pElemList->begin(), m_pElemList->end() ); 476 delete m_pElemList; 477 } 478 479 //------------------------------------------------------------------------------------ 480 sal_Int16 SvtFilePicker::implExecutePicker( ) 481 { 482 getDialog()->SetFileCallback( this ); 483 484 prepareExecute(); 485 486 getDialog()->EnableAutocompletion( sal_True ); 487 // now we are ready to execute the dialog 488 sal_Int16 nRet = getDialog()->Execute(); 489 490 // the execution of the dialog yields, so it is possible the at this point the window or the dialog is closed 491 if ( getDialog() ) 492 getDialog()->SetFileCallback( NULL ); 493 494 return nRet; 495 } 496 497 //------------------------------------------------------------------------------------ 498 SvtFileDialog* SvtFilePicker::implCreateDialog( Window* _pParent ) 499 { 500 WinBits nExtraBits; 501 WinBits nBits = getWinBits( nExtraBits ); 502 503 SvtFileDialog* dialog = new SvtFileDialog( _pParent, nBits, nExtraBits ); 504 505 // Set StandardDir if present 506 if ( m_aStandardDir.getLength() > 0) 507 { 508 String sStandardDir = String( m_aStandardDir ); 509 dialog->SetStandardDir( sStandardDir ); 510 dialog->SetBlackList( m_aBlackList ); 511 } 512 513 return dialog; 514 } 515 516 //------------------------------------------------------------------------------------ 517 // disambiguate XInterface 518 //------------------------------------------------------------------------------------ 519 IMPLEMENT_FORWARD_XINTERFACE2( SvtFilePicker, OCommonPicker, SvtFilePicker_Base ) 520 521 //------------------------------------------------------------------------------------ 522 // disambiguate XTypeProvider 523 //------------------------------------------------------------------------------------ 524 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SvtFilePicker, OCommonPicker, SvtFilePicker_Base ) 525 526 //------------------------------------------------------------------------------------ 527 // XExecutableDialog functions 528 //------------------------------------------------------------------------------------ 529 530 //------------------------------------------------------------------------------------ 531 void SAL_CALL SvtFilePicker::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException) 532 { 533 OCommonPicker::setTitle( _rTitle ); 534 } 535 536 //------------------------------------------------------------------------------------ 537 sal_Int16 SAL_CALL SvtFilePicker::execute( ) throw (RuntimeException) 538 { 539 return OCommonPicker::execute(); 540 } 541 542 //------------------------------------------------------------------------------------ 543 // XAsynchronousExecutableDialog functions 544 //------------------------------------------------------------------------------------ 545 546 //------------------------------------------------------------------------------------ 547 void SAL_CALL SvtFilePicker::setDialogTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException) 548 { 549 setTitle( _rTitle ); 550 } 551 552 //------------------------------------------------------------------------------------ 553 void SAL_CALL SvtFilePicker::startExecuteModal( const Reference< ::com::sun::star::ui::dialogs::XDialogClosedListener >& xListener ) throw (RuntimeException) 554 { 555 m_xDlgClosedListener = xListener; 556 prepareDialog(); 557 prepareExecute(); 558 getDialog()->EnableAutocompletion( sal_True ); 559 getDialog()->StartExecuteModal( LINK( this, SvtFilePicker, DialogClosedHdl ) ); 560 } 561 562 //------------------------------------------------------------------------------------ 563 // XFilePicker functions 564 //------------------------------------------------------------------------------------ 565 566 void SAL_CALL SvtFilePicker::setMultiSelectionMode( sal_Bool bMode ) throw( RuntimeException ) 567 { 568 checkAlive(); 569 570 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 571 m_bMultiSelection = bMode; 572 } 573 574 void SAL_CALL SvtFilePicker::setDefaultName( const rtl::OUString& aName ) throw( RuntimeException ) 575 { 576 checkAlive(); 577 578 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 579 m_aDefaultName = aName; 580 } 581 582 void SAL_CALL SvtFilePicker::setDisplayDirectory( const rtl::OUString& aDirectory ) 583 throw( IllegalArgumentException, RuntimeException ) 584 { 585 checkAlive(); 586 587 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 588 m_aDisplayDirectory = aDirectory; 589 } 590 591 rtl::OUString SAL_CALL SvtFilePicker::getDisplayDirectory() throw( RuntimeException ) 592 { 593 checkAlive(); 594 595 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 596 if ( getDialog() ) 597 { 598 rtl::OUString aPath = getDialog()->GetPath(); 599 600 // #97148# ---- 601 if( m_aOldHideDirectory == aPath ) 602 return m_aOldDisplayDirectory; 603 m_aOldHideDirectory = aPath; 604 605 // #102204# ----- 606 if( !getDialog()->ContentIsFolder( aPath ) ) 607 { 608 INetURLObject aFolder( aPath ); 609 aFolder.CutLastName(); 610 aPath = aFolder.GetMainURL( INetURLObject::NO_DECODE ); 611 } 612 m_aOldDisplayDirectory = aPath; 613 return aPath; 614 } 615 else 616 return m_aDisplayDirectory; 617 } 618 619 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getFiles() throw( RuntimeException ) 620 { 621 checkAlive(); 622 623 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 624 if ( ! getDialog() ) 625 { 626 Sequence< rtl::OUString > aEmpty; 627 return aEmpty; 628 } 629 630 // if there is more than one path we have to return the path to the 631 // files first and then the list of the selected entries 632 633 SvStringsDtor* pPathList = getDialog()->GetPathList(); 634 sal_uInt16 i, nCount = pPathList->Count(); 635 sal_uInt16 nTotal = nCount > 1 ? nCount+1: nCount; 636 637 Sequence< rtl::OUString > aPath( nTotal ); 638 639 if ( nCount == 1 ) 640 aPath[0] = rtl::OUString( *pPathList->GetObject( 0 ) ); 641 else if ( nCount > 1 ) 642 { 643 INetURLObject aObj( *pPathList->GetObject( 0 ) ); 644 aObj.removeSegment(); 645 aPath[0] = aObj.GetMainURL( INetURLObject::NO_DECODE ); 646 647 for ( i = 0; i < nCount; /* i++ is done below */ ) 648 { 649 aObj.SetURL( *pPathList->GetObject(i++) ); 650 aPath[i] = aObj.getName(); 651 } 652 } 653 654 delete pPathList; 655 return aPath; 656 } 657 658 //------------------------------------------------------------------------------------ 659 // XFilePickerControlAccess functions 660 //------------------------------------------------------------------------------------ 661 662 void SAL_CALL SvtFilePicker::setValue( sal_Int16 nElementID, 663 sal_Int16 nControlAction, 664 const Any& rValue ) 665 throw( RuntimeException ) 666 { 667 checkAlive(); 668 669 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 670 if ( getDialog() ) 671 { 672 ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() ); 673 aAccess.setValue( nElementID, nControlAction, rValue ); 674 } 675 else 676 { 677 if ( !m_pElemList ) 678 m_pElemList = new ElementList; 679 680 sal_Bool bFound = sal_False; 681 ElementList::iterator aListIter; 682 683 for ( aListIter = m_pElemList->begin(); 684 aListIter != m_pElemList->end(); ++aListIter ) 685 { 686 ElementEntry_Impl& rEntry = *aListIter; 687 if ( ( rEntry.m_nElementID == nElementID ) && 688 ( !rEntry.m_bHasValue || ( rEntry.m_nControlAction == nControlAction ) ) ) 689 { 690 rEntry.setAction( nControlAction ); 691 rEntry.setValue( rValue ); 692 bFound = sal_True; 693 } 694 } 695 696 if ( !bFound ) 697 { 698 ElementEntry_Impl aNew( nElementID ); 699 aNew.setAction( nControlAction ); 700 aNew.setValue( rValue ); 701 m_pElemList->insert( m_pElemList->end(), aNew ); 702 } 703 } 704 } 705 706 //------------------------------------------------------------------------------------ 707 708 Any SAL_CALL SvtFilePicker::getValue( sal_Int16 nElementID, sal_Int16 nControlAction ) 709 throw( RuntimeException ) 710 { 711 checkAlive(); 712 713 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 714 Any aAny; 715 716 // execute() called? 717 if ( getDialog() ) 718 { 719 ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() ); 720 aAny = aAccess.getValue( nElementID, nControlAction ); 721 } 722 else if ( m_pElemList && !m_pElemList->empty() ) 723 { 724 ElementList::iterator aListIter; 725 for ( aListIter = m_pElemList->begin(); 726 aListIter != m_pElemList->end(); ++aListIter ) 727 { 728 ElementEntry_Impl& rEntry = *aListIter; 729 if ( ( rEntry.m_nElementID == nElementID ) && 730 ( rEntry.m_bHasValue ) && 731 ( rEntry.m_nControlAction == nControlAction ) ) 732 { 733 aAny = rEntry.m_aValue; 734 break; 735 } 736 } 737 } 738 739 return aAny; 740 } 741 742 743 //------------------------------------------------------------------------------------ 744 void SAL_CALL SvtFilePicker::setLabel( sal_Int16 nLabelID, const rtl::OUString& rValue ) 745 throw ( RuntimeException ) 746 { 747 checkAlive(); 748 749 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 750 if ( getDialog() ) 751 { 752 ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() ); 753 aAccess.setLabel( nLabelID, rValue ); 754 } 755 else 756 { 757 if ( !m_pElemList ) 758 m_pElemList = new ElementList; 759 760 sal_Bool bFound = sal_False; 761 ElementList::iterator aListIter; 762 763 for ( aListIter = m_pElemList->begin(); 764 aListIter != m_pElemList->end(); ++aListIter ) 765 { 766 ElementEntry_Impl& rEntry = *aListIter; 767 if ( rEntry.m_nElementID == nLabelID ) 768 { 769 rEntry.setLabel( rValue ); 770 bFound = sal_True; 771 } 772 } 773 774 if ( !bFound ) 775 { 776 ElementEntry_Impl aNew( nLabelID ); 777 aNew.setLabel( rValue ); 778 m_pElemList->insert( m_pElemList->end(), aNew ); 779 } 780 } 781 } 782 783 //------------------------------------------------------------------------------------ 784 rtl::OUString SAL_CALL SvtFilePicker::getLabel( sal_Int16 nLabelID ) 785 throw ( RuntimeException ) 786 { 787 checkAlive(); 788 789 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 790 rtl::OUString aLabel; 791 792 if ( getDialog() ) 793 { 794 ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() ); 795 aLabel = aAccess.getLabel( nLabelID ); 796 } 797 else if ( m_pElemList && !m_pElemList->empty() ) 798 { 799 ElementList::iterator aListIter; 800 for ( aListIter = m_pElemList->begin(); 801 aListIter != m_pElemList->end(); ++aListIter ) 802 { 803 ElementEntry_Impl& rEntry = *aListIter; 804 if ( rEntry.m_nElementID == nLabelID ) 805 { 806 if ( rEntry.m_bHasLabel ) 807 aLabel = rEntry.m_aLabel; 808 break; 809 } 810 } 811 } 812 813 return aLabel; 814 } 815 816 //------------------------------------------------------------------------------------ 817 void SAL_CALL SvtFilePicker::enableControl( sal_Int16 nElementID, sal_Bool bEnable ) 818 throw( RuntimeException ) 819 { 820 checkAlive(); 821 822 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 823 if ( getDialog() ) 824 { 825 ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() ); 826 aAccess.enableControl( nElementID, bEnable ); 827 } 828 else 829 { 830 if ( !m_pElemList ) 831 m_pElemList = new ElementList; 832 833 sal_Bool bFound = sal_False; 834 ElementList::iterator aListIter; 835 836 for ( aListIter = m_pElemList->begin(); 837 aListIter != m_pElemList->end(); ++aListIter ) 838 { 839 ElementEntry_Impl& rEntry = *aListIter; 840 if ( rEntry.m_nElementID == nElementID ) 841 { 842 rEntry.setEnabled( bEnable ); 843 bFound = sal_True; 844 } 845 } 846 847 if ( !bFound ) 848 { 849 ElementEntry_Impl aNew( nElementID ); 850 aNew.setEnabled( bEnable ); 851 m_pElemList->insert( m_pElemList->end(), aNew ); 852 } 853 } 854 } 855 856 //------------------------------------------------------------------------------------ 857 // XFilePickerNotifier functions 858 //------------------------------------------------------------------------------------ 859 860 void SAL_CALL SvtFilePicker::addFilePickerListener( const Reference< XFilePickerListener >& xListener ) throw ( RuntimeException ) 861 { 862 checkAlive(); 863 864 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 865 m_xListener = xListener; 866 } 867 868 //------------------------------------------------------------------------------------ 869 void SAL_CALL SvtFilePicker::removeFilePickerListener( const Reference< XFilePickerListener >& ) throw ( RuntimeException ) 870 { 871 checkAlive(); 872 873 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 874 m_xListener.clear(); 875 } 876 877 //------------------------------------------------------------------------------------ 878 // XFilePreview functions 879 //------------------------------------------------------------------------------------ 880 881 Sequence< sal_Int16 > SAL_CALL SvtFilePicker::getSupportedImageFormats() 882 throw ( RuntimeException ) 883 { 884 checkAlive(); 885 886 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 887 Sequence< sal_Int16 > aFormats( 1 ); 888 889 aFormats[0] = FilePreviewImageFormats::BITMAP; 890 891 return aFormats; 892 } 893 894 //------------------------------------------------------------------------------------ 895 sal_Int32 SAL_CALL SvtFilePicker::getTargetColorDepth() throw ( RuntimeException ) 896 { 897 checkAlive(); 898 899 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 900 sal_Int32 nDepth = 0; 901 902 if ( getDialog() ) 903 nDepth = getDialog()->getTargetColorDepth(); 904 905 return nDepth; 906 } 907 908 //------------------------------------------------------------------------------------ 909 sal_Int32 SAL_CALL SvtFilePicker::getAvailableWidth() throw ( RuntimeException ) 910 { 911 checkAlive(); 912 913 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 914 sal_Int32 nWidth = 0; 915 916 if ( getDialog() ) 917 nWidth = getDialog()->getAvailableWidth(); 918 919 return nWidth; 920 } 921 922 //------------------------------------------------------------------------------------ 923 sal_Int32 SAL_CALL SvtFilePicker::getAvailableHeight() throw ( RuntimeException ) 924 { 925 checkAlive(); 926 927 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 928 sal_Int32 nHeigth = 0; 929 930 if ( getDialog() ) 931 nHeigth = getDialog()->getAvailableHeight(); 932 933 return nHeigth; 934 } 935 936 //------------------------------------------------------------------------------------ 937 void SAL_CALL SvtFilePicker::setImage( sal_Int16 aImageFormat, const Any& rImage ) 938 throw ( IllegalArgumentException, RuntimeException ) 939 { 940 checkAlive(); 941 942 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 943 if ( getDialog() ) 944 getDialog()->setImage( aImageFormat, rImage ); 945 } 946 947 //------------------------------------------------------------------------------------ 948 sal_Bool SAL_CALL SvtFilePicker::setShowState( sal_Bool bShowState ) 949 throw ( RuntimeException ) 950 { 951 checkAlive(); 952 953 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 954 sal_Bool bRet = sal_False; 955 956 if ( getDialog() ) 957 bRet = getDialog()->setShowState( bShowState ); 958 959 return bRet; 960 } 961 962 //------------------------------------------------------------------------------------ 963 sal_Bool SAL_CALL SvtFilePicker::getShowState() throw ( RuntimeException ) 964 { 965 checkAlive(); 966 967 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 968 sal_Bool bRet = sal_False; 969 970 if ( getDialog() ) 971 bRet = getDialog()->getShowState(); 972 973 return bRet; 974 } 975 976 //------------------------------------------------------------------------------------ 977 // XFilterGroupManager functions 978 //------------------------------------------------------------------------------------ 979 980 void SAL_CALL SvtFilePicker::appendFilterGroup( const ::rtl::OUString& sGroupTitle, 981 const Sequence< StringPair >& aFilters ) 982 throw ( IllegalArgumentException, RuntimeException ) 983 { 984 checkAlive(); 985 986 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 987 988 // check the names 989 if ( FilterNameExists( aFilters ) ) 990 throw IllegalArgumentException( 991 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("filter name exists")), 992 static_cast< OWeakObject * >(this), 1); 993 994 // ensure that we have a filter list 995 ::rtl::OUString sInitialCurrentFilter; 996 if ( aFilters.getLength() ) 997 sInitialCurrentFilter = aFilters[0].First; 998 ensureFilterList( sInitialCurrentFilter ); 999 1000 // append the filter 1001 m_pFilterList->insert( m_pFilterList->end(), FilterEntry( sGroupTitle, aFilters ) ); 1002 } 1003 1004 //------------------------------------------------------------------------------------ 1005 // XFilterManager functions 1006 //------------------------------------------------------------------------------------ 1007 1008 void SAL_CALL SvtFilePicker::appendFilter( const rtl::OUString& aTitle, 1009 const rtl::OUString& aFilter ) 1010 throw( IllegalArgumentException, RuntimeException ) 1011 { 1012 checkAlive(); 1013 1014 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1015 // check the name 1016 if ( FilterNameExists( aTitle ) ) 1017 // TODO: a more precise exception message 1018 throw IllegalArgumentException(); 1019 1020 // ensure that we have a filter list 1021 ensureFilterList( aTitle ); 1022 1023 // append the filter 1024 m_pFilterList->insert( m_pFilterList->end(), FilterEntry( aTitle, aFilter ) ); 1025 } 1026 1027 //------------------------------------------------------------------------------------ 1028 void SAL_CALL SvtFilePicker::setCurrentFilter( const rtl::OUString& aTitle ) 1029 throw( IllegalArgumentException, RuntimeException ) 1030 { 1031 checkAlive(); 1032 1033 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1034 if ( ! FilterNameExists( aTitle ) ) 1035 throw IllegalArgumentException(); 1036 1037 m_aCurrentFilter = aTitle; 1038 1039 if ( getDialog() ) 1040 getDialog()->SetCurFilter( aTitle ); 1041 } 1042 1043 //------------------------------------------------------------------------------------ 1044 rtl::OUString SAL_CALL SvtFilePicker::getCurrentFilter() 1045 throw( RuntimeException ) 1046 { 1047 checkAlive(); 1048 1049 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1050 rtl::OUString aFilter = getDialog() ? rtl::OUString( getDialog()->GetCurFilter() ) : 1051 rtl::OUString( m_aCurrentFilter ); 1052 return aFilter; 1053 } 1054 1055 1056 //------------------------------------------------------------------------------------ 1057 // XInitialization functions 1058 //------------------------------------------------------------------------------------ 1059 1060 void SAL_CALL SvtFilePicker::initialize( const Sequence< Any >& _rArguments ) 1061 throw ( Exception, RuntimeException ) 1062 { 1063 checkAlive(); 1064 1065 Sequence< Any > aArguments( _rArguments.getLength()); 1066 1067 m_nServiceType = TemplateDescription::FILEOPEN_SIMPLE; 1068 1069 if ( _rArguments.getLength() >= 1 ) 1070 { 1071 // compatibility: one argument, type sal_Int16 , specifies the service type 1072 int index = 0; 1073 1074 if (_rArguments[0] >>= m_nServiceType) 1075 { 1076 // skip the first entry if it was the ServiceType, because it's not needed in OCommonPicker::initialize and it's not a NamedValue 1077 NamedValue emptyNamedValue; 1078 aArguments[0] <<= emptyNamedValue; 1079 index = 1; 1080 1081 } 1082 for ( int i = index; i < _rArguments.getLength(); i++) 1083 { 1084 NamedValue namedValue; 1085 aArguments[i] <<= _rArguments[i]; 1086 1087 if (aArguments[i] >>= namedValue ) 1088 { 1089 1090 if ( namedValue.Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StandardDir" ) ) ) ) 1091 { 1092 ::rtl::OUString sStandardDir; 1093 1094 namedValue.Value >>= sStandardDir; 1095 1096 // Set the directory for the "back to the default dir" button 1097 if ( sStandardDir.getLength() > 0 ) 1098 { 1099 m_aStandardDir = sStandardDir; 1100 } 1101 } 1102 else if ( namedValue.Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BlackList" ) ) ) ) 1103 { 1104 namedValue.Value >>= m_aBlackList; 1105 } 1106 } 1107 } 1108 } 1109 1110 // let the base class analyze the sequence (will call into implHandleInitializationArgument) 1111 OCommonPicker::initialize( aArguments ); 1112 } 1113 1114 //------------------------------------------------------------------------- 1115 sal_Bool SvtFilePicker::implHandleInitializationArgument( const ::rtl::OUString& _rName, const Any& _rValue ) SAL_THROW( ( Exception, RuntimeException ) ) 1116 { 1117 if ( _rName.equalsAscii( "TemplateDescription" ) ) 1118 { 1119 m_nServiceType = TemplateDescription::FILEOPEN_SIMPLE; 1120 OSL_VERIFY( _rValue >>= m_nServiceType ); 1121 return sal_True; 1122 } 1123 if ( _rName.equalsAscii( "StandardDir" ) ) 1124 { 1125 OSL_VERIFY( _rValue >>= m_aStandardDir ); 1126 return sal_True; 1127 } 1128 1129 if ( _rName.equalsAscii( "BlackList" ) ) 1130 { 1131 OSL_VERIFY( _rValue >>= m_aBlackList ); 1132 return sal_True; 1133 } 1134 1135 1136 1137 return OCommonPicker::implHandleInitializationArgument( _rName, _rValue ); 1138 } 1139 1140 //------------------------------------------------------------------------------------ 1141 // XServiceInfo 1142 //------------------------------------------------------------------------------------ 1143 1144 /* XServiceInfo */ 1145 rtl::OUString SAL_CALL SvtFilePicker::getImplementationName() throw( RuntimeException ) 1146 { 1147 return impl_getStaticImplementationName(); 1148 } 1149 1150 /* XServiceInfo */ 1151 sal_Bool SAL_CALL SvtFilePicker::supportsService( const rtl::OUString& sServiceName ) throw( RuntimeException ) 1152 { 1153 Sequence< rtl::OUString > seqServiceNames = getSupportedServiceNames(); 1154 const rtl::OUString* pArray = seqServiceNames.getConstArray(); 1155 for ( sal_Int32 i = 0; i < seqServiceNames.getLength(); i++ ) 1156 { 1157 if ( sServiceName == pArray[i] ) 1158 { 1159 return sal_True ; 1160 } 1161 } 1162 return sal_False ; 1163 } 1164 1165 /* XServiceInfo */ 1166 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getSupportedServiceNames() throw( RuntimeException ) 1167 { 1168 return impl_getStaticSupportedServiceNames(); 1169 } 1170 1171 /* Helper for XServiceInfo */ 1172 Sequence< rtl::OUString > SvtFilePicker::impl_getStaticSupportedServiceNames() 1173 { 1174 Sequence< rtl::OUString > seqServiceNames( 1 ); 1175 rtl::OUString* pArray = seqServiceNames.getArray(); 1176 pArray[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.OfficeFilePicker" ); 1177 return seqServiceNames ; 1178 } 1179 1180 /* Helper for XServiceInfo */ 1181 rtl::OUString SvtFilePicker::impl_getStaticImplementationName() 1182 { 1183 return rtl::OUString::createFromAscii( "com.sun.star.svtools.OfficeFilePicker" ); 1184 } 1185 1186 /* Helper for registry */ 1187 Reference< XInterface > SAL_CALL SvtFilePicker::impl_createInstance( 1188 const Reference< XComponentContext >& rxContext) throw( Exception ) 1189 { 1190 Reference< XMultiServiceFactory > xServiceManager (rxContext->getServiceManager(), UNO_QUERY_THROW); 1191 return Reference< XInterface >( *new SvtFilePicker( xServiceManager ) ); 1192 } 1193