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