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