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