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