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 : #ifndef INCLUDED_SVTOOLS_TREELIST_HXX
21 : #define INCLUDED_SVTOOLS_TREELIST_HXX
22 :
23 : #include <svtools/svtdllapi.h>
24 : #include <svtools/treelistentries.hxx>
25 : #include <svtools/viewdataentry.hxx>
26 :
27 : #include <tools/solar.h>
28 : #include <tools/link.hxx>
29 : #include <tools/debug.hxx>
30 : #include <tools/contnr.hxx>
31 :
32 : #include <limits.h>
33 : #include <vector>
34 : #include <boost/ptr_container/ptr_map.hpp>
35 :
36 : #define LISTACTION_INSERTED 1
37 : #define LISTACTION_REMOVING 2
38 : #define LISTACTION_REMOVED 3
39 : #define LISTACTION_MOVING 4
40 : #define LISTACTION_MOVED 5
41 : #define LISTACTION_CLEARING 6
42 : #define LISTACTION_INSERTED_TREE 7
43 : #define LISTACTION_INVALIDATE_ENTRY 8
44 : #define LISTACTION_RESORTING 9
45 : #define LISTACTION_RESORTED 10
46 : #define LISTACTION_CLEARED 11
47 :
48 : class SvTreeListEntry;
49 : class SvListView;
50 :
51 : enum SvSortMode { SortAscending, SortDescending, SortNone };
52 :
53 : // For the return values of Sortlink:
54 : // See International::Compare( pLeft, pRight )
55 : // ( Compare(a,b) ==> b.Compare(a) ==> strcmp(a,b) )
56 : struct SvSortData
57 : {
58 : const SvTreeListEntry* pLeft;
59 : const SvTreeListEntry* pRight;
60 : };
61 :
62 : class SVT_DLLPUBLIC SvTreeList
63 : {
64 : typedef std::vector<SvListView*> ListViewsType;
65 :
66 : friend class SvListView;
67 :
68 : ListViewsType aViewList;
69 : sal_uLong nEntryCount;
70 :
71 : Link aCloneLink;
72 : Link aCompareLink;
73 : SvSortMode eSortMode;
74 :
75 : sal_uInt16 nRefCount;
76 :
77 : bool bAbsPositionsValid;
78 :
79 0 : SvTreeListEntry* FirstVisible() const { return First(); }
80 : SvTreeListEntry* NextVisible( const SvListView*,SvTreeListEntry* pEntry, sal_uInt16* pDepth=0 ) const;
81 : SvTreeListEntry* PrevVisible( const SvListView*,SvTreeListEntry* pEntry, sal_uInt16* pDepth=0 ) const;
82 : SvTreeListEntry* LastVisible( const SvListView*,sal_uInt16* pDepth=0 ) const;
83 : SvTreeListEntry* NextVisible( const SvListView*,SvTreeListEntry* pEntry, sal_uInt16& rDelta ) const;
84 : SvTreeListEntry* PrevVisible( const SvListView*,SvTreeListEntry* pEntry, sal_uInt16& rDelta ) const;
85 :
86 : bool IsEntryVisible( const SvListView*,SvTreeListEntry* pEntry ) const;
87 : SvTreeListEntry* GetEntryAtVisPos( const SvListView*,sal_uLong nVisPos ) const;
88 : sal_uLong GetVisiblePos( const SvListView*,SvTreeListEntry* pEntry ) const;
89 : sal_uLong GetVisibleCount( SvListView* ) const;
90 : sal_uLong GetVisibleChildCount( const SvListView*,SvTreeListEntry* pParent ) const;
91 :
92 : SvTreeListEntry* FirstSelected( const SvListView*) const;
93 : SvTreeListEntry* NextSelected( const SvListView*,SvTreeListEntry* pEntry ) const;
94 : SvTreeListEntry* PrevSelected( const SvListView*,SvTreeListEntry* pEntry ) const;
95 : SvTreeListEntry* LastSelected( const SvListView*) const;
96 :
97 : bool Select( SvListView*,SvTreeListEntry* pEntry, bool bSelect=true );
98 : void SelectAll( SvListView*, bool bSelect ); // Does not call Select Handler
99 : sal_uLong GetChildSelectionCount( const SvListView*,SvTreeListEntry* pParent ) const;
100 :
101 : void Expand( SvListView*,SvTreeListEntry* pParent );
102 : void Collapse( SvListView*,SvTreeListEntry* pParent );
103 :
104 : SVT_DLLPRIVATE void SetAbsolutePositions();
105 :
106 : SVT_DLLPRIVATE void CloneChildren(
107 : SvTreeListEntries& rDst, sal_uLong& rCloneCount, SvTreeListEntries& rSrc, SvTreeListEntry* pNewParent) const;
108 :
109 : /**
110 : * Invalidate the cached position data to have them re-generated before
111 : * the next access.
112 : */
113 : SVT_DLLPRIVATE void SetListPositions( SvTreeListEntries& rEntries );
114 :
115 : // rPos is not changed for SortModeNone
116 : SVT_DLLPRIVATE void GetInsertionPos(
117 : SvTreeListEntry* pEntry,
118 : SvTreeListEntry* pParent,
119 : sal_uLong& rPos
120 : );
121 :
122 : SVT_DLLPRIVATE void ResortChildren( SvTreeListEntry* pParent );
123 :
124 : SvTreeList(const SvTreeList&); // disabled
125 : SvTreeList& operator= (const SvTreeList&); // disabled
126 :
127 : protected:
128 : SvTreeListEntry* pRootItem;
129 :
130 : public:
131 :
132 : SvTreeList();
133 : virtual ~SvTreeList();
134 :
135 : void InsertView( SvListView* );
136 : void RemoveView( SvListView* );
137 : sal_uLong GetViewCount() const
138 : { return aViewList.size(); }
139 :
140 0 : SvListView* GetView( sal_uLong nPos ) const
141 0 : { return ( nPos < aViewList.size() ) ? aViewList[ nPos ] : NULL; }
142 :
143 : void Broadcast(
144 : sal_uInt16 nActionId,
145 : SvTreeListEntry* pEntry1=0,
146 : SvTreeListEntry* pEntry2=0,
147 : sal_uLong nPos=0
148 : );
149 :
150 : // Notify all Listeners
151 : void InvalidateEntry( SvTreeListEntry* );
152 :
153 0 : sal_uLong GetEntryCount() const { return nEntryCount; }
154 : SvTreeListEntry* First() const;
155 : SvTreeListEntry* Next( SvTreeListEntry* pEntry, sal_uInt16* pDepth=0 ) const;
156 : SvTreeListEntry* Prev( SvTreeListEntry* pEntry, sal_uInt16* pDepth=0 ) const;
157 : SvTreeListEntry* Last() const;
158 :
159 : SvTreeListEntry* FirstChild( SvTreeListEntry* pParent ) const;
160 : SvTreeListEntry* NextSibling( SvTreeListEntry* pEntry ) const;
161 : SvTreeListEntry* PrevSibling( SvTreeListEntry* pEntry ) const;
162 : SvTreeListEntry* LastSibling( SvTreeListEntry* pEntry ) const;
163 :
164 : sal_uLong Insert( SvTreeListEntry* pEntry,SvTreeListEntry* pPar,sal_uLong nPos = TREELIST_APPEND);
165 0 : sal_uLong Insert( SvTreeListEntry* pEntry,sal_uLong nRootPos = TREELIST_APPEND )
166 0 : { return Insert(pEntry, pRootItem, nRootPos ); }
167 :
168 : void InsertTree( SvTreeListEntry* pTree, SvTreeListEntry* pTargetParent, sal_uLong nListPos );
169 :
170 : // Entries need to be in the same Model!
171 : void Move( SvTreeListEntry* pSource, SvTreeListEntry* pTarget );
172 :
173 : // Creates ChildList if needed
174 : sal_uLong Move( SvTreeListEntry* pSource, SvTreeListEntry* pTargetParent, sal_uLong nListPos);
175 : void Copy( SvTreeListEntry* pSource, SvTreeListEntry* pTarget );
176 : sal_uLong Copy( SvTreeListEntry* pSource, SvTreeListEntry* pTargetParent, sal_uLong nListPos);
177 :
178 : bool Remove( const SvTreeListEntry* pEntry );
179 : void Clear();
180 :
181 : bool HasChildren( const SvTreeListEntry* pEntry ) const;
182 : bool HasParent( const SvTreeListEntry* pEntry ) const;
183 :
184 : bool IsChild(const SvTreeListEntry* pParent, const SvTreeListEntry* pChild) const;
185 : SvTreeListEntry* GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const;
186 : SvTreeListEntry* GetEntry( sal_uLong nRootPos ) const;
187 : SvTreeListEntry* GetEntryAtAbsPos( sal_uLong nAbsPos ) const;
188 :
189 : const SvTreeListEntry* GetParent( const SvTreeListEntry* pEntry ) const;
190 : SvTreeListEntry* GetParent( SvTreeListEntry* pEntry );
191 :
192 : SvTreeListEntry* GetRootLevelParent( SvTreeListEntry* pEntry ) const;
193 : const SvTreeListEntries& GetChildList( SvTreeListEntry* pParent ) const;
194 : SvTreeListEntries& GetChildList( SvTreeListEntry* pParent );
195 :
196 : std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator>
197 : GetChildIterators(SvTreeListEntry* pParent);
198 :
199 : sal_uLong GetAbsPos( const SvTreeListEntry* pEntry ) const;
200 : sal_uLong GetRelPos( const SvTreeListEntry* pChild ) const;
201 :
202 : sal_uLong GetChildCount( const SvTreeListEntry* pParent ) const;
203 : sal_uInt16 GetDepth( const SvTreeListEntry* pEntry ) const;
204 : bool IsAtRootDepth( const SvTreeListEntry* pEntry ) const;
205 :
206 : // The Model calls the Clone Link to clone Entries.
207 : // Thus we do not need to derive from the Model if we derive from SvTreeListEntry.
208 : // Declaration of the Clone Handler:
209 : // DECL_LINK(CloneHdl,SvTreeListEntry*);
210 : // The Handler needs to return a SvTreeListEntry*
211 : SvTreeListEntry* Clone( SvTreeListEntry* pEntry, sal_uLong& nCloneCount ) const;
212 0 : void SetCloneLink( const Link& rLink )
213 0 : { aCloneLink=rLink; }
214 :
215 0 : const Link& GetCloneLink() const
216 0 : { return aCloneLink; }
217 :
218 : virtual SvTreeListEntry* CloneEntry( SvTreeListEntry* pSource ) const; // Calls the Clone Link
219 : virtual SvTreeListEntry* CreateEntry() const; // To create Entries
220 :
221 0 : sal_uInt16 GetRefCount() const { return nRefCount; }
222 0 : void SetRefCount( sal_uInt16 nRef ) { nRefCount = nRef; }
223 :
224 0 : void SetSortMode( SvSortMode eMode ) { eSortMode = eMode; }
225 0 : SvSortMode GetSortMode() const { return eSortMode; }
226 : sal_Int32 Compare(const SvTreeListEntry* pLeft, const SvTreeListEntry* pRight) const;
227 0 : void SetCompareHdl( const Link& rLink ) { aCompareLink = rLink; }
228 : const Link& GetCompareHdl() const { return aCompareLink; }
229 : void Resort();
230 : };
231 :
232 : class SVT_DLLPUBLIC SvListView
233 : {
234 : friend class SvTreeList;
235 :
236 : typedef boost::ptr_map<SvTreeListEntry*, SvViewDataEntry> SvDataTable;
237 :
238 : sal_uLong nVisibleCount;
239 : sal_uLong nSelectionCount;
240 : bool bVisPositionsValid;
241 :
242 : SVT_DLLPRIVATE void InitTable();
243 : SVT_DLLPRIVATE void RemoveViewData( SvTreeListEntry* pParent );
244 :
245 : SvDataTable maDataTable; // Mapping SvTreeListEntry -> ViewData
246 :
247 : void ActionMoving( SvTreeListEntry* pEntry,SvTreeListEntry* pTargetPrnt,sal_uLong nChildPos);
248 : void ActionMoved( SvTreeListEntry* pEntry,SvTreeListEntry* pTargetPrnt,sal_uLong nChildPos);
249 : void ActionInserted( SvTreeListEntry* pEntry );
250 : void ActionInsertedTree( SvTreeListEntry* pEntry );
251 : void ActionRemoving( SvTreeListEntry* pEntry );
252 : void ActionRemoved( SvTreeListEntry* pEntry );
253 : void ActionClear();
254 :
255 : protected:
256 : SvTreeList* pModel;
257 :
258 0 : void ExpandListEntry( SvTreeListEntry* pParent )
259 0 : { pModel->Expand((SvListView*)this,pParent); }
260 :
261 0 : void CollapseListEntry( SvTreeListEntry* pParent )
262 0 : { pModel->Collapse((SvListView*)this,pParent); }
263 :
264 0 : bool SelectListEntry( SvTreeListEntry* pEntry, bool bSelect )
265 0 : { return pModel->Select((SvListView*)this,pEntry,bSelect); }
266 :
267 : public:
268 : SvListView(); // Sets the Model to 0
269 : virtual ~SvListView();
270 : void Clear();
271 : virtual void SetModel( SvTreeList* );
272 : virtual void ModelNotification(
273 : sal_uInt16 nActionId,
274 : SvTreeListEntry* pEntry1,
275 : SvTreeListEntry* pEntry2,
276 : sal_uLong nPos
277 : );
278 :
279 0 : sal_uLong GetVisibleCount() const
280 0 : { return pModel->GetVisibleCount( (SvListView*)this ); }
281 :
282 0 : SvTreeListEntry* FirstVisible() const
283 0 : { return pModel->FirstVisible(); }
284 :
285 0 : SvTreeListEntry* NextVisible( SvTreeListEntry* pEntry, sal_uInt16* pDepth=0 ) const
286 0 : { return pModel->NextVisible(this,pEntry,pDepth); }
287 :
288 0 : SvTreeListEntry* PrevVisible( SvTreeListEntry* pEntry, sal_uInt16* pDepth=0 ) const
289 0 : { return pModel->PrevVisible(this,pEntry,pDepth); }
290 :
291 0 : SvTreeListEntry* LastVisible( sal_uInt16* pDepth=0 ) const
292 0 : { return pModel->LastVisible(this,pDepth); }
293 :
294 0 : SvTreeListEntry* NextVisible( SvTreeListEntry* pEntry, sal_uInt16& rDelta ) const
295 0 : { return pModel->NextVisible(this,pEntry,rDelta); }
296 :
297 0 : SvTreeListEntry* PrevVisible( SvTreeListEntry* pEntry, sal_uInt16& rDelta ) const
298 0 : { return pModel->PrevVisible(this,pEntry,rDelta); }
299 :
300 0 : sal_uLong GetSelectionCount() const
301 0 : { return nSelectionCount; }
302 :
303 0 : SvTreeListEntry* FirstSelected() const
304 0 : { return pModel->FirstSelected(this); }
305 :
306 0 : SvTreeListEntry* NextSelected( SvTreeListEntry* pEntry ) const
307 0 : { return pModel->NextSelected(this,pEntry); }
308 :
309 0 : SvTreeListEntry* PrevSelected( SvTreeListEntry* pEntry ) const
310 0 : { return pModel->PrevSelected(this,pEntry); }
311 :
312 0 : SvTreeListEntry* LastSelected() const
313 0 : { return pModel->LastSelected(this); }
314 0 : SvTreeListEntry* GetEntryAtAbsPos( sal_uLong nAbsPos ) const
315 0 : { return pModel->GetEntryAtAbsPos(nAbsPos); }
316 :
317 0 : SvTreeListEntry* GetEntryAtVisPos( sal_uLong nVisPos ) const
318 0 : { return pModel->GetEntryAtVisPos((SvListView*)this,nVisPos); }
319 :
320 0 : sal_uLong GetAbsPos( SvTreeListEntry* pEntry ) const
321 0 : { return pModel->GetAbsPos(pEntry); }
322 :
323 0 : sal_uLong GetVisiblePos( SvTreeListEntry* pEntry ) const
324 0 : { return pModel->GetVisiblePos((SvListView*)this,pEntry); }
325 :
326 0 : sal_uLong GetVisibleChildCount(SvTreeListEntry* pParent ) const
327 0 : { return pModel->GetVisibleChildCount((SvListView*)this,pParent); }
328 :
329 0 : sal_uLong GetChildSelectionCount( SvTreeListEntry* pParent ) const
330 0 : { return pModel->GetChildSelectionCount((SvListView*)this,pParent); }
331 :
332 : // Does not call the Select Handler
333 0 : virtual void SelectAll( bool bSelect, bool )
334 0 : { pModel->SelectAll((SvListView*)this, bSelect); }
335 :
336 0 : bool IsEntryVisible( SvTreeListEntry* pEntry ) const
337 0 : { return pModel->IsEntryVisible((SvListView*)this,pEntry); }
338 :
339 : bool IsExpanded( SvTreeListEntry* pEntry ) const;
340 : bool IsSelected( SvTreeListEntry* pEntry ) const;
341 : void SetEntryFocus( SvTreeListEntry* pEntry, bool bFocus );
342 : const SvViewDataEntry* GetViewData( const SvTreeListEntry* pEntry ) const;
343 : SvViewDataEntry* GetViewData( SvTreeListEntry* pEntry );
344 0 : bool HasViewData() const
345 0 : { return maDataTable.size() > 1; } // There's always a ROOT
346 :
347 : virtual SvViewDataEntry* CreateViewData( SvTreeListEntry* pEntry );
348 : virtual void InitViewData( SvViewDataEntry*, SvTreeListEntry* pEntry );
349 :
350 : virtual void ModelHasCleared();
351 : virtual void ModelHasInserted( SvTreeListEntry* pEntry );
352 : virtual void ModelHasInsertedTree( SvTreeListEntry* pEntry );
353 : virtual void ModelIsMoving(
354 : SvTreeListEntry* pSource,
355 : SvTreeListEntry* pTargetParent,
356 : sal_uLong nPos
357 : );
358 : virtual void ModelHasMoved( SvTreeListEntry* pSource );
359 : virtual void ModelIsRemoving( SvTreeListEntry* pEntry );
360 : virtual void ModelHasRemoved( SvTreeListEntry* pEntry );
361 : virtual void ModelHasEntryInvalidated( SvTreeListEntry* pEntry );
362 : };
363 :
364 : #endif
365 :
366 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|