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