1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
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
100 //====================================================================
102 //====================================================================
104 class ITimeoutHandler
107 virtual void onTimeout( CallbackTimer
* _pInstigator
) = 0;
110 ~ITimeoutHandler() {}
113 //====================================================================
115 //====================================================================
116 class CallbackTimer
: public ::salhelper::Timer
119 ITimeoutHandler
* m_pTimeoutHandler
;
122 CallbackTimer( ITimeoutHandler
* _pHandler
) : m_pTimeoutHandler( _pHandler
) { }
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
);
134 pHandler
->onTimeout( this );
139 // -----------------------------------------------------------------------
141 void FilterMatch::createWildCardFilterList(const OUString
& _rFilterList
,::std::vector
< WildCard
>& _rFilters
)
143 if( _rFilterList
.getLength() )
146 sal_Int32 nIndex
= 0;
150 sToken
= _rFilterList
.getToken( 0, ';', nIndex
);
151 if ( !sToken
.isEmpty() )
153 _rFilters
.push_back( WildCard( sToken
.toAsciiUpperCase() ) );
156 while ( nIndex
>= 0 );
160 // no filter is given -> match all
161 _rFilters
.push_back( WildCard(OUString("*")) );
164 // class ViewTabListBox_Impl ---------------------------------------------
166 class ViewTabListBox_Impl
: public SvHeaderTabListBox
169 Reference
< XCommandEnvironment
> mxCmdEnv
;
171 ::osl::Mutex maMutex
;
172 HeaderBar
* mpHeaderBar
;
173 SvtFileView_Impl
* mpParent
;
174 Timer maResetQuickSearch
;
175 OUString maQuickSearchText
;
176 OUString msAccessibleDescText
;
179 sal_uInt32 mnSearchIndex
;
180 sal_Bool mbResizeDisabled
: 1;
181 sal_Bool mbAutoResize
: 1;
182 sal_Bool mbEnableDelete
: 1;
183 sal_Bool mbEnableRename
: 1;
186 void DeleteEntries();
187 void DoQuickSearch( const sal_Unicode
& rChar
);
188 sal_Bool
Kill( const OUString
& rURL
);
191 virtual sal_Bool
DoubleClickHdl();
192 virtual OUString
GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType
, sal_Int32 _nPos
) const;
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
);
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 --------------------------------------------------
221 { // just a special String which can be compared on equality much faster
224 sal_Int32 mnHashCode
;
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;
271 return mnHashCode
< rRef
.mnHashCode
;
274 inline const OUString
& HashedEntry::GetName() const
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
288 OUString maTranslatedName
;
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
):
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();
319 INetURLObject maTransFile
; // URL of file with translation entries
320 HashedEntry maHashedURL
; // for future purposes when dealing with a set of cached
321 // NameTranslationLists
323 const OUString maTransFileName
;
324 void Init(); // reads the translation file and fills the (internal) list
327 NameTranslationList( const INetURLObject
& rBaseURL
);
328 // rBaseURL: path to folder for which the translation of the entries
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
);
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
)
404 pSearch
= static_cast<const NameTranslationEntry
*>(&*it
);
407 return pSearch
? &pSearch
->GetTranslation() : NULL
;
410 inline void NameTranslationList::Update()
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
423 NameTranslationList
* mpActFolder
;
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 //====================================================================
438 //====================================================================
440 class SvtFileView_Impl
:public ::svt::IEnumerationResultHandler
441 ,public ITimeoutHandler
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
;
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
;
474 OUString maAllFilter
;
475 OUString maCurrentFilter
;
478 Reference
< XCommandEnvironment
> mxCmdEnv
;
480 SvtFileView_Impl( SvtFileView
* pAntiImpl
, Reference
< XCommandEnvironment
> xEnv
,
482 sal_Bool bOnlyFolder
);
483 virtual ~SvtFileView_Impl();
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();
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();
532 inline void EndEditing( bool _bCancel
);
535 DECL_LINK( SelectionMultiplexer
, void* );
538 // IEnumerationResultHandler overridables
539 virtual void enumerationDone( ::svt::EnumerationResult _eResult
);
540 void implEnumerationSuccess();
543 virtual void onTimeout( CallbackTimer
* _pInstigator
);
546 inline void SvtFileView_Impl::EnableContextMenu( sal_Bool bEnable
)
548 mpView
->EnableContextMenuHandling( bEnable
);
550 mbReplaceNames
= sal_False
;
553 inline void SvtFileView_Impl::EnableDelete( sal_Bool bEnable
)
555 mpView
->EnableDelete( bEnable
);
557 mbReplaceNames
= sal_False
;
560 inline sal_Bool
SvtFileView_Impl::EnableNameReplacing( sal_Bool bEnable
)
562 mpView
->EnableRename( bEnable
);
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
572 mbReplaceNames
= bEnable
;
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
);
592 long nMega
= 1024 * 1024;
593 long nGiga
= nMega
* 1024;
595 OUString
aUnitStr(' ');
599 aUnitStr
+= SVT_RESSTR(STR_SVT_BYTES
);
602 else if ( nSize
< nMega
)
605 aUnitStr
+= SVT_RESSTR(STR_SVT_KB
);
608 else if ( nSize
< nGiga
)
611 aUnitStr
+= SVT_RESSTR(STR_SVT_MB
);
617 aUnitStr
+= SVT_RESSTR(STR_SVT_GB
);
621 OUString
aSizeStr( ::rtl::math::doubleToUString( fSize
,
622 rtl_math_StringFormat_F
, nDec
,
623 SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]) );
624 aSizeStr
+= aUnitStr
;
629 // -----------------------------------------------------------------------
630 // class ViewTabListBox_Impl ---------------------------------------------
631 // -----------------------------------------------------------------------
633 ViewTabListBox_Impl::ViewTabListBox_Impl( Window
* pParentWin
,
634 SvtFileView_Impl
* pParent
,
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
) ),
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
);
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
);
680 SetEntryHeight( ROW_HEIGHT
);
681 if (nFlags
& FILEVIEW_MULTISELECTION
)
682 SetSelectionMode( MULTIPLE_SELECTION
);
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();
709 // -----------------------------------------------------------------------
711 IMPL_LINK_NOARG(ViewTabListBox_Impl
, ResetQuickSearch_Impl
)
713 ::osl::MutexGuard
aGuard( maMutex
);
715 maQuickSearchText
= "";
721 // -----------------------------------------------------------------------
723 void ViewTabListBox_Impl::Resize()
725 SvTabListBox::Resize();
726 Size aBoxSize
= Control::GetParent()->GetOutputSizePixel();
728 if ( mbResizeDisabled
|| !aBoxSize
.Width() )
734 aBarSize
= mpHeaderBar
->GetSizePixel();
735 aBarSize
.Width() = mbAutoResize
? aBoxSize
.Width() : GetSizePixel().Width();
736 mpHeaderBar
->SetSizePixel( aBarSize
);
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 );
763 else if ( ( rKeyCode
.GetCode() == KEY_DELETE
) &&
766 ResetQuickSearch_Impl( NULL
);
770 else if ( ( rKEvt
.GetKeyCode().GetGroup() == KEYGROUP_NUM
) ||
771 ( rKEvt
.GetKeyCode().GetGroup() == KEYGROUP_ALPHA
) )
773 DoQuickSearch( rKEvt
.GetCharCode() );
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();
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;
820 Reference
< XCommandInfo
> aCommands
= aCnt
.getCommands();
821 if ( aCommands
.is() )
823 = aCommands
->hasCommandByName(
824 OUString( "delete" ) );
826 bEnableDelete
= false;
828 catch( Exception
const & )
830 bEnableDelete
= false;
838 Reference
< XPropertySetInfo
> aProps
= aCnt
.getProperties();
842 = aProps
->getPropertyByName(
843 OUString( "Title" ) );
845 = !( aProp
.Attributes
& PropertyAttribute::READONLY
);
848 bEnableRename
= false;
850 catch( Exception
const & )
852 bEnableRename
= false;
856 pEntry
= ( bEnableDelete
|| bEnableRename
)
857 ? NextSelected( pEntry
)
862 if ( bEnableDelete
|| bEnableRename
)
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
);
875 // -----------------------------------------------------------------------
877 void ViewTabListBox_Impl::ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry
)
879 switch ( nSelectedPopupEntry
)
881 case MID_FILEVIEW_DELETE
:
885 case MID_FILEVIEW_RENAME
:
886 EditEntry( FirstSelected() );
891 // -----------------------------------------------------------------------
893 void ViewTabListBox_Impl::ClearAll()
895 for ( sal_uInt16 i
= 0; i
< GetEntryCount(); ++i
)
896 delete (SvtContentEntry
*)GetEntry(i
)->GetUserData();
900 // -----------------------------------------------------------------------
901 void ViewTabListBox_Impl::DeleteEntries()
903 svtools::QueryDeleteResult_Impl eResult
= svtools::QUERYDELETE_YES
;
904 SvTreeListEntry
* pEntry
= FirstSelected();
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() )
919 bool canDelete
= true;
922 ::ucbhelper::Content
aCnt( aURL
, mxCmdEnv
, comphelper::getProcessComponentContext() );
923 Reference
< XCommandInfo
> aCommands
= aCnt
.getCommands();
924 if ( aCommands
.is() )
926 = aCommands
->hasCommandByName(
927 OUString( "delete" ) );
931 catch( Exception
const & )
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();
952 eResult
= svtools::QUERYDELETE_CANCEL
;
954 sDialogPosition
= aDlg
.GetWindowState( );
957 if ( ( eResult
== svtools::QUERYDELETE_ALL
) ||
958 ( eResult
== svtools::QUERYDELETE_YES
) )
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
;
977 SvtContentEntry
* pData
= (SvtContentEntry
*)pEntry
->GetUserData();
982 if ( aURL
.isEmpty() )
987 OUString
aPropName( "Title" );
988 bool canRename
= true;
989 ::ucbhelper::Content
aContent( aURL
, mxCmdEnv
, comphelper::getProcessComponentContext() );
993 Reference
< XPropertySetInfo
> aProps
= aContent
.getProperties();
996 Property aProp
= aProps
->getPropertyByName( aPropName
);
997 canRename
= !( aProp
.Attributes
& PropertyAttribute::READONLY
);
1004 catch ( Exception
const & )
1012 aValue
<<= rNewText
;
1013 aContent
.setPropertyValue( aPropName
, aValue
);
1014 mpParent
->EntryRenamed( aURL
, rNewText
);
1016 pData
->maURL
= aURL
;
1017 pEntry
->SetUserData( pData
);
1022 catch( Exception
const & )
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
);
1053 SvTreeListEntry
* pEntry
= GetEntry( mnSearchIndex
);
1056 SelectAll( sal_False
);
1058 SetCurEntry( pEntry
);
1059 MakeVisible( pEntry
);
1063 maResetQuickSearch
.Start();
1066 // -----------------------------------------------------------------------
1067 sal_Bool
ViewTabListBox_Impl::DoubleClickHdl()
1069 SvHeaderTabListBox::DoubleClickHdl();
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
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
);
1092 SvtContentEntry
* pData
= (SvtContentEntry
*)pEntry
->GetUserData();
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
);
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" );
1123 catch( Exception
const & )
1125 DBG_WARNING( "Any other exception" );
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;
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
;
1192 // -----------------------------------------------------------------------
1194 OUString
SvtFileView::GetURL( SvTreeListEntry
* pEntry
) const
1197 if ( pEntry
&& pEntry
->GetUserData() )
1198 aURL
= ( (SvtContentEntry
*)pEntry
->GetUserData() )->maURL
;
1202 // -----------------------------------------------------------------------
1204 OUString
SvtFileView::GetCurrentURL() const
1207 SvTreeListEntry
* pEntry
= mpImp
->mpView
->FirstSelected();
1208 if ( pEntry
&& pEntry
->GetUserData() )
1209 aURL
= ( (SvtContentEntry
*)pEntry
->GetUserData() )->maURL
;
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
);
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
);
1248 Reference
< XContent
> xParent( xChild
->getParent(), UNO_QUERY
);
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")
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 );
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
)
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 );
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
);
1334 mpImp
->maViewURL
= sPushURL
;
1338 OSL_ENSURE( pAsyncDescriptor
, "SvtFileView::Initialize: we told it to read synchronously!" );
1343 OSL_FAIL( "SvtFileView::Initialize: unreachable!" );
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
;
1367 mpImp
->CreateVector_Impl( aContents
);
1368 if( GetSortColumn() )
1369 mpImp
->SortFolderContent_Impl();
1371 mpImp
->OpenFolder_Impl();
1373 mpImp
->maOpenDoneLink
.Call( this );
1378 // -----------------------------------------------------------------------
1380 FileViewResult
SvtFileView::ExecuteFilter( const OUString
& rFilter
, const FileViewAsyncAction
* pAsyncDescriptor
)
1382 mpImp
->maCurrentFilter
= rFilter
.toAsciiLowerCase();
1385 FileViewResult eResult
= mpImp
->GetFolderContent_Impl( mpImp
->maViewURL
, pAsyncDescriptor
, mpBlackList
);
1386 OSL_ENSURE( ( eResult
!= eStillRunning
) || pAsyncDescriptor
, "SvtFileView::ExecuteFilter: we told it to read synchronously!" );
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
)
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
);
1526 nBits
&= ~HIB_UPARROW
;
1527 nBits
|= HIB_DOWNARROW
;
1531 nBits
&= ~HIB_DOWNARROW
;
1532 nBits
|= HIB_UPARROW
;
1535 pBar
->SetItemBits( nItemID
, nBits
);
1536 mpImp
->Resort_Impl( nItemID
, !bUp
);
1540 // -----------------------------------------------------------------------
1541 IMPL_LINK( SvtFileView
, HeaderEndDrag_Impl
, HeaderBar
*, pBar
)
1543 if ( !pBar
->IsItemMode() )
1546 sal_uInt16 nTabs
= pBar
->GetItemCount();
1549 for ( sal_uInt16 i
= 1; i
<= nTabs
; ++i
)
1551 long nWidth
= pBar
->GetItemSize(i
);
1552 aSize
.Width() = nWidth
+ nTmpSize
;
1554 mpImp
->mpView
->SetTab( i
, aSize
.Width(), MAP_PIXEL
);
1561 // -----------------------------------------------------------------------
1562 OUString
SvtFileView::GetConfigString() const
1565 HeaderBar
* pBar
= mpImp
->mpView
->GetHeaderBar();
1566 DBG_ASSERT( pBar
, "invalid headerbar" );
1569 sRet
+= OUString::number( mpImp
->mnSortColumn
);
1571 HeaderBarItemBits nBits
= pBar
->GetItemBits( mpImp
->mnSortColumn
);
1572 sal_Bool bUp
= ( ( nBits
& HIB_UPARROW
) == HIB_UPARROW
);
1573 sRet
+= bUp
? OUString("1") : OUString("0");
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
);
1582 sRet
+= OUString::number( pBar
->GetItemSize( nId
) );
1586 sRet
= comphelper::string::stripEnd(sRet
, ';');
1590 // -----------------------------------------------------------------------
1591 void SvtFileView::SetConfigString( const OUString
& rCfgStr
)
1593 HeaderBar
* pBar
= mpImp
->mpView
->GetHeaderBar();
1594 DBG_ASSERT( pBar
, "invalid headerbar" );
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
);
1603 nBits
&= ~HIB_UPARROW
;
1604 nBits
|= HIB_DOWNARROW
;
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
)
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()
1646 void NameTranslator_Impl::SetActualFolder( const INetURLObject
& rActualFolder
)
1648 HashedEntry
aActFolder( rActualFolder
);
1652 if( *mpActFolder
!= aActFolder
)
1655 mpActFolder
= new NameTranslationList( rActualFolder
);
1659 mpActFolder
= new NameTranslationList( rActualFolder
);
1662 sal_Bool
NameTranslator_Impl::GetTranslation( const OUString
& rOrg
, OUString
& rTrans
) const
1664 sal_Bool bRet
= sal_False
;
1668 const OUString
* pTrans
= mpActFolder
->Translate( rOrg
);
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
) )
1706 maAllFilter
= "*.*";
1707 mpView
= new ViewTabListBox_Impl( mpAntiImpl
, this, nFlags
);
1708 mpView
->EnableCellFocus();
1711 // -----------------------------------------------------------------------
1712 SvtFileView_Impl::~SvtFileView_Impl()
1716 // use temp pointer to prevent access of deleted member (GetFocus())
1717 ViewTabListBox_Impl
* pTemp
= mpView
;
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
)
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
) );
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();
1780 m_pContentEnumerator
.clear();
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)
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?" );
1838 return eStillRunning
;
1841 m_bRunningAsyncAction
= false;
1842 switch ( m_eAsyncActionResult
)
1844 case ::svt::SUCCESS
:
1850 case ::svt::RUNNING
:
1851 return eStillRunning
;
1854 SAL_WARN( "svtools.contnr", "SvtFileView_Impl::GetFolderContent_Impl: unreachable!" );
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();
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")
1881 ::osl::MutexGuard
aGuard( maMutex
);
1883 if ( maContent
.empty() )
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
++ == ';' )
1894 // collect the filter tokens
1895 ::std::vector
< WildCard
> aFilters
;
1896 FilterMatch::createWildCardFilterList(rFilter
,aFilters
);
1900 ::std::vector
< SortingData_Impl
* >::iterator aContentLoop
= maContent
.begin();
1901 OUString sCompareString
;
1904 if ( (*aContentLoop
)->mbIsFolder
)
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!
1913 if( bHideTransFile
&& sCompareString
== sHideEntry
)
1917 // search for the first filter which matches
1918 ::std::vector
< WildCard
>::const_iterator pMatchingFilter
=
1922 FilterMatch( sCompareString
)
1925 bDelete
= aFilters
.end() == pMatchingFilter
;
1930 // none of the filters did match
1931 delete (*aContentLoop
);
1933 if ( maContent
.begin() == aContentLoop
)
1935 maContent
.erase( aContentLoop
);
1936 aContentLoop
= maContent
.begin();
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 ....
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();
1977 mpView
->SetCursor( pFirst
, sal_True
);
1980 // -----------------------------------------------------------------------
1981 void SvtFileView_Impl::OpenFolder_Impl()
1983 ::osl::MutexGuard
aGuard( maMutex
);
1985 mpView
->SetUpdateMode( sal_False
);
1988 std::vector
< SortingData_Impl
* >::iterator aIt
;
1990 for ( aIt
= maContent
.begin(); aIt
!= maContent
.end(); ++aIt
)
1992 if ( mbOnlyFolder
&& ! (*aIt
)->mbIsFolder
)
1995 // insert entry and set user data
1996 SvTreeListEntry
* pEntry
= mpView
->InsertEntry( (*aIt
)->maDisplayText
,
2000 SvtContentEntry
* pUserData
= new SvtContentEntry( (*aIt
)->maTargetURL
,
2001 (*aIt
)->mbIsFolder
);
2002 pEntry
->SetUserData( pUserData
);
2007 ++mnSuspendSelectCallback
;
2008 mpView
->SetUpdateMode( sal_True
);
2009 --mnSuspendSelectCallback
;
2014 // -----------------------------------------------------------------------
2015 void SvtFileView_Impl::ResetCursor()
2018 SvTreeListEntry
* pEntry
= mpView
->FirstSelected();
2020 mpView
->Select( pEntry
, sal_False
);
2021 // set cursor to the first entry
2022 mpView
->SetCursor( mpView
->First(), sal_True
);
2026 // -----------------------------------------------------------------------
2027 void SvtFileView_Impl::CancelRunningAsyncAction()
2029 DBG_TESTSOLARMUTEX();
2030 ::osl::MutexGuard
aGuard( maMutex
);
2031 if ( !m_pContentEnumerator
.is() )
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
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
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();
2099 maOpenDoneLink
.Call( mpAntiImpl
);
2102 // -----------------------------------------------------------------------
2103 void SvtFileView_Impl::ReplaceTabWithString( OUString
& aValue
)
2105 OUString
aTab( "\t" );
2106 OUString
aTabString( "%09" );
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
);
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
);
2131 aValue
+= (*aIt
)->maType
;
2133 // folders don't have a size
2134 if ( ! (*aIt
)->mbIsFolder
)
2135 aValue
+= CreateExactSizeText( (*aIt
)->maSize
);
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
);
2144 aValue
+= rLocaleData
.getTime( (*aIt
)->maModDate
);
2146 (*aIt
)->maDisplayText
= aValue
;
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
);
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;
2182 pEntry
->SetNewTitle( aValue
.getToken( 0, '\t', nIndex
) );
2183 aDisplayText
= pEntry
->GetTitle();
2184 ReplaceTabWithString( aDisplayText
);
2185 aDisplayText
+= aTab
;
2190 pEntry
->maType
= aValue
.getToken( 0, '\t', nIndex
);
2191 aDisplayText
+= pEntry
->maType
;
2193 aDisplayText
+= aTab
;
2198 OUString aSize
= aValue
.getToken( 0, '\t', nIndex
);
2199 aDisplayText
+= aSize
;
2201 if ( !aSize
.isEmpty() )
2202 pEntry
->maSize
= aSize
.toInt64();
2204 aDisplayText
+= aTab
;
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
2221 pEntry
->maTargetURL
= aValue
.getToken( 0, '\t', nIndex
);
2226 OUString aBool
= aValue
.getToken( 0, '\t', nIndex
);
2227 if ( !aBool
.isEmpty() )
2228 pEntry
->mbIsFolder
= aBool
.toBoolean();
2230 // get the image url
2233 pEntry
->maImageURL
= aValue
.getToken( 0, '\t', nIndex
);
2236 // set the display text
2237 pEntry
->maDisplayText
= aDisplayText
;
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
) )
2258 // reset the quick search index
2259 mpView
->ResetQuickSearch_Impl( NULL
);
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();
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
;
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!" );
2300 sal_Bool bRet
= sal_False
;
2301 sal_Bool bEqual
= sal_False
;
2303 if ( aOne
->mbIsFolder
!= aTwo
->mbIsFolder
)
2305 if ( aOne
->mbIsFolder
)
2310 // !!! pb: #100376# folder always on top
2319 // compare case insensitive first
2320 nComp
= pCollatorWrapper
->compareString( aOne
->GetLowerTitle(), aTwo
->GetLowerTitle() );
2323 nComp
= pCollatorWrapper
->compareString( aOne
->GetTitle(), aTwo
->GetTitle() );
2327 else if ( nComp
> 0 )
2333 nComp
= pCollatorWrapper
->compareString( aOne
->maType
, aTwo
->maType
);
2336 else if ( nComp
> 0 )
2342 if ( aOne
->maSize
< aTwo
->maSize
)
2344 else if ( aOne
->maSize
> aTwo
->maSize
)
2350 if ( aOne
->maModDate
< aTwo
->maModDate
)
2352 else if ( aOne
->maModDate
> aTwo
->maModDate
)
2358 DBG_WARNING( "CompareSortingData_Impl: Compare unknown type!" );
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 )
2368 return gbAscending
? bRet
: !bRet
;
2371 // -----------------------------------------------------------------------
2372 void SvtFileView_Impl::SortFolderContent_Impl()
2374 ::osl::MutexGuard
aGuard( maMutex
);
2376 sal_uInt32 nSize
= maContent
.size();
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
);
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' );
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
;
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
);
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
);
2454 OUString
aTab( "\t" );
2455 OUString
aDateSep( ", " );
2457 // title, type, size, date
2458 aValue
= pData
->GetTitle();
2459 ReplaceTabWithString( aValue
);
2461 aValue
+= pData
->maType
;
2463 // folders don't have a size
2466 SvtSysLocale aSysLocale
;
2467 const LocaleDataWrapper
& rLocaleData
= aSysLocale
.GetLocaleData();
2468 aValue
+= rLocaleData
.getDate( pData
->maModDate
);
2470 aValue
+= rLocaleData
.getTime( pData
->maModDate
);
2472 pData
->maDisplayText
= aValue
;
2473 maContent
.push_back( pData
);
2478 // -----------------------------------------------------------------------
2479 sal_uLong
SvtFileView_Impl::GetEntryPos( const OUString
& rURL
)
2481 ::osl::MutexGuard
aGuard( maMutex
);
2483 std::vector
< SortingData_Impl
* >::iterator aIt
;
2486 for ( aIt
= maContent
.begin(); aIt
!= maContent
.end(); ++aIt
)
2488 if ( (*aIt
)->maTargetURL
== rURL
)
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 )
2514 while ( nIndex
< nEnd
&& nIndex
<= nStart
)
2516 SortingData_Impl
* pData
= maContent
[ nIndex
];
2517 if ( rTitle
.compareTo( pData
->GetLowerTitle(), rTitle
.getLength() ) == 0 )
2526 // -----------------------------------------------------------------------
2527 void SvtFileView_Impl::SetActualFolder( const INetURLObject
& rActualFolder
)
2529 if( mbReplaceNames
)
2532 mpNameTrans
->SetActualFolder( rActualFolder
);
2534 mpNameTrans
= new NameTranslator_Impl( rActualFolder
);
2540 // -----------------------------------------------------------------------
2541 // QueryDeleteDlg_Impl
2542 // -----------------------------------------------------------------------
2544 QueryDeleteDlg_Impl::QueryDeleteDlg_Impl
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
)
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
);
2599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */