GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / contnr / fileview.cxx
blob8757ca0b9178ca32f645cf80a6a538b17dddef7a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "fileview.hxx"
21 #include "sal/config.h"
22 #include "svtools/treelistentry.hxx"
23 #include <svtools/fileview.hxx>
24 #include <svtools/svtresid.hxx>
25 #include <svtools/imagemgr.hxx>
26 #include <svtools/headbar.hxx>
27 #include <svtools/svtabbx.hxx>
28 #include <svtools/svtools.hrc>
29 #include "svtools/viewdataentry.hxx"
30 #include "fileview.hrc"
31 #include "contentenumeration.hxx"
32 #include <svtools/AccessibleBrowseBoxObjType.hxx>
33 #include <com/sun/star/util/DateTime.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/task/InteractionHandler.hpp>
36 #include <com/sun/star/ucb/XProgressHandler.hpp>
37 #include <com/sun/star/sdbc/XResultSet.hpp>
38 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
39 #include <com/sun/star/ucb/XContentAccess.hpp>
40 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
41 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
42 #include <com/sun/star/sdbc/XRow.hpp>
43 #include <com/sun/star/container/XChild.hpp>
44 #include <com/sun/star/ucb/CommandAbortedException.hpp>
45 #include <com/sun/star/ucb/ContentCreationException.hpp>
46 #include <vcl/waitobj.hxx>
47 #include <com/sun/star/io/XPersist.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <com/sun/star/ucb/XCommandInfo.hpp>
50 #include <com/sun/star/beans/XPropertySetInfo.hpp>
51 #include <com/sun/star/beans/PropertyAttribute.hpp>
53 #include <algorithm>
54 #include <memory>
55 #include <vector>
56 #include <tools/urlobj.hxx>
57 #include <comphelper/processfactory.hxx>
58 #include <comphelper/string.hxx>
59 #include <unotools/localfilehelper.hxx>
60 #include <ucbhelper/content.hxx>
61 #include <ucbhelper/commandenvironment.hxx>
62 #include <vcl/msgbox.hxx>
63 #include <rtl/math.hxx>
64 #include <tools/config.hxx>
65 #include <osl/mutex.hxx>
66 #include <osl/conditn.hxx>
67 #include <salhelper/timer.hxx>
68 #include <vcl/svapp.hxx>
69 #include <unotools/ucbhelper.hxx>
70 #include <unotools/intlwrapper.hxx>
71 #include <unotools/syslocale.hxx>
72 #include <svl/urlfilter.hxx>
73 #include <boost/ptr_container/ptr_set.hpp>
75 using namespace ::com::sun::star::lang;
76 using namespace ::com::sun::star::sdbc;
77 using namespace ::com::sun::star::task;
78 using namespace ::com::sun::star::ucb;
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star::io;
81 using namespace ::com::sun::star::beans;
82 using namespace ::comphelper;
83 using ::svt::SortingData_Impl;
84 using ::svt::FolderDescriptor;
86 #define ALL_FILES_FILTER "*.*"
88 #define COLUMN_TITLE 1
89 #define COLUMN_TYPE 2
90 #define COLUMN_SIZE 3
91 #define COLUMN_DATE 4
93 #define SEPARATOR_STR "----------------------------------"
95 #define ROW_HEIGHT 17 // the height of a row has to be a little higher than the bitmap
96 #define QUICK_SEARCH_TIMEOUT 1500 // time in mSec before the quicksearch string will be reseted
98 namespace
100 //====================================================================
101 //= ITimeoutHandler
102 //====================================================================
103 class CallbackTimer;
104 class ITimeoutHandler
106 public:
107 virtual void onTimeout( CallbackTimer* _pInstigator ) = 0;
109 protected:
110 ~ITimeoutHandler() {}
113 //====================================================================
114 //= CallbackTimer
115 //====================================================================
116 class CallbackTimer : public ::salhelper::Timer
118 protected:
119 ITimeoutHandler* m_pTimeoutHandler;
121 public:
122 CallbackTimer( ITimeoutHandler* _pHandler ) : m_pTimeoutHandler( _pHandler ) { }
124 protected:
125 virtual void SAL_CALL onShot();
128 //--------------------------------------------------------------------
129 void SAL_CALL CallbackTimer::onShot()
131 OSL_ENSURE( m_pTimeoutHandler, "CallbackTimer::onShot: nobody interested in?" );
132 ITimeoutHandler* pHandler( m_pTimeoutHandler );
133 if ( pHandler )
134 pHandler->onTimeout( this );
139 // -----------------------------------------------------------------------
141 void FilterMatch::createWildCardFilterList(const OUString& _rFilterList,::std::vector< WildCard >& _rFilters)
143 if( _rFilterList.getLength() )
145 // filter is given
146 sal_Int32 nIndex = 0;
147 OUString sToken;
150 sToken = _rFilterList.getToken( 0, ';', nIndex );
151 if ( !sToken.isEmpty() )
153 _rFilters.push_back( WildCard( sToken.toAsciiUpperCase() ) );
156 while ( nIndex >= 0 );
158 else
160 // no filter is given -> match all
161 _rFilters.push_back( WildCard(OUString("*")) );
164 // class ViewTabListBox_Impl ---------------------------------------------
166 class ViewTabListBox_Impl : public SvHeaderTabListBox
168 private:
169 Reference< XCommandEnvironment > mxCmdEnv;
171 ::osl::Mutex maMutex;
172 HeaderBar* mpHeaderBar;
173 SvtFileView_Impl* mpParent;
174 Timer maResetQuickSearch;
175 OUString maQuickSearchText;
176 OUString msAccessibleDescText;
177 OUString msFolder;
178 OUString msFile;
179 sal_uInt32 mnSearchIndex;
180 sal_Bool mbResizeDisabled : 1;
181 sal_Bool mbAutoResize : 1;
182 sal_Bool mbEnableDelete : 1;
183 sal_Bool mbEnableRename : 1;
184 bool mbShowHeader;
186 void DeleteEntries();
187 void DoQuickSearch( const sal_Unicode& rChar );
188 sal_Bool Kill( const OUString& rURL );
190 protected:
191 virtual sal_Bool DoubleClickHdl();
192 virtual OUString GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const;
194 public:
195 ViewTabListBox_Impl( Window* pParentWin, SvtFileView_Impl* pParent, sal_Int16 nFlags );
196 ~ViewTabListBox_Impl();
198 virtual void Resize();
199 virtual void KeyInput( const KeyEvent& rKEvt );
200 virtual sal_Bool EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText );
202 void ClearAll();
203 HeaderBar* GetHeaderBar() const { return mpHeaderBar; }
205 void EnableAutoResize() { mbAutoResize = sal_True; }
206 void EnableDelete( sal_Bool bEnable ) { mbEnableDelete = bEnable; }
207 void EnableRename( sal_Bool bEnable ) { mbEnableRename = bEnable; }
208 sal_Bool IsDeleteOrContextMenuEnabled() { return mbEnableDelete || IsContextMenuHandlingEnabled(); }
210 Reference< XCommandEnvironment > GetCommandEnvironment() const { return mxCmdEnv; }
212 DECL_LINK(ResetQuickSearch_Impl, void *);
214 virtual PopupMenu* CreateContextMenu( void );
215 virtual void ExcecuteContextMenuAction( sal_uInt16 nSelectedPopentry );
218 // class HashedEntry --------------------------------------------------
220 class HashedEntry
221 { // just a special String which can be compared on equality much faster
222 protected:
223 OUString maName;
224 sal_Int32 mnHashCode;
225 public:
226 inline HashedEntry( const OUString& rName );
227 inline HashedEntry( const INetURLObject& rURL );
228 inline HashedEntry( const HashedEntry& rCopy );
229 virtual ~HashedEntry();
231 inline bool operator ==( const HashedEntry& rRef ) const;
232 inline bool operator !=( const HashedEntry& rRef ) const;
233 inline bool operator <( const HashedEntry& rRef ) const;
235 inline const OUString& GetName() const;
238 inline HashedEntry::HashedEntry( const OUString& rName ): maName( rName ), mnHashCode( rName.hashCode() )
242 inline HashedEntry::HashedEntry( const INetURLObject& rURL ):
243 maName( rURL.GetMainURL( INetURLObject::NO_DECODE ) ),
244 mnHashCode( maName.hashCode() )
248 inline HashedEntry::HashedEntry( const HashedEntry& r ): maName( r.maName ), mnHashCode( r.mnHashCode )
252 HashedEntry::~HashedEntry()
256 inline bool HashedEntry::operator ==( const HashedEntry& rRef ) const
258 return mnHashCode == rRef.mnHashCode && maName.reverseCompareTo( rRef.maName ) == 0;
261 inline bool HashedEntry::operator !=( const HashedEntry& rRef ) const
263 return mnHashCode != rRef.mnHashCode || maName.reverseCompareTo( rRef.maName ) != 0;
266 inline bool HashedEntry::operator <( const HashedEntry& rRef ) const
268 if( mnHashCode == rRef.mnHashCode )
269 return maName.reverseCompareTo( rRef.maName ) < 0;
270 else
271 return mnHashCode < rRef.mnHashCode;
274 inline const OUString& HashedEntry::GetName() const
276 return maName;
279 // class HashedEntryList ----------------------------------------------
280 // provides a list of _unique_ Entries
281 class HashedEntryList : public boost::ptr_set<HashedEntry> {};
283 // class NameTranslationEntry -----------------------------------------
285 class NameTranslationEntry : public HashedEntry
286 {// a fast compareble String and another String, which is used to get a substitution for a given String
287 protected:
288 OUString maTranslatedName;
289 public:
290 inline NameTranslationEntry( const OUString& rOriginalName, const OUString& rTranslatedName );
291 inline NameTranslationEntry( const OString& rOriginalName, const OString& rTranslatedName );
293 inline const OUString& GetTranslation() const;
296 inline NameTranslationEntry::NameTranslationEntry( const OUString& rOrg, const OUString& rTrans ):
297 HashedEntry( rOrg ),
298 maTranslatedName( rTrans )
302 inline NameTranslationEntry::NameTranslationEntry( const OString& rOrg, const OString& rTrans )
303 : HashedEntry(OStringToOUString(rOrg, RTL_TEXTENCODING_ASCII_US))
304 , maTranslatedName(OStringToOUString(rTrans, RTL_TEXTENCODING_UTF8))
308 inline const OUString& NameTranslationEntry::GetTranslation() const
310 return maTranslatedName;
313 // class NameTranslationList -----------------------------------------
315 class NameTranslationList : protected HashedEntryList
316 { // contains a list of substitutes of strings for a given folder (as URL)
317 // explanation of the circumstances see in remarks for Init();
318 protected:
319 INetURLObject maTransFile; // URL of file with translation entries
320 HashedEntry maHashedURL; // for future purposes when dealing with a set of cached
321 // NameTranslationLists
322 private:
323 const OUString maTransFileName;
324 void Init(); // reads the translation file and fills the (internal) list
326 public:
327 NameTranslationList( const INetURLObject& rBaseURL );
328 // rBaseURL: path to folder for which the translation of the entries
329 // should be done
331 using HashedEntryList::operator==;
332 using HashedEntryList::operator!=;
333 inline bool operator ==( const HashedEntry& rRef ) const;
334 inline bool operator !=( const HashedEntry& rRef ) const;
336 const OUString* Translate( const OUString& rName ) const;
337 // returns NULL, if rName can't be found
339 inline void Update(); // clears list and init
341 inline const OUString& GetTransTableFileName() const;
342 // returns the name for the file, which contains the translation strings
345 inline const OUString& NameTranslationList::GetTransTableFileName() const
347 return maTransFileName;
350 void NameTranslationList::Init()
352 // Tries to read the file ".nametranslation.table" in the base folder. Complete path/name is in maTransFile.
353 // Further on, the found entries in the section "TRANSLATIONNAMES" are used to replace names in the
354 // base folder by translated ones. The translation must be given in UTF8
355 // See examples of such a files in the samples-folder of an Office installation
359 ::ucbhelper::Content aTestContent( maTransFile.GetMainURL( INetURLObject::NO_DECODE ), Reference< XCommandEnvironment >(), comphelper::getProcessComponentContext() );
361 if( aTestContent.isDocument() )
363 // ... also tests the existence of maTransFile by throwing an Exception
364 OUString aFsysName( maTransFile.getFSysPath( INetURLObject::FSYS_DETECT ) );
365 Config aConfig( aFsysName );
367 aConfig.SetGroup( OString("TRANSLATIONNAMES") );
369 sal_uInt16 nKeyCnt = aConfig.GetKeyCount();
371 for( sal_uInt16 nCnt = 0 ; nCnt < nKeyCnt ; ++nCnt )
372 insert( new NameTranslationEntry( aConfig.GetKeyName( nCnt ), aConfig.ReadKey( nCnt ) ) );
375 catch( Exception const & ) {}
378 NameTranslationList::NameTranslationList( const INetURLObject& rBaseURL ):
379 maTransFile( rBaseURL ),
380 maHashedURL( rBaseURL ),
381 maTransFileName( OUString(".nametranslation.table") )
383 maTransFile.insertName( maTransFileName );
384 Init();
387 inline bool NameTranslationList::operator ==( const HashedEntry& rRef ) const
389 return maHashedURL == rRef;
392 inline bool NameTranslationList::operator !=( const HashedEntry& rRef ) const
394 return maHashedURL != rRef;
397 const OUString* NameTranslationList::Translate( const OUString& rName ) const
399 HashedEntry aRef( rName );
400 const NameTranslationEntry* pSearch = NULL;
401 for( const_iterator it = begin(); it != end(); ++it )
402 if( (*it) == aRef )
404 pSearch = static_cast<const NameTranslationEntry*>(&*it);
407 return pSearch ? &pSearch->GetTranslation() : NULL;
410 inline void NameTranslationList::Update()
412 clear();
413 Init();
416 // class NameTranslator_Impl ------------------------------------------
418 // enables the user to get string substitutions (translations for the content) for a given folder
419 // see more explanations above in the description for NameTranslationList
420 class NameTranslator_Impl : public ::svt::IContentTitleTranslation
422 private:
423 NameTranslationList* mpActFolder;
424 public:
425 NameTranslator_Impl( const INetURLObject& rActualFolder );
426 virtual ~NameTranslator_Impl();
428 // IContentTitleTranslation
429 virtual sal_Bool GetTranslation( const OUString& rOriginalName, OUString& rTranslatedName ) const;
431 void SetActualFolder( const INetURLObject& rActualFolder );
432 const OUString* GetTransTableFileName() const;
433 // returns the name for the file, which contains the translation strings
436 //====================================================================
437 //= SvtFileView_Impl
438 //====================================================================
440 class SvtFileView_Impl :public ::svt::IEnumerationResultHandler
441 ,public ITimeoutHandler
443 protected:
444 SvtFileView* mpAntiImpl;
445 Link m_aSelectHandler;
447 ::rtl::Reference< ::svt::FileViewContentEnumerator >
448 m_pContentEnumerator;
449 Link m_aCurrentAsyncActionHandler;
450 ::osl::Condition m_aAsyncActionFinished;
451 ::rtl::Reference< ::salhelper::Timer > m_pCancelAsyncTimer;
452 ::svt::EnumerationResult m_eAsyncActionResult;
453 bool m_bRunningAsyncAction;
454 bool m_bAsyncActionCancelled;
457 public:
459 ::std::vector< SortingData_Impl* > maContent;
460 ::osl::Mutex maMutex;
462 ViewTabListBox_Impl* mpView;
463 NameTranslator_Impl* mpNameTrans;
464 sal_uInt16 mnSortColumn;
465 sal_Bool mbAscending : 1;
466 sal_Bool mbOnlyFolder : 1;
467 sal_Bool mbReplaceNames : 1; // translate folder names or display doc-title instead of file name
468 sal_Int16 mnSuspendSelectCallback : 1;
469 sal_Bool mbIsFirstResort : 1;
471 IntlWrapper aIntlWrapper;
473 OUString maViewURL;
474 OUString maAllFilter;
475 OUString maCurrentFilter;
476 Image maFolderImage;
477 Link maOpenDoneLink;
478 Reference< XCommandEnvironment > mxCmdEnv;
480 SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > xEnv,
481 sal_Int16 nFlags,
482 sal_Bool bOnlyFolder );
483 virtual ~SvtFileView_Impl();
485 void Clear();
487 FileViewResult GetFolderContent_Impl(
488 const OUString& rFolder,
489 const FileViewAsyncAction* pAsyncDescriptor,
490 const ::com::sun::star::uno::Sequence< OUString >& rBlackList = ::com::sun::star::uno::Sequence< OUString >() );
492 FileViewResult GetFolderContent_Impl(
493 const FolderDescriptor& _rFolder,
494 const FileViewAsyncAction* pAsyncDescriptor,
495 const ::com::sun::star::uno::Sequence< OUString >& rBlackList = ::com::sun::star::uno::Sequence< OUString >());
496 void FilterFolderContent_Impl( const OUString &rFilter );
497 void CancelRunningAsyncAction();
499 void OpenFolder_Impl();
500 // #83004# -------
501 void ReplaceTabWithString( OUString& aValue );
502 void CreateDisplayText_Impl();
503 void CreateVector_Impl( const Sequence < OUString > &rList );
504 void SortFolderContent_Impl();
506 void EntryRemoved( const OUString& rURL );
507 void EntryRenamed( OUString& rURL,
508 const OUString& rName );
509 OUString FolderInserted( const OUString& rURL,
510 const OUString& rTitle );
512 sal_uLong GetEntryPos( const OUString& rURL );
514 inline void EnableContextMenu( sal_Bool bEnable );
515 inline void EnableDelete( sal_Bool bEnable );
517 void Resort_Impl( sal_Int16 nColumn, sal_Bool bAscending );
518 sal_Bool SearchNextEntry( sal_uInt32 &nIndex,
519 const OUString& rTitle,
520 sal_Bool bWrapAround );
522 inline sal_Bool EnableNameReplacing( sal_Bool bEnable = sal_True ); // returns false, if action wasn't possible
523 void SetActualFolder( const INetURLObject& rActualFolder );
525 sal_Bool GetDocTitle( const OUString& rTargetURL, OUString& rDocTitle ) const;
527 void SetSelectHandler( const Link& _rHdl );
529 void InitSelection();
530 void ResetCursor();
532 inline void EndEditing( bool _bCancel );
534 protected:
535 DECL_LINK( SelectionMultiplexer, void* );
537 protected:
538 // IEnumerationResultHandler overridables
539 virtual void enumerationDone( ::svt::EnumerationResult _eResult );
540 void implEnumerationSuccess();
542 // ITimeoutHandler
543 virtual void onTimeout( CallbackTimer* _pInstigator );
546 inline void SvtFileView_Impl::EnableContextMenu( sal_Bool bEnable )
548 mpView->EnableContextMenuHandling( bEnable );
549 if( bEnable )
550 mbReplaceNames = sal_False;
553 inline void SvtFileView_Impl::EnableDelete( sal_Bool bEnable )
555 mpView->EnableDelete( bEnable );
556 if( bEnable )
557 mbReplaceNames = sal_False;
560 inline sal_Bool SvtFileView_Impl::EnableNameReplacing( sal_Bool bEnable )
562 mpView->EnableRename( bEnable );
564 sal_Bool bRet;
565 if( mpView->IsDeleteOrContextMenuEnabled() )
567 DBG_ASSERT( !mbReplaceNames, "SvtFileView_Impl::EnableNameReplacing(): state should be not possible!" );
568 bRet = !bEnable; // only for enabling this is an unsuccessful result
570 else
572 mbReplaceNames = bEnable;
573 bRet = sal_True;
576 return bRet;
579 inline void SvtFileView_Impl::EndEditing( bool _bCancel )
581 if ( mpView->IsEditingActive() )
582 mpView->EndEditing( _bCancel != false );
585 // functions -------------------------------------------------------------
587 OUString CreateExactSizeText( sal_Int64 nSize )
589 double fSize( ( double ) nSize );
590 int nDec;
592 long nMega = 1024 * 1024;
593 long nGiga = nMega * 1024;
595 OUString aUnitStr(' ');
597 if ( nSize < 10000 )
599 aUnitStr += SVT_RESSTR(STR_SVT_BYTES );
600 nDec = 0;
602 else if ( nSize < nMega )
604 fSize /= 1024;
605 aUnitStr += SVT_RESSTR(STR_SVT_KB);
606 nDec = 1;
608 else if ( nSize < nGiga )
610 fSize /= nMega;
611 aUnitStr += SVT_RESSTR(STR_SVT_MB);
612 nDec = 2;
614 else
616 fSize /= nGiga;
617 aUnitStr += SVT_RESSTR(STR_SVT_GB);
618 nDec = 3;
621 OUString aSizeStr( ::rtl::math::doubleToUString( fSize,
622 rtl_math_StringFormat_F, nDec,
623 SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]) );
624 aSizeStr += aUnitStr;
626 return aSizeStr;
629 // -----------------------------------------------------------------------
630 // class ViewTabListBox_Impl ---------------------------------------------
631 // -----------------------------------------------------------------------
633 ViewTabListBox_Impl::ViewTabListBox_Impl( Window* pParentWin,
634 SvtFileView_Impl* pParent,
635 sal_Int16 nFlags ) :
637 SvHeaderTabListBox( pParentWin, WB_TABSTOP ),
639 mpHeaderBar ( NULL ),
640 mpParent ( pParent ),
641 msAccessibleDescText( SVT_RESSTR(STR_SVT_ACC_DESC_FILEVIEW) ),
642 msFolder ( SVT_RESSTR(STR_SVT_ACC_DESC_FOLDER) ),
643 msFile ( SVT_RESSTR(STR_SVT_ACC_DESC_FILE) ),
644 mnSearchIndex ( 0 ),
645 mbResizeDisabled ( sal_False ),
646 mbAutoResize ( sal_False ),
647 mbEnableDelete ( sal_True ),
648 mbEnableRename ( sal_True ),
649 mbShowHeader ( (nFlags & FILEVIEW_SHOW_NONE) == 0 )
651 Size aBoxSize = pParentWin->GetSizePixel();
652 mpHeaderBar = new HeaderBar( pParentWin, WB_BUTTONSTYLE | WB_BOTTOMBORDER );
653 mpHeaderBar->SetPosSizePixel( Point( 0, 0 ), mpHeaderBar->CalcWindowSizePixel() );
655 HeaderBarItemBits nBits = ( HIB_LEFT | HIB_VCENTER | HIB_CLICKABLE );
656 if (nFlags & FILEVIEW_SHOW_ONLYTITLE)
658 long pTabs[] = { 2, 20, 600 };
659 SetTabs(&pTabs[0], MAP_PIXEL);
661 mpHeaderBar->InsertItem(COLUMN_TITLE, SVT_RESSTR(STR_SVT_FILEVIEW_COLUMN_TITLE), 600, nBits | HIB_UPARROW);
663 else
665 long pTabs[] = { 5, 20, 180, 320, 400, 600 };
666 SetTabs(&pTabs[0], MAP_PIXEL);
667 SetTabJustify(2, AdjustRight); // column "Size"
669 mpHeaderBar->InsertItem(COLUMN_TITLE, SVT_RESSTR(STR_SVT_FILEVIEW_COLUMN_TITLE), 180, nBits | HIB_UPARROW);
670 mpHeaderBar->InsertItem(COLUMN_TYPE, SVT_RESSTR(STR_SVT_FILEVIEW_COLUMN_TYPE), 140, nBits);
671 mpHeaderBar->InsertItem(COLUMN_SIZE, SVT_RESSTR(STR_SVT_FILEVIEW_COLUMN_SIZE), 80, nBits);
672 mpHeaderBar->InsertItem(COLUMN_DATE, SVT_RESSTR(STR_SVT_FILEVIEW_COLUMN_DATE), 500, nBits);
675 Size aHeadSize = mpHeaderBar->GetSizePixel();
676 SetPosSizePixel( Point( 0, aHeadSize.Height() ),
677 Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) );
678 InitHeaderBar( mpHeaderBar );
679 SetHighlightRange();
680 SetEntryHeight( ROW_HEIGHT );
681 if (nFlags & FILEVIEW_MULTISELECTION)
682 SetSelectionMode( MULTIPLE_SELECTION );
684 Show();
685 if( mbShowHeader )
686 mpHeaderBar->Show();
688 maResetQuickSearch.SetTimeout( QUICK_SEARCH_TIMEOUT );
689 maResetQuickSearch.SetTimeoutHdl( LINK( this, ViewTabListBox_Impl, ResetQuickSearch_Impl ) );
691 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
692 Reference< XInteractionHandler > xInteractionHandler(
693 InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
695 mxCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
697 EnableContextMenuHandling();
700 // -----------------------------------------------------------------------
702 ViewTabListBox_Impl::~ViewTabListBox_Impl()
704 maResetQuickSearch.Stop();
706 delete mpHeaderBar;
709 // -----------------------------------------------------------------------
711 IMPL_LINK_NOARG(ViewTabListBox_Impl, ResetQuickSearch_Impl)
713 ::osl::MutexGuard aGuard( maMutex );
715 maQuickSearchText = "";
716 mnSearchIndex = 0;
718 return 0;
721 // -----------------------------------------------------------------------
723 void ViewTabListBox_Impl::Resize()
725 SvTabListBox::Resize();
726 Size aBoxSize = Control::GetParent()->GetOutputSizePixel();
728 if ( mbResizeDisabled || !aBoxSize.Width() )
729 return;
731 Size aBarSize;
732 if ( mbShowHeader )
734 aBarSize = mpHeaderBar->GetSizePixel();
735 aBarSize.Width() = mbAutoResize ? aBoxSize.Width() : GetSizePixel().Width();
736 mpHeaderBar->SetSizePixel( aBarSize );
739 if ( mbAutoResize )
741 mbResizeDisabled = sal_True;
742 SetPosSizePixel( Point( 0, aBarSize.Height() ),
743 Size( aBoxSize.Width(), aBoxSize.Height() - aBarSize.Height() ) );
744 mbResizeDisabled = sal_False;
748 // -----------------------------------------------------------------------
750 void ViewTabListBox_Impl::KeyInput( const KeyEvent& rKEvt )
752 bool bHandled = false;
754 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
755 if ( 0 == rKeyCode.GetModifier() )
757 if ( rKeyCode.GetCode() == KEY_RETURN )
759 ResetQuickSearch_Impl( NULL );
760 GetDoubleClickHdl().Call( this );
761 bHandled = true;
763 else if ( ( rKeyCode.GetCode() == KEY_DELETE ) &&
764 mbEnableDelete )
766 ResetQuickSearch_Impl( NULL );
767 DeleteEntries();
768 bHandled = true;
770 else if ( ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_NUM ) ||
771 ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_ALPHA ) )
773 DoQuickSearch( rKEvt.GetCharCode() );
774 bHandled = true;
778 if ( !bHandled )
780 ResetQuickSearch_Impl( NULL );
781 SvHeaderTabListBox::KeyInput( rKEvt );
785 // -----------------------------------------------------------------------
787 PopupMenu* ViewTabListBox_Impl::CreateContextMenu( void )
789 bool bEnableDelete = mbEnableDelete;
790 bool bEnableRename = mbEnableRename;
792 if ( bEnableDelete || bEnableRename )
794 sal_Int32 nSelectedEntries = GetSelectionCount();
795 bEnableDelete &= nSelectedEntries > 0;
796 bEnableRename &= nSelectedEntries == 1;
799 if ( bEnableDelete || bEnableRename )
801 SvTreeListEntry* pEntry = FirstSelected();
802 while ( pEntry )
804 ::ucbhelper::Content aCnt;
807 OUString aURL( static_cast< SvtContentEntry * >(
808 pEntry->GetUserData() )->maURL );
809 aCnt = ::ucbhelper::Content( aURL, mxCmdEnv, comphelper::getProcessComponentContext() );
811 catch( Exception const & )
813 bEnableDelete = bEnableRename = false;
816 if ( bEnableDelete )
820 Reference< XCommandInfo > aCommands = aCnt.getCommands();
821 if ( aCommands.is() )
822 bEnableDelete
823 = aCommands->hasCommandByName(
824 OUString( "delete" ) );
825 else
826 bEnableDelete = false;
828 catch( Exception const & )
830 bEnableDelete = false;
834 if ( bEnableRename )
838 Reference< XPropertySetInfo > aProps = aCnt.getProperties();
839 if ( aProps.is() )
841 Property aProp
842 = aProps->getPropertyByName(
843 OUString( "Title" ) );
844 bEnableRename
845 = !( aProp.Attributes & PropertyAttribute::READONLY );
847 else
848 bEnableRename = false;
850 catch( Exception const & )
852 bEnableRename = false;
856 pEntry = ( bEnableDelete || bEnableRename )
857 ? NextSelected( pEntry )
858 : 0;
862 if ( bEnableDelete || bEnableRename )
864 PopupMenu * pRet
865 = new PopupMenu( SvtResId( RID_FILEVIEW_CONTEXTMENU ) );
866 pRet->EnableItem( MID_FILEVIEW_DELETE, bEnableDelete );
867 pRet->EnableItem( MID_FILEVIEW_RENAME, bEnableRename );
868 pRet->RemoveDisabledEntries( sal_True, sal_True );
869 return pRet;
872 return NULL;
875 // -----------------------------------------------------------------------
877 void ViewTabListBox_Impl::ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry )
879 switch ( nSelectedPopupEntry )
881 case MID_FILEVIEW_DELETE :
882 DeleteEntries();
883 break;
885 case MID_FILEVIEW_RENAME :
886 EditEntry( FirstSelected() );
887 break;
891 // -----------------------------------------------------------------------
893 void ViewTabListBox_Impl::ClearAll()
895 for ( sal_uInt16 i = 0; i < GetEntryCount(); ++i )
896 delete (SvtContentEntry*)GetEntry(i)->GetUserData();
897 Clear();
900 // -----------------------------------------------------------------------
901 void ViewTabListBox_Impl::DeleteEntries()
903 svtools::QueryDeleteResult_Impl eResult = svtools::QUERYDELETE_YES;
904 SvTreeListEntry* pEntry = FirstSelected();
905 OUString aURL;
907 OString sDialogPosition;
908 while ( pEntry && ( eResult != svtools::QUERYDELETE_CANCEL ) )
910 SvTreeListEntry *pCurEntry = pEntry;
911 pEntry = NextSelected( pEntry );
913 if ( pCurEntry->GetUserData() )
914 aURL = ( (SvtContentEntry*)pCurEntry->GetUserData() )->maURL;
916 if ( aURL.isEmpty() )
917 continue;
919 bool canDelete = true;
922 ::ucbhelper::Content aCnt( aURL, mxCmdEnv, comphelper::getProcessComponentContext() );
923 Reference< XCommandInfo > aCommands = aCnt.getCommands();
924 if ( aCommands.is() )
925 canDelete
926 = aCommands->hasCommandByName(
927 OUString( "delete" ) );
928 else
929 canDelete = false;
931 catch( Exception const & )
933 canDelete = false;
936 if (!canDelete)
937 continue; // process next entry
939 if ( eResult != svtools::QUERYDELETE_ALL )
941 INetURLObject aObj( aURL );
942 svtools::QueryDeleteDlg_Impl aDlg( NULL, aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) );
943 if ( sDialogPosition.getLength() )
944 aDlg.SetWindowState( sDialogPosition );
946 if ( GetSelectionCount() > 1 )
947 aDlg.EnableAllButton();
949 if ( aDlg.Execute() == RET_OK )
950 eResult = aDlg.GetResult();
951 else
952 eResult = svtools::QUERYDELETE_CANCEL;
954 sDialogPosition = aDlg.GetWindowState( );
957 if ( ( eResult == svtools::QUERYDELETE_ALL ) ||
958 ( eResult == svtools::QUERYDELETE_YES ) )
960 if ( Kill( aURL ) )
962 delete (SvtContentEntry*)pCurEntry->GetUserData();
963 GetModel()->Remove( pCurEntry );
964 mpParent->EntryRemoved( aURL );
970 // -----------------------------------------------------------------------
971 sal_Bool ViewTabListBox_Impl::EditedEntry( SvTreeListEntry* pEntry,
972 const OUString& rNewText )
974 sal_Bool bRet = sal_False;
976 OUString aURL;
977 SvtContentEntry* pData = (SvtContentEntry*)pEntry->GetUserData();
979 if ( pData )
980 aURL = pData->maURL;
982 if ( aURL.isEmpty() )
983 return bRet;
987 OUString aPropName( "Title" );
988 bool canRename = true;
989 ::ucbhelper::Content aContent( aURL, mxCmdEnv, comphelper::getProcessComponentContext() );
993 Reference< XPropertySetInfo > aProps = aContent.getProperties();
994 if ( aProps.is() )
996 Property aProp = aProps->getPropertyByName( aPropName );
997 canRename = !( aProp.Attributes & PropertyAttribute::READONLY );
999 else
1001 canRename = false;
1004 catch ( Exception const & )
1006 canRename = false;
1009 if ( canRename )
1011 Any aValue;
1012 aValue <<= rNewText;
1013 aContent.setPropertyValue( aPropName, aValue );
1014 mpParent->EntryRenamed( aURL, rNewText );
1016 pData->maURL = aURL;
1017 pEntry->SetUserData( pData );
1019 bRet = sal_True;
1022 catch( Exception const & )
1026 return bRet;
1029 // -----------------------------------------------------------------------
1030 void ViewTabListBox_Impl::DoQuickSearch( const sal_Unicode& rChar )
1032 ::osl::MutexGuard aGuard( maMutex );
1034 maResetQuickSearch.Stop();
1036 OUString aLastText = maQuickSearchText;
1037 sal_uInt32 aLastPos = mnSearchIndex;
1039 maQuickSearchText += OUString(rChar).toAsciiLowerCase();
1041 sal_Bool bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, sal_False );
1043 if ( !bFound && ( aLastText.getLength() == 1 ) &&
1044 ( aLastText == OUString(rChar) ) )
1046 mnSearchIndex = aLastPos + 1;
1047 maQuickSearchText = aLastText;
1048 bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, sal_True );
1051 if ( bFound )
1053 SvTreeListEntry* pEntry = GetEntry( mnSearchIndex );
1054 if ( pEntry )
1056 SelectAll( sal_False );
1057 Select( pEntry );
1058 SetCurEntry( pEntry );
1059 MakeVisible( pEntry );
1063 maResetQuickSearch.Start();
1066 // -----------------------------------------------------------------------
1067 sal_Bool ViewTabListBox_Impl::DoubleClickHdl()
1069 SvHeaderTabListBox::DoubleClickHdl();
1070 return sal_False;
1071 // this means "do no additional handling". Especially this means that the SvImpLBox does not
1072 // recognize that the entry at the double click position change after the handler call (which is
1073 // the case if in the handler, our content was replaced)
1074 // If it _would_ recognize this change, it would take this as a reason to select the entry, again
1075 // - which is not what in the case of content replace
1076 // (I really doubt that this behaviour of the SvImpLBox does make any sense at all, but
1077 // who knows ...)
1080 OUString ViewTabListBox_Impl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
1082 OUString sRet = SvHeaderTabListBox::GetAccessibleObjectDescription( _eType, _nPos );
1083 if ( ::svt::BBTYPE_TABLECELL == _eType )
1085 sal_Int32 nRow = -1;
1086 const sal_uInt16 nColumnCount = GetColumnCount();
1087 if (nColumnCount > 0)
1088 nRow = _nPos / nColumnCount;
1089 SvTreeListEntry* pEntry = GetEntry( nRow );
1090 if ( pEntry )
1092 SvtContentEntry* pData = (SvtContentEntry*)pEntry->GetUserData();
1093 if ( pData )
1095 const OUString sVar1( "%1" );
1096 const OUString sVar2( "%2" );
1097 OUString aText( msAccessibleDescText );
1098 aText = aText.replaceAll( sVar1, pData->mbIsFolder ? msFolder : msFile );
1099 aText = aText.replaceAll( sVar2, pData->maURL );
1100 sRet += aText;
1105 return sRet;
1108 // -----------------------------------------------------------------------
1109 sal_Bool ViewTabListBox_Impl::Kill( const OUString& rContent )
1111 sal_Bool bRet = sal_True;
1115 ::ucbhelper::Content aCnt( rContent, mxCmdEnv, comphelper::getProcessComponentContext() );
1116 aCnt.executeCommand( OUString( "delete" ), makeAny( sal_Bool( sal_True ) ) );
1118 catch( ::com::sun::star::ucb::CommandAbortedException const & )
1120 DBG_WARNING( "CommandAbortedException" );
1121 bRet = sal_False;
1123 catch( Exception const & )
1125 DBG_WARNING( "Any other exception" );
1126 bRet = sal_False;
1129 return bRet;
1135 // -----------------------------------------------------------------------
1136 // class SvtFileView -----------------------------------------------------
1137 // -----------------------------------------------------------------------
1139 SvtFileView::SvtFileView( Window* pParent, const ResId& rResId,
1140 sal_Bool bOnlyFolder, sal_Bool bMultiSelection ) :
1142 Control( pParent, rResId )
1144 sal_Int8 nFlags = 0;
1145 if ( bOnlyFolder )
1146 nFlags |= FILEVIEW_ONLYFOLDER;
1147 if ( bMultiSelection )
1148 nFlags |= FILEVIEW_MULTISELECTION;
1150 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1151 Reference< XInteractionHandler > xInteractionHandler(
1152 InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
1153 Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
1155 mpImp = new SvtFileView_Impl( this, xCmdEnv, nFlags, bOnlyFolder );
1156 mpImp->mpView->ForbidEmptyText();
1157 SetSortColumn( true );
1159 HeaderBar* pHeaderBar = mpImp->mpView->GetHeaderBar();
1160 pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) );
1161 pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) );
1164 SvtFileView::SvtFileView( Window* pParent, const ResId& rResId, sal_uInt8 nFlags ) :
1166 Control( pParent, rResId )
1168 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1169 Reference< XInteractionHandler > xInteractionHandler(
1170 InteractionHandler::createWithParent(xContext, 0), UNO_QUERY_THROW );
1171 Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
1173 mpImp = new SvtFileView_Impl( this, xCmdEnv, nFlags, nFlags & FILEVIEW_ONLYFOLDER );
1175 SetSortColumn( (nFlags & FILEVIEW_SHOW_NONE) == 0 );
1177 HeaderBar *pHeaderBar = mpImp->mpView->GetHeaderBar();
1178 pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) );
1179 pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) );
1182 // -----------------------------------------------------------------------
1184 SvtFileView::~SvtFileView()
1186 // use temp pointer to prevent access of deleted member (GetFocus())
1187 SvtFileView_Impl* pTemp = mpImp;
1188 mpImp = NULL;
1189 delete pTemp;
1192 // -----------------------------------------------------------------------
1194 OUString SvtFileView::GetURL( SvTreeListEntry* pEntry ) const
1196 OUString aURL;
1197 if ( pEntry && pEntry->GetUserData() )
1198 aURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL;
1199 return aURL;
1202 // -----------------------------------------------------------------------
1204 OUString SvtFileView::GetCurrentURL() const
1206 OUString aURL;
1207 SvTreeListEntry* pEntry = mpImp->mpView->FirstSelected();
1208 if ( pEntry && pEntry->GetUserData() )
1209 aURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL;
1210 return aURL;
1212 // -----------------------------------------------------------------------------
1214 void SvtFileView::CreatedFolder( const OUString& rUrl, const OUString& rNewFolder )
1216 OUString sEntry = mpImp->FolderInserted( rUrl, rNewFolder );
1217 SvTreeListEntry* pEntry = mpImp->mpView->InsertEntry( sEntry, mpImp->maFolderImage, mpImp->maFolderImage );
1218 SvtContentEntry* pUserData = new SvtContentEntry( rUrl, sal_True );
1219 pEntry->SetUserData( pUserData );
1220 mpImp->mpView->MakeVisible( pEntry );
1223 // -----------------------------------------------------------------------
1225 FileViewResult SvtFileView::PreviousLevel( const FileViewAsyncAction* pAsyncDescriptor )
1227 FileViewResult eResult = eFailure;
1229 OUString sParentURL;
1230 if ( GetParentURL( sParentURL ) )
1231 eResult = Initialize( sParentURL, mpImp->maCurrentFilter, pAsyncDescriptor, mpBlackList );
1233 return eResult;
1236 // -----------------------------------------------------------------------
1238 sal_Bool SvtFileView::GetParentURL( OUString& rParentURL ) const
1240 sal_Bool bRet = sal_False;
1243 ::ucbhelper::Content aCnt( mpImp->maViewURL, mpImp->mxCmdEnv, comphelper::getProcessComponentContext() );
1244 Reference< XContent > xContent( aCnt.get() );
1245 Reference< com::sun::star::container::XChild > xChild( xContent, UNO_QUERY );
1246 if ( xChild.is() )
1248 Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
1249 if ( xParent.is() )
1251 rParentURL = xParent->getIdentifier()->getContentIdentifier();
1252 bRet = !rParentURL.isEmpty() && rParentURL != mpImp->maViewURL;
1256 catch( Exception const & )
1258 // perhaps an unknown url protocol (e.g. "private:newdoc")
1261 return bRet;
1264 // -----------------------------------------------------------------------
1266 const OString& SvtFileView::GetHelpId( ) const
1268 return mpImp->mpView->GetHelpId( );
1271 // -----------------------------------------------------------------------
1273 void SvtFileView::SetHelpId( const OString& rHelpId )
1275 mpImp->mpView->SetHelpId( rHelpId );
1278 // -----------------------------------------------------------------------
1280 void SvtFileView::SetSizePixel( const Size& rNewSize )
1282 Control::SetSizePixel( rNewSize );
1283 mpImp->mpView->SetSizePixel( rNewSize );
1286 // -----------------------------------------------------------------------
1288 void SvtFileView::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1290 SetPosPixel( rNewPos );
1291 SetSizePixel( rNewSize );
1294 // -----------------------------------------------------------------------------
1295 sal_Bool SvtFileView::Initialize( const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent>& _xContent, const OUString& rFilter )
1297 WaitObject aWaitCursor( this );
1299 mpImp->Clear();
1300 ::ucbhelper::Content aContent(_xContent, mpImp->mxCmdEnv, comphelper::getProcessComponentContext() );
1301 FileViewResult eResult = mpImp->GetFolderContent_Impl( FolderDescriptor( aContent ), NULL );
1302 OSL_ENSURE( eResult != eStillRunning, "SvtFileView::Initialize: this was expected to be synchronous!" );
1303 if ( eResult != eSuccess )
1304 return sal_False;
1306 mpImp->FilterFolderContent_Impl( rFilter );
1308 mpImp->SortFolderContent_Impl(); // possibly not necessary!!!!!!!!!!
1309 mpImp->CreateDisplayText_Impl();
1310 mpImp->OpenFolder_Impl();
1312 mpImp->maOpenDoneLink.Call( this );
1313 return sal_True;
1316 // -----------------------------------------------------------------------
1317 FileViewResult SvtFileView::Initialize(
1318 const OUString& rURL,
1319 const OUString& rFilter,
1320 const FileViewAsyncAction* pAsyncDescriptor,
1321 const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
1323 WaitObject aWaitCursor( this );
1324 mpBlackList = rBlackList;
1326 OUString sPushURL( mpImp->maViewURL );
1328 mpImp->maViewURL = rURL;
1329 FileViewResult eResult = ExecuteFilter( rFilter, pAsyncDescriptor );
1330 switch ( eResult )
1332 case eFailure:
1333 case eTimeout:
1334 mpImp->maViewURL = sPushURL;
1335 return eResult;
1337 case eStillRunning:
1338 OSL_ENSURE( pAsyncDescriptor, "SvtFileView::Initialize: we told it to read synchronously!" );
1339 case eSuccess:
1340 return eResult;
1343 OSL_FAIL( "SvtFileView::Initialize: unreachable!" );
1344 return eFailure;
1347 // -----------------------------------------------------------------------
1348 FileViewResult SvtFileView::Initialize(
1349 const OUString& rURL,
1350 const OUString& rFilter,
1351 const FileViewAsyncAction* pAsyncDescriptor )
1353 return Initialize( rURL, rFilter, pAsyncDescriptor, ::com::sun::star::uno::Sequence< OUString >());
1356 // -----------------------------------------------------------------------
1358 // -----------------------------------------------------------------------
1359 sal_Bool SvtFileView::Initialize( const Sequence< OUString >& aContents )
1361 WaitObject aWaitCursor( this );
1363 mpImp->maViewURL = "";
1364 mpImp->maCurrentFilter = mpImp->maAllFilter;
1366 mpImp->Clear();
1367 mpImp->CreateVector_Impl( aContents );
1368 if( GetSortColumn() )
1369 mpImp->SortFolderContent_Impl();
1371 mpImp->OpenFolder_Impl();
1373 mpImp->maOpenDoneLink.Call( this );
1375 return sal_True;
1378 // -----------------------------------------------------------------------
1380 FileViewResult SvtFileView::ExecuteFilter( const OUString& rFilter, const FileViewAsyncAction* pAsyncDescriptor )
1382 mpImp->maCurrentFilter = rFilter.toAsciiLowerCase();
1384 mpImp->Clear();
1385 FileViewResult eResult = mpImp->GetFolderContent_Impl( mpImp->maViewURL, pAsyncDescriptor, mpBlackList );
1386 OSL_ENSURE( ( eResult != eStillRunning ) || pAsyncDescriptor, "SvtFileView::ExecuteFilter: we told it to read synchronously!" );
1387 return eResult;
1390 // -----------------------------------------------------------------------
1392 void SvtFileView::CancelRunningAsyncAction()
1394 mpImp->CancelRunningAsyncAction();
1397 // -----------------------------------------------------------------------
1399 void SvtFileView::SetNoSelection()
1401 mpImp->mpView->SelectAll( sal_False );
1404 // -----------------------------------------------------------------------
1406 void SvtFileView::GetFocus()
1408 Control::GetFocus();
1409 if ( mpImp && mpImp->mpView )
1410 mpImp->mpView->GrabFocus();
1413 // -----------------------------------------------------------------------
1415 void SvtFileView::SetSelectHdl( const Link& rHdl )
1417 mpImp->SetSelectHandler( rHdl );
1420 // -----------------------------------------------------------------------
1422 void SvtFileView::SetDoubleClickHdl( const Link& rHdl )
1424 mpImp->mpView->SetDoubleClickHdl( rHdl );
1427 // -----------------------------------------------------------------------
1429 sal_uLong SvtFileView::GetSelectionCount() const
1431 return mpImp->mpView->GetSelectionCount();
1434 // -----------------------------------------------------------------------
1436 SvTreeListEntry* SvtFileView::FirstSelected() const
1438 return mpImp->mpView->FirstSelected();
1441 // -----------------------------------------------------------------------
1443 SvTreeListEntry* SvtFileView::NextSelected( SvTreeListEntry* pEntry ) const
1445 return mpImp->mpView->NextSelected( pEntry );
1448 // -----------------------------------------------------------------------
1450 void SvtFileView::EnableAutoResize()
1452 mpImp->mpView->EnableAutoResize();
1455 // -----------------------------------------------------------------------
1457 void SvtFileView::SetFocus()
1459 mpImp->mpView->GrabFocus();
1462 // -----------------------------------------------------------------------
1463 const OUString& SvtFileView::GetViewURL() const
1465 return mpImp->maViewURL;
1468 // -----------------------------------------------------------------------
1469 void SvtFileView::SetOpenDoneHdl( const Link& rHdl )
1471 mpImp->maOpenDoneLink = rHdl;
1474 // -----------------------------------------------------------------------
1475 void SvtFileView::EnableContextMenu( sal_Bool bEnable )
1477 mpImp->EnableContextMenu( bEnable );
1480 // -----------------------------------------------------------------------
1481 void SvtFileView::EnableDelete( sal_Bool bEnable )
1483 mpImp->EnableDelete( bEnable );
1486 void SvtFileView::EnableNameReplacing( sal_Bool bEnable )
1488 mpImp->EnableNameReplacing( bEnable );
1491 // -----------------------------------------------------------------------
1492 void SvtFileView::EndInplaceEditing( bool _bCancel )
1494 return mpImp->EndEditing( _bCancel );
1497 // -----------------------------------------------------------------------
1498 IMPL_LINK( SvtFileView, HeaderSelect_Impl, HeaderBar*, pBar )
1500 DBG_ASSERT( pBar, "no headerbar" );
1501 sal_uInt16 nItemID = pBar->GetCurItemId();
1503 HeaderBarItemBits nBits;
1505 // clear the arrow of the recently used column
1506 if ( nItemID != mpImp->mnSortColumn )
1508 if ( !nItemID )
1510 // first call -> remove arrow from title column,
1511 // because another column is the sort column
1512 nItemID = mpImp->mnSortColumn;
1513 mpImp->mnSortColumn = COLUMN_TITLE;
1515 nBits = pBar->GetItemBits( mpImp->mnSortColumn );
1516 nBits &= ~( HIB_UPARROW | HIB_DOWNARROW );
1517 pBar->SetItemBits( mpImp->mnSortColumn, nBits );
1520 nBits = pBar->GetItemBits( nItemID );
1522 sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
1524 if ( bUp )
1526 nBits &= ~HIB_UPARROW;
1527 nBits |= HIB_DOWNARROW;
1529 else
1531 nBits &= ~HIB_DOWNARROW;
1532 nBits |= HIB_UPARROW;
1535 pBar->SetItemBits( nItemID, nBits );
1536 mpImp->Resort_Impl( nItemID, !bUp );
1537 return 1;
1540 // -----------------------------------------------------------------------
1541 IMPL_LINK( SvtFileView, HeaderEndDrag_Impl, HeaderBar*, pBar )
1543 if ( !pBar->IsItemMode() )
1545 Size aSize;
1546 sal_uInt16 nTabs = pBar->GetItemCount();
1547 long nTmpSize = 0;
1549 for ( sal_uInt16 i = 1; i <= nTabs; ++i )
1551 long nWidth = pBar->GetItemSize(i);
1552 aSize.Width() = nWidth + nTmpSize;
1553 nTmpSize += nWidth;
1554 mpImp->mpView->SetTab( i, aSize.Width(), MAP_PIXEL );
1558 return 0;
1561 // -----------------------------------------------------------------------
1562 OUString SvtFileView::GetConfigString() const
1564 OUString sRet;
1565 HeaderBar* pBar = mpImp->mpView->GetHeaderBar();
1566 DBG_ASSERT( pBar, "invalid headerbar" );
1568 // sort order
1569 sRet += OUString::number( mpImp->mnSortColumn );
1570 sRet += ";";
1571 HeaderBarItemBits nBits = pBar->GetItemBits( mpImp->mnSortColumn );
1572 sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
1573 sRet += bUp ? OUString("1") : OUString("0");
1574 sRet += ";";
1576 sal_uInt16 nCount = pBar->GetItemCount();
1577 for ( sal_uInt16 i = 0; i < nCount; ++i )
1579 sal_uInt16 nId = pBar->GetItemId(i);
1580 sRet += OUString::number( nId );
1581 sRet += ";";
1582 sRet += OUString::number( pBar->GetItemSize( nId ) );
1583 sRet += ";";
1586 sRet = comphelper::string::stripEnd(sRet, ';');
1587 return sRet;
1590 // -----------------------------------------------------------------------
1591 void SvtFileView::SetConfigString( const OUString& rCfgStr )
1593 HeaderBar* pBar = mpImp->mpView->GetHeaderBar();
1594 DBG_ASSERT( pBar, "invalid headerbar" );
1596 sal_Int32 nIdx = 0;
1597 mpImp->mnSortColumn = (sal_uInt16)rCfgStr.getToken( 0, ';', nIdx ).toInt32();
1598 sal_Bool bUp = (sal_Bool)(sal_uInt16)rCfgStr.getToken( 0, ';', nIdx ).toInt32();
1599 HeaderBarItemBits nBits = pBar->GetItemBits( mpImp->mnSortColumn );
1601 if ( bUp )
1603 nBits &= ~HIB_UPARROW;
1604 nBits |= HIB_DOWNARROW;
1606 else
1608 nBits &= ~HIB_DOWNARROW;
1609 nBits |= HIB_UPARROW;
1611 pBar->SetItemBits( mpImp->mnSortColumn, nBits );
1613 while ( nIdx != -1 )
1615 sal_uInt16 nItemId = (sal_uInt16)rCfgStr.getToken( 0, ';', nIdx ).toInt32();
1616 pBar->SetItemSize( nItemId, rCfgStr.getToken( 0, ';', nIdx ).toInt32() );
1619 HeaderSelect_Impl( pBar );
1620 HeaderEndDrag_Impl( pBar );
1623 // -----------------------------------------------------------------------
1624 void SvtFileView::StateChanged( StateChangedType nStateChange )
1626 if ( nStateChange == STATE_CHANGE_ENABLE )
1627 Invalidate();
1628 Control::StateChanged( nStateChange );
1631 // -----------------------------------------------------------------------
1632 // class NameTranslator_Impl
1633 // -----------------------------------------------------------------------
1635 NameTranslator_Impl::NameTranslator_Impl( const INetURLObject& rActualFolder )
1637 mpActFolder = new NameTranslationList( rActualFolder );
1640 NameTranslator_Impl::~NameTranslator_Impl()
1642 if( mpActFolder )
1643 delete mpActFolder;
1646 void NameTranslator_Impl::SetActualFolder( const INetURLObject& rActualFolder )
1648 HashedEntry aActFolder( rActualFolder );
1650 if( mpActFolder )
1652 if( *mpActFolder != aActFolder )
1654 delete mpActFolder;
1655 mpActFolder = new NameTranslationList( rActualFolder );
1658 else
1659 mpActFolder = new NameTranslationList( rActualFolder );
1662 sal_Bool NameTranslator_Impl::GetTranslation( const OUString& rOrg, OUString& rTrans ) const
1664 sal_Bool bRet = sal_False;
1666 if( mpActFolder )
1668 const OUString* pTrans = mpActFolder->Translate( rOrg );
1669 if( pTrans )
1671 rTrans = *pTrans;
1672 bRet = sal_True;
1676 return bRet;
1679 const OUString* NameTranslator_Impl::GetTransTableFileName() const
1681 return mpActFolder? &mpActFolder->GetTransTableFileName() : NULL;
1684 // -----------------------------------------------------------------------
1685 // class SvtFileView_Impl
1686 // -----------------------------------------------------------------------
1688 SvtFileView_Impl::SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > xEnv, sal_Int16 nFlags, sal_Bool bOnlyFolder )
1690 :mpAntiImpl ( pAntiImpl )
1691 ,m_eAsyncActionResult ( ::svt::ERROR )
1692 ,m_bRunningAsyncAction ( false )
1693 ,m_bAsyncActionCancelled ( false )
1694 ,mpNameTrans ( NULL )
1695 ,mnSortColumn ( COLUMN_TITLE )
1696 ,mbAscending ( sal_True )
1697 ,mbOnlyFolder ( bOnlyFolder )
1698 ,mbReplaceNames ( sal_False )
1699 ,mnSuspendSelectCallback ( 0 )
1700 ,mbIsFirstResort ( sal_True )
1701 ,aIntlWrapper ( Application::GetSettings().GetLanguageTag() )
1702 ,maFolderImage ( SvtResId( IMG_SVT_FOLDER ) )
1703 ,mxCmdEnv ( xEnv )
1706 maAllFilter = "*.*";
1707 mpView = new ViewTabListBox_Impl( mpAntiImpl, this, nFlags );
1708 mpView->EnableCellFocus();
1711 // -----------------------------------------------------------------------
1712 SvtFileView_Impl::~SvtFileView_Impl()
1714 Clear();
1716 // use temp pointer to prevent access of deleted member (GetFocus())
1717 ViewTabListBox_Impl* pTemp = mpView;
1718 mpView = NULL;
1719 delete pTemp;
1722 // -----------------------------------------------------------------------
1723 void SvtFileView_Impl::Clear()
1725 ::osl::MutexGuard aGuard( maMutex );
1727 std::vector< SortingData_Impl* >::iterator aIt;
1729 for ( aIt = maContent.begin(); aIt != maContent.end(); ++aIt )
1730 delete (*aIt);
1732 maContent.clear();
1734 if( mpNameTrans )
1735 DELETEZ( mpNameTrans );
1738 // -----------------------------------------------------------------------
1739 FileViewResult SvtFileView_Impl::GetFolderContent_Impl(
1740 const OUString& rFolder,
1741 const FileViewAsyncAction* pAsyncDescriptor,
1742 const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
1744 ::osl::ClearableMutexGuard aGuard( maMutex );
1745 INetURLObject aFolderObj( rFolder );
1746 DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
1748 // prepare name translation
1749 SetActualFolder( aFolderObj );
1751 FolderDescriptor aFolder( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) );
1753 aGuard.clear();
1754 return GetFolderContent_Impl( aFolder, pAsyncDescriptor, rBlackList );
1757 // -----------------------------------------------------------------------
1758 FileViewResult SvtFileView_Impl::GetFolderContent_Impl(
1759 const FolderDescriptor& _rFolder,
1760 const FileViewAsyncAction* pAsyncDescriptor,
1761 const ::com::sun::star::uno::Sequence< OUString >& rBlackList )
1763 DBG_TESTSOLARMUTEX();
1764 ::osl::ClearableMutexGuard aGuard( maMutex );
1766 OSL_ENSURE( !m_pContentEnumerator.is(), "SvtFileView_Impl::GetFolderContent_Impl: still running another enumeration!" );
1767 m_pContentEnumerator = new ::svt::FileViewContentEnumerator(
1768 mpView->GetCommandEnvironment(), maContent, maMutex, mbReplaceNames ? mpNameTrans : NULL );
1769 // TODO: should we cache and re-use this thread?
1771 if ( !pAsyncDescriptor )
1773 ::svt::EnumerationResult eResult = m_pContentEnumerator->enumerateFolderContentSync( _rFolder, rBlackList );
1774 if ( ::svt::SUCCESS == eResult )
1776 implEnumerationSuccess();
1777 m_pContentEnumerator.clear();
1778 return eSuccess;
1780 m_pContentEnumerator.clear();
1781 return eFailure;
1784 m_bRunningAsyncAction = true;
1785 m_bAsyncActionCancelled = false;
1786 m_eAsyncActionResult = ::svt::ERROR;
1787 m_aAsyncActionFinished.reset();
1789 // don't (yet) set m_aCurrentAsyncActionHandler to pTimeout->aFinishHandler.
1790 // By definition, this handler *only* get's called when the result cannot be obtained
1791 // during the minimum wait time, so it is only set below, when needed.
1792 m_aCurrentAsyncActionHandler = Link();
1794 // minimum time to wait
1795 ::std::auto_ptr< TimeValue > pTimeout( new TimeValue );
1796 sal_Int32 nMinTimeout = pAsyncDescriptor->nMinTimeout;
1797 OSL_ENSURE( nMinTimeout > 0, "SvtFileView_Impl::GetFolderContent_Impl: invalid minimum timeout!" );
1798 if ( nMinTimeout <= 0 )
1799 nMinTimeout = sal_Int32( 1000L );
1800 pTimeout->Seconds = nMinTimeout / 1000L;
1801 pTimeout->Nanosec = ( nMinTimeout % 1000L ) * 1000000L;
1803 m_pContentEnumerator->enumerateFolderContent( _rFolder, this );
1805 // wait until the enumeration is finished
1806 // for this, release our own mutex (which is used by the enumerator thread)
1807 aGuard.clear();
1809 ::osl::Condition::Result eResult = ::osl::Condition::result_ok;
1811 // also release the SolarMutex. Not all code which is needed during the enumeration
1812 // is Solar-Thread-Safe, in particular there is some code which needs to access
1813 // string resources (and our resource system relies on the SolarMutex :()
1814 SolarMutexReleaser aSolarRelease;
1816 // now wait. Note that if we didn't get an pAsyncDescriptor, then this is an infinite wait.
1817 eResult = m_aAsyncActionFinished.wait( pTimeout.get() );
1820 ::osl::MutexGuard aGuard2( maMutex );
1821 if ( ::osl::Condition::result_timeout == eResult )
1823 // maximum time to wait
1824 OSL_ENSURE( !m_pCancelAsyncTimer.get(), "SvtFileView_Impl::GetFolderContent_Impl: there's still a previous timer!" );
1825 m_pCancelAsyncTimer = new CallbackTimer( this );
1826 sal_Int32 nMaxTimeout = pAsyncDescriptor->nMaxTimeout;
1827 OSL_ENSURE( nMaxTimeout > nMinTimeout,
1828 "SvtFileView_Impl::GetFolderContent_Impl: invalid maximum timeout!" );
1829 if ( nMaxTimeout <= nMinTimeout )
1830 nMaxTimeout = nMinTimeout + 5000;
1831 m_pCancelAsyncTimer->setRemainingTime( salhelper::TTimeValue( nMaxTimeout - nMinTimeout ) );
1832 // we already waited for nMinTimeout milliseconds, so take this into account
1833 m_pCancelAsyncTimer->start();
1835 m_aCurrentAsyncActionHandler = pAsyncDescriptor->aFinishHandler;
1836 DBG_ASSERT( m_aCurrentAsyncActionHandler.IsSet(), "SvtFileView_Impl::GetFolderContent_Impl: nobody interested when it's finished?" );
1837 mpView->ClearAll();
1838 return eStillRunning;
1841 m_bRunningAsyncAction = false;
1842 switch ( m_eAsyncActionResult )
1844 case ::svt::SUCCESS:
1845 return eSuccess;
1847 case ::svt::ERROR:
1848 return eFailure;
1850 case ::svt::RUNNING:
1851 return eStillRunning;
1854 SAL_WARN( "svtools.contnr", "SvtFileView_Impl::GetFolderContent_Impl: unreachable!" );
1855 return eFailure;
1858 // -----------------------------------------------------------------------
1859 void SvtFileView_Impl::FilterFolderContent_Impl( const OUString &rFilter )
1861 sal_Bool bHideTransFile = mbReplaceNames && mpNameTrans;
1863 OUString sHideEntry;
1864 if( bHideTransFile )
1866 const OUString* pTransTableFileName = mpNameTrans->GetTransTableFileName();
1867 if( pTransTableFileName )
1869 sHideEntry = *pTransTableFileName;
1870 sHideEntry = sHideEntry.toAsciiUpperCase();
1872 else
1873 bHideTransFile = sal_False;
1876 if ( !bHideTransFile &&
1877 ( rFilter.isEmpty() || ( rFilter == ALL_FILES_FILTER ) ) )
1878 // when replacing names, there is always something to filter (no view of ".nametranslation.table")
1879 return;
1881 ::osl::MutexGuard aGuard( maMutex );
1883 if ( maContent.empty() )
1884 return;
1886 // count (estimate) the number of filter tokens
1887 sal_Int32 nTokens=0;
1888 const sal_Unicode* pStart = rFilter.getStr();
1889 const sal_Unicode* pEnd = pStart + rFilter.getLength();
1890 while ( pStart != pEnd )
1891 if ( *pStart++ == ';' )
1892 ++nTokens;
1894 // collect the filter tokens
1895 ::std::vector< WildCard > aFilters;
1896 FilterMatch::createWildCardFilterList(rFilter,aFilters);
1899 // do the filtering
1900 ::std::vector< SortingData_Impl* >::iterator aContentLoop = maContent.begin();
1901 OUString sCompareString;
1904 if ( (*aContentLoop)->mbIsFolder )
1905 ++aContentLoop;
1906 else
1908 // normalize the content title (we always match case-insensitive)
1909 // 91872 - 11.09.2001 - frank.schoenheit@sun.com
1910 sCompareString = (*aContentLoop)->GetFileName(); // filter works on file name, not on title!
1911 sal_Bool bDelete;
1913 if( bHideTransFile && sCompareString == sHideEntry )
1914 bDelete = sal_True;
1915 else
1917 // search for the first filter which matches
1918 ::std::vector< WildCard >::const_iterator pMatchingFilter =
1919 ::std::find_if(
1920 aFilters.begin(),
1921 aFilters.end(),
1922 FilterMatch( sCompareString )
1925 bDelete = aFilters.end() == pMatchingFilter;
1928 if( bDelete )
1930 // none of the filters did match
1931 delete (*aContentLoop);
1933 if ( maContent.begin() == aContentLoop )
1935 maContent.erase( aContentLoop );
1936 aContentLoop = maContent.begin();
1938 else
1940 std::vector< SortingData_Impl* >::iterator aDelete = aContentLoop;
1941 --aContentLoop; // move the iterator to a position which is not invalidated by the erase
1942 maContent.erase( aDelete );
1943 ++aContentLoop; // this is now the next one ....
1946 else
1947 ++aContentLoop;
1950 while ( aContentLoop != maContent.end() );
1953 // -----------------------------------------------------------------------
1954 IMPL_LINK( SvtFileView_Impl, SelectionMultiplexer, void*, _pSource )
1956 return mnSuspendSelectCallback ? 0L : m_aSelectHandler.Call( _pSource );
1959 // -----------------------------------------------------------------------
1960 void SvtFileView_Impl::SetSelectHandler( const Link& _rHdl )
1962 m_aSelectHandler = _rHdl;
1964 Link aMasterHandler;
1965 if ( m_aSelectHandler.IsSet() )
1966 aMasterHandler = LINK( this, SvtFileView_Impl, SelectionMultiplexer );
1968 mpView->SetSelectHdl( aMasterHandler );
1971 // -----------------------------------------------------------------------
1972 void SvtFileView_Impl::InitSelection()
1974 mpView->SelectAll( sal_False );
1975 SvTreeListEntry* pFirst = mpView->First();
1976 if ( pFirst )
1977 mpView->SetCursor( pFirst, sal_True );
1980 // -----------------------------------------------------------------------
1981 void SvtFileView_Impl::OpenFolder_Impl()
1983 ::osl::MutexGuard aGuard( maMutex );
1985 mpView->SetUpdateMode( sal_False );
1986 mpView->ClearAll();
1988 std::vector< SortingData_Impl* >::iterator aIt;
1990 for ( aIt = maContent.begin(); aIt != maContent.end(); ++aIt )
1992 if ( mbOnlyFolder && ! (*aIt)->mbIsFolder )
1993 continue;
1995 // insert entry and set user data
1996 SvTreeListEntry* pEntry = mpView->InsertEntry( (*aIt)->maDisplayText,
1997 (*aIt)->maImage,
1998 (*aIt)->maImage );
2000 SvtContentEntry* pUserData = new SvtContentEntry( (*aIt)->maTargetURL,
2001 (*aIt)->mbIsFolder );
2002 pEntry->SetUserData( pUserData );
2005 InitSelection();
2007 ++mnSuspendSelectCallback;
2008 mpView->SetUpdateMode( sal_True );
2009 --mnSuspendSelectCallback;
2011 ResetCursor();
2014 // -----------------------------------------------------------------------
2015 void SvtFileView_Impl::ResetCursor()
2017 // deselect
2018 SvTreeListEntry* pEntry = mpView->FirstSelected();
2019 if ( pEntry )
2020 mpView->Select( pEntry, sal_False );
2021 // set cursor to the first entry
2022 mpView->SetCursor( mpView->First(), sal_True );
2023 mpView->Update();
2026 // -----------------------------------------------------------------------
2027 void SvtFileView_Impl::CancelRunningAsyncAction()
2029 DBG_TESTSOLARMUTEX();
2030 ::osl::MutexGuard aGuard( maMutex );
2031 if ( !m_pContentEnumerator.is() )
2032 return;
2034 m_bAsyncActionCancelled = true;
2035 m_pContentEnumerator->cancel();
2036 m_bRunningAsyncAction = false;
2038 m_pContentEnumerator.clear();
2039 if ( m_pCancelAsyncTimer.is() && m_pCancelAsyncTimer->isTicking() )
2040 m_pCancelAsyncTimer->stop();
2041 m_pCancelAsyncTimer = NULL;
2044 //-----------------------------------------------------------------------
2045 void SvtFileView_Impl::onTimeout( CallbackTimer* )
2047 SolarMutexGuard aSolarGuard;
2048 ::osl::MutexGuard aGuard( maMutex );
2049 if ( !m_bRunningAsyncAction )
2050 // there might have been a race condition while we waited for the mutex
2051 return;
2053 CancelRunningAsyncAction();
2055 if ( m_aCurrentAsyncActionHandler.IsSet() )
2057 Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( eTimeout ) );
2058 m_aCurrentAsyncActionHandler = Link();
2062 //-----------------------------------------------------------------------
2063 void SvtFileView_Impl::enumerationDone( ::svt::EnumerationResult _eResult )
2065 SolarMutexGuard aSolarGuard;
2066 ::osl::MutexGuard aGuard( maMutex );
2068 m_pContentEnumerator.clear();
2069 if ( m_pCancelAsyncTimer.is() && m_pCancelAsyncTimer->isTicking() )
2070 m_pCancelAsyncTimer->stop();
2071 m_pCancelAsyncTimer = NULL;
2073 if ( m_bAsyncActionCancelled )
2074 // this is to prevent race conditions
2075 return;
2077 m_eAsyncActionResult = _eResult;
2078 m_bRunningAsyncAction = false;
2080 m_aAsyncActionFinished.set();
2082 if ( svt::SUCCESS == _eResult )
2083 implEnumerationSuccess();
2085 if ( m_aCurrentAsyncActionHandler.IsSet() )
2087 Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( m_eAsyncActionResult ) );
2088 m_aCurrentAsyncActionHandler = Link();
2092 //-----------------------------------------------------------------------
2093 void SvtFileView_Impl::implEnumerationSuccess()
2095 FilterFolderContent_Impl( maCurrentFilter );
2096 SortFolderContent_Impl();
2097 CreateDisplayText_Impl();
2098 OpenFolder_Impl();
2099 maOpenDoneLink.Call( mpAntiImpl );
2102 // -----------------------------------------------------------------------
2103 void SvtFileView_Impl::ReplaceTabWithString( OUString& aValue )
2105 OUString aTab( "\t" );
2106 OUString aTabString( "%09" );
2107 sal_Int32 iPos;
2109 while ( ( iPos = aValue.indexOf( aTab ) ) >= 0 )
2110 aValue = aValue.replaceAt( iPos, 1, aTabString );
2113 // -----------------------------------------------------------------------
2114 void SvtFileView_Impl::CreateDisplayText_Impl()
2116 ::osl::MutexGuard aGuard( maMutex );
2118 OUString aValue;
2119 OUString aTab( "\t" );
2120 OUString aDateSep( ", " );
2122 std::vector< SortingData_Impl* >::iterator aIt;
2124 for ( aIt = maContent.begin(); aIt != maContent.end(); ++aIt )
2126 // title, type, size, date
2127 aValue = (*aIt)->GetTitle();
2128 // #83004# --------------------
2129 ReplaceTabWithString( aValue );
2130 aValue += aTab;
2131 aValue += (*aIt)->maType;
2132 aValue += aTab;
2133 // folders don't have a size
2134 if ( ! (*aIt)->mbIsFolder )
2135 aValue += CreateExactSizeText( (*aIt)->maSize );
2136 aValue += aTab;
2137 // set the date, but volumes have no date
2138 if ( ! (*aIt)->mbIsFolder || ! (*aIt)->mbIsVolume )
2140 SvtSysLocale aSysLocale;
2141 const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
2142 aValue += rLocaleData.getDate( (*aIt)->maModDate );
2143 aValue += aDateSep;
2144 aValue += rLocaleData.getTime( (*aIt)->maModDate );
2146 (*aIt)->maDisplayText = aValue;
2148 // detect image
2149 if ( (*aIt)->mbIsFolder )
2151 ::svtools::VolumeInfo aVolInfo( (*aIt)->mbIsVolume, (*aIt)->mbIsRemote,
2152 (*aIt)->mbIsRemoveable, (*aIt)->mbIsFloppy,
2153 (*aIt)->mbIsCompactDisc );
2154 (*aIt)->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, sal_False );
2156 else
2157 (*aIt)->maImage = SvFileInformationManager::GetFileImage( INetURLObject( (*aIt)->maTargetURL ), sal_False );
2161 // -----------------------------------------------------------------------
2162 // this function converts the sequence of strings into a vector of SortingData
2163 // the string should have the form :
2164 // title \t type \t size \t date \t target url \t is folder \t image url
2166 void SvtFileView_Impl::CreateVector_Impl( const Sequence < OUString > &rList )
2168 ::osl::MutexGuard aGuard( maMutex );
2170 OUString aTab( "\t" );
2172 sal_uInt32 nCount = (sal_uInt32) rList.getLength();
2174 for( sal_uInt32 i = 0; i < nCount; i++ )
2176 SortingData_Impl* pEntry = new SortingData_Impl;
2177 OUString aValue = rList[i];
2178 OUString aDisplayText;
2179 sal_Int32 nIndex = 0;
2181 // get the title
2182 pEntry->SetNewTitle( aValue.getToken( 0, '\t', nIndex ) );
2183 aDisplayText = pEntry->GetTitle();
2184 ReplaceTabWithString( aDisplayText );
2185 aDisplayText += aTab;
2187 // get the type
2188 if ( nIndex >= 0 )
2190 pEntry->maType = aValue.getToken( 0, '\t', nIndex );
2191 aDisplayText += pEntry->maType;
2193 aDisplayText += aTab;
2195 // get the size
2196 if ( nIndex >= 0 )
2198 OUString aSize = aValue.getToken( 0, '\t', nIndex );
2199 aDisplayText += aSize;
2201 if ( !aSize.isEmpty() )
2202 pEntry->maSize = aSize.toInt64();
2204 aDisplayText += aTab;
2206 // get the date
2207 if ( nIndex >= 0 )
2209 OUString aDate = aValue.getToken( 0, '\t', nIndex );
2210 aDisplayText += aDate;
2212 if ( !aDate.isEmpty() )
2214 SAL_WARN( "svtools.contnr", "Don't know, how to convert date" );
2215 ;// convert date string to date
2218 // get the target url
2219 if ( nIndex >= 0 )
2221 pEntry->maTargetURL = aValue.getToken( 0, '\t', nIndex );
2223 // get the size
2224 if ( nIndex >= 0 )
2226 OUString aBool = aValue.getToken( 0, '\t', nIndex );
2227 if ( !aBool.isEmpty() )
2228 pEntry->mbIsFolder = aBool.toBoolean();
2230 // get the image url
2231 if ( nIndex >= 0 )
2233 pEntry->maImageURL = aValue.getToken( 0, '\t', nIndex );
2236 // set the display text
2237 pEntry->maDisplayText = aDisplayText;
2239 // detect the image
2240 if( aValue != SEPARATOR_STR )
2242 INetURLObject aObj( !pEntry->maImageURL.isEmpty() ? pEntry->maImageURL : pEntry->maTargetURL );
2243 pEntry->maImage = SvFileInformationManager::GetImage( aObj, sal_False );
2245 maContent.push_back( pEntry );
2249 // -----------------------------------------------------------------------
2250 void SvtFileView_Impl::Resort_Impl( sal_Int16 nColumn, sal_Bool bAscending )
2252 ::osl::MutexGuard aGuard( maMutex );
2254 if ( ( nColumn == mnSortColumn ) &&
2255 ( bAscending == mbAscending ) )
2256 return;
2258 // reset the quick search index
2259 mpView->ResetQuickSearch_Impl( NULL );
2261 OUString aEntryURL;
2262 SvTreeListEntry* pEntry = mpView->GetCurEntry();
2263 if ( pEntry && pEntry->GetUserData() )
2264 aEntryURL = ( (SvtContentEntry*)pEntry->GetUserData() )->maURL;
2266 mnSortColumn = nColumn;
2267 mbAscending = bAscending;
2269 SortFolderContent_Impl();
2270 OpenFolder_Impl();
2272 if ( !mbIsFirstResort )
2274 sal_uLong nPos = GetEntryPos( aEntryURL );
2275 if ( nPos < mpView->GetEntryCount() )
2277 pEntry = mpView->GetEntry( nPos );
2279 ++mnSuspendSelectCallback; // #i15668#
2280 mpView->SetCurEntry( pEntry );
2281 --mnSuspendSelectCallback;
2284 else
2285 mbIsFirstResort = sal_False;
2288 // -----------------------------------------------------------------------
2289 static sal_Bool gbAscending = sal_True;
2290 static sal_Int16 gnColumn = COLUMN_TITLE;
2291 static const CollatorWrapper* pCollatorWrapper = NULL;
2293 /* this functions returns true, if aOne is less then aTwo
2295 sal_Bool CompareSortingData_Impl( SortingData_Impl* const aOne, SortingData_Impl* const aTwo )
2297 DBG_ASSERT( pCollatorWrapper, "*CompareSortingData_Impl(): Can't work this way!" );
2299 sal_Int32 nComp;
2300 sal_Bool bRet = sal_False;
2301 sal_Bool bEqual = sal_False;
2303 if ( aOne->mbIsFolder != aTwo->mbIsFolder )
2305 if ( aOne->mbIsFolder )
2306 bRet = sal_True;
2307 else
2308 bRet = sal_False;
2310 // !!! pb: #100376# folder always on top
2311 if ( !gbAscending )
2312 bRet = !bRet;
2314 else
2316 switch ( gnColumn )
2318 case COLUMN_TITLE:
2319 // compare case insensitive first
2320 nComp = pCollatorWrapper->compareString( aOne->GetLowerTitle(), aTwo->GetLowerTitle() );
2322 if ( nComp == 0 )
2323 nComp = pCollatorWrapper->compareString( aOne->GetTitle(), aTwo->GetTitle() );
2325 if ( nComp < 0 )
2326 bRet = sal_True;
2327 else if ( nComp > 0 )
2328 bRet = sal_False;
2329 else
2330 bEqual = sal_True;
2331 break;
2332 case COLUMN_TYPE:
2333 nComp = pCollatorWrapper->compareString( aOne->maType, aTwo->maType );
2334 if ( nComp < 0 )
2335 bRet = sal_True;
2336 else if ( nComp > 0 )
2337 bRet = sal_False;
2338 else
2339 bEqual = sal_True;
2340 break;
2341 case COLUMN_SIZE:
2342 if ( aOne->maSize < aTwo->maSize )
2343 bRet = sal_True;
2344 else if ( aOne->maSize > aTwo->maSize )
2345 bRet = sal_False;
2346 else
2347 bEqual = sal_True;
2348 break;
2349 case COLUMN_DATE:
2350 if ( aOne->maModDate < aTwo->maModDate )
2351 bRet = sal_True;
2352 else if ( aOne->maModDate > aTwo->maModDate )
2353 bRet = sal_False;
2354 else
2355 bEqual = sal_True;
2356 break;
2357 default:
2358 DBG_WARNING( "CompareSortingData_Impl: Compare unknown type!" );
2359 bRet = sal_False;
2363 // when the two elements are equal, we must not return sal_True (which would
2364 // happen if we just return ! ( a < b ) when not sorting ascending )
2365 if ( bEqual )
2366 return sal_False;
2368 return gbAscending ? bRet : !bRet;
2371 // -----------------------------------------------------------------------
2372 void SvtFileView_Impl::SortFolderContent_Impl()
2374 ::osl::MutexGuard aGuard( maMutex );
2376 sal_uInt32 nSize = maContent.size();
2378 if ( nSize > 1 )
2380 gbAscending = mbAscending;
2381 gnColumn = mnSortColumn;
2382 pCollatorWrapper = aIntlWrapper.getCaseCollator();
2384 std::stable_sort( maContent.begin(), maContent.end(), CompareSortingData_Impl );
2386 pCollatorWrapper = NULL;
2390 // -----------------------------------------------------------------------
2391 void SvtFileView_Impl::EntryRemoved( const OUString& rURL )
2393 ::osl::MutexGuard aGuard( maMutex );
2395 std::vector< SortingData_Impl* >::iterator aIt;
2397 for ( aIt = maContent.begin(); aIt != maContent.end(); ++aIt )
2399 if ( (*aIt)->maTargetURL == rURL )
2401 maContent.erase( aIt );
2402 break;
2407 // -----------------------------------------------------------------------
2408 void SvtFileView_Impl::EntryRenamed( OUString& rURL,
2409 const OUString& rTitle )
2411 ::osl::MutexGuard aGuard( maMutex );
2413 std::vector< SortingData_Impl* >::iterator aIt;
2415 for ( aIt = maContent.begin(); aIt != maContent.end(); ++aIt )
2417 if ( (*aIt)->maTargetURL == rURL )
2419 (*aIt)->SetNewTitle( rTitle );
2420 OUString aDisplayText = (*aIt)->maDisplayText;
2421 sal_Int32 nIndex = aDisplayText.indexOf( '\t' );
2423 if ( nIndex > 0 )
2424 (*aIt)->maDisplayText = aDisplayText.replaceAt( 0, nIndex, rTitle );
2426 INetURLObject aURLObj( rURL );
2427 aURLObj.SetName( rTitle, INetURLObject::ENCODE_ALL );
2429 rURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
2431 (*aIt)->maTargetURL = rURL;
2432 break;
2437 // -----------------------------------------------------------------------
2438 OUString SvtFileView_Impl::FolderInserted( const OUString& rURL, const OUString& rTitle )
2440 ::osl::MutexGuard aGuard( maMutex );
2442 SortingData_Impl* pData = new SortingData_Impl;
2444 pData->SetNewTitle( rTitle );
2445 pData->maSize = 0;
2446 pData->mbIsFolder = sal_True;
2447 pData->maTargetURL = rURL;
2449 ::svtools::VolumeInfo aVolInfo;
2450 pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
2451 pData->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, sal_False );
2453 OUString aValue;
2454 OUString aTab( "\t" );
2455 OUString aDateSep( ", " );
2457 // title, type, size, date
2458 aValue = pData->GetTitle();
2459 ReplaceTabWithString( aValue );
2460 aValue += aTab;
2461 aValue += pData->maType;
2462 aValue += aTab;
2463 // folders don't have a size
2464 aValue += aTab;
2465 // set the date
2466 SvtSysLocale aSysLocale;
2467 const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
2468 aValue += rLocaleData.getDate( pData->maModDate );
2469 aValue += aDateSep;
2470 aValue += rLocaleData.getTime( pData->maModDate );
2472 pData->maDisplayText = aValue;
2473 maContent.push_back( pData );
2475 return aValue;
2478 // -----------------------------------------------------------------------
2479 sal_uLong SvtFileView_Impl::GetEntryPos( const OUString& rURL )
2481 ::osl::MutexGuard aGuard( maMutex );
2483 std::vector< SortingData_Impl* >::iterator aIt;
2484 sal_uLong nPos = 0;
2486 for ( aIt = maContent.begin(); aIt != maContent.end(); ++aIt )
2488 if ( (*aIt)->maTargetURL == rURL )
2489 return nPos;
2490 nPos += 1;
2493 return nPos;
2496 // -----------------------------------------------------------------------
2497 sal_Bool SvtFileView_Impl::SearchNextEntry( sal_uInt32& nIndex, const OUString& rTitle, sal_Bool bWrapAround )
2499 ::osl::MutexGuard aGuard( maMutex );
2501 sal_uInt32 nEnd = maContent.size();
2502 sal_uInt32 nStart = nIndex;
2503 while ( nIndex < nEnd )
2505 SortingData_Impl* pData = maContent[ nIndex ];
2506 if ( rTitle.compareTo( pData->GetLowerTitle(), rTitle.getLength() ) == 0 )
2507 return sal_True;
2508 nIndex += 1;
2511 if ( bWrapAround )
2513 nIndex = 0;
2514 while ( nIndex < nEnd && nIndex <= nStart )
2516 SortingData_Impl* pData = maContent[ nIndex ];
2517 if ( rTitle.compareTo( pData->GetLowerTitle(), rTitle.getLength() ) == 0 )
2518 return sal_True;
2519 nIndex += 1;
2523 return sal_False;
2526 // -----------------------------------------------------------------------
2527 void SvtFileView_Impl::SetActualFolder( const INetURLObject& rActualFolder )
2529 if( mbReplaceNames )
2531 if( mpNameTrans )
2532 mpNameTrans->SetActualFolder( rActualFolder );
2533 else
2534 mpNameTrans = new NameTranslator_Impl( rActualFolder );
2538 namespace svtools {
2540 // -----------------------------------------------------------------------
2541 // QueryDeleteDlg_Impl
2542 // -----------------------------------------------------------------------
2544 QueryDeleteDlg_Impl::QueryDeleteDlg_Impl
2546 Window* pParent,
2547 const OUString& rName // entry name
2550 ModalDialog( pParent, SvtResId( DLG_SVT_QUERYDELETE ) ),
2552 _aEntryLabel ( this, SvtResId( TXT_ENTRY ) ),
2553 _aEntry ( this, SvtResId( TXT_ENTRYNAME ) ),
2554 _aQueryMsg ( this, SvtResId( TXT_QUERYMSG ) ),
2555 _aYesButton ( this, SvtResId( BTN_YES ) ),
2556 _aAllButton ( this, SvtResId( BTN_ALL ) ),
2557 _aNoButton ( this, SvtResId( BTN_NO ) ),
2558 _aCancelButton( this, SvtResId( BTN_CANCEL ) ),
2560 _eResult( QUERYDELETE_YES )
2563 FreeResource();
2565 // Handler
2566 Link aLink( STATIC_LINK( this, QueryDeleteDlg_Impl, ClickLink ) );
2567 _aYesButton.SetClickHdl( aLink );
2568 _aAllButton.SetClickHdl( aLink );
2569 _aNoButton.SetClickHdl( aLink );
2571 // display specified texts
2573 WinBits nTmpStyle = _aEntry.GetStyle();
2574 nTmpStyle |= WB_PATHELLIPSIS;
2575 _aEntry.SetStyle( nTmpStyle );
2576 _aEntry.SetText( rName );
2579 // -----------------------------------------------------------------------
2581 IMPL_STATIC_LINK( QueryDeleteDlg_Impl, ClickLink, PushButton*, pBtn )
2583 if ( pBtn == &pThis->_aYesButton )
2584 pThis->_eResult = QUERYDELETE_YES;
2585 else if ( pBtn == &pThis->_aNoButton )
2586 pThis->_eResult = QUERYDELETE_NO;
2587 else if ( pBtn == &pThis->_aAllButton )
2588 pThis->_eResult = QUERYDELETE_ALL;
2589 else if ( pBtn == &pThis->_aCancelButton )
2590 pThis->_eResult = QUERYDELETE_CANCEL;
2592 pThis->EndDialog( RET_OK );
2594 return 0;
2599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */