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_svtools.hxx" 30 31 #include <svtools/fileview.hxx> 32 #include <svtools/svtdata.hxx> 33 #include <svtools/imagemgr.hxx> 34 #include <svtools/headbar.hxx> 35 #include <svtools/svtabbx.hxx> 36 #include <svtools/svtools.hrc> 37 #include "fileview.hrc" 38 #include "contentenumeration.hxx" 39 #include <svtools/AccessibleBrowseBoxObjType.hxx> 40 #include <com/sun/star/util/DateTime.hpp> 41 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 42 #include <com/sun/star/task/XInteractionHandler.hpp> 43 #include <com/sun/star/ucb/XProgressHandler.hpp> 44 #include <com/sun/star/sdbc/XResultSet.hpp> 45 #include <com/sun/star/ucb/XAnyCompareFactory.hpp> 46 #include <com/sun/star/ucb/XContentAccess.hpp> 47 #include <com/sun/star/ucb/XDynamicResultSet.hpp> 48 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp> 49 #include <com/sun/star/sdbc/XRow.hpp> 50 #include <com/sun/star/container/XChild.hpp> 51 #include <com/sun/star/ucb/CommandAbortedException.hpp> 52 #include <com/sun/star/ucb/ContentCreationException.hpp> 53 #include <vcl/waitobj.hxx> 54 #include <com/sun/star/io/XPersist.hpp> 55 #include <com/sun/star/beans/XPropertySet.hpp> 56 #include <com/sun/star/ucb/XCommandInfo.hpp> 57 #include <com/sun/star/beans/XPropertySetInfo.hpp> 58 #include <com/sun/star/beans/PropertyAttribute.hpp> 59 60 #include <algorithm> 61 #include <memory> 62 #include <tools/urlobj.hxx> 63 #include <tools/datetime.hxx> 64 #include <comphelper/processfactory.hxx> 65 #include <unotools/localfilehelper.hxx> 66 #include <ucbhelper/content.hxx> 67 #include <ucbhelper/commandenvironment.hxx> 68 #include <vcl/msgbox.hxx> 69 #ifndef INCLUDED_RTL_MATH_H 70 #include <rtl/math.hxx> 71 #endif 72 #include <tools/config.hxx> 73 #include <osl/mutex.hxx> 74 #include <osl/conditn.hxx> 75 #include <vos/timer.hxx> 76 #include <vcl/svapp.hxx> 77 #include <vcl/sound.hxx> 78 #include <unotools/ucbhelper.hxx> 79 #include <unotools/intlwrapper.hxx> 80 #include <unotools/syslocale.hxx> 81 #include <svl/urlfilter.hxx> 82 83 using namespace ::com::sun::star::lang; 84 using namespace ::com::sun::star::sdbc; 85 using namespace ::com::sun::star::task; 86 using namespace ::com::sun::star::ucb; 87 using namespace ::com::sun::star::uno; 88 using namespace ::com::sun::star::io; 89 using namespace ::com::sun::star::beans; 90 using namespace ::comphelper; 91 using ::svt::SortingData_Impl; 92 using ::svt::FolderDescriptor; 93 using ::vos::TTimeValue; 94 using ::rtl::OUString; 95 96 #define ALL_FILES_FILTER "*.*" 97 98 #define COLUMN_TITLE 1 99 #define COLUMN_TYPE 2 100 #define COLUMN_SIZE 3 101 #define COLUMN_DATE 4 102 103 DECLARE_LIST( StringList_Impl, OUString* ) 104 105 #define ROW_HEIGHT 17 // the height of a row has to be a little higher than the bitmap 106 #define QUICK_SEARCH_TIMEOUT 1500 // time in mSec before the quicksearch string will be reseted 107 108 namespace 109 { 110 //==================================================================== 111 //= ReleaseSolarMutex 112 //==================================================================== 113 struct ReleaseSolarMutex 114 { 115 private: 116 sal_uLong m_nCount; 117 118 public: 119 inline ReleaseSolarMutex() 120 { 121 m_nCount = Application::ReleaseSolarMutex(); 122 } 123 inline ~ReleaseSolarMutex() 124 { 125 Application::AcquireSolarMutex( m_nCount ); 126 } 127 }; 128 129 //==================================================================== 130 //= ITimeoutHandler 131 //==================================================================== 132 class CallbackTimer; 133 class ITimeoutHandler 134 { 135 public: 136 virtual void onTimeout( CallbackTimer* _pInstigator ) = 0; 137 }; 138 139 //==================================================================== 140 //= CallbackTimer 141 //==================================================================== 142 class CallbackTimer : public ::vos::OTimer 143 { 144 protected: 145 ITimeoutHandler* m_pTimeoutHandler; 146 147 public: 148 CallbackTimer( ITimeoutHandler* _pHandler ) : m_pTimeoutHandler( _pHandler ) { } 149 150 protected: 151 virtual void SAL_CALL onShot(); 152 }; 153 154 //-------------------------------------------------------------------- 155 void SAL_CALL CallbackTimer::onShot() 156 { 157 OSL_ENSURE( m_pTimeoutHandler, "CallbackTimer::onShot: nobody interested in?" ); 158 ITimeoutHandler* pHandler( m_pTimeoutHandler ); 159 if ( pHandler ) 160 pHandler->onTimeout( this ); 161 } 162 163 } 164 165 // ----------------------------------------------------------------------- 166 167 static sal_Bool isHighContrast( const Window* _pView ) 168 { 169 return _pView->GetSettings().GetStyleSettings().GetHighContrastMode(); 170 } 171 172 // ----------------------------------------------------------------------- 173 174 void FilterMatch::createWildCardFilterList(const String& _rFilterList,::std::vector< WildCard >& _rFilters) 175 { 176 if( _rFilterList.Len() ) 177 {// filter is given 178 xub_StrLen nCount = _rFilterList.GetTokenCount(); 179 _rFilters.reserve( nCount ); 180 xub_StrLen nIndex = 0; 181 OUString sToken; 182 do 183 { 184 sToken = _rFilterList.GetToken( 0, ';', nIndex ); 185 if ( sToken.getLength() ) 186 { 187 _rFilters.push_back( WildCard( sToken.toAsciiUpperCase() ) ); 188 } 189 } 190 while ( nIndex != STRING_NOTFOUND ); 191 } 192 else 193 // no filter is given -> match all 194 _rFilters.push_back( WildCard( String::CreateFromAscii( "*" ) ) ); 195 } 196 // class ViewTabListBox_Impl --------------------------------------------- 197 198 class ViewTabListBox_Impl : public SvHeaderTabListBox 199 { 200 private: 201 Reference< XCommandEnvironment > mxCmdEnv; 202 203 ::osl::Mutex maMutex; 204 HeaderBar* mpHeaderBar; 205 SvtFileView_Impl* mpParent; 206 Timer maResetQuickSearch; 207 OUString maQuickSearchText; 208 String msAccessibleDescText; 209 String msFolder; 210 String msFile; 211 sal_uInt32 mnSearchIndex; 212 sal_Bool mbResizeDisabled : 1; 213 sal_Bool mbAutoResize : 1; 214 sal_Bool mbEnableDelete : 1; 215 sal_Bool mbEnableRename : 1; 216 217 void DeleteEntries(); 218 void DoQuickSearch( const xub_Unicode& rChar ); 219 sal_Bool Kill( const OUString& rURL ); 220 221 protected: 222 virtual sal_Bool DoubleClickHdl(); 223 virtual ::rtl::OUString GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const; 224 225 public: 226 ViewTabListBox_Impl( Window* pParentWin, SvtFileView_Impl* pParent, sal_Int16 nFlags ); 227 ~ViewTabListBox_Impl(); 228 229 virtual void Resize(); 230 virtual void KeyInput( const KeyEvent& rKEvt ); 231 virtual sal_Bool EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ); 232 233 void ClearAll(); 234 HeaderBar* GetHeaderBar() const { return mpHeaderBar; } 235 236 void EnableAutoResize() { mbAutoResize = sal_True; } 237 void EnableDelete( sal_Bool bEnable ) { mbEnableDelete = bEnable; } 238 void EnableRename( sal_Bool bEnable ) { mbEnableRename = bEnable; } 239 sal_Bool IsDeleteOrContextMenuEnabled() { return mbEnableDelete || IsContextMenuHandlingEnabled(); } 240 241 Reference< XCommandEnvironment > GetCommandEnvironment() const { return mxCmdEnv; } 242 243 DECL_LINK( ResetQuickSearch_Impl, Timer * ); 244 245 virtual PopupMenu* CreateContextMenu( void ); 246 virtual void ExcecuteContextMenuAction( sal_uInt16 nSelectedPopentry ); 247 }; 248 249 // class HashedEntry -------------------------------------------------- 250 251 class HashedEntry 252 { // just a special String which can be compared on equality much faster 253 protected: 254 OUString maName; 255 sal_Int32 mnHashCode; 256 public: 257 inline HashedEntry( const OUString& rName ); 258 inline HashedEntry( const INetURLObject& rURL ); 259 inline HashedEntry( const HashedEntry& rCopy ); 260 virtual ~HashedEntry(); 261 262 inline sal_Bool operator ==( const HashedEntry& rRef ) const; 263 inline sal_Bool operator !=( const HashedEntry& rRef ) const; 264 265 inline const OUString& GetName() const; 266 }; 267 268 inline HashedEntry::HashedEntry( const OUString& rName ): maName( rName ), mnHashCode( rName.hashCode() ) 269 { 270 } 271 272 inline HashedEntry::HashedEntry( const INetURLObject& rURL ): 273 maName( rURL.GetMainURL( INetURLObject::NO_DECODE ) ), 274 mnHashCode( maName.hashCode() ) 275 { 276 } 277 278 inline HashedEntry::HashedEntry( const HashedEntry& r ): maName( r.maName ), mnHashCode( r.mnHashCode ) 279 { 280 } 281 282 HashedEntry::~HashedEntry() 283 { 284 } 285 286 inline sal_Bool HashedEntry::operator ==( const HashedEntry& rRef ) const 287 { 288 return mnHashCode == rRef.mnHashCode && maName.reverseCompareTo( rRef.maName ) == 0; 289 } 290 291 inline sal_Bool HashedEntry::operator !=( const HashedEntry& rRef ) const 292 { 293 return mnHashCode != rRef.mnHashCode || maName.reverseCompareTo( rRef.maName ) != 0; 294 } 295 296 inline const OUString& HashedEntry::GetName() const 297 { 298 return maName; 299 } 300 301 // class HashedEntryList ---------------------------------------------- 302 303 class HashedEntryList : protected List 304 {// provides a list of _unique_ Entries 305 protected: 306 inline HashedEntry* First(); 307 inline HashedEntry* Next(); 308 inline void Append( HashedEntry* pNewEntry ); 309 public: 310 virtual ~HashedEntryList(); 311 312 const HashedEntry* Find( const OUString& rNameToSearchFor ); 313 const HashedEntry* Find( const HashedEntry& rToSearchFor ); 314 // not const, because First()/Next() is used 315 using List::Insert; 316 const HashedEntry& Insert( HashedEntry* pInsertOrDelete ); 317 // don't care about pInsertOrDelete after this any more and handle it as invalid! 318 // returns the Entry, which is effectively inserted 319 320 void Clear(); 321 }; 322 323 inline HashedEntry* HashedEntryList::First() 324 { 325 return ( HashedEntry* ) List::First(); 326 } 327 328 inline HashedEntry* HashedEntryList::Next() 329 { 330 return ( HashedEntry* ) List::Next(); 331 } 332 333 inline void HashedEntryList::Append( HashedEntry* pNew ) 334 { 335 List::Insert( pNew, LIST_APPEND ); 336 } 337 338 HashedEntryList::~HashedEntryList() 339 { 340 Clear(); 341 } 342 343 const HashedEntry* HashedEntryList::Find( const OUString& rRefName ) 344 { // simple linear search, which should be fast enough for this purpose 345 HashedEntry aRef( rRefName ); 346 HashedEntry* pIter = First(); 347 while( pIter && *pIter != aRef ) 348 pIter = Next(); 349 350 return pIter; 351 } 352 353 const HashedEntry* HashedEntryList::Find( const HashedEntry& rRef ) 354 { // simple linear search, which should be fast enough for this purpose 355 HashedEntry* pIter = First(); 356 while( pIter && *pIter != rRef ) 357 pIter = Next(); 358 359 return pIter; 360 } 361 362 const HashedEntry& HashedEntryList::Insert( HashedEntry* pNew ) 363 { // inserts (appends) only, if entry doesn't already exists 364 // if it already exists, pNew is deleted, because the caller must not worry about pNew any more 365 366 DBG_ASSERT( pNew, "HashedEntryList::Insert(): NULL-pointer can't be inserted" ); 367 368 const HashedEntry* pSearch = Find( *pNew ); 369 if( pSearch ) 370 { 371 delete pNew; 372 return *pSearch; 373 } 374 375 Append( pNew ); 376 377 return *pNew; 378 } 379 380 void HashedEntryList::Clear() 381 { 382 HashedEntry* p = First(); 383 while( p ) 384 { 385 delete p; 386 p = Next(); 387 } 388 } 389 390 // class NameTranslationEntry ----------------------------------------- 391 392 class NameTranslationEntry : public HashedEntry 393 {// a fast compareble String and another String, which is used to get a substitution for a given String 394 protected: 395 OUString maTranslatedName; 396 public: 397 inline NameTranslationEntry( const OUString& rOriginalName, const OUString& rTranslatedName ); 398 inline NameTranslationEntry( const ByteString& rOriginalName, const ByteString& rTranslatedName ); 399 400 inline const OUString& GetTranslation() const; 401 }; 402 403 inline NameTranslationEntry::NameTranslationEntry( const OUString& rOrg, const OUString& rTrans ): 404 HashedEntry( rOrg ), 405 maTranslatedName( rTrans ) 406 { 407 } 408 409 inline NameTranslationEntry::NameTranslationEntry( const ByteString& rOrg, const ByteString& rTrans ): 410 HashedEntry( OUString( rOrg.GetBuffer(), rOrg.Len(), RTL_TEXTENCODING_ASCII_US ) ), 411 maTranslatedName( OUString( rTrans.GetBuffer(), rTrans.Len(), RTL_TEXTENCODING_UTF8 ) ) 412 { 413 } 414 415 inline const OUString& NameTranslationEntry::GetTranslation() const 416 { 417 return maTranslatedName; 418 } 419 420 // class NameTranslationList ----------------------------------------- 421 422 class NameTranslationList : protected HashedEntryList 423 { // contains a list of substitutes of strings for a given folder (as URL) 424 // explanation of the circumstances see in remarks for Init(); 425 protected: 426 INetURLObject maTransFile; // URL of file with translation entries 427 HashedEntry maHashedURL; // for future purposes when dealing with a set of cached 428 // NameTranslationLists 429 private: 430 const String maTransFileName; 431 void Init(); // reads the translation file and fills the (internal) list 432 433 public: 434 NameTranslationList( const INetURLObject& rBaseURL ); 435 // rBaseURL: path to folder for which the translation of the entries 436 // should be done 437 438 using List::operator==; 439 inline sal_Bool operator ==( const HashedEntry& rRef ) const; 440 using List::operator!=; 441 inline sal_Bool operator !=( const HashedEntry& rRef ) const; 442 443 const OUString* Translate( const OUString& rName ) const; 444 // returns NULL, if rName can't be found 445 446 inline void Update(); // clears list and init 447 448 inline const String& GetTransTableFileName() const; 449 // returns the name for the file, which contains the translation strings 450 }; 451 452 inline const String& NameTranslationList::GetTransTableFileName() const 453 { 454 return maTransFileName; 455 } 456 457 void NameTranslationList::Init() 458 { 459 // Tries to read the file ".nametranslation.table" in the base folder. Complete path/name is in maTransFile. 460 // Further on, the found entries in the section "TRANSLATIONNAMES" are used to replace names in the 461 // base folder by translated ones. The translation must be given in UTF8 462 // See examples of such a files in the samples-folder of an Office installation 463 464 try 465 { 466 ::ucbhelper::Content aTestContent( maTransFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >() ); 467 468 if( aTestContent.isDocument() ) 469 {// ... also tests the existence of maTransFile by throwing an Exception 470 const sal_Char* pSection = "TRANSLATIONNAMES"; 471 String aFsysName( maTransFile.getFSysPath( INetURLObject::FSYS_DETECT ) ); 472 Config aConfig( aFsysName ); 473 474 aConfig.SetGroup( ByteString( pSection ) ); 475 476 sal_uInt16 nKeyCnt = aConfig.GetKeyCount(); 477 478 for( sal_uInt16 nCnt = 0 ; nCnt < nKeyCnt ; ++nCnt ) 479 Insert( new NameTranslationEntry( aConfig.GetKeyName( nCnt ), aConfig.ReadKey( nCnt ) ) ); 480 } 481 } 482 catch( Exception const & ) {} 483 } 484 485 NameTranslationList::NameTranslationList( const INetURLObject& rBaseURL ): 486 maTransFile( rBaseURL ), 487 maHashedURL( rBaseURL ), 488 maTransFileName( String::CreateFromAscii( ".nametranslation.table" ) ) 489 { 490 maTransFile.insertName( maTransFileName ); 491 Init(); 492 } 493 494 inline sal_Bool NameTranslationList::operator ==( const HashedEntry& rRef ) const 495 { 496 return maHashedURL == rRef; 497 } 498 499 inline sal_Bool NameTranslationList::operator !=( const HashedEntry& rRef ) const 500 { 501 return maHashedURL != rRef; 502 } 503 504 const OUString* NameTranslationList::Translate( const OUString& rName ) const 505 { 506 const NameTranslationEntry* pSearch = static_cast< const NameTranslationEntry* >( 507 ( const_cast< NameTranslationList* >( this ) )->Find( rName ) ); 508 509 return pSearch? &pSearch->GetTranslation() : NULL; 510 } 511 512 inline void NameTranslationList::Update() 513 { 514 Clear(); 515 Init(); 516 } 517 518 // class NameTranslator_Impl ------------------------------------------ 519 520 // enables the user to get string substitutions (translations for the content) for a given folder 521 // see more explanations above in the description for NameTranslationList 522 class NameTranslator_Impl : public ::svt::IContentTitleTranslation 523 { 524 private: 525 NameTranslationList* mpActFolder; 526 public: 527 NameTranslator_Impl( void ); 528 NameTranslator_Impl( const INetURLObject& rActualFolder ); 529 virtual ~NameTranslator_Impl(); 530 531 // IContentTitleTranslation 532 virtual sal_Bool GetTranslation( const OUString& rOriginalName, OUString& rTranslatedName ) const; 533 534 void UpdateTranslationTable(); // reads the translation file again 535 536 void SetActualFolder( const INetURLObject& rActualFolder ); 537 const String* GetTransTableFileName() const; 538 // returns the name for the file, which contains the translation strings 539 }; 540 541 //==================================================================== 542 //= SvtFileView_Impl 543 //==================================================================== 544 545 class SvtFileView_Impl :public ::svt::IEnumerationResultHandler 546 ,public ITimeoutHandler 547 { 548 protected: 549 SvtFileView* mpAntiImpl; 550 Link m_aSelectHandler; 551 552 ::rtl::Reference< ::svt::FileViewContentEnumerator > 553 m_pContentEnumerator; 554 Link m_aCurrentAsyncActionHandler; 555 ::osl::Condition m_aAsyncActionFinished; 556 ::rtl::Reference< ::vos::OTimer > m_pCancelAsyncTimer; 557 ::svt::EnumerationResult m_eAsyncActionResult; 558 bool m_bRunningAsyncAction; 559 bool m_bAsyncActionCancelled; 560 561 562 public: 563 564 ::std::vector< SortingData_Impl* > maContent; 565 ::osl::Mutex maMutex; 566 567 ViewTabListBox_Impl* mpView; 568 NameTranslator_Impl* mpNameTrans; 569 const IUrlFilter* mpUrlFilter; 570 sal_uInt16 mnSortColumn; 571 sal_Bool mbAscending : 1; 572 sal_Bool mbOnlyFolder : 1; 573 sal_Bool mbReplaceNames : 1; // translate folder names or display doc-title instead of file name 574 sal_Int16 mnSuspendSelectCallback : 1; 575 sal_Bool mbIsFirstResort : 1; 576 577 IntlWrapper aIntlWrapper; 578 579 String maViewURL; 580 String maAllFilter; 581 String maCurrentFilter; 582 Image maFolderImage; 583 Link maOpenDoneLink; 584 Reference< XCommandEnvironment > mxCmdEnv; 585 586 SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > xEnv, 587 sal_Int16 nFlags, 588 sal_Bool bOnlyFolder ); 589 virtual ~SvtFileView_Impl(); 590 591 void Clear(); 592 593 FileViewResult GetFolderContent_Impl( 594 const String& rFolder, 595 const FileViewAsyncAction* pAsyncDescriptor, 596 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList = ::com::sun::star::uno::Sequence< ::rtl::OUString >() ); 597 598 FileViewResult GetFolderContent_Impl( 599 const FolderDescriptor& _rFolder, 600 const FileViewAsyncAction* pAsyncDescriptor, 601 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList = ::com::sun::star::uno::Sequence< ::rtl::OUString >()); 602 void FilterFolderContent_Impl( const OUString &rFilter ); 603 void CancelRunningAsyncAction(); 604 605 void OpenFolder_Impl(); 606 // #83004# ------- 607 void ReplaceTabWithString( OUString& aValue ); 608 void CreateDisplayText_Impl(); 609 void CreateVector_Impl( const Sequence < OUString > &rList ); 610 void SortFolderContent_Impl(); 611 612 void EntryRemoved( const OUString& rURL ); 613 void EntryRenamed( OUString& rURL, 614 const OUString& rName ); 615 String FolderInserted( const OUString& rURL, 616 const OUString& rTitle ); 617 618 sal_uLong GetEntryPos( const OUString& rURL ); 619 620 inline void EnableContextMenu( sal_Bool bEnable ); 621 inline void EnableDelete( sal_Bool bEnable ); 622 623 void Resort_Impl( sal_Int16 nColumn, sal_Bool bAscending ); 624 sal_Bool SearchNextEntry( sal_uInt32 &nIndex, 625 const OUString& rTitle, 626 sal_Bool bWrapAround ); 627 628 inline sal_Bool EnableNameReplacing( sal_Bool bEnable = sal_True ); // returns false, if action wasn't possible 629 void SetActualFolder( const INetURLObject& rActualFolder ); 630 631 sal_Bool GetDocTitle( const OUString& rTargetURL, OUString& rDocTitle ) const; 632 633 void SetSelectHandler( const Link& _rHdl ); 634 635 void InitSelection(); 636 void ResetCursor(); 637 638 inline void EndEditing( bool _bCancel ); 639 640 protected: 641 DECL_LINK( SelectionMultiplexer, void* ); 642 643 protected: 644 // IEnumerationResultHandler overridables 645 virtual void enumerationDone( ::svt::EnumerationResult _eResult ); 646 void implEnumerationSuccess(); 647 648 // ITimeoutHandler 649 virtual void onTimeout( CallbackTimer* _pInstigator ); 650 }; 651 652 inline void SvtFileView_Impl::EnableContextMenu( sal_Bool bEnable ) 653 { 654 mpView->EnableContextMenuHandling( bEnable ); 655 if( bEnable ) 656 mbReplaceNames = sal_False; 657 } 658 659 inline void SvtFileView_Impl::EnableDelete( sal_Bool bEnable ) 660 { 661 mpView->EnableDelete( bEnable ); 662 if( bEnable ) 663 mbReplaceNames = sal_False; 664 } 665 666 inline sal_Bool SvtFileView_Impl::EnableNameReplacing( sal_Bool bEnable ) 667 { 668 mpView->EnableRename( bEnable ); 669 670 sal_Bool bRet; 671 if( mpView->IsDeleteOrContextMenuEnabled() ) 672 { 673 DBG_ASSERT( !mbReplaceNames, "SvtFileView_Impl::EnableNameReplacing(): state should be not possible!" ); 674 bRet = !bEnable; // only for enabling this is an unsuccessful result 675 } 676 else 677 { 678 mbReplaceNames = bEnable; 679 bRet = sal_True; 680 } 681 682 return bRet; 683 } 684 685 inline void SvtFileView_Impl::EndEditing( bool _bCancel ) 686 { 687 if ( mpView->IsEditingActive() ) 688 mpView->EndEditing( _bCancel != false ); 689 } 690 691 // functions ------------------------------------------------------------- 692 693 OUString CreateExactSizeText_Impl( sal_Int64 nSize ) 694 { 695 double fSize( ( double ) nSize ); 696 int nDec; 697 698 long nMega = 1024 * 1024; 699 long nGiga = nMega * 1024; 700 701 String aUnitStr = ' '; 702 703 if ( nSize < 10000 ) 704 { 705 aUnitStr += String( SvtResId( STR_SVT_BYTES ) ); 706 nDec = 0; 707 } 708 else if ( nSize < nMega ) 709 { 710 fSize /= 1024; 711 aUnitStr += String( SvtResId( STR_SVT_KB ) ); 712 nDec = 1; 713 } 714 else if ( nSize < nGiga ) 715 { 716 fSize /= nMega; 717 aUnitStr += String( SvtResId( STR_SVT_MB ) ); 718 nDec = 2; 719 } 720 else 721 { 722 fSize /= nGiga; 723 aUnitStr += String( SvtResId( STR_SVT_GB ) ); 724 nDec = 3; 725 } 726 727 OUString aSizeStr( ::rtl::math::doubleToUString( fSize, 728 rtl_math_StringFormat_F, nDec, 729 SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0))); 730 aSizeStr += aUnitStr; 731 732 return aSizeStr; 733 } 734 735 // ----------------------------------------------------------------------- 736 // class ViewTabListBox_Impl --------------------------------------------- 737 // ----------------------------------------------------------------------- 738 739 ViewTabListBox_Impl::ViewTabListBox_Impl( Window* pParentWin, 740 SvtFileView_Impl* pParent, 741 sal_Int16 nFlags ) : 742 743 SvHeaderTabListBox( pParentWin, WB_TABSTOP ), 744 745 mpHeaderBar ( NULL ), 746 mpParent ( pParent ), 747 msAccessibleDescText( SvtResId( STR_SVT_ACC_DESC_FILEVIEW ) ), 748 msFolder ( SvtResId( STR_SVT_ACC_DESC_FOLDER ) ), 749 msFile ( SvtResId( STR_SVT_ACC_DESC_FILE ) ), 750 mnSearchIndex ( 0 ), 751 mbResizeDisabled ( sal_False ), 752 mbAutoResize ( sal_False ), 753 mbEnableDelete ( sal_True ), 754 mbEnableRename ( sal_True ) 755 756 { 757 Size aBoxSize = pParentWin->GetSizePixel(); 758 mpHeaderBar = new HeaderBar( pParentWin, WB_BUTTONSTYLE | WB_BOTTOMBORDER ); 759 mpHeaderBar->SetPosSizePixel( Point( 0, 0 ), mpHeaderBar->CalcWindowSizePixel() ); 760 761 HeaderBarItemBits nBits = ( HIB_LEFT | HIB_VCENTER | HIB_CLICKABLE ); 762 if ( ( nFlags & FILEVIEW_SHOW_ALL ) == FILEVIEW_SHOW_ALL ) 763 { 764 mpHeaderBar->InsertItem( COLUMN_TITLE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_TITLE ) ), 180, nBits | HIB_UPARROW ); 765 mpHeaderBar->InsertItem( COLUMN_TYPE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_TYPE ) ), 140, nBits ); 766 mpHeaderBar->InsertItem( COLUMN_SIZE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_SIZE ) ), 80, nBits ); 767 mpHeaderBar->InsertItem( COLUMN_DATE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_DATE ) ), 500, nBits ); 768 } 769 else 770 mpHeaderBar->InsertItem( COLUMN_TITLE, String( SvtResId( STR_SVT_FILEVIEW_COLUMN_TITLE ) ), 600, nBits ); 771 772 Size aHeadSize = mpHeaderBar->GetSizePixel(); 773 SetPosSizePixel( Point( 0, aHeadSize.Height() ), 774 Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) ); 775 InitHeaderBar( mpHeaderBar ); 776 SetHighlightRange(); 777 SetEntryHeight( ROW_HEIGHT ); 778 779 Show(); 780 mpHeaderBar->Show(); 781 782 maResetQuickSearch.SetTimeout( QUICK_SEARCH_TIMEOUT ); 783 maResetQuickSearch.SetTimeoutHdl( LINK( this, ViewTabListBox_Impl, ResetQuickSearch_Impl ) ); 784 785 Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); 786 Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > ( 787 xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY ); 788 789 mxCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() ); 790 791 EnableContextMenuHandling(); 792 } 793 794 // ----------------------------------------------------------------------- 795 796 ViewTabListBox_Impl::~ViewTabListBox_Impl() 797 { 798 maResetQuickSearch.Stop(); 799 800 delete mpHeaderBar; 801 } 802 803 // ----------------------------------------------------------------------- 804 805 IMPL_LINK( ViewTabListBox_Impl, ResetQuickSearch_Impl, Timer*, EMPTYARG ) 806 { 807 ::osl::MutexGuard aGuard( maMutex ); 808 809 maQuickSearchText = OUString(); 810 mnSearchIndex = 0; 811 812 return 0; 813 } 814 815 // ----------------------------------------------------------------------- 816 817 void ViewTabListBox_Impl::Resize() 818 { 819 SvTabListBox::Resize(); 820 Size aBoxSize = Control::GetParent()->GetOutputSizePixel(); 821 822 if ( mbResizeDisabled || !aBoxSize.Width() ) 823 return; 824 825 Size aBarSize = mpHeaderBar->GetSizePixel(); 826 aBarSize.Width() = mbAutoResize ? aBoxSize.Width() : GetSizePixel().Width(); 827 mpHeaderBar->SetSizePixel( aBarSize ); 828 829 if ( mbAutoResize ) 830 { 831 mbResizeDisabled = sal_True; 832 Point aPos = GetPosPixel(); 833 SetPosSizePixel( Point( 0, aBarSize.Height() ), 834 Size( aBoxSize.Width(), aBoxSize.Height() - aBarSize.Height() ) ); 835 mbResizeDisabled = sal_False; 836 } 837 } 838 839 // ----------------------------------------------------------------------- 840 841 void ViewTabListBox_Impl::KeyInput( const KeyEvent& rKEvt ) 842 { 843 bool bHandled = false; 844 845 const KeyCode& rKeyCode = rKEvt.GetKeyCode(); 846 if ( 0 == rKeyCode.GetModifier() ) 847 { 848 if ( rKeyCode.GetCode() == KEY_RETURN ) 849 { 850 ResetQuickSearch_Impl( NULL ); 851 GetDoubleClickHdl().Call( this ); 852 bHandled = true; 853 } 854 else if ( ( rKeyCode.GetCode() == KEY_DELETE ) && 855 mbEnableDelete ) 856 { 857 ResetQuickSearch_Impl( NULL ); 858 DeleteEntries(); 859 bHandled = true; 860 } 861 else if ( ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_NUM ) || 862 ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_ALPHA ) ) 863 { 864 DoQuickSearch( rKEvt.GetCharCode() ); 865 bHandled = true; 866 } 867 } 868 869 if ( !bHandled ) 870 { 871 ResetQuickSearch_Impl( NULL ); 872 SvHeaderTabListBox::KeyInput( rKEvt ); 873 } 874 } 875 876 // ----------------------------------------------------------------------- 877 878 PopupMenu* ViewTabListBox_Impl::CreateContextMenu( void ) 879 { 880 bool bEnableDelete = mbEnableDelete; 881 bool bEnableRename = mbEnableRename; 882 883 if ( bEnableDelete || bEnableRename ) 884 { 885 sal_Int32 nSelectedEntries = GetSelectionCount(); 886 bEnableDelete &= nSelectedEntries > 0; 887 bEnableRename &= nSelectedEntries == 1; 888 } 889 890 if ( bEnableDelete || bEnableRename ) 891 { 892 SvLBoxEntry* pEntry = FirstSelected(); 893 while ( pEntry ) 894 { 895 ::ucbhelper::Content aCnt; 896 try 897 { 898 OUString aURL( static_cast< SvtContentEntry * >( 899 pEntry->GetUserData() )->maURL ); 900 aCnt = ::ucbhelper::Content( aURL, mxCmdEnv ); 901 } 902 catch( Exception const & ) 903 { 904 bEnableDelete = bEnableRename = false; 905 } 906 907 if ( bEnableDelete ) 908 { 909 try 910 { 911 Reference< XCommandInfo > aCommands = aCnt.getCommands(); 912 if ( aCommands.is() ) 913 bEnableDelete 914 = aCommands->hasCommandByName( 915 OUString::createFromAscii( "delete" ) ); 916 else 917 bEnableDelete = false; 918 } 919 catch( Exception const & ) 920 { 921 bEnableDelete = false; 922 } 923 } 924 925 if ( bEnableRename ) 926 { 927 try 928 { 929 Reference< XPropertySetInfo > aProps = aCnt.getProperties(); 930 if ( aProps.is() ) 931 { 932 Property aProp 933 = aProps->getPropertyByName( 934 OUString::createFromAscii( "Title" ) ); 935 bEnableRename 936 = !( aProp.Attributes & PropertyAttribute::READONLY ); 937 } 938 else 939 bEnableRename = false; 940 } 941 catch( Exception const & ) 942 { 943 bEnableRename = false; 944 } 945 } 946 947 pEntry = ( bEnableDelete || bEnableRename ) 948 ? NextSelected( pEntry ) 949 : 0; 950 } 951 } 952 953 if ( bEnableDelete || bEnableRename ) 954 { 955 PopupMenu * pRet 956 = new PopupMenu( SvtResId( RID_FILEVIEW_CONTEXTMENU ) ); 957 pRet->EnableItem( MID_FILEVIEW_DELETE, bEnableDelete ); 958 pRet->EnableItem( MID_FILEVIEW_RENAME, bEnableRename ); 959 pRet->RemoveDisabledEntries( sal_True, sal_True ); 960 return pRet; 961 } 962 963 return NULL; 964 } 965 966 // ----------------------------------------------------------------------- 967 968 void ViewTabListBox_Impl::ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry ) 969 { 970 switch ( nSelectedPopupEntry ) 971 { 972 case MID_FILEVIEW_DELETE : 973 DeleteEntries(); 974 break; 975 976 case MID_FILEVIEW_RENAME : 977 EditEntry( FirstSelected() ); 978 break; 979 } 980 } 981 982 // ----------------------------------------------------------------------- 983 984 void ViewTabListBox_Impl::ClearAll() 985 { 986 for ( sal_uInt16 i = 0; i < GetEntryCount(); ++i ) 987 delete (SvtContentEntry*)GetEntry(i)->GetUserData(); 988 Clear(); 989 } 990 991 // ----------------------------------------------------------------------- 992 void ViewTabListBox_Impl::DeleteEntries() 993 { 994 svtools::QueryDeleteResult_Impl eResult = svtools::QUERYDELETE_YES; 995 SvLBoxEntry* pEntry = FirstSelected(); 996 String aURL; 997 998 ByteString sDialogPosition; 999 while ( pEntry && ( eResult != svtools::QUERYDELETE_CANCEL ) ) 1000 { 1001 SvLBoxEntry *pCurEntry = pEntry; 1002 pEntry = NextSelected( pEntry ); 1003 1004 if ( pCurEntry->GetUserData() ) 1005 aURL = ( (SvtContentEntry*)pCurEntry->GetUserData() )->maURL; 1006 1007 if ( !aURL.Len() ) 1008 continue; 1009 1010 bool canDelete = true; 1011 try 1012 { 1013 ::ucbhelper::Content aCnt( aURL, mxCmdEnv ); 1014 Reference< XCommandInfo > aCommands = aCnt.getCommands(); 1015 if ( aCommands.is() ) 1016 canDelete 1017 = aCommands->hasCommandByName( 1018 OUString::createFromAscii( "delete" ) ); 1019 else 1020 canDelete = false; 1021 } 1022 catch( Exception const & ) 1023 { 1024 canDelete = false; 1025 } 1026 1027 if (!canDelete) 1028 continue; // process next entry 1029 1030 if ( eResult != svtools::QUERYDELETE_ALL ) 1031 { 1032 INetURLObject aObj( aURL ); 1033 svtools::QueryDeleteDlg_Impl aDlg( NULL, aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) ); 1034 if ( sDialogPosition.Len() ) 1035 aDlg.SetWindowState( sDialogPosition ); 1036 1037 if ( GetSelectionCount() > 1 ) 1038 aDlg.EnableAllButton(); 1039 1040 if ( aDlg.Execute() == RET_OK ) 1041 eResult = aDlg.GetResult(); 1042 else 1043 eResult = svtools::QUERYDELETE_CANCEL; 1044 1045 sDialogPosition = aDlg.GetWindowState( ); 1046 } 1047 1048 if ( ( eResult == svtools::QUERYDELETE_ALL ) || 1049 ( eResult == svtools::QUERYDELETE_YES ) ) 1050 { 1051 if ( Kill( aURL ) ) 1052 { 1053 delete (SvtContentEntry*)pCurEntry->GetUserData(); 1054 GetModel()->Remove( pCurEntry ); 1055 mpParent->EntryRemoved( aURL ); 1056 } 1057 } 1058 } 1059 } 1060 1061 // ----------------------------------------------------------------------- 1062 sal_Bool ViewTabListBox_Impl::EditedEntry( SvLBoxEntry* pEntry, 1063 const XubString& rNewText ) 1064 { 1065 sal_Bool bRet = sal_False; 1066 1067 OUString aURL; 1068 SvtContentEntry* pData = (SvtContentEntry*)pEntry->GetUserData(); 1069 1070 if ( pData ) 1071 aURL = OUString( pData->maURL ); 1072 1073 if ( ! aURL.getLength() ) 1074 return bRet; 1075 1076 try 1077 { 1078 OUString aPropName = OUString::createFromAscii( "Title" ); 1079 bool canRename = true; 1080 ::ucbhelper::Content aContent( aURL, mxCmdEnv ); 1081 1082 try 1083 { 1084 Reference< XPropertySetInfo > aProps = aContent.getProperties(); 1085 if ( aProps.is() ) 1086 { 1087 Property aProp = aProps->getPropertyByName( aPropName ); 1088 canRename = !( aProp.Attributes & PropertyAttribute::READONLY ); 1089 } 1090 else 1091 { 1092 canRename = false; 1093 } 1094 } 1095 catch ( Exception const & ) 1096 { 1097 canRename = false; 1098 } 1099 1100 if ( canRename ) 1101 { 1102 Any aValue; 1103 aValue <<= OUString( rNewText ); 1104 aContent.setPropertyValue( aPropName, aValue ); 1105 mpParent->EntryRenamed( aURL, rNewText ); 1106 1107 pData->maURL = aURL; 1108 pEntry->SetUserData( pData ); 1109 1110 bRet = sal_True; 1111 } 1112 } 1113 catch( Exception const & ) 1114 { 1115 } 1116 1117 return bRet; 1118 } 1119 1120 // ----------------------------------------------------------------------- 1121 void ViewTabListBox_Impl::DoQuickSearch( const xub_Unicode& rChar ) 1122 { 1123 ::osl::MutexGuard aGuard( maMutex ); 1124 1125 maResetQuickSearch.Stop(); 1126 1127 OUString aLastText = maQuickSearchText; 1128 sal_uInt32 aLastPos = mnSearchIndex; 1129 sal_Bool bFound = sal_False; 1130 1131 maQuickSearchText += OUString( String( rChar ) ).toAsciiLowerCase(); 1132 1133 bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, sal_False ); 1134 1135 if ( !bFound && ( aLastText.getLength() == 1 ) && 1136 ( aLastText == OUString( String( rChar ) ) ) ) 1137 { 1138 mnSearchIndex = aLastPos + 1; 1139 maQuickSearchText = aLastText; 1140 bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, sal_True ); 1141 } 1142 1143 if ( bFound ) 1144 { 1145 SvLBoxEntry* pEntry = GetEntry( mnSearchIndex ); 1146 if ( pEntry ) 1147 { 1148 SelectAll( sal_False ); 1149 Select( pEntry ); 1150 SetCurEntry( pEntry ); 1151 MakeVisible( pEntry ); 1152 } 1153 else 1154 bFound = sal_False; 1155 } 1156 1157 if ( !bFound ) 1158 Sound::Beep(); 1159 1160 maResetQuickSearch.Start(); 1161 } 1162 1163 // ----------------------------------------------------------------------- 1164 sal_Bool ViewTabListBox_Impl::DoubleClickHdl() 1165 { 1166 SvHeaderTabListBox::DoubleClickHdl(); 1167 return sal_False; 1168 // this means "do no additional handling". Especially this means that the SvImpLBox does not 1169 // recognize that the entry at the double click position change after the handler call (which is 1170 // the case if in the handler, our content was replaced) 1171 // If it _would_ recognize this change, it would take this as a reason to select the entry, again 1172 // - which is not what in the case of content replace 1173 // (I really doubt that this behaviour of the SvImpLBox does make any sense at all, but 1174 // who knows ...) 1175 // 07.12.2001 - 95727 - fs@openoffice.org 1176 } 1177 1178 ::rtl::OUString ViewTabListBox_Impl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const 1179 { 1180 ::rtl::OUString sRet = SvHeaderTabListBox::GetAccessibleObjectDescription( _eType, _nPos ); 1181 if ( ::svt::BBTYPE_TABLECELL == _eType ) 1182 { 1183 sal_Int32 nRow = -1; 1184 const sal_uInt16 nColumnCount = GetColumnCount(); 1185 if (nColumnCount > 0) 1186 nRow = _nPos / nColumnCount; 1187 SvLBoxEntry* pEntry = GetEntry( nRow ); 1188 if ( pEntry ) 1189 { 1190 SvtContentEntry* pData = (SvtContentEntry*)pEntry->GetUserData(); 1191 if ( pData ) 1192 { 1193 static const String sVar1( RTL_CONSTASCII_USTRINGPARAM( "%1" ) ); 1194 static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) ); 1195 String aText( msAccessibleDescText ); 1196 aText.SearchAndReplace( sVar1, pData->mbIsFolder ? msFolder : msFile ); 1197 aText.SearchAndReplace( sVar2, pData->maURL ); 1198 sRet += ::rtl::OUString( aText ); 1199 } 1200 } 1201 } 1202 1203 return sRet; 1204 } 1205 1206 // ----------------------------------------------------------------------- 1207 sal_Bool ViewTabListBox_Impl::Kill( const OUString& rContent ) 1208 { 1209 sal_Bool bRet = sal_True; 1210 1211 try 1212 { 1213 ::ucbhelper::Content aCnt( rContent, mxCmdEnv ); 1214 aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); 1215 } 1216 catch( ::com::sun::star::ucb::CommandAbortedException const & ) 1217 { 1218 DBG_WARNING( "CommandAbortedException" ); 1219 bRet = sal_False; 1220 } 1221 catch( Exception const & ) 1222 { 1223 DBG_WARNING( "Any other exception" ); 1224 bRet = sal_False; 1225 } 1226 1227 return bRet; 1228 } 1229 1230 1231 1232 1233 // ----------------------------------------------------------------------- 1234 // class SvtFileView ----------------------------------------------------- 1235 // ----------------------------------------------------------------------- 1236 1237 SvtFileView::SvtFileView( Window* pParent, const ResId& rResId, 1238 sal_Bool bOnlyFolder, sal_Bool bMultiSelection ) : 1239 1240 Control( pParent, rResId ) 1241 { 1242 sal_Int8 nFlags = FILEVIEW_SHOW_ALL; 1243 if ( bOnlyFolder ) 1244 nFlags |= FILEVIEW_ONLYFOLDER; 1245 if ( bMultiSelection ) 1246 nFlags |= FILEVIEW_MULTISELECTION; 1247 1248 Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > ( 1249 ::comphelper::getProcessServiceFactory()->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY ); 1250 Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() ); 1251 1252 mpImp = new SvtFileView_Impl( this, xCmdEnv, nFlags, bOnlyFolder ); 1253 mpImp->mpView->ForbidEmptyText(); 1254 1255 long pTabs[] = { 5, 20, 180, 320, 400, 600 }; 1256 mpImp->mpView->SetTabs( &pTabs[0], MAP_PIXEL ); 1257 mpImp->mpView->SetTabJustify( 2, AdjustRight ); // column "Size" 1258 1259 if ( bMultiSelection ) 1260 mpImp->mpView->SetSelectionMode( MULTIPLE_SELECTION ); 1261 1262 HeaderBar* pHeaderBar = mpImp->mpView->GetHeaderBar(); 1263 pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) ); 1264 pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) ); 1265 } 1266 1267 SvtFileView::SvtFileView( Window* pParent, const ResId& rResId, sal_Int8 nFlags ) : 1268 1269 Control( pParent, rResId ) 1270 { 1271 Reference< XInteractionHandler > xInteractionHandler = Reference< XInteractionHandler > ( 1272 ::comphelper::getProcessServiceFactory()->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uui.InteractionHandler") ) ), UNO_QUERY ); 1273 Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() ); 1274 mpImp = new SvtFileView_Impl( this, xCmdEnv, nFlags, 1275 ( nFlags & FILEVIEW_ONLYFOLDER ) == FILEVIEW_ONLYFOLDER ); 1276 1277 if ( ( nFlags & FILEVIEW_SHOW_ALL ) == FILEVIEW_SHOW_ALL ) 1278 { 1279 long pTabs[] = { 5, 20, 180, 320, 400, 600 }; 1280 mpImp->mpView->SetTabs( &pTabs[0], MAP_PIXEL ); 1281 mpImp->mpView->SetTabJustify( 2, AdjustRight ); // column "Size" 1282 } 1283 else 1284 { 1285 // show only title 1286 long pTabs[] = { 2, 20, 600 }; 1287 mpImp->mpView->SetTabs( &pTabs[0], MAP_PIXEL ); 1288 } 1289 1290 if ( ( nFlags & FILEVIEW_MULTISELECTION ) == FILEVIEW_MULTISELECTION ) 1291 mpImp->mpView->SetSelectionMode( MULTIPLE_SELECTION ); 1292 1293 HeaderBar *pHeaderBar = mpImp->mpView->GetHeaderBar(); 1294 pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) ); 1295 pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) ); 1296 } 1297 1298 // ----------------------------------------------------------------------- 1299 1300 SvtFileView::~SvtFileView() 1301 { 1302 // use temp pointer to prevent access of deleted member (GetFocus()) 1303 SvtFileView_Impl* pTemp = mpImp; 1304 mpImp = NULL; 1305 delete pTemp; 1306 } 1307 1308 // ----------------------------------------------------------------------- 1309 1310 void SvtFileView::OpenFolder( const Sequence< OUString >& aContents ) 1311 { 1312 mpImp->mpView->ClearAll(); 1313 const OUString* pFileProperties = aContents.getConstArray(); 1314 sal_uInt32 i, nCount = aContents.getLength(); 1315 for ( i = 0; i < nCount; ++i ) 1316 { 1317 String aRow( pFileProperties[i] ); 1318 // extract columns 1319 // the columns are: title, type, size, date, target url, is folder, image url 1320 String aTitle, aType, aSize, aDate, aURL, aImageURL; 1321 xub_StrLen nIdx = 0; 1322 aTitle = aRow.GetToken( 0, '\t', nIdx ); 1323 aType = aRow.GetToken( 0, '\t', nIdx ); 1324 aSize = aRow.GetToken( 0, '\t', nIdx ); 1325 aDate = aRow.GetToken( 0, '\t', nIdx ); 1326 aURL = aRow.GetToken( 0, '\t', nIdx ); 1327 sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0); 1328 sal_Bool bIsFolder = ( '1' == cFolder ); 1329 if ( nIdx != STRING_NOTFOUND ) 1330 aImageURL = aRow.GetToken( 0, '\t', nIdx ); 1331 1332 if ( mpImp->mbOnlyFolder && !bIsFolder ) 1333 continue; 1334 1335 // build new row 1336 String aNewRow = aTitle; 1337 aNewRow += '\t'; 1338 aNewRow += aType; 1339 aNewRow += '\t'; 1340 aNewRow += aSize; 1341 aNewRow += '\t'; 1342 aNewRow += aDate; 1343 // detect image 1344 sal_Bool bDoInsert = sal_True; 1345 INetURLObject aObj( aImageURL.Len() > 0 ? aImageURL : aURL ); 1346 Image aImage = SvFileInformationManager::GetImage( aObj, sal_False, isHighContrast( this ) ); 1347 1348 if ( bDoInsert ) 1349 { 1350 // insert entry and set user data 1351 SvLBoxEntry* pEntry = mpImp->mpView->InsertEntry( aNewRow, aImage, aImage, NULL ); 1352 SvtContentEntry* pUserData = new SvtContentEntry( aURL, bIsFolder ); 1353 pEntry->SetUserData( pUserData ); 1354 } 1355 } 1356 1357 mpImp->InitSelection(); 1358 mpImp->ResetCursor(); 1359 } 1360 1361 // ----------------------------------------------------------------------- 1362 1363 String SvtFileView::GetURL( SvLBoxEntry* pEntry ) const 1364 { 1365 String aURL; 1366 if ( pEntry && pEntry->GetUserData() ) 1367 aURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL; 1368 return aURL; 1369 } 1370 1371 // ----------------------------------------------------------------------- 1372 1373 String SvtFileView::GetCurrentURL() const 1374 { 1375 String aURL; 1376 SvLBoxEntry* pEntry = mpImp->mpView->FirstSelected(); 1377 if ( pEntry && pEntry->GetUserData() ) 1378 aURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL; 1379 return aURL; 1380 } 1381 // ----------------------------------------------------------------------------- 1382 1383 sal_Bool SvtFileView::CreateNewFolder( const String& rNewFolder ) 1384 { 1385 sal_Bool bRet = sal_False; 1386 INetURLObject aObj( mpImp->maViewURL ); 1387 aObj.insertName( rNewFolder, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL ); 1388 String sURL = aObj.GetMainURL( INetURLObject::NO_DECODE ); 1389 if ( ::utl::UCBContentHelper::MakeFolder( sURL, sal_True ) ) 1390 { 1391 String sTitle = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); 1392 String sEntry = mpImp->FolderInserted( sURL, sTitle ); 1393 SvLBoxEntry* pEntry = mpImp->mpView->InsertEntry( sEntry, mpImp->maFolderImage, mpImp->maFolderImage ); 1394 SvtContentEntry* pUserData = new SvtContentEntry( sURL, sal_True ); 1395 pEntry->SetUserData( pUserData ); 1396 mpImp->mpView->MakeVisible( pEntry ); 1397 bRet = sal_True; 1398 } 1399 return bRet; 1400 } 1401 1402 // ----------------------------------------------------------------------- 1403 1404 FileViewResult SvtFileView::PreviousLevel( const FileViewAsyncAction* pAsyncDescriptor ) 1405 { 1406 FileViewResult eResult = eFailure; 1407 1408 String sParentURL; 1409 if ( GetParentURL( sParentURL ) ) 1410 eResult = Initialize( sParentURL, mpImp->maCurrentFilter, pAsyncDescriptor, mpBlackList ); 1411 1412 return eResult; 1413 } 1414 1415 // ----------------------------------------------------------------------- 1416 1417 sal_Bool SvtFileView::GetParentURL( String& rParentURL ) const 1418 { 1419 sal_Bool bRet = sal_False; 1420 try 1421 { 1422 ::ucbhelper::Content aCnt( mpImp->maViewURL, mpImp->mxCmdEnv ); 1423 Reference< XContent > xContent( aCnt.get() ); 1424 Reference< com::sun::star::container::XChild > xChild( xContent, UNO_QUERY ); 1425 if ( xChild.is() ) 1426 { 1427 Reference< XContent > xParent( xChild->getParent(), UNO_QUERY ); 1428 if ( xParent.is() ) 1429 { 1430 rParentURL = String( xParent->getIdentifier()->getContentIdentifier() ); 1431 bRet = ( rParentURL.Len() > 0 && rParentURL != mpImp->maViewURL ); 1432 } 1433 } 1434 } 1435 catch( Exception const & ) 1436 { 1437 // perhaps an unkown url protocol (e.g. "private:newdoc") 1438 } 1439 1440 return bRet; 1441 } 1442 1443 // ----------------------------------------------------------------------- 1444 1445 const rtl::OString& SvtFileView::GetHelpId( ) const 1446 { 1447 return mpImp->mpView->GetHelpId( ); 1448 } 1449 1450 // ----------------------------------------------------------------------- 1451 1452 void SvtFileView::SetHelpId( const rtl::OString& rHelpId ) 1453 { 1454 mpImp->mpView->SetHelpId( rHelpId ); 1455 } 1456 1457 // ----------------------------------------------------------------------- 1458 1459 void SvtFileView::SetSizePixel( const Size& rNewSize ) 1460 { 1461 Control::SetSizePixel( rNewSize ); 1462 mpImp->mpView->SetSizePixel( rNewSize ); 1463 } 1464 1465 // ----------------------------------------------------------------------- 1466 1467 void SvtFileView::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize ) 1468 { 1469 SetPosPixel( rNewPos ); 1470 SetSizePixel( rNewSize ); 1471 } 1472 1473 // ----------------------------------------------------------------------------- 1474 sal_Bool SvtFileView::Initialize( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent>& _xContent, const String& rFilter ) 1475 { 1476 WaitObject aWaitCursor( this ); 1477 1478 mpImp->Clear(); 1479 ::ucbhelper::Content aContent(_xContent, mpImp->mxCmdEnv ); 1480 FileViewResult eResult = mpImp->GetFolderContent_Impl( FolderDescriptor( aContent ), NULL ); 1481 OSL_ENSURE( eResult != eStillRunning, "SvtFileView::Initialize: this was expected to be synchronous!" ); 1482 if ( eResult != eSuccess ) 1483 return sal_False; 1484 1485 mpImp->FilterFolderContent_Impl( rFilter ); 1486 1487 mpImp->SortFolderContent_Impl(); // possibly not necessary!!!!!!!!!! 1488 mpImp->CreateDisplayText_Impl(); 1489 mpImp->OpenFolder_Impl(); 1490 1491 mpImp->maOpenDoneLink.Call( this ); 1492 return sal_True; 1493 } 1494 1495 // ----------------------------------------------------------------------- 1496 FileViewResult SvtFileView::Initialize( 1497 const String& rURL, 1498 const String& rFilter, 1499 const FileViewAsyncAction* pAsyncDescriptor, 1500 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) 1501 { 1502 WaitObject aWaitCursor( this ); 1503 mpBlackList = rBlackList; 1504 1505 String sPushURL( mpImp->maViewURL ); 1506 1507 mpImp->maViewURL = rURL; 1508 FileViewResult eResult = ExecuteFilter( rFilter, pAsyncDescriptor ); 1509 switch ( eResult ) 1510 { 1511 case eFailure: 1512 case eTimeout: 1513 mpImp->maViewURL = sPushURL; 1514 return eResult; 1515 1516 case eStillRunning: 1517 OSL_ENSURE( pAsyncDescriptor, "SvtFileView::Initialize: we told it to read synchronously!" ); 1518 case eSuccess: 1519 return eResult; 1520 } 1521 1522 OSL_ENSURE( sal_False, "SvtFileView::Initialize: unreachable!" ); 1523 return eFailure; 1524 } 1525 1526 // ----------------------------------------------------------------------- 1527 FileViewResult SvtFileView::Initialize( 1528 const String& rURL, 1529 const String& rFilter, 1530 const FileViewAsyncAction* pAsyncDescriptor ) 1531 { 1532 return Initialize( rURL, rFilter, pAsyncDescriptor, ::com::sun::star::uno::Sequence< ::rtl::OUString >()); 1533 } 1534 1535 // ----------------------------------------------------------------------- 1536 1537 // ----------------------------------------------------------------------- 1538 sal_Bool SvtFileView::Initialize( const Sequence< OUString >& aContents ) 1539 { 1540 WaitObject aWaitCursor( this ); 1541 1542 mpImp->maViewURL = String(); 1543 mpImp->maCurrentFilter = mpImp->maAllFilter; 1544 1545 mpImp->Clear(); 1546 mpImp->CreateVector_Impl( aContents ); 1547 mpImp->SortFolderContent_Impl(); 1548 1549 mpImp->OpenFolder_Impl(); 1550 1551 mpImp->maOpenDoneLink.Call( this ); 1552 1553 return sal_True; 1554 } 1555 1556 // ----------------------------------------------------------------------- 1557 1558 FileViewResult SvtFileView::ExecuteFilter( const String& rFilter, const FileViewAsyncAction* pAsyncDescriptor ) 1559 { 1560 mpImp->maCurrentFilter = rFilter; 1561 mpImp->maCurrentFilter.ToLowerAscii(); 1562 1563 mpImp->Clear(); 1564 FileViewResult eResult = mpImp->GetFolderContent_Impl( mpImp->maViewURL, pAsyncDescriptor, mpBlackList ); 1565 OSL_ENSURE( ( eResult != eStillRunning ) || pAsyncDescriptor, "SvtFileView::ExecuteFilter: we told it to read synchronously!" ); 1566 return eResult; 1567 } 1568 1569 // ----------------------------------------------------------------------- 1570 1571 void SvtFileView::CancelRunningAsyncAction() 1572 { 1573 mpImp->CancelRunningAsyncAction(); 1574 } 1575 1576 // ----------------------------------------------------------------------- 1577 1578 void SvtFileView::SetNoSelection() 1579 { 1580 mpImp->mpView->SelectAll( sal_False ); 1581 } 1582 1583 // ----------------------------------------------------------------------- 1584 1585 void SvtFileView::GetFocus() 1586 { 1587 Control::GetFocus(); 1588 if ( mpImp && mpImp->mpView ) 1589 mpImp->mpView->GrabFocus(); 1590 } 1591 1592 // ----------------------------------------------------------------------- 1593 1594 void SvtFileView::ResetCursor() 1595 { 1596 mpImp->ResetCursor(); 1597 } 1598 1599 // ----------------------------------------------------------------------- 1600 1601 void SvtFileView::SetSelectHdl( const Link& rHdl ) 1602 { 1603 mpImp->SetSelectHandler( rHdl ); 1604 } 1605 1606 // ----------------------------------------------------------------------- 1607 1608 void SvtFileView::SetDoubleClickHdl( const Link& rHdl ) 1609 { 1610 mpImp->mpView->SetDoubleClickHdl( rHdl ); 1611 } 1612 1613 // ----------------------------------------------------------------------- 1614 1615 sal_uLong SvtFileView::GetSelectionCount() const 1616 { 1617 return mpImp->mpView->GetSelectionCount(); 1618 } 1619 1620 // ----------------------------------------------------------------------- 1621 1622 SvLBoxEntry* SvtFileView::FirstSelected() const 1623 { 1624 return mpImp->mpView->FirstSelected(); 1625 } 1626 1627 // ----------------------------------------------------------------------- 1628 1629 SvLBoxEntry* SvtFileView::NextSelected( SvLBoxEntry* pEntry ) const 1630 { 1631 return mpImp->mpView->NextSelected( pEntry ); 1632 } 1633 1634 // ----------------------------------------------------------------------- 1635 1636 void SvtFileView::EnableAutoResize() 1637 { 1638 mpImp->mpView->EnableAutoResize(); 1639 } 1640 1641 // ----------------------------------------------------------------------- 1642 1643 void SvtFileView::SetFocus() 1644 { 1645 mpImp->mpView->GrabFocus(); 1646 } 1647 1648 // ----------------------------------------------------------------------- 1649 const String& SvtFileView::GetViewURL() const 1650 { 1651 return mpImp->maViewURL; 1652 } 1653 1654 // ----------------------------------------------------------------------- 1655 void SvtFileView::SetOpenDoneHdl( const Link& rHdl ) 1656 { 1657 mpImp->maOpenDoneLink = rHdl; 1658 } 1659 1660 // ----------------------------------------------------------------------- 1661 void SvtFileView::EnableContextMenu( sal_Bool bEnable ) 1662 { 1663 mpImp->EnableContextMenu( bEnable ); 1664 } 1665 1666 // ----------------------------------------------------------------------- 1667 void SvtFileView::EnableDelete( sal_Bool bEnable ) 1668 { 1669 mpImp->EnableDelete( bEnable ); 1670 } 1671 1672 void SvtFileView::EnableNameReplacing( sal_Bool bEnable ) 1673 { 1674 mpImp->EnableNameReplacing( bEnable ); 1675 } 1676 1677 // ----------------------------------------------------------------------- 1678 void SvtFileView::EndInplaceEditing( bool _bCancel ) 1679 { 1680 return mpImp->EndEditing( _bCancel ); 1681 } 1682 1683 // ----------------------------------------------------------------------- 1684 IMPL_LINK( SvtFileView, HeaderSelect_Impl, HeaderBar*, pBar ) 1685 { 1686 DBG_ASSERT( pBar, "no headerbar" ); 1687 sal_uInt16 nItemID = pBar->GetCurItemId(); 1688 1689 HeaderBarItemBits nBits; 1690 1691 // clear the arrow of the recently used column 1692 if ( nItemID != mpImp->mnSortColumn ) 1693 { 1694 if ( !nItemID ) 1695 { 1696 // first call -> remove arrow from title column, 1697 // because another column is the sort column 1698 nItemID = mpImp->mnSortColumn; 1699 mpImp->mnSortColumn = COLUMN_TITLE; 1700 } 1701 nBits = pBar->GetItemBits( mpImp->mnSortColumn ); 1702 nBits &= ~( HIB_UPARROW | HIB_DOWNARROW ); 1703 pBar->SetItemBits( mpImp->mnSortColumn, nBits ); 1704 } 1705 1706 nBits = pBar->GetItemBits( nItemID ); 1707 1708 sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW ); 1709 1710 if ( bUp ) 1711 { 1712 nBits &= ~HIB_UPARROW; 1713 nBits |= HIB_DOWNARROW; 1714 } 1715 else 1716 { 1717 nBits &= ~HIB_DOWNARROW; 1718 nBits |= HIB_UPARROW; 1719 } 1720 1721 pBar->SetItemBits( nItemID, nBits ); 1722 mpImp->Resort_Impl( nItemID, !bUp ); 1723 return 1; 1724 } 1725 1726 // ----------------------------------------------------------------------- 1727 IMPL_LINK( SvtFileView, HeaderEndDrag_Impl, HeaderBar*, pBar ) 1728 { 1729 if ( !pBar->IsItemMode() ) 1730 { 1731 Size aSize; 1732 sal_uInt16 nTabs = pBar->GetItemCount(); 1733 long nTmpSize = 0; 1734 1735 for ( sal_uInt16 i = 1; i <= nTabs; ++i ) 1736 { 1737 long nWidth = pBar->GetItemSize(i); 1738 aSize.Width() = nWidth + nTmpSize; 1739 nTmpSize += nWidth; 1740 mpImp->mpView->SetTab( i, aSize.Width(), MAP_PIXEL ); 1741 } 1742 } 1743 1744 return 0; 1745 } 1746 1747 // ----------------------------------------------------------------------- 1748 String SvtFileView::GetConfigString() const 1749 { 1750 String sRet; 1751 HeaderBar* pBar = mpImp->mpView->GetHeaderBar(); 1752 DBG_ASSERT( pBar, "invalid headerbar" ); 1753 1754 // sort order 1755 sRet += String::CreateFromInt32( mpImp->mnSortColumn ); 1756 sRet += ';'; 1757 HeaderBarItemBits nBits = pBar->GetItemBits( mpImp->mnSortColumn ); 1758 sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW ); 1759 sRet += bUp ? '1' : '0'; 1760 sRet += ';'; 1761 1762 sal_uInt16 nCount = pBar->GetItemCount(); 1763 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1764 { 1765 sal_uInt16 nId = pBar->GetItemId(i); 1766 sRet += String::CreateFromInt32( nId ); 1767 sRet += ';'; 1768 sRet += String::CreateFromInt32( pBar->GetItemSize( nId ) ); 1769 sRet += ';'; 1770 } 1771 1772 sRet.EraseTrailingChars( ';' ); 1773 return sRet; 1774 } 1775 1776 // ----------------------------------------------------------------------- 1777 void SvtFileView::SetConfigString( const String& rCfgStr ) 1778 { 1779 HeaderBar* pBar = mpImp->mpView->GetHeaderBar(); 1780 DBG_ASSERT( pBar, "invalid headerbar" ); 1781 1782 sal_uInt16 nIdx = 0; 1783 mpImp->mnSortColumn = (sal_uInt16)rCfgStr.GetToken( 0, ';', nIdx ).ToInt32(); 1784 sal_Bool bUp = (sal_Bool)(sal_uInt16)rCfgStr.GetToken( 0, ';', nIdx ).ToInt32(); 1785 HeaderBarItemBits nBits = pBar->GetItemBits( mpImp->mnSortColumn ); 1786 1787 if ( bUp ) 1788 { 1789 nBits &= ~HIB_UPARROW; 1790 nBits |= HIB_DOWNARROW; 1791 } 1792 else 1793 { 1794 nBits &= ~HIB_DOWNARROW; 1795 nBits |= HIB_UPARROW; 1796 } 1797 pBar->SetItemBits( mpImp->mnSortColumn, nBits ); 1798 1799 while ( nIdx != STRING_NOTFOUND ) 1800 { 1801 sal_uInt16 nItemId = (sal_uInt16)rCfgStr.GetToken( 0, ';', nIdx ).ToInt32(); 1802 pBar->SetItemSize( nItemId, rCfgStr.GetToken( 0, ';', nIdx ).ToInt32() ); 1803 } 1804 1805 HeaderSelect_Impl( pBar ); 1806 HeaderEndDrag_Impl( pBar ); 1807 } 1808 1809 // ----------------------------------------------------------------------- 1810 void SvtFileView::SetUrlFilter( const IUrlFilter* _pFilter ) 1811 { 1812 mpImp->mpUrlFilter = _pFilter; 1813 } 1814 1815 // ----------------------------------------------------------------------- 1816 const IUrlFilter* SvtFileView::GetUrlFilter( ) const 1817 { 1818 return mpImp->mpUrlFilter; 1819 } 1820 1821 // ----------------------------------------------------------------------- 1822 void SvtFileView::StateChanged( StateChangedType nStateChange ) 1823 { 1824 if ( nStateChange == STATE_CHANGE_ENABLE ) 1825 Invalidate(); 1826 Control::StateChanged( nStateChange ); 1827 } 1828 1829 // ----------------------------------------------------------------------- 1830 // class NameTranslator_Impl 1831 // ----------------------------------------------------------------------- 1832 1833 NameTranslator_Impl::NameTranslator_Impl( void ) : 1834 mpActFolder( NULL ) 1835 { 1836 } 1837 1838 NameTranslator_Impl::NameTranslator_Impl( const INetURLObject& rActualFolder ) 1839 { 1840 mpActFolder = new NameTranslationList( rActualFolder ); 1841 } 1842 1843 NameTranslator_Impl::~NameTranslator_Impl() 1844 { 1845 if( mpActFolder ) 1846 delete mpActFolder; 1847 } 1848 1849 void NameTranslator_Impl::UpdateTranslationTable() 1850 { 1851 if( mpActFolder ) 1852 mpActFolder->Update(); 1853 } 1854 1855 void NameTranslator_Impl::SetActualFolder( const INetURLObject& rActualFolder ) 1856 { 1857 HashedEntry aActFolder( rActualFolder ); 1858 1859 if( mpActFolder ) 1860 { 1861 if( *mpActFolder != aActFolder ) 1862 { 1863 delete mpActFolder; 1864 mpActFolder = new NameTranslationList( rActualFolder ); 1865 } 1866 } 1867 else 1868 mpActFolder = new NameTranslationList( rActualFolder ); 1869 } 1870 1871 sal_Bool NameTranslator_Impl::GetTranslation( const OUString& rOrg, OUString& rTrans ) const 1872 { 1873 sal_Bool bRet = sal_False; 1874 1875 if( mpActFolder ) 1876 { 1877 const OUString* pTrans = mpActFolder->Translate( rOrg ); 1878 if( pTrans ) 1879 { 1880 rTrans = *pTrans; 1881 bRet = sal_True; 1882 } 1883 } 1884 1885 return bRet; 1886 } 1887 1888 const String* NameTranslator_Impl::GetTransTableFileName() const 1889 { 1890 return mpActFolder? &mpActFolder->GetTransTableFileName() : NULL; 1891 } 1892 1893 // ----------------------------------------------------------------------- 1894 // class SvtFileView_Impl 1895 // ----------------------------------------------------------------------- 1896 1897 SvtFileView_Impl::SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > xEnv, sal_Int16 nFlags, sal_Bool bOnlyFolder ) 1898 1899 :mpAntiImpl ( pAntiImpl ) 1900 ,m_eAsyncActionResult ( ::svt::ERROR ) 1901 ,m_bRunningAsyncAction ( false ) 1902 ,m_bAsyncActionCancelled ( false ) 1903 ,mpNameTrans ( NULL ) 1904 ,mpUrlFilter ( NULL ) 1905 ,mnSortColumn ( COLUMN_TITLE ) 1906 ,mbAscending ( sal_True ) 1907 ,mbOnlyFolder ( bOnlyFolder ) 1908 ,mbReplaceNames ( sal_False ) 1909 ,mnSuspendSelectCallback ( 0 ) 1910 ,mbIsFirstResort ( sal_True ) 1911 ,aIntlWrapper ( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ) 1912 ,maFolderImage ( SvtResId( IMG_SVT_FOLDER ) ) 1913 ,mxCmdEnv ( xEnv ) 1914 1915 { 1916 maAllFilter = String::CreateFromAscii( "*.*" ); 1917 mpView = new ViewTabListBox_Impl( mpAntiImpl, this, nFlags ); 1918 mpView->EnableCellFocus(); 1919 } 1920 1921 // ----------------------------------------------------------------------- 1922 SvtFileView_Impl::~SvtFileView_Impl() 1923 { 1924 Clear(); 1925 1926 // use temp pointer to prevent access of deleted member (GetFocus()) 1927 ViewTabListBox_Impl* pTemp = mpView; 1928 mpView = NULL; 1929 delete pTemp; 1930 } 1931 1932 // ----------------------------------------------------------------------- 1933 void SvtFileView_Impl::Clear() 1934 { 1935 ::osl::MutexGuard aGuard( maMutex ); 1936 1937 std::vector< SortingData_Impl* >::iterator aIt; 1938 1939 for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ ) 1940 delete (*aIt); 1941 1942 maContent.clear(); 1943 1944 if( mpNameTrans ) 1945 DELETEZ( mpNameTrans ); 1946 } 1947 1948 // ----------------------------------------------------------------------- 1949 FileViewResult SvtFileView_Impl::GetFolderContent_Impl( 1950 const String& rFolder, 1951 const FileViewAsyncAction* pAsyncDescriptor, 1952 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) 1953 { 1954 ::osl::ClearableMutexGuard aGuard( maMutex ); 1955 INetURLObject aFolderObj( rFolder ); 1956 DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" ); 1957 1958 // prepare name translation 1959 SetActualFolder( aFolderObj ); 1960 1961 FolderDescriptor aFolder( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) ); 1962 1963 aGuard.clear(); 1964 return GetFolderContent_Impl( aFolder, pAsyncDescriptor, rBlackList ); 1965 } 1966 1967 // ----------------------------------------------------------------------- 1968 FileViewResult SvtFileView_Impl::GetFolderContent_Impl( 1969 const FolderDescriptor& _rFolder, 1970 const FileViewAsyncAction* pAsyncDescriptor, 1971 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) 1972 { 1973 DBG_TESTSOLARMUTEX(); 1974 ::osl::ClearableMutexGuard aGuard( maMutex ); 1975 1976 OSL_ENSURE( !m_pContentEnumerator.is(), "SvtFileView_Impl::GetFolderContent_Impl: still running another enumeration!" ); 1977 m_pContentEnumerator = new ::svt::FileViewContentEnumerator( 1978 mpView->GetCommandEnvironment(), maContent, maMutex, mbReplaceNames ? mpNameTrans : NULL ); 1979 // TODO: should we cache and re-use this thread? 1980 1981 if ( !pAsyncDescriptor ) 1982 { 1983 ::svt::EnumerationResult eResult = m_pContentEnumerator->enumerateFolderContentSync( _rFolder, mpUrlFilter, rBlackList ); 1984 if ( ::svt::SUCCESS == eResult ) 1985 { 1986 implEnumerationSuccess(); 1987 m_pContentEnumerator = NULL; 1988 return eSuccess; 1989 } 1990 m_pContentEnumerator = NULL; 1991 return eFailure; 1992 } 1993 1994 m_bRunningAsyncAction = true; 1995 m_bAsyncActionCancelled = false; 1996 m_eAsyncActionResult = ::svt::ERROR; 1997 m_aAsyncActionFinished.reset(); 1998 1999 // don't (yet) set m_aCurrentAsyncActionHandler to pTimeout->aFinishHandler. 2000 // By definition, this handler *only* get's called when the result cannot be obtained 2001 // during the minimum wait time, so it is only set below, when needed. 2002 m_aCurrentAsyncActionHandler = Link(); 2003 2004 // minimum time to wait 2005 ::std::auto_ptr< TimeValue > pTimeout( new TimeValue ); 2006 sal_Int32 nMinTimeout = pAsyncDescriptor->nMinTimeout; 2007 OSL_ENSURE( nMinTimeout > 0, "SvtFileView_Impl::GetFolderContent_Impl: invalid minimum timeout!" ); 2008 if ( nMinTimeout <= 0 ) 2009 nMinTimeout = sal_Int32( 1000L ); 2010 pTimeout->Seconds = nMinTimeout / 1000L; 2011 pTimeout->Nanosec = ( nMinTimeout % 1000L ) * 1000000L; 2012 2013 m_pContentEnumerator->enumerateFolderContent( _rFolder, mpUrlFilter, this ); 2014 2015 // wait until the enumeration is finished 2016 // for this, release our own mutex (which is used by the enumerator thread) 2017 aGuard.clear(); 2018 2019 ::osl::Condition::Result eResult = ::osl::Condition::result_ok; 2020 { 2021 // also release the SolarMutex. Not all code which is needed during the enumeration 2022 // is Solar-Thread-Safe, in particular there is some code which needs to access 2023 // string resources (and our resource system relies on the SolarMutex :() 2024 ReleaseSolarMutex aSolarRelease; 2025 2026 // now wait. Note that if we didn't get an pAsyncDescriptor, then this is an infinite wait. 2027 eResult = m_aAsyncActionFinished.wait( pTimeout.get() ); 2028 } 2029 2030 ::osl::MutexGuard aGuard2( maMutex ); 2031 if ( ::osl::Condition::result_timeout == eResult ) 2032 { 2033 // maximum time to wait 2034 OSL_ENSURE( !m_pCancelAsyncTimer.get(), "SvtFileView_Impl::GetFolderContent_Impl: there's still a previous timer!" ); 2035 m_pCancelAsyncTimer = new CallbackTimer( this ); 2036 sal_Int32 nMaxTimeout = pAsyncDescriptor->nMaxTimeout; 2037 OSL_ENSURE( nMaxTimeout > nMinTimeout, 2038 "SvtFileView_Impl::GetFolderContent_Impl: invalid maximum timeout!" ); 2039 if ( nMaxTimeout <= nMinTimeout ) 2040 nMaxTimeout = nMinTimeout + 5000; 2041 m_pCancelAsyncTimer->setRemainingTime( TTimeValue( nMaxTimeout - nMinTimeout ) ); 2042 // we already waited for nMinTimeout milliseconds, so take this into account 2043 m_pCancelAsyncTimer->start(); 2044 2045 m_aCurrentAsyncActionHandler = pAsyncDescriptor->aFinishHandler; 2046 DBG_ASSERT( m_aCurrentAsyncActionHandler.IsSet(), "SvtFileView_Impl::GetFolderContent_Impl: nobody interested when it's finished?" ); 2047 mpView->ClearAll(); 2048 return eStillRunning; 2049 } 2050 2051 m_bRunningAsyncAction = false; 2052 switch ( m_eAsyncActionResult ) 2053 { 2054 case ::svt::SUCCESS: 2055 return eSuccess; 2056 2057 case ::svt::ERROR: 2058 return eFailure; 2059 2060 case ::svt::RUNNING: 2061 return eStillRunning; 2062 } 2063 2064 DBG_ERRORFILE( "SvtFileView_Impl::GetFolderContent_Impl: unreachable!" ); 2065 return eFailure; 2066 } 2067 2068 // ----------------------------------------------------------------------- 2069 void SvtFileView_Impl::FilterFolderContent_Impl( const OUString &rFilter ) 2070 { 2071 sal_Bool bHideTransFile = mbReplaceNames && mpNameTrans; 2072 2073 String sHideEntry; 2074 if( bHideTransFile ) 2075 { 2076 const String* pTransTableFileName = mpNameTrans->GetTransTableFileName(); 2077 if( pTransTableFileName ) 2078 { 2079 sHideEntry = *pTransTableFileName; 2080 sHideEntry.ToUpperAscii(); 2081 } 2082 else 2083 bHideTransFile = sal_False; 2084 } 2085 2086 if ( !bHideTransFile && 2087 ( !rFilter.getLength() || ( rFilter.compareToAscii( ALL_FILES_FILTER ) == COMPARE_EQUAL ) ) ) 2088 // when replacing names, there is always something to filter (no view of ".nametranslation.table") 2089 return; 2090 2091 ::osl::MutexGuard aGuard( maMutex ); 2092 2093 if ( maContent.empty() ) 2094 return; 2095 2096 // count (estimate) the number of filter tokens 2097 sal_Int32 nTokens=0; 2098 const sal_Unicode* pStart = rFilter.getStr(); 2099 const sal_Unicode* pEnd = pStart + rFilter.getLength(); 2100 while ( pStart != pEnd ) 2101 if ( *pStart++ == ';' ) 2102 ++nTokens; 2103 2104 // collect the filter tokens 2105 ::std::vector< WildCard > aFilters; 2106 FilterMatch::createWildCardFilterList(rFilter,aFilters); 2107 2108 2109 // do the filtering 2110 ::std::vector< SortingData_Impl* >::iterator aContentLoop = maContent.begin(); 2111 String sCompareString; 2112 do 2113 { 2114 if ( (*aContentLoop)->mbIsFolder ) 2115 ++aContentLoop; 2116 else 2117 { 2118 // normalize the content title (we always match case-insensitive) 2119 // 91872 - 11.09.2001 - frank.schoenheit@sun.com 2120 sCompareString = (*aContentLoop)->GetFileName(); // filter works on file name, not on title! 2121 sal_Bool bDelete; 2122 2123 if( bHideTransFile && sCompareString == sHideEntry ) 2124 bDelete = sal_True; 2125 else 2126 { 2127 // search for the first filter which matches 2128 ::std::vector< WildCard >::const_iterator pMatchingFilter = 2129 ::std::find_if( 2130 aFilters.begin(), 2131 aFilters.end(), 2132 FilterMatch( sCompareString ) 2133 ); 2134 2135 bDelete = aFilters.end() == pMatchingFilter; 2136 } 2137 2138 if( bDelete ) 2139 { 2140 // none of the filters did match 2141 delete (*aContentLoop); 2142 2143 if ( maContent.begin() == aContentLoop ) 2144 { 2145 maContent.erase( aContentLoop ); 2146 aContentLoop = maContent.begin(); 2147 } 2148 else 2149 { 2150 std::vector< SortingData_Impl* >::iterator aDelete = aContentLoop; 2151 --aContentLoop; // move the iterator to a position which is not invalidated by the erase 2152 maContent.erase( aDelete ); 2153 ++aContentLoop; // this is now the next one .... 2154 } 2155 } 2156 else 2157 ++aContentLoop; 2158 } 2159 } 2160 while ( aContentLoop != maContent.end() ); 2161 } 2162 2163 // ----------------------------------------------------------------------- 2164 IMPL_LINK( SvtFileView_Impl, SelectionMultiplexer, void*, _pSource ) 2165 { 2166 return mnSuspendSelectCallback ? 0L : m_aSelectHandler.Call( _pSource ); 2167 } 2168 2169 // ----------------------------------------------------------------------- 2170 void SvtFileView_Impl::SetSelectHandler( const Link& _rHdl ) 2171 { 2172 m_aSelectHandler = _rHdl; 2173 2174 Link aMasterHandler; 2175 if ( m_aSelectHandler.IsSet() ) 2176 aMasterHandler = LINK( this, SvtFileView_Impl, SelectionMultiplexer ); 2177 2178 mpView->SetSelectHdl( aMasterHandler ); 2179 } 2180 2181 // ----------------------------------------------------------------------- 2182 void SvtFileView_Impl::InitSelection() 2183 { 2184 mpView->SelectAll( sal_False ); 2185 SvLBoxEntry* pFirst = mpView->First(); 2186 if ( pFirst ) 2187 mpView->SetCursor( pFirst, sal_True ); 2188 } 2189 2190 // ----------------------------------------------------------------------- 2191 void SvtFileView_Impl::OpenFolder_Impl() 2192 { 2193 ::osl::MutexGuard aGuard( maMutex ); 2194 2195 mpView->SetUpdateMode( sal_False ); 2196 mpView->ClearAll(); 2197 2198 std::vector< SortingData_Impl* >::iterator aIt; 2199 2200 for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ ) 2201 { 2202 if ( mbOnlyFolder && ! (*aIt)->mbIsFolder ) 2203 continue; 2204 2205 // insert entry and set user data 2206 SvLBoxEntry* pEntry = mpView->InsertEntry( (*aIt)->maDisplayText, 2207 (*aIt)->maImage, 2208 (*aIt)->maImage ); 2209 2210 SvtContentEntry* pUserData = new SvtContentEntry( (*aIt)->maTargetURL, 2211 (*aIt)->mbIsFolder ); 2212 pEntry->SetUserData( pUserData ); 2213 } 2214 2215 InitSelection(); 2216 2217 ++mnSuspendSelectCallback; 2218 mpView->SetUpdateMode( sal_True ); 2219 --mnSuspendSelectCallback; 2220 2221 ResetCursor(); 2222 } 2223 2224 // ----------------------------------------------------------------------- 2225 void SvtFileView_Impl::ResetCursor() 2226 { 2227 // deselect 2228 SvLBoxEntry* pEntry = mpView->FirstSelected(); 2229 if ( pEntry ) 2230 mpView->Select( pEntry, sal_False ); 2231 // set cursor to the first entry 2232 mpView->SetCursor( mpView->First(), sal_True ); 2233 mpView->Update(); 2234 } 2235 2236 // ----------------------------------------------------------------------- 2237 void SvtFileView_Impl::CancelRunningAsyncAction() 2238 { 2239 DBG_TESTSOLARMUTEX(); 2240 ::osl::MutexGuard aGuard( maMutex ); 2241 if ( !m_pContentEnumerator.is() ) 2242 return; 2243 2244 m_bAsyncActionCancelled = true; 2245 m_pContentEnumerator->cancel(); 2246 m_bRunningAsyncAction = false; 2247 2248 m_pContentEnumerator = NULL; 2249 if ( m_pCancelAsyncTimer.is() && m_pCancelAsyncTimer->isTicking() ) 2250 m_pCancelAsyncTimer->stop(); 2251 m_pCancelAsyncTimer = NULL; 2252 } 2253 2254 //----------------------------------------------------------------------- 2255 void SvtFileView_Impl::onTimeout( CallbackTimer* ) 2256 { 2257 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 2258 ::osl::MutexGuard aGuard( maMutex ); 2259 if ( !m_bRunningAsyncAction ) 2260 // there might have been a race condition while we waited for the mutex 2261 return; 2262 2263 CancelRunningAsyncAction(); 2264 2265 if ( m_aCurrentAsyncActionHandler.IsSet() ) 2266 { 2267 Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( eTimeout ) ); 2268 m_aCurrentAsyncActionHandler = Link(); 2269 } 2270 } 2271 2272 //----------------------------------------------------------------------- 2273 void SvtFileView_Impl::enumerationDone( ::svt::EnumerationResult _eResult ) 2274 { 2275 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 2276 ::osl::MutexGuard aGuard( maMutex ); 2277 2278 m_pContentEnumerator = NULL; 2279 if ( m_pCancelAsyncTimer.is() && m_pCancelAsyncTimer->isTicking() ) 2280 m_pCancelAsyncTimer->stop(); 2281 m_pCancelAsyncTimer = NULL; 2282 2283 if ( m_bAsyncActionCancelled ) 2284 // this is to prevent race conditions 2285 return; 2286 2287 m_eAsyncActionResult = _eResult; 2288 m_bRunningAsyncAction = false; 2289 2290 m_aAsyncActionFinished.set(); 2291 2292 if ( svt::SUCCESS == _eResult ) 2293 implEnumerationSuccess(); 2294 2295 if ( m_aCurrentAsyncActionHandler.IsSet() ) 2296 { 2297 Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( m_eAsyncActionResult ) ); 2298 m_aCurrentAsyncActionHandler = Link(); 2299 } 2300 } 2301 2302 //----------------------------------------------------------------------- 2303 void SvtFileView_Impl::implEnumerationSuccess() 2304 { 2305 FilterFolderContent_Impl( maCurrentFilter ); 2306 SortFolderContent_Impl(); 2307 CreateDisplayText_Impl(); 2308 OpenFolder_Impl(); 2309 maOpenDoneLink.Call( mpAntiImpl ); 2310 } 2311 2312 // ----------------------------------------------------------------------- 2313 void SvtFileView_Impl::ReplaceTabWithString( OUString& aValue ) 2314 { 2315 OUString aTab = OUString::createFromAscii( "\t" ); 2316 OUString aTabString = OUString::createFromAscii( "%09" ); 2317 sal_Int32 iPos; 2318 2319 while ( ( iPos = aValue.indexOf( aTab ) ) >= 0 ) 2320 aValue = aValue.replaceAt( iPos, 1, aTabString ); 2321 } 2322 2323 // ----------------------------------------------------------------------- 2324 void SvtFileView_Impl::CreateDisplayText_Impl() 2325 { 2326 ::osl::MutexGuard aGuard( maMutex ); 2327 2328 OUString aValue; 2329 OUString aTab = OUString::createFromAscii( "\t" ); 2330 OUString aDateSep = OUString::createFromAscii( ", " ); 2331 2332 std::vector< SortingData_Impl* >::iterator aIt; 2333 2334 for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ ) 2335 { 2336 // title, type, size, date 2337 aValue = (*aIt)->GetTitle(); 2338 // #83004# -------------------- 2339 ReplaceTabWithString( aValue ); 2340 aValue += aTab; 2341 aValue += (*aIt)->maType; 2342 aValue += aTab; 2343 // folders don't have a size 2344 if ( ! (*aIt)->mbIsFolder ) 2345 aValue += CreateExactSizeText_Impl( (*aIt)->maSize ); 2346 aValue += aTab; 2347 // set the date, but volumes have no date 2348 if ( ! (*aIt)->mbIsFolder || ! (*aIt)->mbIsVolume ) 2349 { 2350 SvtSysLocale aSysLocale; 2351 const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); 2352 aValue += rLocaleData.getDate( (*aIt)->maModDate ); 2353 aValue += aDateSep; 2354 aValue += rLocaleData.getTime( (*aIt)->maModDate ); 2355 } 2356 (*aIt)->maDisplayText = aValue; 2357 2358 // detect image 2359 if ( (*aIt)->mbIsFolder ) 2360 { 2361 ::svtools::VolumeInfo aVolInfo( (*aIt)->mbIsVolume, (*aIt)->mbIsRemote, 2362 (*aIt)->mbIsRemoveable, (*aIt)->mbIsFloppy, 2363 (*aIt)->mbIsCompactDisc ); 2364 (*aIt)->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, sal_False, isHighContrast( mpView ) ); 2365 } 2366 else 2367 (*aIt)->maImage = SvFileInformationManager::GetFileImage( INetURLObject( (*aIt)->maTargetURL ), sal_False, isHighContrast( mpView )); 2368 } 2369 } 2370 2371 // ----------------------------------------------------------------------- 2372 // this function converts the sequence of strings into a vector of SortingData 2373 // the string should have the form : 2374 // title \t type \t size \t date \t target url \t is folder \t image url 2375 2376 void SvtFileView_Impl::CreateVector_Impl( const Sequence < OUString > &rList ) 2377 { 2378 ::osl::MutexGuard aGuard( maMutex ); 2379 2380 OUString aTab = OUString::createFromAscii( "\t" ); 2381 2382 sal_uInt32 nCount = (sal_uInt32) rList.getLength(); 2383 2384 for( sal_uInt32 i = 0; i < nCount; i++ ) 2385 { 2386 SortingData_Impl* pEntry = new SortingData_Impl; 2387 OUString aValue = rList[i]; 2388 OUString aDisplayText; 2389 sal_Int32 nIndex = 0; 2390 2391 // get the title 2392 pEntry->SetNewTitle( aValue.getToken( 0, '\t', nIndex ) ); 2393 aDisplayText = pEntry->GetTitle(); 2394 // #83004# -------------------- 2395 ReplaceTabWithString( aDisplayText ); 2396 aDisplayText += aTab; 2397 2398 // get the type 2399 if ( nIndex >= 0 ) 2400 { 2401 pEntry->maType = aValue.getToken( 0, '\t', nIndex ); 2402 aDisplayText += pEntry->maType; 2403 } 2404 aDisplayText += aTab; 2405 2406 // get the size 2407 if ( nIndex >= 0 ) 2408 { 2409 OUString aSize = aValue.getToken( 0, '\t', nIndex ); 2410 aDisplayText += aSize; 2411 2412 if ( aSize.getLength() ) 2413 pEntry->maSize = aSize.toInt64(); 2414 } 2415 aDisplayText += aTab; 2416 2417 // get the date 2418 if ( nIndex >= 0 ) 2419 { 2420 OUString aDate = aValue.getToken( 0, '\t', nIndex ); 2421 aDisplayText += aDate; 2422 2423 if ( aDate.getLength() ) 2424 { 2425 DBG_ERRORFILE( "Don't know, how to convert date" ); 2426 ;// convert date string to date 2427 } 2428 } 2429 // get the target url 2430 if ( nIndex >= 0 ) 2431 { 2432 pEntry->maTargetURL = aValue.getToken( 0, '\t', nIndex ); 2433 } 2434 // get the size 2435 if ( nIndex >= 0 ) 2436 { 2437 OUString aBool = aValue.getToken( 0, '\t', nIndex ); 2438 if ( aBool.getLength() ) 2439 pEntry->mbIsFolder = aBool.toBoolean(); 2440 } 2441 // get the image url 2442 if ( nIndex >= 0 ) 2443 { 2444 pEntry->maImageURL = aValue.getToken( 0, '\t', nIndex ); 2445 } 2446 2447 // set the display text 2448 pEntry->maDisplayText = aDisplayText; 2449 2450 // detect the image 2451 INetURLObject aObj( pEntry->maImageURL.getLength() ? pEntry->maImageURL : pEntry->maTargetURL ); 2452 pEntry->maImage = SvFileInformationManager::GetImage( aObj, sal_False, isHighContrast( mpView ) ); 2453 2454 maContent.push_back( pEntry ); 2455 } 2456 } 2457 2458 // ----------------------------------------------------------------------- 2459 void SvtFileView_Impl::Resort_Impl( sal_Int16 nColumn, sal_Bool bAscending ) 2460 { 2461 ::osl::MutexGuard aGuard( maMutex ); 2462 2463 if ( ( nColumn == mnSortColumn ) && 2464 ( bAscending == mbAscending ) ) 2465 return; 2466 2467 // reset the quick search index 2468 mpView->ResetQuickSearch_Impl( NULL ); 2469 2470 String aEntryURL; 2471 SvLBoxEntry* pEntry = mpView->GetCurEntry(); 2472 if ( pEntry && pEntry->GetUserData() ) 2473 aEntryURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL; 2474 2475 mnSortColumn = nColumn; 2476 mbAscending = bAscending; 2477 2478 SortFolderContent_Impl(); 2479 OpenFolder_Impl(); 2480 2481 if ( !mbIsFirstResort ) 2482 { 2483 sal_uLong nPos = GetEntryPos( aEntryURL ); 2484 if ( nPos < mpView->GetEntryCount() ) 2485 { 2486 pEntry = mpView->GetEntry( nPos ); 2487 2488 ++mnSuspendSelectCallback; // #i15668# - 2004-04-25 - fs@openoffice.org 2489 mpView->SetCurEntry( pEntry ); 2490 --mnSuspendSelectCallback; 2491 } 2492 } 2493 else 2494 mbIsFirstResort = sal_False; 2495 } 2496 2497 // ----------------------------------------------------------------------- 2498 static sal_Bool gbAscending = sal_True; 2499 static sal_Int16 gnColumn = COLUMN_TITLE; 2500 static const CollatorWrapper* pCollatorWrapper = NULL; 2501 2502 /* this functions returns true, if aOne is less then aTwo 2503 */ 2504 sal_Bool CompareSortingData_Impl( SortingData_Impl* const aOne, SortingData_Impl* const aTwo ) 2505 { 2506 DBG_ASSERT( pCollatorWrapper, "*CompareSortingData_Impl(): Can't work this way!" ); 2507 2508 sal_Int32 nComp; 2509 sal_Bool bRet = sal_False; 2510 sal_Bool bEqual = sal_False; 2511 2512 if ( aOne->mbIsFolder != aTwo->mbIsFolder ) 2513 { 2514 if ( aOne->mbIsFolder ) 2515 bRet = sal_True; 2516 else 2517 bRet = sal_False; 2518 2519 // !!! pb: #100376# folder always on top 2520 if ( !gbAscending ) 2521 bRet = !bRet; 2522 } 2523 else 2524 { 2525 switch ( gnColumn ) 2526 { 2527 case COLUMN_TITLE: 2528 // compare case insensitiv first 2529 nComp = pCollatorWrapper->compareString( aOne->GetLowerTitle(), aTwo->GetLowerTitle() ); 2530 2531 if ( nComp == 0 ) 2532 nComp = pCollatorWrapper->compareString( aOne->GetTitle(), aTwo->GetTitle() ); 2533 2534 if ( nComp < 0 ) 2535 bRet = sal_True; 2536 else if ( nComp > 0 ) 2537 bRet = sal_False; 2538 else 2539 bEqual = sal_True; 2540 break; 2541 case COLUMN_TYPE: 2542 nComp = pCollatorWrapper->compareString( aOne->maType, aTwo->maType ); 2543 if ( nComp < 0 ) 2544 bRet = sal_True; 2545 else if ( nComp > 0 ) 2546 bRet = sal_False; 2547 else 2548 bEqual = sal_True; 2549 break; 2550 case COLUMN_SIZE: 2551 if ( aOne->maSize < aTwo->maSize ) 2552 bRet = sal_True; 2553 else if ( aOne->maSize > aTwo->maSize ) 2554 bRet = sal_False; 2555 else 2556 bEqual = sal_True; 2557 break; 2558 case COLUMN_DATE: 2559 if ( aOne->maModDate < aTwo->maModDate ) 2560 bRet = sal_True; 2561 else if ( aOne->maModDate > aTwo->maModDate ) 2562 bRet = sal_False; 2563 else 2564 bEqual = sal_True; 2565 break; 2566 default: 2567 DBG_WARNING( "CompareSortingData_Impl: Compare unknown type!" ); 2568 bRet = sal_False; 2569 } 2570 } 2571 2572 // when the two elements are equal, we must not return sal_True (which would 2573 // happen if we just return ! ( a < b ) when not sorting ascending ) 2574 if ( bEqual ) 2575 return sal_False; 2576 2577 return gbAscending ? bRet : !bRet; 2578 } 2579 2580 // ----------------------------------------------------------------------- 2581 void SvtFileView_Impl::SortFolderContent_Impl() 2582 { 2583 ::osl::MutexGuard aGuard( maMutex ); 2584 2585 sal_uInt32 nSize = maContent.size(); 2586 2587 if ( nSize > 1 ) 2588 { 2589 gbAscending = mbAscending; 2590 gnColumn = mnSortColumn; 2591 pCollatorWrapper = aIntlWrapper.getCaseCollator(); 2592 2593 std::stable_sort( maContent.begin(), maContent.end(), CompareSortingData_Impl ); 2594 2595 pCollatorWrapper = NULL; 2596 } 2597 } 2598 2599 // ----------------------------------------------------------------------- 2600 void SvtFileView_Impl::EntryRemoved( const OUString& rURL ) 2601 { 2602 ::osl::MutexGuard aGuard( maMutex ); 2603 2604 std::vector< SortingData_Impl* >::iterator aIt; 2605 2606 for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ ) 2607 { 2608 if ( (*aIt)->maTargetURL == rURL ) 2609 { 2610 maContent.erase( aIt ); 2611 break; 2612 } 2613 } 2614 } 2615 2616 // ----------------------------------------------------------------------- 2617 void SvtFileView_Impl::EntryRenamed( OUString& rURL, 2618 const OUString& rTitle ) 2619 { 2620 ::osl::MutexGuard aGuard( maMutex ); 2621 2622 std::vector< SortingData_Impl* >::iterator aIt; 2623 2624 for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ ) 2625 { 2626 if ( (*aIt)->maTargetURL == rURL ) 2627 { 2628 (*aIt)->SetNewTitle( rTitle ); 2629 OUString aDisplayText = (*aIt)->maDisplayText; 2630 sal_Int32 nIndex = aDisplayText.indexOf( '\t' ); 2631 2632 if ( nIndex > 0 ) 2633 (*aIt)->maDisplayText = aDisplayText.replaceAt( 0, nIndex, rTitle ); 2634 2635 INetURLObject aURLObj( rURL ); 2636 aURLObj.SetName( rTitle, INetURLObject::ENCODE_ALL ); 2637 2638 rURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE ); 2639 2640 (*aIt)->maTargetURL = rURL; 2641 break; 2642 } 2643 } 2644 } 2645 2646 // ----------------------------------------------------------------------- 2647 String SvtFileView_Impl::FolderInserted( const OUString& rURL, const OUString& rTitle ) 2648 { 2649 ::osl::MutexGuard aGuard( maMutex ); 2650 2651 SortingData_Impl* pData = new SortingData_Impl; 2652 2653 pData->SetNewTitle( rTitle ); 2654 pData->maSize = 0; 2655 pData->mbIsFolder = sal_True; 2656 pData->maTargetURL = rURL; 2657 2658 INetURLObject aURLObj( rURL ); 2659 2660 ::svtools::VolumeInfo aVolInfo; 2661 pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo ); 2662 pData->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, sal_False, isHighContrast( mpView ) ); 2663 2664 OUString aValue; 2665 OUString aTab = OUString::createFromAscii( "\t" ); 2666 OUString aDateSep = OUString::createFromAscii( ", " ); 2667 2668 // title, type, size, date 2669 aValue = pData->GetTitle(); 2670 // #83004# -------------------- 2671 ReplaceTabWithString( aValue ); 2672 aValue += aTab; 2673 aValue += pData->maType; 2674 aValue += aTab; 2675 // folders don't have a size 2676 aValue += aTab; 2677 // set the date 2678 SvtSysLocale aSysLocale; 2679 const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData(); 2680 aValue += rLocaleData.getDate( pData->maModDate ); 2681 aValue += aDateSep; 2682 aValue += rLocaleData.getTime( pData->maModDate ); 2683 2684 pData->maDisplayText = aValue; 2685 maContent.push_back( pData ); 2686 2687 return String( aValue ); 2688 } 2689 2690 // ----------------------------------------------------------------------- 2691 sal_uLong SvtFileView_Impl::GetEntryPos( const OUString& rURL ) 2692 { 2693 ::osl::MutexGuard aGuard( maMutex ); 2694 2695 std::vector< SortingData_Impl* >::iterator aIt; 2696 sal_uLong nPos = 0; 2697 2698 for ( aIt = maContent.begin(); aIt != maContent.end(); aIt++ ) 2699 { 2700 if ( (*aIt)->maTargetURL == rURL ) 2701 return nPos; 2702 nPos += 1; 2703 } 2704 2705 return nPos; 2706 } 2707 2708 // ----------------------------------------------------------------------- 2709 sal_Bool SvtFileView_Impl::SearchNextEntry( sal_uInt32& nIndex, const OUString& rTitle, sal_Bool bWrapAround ) 2710 { 2711 ::osl::MutexGuard aGuard( maMutex ); 2712 2713 sal_uInt32 nEnd = maContent.size(); 2714 sal_uInt32 nStart = nIndex; 2715 while ( nIndex < nEnd ) 2716 { 2717 SortingData_Impl* pData = maContent[ nIndex ]; 2718 if ( rTitle.compareTo( pData->GetLowerTitle(), rTitle.getLength() ) == 0 ) 2719 return sal_True; 2720 nIndex += 1; 2721 } 2722 2723 if ( bWrapAround ) 2724 { 2725 nIndex = 0; 2726 while ( nIndex < nEnd && nIndex <= nStart ) 2727 { 2728 SortingData_Impl* pData = maContent[ nIndex ]; 2729 if ( rTitle.compareTo( pData->GetLowerTitle(), rTitle.getLength() ) == 0 ) 2730 return sal_True; 2731 nIndex += 1; 2732 } 2733 } 2734 2735 return sal_False; 2736 } 2737 2738 // ----------------------------------------------------------------------- 2739 void SvtFileView_Impl::SetActualFolder( const INetURLObject& rActualFolder ) 2740 { 2741 if( mbReplaceNames ) 2742 { 2743 if( mpNameTrans ) 2744 mpNameTrans->SetActualFolder( rActualFolder ); 2745 else 2746 mpNameTrans = new NameTranslator_Impl( rActualFolder ); 2747 } 2748 } 2749 2750 namespace svtools { 2751 2752 // ----------------------------------------------------------------------- 2753 // QueryDeleteDlg_Impl 2754 // ----------------------------------------------------------------------- 2755 2756 QueryDeleteDlg_Impl::QueryDeleteDlg_Impl 2757 ( 2758 Window* pParent, 2759 const String& rName // Eintragsname 2760 ) : 2761 2762 ModalDialog( pParent, SvtResId( DLG_SVT_QUERYDELETE ) ), 2763 2764 _aEntryLabel ( this, SvtResId( TXT_ENTRY ) ), 2765 _aEntry ( this, SvtResId( TXT_ENTRYNAME ) ), 2766 _aQueryMsg ( this, SvtResId( TXT_QUERYMSG ) ), 2767 _aYesButton ( this, SvtResId( BTN_YES ) ), 2768 _aAllButton ( this, SvtResId( BTN_ALL ) ), 2769 _aNoButton ( this, SvtResId( BTN_NO ) ), 2770 _aCancelButton( this, SvtResId( BTN_CANCEL ) ) 2771 2772 { 2773 FreeResource(); 2774 2775 // Handler 2776 Link aLink( STATIC_LINK( this, QueryDeleteDlg_Impl, ClickLink ) ); 2777 _aYesButton.SetClickHdl( aLink ); 2778 _aAllButton.SetClickHdl( aLink ); 2779 _aNoButton.SetClickHdl( aLink ); 2780 2781 // Anzeige der spezifizierten Texte 2782 2783 WinBits nTmpStyle = _aEntry.GetStyle(); 2784 nTmpStyle |= WB_PATHELLIPSIS; 2785 _aEntry.SetStyle( nTmpStyle ); 2786 _aEntry.SetText( rName ); 2787 } 2788 2789 // ----------------------------------------------------------------------- 2790 2791 IMPL_STATIC_LINK( QueryDeleteDlg_Impl, ClickLink, PushButton*, pBtn ) 2792 { 2793 if ( pBtn == &pThis->_aYesButton ) 2794 pThis->_eResult = QUERYDELETE_YES; 2795 else if ( pBtn == &pThis->_aNoButton ) 2796 pThis->_eResult = QUERYDELETE_NO; 2797 else if ( pBtn == &pThis->_aAllButton ) 2798 pThis->_eResult = QUERYDELETE_ALL; 2799 else if ( pBtn == &pThis->_aCancelButton ) 2800 pThis->_eResult = QUERYDELETE_CANCEL; 2801 2802 pThis->EndDialog( RET_OK ); 2803 2804 return 0; 2805 } 2806 2807 } 2808 2809