--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/aknlayoutcompiler/src/MLEqCompData.cpp Thu Dec 17 09:14:18 2009 +0200
@@ -0,0 +1,1134 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*
+*/
+
+
+#include "MLEqCompData.h"
+#include "MLEqCompDataParse.h"
+#include "MLEqCompData2DHuiML.h"
+#include "MLAttributes.h"
+#include "FormulaTree.h"
+
+#include "LayoutCompilerErr.h"
+#include "CodeGenConsts.h"
+#include "UsefulDefinitions.h"
+
+#include "Akndef.hrh"
+
+#include <set>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+
+//
+// const data
+//
+
+
+
+const string KEqCompDataKeywordParamLeft = "l";
+const string KEqCompDataKeywordParamTop = "t";
+const string KEqCompDataKeywordParamRight = "r";
+const string KEqCompDataKeywordParamBottom = "b";
+const string KEqCompDataKeywordParamWidth = "w";
+const string KEqCompDataKeywordParamHeight = "h";
+
+const string KEqCompDataPaneOutputOrder[] =
+ {
+ KEqCompDataKeywordParamLeft,
+ KEqCompDataKeywordParamTop,
+ KEqCompDataKeywordParamRight,
+ KEqCompDataKeywordParamBottom,
+ KEqCompDataKeywordParamWidth,
+ KEqCompDataKeywordParamHeight
+ };
+
+const int KEqCompDataPaneOutputOrderSize = ARRAY_LEN(KEqCompDataPaneOutputOrder);
+
+
+const string KEqCompDataKeywordParamType = "Type";
+const string KEqCompDataKeywordParamFont = "Font";
+const string KEqCompDataKeywordParamNumCols = "NumCols";
+const string KEqCompDataKeywordParamNumRows = "NumRows";
+const string KEqCompDataKeywordScreenContents = "Screen Contents";
+
+const string KEqCompDataKeywordUnderscore = "_";
+const string KEqCompDataKeywordLineNameSuffixGraphic = "g";
+const string KEqCompDataKeywordLineNameSuffixText = "t";
+
+const string KEqCompDataSearchCollectionNumeric = "0123456789";
+const string KEqCompDataBadValue = "Bad Value";
+const string KEqCompDataLayoutEmpty = "ELayoutEmpty";
+const string KEqCompDataUnknown = "unknown";
+
+const string KEqCompDataCellNameLeft("l");
+const string KEqCompDataCellNameRight("r");
+const string KEqCompDataCellNameJustification("J");
+
+const string KAttributeNameStyle1 = "style_1";
+const string KAttributeNameStyle1Plain = "plain";
+const string KAttributeNameStyle1Bold = "bold";
+
+const string KAttributeNameNumberOfColumns = "Number_of_columns";
+const string KAttributeNameNumberOfRows = "Number_of_rows";
+const string KAttributeNameNumberOfRowsColsAuto = "AUTO";
+
+//
+// struct TMLEqCompDataFormula
+//
+TMLEqCompDataFormula::TMLEqCompDataFormula()
+ :
+ iFormulaString(),
+ iZoomId(0),
+ iFormulaTree(NULL)
+ {
+
+ }
+
+TMLEqCompDataFormula::TMLEqCompDataFormula(const TMLEqCompDataFormula& aOther)
+ :
+ iFormulaString(aOther.iFormulaString),
+ iZoomId(aOther.iZoomId),
+ iFormulaTree(aOther.iFormulaTree)
+ {
+ int x = 0;
+ }
+
+const TMLEqCompDataFormula& TMLEqCompDataFormula::operator=(const TMLEqCompDataFormula& aOther)
+ {
+ if(this == &aOther)
+ return aOther;
+
+ iFormulaString = aOther.iFormulaString;
+ iZoomId = aOther.iZoomId;
+
+ if(iFormulaTree)
+ {
+ delete iFormulaTree;
+ iFormulaTree = 0;
+ }
+ iFormulaTree = aOther.iFormulaTree;
+ return *this;
+ }
+
+TMLEqCompDataFormula::TMLEqCompDataFormula(string aFormulaString)
+ :
+ iFormulaString(aFormulaString),
+ iZoomId(0),
+ iFormulaTree(NULL)
+ {
+
+ }
+
+TMLEqCompDataFormula::~TMLEqCompDataFormula()
+ {
+ delete iFormulaTree;
+ iFormulaTree = 0;
+ }
+
+
+bool TMLEqCompDataFormula::operator==(const TMLEqCompDataFormula& aOther) const
+ {
+ return (iFormulaString == aOther.iFormulaString && iZoomId == aOther.iZoomId);
+ }
+
+void TMLEqCompDataFormula::Compile()
+ {
+ if(!iFormulaTree)
+ {
+ iFormulaTree = FormulaTreeNode::Parse(iFormulaString);
+ }
+ else
+ {
+ throw GeneralErr(string("TMLEqCompDataFormula::Compile - formula already parsed."));
+ }
+ }
+
+//
+// TMLEqCompDataValuesOptionSet
+//
+void TMLEqCompDataValuesOptionSet::Compile()
+ {
+ for(iterator pFormula = begin(); pFormula != end(); ++pFormula)
+ {
+ pFormula->Compile();
+ }
+ }
+
+
+//
+// TMLEqCompDataValues
+//
+
+TMLEqCompDataValues::TMLEqCompDataValues()
+ :
+ iLine(NULL),
+ iName(KEqCompDataBadValue)
+ {
+ }
+
+TMLEqCompDataValues::TMLEqCompDataValues(TMLEqCompDataLine* aLine)
+ :
+ iLine(aLine),
+ iName(aLine->iName)
+ {
+ }
+
+bool TMLEqCompDataValues::operator==(const TMLEqCompDataValues& aOther) const
+ {
+ typedef const vector<TMLEqCompDataFormula> TBase;
+ bool eq =
+ iName == aOther.iName &&
+ (*static_cast<TBase*>(this) == aOther);
+ return eq;
+ }
+
+TMLEqCompDataValues::~TMLEqCompDataValues()
+ {
+ }
+
+bool TMLEqCompDataValues::Merge(TMLEqCompDataLine* aLine, string aName, TMLEqCompDataValues& aOtherValues, bool aMirrorMerge)
+ {
+/*
+ iLine = aLine;
+ iName = aName; // we may be swapping l and r
+
+ // create missing values in this line if needed
+ for (iterator pOtherVal=aOtherValues.begin(); pOtherVal!=aOtherValues.end(); ++pOtherVal)
+ {
+ TMLEqCompDataZoomLevels& otherZoomLevels = pOtherVal->second;
+ TMLEqCompDataZoomLevels& thisZoomLevels = (*this)[pOtherVal->first];
+ thisZoomLevels = otherZoomLevels; // we want exactly the correct number of calcs from the other cell
+ if(aMirrorMerge)
+ {
+ if(iName == KEqCompDataCellNameJustification)
+ {
+ // reverse the justification
+ for(TMLEqCompDataZoomLevels::iterator pCalcs = thisZoomLevels.begin(); pCalcs != thisZoomLevels.end(); ++pCalcs)
+ {
+ TMLEqCompDataCalcs& calcs = pCalcs->second;
+ for(TMLEqCompDataCalcs::iterator pVal = calcs.begin(); pVal != calcs.end(); ++pVal)
+ pVal->second = MirrorJustificationValue(pVal->second);
+ }
+ }
+ }
+ }
+*/
+ return true;
+ }
+
+
+const string KParamLimitNames[] = { "NumCols", "NumRows" };
+const string KHorizNames[] = { "l", "r", "W" };
+const string KVertNames[] = { "t", "b", "H", "Font" };
+const set<string> KParamLimitNamesSet(KParamLimitNames, ARRAY_END(KParamLimitNames));
+const set<string> KHorizNamesSet(KHorizNames, ARRAY_END(KHorizNames));
+const set<string> KVertNamesSet(KVertNames, ARRAY_END(KVertNames));
+
+string TMLEqCompDataValues::MirrorJustificationValue(const string& aValue)
+ {
+ int val = CdlTkUtil::ParseInt(aValue);
+ if(val == ELayoutAlignLeft)
+ val = ELayoutAlignRight;
+ else if(val == ELayoutAlignRight)
+ val = ELayoutAlignLeft;
+ return CdlTkUtil::IntToString(val);
+ }
+
+
+void TMLEqCompDataValues::Compile(int aOptionSetId)
+ {
+ TMLEqCompDataValuesOptionSet& set = iOptionSets[aOptionSetId];
+ set.Compile();
+ }
+
+string TMLEqCompDataValues::CppValue(const string& aValue)
+ {
+ if (aValue.size())
+ return aValue;
+ else
+ return KEqCompDataLayoutEmpty;
+ }
+
+//
+// TMLEqCompDataParentInfoSelector
+//
+TMLEqCompDataParentInfoSelector::TMLEqCompDataParentInfoSelector()
+ {
+
+ }
+
+TMLEqCompDataParentInfoSelector::TMLEqCompDataParentInfoSelector(int aParentId, int aParentVariety)
+ :
+ iParentId(aParentId),
+ iParentVariety(aParentVariety)
+ {
+
+ }
+
+//
+// TMLEqCompDataParentInfo
+//
+
+TMLEqCompDataParentInfo::TMLEqCompDataParentInfo()
+ :
+ iLine(0)
+ {
+
+ }
+
+TMLEqCompDataParentInfo::TMLEqCompDataParentInfo(TMLEqCompDataLine* aLine)
+ :
+ iLine(aLine)
+ {
+
+ }
+
+TMLEqCompDataParentInfo::~TMLEqCompDataParentInfo()
+ {
+
+ }
+
+void TMLEqCompDataParentInfo::Merge(const TMLEqCompDataParentInfo& aOther)
+ {
+/*
+ for (const_iterator pOtherVariety = aOther.begin(); pOtherVariety != aOther.end(); ++pOtherVariety)
+ {
+ int varietyIndex = pOtherVariety->first;
+ const TMLEqCompDataParentInfoSelector& selector = pOtherVariety->second;
+ insert(make_pair(varietyIndex, selector));
+ }
+*/
+ }
+
+//
+// TMLEqCompDataLine
+//
+
+TMLEqCompDataLine::TMLEqCompDataLine()
+: iId(0),
+ iIsUnique(true),
+ iIsMirroredHorizontally(false),
+ iType(EUnknownComponent),
+ iName(KEqCompDataUnknown),
+ iDrawingOrder(-1),
+ iParentTable(0),
+ iParentInfo(0),
+// iAttributeInfo(0),
+ iNumCols(1),
+ iNumRows(1),
+ iGlobalIndex(0)
+ {
+
+ }
+
+TMLEqCompDataLine::TMLEqCompDataLine(const TMLEqCompDataLine& aOther)
+ {
+ if(this == &aOther)
+ return;
+
+/*
+ *this = aOther; // this will take a copy of the owning pointer
+ if(aOther.iParentInfo) // if it wasn't zero
+ iParentInfo = new TMLEqCompDataParentInfo(*(aOther.iParentInfo)); // we don't want to take ownership, so make our own copy
+ if(aOther.iAttributeInfo) // if it wasn't zero
+ iAttributeInfo = new TMLEqCompDataAttributeInfo(*(aOther.iAttributeInfo)); // we don't want to take ownership, so make our own copy
+*/
+ for (iterator pVal = begin(); pVal != end(); ++pVal)
+ {
+ TMLEqCompDataValues& val = pVal->second;
+ val.iLine = this;
+ }
+ iParentTable = 0; // will be set during compile
+ }
+
+bool TMLEqCompDataLine::operator==(const TMLEqCompDataLine& aOther) const
+ {
+ return (Name() == aOther.Name()) && ValuesEqual(aOther);
+ }
+
+TMLEqCompDataLine::~TMLEqCompDataLine()
+ {
+/*
+ delete iParentInfo;
+ delete iAttributeInfo;
+*/
+ }
+
+bool TMLEqCompDataLine::lessthan(TMLEqCompDataLine* aLeft, TMLEqCompDataLine* aRight)
+ {
+ string pureNameLeft = aLeft->NameDiscountingSuffix();
+ string pureNameRight = aRight->NameDiscountingSuffix();
+ if(pureNameLeft != pureNameRight)
+ {
+ return (aLeft->iName) < (aRight->iName);
+ }
+ else
+ {
+ int left = CdlTkUtil::ParseInt(aLeft->NameSuffix());
+ int right = CdlTkUtil::ParseInt(aRight->NameSuffix());
+ return left < right;
+ }
+ }
+
+bool TMLEqCompDataLine::ValuesEqual(const TMLEqCompDataLine& aOther) const
+ {
+ bool eq = true;
+ const_iterator pVal, pOther;
+ for (pVal = begin(), pOther = aOther.begin();
+ eq && pVal != end() && pOther != aOther.end();
+ ++pVal, ++pOther)
+ {
+ eq = (*pVal == *pOther);
+ }
+ eq = eq && pVal == end() && pOther == aOther.end();
+ return eq;
+ }
+
+string TMLEqCompDataLine::Name() const
+ {
+ return iName;
+ }
+
+bool TMLEqCompDataLine::Merge(TMLEqCompDataLine& aOtherLine)
+ {
+/*
+ bool compatible =
+ (iId == aOtherLine.iId) ||
+ (iName == aOtherLine.iName) ||
+ (iType == aOtherLine.iType);
+ if(compatible)
+ {
+ iDrawingOrder = aOtherLine.iDrawingOrder;
+ iMaxVariety = aOtherLine.iMaxVariety;
+ iIsMirroredHorizontally |= aOtherLine.iIsMirroredHorizontally; // in the case of an elaf layout merging onto an abrw layout, the chirality will be preserved
+ iNeedsOptions |= aOtherLine.iNeedsOptions;
+
+ if(!iParentInfo)
+ {
+ // must be screen...
+ iParentInfo = new TMLEqCompDataParentInfo();
+ }
+ if(aOtherLine.iParentInfo)
+ {
+ iParentInfo->Merge(*(aOtherLine.iParentInfo));
+ }
+
+ if(!iAttributeInfo)
+ {
+ // must be screen...
+ iAttributeInfo = new TMLEqCompDataAttributeInfo();
+ }
+ if(aOtherLine.iAttributeInfo)
+ {
+ iAttributeInfo->Merge(*(aOtherLine.iAttributeInfo));
+ }
+
+ // for the API, we need to know if there are any multi-value components in either orientation
+ iNeedsCols = iNeedsCols || aOtherLine.iNeedsCols;
+ iNeedsRows = iNeedsRows || aOtherLine.iNeedsRows;
+ // however, we want exactly the correct number of calcs from the other cell
+ iNumCols = aOtherLine.iNumCols;
+ iNumRows = aOtherLine.iNumRows;
+
+ // if this line has no values, then we must do a mirror merge
+ bool mirrorMerge = empty() && iIsMirroredHorizontally;
+
+ // create missing values in this line if needed
+ for (TMLEqCompDataLine::iterator pOtherValues=aOtherLine.begin(); pOtherValues!=aOtherLine.end(); ++pOtherValues)
+ {
+ string index = pOtherValues->first;
+ if(mirrorMerge)
+ {
+ // flip left and right
+ if(index == KEqCompDataCellNameLeft)
+ index = KEqCompDataCellNameRight;
+ else if(index == KEqCompDataCellNameRight)
+ index = KEqCompDataCellNameLeft;
+ }
+
+ (*this)[index].Merge(this, index, pOtherValues->second, mirrorMerge);
+ }
+ }
+ return compatible;
+ */
+ return false;
+ }
+
+TMLAttributeZoomLevels* TMLEqCompDataLine::GetAttributeZoomLevels(string aAttribName, int aVariety)
+ {
+/*
+ TMLAttributeZoomLevels* found = 0;
+ TMLEqCompData& data = *(iParentTable->iTables);
+ TMLAttributes& attributes = *(data.iAttributes);
+ int attribId = attributes.iNames[aAttribName];
+ if(attribId == 0)
+ throw GeneralErr(string("Attribute name not found: ") + aAttribName);
+ // find out from attribute info which attribute set we need
+ // but if there is none specified, we don't need to search
+ if(iAttributeInfo)
+ {
+ TMLEqCompDataAttributeInfoSelector& selector = (*iAttributeInfo)[aVariety];
+ // go to parent straight away, as parent always stores attribute data for its children
+ found = GetParentAttributeZoomLevels(selector.iAttributeSetName, attribId, aVariety);
+ }
+ return found;
+*/
+ return NULL;
+ }
+
+TMLAttributeZoomLevels* TMLEqCompDataLine::GetParentAttributeZoomLevels(string aAttribSetName, int aAttribId, int aVariety)
+ {
+ TMLAttributeZoomLevels* found = NULL;
+ TMLEqCompDataParentInfo::iterator pFoundSelector = iParentInfo->find(aVariety);
+ if(pFoundSelector != iParentInfo->end())
+ {
+ const TMLEqCompDataParentInfoSelector& parentInfoSelector = pFoundSelector->second;
+ if(iParentTable && iParentTable->iParentLine)
+ {
+ found = iParentTable->iParentLine->FindAttributeZoomLevels(aAttribSetName, aAttribId);
+ if(!found)
+ {
+ // recurse to next parent container
+ int variety = parentInfoSelector.iParentVariety;
+ iParentTable->iParentLine->GetParentAttributeZoomLevels(aAttribSetName, aAttribId, variety);
+ }
+ }
+ }
+ return found;
+ }
+
+TMLAttributeZoomLevels* TMLEqCompDataLine::FindAttributeZoomLevels(string aAttribSetName, int aAttribId)
+ {
+ TMLEqCompData& data = *(iParentTable->iTables);
+ TMLAttributes& attributes = *(data.iAttributes);
+ int id = iId;
+ TMLAttributes::iterator foundAttributeSetComponent = attributes.find(id);
+ if(foundAttributeSetComponent != attributes.end())
+ {
+ TMLAttributeSetComponent& component = foundAttributeSetComponent->second;
+ TMLAttributeSet* pSet = component[aAttribSetName];
+ if(pSet)
+ {
+ TMLAttributeSet& attributeSet = *pSet;
+ TMLAttributeSet::iterator foundAttrib = attributeSet.find(aAttribId);
+ if(foundAttrib != attributeSet.end())
+ {
+ return &(foundAttrib->second);
+ }
+ }
+ }
+ return NULL;
+ }
+
+void TMLEqCompDataLine::Compile(int aOptionSetId)
+ {
+ // compile values
+ for(iterator pVal = begin(); pVal != end(); ++pVal)
+ {
+ (pVal->second).Compile(aOptionSetId);
+ }
+ }
+
+bool TMLEqCompDataLine::MatchNameDiscountingSuffix(const TMLEqCompDataLine& aLine) const
+ {
+ // we are trying to compare whether the names are the same apart from a trailing number
+ string pureName = NameDiscountingSuffix();
+ string pureNameOther = aLine.NameDiscountingSuffix();
+ string ending = pureName.substr(pureName.find_last_not_of(KEqCompDataKeywordUnderscore));
+
+ bool namesMatch = (pureName == pureNameOther);
+ bool correctEnding = (ending == KEqCompDataKeywordLineNameSuffixGraphic || ending == KEqCompDataKeywordLineNameSuffixText);
+ return (namesMatch && correctEnding);
+ }
+
+bool TMLEqCompDataLine::MatchType(const TMLEqCompDataLine& aLine) const
+ {
+ // first check that the type is equivalent
+ bool equivalent = false;
+ switch(iType)
+ {
+ case ETextComponent:
+ {
+ if(aLine.iType == ETextComponent)
+ {
+ equivalent = true;
+ }
+ break;
+ }
+ case EScreenComponent:
+ case EContainerComponent:
+ case EPaneComponent:
+ case EGraphicComponent:
+ {
+ if(aLine.iType == EScreenComponent
+ || aLine.iType == EContainerComponent
+ || aLine.iType == EPaneComponent
+ || aLine.iType == EGraphicComponent)
+ {
+ equivalent = true;
+ }
+ break;
+ }
+ case EUnknownComponent:
+ default:
+ {
+ if(aLine.iType == EUnknownComponent)
+ {
+ equivalent = true;
+ }
+ break;
+ }
+ }
+
+ return equivalent;
+ }
+
+string TMLEqCompDataLine::NameDiscountingSuffix() const
+ {
+ int lastNonNumericPos = iName.find_last_not_of(KEqCompDataSearchCollectionNumeric);
+ int length = lastNonNumericPos + 1;
+ return iName.substr(0, length);
+ }
+
+string TMLEqCompDataLine::NameSuffix() const
+ {
+ int lastNonNumericPos = iName.find_last_not_of(KEqCompDataSearchCollectionNumeric);
+ int suffixPos = lastNonNumericPos + 1;
+ return iName.substr(suffixPos);
+ }
+
+int TMLEqCompDataLine::NumCols() const
+ {
+ return iNumCols;
+ }
+
+int TMLEqCompDataLine::NumRows() const
+ {
+ return iNumRows;
+ }
+
+
+void TMLEqCompDataLine::SetNumCols(int aNumCols)
+ {
+ iNumCols = aNumCols;
+ }
+
+void TMLEqCompDataLine::SetNumRows(int aNumRows)
+ {
+ iNumRows = aNumRows;
+ }
+
+
+//
+// TMLEqCompDataAttributeInfoSelector
+//
+TMLEqCompDataAttributeInfoSelector::TMLEqCompDataAttributeInfoSelector()
+ {
+
+ }
+
+TMLEqCompDataAttributeInfoSelector::TMLEqCompDataAttributeInfoSelector(string aAttributeSetName)
+ :
+ iAttributeSetName(aAttributeSetName)
+ {
+
+ }
+
+//
+// TMLEqCompDataAttributeInfo
+//
+
+TMLEqCompDataAttributeInfo::TMLEqCompDataAttributeInfo()
+ :
+ iLine(0)
+ {
+
+ }
+
+TMLEqCompDataAttributeInfo::TMLEqCompDataAttributeInfo(TMLEqCompDataLine* aLine)
+ :
+ iLine(aLine)
+ {
+
+ }
+
+TMLEqCompDataAttributeInfo::~TMLEqCompDataAttributeInfo()
+ {
+
+ }
+
+void TMLEqCompDataAttributeInfo::Merge(const TMLEqCompDataAttributeInfo& aOther)
+ {
+ for (const_iterator pOtherVariety = aOther.begin(); pOtherVariety != aOther.end(); ++pOtherVariety)
+ {
+ int varietyIndex = pOtherVariety->first;
+ const TMLEqCompDataAttributeInfoSelector& selector = pOtherVariety->second;
+ insert(make_pair(varietyIndex, selector));
+ }
+ }
+
+
+//
+// TMLEqCompDataTableOptionSet
+//
+TMLEqCompDataTableOptionSet::TMLEqCompDataTableOptionSet()
+ :
+ iOrientation(EMLEqCompDataOptionSetOrientationUndefined)
+ {
+
+ }
+
+TMLEqCompDataTableOptionSet::TMLEqCompDataTableOptionSet(const TMLEqCompDataTableOptionSet& aOther)
+ :
+ iOrientation(aOther.iOrientation)
+ {
+ for(const_iterator pOtherLines = aOther.begin(); pOtherLines != aOther.end(); ++pOtherLines)
+ {
+ push_back(*pOtherLines);
+ }
+ }
+
+TMLEqCompDataTableOptionSet::~TMLEqCompDataTableOptionSet()
+ {
+ // don't delete pointers to lines, as they are not owned
+ clear();
+ }
+
+void TMLEqCompDataTableOptionSet::Compile(int aOptionSetId)
+ {
+ for (iterator pLine = begin(); pLine != end(); ++pLine)
+ {
+ (*pLine)->Compile(aOptionSetId);
+ }
+ }
+
+TMLEqCompDataLine* TMLEqCompDataTableOptionSet::FindLine(int aId) const
+ {
+ for(const_iterator pLine = begin(); pLine != end(); ++pLine)
+ {
+ TMLEqCompDataLine* line = *pLine;
+ if(line)
+ {
+ if(line->iId == aId)
+ return line;
+ }
+ }
+ return NULL;
+ }
+
+//
+// TMLEqCompDataTable
+//
+
+TMLEqCompDataTable::TMLEqCompDataTable(TMLEqCompData* aTables)
+ :
+ iTables(aTables),
+ iParentLine(NULL),
+ iId(0)
+ {
+ }
+
+TMLEqCompDataTable::TMLEqCompDataTable(TMLEqCompData* aTables, const TMLEqCompDataTable& aOther)
+ :
+ iTables(aTables),
+ iParentLine(NULL),
+ iParentName(aOther.iParentName),
+ iId(aOther.iId)
+ {
+ for (const_iterator pOptionSet = aOther.begin(); pOptionSet != aOther.end(); ++pOptionSet)
+ {
+ insert(make_pair(pOptionSet->first, TMLEqCompDataTableOptionSet(pOptionSet->second)));
+ }
+ }
+
+TMLEqCompDataTable::~TMLEqCompDataTable()
+ {
+ // no need to delete lines, as they are not owned.
+ }
+
+string TMLEqCompDataTable::Name()
+ {
+ return iName;
+ }
+
+// @todo this will need to be modified to allow for searching for a line at a specific option set number
+TMLEqCompDataLine* TMLEqCompDataTable::FindLine(const string& aName)
+ {
+/*
+ for (iterator pLine = begin(); pLine != end(); ++pLine)
+ {
+ TMLEqCompDataLine& line = **pLine;
+ if (line.Name() == aName)
+ return *pLine;
+ }
+*/
+ return 0;
+ }
+
+void TMLEqCompDataTable::Merge(TMLEqCompDataTable& aOther)
+ {
+/*
+ for (iterator pOtherLine = aOther.begin(); pOtherLine != aOther.end(); )
+ {
+ TMLEqCompDataLine* found = FindLine((*pOtherLine)->Name());
+ if(found)
+ {
+ found->Merge(**pOtherLine);
+ delete *pOtherLine;
+ pOtherLine = aOther.erase(pOtherLine);
+ }
+ else
+ {
+ push_back(*pOtherLine);
+ (*pOtherLine)->iParentTable = this;
+ pOtherLine = aOther.erase(pOtherLine);
+ }
+ }
+*/
+ }
+
+
+void TMLEqCompDataTable::Compile()
+ {
+// SetDefaultColumnNames();
+// sort(begin(), end(), TMLEqCompDataLine::lessthan);
+
+ for (iterator pOptionSet = begin(); pOptionSet != end(); ++pOptionSet)
+ {
+ pOptionSet->second.Compile(pOptionSet->first);
+ }
+ }
+
+
+
+const string KValueNames[] = { "Font", "C", "l", "r", "W", "J", "t", "r", "b", "H" };
+const set<string> KValueNamesSet(KValueNames, ARRAY_END(KValueNames));
+
+bool TMLEqCompDataTable::IsValueColumn(string aName)
+ {
+ return KValueNamesSet.find(aName) != KValueNamesSet.end();
+ }
+
+const string KNumericNames[] = { "C", "l", "r", "W", "t", "r", "b", "H" };
+const set<string> KNumericNamesSet(KNumericNames, ARRAY_END(KNumericNames));
+
+bool TMLEqCompDataTable::IsNumericColumn(string aName)
+ {
+ return KNumericNamesSet.find(aName) != KNumericNamesSet.end();
+ }
+
+const string KHorizontalColumnNames[] = { "l", "r", "W"};
+const set<string> KHorizontalNamesSet(KHorizontalColumnNames, ARRAY_END(KHorizontalColumnNames));
+
+bool TMLEqCompDataTable::IsHorizontalColumn(string aName)
+ {
+ return KHorizontalNamesSet.find(aName) != KHorizontalNamesSet.end();
+ }
+
+const string KVerticalColumnNames[] = {"t", "b", "H" };
+const set<string> KVerticalNamesSet(KVerticalColumnNames, ARRAY_END(KVerticalColumnNames));
+
+bool TMLEqCompDataTable::IsVerticalColumn(string aName)
+ {
+ return KVerticalNamesSet.find(aName) != KVerticalNamesSet.end();
+ }
+
+
+const string KPaneColumnNames[] = {"Item", "C", "l", "t", "r", "b", "W", "H", "Remarks"};
+const string KGraphicColumnNames[] = {"Item", "C", "l", "t", "r", "b", "W", "H", "Remarks"};
+const string KTextColumnNames[] = {"Font", "C", "l", "r", "t", "b", "W", "H", "J", "Remarks"};
+
+void TMLEqCompDataTable::SetDefaultColumnNames()
+ {
+ iColumnNames.clear();
+ iColumnNames.insert(iColumnNames.end(), KPaneColumnNames, ARRAY_END(KTextColumnNames)); // superset
+ }
+
+
+//
+// TMLEqListComponent
+//
+TMLEqListComponent::TMLEqListComponent()
+ :
+ iId(-1),
+ iName("badName")
+ {
+
+ }
+
+//
+// struct TMLEqParChildComponent
+//
+ TMLEqParChildComponent::TMLEqParChildComponent()
+ :
+ iId(-1),
+ iParentId(0)
+ {
+
+ }
+
+
+//
+// TMLEqCompData
+//
+
+TMLEqCompData::TMLEqCompData()
+ :
+ iCanBeMirror(false),
+ iIsBaseInstance(false),
+ iAttributes(0)
+ {
+ }
+
+TMLEqCompData::TMLEqCompData(const TMLEqCompData& aOther)
+ {
+ *this = aOther;
+ }
+
+TMLEqCompData& TMLEqCompData::operator=(const TMLEqCompData& aOther)
+ {
+ if (this != &aOther)
+ {
+ iName = aOther.iName;
+ iCanBeMirror = aOther.iCanBeMirror;
+ for (const_iterator pTab = aOther.begin(); pTab != aOther.end(); ++pTab)
+ push_back(new TMLEqCompDataTable(this, **pTab));
+ Compile();
+ }
+ return *this;
+ }
+
+TMLEqCompData::~TMLEqCompData()
+ {
+ for (iterator pTab = begin(); pTab != end(); ++pTab)
+ delete *pTab;
+ DeleteComponents();
+ delete iAttributes;
+ }
+
+TMLEqCompDataLine* TMLEqCompData::FindComponent(const string& aName) const
+ {
+ for (TMLEqCompDataComponents::const_iterator pComp = iComponents.begin(); pComp != iComponents.end(); ++pComp)
+ {
+ TMLEqCompDataLine* line = pComp->second;
+ if (line->Name() == aName)
+ return line;
+ }
+
+ return 0;
+ }
+
+TMLEqCompDataLine* TMLEqCompData::FindLine(const string& aName) const
+ {
+ for (const_iterator pTab = begin(); pTab != end(); ++pTab)
+ {
+ TMLEqCompDataLine* line = (*pTab)->FindLine(aName);
+ if (line)
+ return line;
+ }
+
+ return 0;
+ }
+
+TMLEqCompDataTable* TMLEqCompData::FindTable(const string& aName) const
+ {
+ for (const_iterator pTab = begin(); pTab != end(); ++pTab)
+ {
+ if ((*pTab)->Name() == aName)
+ return *pTab;
+ }
+
+ return 0;
+ }
+
+TMLEqCompDataTable* TMLEqCompData::FindTable(int aId) const
+ {
+ for (const_iterator pTab = begin(); pTab != end(); ++pTab)
+ {
+ if ((*pTab)->iId == aId)
+ return *pTab;
+ }
+
+ return 0;
+ }
+
+void TMLEqCompData::Merge(TMLEqCompData& aOther)
+ {
+ iName = aOther.iName;
+ iCanBeMirror |= aOther.iCanBeMirror; // in the case of an elaf layout merging onto an abrw layout, the chirality will be preserved
+ MergeComponents(aOther);
+ }
+
+void TMLEqCompData::MergeComponents(TMLEqCompData& aOther)
+ {
+ for (TMLEqCompDataComponents::iterator pOtherLine = aOther.iComponents.begin(); pOtherLine != aOther.iComponents.end(); ++pOtherLine)
+ {
+ TMLEqCompDataLine& otherLine = *(pOtherLine->second);
+ TMLEqCompDataLine* found = FindComponent(otherLine.iName);
+ if(found)
+ {
+ found->Merge(otherLine);
+ }
+ else
+ {
+ TMLEqCompDataLine* newLine = new TMLEqCompDataLine(otherLine);
+ iComponents.insert(make_pair(otherLine.iId, newLine));
+ }
+ }
+ }
+
+void TMLEqCompData::Compile()
+ {
+ UpdateNames();
+ CreateTables();
+
+ // now add a special table for the screen contents
+ TMLEqCompDataTable* topTab = new TMLEqCompDataTable(this);
+ topTab->iId = -1;
+ topTab->iName = KEqCompDataKeywordScreenContents;
+
+ // then insert each line into its parent
+ for (TMLEqCompDataComponents::iterator pComp = iComponents.begin(); pComp != iComponents.end(); ++pComp)
+ {
+ TMLEqCompDataLine& line = *(pComp->second);
+ if(line.iType == TMLEqCompDataLine::EScreenComponent)
+ {
+ line.iParentTable = topTab;
+ TMLEqCompDataTableOptionSet& optionSet = (*topTab)[0];
+ optionSet.push_back(&line);
+ }
+ else
+ {
+ bool parentFound = false;
+ TMLEqParChildComponent* parChild = iParChildComponents[line.iId];
+ int parentId = parChild->iParentId;
+ if(parentId != 0)
+ {
+ TMLEqCompDataTable* parentTable = FindTable(parentId);
+ TMLEqCompDataLine* parentLine = iComponents[parentId];
+ if(parentTable)
+ {
+ line.iParentTable = parentTable;
+
+ // iterate through the line and populate the table option sets as needed
+ for(TMLEqCompDataLine::iterator pValues = line.begin(); pValues != line.end(); ++pValues)
+ {
+ TMLEqCompDataValues& values = pValues->second;
+ TMLEqCompDataValuesOptionSets& sets = values.iOptionSets;
+ for(TMLEqCompDataValuesOptionSets::iterator pValuesOptionSet = sets.begin(); pValuesOptionSet != sets.end(); ++pValuesOptionSet)
+ {
+ TMLEqCompDataValuesOptionSet& valuesSet = pValuesOptionSet->second;
+ int optionId = pValuesOptionSet->first;
+ TMLEqCompDataTableOptionSet& tableSet = (*parentTable)[optionId]; // constructs if not yet present
+ if(tableSet.iOrientation != valuesSet.iOrientation)
+ tableSet.iOrientation = valuesSet.iOrientation;
+
+ TMLEqCompDataLine* lineInTable = tableSet.FindLine(line.iId);
+ if(!lineInTable)
+ {
+ // make one
+ tableSet.push_back(&line);
+ }
+ }
+ }
+
+ // copy the pointer from the components table
+// parentTable->insert(make_pair(line.iId, &line));
+ parentFound = true;
+
+ // now insert the table into its place in the tree
+ parentTable->iParentLine = iComponents[parentId];
+ }
+ else
+ {
+ parentFound = false;
+ }
+ }
+ if(!parentFound)
+ {
+ string errorText = string(" TMLEqCompData::Compile() - can't find parent component: ");
+ errorText += CdlTkUtil::IntToString(parentId);
+ throw GeneralErr(errorText);
+ }
+ }
+ }
+ push_back(topTab);
+
+ // now compile the tables
+ iterator pTab;
+ for (pTab = begin(); pTab != end(); ++pTab)
+ (*pTab)->Compile();
+
+ // now sort the tables
+// sort(begin(), end(), TMLEqCompDataTable::lessthan);
+ }
+
+void TMLEqCompData::UpdateNames()
+ {
+ // from the list of components, get the name of each line from the list
+ for (TMLEqCompDataComponents::iterator pComp = iComponents.begin(); pComp != iComponents.end(); ++pComp)
+ {
+ TMLEqCompDataLine* line = pComp->second;
+ TMLEqListComponent* pListComp = iListComponents[line->iId];
+ line->iName = pListComp->iName;
+ }
+
+ }
+
+void TMLEqCompData::CreateTables()
+ {
+ // from the list of components, first create a table for each pane
+ for (TMLEqCompDataComponents::iterator pComp = iComponents.begin(); pComp != iComponents.end(); ++pComp)
+ {
+ TMLEqCompDataLine& line = *(pComp->second);
+ switch(line.iType)
+ {
+ case TMLEqCompDataLine::EScreenComponent:
+ case TMLEqCompDataLine::EContainerComponent:
+ case TMLEqCompDataLine::EPaneComponent:
+ {
+ TMLEqCompDataTable* tab = new TMLEqCompDataTable(this);
+ tab->iId = line.iId;
+ tab->iName = line.iName;
+ push_back(tab);
+ break;
+ }
+ case TMLEqCompDataLine::EGraphicComponent:
+ case TMLEqCompDataLine::ETextComponent:
+ {
+ // text and graphic components are not panes
+ // and are therefore not represented in our internal object model as tables
+ break;
+ }
+ default:
+ {
+ cout << "TMLEqCompData::CreateTables() - uncategorised component\n";
+ break;
+ }
+ }
+ }
+ }
+
+void TMLEqCompData::DeleteComponents()
+ {
+ for (TMLEqCompDataComponents::iterator pComp = iComponents.begin(); pComp != iComponents.end(); ++pComp)
+ delete pComp->second;
+ }
+
+// End of File