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