|
1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Freestyle tree iterator implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "emailtrace.h" |
|
21 #include <e32const.h> |
|
22 |
|
23 #include "fstreeiterator.h" |
|
24 #include "fstreeitem.h" |
|
25 #include "fstreenode.h" |
|
26 #include "fstreenodevisualizer.h" |
|
27 #include "fstree.h" |
|
28 #include "fsgenericpanic.h" |
|
29 |
|
30 |
|
31 /** Bitmask specifying which flags can be given as parameters. */ |
|
32 const TUint KAllowedParameters = KFsTreeIteratorSkipCollapsedFlag | |
|
33 KFsTreeIteratorSkipHiddenFlag; |
|
34 |
|
35 /** Flag indicating that the next item is stored in the iterator. */ |
|
36 const TUint KNextItemCached = 0x8000; |
|
37 |
|
38 /** Flag indicating that the previous item is stored in the iterator. */ |
|
39 const TUint KPreviousItemCached = 0x4000; |
|
40 |
|
41 |
|
42 // ======== MEMBER FUNCTIONS ======== |
|
43 |
|
44 // --------------------------------------------------------------------------- |
|
45 // Copy constructor. |
|
46 // --------------------------------------------------------------------------- |
|
47 // |
|
48 TFsTreeIterator::TFsTreeIterator( const TFsTreeIterator& aIterator ) |
|
49 : iTree(aIterator.iTree), |
|
50 iCurrent( aIterator.iCurrent ), |
|
51 iRoot( aIterator.iRoot ), |
|
52 iNext( aIterator.iNext ), |
|
53 iPrevious( aIterator.iPrevious ), |
|
54 iFlags( aIterator.iFlags ) |
|
55 { |
|
56 FUNC_LOG; |
|
57 |
|
58 } |
|
59 |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // C++ constructor. |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 TFsTreeIterator::TFsTreeIterator( CFsTreeNode* aRoot, CFsTree* aTree, |
|
66 CFsTreeItem* aCurrent, const TUint aFlags ) |
|
67 : iTree(aTree), |
|
68 iCurrent( aCurrent ), |
|
69 iRoot( aRoot ), |
|
70 iNext( NULL ), |
|
71 iPrevious( NULL ), |
|
72 iFlags( aFlags & KAllowedParameters ) |
|
73 { |
|
74 FUNC_LOG; |
|
75 |
|
76 } |
|
77 |
|
78 // --------------------------------------------------------------------------- |
|
79 // Returns whether the iterator has next tree item. |
|
80 // --------------------------------------------------------------------------- |
|
81 // |
|
82 TBool TFsTreeIterator::HasNext() |
|
83 { |
|
84 FUNC_LOG; |
|
85 return FindNext() ? ETrue : EFalse; |
|
86 } |
|
87 |
|
88 // --------------------------------------------------------------------------- |
|
89 // Returns a pointer to the next tree item. |
|
90 // --------------------------------------------------------------------------- |
|
91 // |
|
92 TFsTreeItemId TFsTreeIterator::Next() |
|
93 { |
|
94 FUNC_LOG; |
|
95 CFsTreeItem* next = FindNext(); |
|
96 |
|
97 iPrevious = iCurrent; |
|
98 iCurrent = next; |
|
99 iFlags = ( iFlags & KAllowedParameters ) | KPreviousItemCached; |
|
100 |
|
101 return iTree->Id(next); |
|
102 } |
|
103 |
|
104 // --------------------------------------------------------------------------- |
|
105 // Returns whether the iterator has previous tree item. |
|
106 // --------------------------------------------------------------------------- |
|
107 // |
|
108 TBool TFsTreeIterator::HasPrevious() |
|
109 { |
|
110 FUNC_LOG; |
|
111 return FindPrevious() ? ETrue : EFalse; |
|
112 } |
|
113 |
|
114 // --------------------------------------------------------------------------- |
|
115 // Returns an id of the previous tree item. |
|
116 // --------------------------------------------------------------------------- |
|
117 // |
|
118 TFsTreeItemId TFsTreeIterator::Previous() |
|
119 { |
|
120 FUNC_LOG; |
|
121 CFsTreeItem* previous = FindPrevious(); |
|
122 |
|
123 iNext = iCurrent; |
|
124 iCurrent = previous; |
|
125 iFlags = ( iFlags & KAllowedParameters ) | KNextItemCached; |
|
126 |
|
127 return iTree->Id( previous ); |
|
128 } |
|
129 |
|
130 // --------------------------------------------------------------------------- |
|
131 // Returns an id of the current tree item. |
|
132 // --------------------------------------------------------------------------- |
|
133 // |
|
134 TFsTreeItemId TFsTreeIterator::Current() const |
|
135 { |
|
136 FUNC_LOG; |
|
137 return iTree->Id(iCurrent); |
|
138 } |
|
139 |
|
140 // --------------------------------------------------------------------------- |
|
141 // Returns a pointer to the first item in the sequence. |
|
142 // --------------------------------------------------------------------------- |
|
143 // |
|
144 TFsTreeItemId TFsTreeIterator::First() |
|
145 { |
|
146 FUNC_LOG; |
|
147 CFsTreeItem* first = NULL; |
|
148 |
|
149 if ( iRoot->CountChildren() > 0 ) |
|
150 { |
|
151 first = iRoot->Child( 0 ); |
|
152 } |
|
153 else |
|
154 { |
|
155 first = iRoot; |
|
156 } |
|
157 |
|
158 return iTree->Id( first ); |
|
159 } |
|
160 |
|
161 // --------------------------------------------------------------------------- |
|
162 // Returns pointer to the las item in the sequence. |
|
163 // --------------------------------------------------------------------------- |
|
164 // |
|
165 TFsTreeItemId TFsTreeIterator::Last() |
|
166 { |
|
167 FUNC_LOG; |
|
168 CFsTreeItem* last = NULL; |
|
169 CFsTreeNode* node = iRoot->Node(); |
|
170 CFsTreeItem* item = iRoot; |
|
171 TInt index = 0; |
|
172 TBool found = EFalse; |
|
173 |
|
174 while (!found && (node!=iRoot->Parent())) |
|
175 { |
|
176 node = item->Node(); |
|
177 |
|
178 while (node && node->CountChildren() && |
|
179 |
|
180 (node->NodeVisualizer()->IsExpanded() || !(iFlags & KFsTreeIteratorSkipCollapsedFlag)) && |
|
181 |
|
182 !(node->ItemVisualizer()->IsHidden() && (iFlags & KFsTreeIteratorSkipHiddenFlag))) |
|
183 { |
|
184 index = node->CountChildren()-1; |
|
185 item = node->Child(index); |
|
186 node = item->Node(); |
|
187 } |
|
188 |
|
189 if (!(item->ItemVisualizer()->IsHidden() && (iFlags & KFsTreeIteratorSkipHiddenFlag)) |
|
190 && (iTree->Id(item)!=KFsTreeRootID) ) |
|
191 |
|
192 { |
|
193 last = item; |
|
194 found = ETrue; |
|
195 } |
|
196 else |
|
197 { |
|
198 node = item->Parent(); |
|
199 if (node) |
|
200 { |
|
201 index = node->Index(item); |
|
202 if (index>0) |
|
203 { |
|
204 item = node->Child(--index); |
|
205 } |
|
206 else |
|
207 { |
|
208 item = node; |
|
209 node = item->Parent(); |
|
210 } |
|
211 } |
|
212 } |
|
213 } |
|
214 |
|
215 return iTree->Id(last); |
|
216 } |
|
217 |
|
218 // --------------------------------------------------------------------------- |
|
219 // Assignment operator. |
|
220 // --------------------------------------------------------------------------- |
|
221 // |
|
222 TFsTreeIterator& TFsTreeIterator::operator=(const TFsTreeIterator& aIterator) |
|
223 { |
|
224 FUNC_LOG; |
|
225 iTree = aIterator.iTree; |
|
226 iCurrent = aIterator.iCurrent; |
|
227 iRoot = aIterator.iRoot; |
|
228 iNext = aIterator.iNext; |
|
229 iPrevious = aIterator.iPrevious; |
|
230 iFlags = aIterator.iFlags; |
|
231 |
|
232 return *this; |
|
233 } |
|
234 |
|
235 // --------------------------------------------------------------------------- |
|
236 // Returns pointer to the next tree item. |
|
237 // --------------------------------------------------------------------------- |
|
238 // |
|
239 CFsTreeItem* TFsTreeIterator::FindNext() |
|
240 { |
|
241 FUNC_LOG; |
|
242 CFsTreeItem* next = NULL; |
|
243 if ( iFlags & KNextItemCached ) |
|
244 { |
|
245 next = iNext; |
|
246 } |
|
247 else |
|
248 { |
|
249 CFsTreeItem* item = iCurrent; |
|
250 CFsTreeNode* node = item->Node(); |
|
251 TBool found = EFalse; |
|
252 TInt index = 0; |
|
253 |
|
254 if (node && node->CountChildren() && |
|
255 |
|
256 (node->NodeVisualizer()->IsExpanded() || !(iFlags & KFsTreeIteratorSkipCollapsedFlag)) && |
|
257 |
|
258 !(node->ItemVisualizer()->IsHidden() && (iFlags & KFsTreeIteratorSkipHiddenFlag))) |
|
259 { |
|
260 index = 0; |
|
261 item = node->Child(index); |
|
262 } |
|
263 else |
|
264 { |
|
265 if (item!=iRoot) |
|
266 { |
|
267 node = item->Parent(); |
|
268 index = node->Index(item) + 1; |
|
269 } |
|
270 else |
|
271 { |
|
272 found = ETrue; |
|
273 } |
|
274 } |
|
275 |
|
276 while (!found && (node!=iRoot->Parent())) |
|
277 { |
|
278 if (index < node->CountChildren()) |
|
279 { |
|
280 item = node->Child(index); |
|
281 if (!(item->ItemVisualizer()->IsHidden() && (iFlags & KFsTreeIteratorSkipHiddenFlag))) |
|
282 { |
|
283 found = ETrue; |
|
284 next = item; |
|
285 } |
|
286 } |
|
287 else |
|
288 { |
|
289 item = node; |
|
290 node = item->Parent(); |
|
291 } |
|
292 |
|
293 if (node) |
|
294 { |
|
295 index = node->Index(item) + 1; |
|
296 } |
|
297 } |
|
298 |
|
299 iNext = next; |
|
300 iFlags |= KNextItemCached; |
|
301 } |
|
302 return next; |
|
303 } |
|
304 |
|
305 // --------------------------------------------------------------------------- |
|
306 // Returns pointer ot the previous tree item. |
|
307 // --------------------------------------------------------------------------- |
|
308 // |
|
309 CFsTreeItem* TFsTreeIterator::FindPrevious() |
|
310 { |
|
311 FUNC_LOG; |
|
312 CFsTreeItem* previous = NULL; |
|
313 if ( iFlags & KPreviousItemCached ) |
|
314 { |
|
315 previous = iPrevious; |
|
316 } |
|
317 else if ( iCurrent ) |
|
318 { |
|
319 CFsTreeItem* item = iCurrent; |
|
320 CFsTreeNode* node = item->Parent(); |
|
321 TInt index = 0; |
|
322 |
|
323 TBool found = EFalse; |
|
324 |
|
325 while (!found && (node!=iRoot->Parent())) |
|
326 { |
|
327 index = node->Index(item); |
|
328 if (index>0) |
|
329 { |
|
330 item = node->Child(--index); |
|
331 node = item->Node(); |
|
332 |
|
333 //previous is a node so dig in deeply |
|
334 while (node && node->CountChildren() && |
|
335 |
|
336 (node->NodeVisualizer()->IsExpanded() || !(iFlags & KFsTreeIteratorSkipCollapsedFlag)) && |
|
337 |
|
338 !(node->ItemVisualizer()->IsHidden() && (iFlags & KFsTreeIteratorSkipHiddenFlag))) |
|
339 { |
|
340 index = node->CountChildren()-1; |
|
341 item = node->Child(index); |
|
342 node = item->Node(); |
|
343 } |
|
344 } |
|
345 else |
|
346 { |
|
347 //index == 0 |
|
348 item = node; |
|
349 node = item->Parent(); |
|
350 } |
|
351 |
|
352 if (!(item->ItemVisualizer()->IsHidden() && (iFlags & KFsTreeIteratorSkipHiddenFlag)) && |
|
353 (iTree->Id(item) != KFsTreeRootID)) |
|
354 { |
|
355 found = ETrue; |
|
356 previous = item; |
|
357 } |
|
358 else |
|
359 { |
|
360 node = item->Parent(); |
|
361 } |
|
362 } |
|
363 |
|
364 iPrevious = previous; |
|
365 iFlags |= KPreviousItemCached; |
|
366 } |
|
367 |
|
368 return previous; |
|
369 } |
|
370 |