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