|
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 * |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "Layout.h" |
|
21 #include "LayoutCompilerErr.h" |
|
22 #include "CodeGenConsts.h" |
|
23 #include "UsefulDefinitions.h" |
|
24 |
|
25 #include <set> |
|
26 #include <sstream> |
|
27 #include <iostream> |
|
28 |
|
29 // TValues |
|
30 |
|
31 TValues::TValues() |
|
32 : iLine(0), iName("Bad Value") |
|
33 { |
|
34 } |
|
35 |
|
36 TValues::TValues(TLayoutLine* aLine, string aName) |
|
37 : iLine(aLine), iName(aName), iNeedsIndex(0) |
|
38 { |
|
39 } |
|
40 |
|
41 bool TValues::operator==(const TValues& aOther) const |
|
42 { |
|
43 typedef const vector<string> TBase; |
|
44 bool eq = |
|
45 iName == aOther.iName && |
|
46 iParam == aOther.iParam && |
|
47 iNeedsP == aOther.iNeedsP && |
|
48 iNeedsIndex == aOther.iNeedsIndex && |
|
49 (*static_cast<TBase*>(this) == aOther); |
|
50 return eq; |
|
51 } |
|
52 |
|
53 void TValues::Merge(TValues& aValues) |
|
54 { |
|
55 clear(); |
|
56 insert(begin(), aValues.begin(), aValues.end()); |
|
57 } |
|
58 |
|
59 void TValues::Compile() |
|
60 { |
|
61 iNeedsP = false; |
|
62 if (!TLayoutTable::IsValueColumn(iName)) |
|
63 return; |
|
64 |
|
65 for (iterator it = begin(); it != end(); ++it) |
|
66 { |
|
67 bool back2IsAlphaNum = false; |
|
68 bool back1IsAlphaNum = false; |
|
69 bool back1IsP = false; |
|
70 for (string::iterator pC = it->begin(); pC!=it->end(); ++pC) |
|
71 { |
|
72 bool IsAlphaNum = ( |
|
73 ('A' <= *pC && *pC <= 'Z') || |
|
74 ('a' <= *pC && *pC <= 'z') || |
|
75 ('0' <= *pC && *pC <= '9') || |
|
76 *pC == '_'); |
|
77 |
|
78 if (!back2IsAlphaNum && back1IsP && !IsAlphaNum) |
|
79 iNeedsP = true; |
|
80 |
|
81 back1IsP = *pC == 'p'; |
|
82 back2IsAlphaNum = back1IsAlphaNum; |
|
83 back1IsAlphaNum = IsAlphaNum; |
|
84 } |
|
85 |
|
86 if (!back2IsAlphaNum && back1IsP) |
|
87 iNeedsP = true; |
|
88 } |
|
89 iNeedsIndex = (size() > 1); |
|
90 } |
|
91 |
|
92 string TValues::ParamName() const |
|
93 { |
|
94 if (iParam.length()) |
|
95 return iParam; |
|
96 else |
|
97 return KParamNameBase + iName; |
|
98 } |
|
99 |
|
100 string TValues::CppValue(const string& aValue) |
|
101 { |
|
102 if (aValue.size()) |
|
103 return aValue; |
|
104 else |
|
105 return "ELayoutEmpty"; |
|
106 } |
|
107 |
|
108 |
|
109 // TLayoutLine |
|
110 |
|
111 TLayoutLine::TLayoutLine( TLayoutTable* aTable, int aId ) |
|
112 : iTable(aTable), |
|
113 iId(aId), |
|
114 iIsUnique(true), |
|
115 iIsMirroredHorizontally(false), |
|
116 iIsMergedIdentical(false) |
|
117 {} |
|
118 |
|
119 TLayoutLine::TLayoutLine(TLayoutTable* aTable, const TLayoutLine& aOther) |
|
120 { |
|
121 *this = aOther; |
|
122 iTable = aTable; |
|
123 for (iterator pVal = begin(); pVal != end(); ++pVal) |
|
124 { |
|
125 TValues& val = pVal->second; |
|
126 val.iLine = this; |
|
127 } |
|
128 } |
|
129 |
|
130 #ifdef RD_SHOW_ALL_AKNLAYOUTCOMPILER_WARNINGS |
|
131 void TLayoutLine::WarnMergeMismatch(TLayoutLine& aLine) |
|
132 #else |
|
133 void TLayoutLine::WarnMergeMismatch(TLayoutLine& /* aLine */) |
|
134 #endif |
|
135 { |
|
136 // Merge mismatch warnings are not shown from old lay files. |
|
137 #ifdef RD_SHOW_ALL_AKNLAYOUTCOMPILER_WARNINGS |
|
138 string name = Name(); |
|
139 if (name.empty()) |
|
140 name = TableName(); |
|
141 else |
|
142 name = iTable->iName + " | " + name; |
|
143 cerr << "WARNING merge mismatch: " << iTable->iTables->iName << " | " << name; |
|
144 cerr << " vs " << aLine.iTable->iTables->iName << endl; |
|
145 #endif |
|
146 } |
|
147 |
|
148 void TLayoutLine::Merge(TLayout::TMergeMode aMergeMode, TLayoutLine& aLine) |
|
149 { |
|
150 iIsMergedIdentical = (*this == aLine) && (aMergeMode == TLayout::KMergeModeVariant); |
|
151 if (iIsMergedIdentical) |
|
152 return; |
|
153 |
|
154 bool similar = (Name() == aLine.Name()); |
|
155 iterator pVal; |
|
156 |
|
157 if (similar && aMergeMode == TLayout::KMergeModeVariant && aLine.iTable->iTables->iCanBeMirror) |
|
158 { |
|
159 // need to check to see if the parametrisations are mirrored |
|
160 // first check for P |
|
161 bool lr_p = (find("l")->second.iNeedsP && aLine["r"].iNeedsP); |
|
162 bool rl_p = (find("r")->second.iNeedsP && aLine["l"].iNeedsP); |
|
163 |
|
164 // check if they both params are valid |
|
165 bool lr_both = (find("l")->second.iNeedsIndex && aLine["r"].iNeedsIndex); |
|
166 bool rl_both = (find("r")->second.iNeedsIndex && aLine["l"].iNeedsIndex); |
|
167 |
|
168 // check if params are the same |
|
169 bool lr_same = (find("l")->second.iParam == aLine["r"].iParam); |
|
170 bool rl_same = (find("r")->second.iParam == aLine["l"].iParam); |
|
171 |
|
172 // only mirrored if both are valid and same |
|
173 bool lr = lr_p || (lr_both && lr_same); |
|
174 bool rl = rl_p || (rl_both && rl_same); |
|
175 |
|
176 // if either or both are parametrised the same way, need to swap; doesn't matter if |
|
177 // both attribs have same param, as swapping it won't make any difference. |
|
178 if(rl || lr) |
|
179 { |
|
180 iIsMirroredHorizontally = true; |
|
181 } |
|
182 } |
|
183 |
|
184 if (similar) |
|
185 { |
|
186 for (pVal=begin(); pVal!=end(); ++pVal) |
|
187 { |
|
188 TValues& val = pVal->second; |
|
189 string cell = pVal->first; |
|
190 if (iIsMirroredHorizontally) |
|
191 { |
|
192 if (cell == "l") |
|
193 cell = "r"; |
|
194 else if (cell == "r") |
|
195 cell = "l"; |
|
196 } |
|
197 |
|
198 TValues& other = aLine[cell]; |
|
199 if (val.size() != other.size() || |
|
200 val.iNeedsIndex != other.iNeedsIndex || |
|
201 val.iNeedsP != other.iNeedsP) |
|
202 { |
|
203 similar = false; |
|
204 } |
|
205 } |
|
206 } |
|
207 |
|
208 if (!similar) |
|
209 WarnMergeMismatch(aLine); |
|
210 |
|
211 switch(aMergeMode) |
|
212 { |
|
213 case TLayout::KMergeModeMerge: |
|
214 case TLayout::KMergeModeUnion: |
|
215 if (similar) |
|
216 { |
|
217 for (pVal=begin(); pVal!=end(); ++pVal) |
|
218 pVal->second.Merge(aLine[pVal->first]); |
|
219 } |
|
220 else |
|
221 { |
|
222 clear(); |
|
223 copy(aLine.begin(), aLine.end(), inserter(*this, begin())); |
|
224 for (pVal=begin(); pVal!=end(); ++pVal) |
|
225 pVal->second.iLine = this; |
|
226 } |
|
227 break; |
|
228 case TLayout::KMergeModeVariant: |
|
229 clear(); |
|
230 copy(aLine.begin(), aLine.end(), inserter(*this, begin())); |
|
231 for (pVal=begin(); pVal!=end(); ++pVal) |
|
232 pVal->second.iLine = this; |
|
233 break; |
|
234 } |
|
235 } |
|
236 |
|
237 bool TLayoutLine::operator==(const TLayoutLine& aOther) const |
|
238 { |
|
239 return (Name() == aOther.Name()) && ValuesEqual(aOther); |
|
240 } |
|
241 |
|
242 bool TLayoutLine::ValuesEqual(const TLayoutLine& aOther) const |
|
243 { |
|
244 bool eq = true; |
|
245 const_iterator pVal, pOther; |
|
246 for (pVal = begin(), pOther = aOther.begin(); |
|
247 eq && pVal != end() && pOther != aOther.end(); |
|
248 ++pVal, ++pOther) |
|
249 { |
|
250 eq = (*pVal == *pOther); |
|
251 } |
|
252 eq = eq && pVal == end() && pOther == aOther.end(); |
|
253 return eq; |
|
254 } |
|
255 |
|
256 string TLayoutLine::Name() const |
|
257 { |
|
258 if (find("Item") != end()) |
|
259 return find("Item")->second[0]; |
|
260 else |
|
261 return ""; |
|
262 } |
|
263 |
|
264 string TLayoutLine::TableName() const |
|
265 { |
|
266 stringstream name; |
|
267 name << iTable->Name() << "_Line_" << iId; |
|
268 return name.str(); |
|
269 } |
|
270 |
|
271 void TLayoutLine::Compile() |
|
272 { |
|
273 iNeedsP = false; |
|
274 iNeedsIndex = false; |
|
275 |
|
276 for (iterator pVal = begin(); pVal != end(); ++pVal) |
|
277 { |
|
278 TValues& val = pVal->second; |
|
279 val.Compile(); |
|
280 |
|
281 if (val.iNeedsP) |
|
282 iNeedsP = true; |
|
283 if (val.iNeedsIndex) |
|
284 iNeedsIndex = true; |
|
285 } |
|
286 } |
|
287 |
|
288 bool TLayoutLine::MatchParams(const TLayoutLine& aLine) const |
|
289 { |
|
290 if (iNeedsP != aLine.iNeedsP) |
|
291 return false; |
|
292 |
|
293 for (const_iterator pVal = begin(), pOther = aLine.begin(); pVal != end(); ++pVal, ++pOther) |
|
294 { |
|
295 const TValues& val = pVal->second; |
|
296 const TValues& other = pOther->second; |
|
297 if (val.iNeedsIndex != other.iNeedsIndex || val.ParamName() != other.ParamName()) |
|
298 return false; |
|
299 } |
|
300 |
|
301 return true; |
|
302 } |
|
303 |
|
304 |
|
305 // |
|
306 // TLayoutTable |
|
307 // |
|
308 |
|
309 |
|
310 |
|
311 TLayoutTable::TLayoutTable(TLayout* aTables) |
|
312 : iTables(aTables), iType(EUnknownTable), iParent(0), iFirstLineGlobalIndex(-1), iAppend(false), iNoSubTables(false) |
|
313 { |
|
314 } |
|
315 |
|
316 TLayoutTable::TLayoutTable(TLayout* aTables, const TLayoutTable& aOther) |
|
317 : iTables(aTables), iType(aOther.iType), iParent(0), |
|
318 iFirstLineGlobalIndex(aOther.iFirstLineGlobalIndex), |
|
319 iAppend(aOther.iAppend), iColumnNames(aOther.iColumnNames), iName(aOther.iName), |
|
320 iParentName(aOther.iParentName), iNoSubTables(aOther.iNoSubTables) |
|
321 { |
|
322 for (const_iterator it = aOther.begin(); it != aOther.end(); ++it) |
|
323 push_back(new TLayoutLine(this, **it)); |
|
324 } |
|
325 |
|
326 TLayoutTable::~TLayoutTable() |
|
327 { |
|
328 for (iterator it = begin(); it != end(); ++it) |
|
329 delete *it; |
|
330 DestroySubTables(); |
|
331 } |
|
332 |
|
333 void TLayoutTable::Merge(TLayout::TMergeMode aMergeMode, TLayoutTable& aTable) |
|
334 { |
|
335 if (aTable.iAppend) |
|
336 { |
|
337 insert(end(), aTable.begin(), aTable.end()); |
|
338 aTable.clear(); |
|
339 for (iterator pLine = begin(); pLine != end(); ++pLine) |
|
340 (*pLine)->iTable = this; |
|
341 } |
|
342 else |
|
343 { |
|
344 // merge lines |
|
345 iterator pNew = aTable.begin(); |
|
346 switch(aMergeMode) |
|
347 { |
|
348 case TLayout::KMergeModeMerge: |
|
349 { |
|
350 if (size() == aTable.size()) |
|
351 { |
|
352 for (iterator pLine = begin(); pLine != end(); ++pLine) |
|
353 { |
|
354 (*pLine)->Merge(aMergeMode, **pNew); |
|
355 pNew++; |
|
356 } |
|
357 } |
|
358 else |
|
359 { |
|
360 // move the other tables contents to here |
|
361 iterator pLine; |
|
362 for (pLine = begin(); pLine != end(); ++pLine) |
|
363 delete *pLine; |
|
364 clear(); |
|
365 insert(begin(), aTable.begin(), aTable.end()); |
|
366 aTable.clear(); |
|
367 for (pLine = begin(); pLine != end(); ++pLine) |
|
368 (*pLine)->iTable = this; |
|
369 } |
|
370 break; |
|
371 } |
|
372 case TLayout::KMergeModeVariant: |
|
373 { |
|
374 iterator pLine; |
|
375 // need to merge the matching lines but append the extra ones [LMB 11-10-2002] |
|
376 for (pLine = begin(); pLine != end() && pNew != aTable.end(); ++pLine) |
|
377 { |
|
378 (*pLine)->Merge(aMergeMode, **pNew); |
|
379 pNew++; |
|
380 } |
|
381 insert(end(), pNew, aTable.end()); |
|
382 aTable.clear(); |
|
383 for (pLine = begin(); pLine != end(); ++pLine) |
|
384 (*pLine)->iTable = this; |
|
385 break; |
|
386 } |
|
387 case TLayout::KMergeModeUnion: |
|
388 { |
|
389 int index = 0; |
|
390 for (; pNew != aTable.end(); ++pNew) |
|
391 { |
|
392 bool found = false; |
|
393 for (iterator pLine = begin()+index; pLine != end(); ++pLine) |
|
394 { |
|
395 if ((*pLine)->Name() == (*pNew)->Name()) |
|
396 { |
|
397 (*pLine)->Merge(aMergeMode, **pNew); |
|
398 found = true; |
|
399 break; |
|
400 } |
|
401 } |
|
402 if (found) |
|
403 { |
|
404 delete *pNew; |
|
405 } |
|
406 else |
|
407 { |
|
408 if ((*pNew)->Name().empty()) |
|
409 { |
|
410 throw GeneralErr(Name() + " can't union merge unnamed line"); |
|
411 } |
|
412 push_back(*pNew); |
|
413 (*pNew)->iTable = this; |
|
414 if ((*pNew)->iId != size()) |
|
415 iNoSubTables = true; |
|
416 (*pNew)->iId = size(); |
|
417 } |
|
418 if (index+1 < size()) |
|
419 index++; |
|
420 } |
|
421 aTable.clear(); |
|
422 } |
|
423 } |
|
424 } |
|
425 } |
|
426 |
|
427 string TLayoutTable::Name() |
|
428 { |
|
429 return iName; |
|
430 } |
|
431 |
|
432 TLayoutLine* TLayoutTable::FindLine(const string& aName) |
|
433 { |
|
434 for (iterator it = begin(); it != end(); ++it) |
|
435 if ((*it)->Name() == aName) |
|
436 return *it; |
|
437 return 0; |
|
438 } |
|
439 |
|
440 void TLayoutTable::Compile() |
|
441 { |
|
442 if (iType == EUnknownTable && iColumnNames.size() && iColumnNames[0].size()) |
|
443 { |
|
444 if (iColumnNames[0] == "Item") |
|
445 iType = EWindowTable; |
|
446 else |
|
447 iType = ETextTable; |
|
448 } |
|
449 |
|
450 SetDefaultColumnNames(); |
|
451 |
|
452 iParent = iTables->FindLine(iParentName); |
|
453 |
|
454 iNeedsIndex = false; |
|
455 iNeedsP = false; |
|
456 for (iterator it = begin(); it != end(); ++it) |
|
457 { |
|
458 (*it)->Compile(); |
|
459 if ((*it)->iNeedsIndex) |
|
460 iNeedsIndex = true; |
|
461 if ((*it)->iNeedsP) |
|
462 iNeedsP = true; |
|
463 } |
|
464 |
|
465 BuildSubTables(); |
|
466 } |
|
467 |
|
468 void TLayoutTable::BuildSubTables() |
|
469 { |
|
470 DestroySubTables(); |
|
471 |
|
472 if (iNoSubTables) |
|
473 return; |
|
474 |
|
475 int count = size(); |
|
476 TLayoutSubTable* subTable = 0; |
|
477 for (int i=0; i<count; i++) |
|
478 { |
|
479 TLayoutLine& line = *(*this)[i]; |
|
480 if (subTable) |
|
481 { |
|
482 TLayoutLine* firstLine = (*this)[(*subTable)[0]]; |
|
483 if (!firstLine->MatchParams(line)) |
|
484 { |
|
485 if (subTable->size() > 1) |
|
486 iSubTables.push_back(subTable); |
|
487 else |
|
488 delete subTable; |
|
489 subTable = new TLayoutSubTable; |
|
490 } |
|
491 } |
|
492 else |
|
493 { |
|
494 subTable = new TLayoutSubTable; |
|
495 } |
|
496 subTable->iIsMergedIdentical = subTable->iIsMergedIdentical && line.iIsMergedIdentical; |
|
497 subTable->push_back(i); |
|
498 } |
|
499 |
|
500 if (subTable->size() > 1) |
|
501 iSubTables.push_back(subTable); |
|
502 else |
|
503 delete subTable; |
|
504 |
|
505 /* |
|
506 for (int i=0; i<count; i++) |
|
507 { |
|
508 bool inserted = false; |
|
509 TLayoutLine& nextLine = *(*this)[i]; |
|
510 for (TLayoutSubTables::iterator it = iSubTables.begin(); it != iSubTables.end(); ++it) |
|
511 { |
|
512 TLayoutLine* line = (*this)[*((*it)->begin())]; |
|
513 if (line->MatchParams(*(*this)[i])) |
|
514 { |
|
515 TLayoutSubTable& subTab = **it; |
|
516 subTab.push_back(i); |
|
517 subTab.iIsMergedIdentical = subTab.iIsMergedIdentical && nextLine.iIsMergedIdentical; |
|
518 inserted = true; |
|
519 } |
|
520 } |
|
521 |
|
522 if (!inserted) |
|
523 { |
|
524 TLayoutSubTable* subTable = new TLayoutSubTable; |
|
525 subTable->push_back(i); |
|
526 subTable->iIsMergedIdentical = nextLine.iIsMergedIdentical; |
|
527 iSubTables.push_back(subTable); |
|
528 } |
|
529 } |
|
530 |
|
531 TLayoutSubTables::iterator it = iSubTables.begin(); |
|
532 while (it != iSubTables.end()) |
|
533 { |
|
534 if ((*it)->size() == 1) |
|
535 it = iSubTables.erase(it); |
|
536 else |
|
537 ++it; |
|
538 } |
|
539 */ |
|
540 } |
|
541 |
|
542 void TLayoutTable::DestroySubTables() |
|
543 { |
|
544 for (TLayoutSubTables::iterator it = iSubTables.begin(); it != iSubTables.end(); ++it) |
|
545 delete *it; |
|
546 iSubTables.clear(); |
|
547 } |
|
548 |
|
549 const string KValueNames[] = { "Font", "C", "l", "r", "B", "W", "J", "t", "r", "b", "H" }; |
|
550 const set<string> KValueNamesSet(KValueNames, ARRAY_END(KValueNames)); |
|
551 |
|
552 bool TLayoutTable::IsValueColumn(string aName) |
|
553 { |
|
554 return KValueNamesSet.find(aName) != KValueNamesSet.end(); |
|
555 } |
|
556 |
|
557 const string KNumericNames[] = { "C", "l", "r", "B", "W", "t", "r", "b", "H" }; |
|
558 const set<string> KNumericNamesSet(KNumericNames, ARRAY_END(KNumericNames)); |
|
559 |
|
560 bool TLayoutTable::IsNumericColumn(string aName) |
|
561 { |
|
562 return KNumericNamesSet.find(aName) != KNumericNamesSet.end(); |
|
563 } |
|
564 |
|
565 const string KWindowColumnNames[] = {"Item", "C", "l", "t", "r", "b", "W", "H", "Remarks"}; |
|
566 const string KTextColumnNames[] = {"Font", "C", "l", "r", "B", "W", "J", "Remarks"}; |
|
567 |
|
568 void TLayoutTable::SetDefaultColumnNames() |
|
569 { |
|
570 iColumnNames.clear(); |
|
571 if (iType == EWindowTable) |
|
572 { |
|
573 iColumnNames.insert(iColumnNames.end(), KWindowColumnNames, ARRAY_END(KWindowColumnNames)); |
|
574 } |
|
575 else |
|
576 { |
|
577 iColumnNames.insert(iColumnNames.end(), KTextColumnNames, ARRAY_END(KTextColumnNames)); |
|
578 } |
|
579 } |
|
580 |
|
581 bool TLayoutTable::IsWorthATableIndex() |
|
582 { |
|
583 return iSubTables.size() != 0; |
|
584 } |
|
585 |
|
586 |
|
587 TLayoutTable::TLayoutSubTable::TLayoutSubTable() |
|
588 : iIsMergedIdentical(true) |
|
589 { |
|
590 } |
|
591 |
|
592 // |
|
593 // TLayout |
|
594 // |
|
595 |
|
596 TLayout::TLayout() |
|
597 : iCanBeMirror(false) |
|
598 { |
|
599 } |
|
600 |
|
601 TLayout::TLayout(const TLayout& aOther) |
|
602 { |
|
603 *this = aOther; |
|
604 } |
|
605 |
|
606 TLayout& TLayout::operator=(const TLayout& aOther) |
|
607 { |
|
608 if (this != &aOther) |
|
609 { |
|
610 iName = aOther.iName; |
|
611 iCanBeMirror = aOther.iCanBeMirror; |
|
612 for (const_iterator it = aOther.begin(); it != aOther.end(); ++it) |
|
613 push_back(new TLayoutTable(this, **it)); |
|
614 Compile(); |
|
615 } |
|
616 return *this; |
|
617 } |
|
618 |
|
619 TLayout::~TLayout() |
|
620 { |
|
621 for (iterator it = begin(); it != end(); ++it) |
|
622 delete *it; |
|
623 } |
|
624 |
|
625 void TLayout::Merge(TLayout::TMergeMode aMergeMode, TLayout& aLayout) |
|
626 { |
|
627 if (iName.empty()) |
|
628 iName = aLayout.iName; |
|
629 |
|
630 for (iterator pNew = aLayout.begin(); pNew != aLayout.end();) |
|
631 { |
|
632 iterator pTab; |
|
633 for (pTab = begin(); pTab != end(); ++pTab) |
|
634 { |
|
635 if ((*pTab)->Name() == (*pNew)->Name()) |
|
636 break; |
|
637 } |
|
638 |
|
639 if (pTab == end()) |
|
640 { |
|
641 push_back(*pNew); |
|
642 (*pNew)->iTables = this; |
|
643 pNew = aLayout.erase(pNew); |
|
644 } |
|
645 else |
|
646 { |
|
647 (*pTab)->Merge(aMergeMode, **pNew); |
|
648 ++pNew; |
|
649 } |
|
650 } |
|
651 |
|
652 Compile(); |
|
653 } |
|
654 |
|
655 TLayoutLine* TLayout::FindLine(const string& aName) |
|
656 { |
|
657 for (iterator it = begin(); it != end(); ++it) |
|
658 { |
|
659 TLayoutLine* line = (*it)->FindLine(aName); |
|
660 if (line) |
|
661 return line; |
|
662 } |
|
663 |
|
664 return 0; |
|
665 } |
|
666 |
|
667 void TLayout::Compile() |
|
668 { |
|
669 iterator pTab; |
|
670 for (pTab = begin(); pTab != end(); ++pTab) |
|
671 (*pTab)->Compile(); |
|
672 |
|
673 // set uniqueness for lines |
|
674 multiset<string> names; |
|
675 for (pTab = begin(); pTab != end(); ++pTab) |
|
676 { |
|
677 TLayoutTable& tab = **pTab; |
|
678 for (TLayoutTable::iterator pLine = tab.begin(); pLine != tab.end(); ++pLine) |
|
679 names.insert((*pLine)->Name()); |
|
680 } |
|
681 |
|
682 for (pTab = begin(); pTab != end(); ++pTab) |
|
683 { |
|
684 TLayoutTable& tab = **pTab; |
|
685 for (TLayoutTable::iterator pLine = tab.begin(); pLine != tab.end(); ++pLine) |
|
686 { |
|
687 TLayoutLine& line = **pLine; |
|
688 const string& name = line.Name(); |
|
689 if (name[0] == 'q') |
|
690 { |
|
691 line.iIsUnique = false; |
|
692 } |
|
693 else |
|
694 { |
|
695 line.iIsUnique = (names.count(name) == 1); |
|
696 } |
|
697 } |
|
698 } |
|
699 |
|
700 } |
|
701 |
|
702 |
|
703 // End of File |