|
1 /* |
|
2 * Copyright (c) 2006-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: DT iterator. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 //#include "xndomlist.h" |
|
22 #include "xnnodeappif.h" |
|
23 |
|
24 #include "pmodtiterator.h" |
|
25 |
|
26 // ============================ LOCAL FUNCTIONS =============================== |
|
27 |
|
28 // ----------------------------------------------------------------------------- |
|
29 // Finds next sibling. |
|
30 // Returns NULL if there is no siblings left or there is no parent i.e this is a |
|
31 // root node |
|
32 // Returns: CXnDomNode* Pointer to the node or NULL |
|
33 // |
|
34 // ----------------------------------------------------------------------------- |
|
35 // |
|
36 |
|
37 static CXnNodeAppIf* NextSiblingL( CXnNodeAppIf& aNode ) |
|
38 { |
|
39 CXnNodeAppIf* left( NULL ); |
|
40 CXnNodeAppIf* parent( NULL ); |
|
41 TRAP_IGNORE( parent = aNode.ParentL() ); |
|
42 if ( parent ) |
|
43 { |
|
44 RPointerArray<CXnNodeAppIf> nodeList; |
|
45 TRAP_IGNORE( nodeList = parent->ChildrenL() ); |
|
46 CleanupClosePushL( nodeList ); |
|
47 TInt currentIndex( nodeList.Find( &aNode ) ); |
|
48 TInt nextIndex( ++currentIndex ); |
|
49 TInt length( nodeList.Count() ); |
|
50 if ( nextIndex < length ) |
|
51 { |
|
52 left = nodeList[ nextIndex ]; |
|
53 } |
|
54 CleanupStack::PopAndDestroy( &nodeList ); |
|
55 } |
|
56 return left; |
|
57 } |
|
58 |
|
59 |
|
60 // ============================ MEMBER FUNCTIONS =============================== |
|
61 |
|
62 // ----------------------------------------------------------------------------- |
|
63 // C++ default constructor can NOT contain any code, that |
|
64 // might leave. |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 CPmODTIterator::CPmODTIterator( CXnNodeAppIf& aRootNode ): |
|
68 iFirst(&aRootNode), iCurrent(&aRootNode) |
|
69 { |
|
70 } |
|
71 |
|
72 // ----------------------------------------------------------------------------- |
|
73 // ConstructL |
|
74 // ----------------------------------------------------------------------------- |
|
75 // |
|
76 void CPmODTIterator::ConstructL() |
|
77 { |
|
78 } |
|
79 |
|
80 // ----------------------------------------------------------------------------- |
|
81 // NewL |
|
82 // ----------------------------------------------------------------------------- |
|
83 // |
|
84 CPmODTIterator* CPmODTIterator::NewL( CXnNodeAppIf& aRootNode ) |
|
85 { |
|
86 CPmODTIterator* self = new( ELeave ) CPmODTIterator( aRootNode ); |
|
87 |
|
88 CleanupStack::PushL( self ); |
|
89 self->ConstructL(); |
|
90 CleanupStack::Pop( self ); |
|
91 |
|
92 return self; |
|
93 } |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // Destructor |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 CPmODTIterator::~CPmODTIterator() |
|
100 { |
|
101 iDepthLevel.Close(); |
|
102 } |
|
103 |
|
104 // ----------------------------------------------------------------------------- |
|
105 // First node |
|
106 // ----------------------------------------------------------------------------- |
|
107 // |
|
108 CXnNodeAppIf* CPmODTIterator::First() |
|
109 { |
|
110 return iFirst; |
|
111 } |
|
112 |
|
113 // ----------------------------------------------------------------------------- |
|
114 // Next node |
|
115 // ----------------------------------------------------------------------------- |
|
116 // |
|
117 CXnNodeAppIf* CPmODTIterator::NextL() |
|
118 { |
|
119 CXnNodeAppIf* firstChild( NULL ); |
|
120 |
|
121 //Initialise iCurrent if the whole tree has been walked through |
|
122 if (!iCurrent) |
|
123 { |
|
124 iCurrent = iFirst; |
|
125 } |
|
126 RPointerArray<CXnNodeAppIf> children = iCurrent->ChildrenL(); |
|
127 if( children.Count() > 0 ) |
|
128 { |
|
129 firstChild = children[0]; |
|
130 } |
|
131 children.Close(); |
|
132 |
|
133 // Current node has childs left |
|
134 if (firstChild) |
|
135 { |
|
136 //Keep count of depth level |
|
137 PushL( *iCurrent ); |
|
138 iCurrent = firstChild; |
|
139 } |
|
140 else //If current node has siblings left |
|
141 { |
|
142 SkipBranchL(); |
|
143 } |
|
144 return iCurrent; |
|
145 } |
|
146 |
|
147 // ----------------------------------------------------------------------------- |
|
148 // SkipBranch |
|
149 // ----------------------------------------------------------------------------- |
|
150 // |
|
151 CXnNodeAppIf* CPmODTIterator::SkipBranchL() |
|
152 { |
|
153 CXnNodeAppIf* sibling = NextSiblingL(*iCurrent); |
|
154 if(sibling) |
|
155 { |
|
156 iCurrent = sibling; |
|
157 } |
|
158 else //Current node don't have any childs or siblings left |
|
159 { |
|
160 // Reverse the tree by moving up in hierarchy |
|
161 // Move up one level in hierarchy and check if siblings exists or we are in a |
|
162 // root level |
|
163 TBool stop( EFalse ); |
|
164 while( !stop && iDepthLevel.Count() ) |
|
165 { |
|
166 iCurrent = Pop(); //Reach the previous level |
|
167 sibling = NextSiblingL( *iCurrent ); //Check if siblings exist |
|
168 if ( sibling && iDepthLevel.Count() ) |
|
169 { |
|
170 iCurrent = sibling; |
|
171 stop = ETrue; |
|
172 } |
|
173 else //We didn't find any siblings |
|
174 { |
|
175 iCurrent = NULL; |
|
176 } |
|
177 } |
|
178 } |
|
179 return iCurrent; |
|
180 } |
|
181 |
|
182 // ----------------------------------------------------------------------------- |
|
183 // Push node into stack. |
|
184 // ----------------------------------------------------------------------------- |
|
185 // |
|
186 void CPmODTIterator::PushL( CXnNodeAppIf& aNode ) |
|
187 { |
|
188 iDepthLevel.AppendL( &aNode ); |
|
189 } |
|
190 |
|
191 // ----------------------------------------------------------------------------- |
|
192 // Pop node from stack. |
|
193 // ----------------------------------------------------------------------------- |
|
194 // |
|
195 CXnNodeAppIf* CPmODTIterator::Pop() |
|
196 { |
|
197 CXnNodeAppIf* pop = NULL; |
|
198 TInt count( iDepthLevel.Count() ); |
|
199 if ( count ) |
|
200 { |
|
201 pop = iDepthLevel[ count-1 ]; |
|
202 iDepthLevel.Remove( count-1 ); |
|
203 } |
|
204 return pop; |
|
205 } |