[dasher] Rm PrependElidedGroup & make CDasherNode fields const



commit 6c00459bf1c480ccf0038e0cc35752fd4daea569
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Sat Feb 12 21:31:43 2011 +0000

    Rm PrependElidedGroup & make CDasherNode fields const
    
    by passing elided-group info around {make,Rebuild,Create...Node}{Symbol,Group}
      & into constructors (except that for symbols GetColour is always opaque.)

 Src/DasherCore/AlphabetManager.cpp |   57 +++++++++++++++++-------------------
 Src/DasherCore/AlphabetManager.h   |   44 ++++++++++++++++++---------
 Src/DasherCore/DasherNode.cpp      |    6 ----
 Src/DasherCore/DasherNode.h        |   11 ++-----
 Src/DasherCore/MandarinAlphMgr.cpp |   18 ++++++------
 Src/DasherCore/MandarinAlphMgr.h   |   17 +++++++----
 6 files changed, 79 insertions(+), 74 deletions(-)
---
diff --git a/Src/DasherCore/AlphabetManager.cpp b/Src/DasherCore/AlphabetManager.cpp
index fe99e73..14bc66c 100644
--- a/Src/DasherCore/AlphabetManager.cpp
+++ b/Src/DasherCore/AlphabetManager.cpp
@@ -120,27 +120,27 @@ CAlphabetManager::CAlphNode::CAlphNode(CDasherNode *pParent, int iOffset, unsign
 : CDasherNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText), m_pProbInfo(NULL), m_pMgr(pMgr) {
 }
 
-CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, symbol _iSymbol)
-: CAlphNode(pParent, iOffset, iLbnd, iHbnd, pMgr->GetColour(_iSymbol, iOffset), pMgr->m_pAlphabet->GetDisplayText(_iSymbol), pMgr), iSymbol(_iSymbol) {
+CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CAlphabetManager *pMgr, symbol _iSymbol)
+: CAlphNode(pParent, iOffset, iLbnd, iHbnd, pMgr->GetColour(_iSymbol, iOffset), strGroup+pMgr->m_pAlphabet->GetDisplayText(_iSymbol), pMgr), iSymbol(_iSymbol) {
 }
 
 CAlphabetManager::CSymbolNode::CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CAlphabetManager *pMgr, symbol _iSymbol)
 : CAlphNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, pMgr), iSymbol(_iSymbol) {
 }
 
-CAlphabetManager::CGroupNode::CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, const SGroupInfo *pGroup)
+CAlphabetManager::CGroupNode::CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, CAlphabetManager *pMgr, const SGroupInfo *pGroup)
 : CAlphNode(pParent, iOffset, iLbnd, iHbnd,
-            pGroup ? (pGroup->bVisible ? pGroup->iColour : pParent->getColour())
+            pGroup ? (pGroup->bVisible ? pGroup->iColour : iBkgCol)
             : (iOffset&1) ? 7 : 137, //special case for root nodes
-            pGroup ? pGroup->strLabel : "", pMgr), m_pGroup(pGroup) {
+            pGroup ? strEnc+pGroup->strLabel : strEnc, pMgr), m_pGroup(pGroup) {
 }
 
-CAlphabetManager::CSymbolNode *CAlphabetManager::makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol) {
-  return new CSymbolNode(pParent, iOffset, iLbnd, iHbnd, this, iSymbol);
+CAlphabetManager::CSymbolNode *CAlphabetManager::makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
+  return new CSymbolNode(pParent, iOffset, iLbnd, iHbnd, strGroup, this, iSymbol);
 }
 
