|
1 /* |
|
2 * Copyright (c) 2002 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: |
|
15 * View node class |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <DigViewGraph.h> |
|
22 #include <barsc.h> // RResourceFile |
|
23 #include <barsread.h> // TResourceReader |
|
24 #include <e32std.h> |
|
25 |
|
26 |
|
27 /// Unnamed namespace for local definitions |
|
28 namespace { |
|
29 void CleanupResetAndDestroy(TAny* aObj) |
|
30 { |
|
31 if (aObj) |
|
32 { |
|
33 static_cast<CArrayPtrFlat<CDigViewNode>*>(aObj)->ResetAndDestroy(); |
|
34 delete aObj; |
|
35 } |
|
36 } |
|
37 |
|
38 // LOCAL DEBUG CODE |
|
39 #ifdef _DEBUG |
|
40 // MODULE DATA STRUCTURES |
|
41 enum TPanicCode |
|
42 { |
|
43 EPanicPre_MergeNodesL = 1 |
|
44 }; |
|
45 |
|
46 void Panic(TPanicCode aReason) |
|
47 { |
|
48 _LIT(KPanicText, "CDigViewGraph"); |
|
49 User::Panic(KPanicText,aReason); |
|
50 } |
|
51 #endif |
|
52 } |
|
53 |
|
54 // ================= MEMBER FUNCTIONS ======================= |
|
55 |
|
56 |
|
57 // |
|
58 // CDigViewNode |
|
59 // |
|
60 EXPORT_C CDigViewNode::~CDigViewNode() |
|
61 { |
|
62 } |
|
63 |
|
64 EXPORT_C TBool CDigViewNode::FindTransition |
|
65 (const TDigViewTransition& aTransition) const |
|
66 { |
|
67 for (TInt i=0; i < iTransitions.Count(); ++i) |
|
68 { |
|
69 if (iTransitions[i] == aTransition) |
|
70 return ETrue; |
|
71 } |
|
72 return EFalse; |
|
73 } |
|
74 |
|
75 /** |
|
76 * Finds transition based on aEvent, in case not found returns NULL. |
|
77 * |
|
78 * @param aEvent event to be searched |
|
79 */ |
|
80 TDigViewTransition* CDigViewNode::FindTransition(const TInt aEvent) |
|
81 { |
|
82 for (TInt i=0; i < iTransitions.Count(); ++i) |
|
83 { |
|
84 if (iTransitions[i].iEvent == aEvent) |
|
85 return &iTransitions[i]; |
|
86 } |
|
87 return NULL; |
|
88 } |
|
89 |
|
90 /** |
|
91 * Appends or modify existing transition(s). |
|
92 * |
|
93 * @param aNewNode holds transitions to be processed |
|
94 */ |
|
95 void CDigViewNode::MergeL(CDigViewNode& aNewNode) |
|
96 { |
|
97 TInt transCount = aNewNode.iTransitions.Count(); |
|
98 while (transCount-- > 0) |
|
99 { |
|
100 TDigViewTransition newTrans = aNewNode.iTransitions.At(transCount); |
|
101 TDigViewTransition* trans = FindTransition(newTrans.iEvent); |
|
102 if (trans) |
|
103 { |
|
104 trans->iTargetViewId = newTrans.iTargetViewId; |
|
105 } |
|
106 else |
|
107 { |
|
108 // Add new transition |
|
109 iTransitions.AppendL(newTrans); |
|
110 } |
|
111 } |
|
112 iAdditionalResId = aNewNode.iAdditionalResId; |
|
113 } |
|
114 |
|
115 |
|
116 // |
|
117 // CDigViewGraph |
|
118 // |
|
119 EXPORT_C CDigViewGraph* CDigViewGraph::NewL(TResourceReader& aResReader) |
|
120 { |
|
121 CDigViewGraph* self = new(ELeave) CDigViewGraph; |
|
122 CleanupStack::PushL(self); |
|
123 self->ConstructL(aResReader); |
|
124 CleanupStack::Pop(); //self |
|
125 return self; |
|
126 } |
|
127 |
|
128 void CDigViewGraph::ConstructL(TResourceReader& aResReader) |
|
129 { |
|
130 iNodes = CreateUnlinkedNodesFromResourceL(aResReader); |
|
131 LinkNodesWithTransitions(); |
|
132 } |
|
133 |
|
134 EXPORT_C CDigViewGraph::~CDigViewGraph() |
|
135 { |
|
136 if (iNodes) |
|
137 { |
|
138 iNodes->ResetAndDestroy(); |
|
139 } |
|
140 delete iNodes; |
|
141 } |
|
142 |
|
143 EXPORT_C CDigViewNode* CDigViewGraph::FindNodeWithViewId(TUid aViewId) const |
|
144 { |
|
145 if (aViewId != KNullUid) |
|
146 { |
|
147 TInt count = iNodes->Count(); |
|
148 while (count-- > 0) |
|
149 { |
|
150 CDigViewNode* node = iNodes->At(count); |
|
151 if (node->iViewId == aViewId) |
|
152 return node; |
|
153 } |
|
154 } |
|
155 return NULL; |
|
156 } |
|
157 |
|
158 EXPORT_C void CDigViewGraph::ModifyViewGraphL(TResourceReader& aResReader) |
|
159 { |
|
160 CDigViewNodeArray* nodes = CreateUnlinkedNodesFromResourceL(aResReader); |
|
161 // The nodes of the array are not cleaned up by design, only the array |
|
162 // holding them. The node cleanup is handled in MergeNodesL. |
|
163 CleanupStack::PushL(nodes); |
|
164 MergeNodesL(*nodes); // The ownership of the array's nodes is taken here |
|
165 CleanupStack::PopAndDestroy(nodes); |
|
166 |
|
167 LinkNodesWithTransitions(); |
|
168 } |
|
169 |
|
170 /** |
|
171 * Creates a new view node array from resource file. |
|
172 * |
|
173 * @param aResReader containing DIG_VIEW_GRAPH resource |
|
174 */ |
|
175 CDigViewGraph::CDigViewNodeArray* CDigViewGraph:: |
|
176 CreateUnlinkedNodesFromResourceL(TResourceReader& aResReader) |
|
177 { |
|
178 TInt count = aResReader.ReadInt16(); |
|
179 CDigViewNodeArray* nodes = new (ELeave) CDigViewNodeArray(1); |
|
180 CleanupStack::PushL(TCleanupItem(CleanupResetAndDestroy,nodes)); |
|
181 if (count > 1) |
|
182 { |
|
183 nodes->SetReserveL(count); |
|
184 } |
|
185 |
|
186 while (count-- > 0) |
|
187 { |
|
188 CDigViewNode* node = new(ELeave) CDigViewNode; |
|
189 CleanupStack::PushL(node); |
|
190 |
|
191 // DIG_VIEW_NODE |
|
192 node->iViewId.iUid = aResReader.ReadInt32(); |
|
193 node->iDefaultPrevViewId.iUid = aResReader.ReadInt32(); |
|
194 node->iDefaultPreviousNode = NULL; |
|
195 node->iPreviousNode = NULL; |
|
196 node->iExitNode = aResReader.ReadInt8(); |
|
197 |
|
198 TInt transCount = aResReader.ReadInt16(); // transitions[] |
|
199 node->iTransitions.SetReserveL(transCount); |
|
200 while (transCount-- > 0) |
|
201 { |
|
202 // DIG_VIEW_TRANSITION |
|
203 TDigViewTransition trans; |
|
204 trans.iEvent = aResReader.ReadInt32(); |
|
205 trans.iTargetViewId.iUid = aResReader.ReadInt32(); |
|
206 trans.iNode = NULL; |
|
207 node->iTransitions.AppendL(trans); |
|
208 } |
|
209 node->iAdditionalResId = aResReader.ReadInt32(); |
|
210 |
|
211 nodes->AppendL(node); |
|
212 CleanupStack::Pop(); |
|
213 } |
|
214 CleanupStack::Pop(nodes); |
|
215 return nodes; |
|
216 } |
|
217 |
|
218 /** |
|
219 * Links nodes with transitions. |
|
220 */ |
|
221 void CDigViewGraph::LinkNodesWithTransitions() |
|
222 { |
|
223 for (TInt i(0); i < iNodes->Count(); i++) |
|
224 { |
|
225 CDigViewNode* node = iNodes->At(i); |
|
226 node->iDefaultPreviousNode = FindNodeWithViewId |
|
227 (node->iDefaultPrevViewId); |
|
228 TInt transCount = node->iTransitions.Count(); |
|
229 while (transCount-- > 0) |
|
230 { |
|
231 TDigViewTransition& trans = node->iTransitions.At(transCount); |
|
232 trans.iNode = FindNodeWithViewId(trans.iTargetViewId); |
|
233 } |
|
234 } |
|
235 } |
|
236 |
|
237 /** |
|
238 * Merges two node arrays, iNode and aChangedNodes. |
|
239 * Handles also destruction of nodes existing in aChangedNodes. |
|
240 * |
|
241 * @param aChangedNodes array to be merged with iNode |
|
242 */ |
|
243 void CDigViewGraph::MergeNodesL(CDigViewNodeArray& aChangedNodes) |
|
244 { |
|
245 __ASSERT_DEBUG(iNodes != &aChangedNodes, Panic(EPanicPre_MergeNodesL)); |
|
246 |
|
247 for ( TInt j = aChangedNodes.Count()-1; j >= 0; --j ) |
|
248 { |
|
249 // Changed node has to be destroyed if not appended |
|
250 CDigViewNode* changedNode = aChangedNodes.At(j); |
|
251 CDigViewNode* node = FindNodeWithViewId(changedNode->ViewId()); |
|
252 if (node) |
|
253 { |
|
254 // The changedNode is not in cleanupstack yet, |
|
255 // @see CDigViewGraph::ModifyViewGraphL |
|
256 CleanupStack::PushL(changedNode); |
|
257 node->MergeL(*changedNode); |
|
258 aChangedNodes.Delete(j); |
|
259 CleanupStack::PopAndDestroy(changedNode); |
|
260 } |
|
261 else |
|
262 { |
|
263 // The changedNode is not in cleanupstack yet, |
|
264 // @see CDigViewGraph::ModifyViewGraphL |
|
265 CleanupStack::PushL(changedNode); |
|
266 iNodes->AppendL(changedNode); |
|
267 CleanupStack::Pop(changedNode); |
|
268 } |
|
269 } |
|
270 } |
|
271 |
|
272 |
|
273 // End of File |