Updated German translation
[dasher.git] / Src / DasherCore / ConversionManager.cpp
blob95ae78a1b5414f3155c5cfc5f4e1e5e24037144b
1 // ConversionManager.cpp
2 //
3 // Copyright (c) 2007 The Dasher Team
4 //
5 // This file is part of Dasher.
6 //
7 // Dasher is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
12 // Dasher is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with Dasher; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include "ConversionManager.h"
26 #include "Event.h"
27 #include "Observable.h"
28 #include "NodeCreationManager.h"
29 #include "DasherModel.h"
30 #include "DasherInterfaceBase.h"
32 #include <iostream>
33 #include <cstring>
34 #include <string>
35 #include <vector>
36 #include <stdlib.h>
38 //Note the new implementation in Mandarin Dasher may not be compatible with the previous implementation of Japanese Dasher
39 //Need to reconcile (a small project)
41 using namespace Dasher;
42 using namespace std;
44 CConversionManager::CConversionManager(CSettingsUser *pCreateFrom, CDasherInterfaceBase *pInterface, CNodeCreationManager *pNCManager, const CAlphInfo *pAlphabet, CLanguageModel *pLanguageModel)
45 : CSettingsUser(pCreateFrom), m_pInterface(pInterface), m_pNCManager(pNCManager), m_pAlphabet(pAlphabet), m_pLanguageModel(pLanguageModel) {
47 //Testing for alphabet details, delete if needed:
49 int alphSize = pNCManager->GetAlphabet()->GetNumberSymbols();
50 std::cout<<"Alphabet size: "<<alphSize<<std::endl;
51 for(int i =0; i<alphSize; i++)
52 std::cout<<"symbol: "<<i<<" display text:"<<pNCManager->GetAlphabet()->GetDisplayText(i)<<std::endl;
54 colourStore[0][0]=66;//light blue
55 colourStore[0][1]=64;//very light green
56 colourStore[0][2]=62;//light yellow
57 colourStore[1][0]=78;//light purple
58 colourStore[1][1]=81;//brownish
59 colourStore[1][2]=60;//red
61 m_iLearnContext = m_pLanguageModel->CreateEmptyContext();
65 CConversionManager::CConvNode *CConversionManager::makeNode(int iOffset, int iColour, CDasherScreen::Label *pLabel) {
66 return new CConvNode(iOffset, iColour, pLabel, this);
69 void CConversionManager::ChangeScreen(CDasherScreen *pScreen) {
70 if (m_pScreen==pScreen) return;
71 for (map<string, CDasherScreen::Label *>::iterator it=m_vLabels.begin(); it!=m_vLabels.end(); it++)
72 delete it->second;
73 m_vLabels.clear();
74 m_pScreen=pScreen;
77 CDasherScreen::Label *CConversionManager::GetLabel(const char *pszConversion) {
78 string strConv(pszConversion);
79 if (m_vLabels[strConv])
80 return m_vLabels[strConv];
81 return m_vLabels[strConv] = m_pScreen->MakeLabel(strConv);
84 CConversionManager::CConvNode *CConversionManager::GetRoot(int iOffset, CLanguageModel::Context newCtx) {
86 // TODO: Parameters here are placeholders - need to figure out what's right
88 //TODO: hard-coded colour, and hard-coded displaytext... (ACL: read from Alphabet -> startConversionSymbol ?)
89 CConvNode *pNewNode = makeNode(iOffset, 9, NULL);
91 pNewNode->iContext = newCtx;
93 pNewNode->bisRoot = true;
95 pNewNode->pSCENode = 0;
97 return pNewNode;
100 CConversionManager::CConvNode::CConvNode(int iOffset, int iColour, CDasherScreen::Label *pLabel, CConversionManager *pMgr)
101 : CDasherNode(iOffset, iColour, pLabel), m_pMgr(pMgr) {
104 CConversionManager::CConvNode::~CConvNode() {
105 m_pMgr->m_pLanguageModel->ReleaseContext(iContext);
108 void CConversionManager::RecursiveDumpTree(ostream &out, SCENode *pCurrent, unsigned int iDepth) {
109 const std::vector<SCENode *> &children = pCurrent->GetChildren();
110 for (std::vector<SCENode *>::const_iterator it = children.begin(); it!=children.end(); it++) {
111 SCENode *pCurrent(*it);
112 for(unsigned int i(0); i < iDepth; ++i)
113 out << "-";
114 out << " " << pCurrent->pszConversion << std::endl;//" " << pCurrent->IsHeadAndCandNum << " " << pCurrent->CandIndex << " " << pCurrent->IsComplete << " " << pCurrent->AcCharCount << std::endl;
115 RecursiveDumpTree(out, pCurrent, iDepth + 1);
119 void CConversionManager::CConvNode::GetContext(CDasherInterfaceBase *pInterface, const CAlphabetMap *pAlphabetMap, std::vector<symbol> &vContextSymbols, int iOffset, int iLength) {
120 if (!GetFlag(NF_SEEN) && iOffset+iLength-1 == offset()) {
121 //ACL I'm extrapolating from PinYinConversionHelper (in which root nodes have their
122 // Symbol set by SetConvSymbol, and child nodes are created in PopulateChildren
123 // from SCENode's with Symbols having been set in in AssignSizes); not really sure
124 // whether this is applicable in the general case(! - but although I think it's right
125 // for PinYin, it wouldn't actually be used there, as MandarinDasher overrides contexts
126 // everywhere!)
127 DASHER_ASSERT(bisRoot || pSCENode);
128 if (bisRoot || pSCENode->Symbol!=-1) {
129 if (iLength>1) Parent()->GetContext(pInterface, pAlphabetMap, vContextSymbols, iOffset, iLength-1);
130 vContextSymbols.push_back(bisRoot ? iSymbol : pSCENode->Symbol);
131 return;
132 } //else, non-root with pSCENode->Symbol==-1 => fallthrough back to superclass code
134 CDasherNode::GetContext(pInterface, pAlphabetMap, vContextSymbols, iOffset, iLength);
137 void CConversionManager::CConvNode::Output() {
138 // TODO: Reimplement this
139 // m_pNCManager->m_bContextSensitive = true;
141 SCENode *pCurrentSCENode(pSCENode);
143 if(pCurrentSCENode){
144 m_pMgr->m_pInterface->editOutput(pCurrentSCENode->pszConversion, this);
146 if((GetChildren())[0]->mgr() == m_pMgr) {
147 if (static_cast<CConvNode *>(GetChildren()[0])->m_pMgr == m_pMgr) {
148 m_pMgr->m_pInterface->editProtect(this); //TODO used to pass in offset 0, will now get this node's offset...
152 else {
153 m_pMgr->m_pInterface->editOutput(bisRoot ? ">" : "|", this);
155 m_pMgr->m_pInterface->editConvert(this); //TODO used to pass in offset 0, will now get this node's offset...
159 void CConversionManager::CConvNode::Undo() {
160 SCENode *pCurrentSCENode(pSCENode);
162 if(pCurrentSCENode) {
163 if(pCurrentSCENode->pszConversion && (strlen(pCurrentSCENode->pszConversion) > 0)) {
164 m_pMgr->m_pInterface->editDelete(pCurrentSCENode->pszConversion, this);
167 else {
168 m_pMgr->m_pInterface->editDelete(bisRoot ? ">" : "|", this);
172 // TODO: This function needs to be significantly tidied up
173 // TODO: get rid of pSizes
175 void CConversionManager::AssignChildSizes(const std::vector<SCENode *> &nodes, CLanguageModel::Context context) {
177 AssignSizes(nodes, context, CDasherModel::NORMALIZATION, GetLongParameter(LP_UNIFORM));
181 void CConversionManager::CConvNode::PopulateChildren() {
182 DASHER_ASSERT(mgr()->m_pNCManager);
184 // Do the conversion and build the tree (lattice) if it hasn't been
185 // done already.
189 if(bisRoot && !pSCENode) {
190 mgr()->BuildTree(this);
194 if(pSCENode && !pSCENode->GetChildren().empty()) {
195 const std::vector<SCENode *> &vChildren = pSCENode->GetChildren();
196 // RecursiveDumpTree(pSCENode, 1);
197 mgr()->AssignChildSizes(vChildren, iContext);
199 int iIdx(0);
200 int iCum(0);
202 // int parentClr = pNode->Colour();
203 // TODO: Fixme
204 int parentClr = 0;
206 // Finally loop through and create the children
208 for (std::vector<SCENode *>::const_iterator it = vChildren.begin(); it!=vChildren.end(); it++) {
209 // std::cout << "Current scec: " << pCurrentSCEChild << std::endl;
210 SCENode *pCurrentSCEChild(*it);
211 DASHER_ASSERT(pCurrentSCEChild != NULL);
212 unsigned int iLbnd(iCum);
213 unsigned int iHbnd(iCum + pCurrentSCEChild->NodeSize);
214 //CDasherModel::NORMALIZATION);//
216 iCum = iHbnd;
218 // TODO: Parameters here are placeholders - need to figure out
219 // what's right
221 // std::cout << "#" << pCurrentSCEChild->pszConversion << "#" << std::endl;
223 CConvNode *pNewNode = mgr()->makeNode(offset()+1, mgr()->AssignColour(parentClr, pCurrentSCEChild, iIdx), mgr()->GetLabel(pCurrentSCEChild->pszConversion));
225 // TODO: Reimplement ----
227 // FIXME - handle context properly
228 // pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext());
229 // -----
231 pNewNode->bisRoot = false;
232 pNewNode->pSCENode = pCurrentSCEChild;
234 pNewNode->iContext = mgr()->m_pLanguageModel->CloneContext(this->iContext);
236 if(pCurrentSCEChild ->Symbol !=-1)
237 mgr()->m_pLanguageModel->EnterSymbol(pNewNode->iContext, pCurrentSCEChild->Symbol); // TODO: Don't use symbols?
239 pNewNode->Reparent(this, iLbnd, iHbnd);
241 ++iIdx;
245 else {//End of conversion -> default to alphabet
247 //Phil//
248 // TODO: Placeholder algorithm here
249 // TODO: Add an 'end of conversion' node?
250 //ACL 1/12/09 Note that this adds one to the m_iOffset of the created node
251 // (whereas code that was once here did not, but was otherwise identical...)
252 CDasherNode *pNewNode = m_pMgr->m_pNCManager->GetAlphabetManager()->GetRoot(this, false, offset() + 1);
253 pNewNode->Reparent(this, 0, CDasherModel::NORMALIZATION);
257 int CConversionManager::CConvNode::ExpectedNumChildren() {
258 if(bisRoot && !pSCENode) mgr()->BuildTree(this);
259 if (pSCENode && !pSCENode->GetChildren().empty()) return pSCENode->GetChildren().size();
260 return 1;//Alphabet root
263 void CConversionManager::BuildTree(CConvNode *pRoot) {
264 // Build the string to convert.
265 std::string strCurrentString;
266 // Search backwards but stop at any conversion node.
267 for (CDasherNode *pNode = pRoot->Parent();
268 pNode && pNode->mgr() == this;
269 pNode = pNode->Parent()) {
271 // TODO: Need to make this the edit text rather than the display text
272 strCurrentString =
273 m_pAlphabet->GetText(pNode->GetAlphSymbol())
274 + strCurrentString;
276 // Handle/store the result.
277 SCENode *pStartTemp;
278 Convert(strCurrentString, &pStartTemp);
280 // Store all conversion trees (SCENode trees) in the pUserData->pSCENode
281 // of each Conversion Root.
283 pRoot->pSCENode = pStartTemp;
286 void CConversionManager::CConvNode::SetFlag(int iFlag, bool bValue) {
287 CDasherNode::SetFlag(iFlag, bValue);
288 switch(iFlag) {
289 case NF_COMMITTED:
290 if(bValue){
292 if(!pSCENode)
293 return;
295 symbol s =pSCENode ->Symbol;
298 if(s!=-1)
299 mgr()->m_pLanguageModel->LearnSymbol(mgr()->m_iLearnContext, s);
301 break;