-CAlphabetManager::CGroupNode *CAlphabetManager::makeGroup(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const SGroupInfo *pGroup) {
-  return new CGroupNode(pParent, iOffset, iLbnd, iHbnd, this, pGroup);
+CAlphabetManager::CGroupNode *CAlphabetManager::makeGroup(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pGroup) {
+  return new CGroupNode(pParent, iOffset, iLbnd, iHbnd, strEnc, iBkgCol, this, pGroup);
 }
 
 CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, unsigned int iLower, unsigned int iUpper, bool bEnteredLast, int iOffset) {
@@ -187,10 +187,10 @@ CAlphabetManager::CAlphNode *CAlphabetManager::GetRoot(CDasherNode *pParent, uns
   }
   
   if(!bEnteredLast) {
-    pNewNode = makeGroup(pParent, iNewOffset, iLower, iUpper,  NULL);
+    pNewNode = makeGroup(pParent, iNewOffset, iLower, iUpper, "", 0, NULL);
   } else {
     const symbol iSymbol(vContextSymbols[vContextSymbols.size() - 1]);
-    pNewNode = makeSymbol(pParent, iNewOffset, iLower, iUpper, iSymbol);
+    pNewNode = makeSymbol(pParent, iNewOffset, iLower, iUpper, "", 0, iSymbol);
     //if the new node is not child of an existing node, then it
     // represents a symbol that's already happened - so we're either
     // going backwards (rebuildParent) or creating a new root after a language change
@@ -310,11 +310,11 @@ int CAlphabetManager::CGroupNode::ExpectedNumChildren() {
   return (m_pGroup) ? m_pGroup->iNumChildNodes : CAlphNode::ExpectedNumChildren();
 }
 
-CAlphabetManager::CGroupNode *CAlphabetManager::CreateGroupNode(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd) {
+CAlphabetManager::CGroupNode *CAlphabetManager::CreateGroupNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo) {
 
   // When creating a group node...
   // ...the offset is the same as the parent...
-  CGroupNode *pNewNode = makeGroup(pParent, pParent->offset(), iLbnd, iHbnd, pInfo);
+  CGroupNode *pNewNode = makeGroup(pParent, pParent->offset(), iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
 
   //...as is the context!
   pNewNode->iContext = m_pLanguageModel->CloneContext(pParent->iContext);
@@ -322,7 +322,7 @@ CAlphabetManager::CGroupNode *CAlphabetManager::CreateGroupNode(CAlphNode *pPare
   return pNewNode;
 }
 
-CAlphabetManager::CGroupNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd) {
+CDasherNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo) {
   if (pInfo == m_pGroup) {
     SetRange(iLbnd, iHbnd);
     SetParent(pParent);
@@ -330,7 +330,7 @@ CAlphabetManager::CGroupNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNo
     DASHER_ASSERT (offset() == pParent->offset());
     return this;
   }
-  CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, pInfo, iLbnd, iHbnd);
+  CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
   if (pInfo->iStart <= m_pGroup->iStart && pInfo->iEnd >= m_pGroup->iEnd) {
     //created group node should contain this one
     m_pMgr->IterateChildGroups(pRet,pInfo,this);
@@ -338,8 +338,8 @@ CAlphabetManager::CGroupNode *CAlphabetManager::CGroupNode::RebuildGroup(CAlphNo
   return pRet;
 }
 
-CAlphabetManager::CGroupNode *CAlphabetManager::CSymbolNode::RebuildGroup(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd) {
-  CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, pInfo, iLbnd, iHbnd);
+CDasherNode *CAlphabetManager::CSymbolNode::RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo) {
+  CGroupNode *pRet=m_pMgr->CreateGroupNode(pParent, iLbnd, iHbnd, strEnc, iBkgCol, pInfo);
   if (pInfo->iStart <= iSymbol && pInfo->iEnd > iSymbol) {
     m_pMgr->IterateChildGroups(pRet, pInfo, this);
   }
@@ -353,7 +353,7 @@ CLanguageModel::Context CAlphabetManager::CreateSymbolContext(CAlphNode *pParent
   return iContext;
 }
 
-CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd) {
+CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
 
     // TODO: Exceptions / error handling in general
     
@@ -361,7 +361,7 @@ CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
     // (and we can't call numChars() on the symbol before we've constructed it!)
     int iNewOffset = pParent->offset()+1;
     if (m_pAlphabet->GetText(iSymbol)=="\r\n") iNewOffset++;
-    CSymbolNode *pAlphNode = makeSymbol(pParent, iNewOffset, iLbnd, iHbnd, iSymbol);
+    CSymbolNode *pAlphNode = makeSymbol(pParent, iNewOffset, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
 
     //     std::stringstream ssLabel;
 
@@ -374,18 +374,18 @@ CDasherNode *CAlphabetManager::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
   return pAlphNode;
 }
 
-CDasherNode *CAlphabetManager::CSymbolNode::RebuildSymbol(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd) {
+CDasherNode *CAlphabetManager::CSymbolNode::RebuildSymbol(CAlphNode *pParent,  unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
   if(iSymbol == this->iSymbol) {
     SetRange(iLbnd, iHbnd);
     SetParent(pParent);
     DASHER_ASSERT(offset() == pParent->offset() + numChars());
     return this;
   }
-  return m_pMgr->CreateSymbolNode(pParent, iSymbol, iLbnd, iHbnd);
+  return m_pMgr->CreateSymbolNode(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
 }
 
-CDasherNode *CAlphabetManager::CGroupNode::RebuildSymbol(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd) {
-  return m_pMgr->CreateSymbolNode(pParent, iSymbol, iLbnd, iHbnd);
+CDasherNode *CAlphabetManager::CGroupNode::RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
+  return m_pMgr->CreateSymbolNode(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
 }
 
 void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *pParentGroup, CAlphNode *buildAround) {
@@ -418,15 +418,15 @@ void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *
                          iRange;
     //loop for eliding groups with single children (see below).
     // Variables store necessary properties of any elided groups:
-    std::string groupPrefix=""; int iOverrideColour=-1;
+    std::string groupPrefix=""; int iBackgroundColour=pParent->getColour();
     const SGroupInfo *pInner=pCurrentNode;
     while (true) {
       if (bSymbol) {
-        pNewChild = (buildAround) ? buildAround->RebuildSymbol(pParent, i, iLbnd, iHbnd) : CreateSymbolNode(pParent, i, iLbnd, iHbnd);
+        pNewChild = (buildAround) ? buildAround->RebuildSymbol(pParent, iLbnd, iHbnd, groupPrefix, iBackgroundColour, i) : CreateSymbolNode(pParent, iLbnd, iHbnd, groupPrefix, iBackgroundColour, i);
         i++; //make one symbol at a time - move onto next symbol in next iteration of (outer) loop
         break; //exit inner (group elision) loop
       } else if (pInner->iNumChildNodes>1) { //in/reached nontrivial subgroup - do make node for entire group:
-        pNewChild= (buildAround) ? buildAround->RebuildGroup(pParent, pInner, iLbnd, iHbnd) : CreateGroupNode(pParent, pInner, iLbnd, iHbnd);
+        pNewChild= (buildAround) ? buildAround->RebuildGroup(pParent, iLbnd, iHbnd, groupPrefix, iBackgroundColour, pInner) : CreateGroupNode(pParent, iLbnd, iHbnd, groupPrefix, iBackgroundColour, pInner);
         i = pInner->iEnd; //make one group at a time - so move past entire group...
         pCurrentNode = pCurrentNode->pNext; //next sibling of _original_ pCurrentNode (above)
                                      // (maybe not of pCurrentNode now, which might be a subgroup filling the original)
@@ -441,7 +441,7 @@ void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *
       
       //1. however we also have to take account of the appearance of the elided group. Hence:
       groupPrefix += pInner->strLabel;
-      if (pInner->bVisible) iOverrideColour=pInner->iColour;
+      if (pInner->bVisible) iBackgroundColour=pInner->iColour;
       //2. now go into the group...
       pInner = pInner->pChild;
       bSymbol = (pInner==NULL); //which might contain a single subgroup, or a single symbol
@@ -451,9 +451,6 @@ void CAlphabetManager::IterateChildGroups(CAlphNode *pParent, const SGroupInfo *
     }
     //created a new node - symbol or (group which will have >1 child).
     DASHER_ASSERT(pParent->GetChildren().back()==pNewChild);
-    //now adjust the node we've actually created, to take account of any elided group(s)...
-    // tho not if we've reused the existing node, assume that's been adjusted already
-    if (pNewChild && pNewChild!=buildAround) pNewChild->PrependElidedGroup(iOverrideColour, groupPrefix);
   }
 
   if (!pParentGroup) AddExtras(pParent,pCProb);
diff --git a/Src/DasherCore/AlphabetManager.h b/Src/DasherCore/AlphabetManager.h
index 7abd62e..a8e8aa8 100644
--- a/Src/DasherCore/AlphabetManager.h
+++ b/Src/DasherCore/AlphabetManager.h
@@ -72,8 +72,8 @@ namespace Dasher {
       ///Have to call this from CAlphabetManager, and from CGroupNode on a _different_ CAlphNode, hence public...
       virtual std::vector<unsigned int> *GetProbInfo();
       virtual int ExpectedNumChildren();
-      virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd)=0;
-      virtual CGroupNode *RebuildGroup(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd)=0;
+      virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol)=0;
+      virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo)=0;
     private:
       std::vector<unsigned int> *m_pProbInfo;
     protected:
@@ -82,7 +82,10 @@ namespace Dasher {
     class CSymbolNode : public CAlphNode {
     public:
       ///Standard constructor, gets colour from GetColour(symbol,offset) and label from current alphabet
-      CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, symbol iSymbol);
+      /// \param strGroup caption of any enclosing group(s) of which this symbol is a singleton child
+      /// - this is prepended onto the symbol caption. Note, we don't need the "background colour" of
+      /// any such group, as GetColour() always returns an opaque color.
+      CSymbolNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CAlphabetManager *pMgr, symbol iSymbol);
 
       ///
       /// Provide children for the supplied node
@@ -99,8 +102,8 @@ namespace Dasher {
       virtual void GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength);
       virtual symbol GetAlphSymbol();
       const symbol iSymbol;
-      virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
-      virtual CGroupNode *RebuildGroup(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd);
+      virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+      virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
     protected:
       virtual const std::string &outputText();
       /// Number of unicode _characters_ (not octets) for this symbol.
@@ -114,7 +117,7 @@ namespace Dasher {
 
     class CGroupNode : public CAlphNode {
     public:
-      CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CAlphabetManager *pMgr, const SGroupInfo *pGroup);
+      CGroupNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, CAlphabetManager *pMgr, const SGroupInfo *pGroup);
       
       ///
       /// Provide children for the supplied node
@@ -123,8 +126,8 @@ namespace Dasher {
       virtual void PopulateChildren();
       virtual int ExpectedNumChildren();
       virtual bool GameSearchNode(std::string strTargetUtf8Char);
-      virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
-      virtual CGroupNode *RebuildGroup(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd);
+      virtual CDasherNode *RebuildSymbol(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+      virtual CDasherNode *RebuildGroup(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
       std::vector<unsigned int> *GetProbInfo();
     private:
       const SGroupInfo *m_pGroup;
@@ -142,15 +145,17 @@ namespace Dasher {
     const CAlphInfo *GetAlphabet() const;
     
   protected:
-    ///
     /// Factory method for CAlphNode construction, so subclasses can override.
-    ///
-    virtual CSymbolNode *makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol);
-    virtual CGroupNode *makeGroup(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const SGroupInfo *pGroup);
-    
-    virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
+    virtual CSymbolNode *makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+    virtual CGroupNode *makeGroup(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pGroup);
+
+    ///Called to create a node for a given symbol (leaf), as a child of a specified parent node
+    /// \param strGroup caption of any group containing this node, that will not be created:
+    /// thus, should be prepended onto the caption of the node created.
+    /// \param iBkgCol colour behind the new node, i.e. that should show through if the node is transparent
+    virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
     virtual CLanguageModel::Context CreateSymbolContext(CAlphNode *pParent, symbol iSymbol);
-    virtual CGroupNode *CreateGroupNode(CAlphNode *pParent, const SGroupInfo *pInfo, unsigned int iLbnd, unsigned int iHbnd);
+    virtual CGroupNode *CreateGroupNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strEnc, int iBkgCol, const SGroupInfo *pInfo);
 
     ///Called to add any non-alphabet (non-symbol) children to a top-level node (root or symbol).
     /// Default is just to add the control node, if appropriate.
@@ -173,6 +178,15 @@ namespace Dasher {
     ///Wraps m_pLanguageModel->GetProbs to implement nonuniformity & leave space for control node.
     /// Returns array of non-cumulative probs. Should this be protected and/or virtual???
     void GetProbs(std::vector<unsigned int> *pProbs, CLanguageModel::Context iContext);
+    ///Constructs child nodes under the specified parent according to provided group.
+    /// Nodes are created by calling CreateSymbolNode and CreateGroupNode, unless buildAround is non-null.
+    /// \param pParentGroup group describing which symbols and/or subgroups should be constructed
+    /// (these will fill the parent), or NULL meaning the entire alphabet (i.e. toplevel groups
+    /// and symbols not in any group).
+    /// \param buildAround if non-null, its RebuildSymbol and RebuildGroup methods will be called
+    /// instead of the AlphabetManager's CreateSymbolNode/CreateGroupNode methods. This is used when
+    /// rebuilding parents: passing in the pre-existing node here, allows it to intercept those calls
+    /// and graft itself in in place of a new node, when appropriate.
     void IterateChildGroups(CAlphNode *pParent, const SGroupInfo *pParentGroup, CAlphNode *buildAround);
 
     CDasherInterfaceBase *m_pInterface;
diff --git a/Src/DasherCore/DasherNode.cpp b/Src/DasherCore/DasherNode.cpp
index de68bdc..4d7ab60 100644
--- a/Src/DasherCore/DasherNode.cpp
+++ b/Src/DasherCore/DasherNode.cpp
@@ -72,12 +72,6 @@ CDasherNode::~CDasherNode() {
   iNumNodes--;
 }
 
-void CDasherNode::PrependElidedGroup(int iGroupColour, string &strGroupLabel) {
-  if (m_iColour==-1) m_iColour = iGroupColour;
-  m_strDisplayText = strGroupLabel + m_strDisplayText;
-}
-
-
 void CDasherNode::Trace() const {
   /* TODO sort out
      dchar out[256];
diff --git a/Src/DasherCore/DasherNode.h b/Src/DasherCore/DasherNode.h
index bc7939e..66620c6 100644
--- a/Src/DasherCore/DasherNode.h
+++ b/Src/DasherCore/DasherNode.h
@@ -65,7 +65,7 @@ class Dasher::CDasherNode:private NoClones {
   /// Colour; note invisible nodes just have the same colour as their parent.
   /// (so we know what colour to use when their parents are deleted)
   inline int getColour() {return m_iColour;}
-  inline std::string &getDisplayText() {return m_strDisplayText;}
+  inline const std::string &getDisplayText() {return m_strDisplayText;}
   ///Whether labels on child nodes should be displaced to the right of this node's label.
   /// (Default implementation returns true, subclasses should override if appropriate)
   virtual bool bShove() {return true;}
@@ -90,11 +90,6 @@ class Dasher::CDasherNode:private NoClones {
   ///
   virtual ~CDasherNode();
 
-  /// Adjusts the colour & label of this node to look as it would if it 
-  /// were the sole child of another node with the specified colour and label
-  /// (without actually making the other/group node)
-  void PrependElidedGroup(int iGroupColour, std::string &strGroupLabel);
-  
   void Trace() const;           // diagnostic
 
   /// @name Routines for manipulating node status
@@ -284,8 +279,8 @@ class Dasher::CDasherNode:private NoClones {
   int m_iOffset;
 
  protected:
-  int m_iColour;
-  std::string m_strDisplayText;
+  const int m_iColour;
+  const std::string m_strDisplayText;
 };
 /// @}
 
diff --git a/Src/DasherCore/MandarinAlphMgr.cpp b/Src/DasherCore/MandarinAlphMgr.cpp
index d1bf063..1c0e2d3 100644
--- a/Src/DasherCore/MandarinAlphMgr.cpp
+++ b/Src/DasherCore/MandarinAlphMgr.cpp
@@ -112,7 +112,7 @@ CTrainer *CMandarinAlphMgr::GetTrainer() {
   return new CMandarinTrainer(m_pLanguageModel, m_pAlphabetMap, m_pCHAlphabetMap);
 }
 
-CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd) {
+CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
 
   if (iSymbol <= LAST_PY) {
     //Will wrote:
@@ -132,7 +132,7 @@ CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
     // (SPY syllable+tone) to the relevant set of chinese symbols.
     
     // the same offset as we've still not entered/selected a symbol (leaf)
-    CConvRoot *pNewNode = new CConvRoot(pParent, pParent->offset(), iLbnd, iHbnd, this, &m_pConversionsBySymbol[iSymbol]);
+    CConvRoot *pNewNode = new CConvRoot(pParent, pParent->offset(), iLbnd, iHbnd, strGroup, this, &m_pConversionsBySymbol[iSymbol]);
 
     //from ConversionHelper:
     //pNewNode->m_pLanguageModel = m_pLanguageModel;
@@ -140,11 +140,11 @@ CDasherNode *CMandarinAlphMgr::CreateSymbolNode(CAlphNode *pParent, symbol iSymb
 
 	  return pNewNode;
   }
-  return CAlphabetManager::CreateSymbolNode(pParent, iSymbol, iLbnd, iHbnd);
+  return CAlphabetManager::CreateSymbolNode(pParent, iLbnd, iHbnd, strGroup, iBkgCol, iSymbol);
 }
 
-CMandarinAlphMgr::CConvRoot::CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, const set<symbol> *pConversions)
-: CDasherNode(pParent, iOffset, iLbnd, iHbnd, 9, ""), m_pMgr(pMgr), m_pConversions(pConversions) {
+CMandarinAlphMgr::CConvRoot::CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, const set<symbol> *pConversions)
+: CDasherNode(pParent, iOffset, iLbnd, iHbnd, 9, strGroup), m_pMgr(pMgr), m_pConversions(pConversions) {
   DASHER_ASSERT(pConversions);
   //colour + label from ConversionManager.
 }
@@ -314,18 +314,18 @@ CLanguageModel::Context CMandarinAlphMgr::CreateSymbolContext(CAlphNode *pParent
 	return m_pLanguageModel->CloneContext(pParent->iContext);
 }
 
-CMandarinAlphMgr::CMandNode::CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, symbol iSymbol)
-: CSymbolNode(pParent, iOffset, iLbnd, iHbnd, pMgr, iSymbol) {
+CMandarinAlphMgr::CMandNode::CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const string &strGroup, CMandarinAlphMgr *pMgr, symbol iSymbol)
+: CSymbolNode(pParent, iOffset, iLbnd, iHbnd, strGroup, pMgr, iSymbol) {
 }
 
 CMandarinAlphMgr::CMandNode::CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const string &strDisplayText, CMandarinAlphMgr *pMgr, symbol iSymbol)
 : CSymbolNode(pParent, iOffset, iLbnd, iHbnd, iColour, strDisplayText, pMgr, iSymbol) {
 }
 
-CMandarinAlphMgr::CMandNode *CMandarinAlphMgr::makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol) {
+CMandarinAlphMgr::CMandNode *CMandarinAlphMgr::makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol) {
   // Override standard symbol factory method, called by superclass, to make CMandNodes
   //  - important only to disable learn-as-you-write...
-  return new CMandNode(pParent, iOffset, iLbnd, iHbnd, this, iSymbol);
+  return new CMandNode(pParent, iOffset, iLbnd, iHbnd, strGroup, this, iSymbol);
 }
 
 void CMandarinAlphMgr::CMandNode::SetFlag(int iFlag, bool bValue) {
diff --git a/Src/DasherCore/MandarinAlphMgr.h b/Src/DasherCore/MandarinAlphMgr.h
index 1db6a6f..e4f86e2 100644
--- a/Src/DasherCore/MandarinAlphMgr.h
+++ b/Src/DasherCore/MandarinAlphMgr.h
@@ -58,15 +58,17 @@ namespace Dasher {
     class CMandNode : public CSymbolNode {
     public:
       CMandarinAlphMgr *mgr() {return static_cast<CMandarinAlphMgr *>(CSymbolNode::mgr());}
-      CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, symbol iSymbol);
       virtual void SetFlag(int iFlag, bool bValue);
       virtual CDasherNode *RebuildParent() {return 0;}
+      //Standard constructor, as for CSymbolNode
+      CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, symbol iSymbol);
     protected:
-      /// Constructor for subclasses (CMandSym!) to specify own colour & label
+      ///Compatibility constructor with exact colour & label (inc. enclosing group nodes)
       CMandNode(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, const std::string &strDisplayText, CMandarinAlphMgr *pMgr, symbol iSymbol);
     };
     class CMandSym : public CMandNode {
     public:
+      //CMandSym's only ever created as children of ConvRoots, so no enclosing group nodes to worry about.
       CMandSym(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, int iColour, CMandarinAlphMgr *pMgr, symbol iSymbol);
     private:
       virtual const std::string &outputText();
@@ -78,17 +80,20 @@ namespace Dasher {
     public:
       CMandarinAlphMgr *mgr() {return m_pMgr;}
       /// \param pConversions set of chinese-alphabet symbol numbers that the PY can convert to.
-      CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, CMandarinAlphMgr *pMgr, const std::set<symbol> *pConversions);
+      CConvRoot(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, CMandarinAlphMgr *pMgr, const std::set<symbol> *pConversions);
       void PopulateChildren();
       int ExpectedNumChildren();
-      int iContext;
+      CLanguageModel::Context iContext;
     private:        
       std::vector<std::pair<symbol, unsigned int> > m_vChInfo;
       CMandarinAlphMgr *m_pMgr;
       const std::set<symbol> *m_pConversions;
     };
-    CMandNode *makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, symbol iSymbol);
-    virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, symbol iSymbol, unsigned int iLbnd, unsigned int iHbnd);
+    ///Override to make CMandNodes (for punctuation)
+    CMandNode *makeSymbol(CDasherNode *pParent, int iOffset, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+    ///Override to make CConvRoots for symbols <=1288, fall back to superclass for others (punctuation)
+    virtual CDasherNode *CreateSymbolNode(CAlphNode *pParent, unsigned int iLbnd, unsigned int iHbnd, const std::string &strGroup, int iBkgCol, symbol iSymbol);
+    ///Override: punctuation contexts, are the same as their parent (?!)
     virtual CLanguageModel::Context CreateSymbolContext(CAlphNode *pParent, symbol iSymbol);
 
     int AssignColour(int parentClr, int childIndex);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]