From d4b2f7af08c7aa74b5025d18be8139d7ad8e451f Mon Sep 17 00:00:00 2001 From: Phil Cowans Date: Tue, 12 Sep 2006 10:40:54 +0000 Subject: [PATCH] Checking in before I start playing around with eclipse * Checking in before I start playing around with eclipse --- Data/Help/Gnome/C/dasher.xml | 2 +- Src/DasherCore/ConversionHelper.h | 30 +- Src/DasherCore/ConversionManager.cpp | 497 ++++++++++++++++++++++------ Src/DasherCore/ConversionManager.h | 41 ++- Src/DasherCore/ConversionManagerFactory.cpp | 27 +- Src/DasherCore/ConversionManagerFactory.h | 3 + Src/DasherCore/DasherInterfaceBase.cpp | 54 +++ Src/DasherCore/DasherInterfaceBase.h | 15 +- Src/DasherCore/Makefile.am | 261 +++++++-------- Src/DasherCore/PinYinConversionHelper.cpp | 141 +++++++- Src/DasherCore/PinYinConversionHelper.h | 36 +- Src/Makefile.am | 2 +- configure.in | 16 +- 13 files changed, 861 insertions(+), 264 deletions(-) rewrite Src/DasherCore/Makefile.am (87%) rewrite Src/DasherCore/PinYinConversionHelper.cpp (67%) diff --git a/Data/Help/Gnome/C/dasher.xml b/Data/Help/Gnome/C/dasher.xml index 77e7ca9d..e4b330dc 100644 --- a/Data/Help/Gnome/C/dasher.xml +++ b/Data/Help/Gnome/C/dasher.xml @@ -1203,7 +1203,7 @@ display. - Twho button dynamic mode + Two button dynamic mode Dasher zooms continuously towards the centre of the screen, with the two buttons being used to shift the display up and down. The buttons should be pressed whenever the desired text is aligned with the two markers. diff --git a/Src/DasherCore/ConversionHelper.h b/Src/DasherCore/ConversionHelper.h index aa850ac5..ee16c292 100644 --- a/Src/DasherCore/ConversionHelper.h +++ b/Src/DasherCore/ConversionHelper.h @@ -3,10 +3,38 @@ #include #include +#include + + + +//THESE DEFINITIONS ARE SHARED BETWEEN PYCONVERSIONHELPER AND CONVERSIONMANAGER +#define MAX_CARE_CAND 100 +#define MAX_CARE_PHRASE 20 +#define MAX_HZ_NUM 50 +#define MAX_CM_NUM 10 + + + +//trial change +namespace Dasher{ + class CDasherNode; //trial forward declaration +} class CConversionHelper { public: - virtual bool Convert(const std::string &strSource, std::vector > &vResult) = 0; + virtual bool Convert(const std::string &strSource, SCENode ** pRoot, int * childCount, int CMid) = 0; + + virtual bool GetPhraseList(int HZIndex, SCENode ** psOutput, int CMid)=0; + virtual void BuildDataBase()=0; + virtual void ClearData(int CMid)=0; + + virtual std::vector > > > > * GetDP(int CMid)=0;//get data pointer + + + virtual int AssignColour(int parentClr, SCENode * pNode, int childIndex)=0; + + std::vector > > > > >vContextData; + }; #endif diff --git a/Src/DasherCore/ConversionManager.cpp b/Src/DasherCore/ConversionManager.cpp index e3de3fa5..04ed0c65 100644 --- a/Src/DasherCore/ConversionManager.cpp +++ b/Src/DasherCore/ConversionManager.cpp @@ -2,8 +2,6 @@ #include "config.h" #endif -#ifdef JAPANESE - #include "ConversionManager.h" #include "Event.h" #include "EventHandler.h" @@ -11,25 +9,40 @@ #include #include #include +#include using namespace Dasher; -CConversionManager::CConversionManager(CDasherModel *pModel, CLanguageModel *pLanguageModel, CConversionHelper *pHelper) +CConversionManager::CConversionManager(CDasherModel *pModel, CLanguageModel *pLanguageModel, CConversionHelper *pHelper, int CMid) : CNodeManager(2) { m_pModel = pModel; m_pLanguageModel = pLanguageModel; m_pHelper = pHelper; - + m_iRefCount = 1; + m_iCMID = CMid; + m_iHZCount = 0; - m_bTreeBuilt = false; + m_bTreeBuilt = false; + + //clears the process phrase flags + for(int i(0); iGetStartConversionSymbol(), 0, Opts::Nodes2, iLower, iUpper, m_pLanguageModel, 2); + pNewNode = new CDasherNode(pParent, m_pModel->GetStartConversionSymbol(), 0, Opts::Nodes2, iLower, iUpper, m_pLanguageModel, 9); // FIXME - handle context properly pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext()); @@ -47,32 +60,55 @@ CDasherNode *CConversionManager::GetRoot(CDasherNode *pParent, int iLower, int i void CConversionManager::PopulateChildren( CDasherNode *pNode ) { + if(!m_pModel) + return; + if(!m_bTreeBuilt) { BuildTree(pNode); m_bTreeBuilt = true; } + m_bTraceNeeded = true;//reset trace bool + CDasherNode *pNewNode; - CConversionManagerNode *pCurrentCMNode(static_cast(pNode->m_pUserData)); - - if(pCurrentCMNode == 0) + SCENode *pCurrentSCENode(static_cast(pNode->m_pUserData)); + + if(pCurrentSCENode == 0){ if(m_pRoot) - pCurrentCMNode = m_pRoot[0]; - else - pCurrentCMNode = 0; - else if((pCurrentCMNode->m_pChild == 0) && (pCurrentCMNode->m_iPhrase < m_iRootCount - 1)) - pCurrentCMNode = m_pRoot[pCurrentCMNode->m_iPhrase + 1]; + pCurrentSCENode = m_pRoot[0]; + } + else{ - CConversionManagerNode *pCurrentCMChild; + if((pCurrentSCENode->AcCharCount != m_iHZCount)&&(!pCurrentSCENode->pChild)) + pCurrentSCENode ->pChild = m_pRoot[pCurrentSCENode->AcCharCount]->pChild; - if(pCurrentCMNode) - pCurrentCMChild = pCurrentCMNode->m_pChild; - else - pCurrentCMChild = 0; + else if(pCurrentSCENode->AcCharCount == m_iHZCount) + pCurrentSCENode->pChild =0; + // std::cout<<"signal "<pChild<pChild) + // std::cout<<"signal "<pChild->pszConversion<pChild) already has children + //if complete, has pChild is NULL + } + + SCENode *pCurrentSCEChild; + + if(pCurrentSCENode) + pCurrentSCEChild = pCurrentSCENode->pChild; + else + pCurrentSCEChild = 0; + + if(pCurrentSCEChild) { + + if(m_iHZCount>1) + if(!m_bPhrasesProcessed[pCurrentSCEChild->AcCharCount-1]) + if(pCurrentSCEChild->AcCharCountAcCharCount-1); + // Calculate sizes for the children. Note that normalisation is // done additiviely rather than multiplicatively, so it's not // quite what was originally planned (but I don't think this is @@ -92,23 +128,64 @@ void CConversionManager::PopulateChildren( CDasherNode *pNode ) { // order, rather than in order returned (really not sure about // this - it needs to be thought through). - int *iSize; - iSize = new int[pCurrentCMNode->m_iNumChildren]; - + + + + //TESTING FOR CALCULATESCORE STAGE 1 + //int test; + //test = CalculateScore(pNode, 1); + //std::cout<<"current character"<pszConversion<IsHeadAndCandNum]; + int score[pCurrentSCEChild->IsHeadAndCandNum]; + int total =0; + int max = 0; + int CandNum = pCurrentSCEChild -> IsHeadAndCandNum; + int iRemaining(m_pModel->GetLongParameter(LP_NORMALIZATION)); - for(int i(0); i < pCurrentCMNode->m_iNumChildren; ++i) { - iSize[i] = m_pModel->GetLongParameter(LP_NORMALIZATION) / ((i + 1) * (i + 2)); + + for(int i(0); i < pCurrentSCEChild->IsHeadAndCandNum; ++i){ + + score[i] = CalculateScore(pNode, i); + total += score[i]; + if(i!=0) + if (score[i]>score[i-1]) + max = score[i]; + } + + for(int i(0); i < pCurrentSCEChild->IsHeadAndCandNum; ++i) { + + + //TESTING FOR RESIZING FREQUENT HZ CHARACTERS + //if(i<5) + // if(score[i]GetLongParameter(LP_NORMALIZATION); + else + iSize[i] = m_pModel->GetLongParameter(LP_NORMALIZATION)*((CandNum-i-1)+2*CandNum*score[i])/(CandNum*(CandNum-1)/2+2*CandNum*total); + + //PREVIOUS MODEL: m_pModel->GetLongParameter(LP_NORMALIZATION)/((i + 1) * (i + 2)); + if(iSize[i] < 1) iSize[i] == 1; - + iRemaining -= iSize[i]; } - int iLeft(pCurrentCMNode->m_iNumChildren); + int iLeft(pCurrentSCEChild->IsHeadAndCandNum); - for(int i(0); i < pCurrentCMNode->m_iNumChildren; ++i) { + for(int i(0); i < pCurrentSCEChild->IsHeadAndCandNum; ++i) { int iDiff(iRemaining / iLeft); iSize[i] += iDiff; @@ -119,8 +196,10 @@ void CConversionManager::PopulateChildren( CDasherNode *pNode ) { int iIdx(0); int iCum(0); + + int parentClr = pNode->Colour(); - while(pCurrentCMChild) { + do { // int iLbnd( iIdx*(m_pModel->GetLongParameter(LP_NORMALIZATION)/pCurrentCMNode->m_iNumChildren)); // int iHbnd( (iIdx+1)*(m_pModel->GetLongParameter(LP_NORMALIZATION)/pCurrentCMNode->m_iNumChildren)); @@ -129,8 +208,10 @@ void CConversionManager::PopulateChildren( CDasherNode *pNode ) { iCum = iHbnd; - // TODO: Parameters here are placeholders - need to figure out what's right - pNewNode = new CDasherNode(pNode, m_pModel->GetStartConversionSymbol(), 0, Opts::Nodes2, iLbnd, iHbnd, m_pLanguageModel, 1); + // TODO: Parameters here are placeholders - need to figure out + // what's right + + pNewNode = new CDasherNode(pNode, m_pModel->GetStartConversionSymbol(), 0, Opts::Nodes2, iLbnd, iHbnd, m_pLanguageModel, m_pHelper->AssignColour(parentClr, pCurrentSCEChild, iIdx)); // FIXME - handle context properly pNewNode->SetContext(m_pLanguageModel->CreateEmptyContext()); @@ -138,29 +219,31 @@ void CConversionManager::PopulateChildren( CDasherNode *pNode ) { pNewNode->m_pNodeManager = this; pNewNode->m_pNodeManager->Ref(); - pNewNode->m_pUserData = pCurrentCMChild; - pNewNode->m_strDisplayText = pCurrentCMChild->m_strSymbol; + pNewNode->m_pUserData = pCurrentSCEChild; + pNewNode->m_strDisplayText = pCurrentSCEChild->pszConversion; pNewNode->m_bShove = true; pNewNode->m_pBaseGroup = 0; pNode->Children().push_back(pNewNode); - pCurrentCMChild = pCurrentCMChild->m_pNext; + pCurrentSCEChild = pCurrentSCEChild->pNext; ++iIdx; - } - - delete[] iSize; + }while(pCurrentSCEChild); + + } + else { // TODO: Placeholder algorithm here // TODO: Add an 'end of conversion' node? - int iLbnd(0); + int iLbnd(0); int iHbnd(m_pModel->GetLongParameter(LP_NORMALIZATION)); pNewNode = m_pModel->GetRoot(0, pNode, iLbnd, iHbnd, NULL); pNewNode->Seen(false); pNode->Children().push_back(pNewNode); + // pNode->SetHasAllChildren(false); } } @@ -172,97 +255,288 @@ void CConversionManager::ClearNode( CDasherNode *pNode ) { void CConversionManager::BuildTree(CDasherNode *pRoot) { CDasherNode *pCurrentNode(pRoot->Parent()); - + + SCENode * pStartTemp; std::string strCurrentString; - + bool ConversionSuccess; + m_pHelper->ClearData(m_iCMID); + while(pCurrentNode) { if(pCurrentNode->m_pNodeManager->GetID() == 2) break; + + /// std::cout<m_strDisplayText<<" "<Parent()<m_strDisplayText + strCurrentString; pCurrentNode = pCurrentNode->Parent(); } - // Assume that this is sorted: - std::vector > vCandidateList; - m_pHelper->Convert(strCurrentString, vCandidateList); - m_iRootCount = vCandidateList.size(); + ConversionSuccess = m_pHelper ->Convert(strCurrentString, &pStartTemp , &m_iHZCount, m_iCMID); + + //m_iHZCount returned from Convert is not 100% dependable(BUT THE + //FOLLOWING CODE SHOULD FIX IT) + //std::cout << m_iHZCount << std::endl; - if(m_iRootCount == 0) + if((!ConversionSuccess)||(m_iHZCount==0)) m_pRoot = 0; - else { + + else{ - m_pRoot = new CConversionManagerNode *[m_iRootCount]; + if(m_iHZCount>MAX_HZ_NUM) + m_iHZCount = MAX_HZ_NUM; + + m_pRoot = new SCENode *[m_iHZCount]; + + int i; + + for(i=0; (i< m_iHZCount)&&(pStartTemp); i++){ + m_pRoot[i] = new SCENode; + + m_pRoot[i]->pszConversion = "Convert"; + m_pRoot[i]->pChild = pStartTemp; + pStartTemp = pStartTemp->pChild; + m_pRoot[i]->pNext = 0; + m_pRoot[i]->IsHeadAndCandNum = 0; + } + + if(m_pRoot[0]&&(i!=m_iHZCount)) + m_iHZCount = i; + } +} + - for(int i(0); i < m_iRootCount; ++i) { - m_pRoot[i] = new CConversionManagerNode; +//THIS FUNCTION IS CALLED WHEN A SET OF CHILDREN IS BEING POPULATED +//AND BEFORE CALCULATING EACH NODE'S SCORE. THE POSITION IN THE +//SENTENCE IS GIVEN TO THE PY HELPER->LIBRARY AND A LIST OF PHRASES +//CORRESPONDING TO THE CHARACTER IS RETURNED. THESE PHRASES ARE +//PROCESSED INTO THE CONTEXT DATA IN PY HELPER - m_pRoot[i]->m_strSymbol = "Convert"; - m_pRoot[i]->m_pChild = 0; - m_pRoot[i]->m_pNext = 0; - m_pRoot[i]->m_iNumChildren = 0; - m_pRoot[i]->m_iPhrase = i; +void CConversionManager::ProcessPhrase(HZIDX HZIndex){ + + SCENode * pPhraseList; + SCENode * pNode; + + bool stop=0; + int iIdx(0); + int i; + int score[m_iHZCount-HZIndex]; - for(std::vector::iterator it(vCandidateList[i].begin()); it != vCandidateList[i].end(); ++it) { - CConversionManagerNode *pCurrentNode(m_pRoot[i]); - - int iIdx(0); + CANDIDX CandIndex[m_iHZCount-HZIndex]; //list to store candidates + //returned from HZlookup, + //used to allocate data + std::string strtemp; + + std::vector cell; + + if(!(m_pHelper->GetPhraseList(HZIndex, &pPhraseList, m_iCMID))) + return; + + if(pPhraseList->AcCharCount>4) + pNode = pPhraseList->pNext; + else + pNode = pPhraseList; + + while((pNode)&&(iIdx<=MAX_CARE_PHRASE)){ + + //this section needs research. What scores would be a good estimate. + + switch(pNode->AcCharCount){ + case 2: + score[0] = 2; + score[1] = 3; + break; + case 3: + score[0] = 3; + score[1] = 4; + score[2] = 5; + break; + case 4: + score[0] = 4; + score[1] = 5; + score[2] = 6; + score[3] = 7; + break; + default: + for(int j(0); j< m_iHZCount-HZIndex; j++) + score[j] = 5+j; + break; + } + + + for(i=0 ; (iAcCharCount); i++){ + strtemp=pNode->pszConversion; + + //TESTING + //std::cout<<"accharcount"<AcCharCount<pChild->pszConversion<size()) { - - int iLength; - - // TODO: Really dodgy UTF-8 parser - find a library routine to do this - if((static_cast((*it)[iIdx]) & 0x80) == 0) - iLength = 1; - else if((static_cast((*it)[iIdx]) & 0xE0) == 0xC0) - iLength = 2; - else if((static_cast((*it)[iIdx]) & 0xF0) == 0xE0) - iLength = 3; - else if((static_cast((*it)[iIdx]) & 0xF8) == 0xF0) - iLength = 4; - else if((static_cast((*it)[iIdx]) & 0xFC) == 0xF8) - iLength = 5; - else - iLength = 6; + //TESTING + //std::cout<<"the lookup is"< MAX_HZ_NUM -1)) + (*(m_pHelper->GetDP(m_iCMID)))[HZIndex +i][CandIndex[i]][HZIndex].push_back(cell); + cell.clear(); - pNextNode = pCurrentNode->FindChild(it->substr(iIdx, iLength)); - - if(!pNextNode) { - pNextNode = new CConversionManagerNode; - - pNextNode->m_strSymbol = it->substr(iIdx, iLength); - pNextNode->m_pChild = 0; - pNextNode->m_pNext = pCurrentNode->m_pChild; - pNextNode->m_iNumChildren = 0; - pNextNode->m_iPhrase = pCurrentNode->m_iPhrase; - pCurrentNode->m_pChild = pNextNode; - ++pCurrentNode->m_iNumChildren; - } - - pCurrentNode = pNextNode; - iIdx += iLength; } } + + pNode = pNode ->pNext; + iIdx ++; } + m_bPhrasesProcessed[HZIndex]=1; +} + + + +CANDIDX CConversionManager::HZLookup(HZIDX HZIndex, const std::string &strSource){ + + + // this was done before candindex was put into node member, change + // if have time + + int iIdx(0); + if((HZIndex > m_iHZCount-1)||strSource.size()!=3) + return -1; + + SCENode * pNode = m_pRoot[HZIndex]->pChild; + + while(pNode&&(iIdx<=MAX_CARE_CAND)){ + + if(strSource== pNode->pszConversion) + return iIdx; + pNode = pNode->pNext; + iIdx++; } + + return -1; } +//CALCULATES SCORE OF A CERTAIN CANDIDATE HZ CHARACTER NODE TO BE +//POPULATED, FROM THE CONTEXT DATA IN PY HELPER. FINDS VTRACE TO MATCH +//CONTEXT SEQUENCE STORED IN THE LAST LEVEL OF DATABASE + +int CConversionManager::CalculateScore(CDasherNode * pNode, CANDIDX CandIndex){ + CDasherNode *pIterateDNode(pNode); + SCENode *pTemp; + + HZIDX HZIndex; + int score=0; + + bool addtick=1; //bool to signal add score + + + + //THIS SECTION IS TO FIND VTRACE, IN THE SAME WAY AS FINDING INPUT + //PY STRING + + if(m_bTraceNeeded){ + vTrace.clear(); + + while(pIterateDNode&&(pIterateDNode->m_pNodeManager->GetID() == 2)) { + + pTemp=static_cast(pIterateDNode->m_pUserData); + + if(!pTemp) + pIterateDNode=0; + else{ + vTrace.push_back(pTemp->CandIndex); + pIterateDNode= pIterateDNode->Parent(); + } + } + + //THE FOLLOWING IS TESTING FOR VTRACE + // if(vTrace.size()!=0){ + // std::cout<<"signal"<::iterator it(vTrace.begin());it!=vTrace.end();it++) + // std::cout<< *it <=MAX_CARE_CAND) + return 0; + + + + pTemp=static_cast(pNode->m_pUserData); + + if(pTemp) + HZIndex = pTemp->AcCharCount; + else + HZIndex = 0; + + + //THE DATA IS CONSTRUCTED OF UNITS OF SINGLE CELLS STORING CONTEXT SEQUENCE + //AND A CORRESPONDING SCORE + + //LEVEL 1 : HZ INDEX : NUMBER OF CHARACTERS CONVERTED + //LEVEL 2 : CAND INDEX : NUMBER OF CANDIDATES WITH EACH POSITION + //LEVEL 3 : SUB HZ INDEX :(COULD BE REDUNDANT) CORRESPONDES TO + // INDEX OF CHARACTERS WHICH WERE CONSISTED IN PHRASES + //LEVEL 4 : SUB CAND INDEX : WHICH CAND WAS IN THE PHRASE + //LEVLE 5 : CELL: STORING PHASES IN HZ INDEX AND ASSIGNED SCORE + // IN THE WAY: 1.SCORE 2.Z 3.Y 4.X FOR PHRASE XYZ + // PREVIOUSLY PROCESSED + + for(std::vector > >::iterator itIndex((*(m_pHelper->GetDP(m_iCMID)))[HZIndex][CandIndex].begin()); itIndex!=(*(m_pHelper->GetDP(m_iCMID)))[HZIndex][CandIndex].end();itIndex++){ + + for(std::vector >::iterator itCand(itIndex->begin()); itCand!=itIndex->end(); itCand++){ + + //IF HAS LEFT CONTEXT INFORMATION, MATCH VTRACE WITH CELL + //POSITION 1 + + if((*itCand).size() !=1){ + for(int i(0); i<(*itCand).size()-1; i++) + if((*itCand)[i+1]!=vTrace[i]){ + addtick = 0; + break; + } + if(addtick) + score+=(*itCand)[0]; + addtick =1; + } + else + score+=(*itCand)[0]; + } + } + + return score; +} + + void CConversionManager::Output( CDasherNode *pNode, Dasher::VECTOR_SYMBOL_PROB* pAdded, int iNormalization) { m_pModel->m_bContextSensitive = true; - CConversionManagerNode *pCurrentCMNode(static_cast(pNode->m_pUserData)); + SCENode *pCurrentSCENode(static_cast(pNode->m_pUserData)); - if(pCurrentCMNode) { - Dasher::CEditEvent oEvent(1, pCurrentCMNode->m_strSymbol); + if(pCurrentSCENode) { + Dasher::CEditEvent oEvent(1, pCurrentSCENode->pszConversion); m_pModel->InsertEvent(&oEvent); - + if((pNode->GetChildren())[0]->m_pNodeManager != this) { Dasher::CEditEvent oEvent(11, ""); m_pModel->InsertEvent(&oEvent); @@ -275,14 +549,33 @@ void CConversionManager::Output( CDasherNode *pNode, Dasher::VECTOR_SYMBOL_PROB* } void CConversionManager::Undo( CDasherNode *pNode ) { - CConversionManagerNode *pCurrentCMNode(static_cast(pNode->m_pUserData)); + SCENode *pCurrentSCENode(static_cast(pNode->m_pUserData)); - if(pCurrentCMNode) { - if(pCurrentCMNode->m_strSymbol.size() > 0) { - Dasher::CEditEvent oEvent(2, pCurrentCMNode->m_strSymbol); + if(pCurrentSCENode) { + if(strlen(pCurrentSCENode->pszConversion) > 0) { + Dasher::CEditEvent oEvent(2, pCurrentSCENode->pszConversion); m_pModel->InsertEvent(&oEvent); } } } -#endif +bool CConversionManager::RecursiveDelTree(SCENode* pNode){ + + SCENode * pTemp; + + if(!pNode) + return 0; + else if(pNode->pChild) + return RecursiveDelTree(pNode->pChild); + else{ + + while(!pNode->pChild){ + pTemp = pNode->pNext; + delete pNode; + pNode = pTemp; + if(!pNode) + return 1; + } + return RecursiveDelTree(pNode->pChild); + } +} diff --git a/Src/DasherCore/ConversionManager.h b/Src/DasherCore/ConversionManager.h index 9220a097..a6092e29 100644 --- a/Src/DasherCore/ConversionManager.h +++ b/Src/DasherCore/ConversionManager.h @@ -1,12 +1,20 @@ #ifndef __conversion_manager_h__ #define __conversion_manager_h__ + #include "ConversionHelper.h" #include "DasherModel.h" #include "DasherTypes.h" #include "LanguageModelling/LanguageModel.h" // Urgh - we really shouldn't need to know about language models here #include "NodeManager.h" +#include + + +//both of these start from 0 +typedef int HZIDX; +typedef int CANDIDX; + namespace Dasher { class CDasherNode; // Forward declaration @@ -17,15 +25,18 @@ namespace Dasher { class CConversionManager : public CNodeManager { public: // TODO: We shouldn't need to know about this stuff, but the code is somewhat in knots at the moment - CConversionManager(CDasherModel *pModel, CLanguageModel *pLanguageModel, CConversionHelper *pHelper); + CConversionManager(CDasherModel *pModel, CLanguageModel *pLanguageModel, CConversionHelper *pHelper, int CMid); + + ~CConversionManager(); + - ~CConversionManager() { + /* ~CConversionManager() { for(int i(0); i < m_iRootCount; ++i) delete m_pRoot[i]; delete[] m_pRoot; }; - + */ /// /// Increment reference count /// @@ -110,18 +121,38 @@ namespace Dasher { }; }; + bool RecursiveDelTree(SCENode* pNode); + void BuildTree(CDasherNode *pRoot); + void ProcessPhrase(HZIDX HZIndex); + int CalculateScore(CDasherNode * pNode, CANDIDX CandIndex); + + CANDIDX HZLookup(HZIDX HZIndex, const std::string &strSource);//finds the index of a HZ candidate bool m_bTreeBuilt; + bool m_bTraceNeeded; + bool m_bPhrasesProcessed[MAX_HZ_NUM-1]; // flags to signal whether + // phrases are processed + // at a particular Chinese + // HZ index position + - CConversionManagerNode **m_pRoot; - int m_iRootCount; + SCENode **m_pRoot; + + CDasherModel *m_pModel; CLanguageModel *m_pLanguageModel; CConversionHelper *m_pHelper; int m_iRefCount; + int m_iCMID; + int m_iHZCount; + + std::vector vTrace; //used to store the last input string of + //Chinese HZ characters found in + //CalculateScore + }; } diff --git a/Src/DasherCore/ConversionManagerFactory.cpp b/Src/DasherCore/ConversionManagerFactory.cpp index c0790939..e52e2af6 100644 --- a/Src/DasherCore/ConversionManagerFactory.cpp +++ b/Src/DasherCore/ConversionManagerFactory.cpp @@ -2,14 +2,16 @@ #include "config.h" #endif -#ifdef JAPANESE - #include "ConversionManager.h" #include "ConversionManagerFactory.h" #ifdef WIN32 #include "IMEConversionHelper.h" #else -#include "CannaConversionHelper.h" + +#ifdef CHINESE +#include "PinYinConversionHelper.h" +#endif + #endif using namespace Dasher; @@ -20,13 +22,24 @@ CConversionManagerFactory::CConversionManagerFactory(CDasherModel *pModel, CLang #ifdef WIN32 m_pHelper = new CIMEConversionHelper; #else - m_pHelper = new CCannaConversionHelper; +#ifdef CHINESE + m_pHelper = new CPinYinConversionHelper; +#else + m_pHelper = NULL; #endif +#endif + + pagecount = 0; + m_iCMCount = 0; } CDasherNode *CConversionManagerFactory::GetRoot(CDasherNode *pParent, int iLower, int iUpper, void *pUserData) { - CConversionManager *pConversionManager(new CConversionManager(m_pModel, m_pLanguageModel, m_pHelper)); + CConversionManager *pConversionManager(new CConversionManager(m_pModel, m_pLanguageModel, m_pHelper, m_iCMCount)); + if(m_iCMCount >= MAX_CM_NUM-1){ + pagecount ++; + m_iCMCount =0; + } + else + m_iCMCount++; return pConversionManager->GetRoot(pParent, iLower, iUpper, pUserData); } - -#endif diff --git a/Src/DasherCore/ConversionManagerFactory.h b/Src/DasherCore/ConversionManagerFactory.h index 1457c637..25530d29 100644 --- a/Src/DasherCore/ConversionManagerFactory.h +++ b/Src/DasherCore/ConversionManagerFactory.h @@ -17,6 +17,9 @@ namespace Dasher { CDasherModel *m_pModel; CLanguageModel *m_pLanguageModel; CConversionHelper *m_pHelper; + + int m_iCMCount; + int pagecount;//test }; } diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp index b90c9516..9f2a04c5 100644 --- a/Src/DasherCore/DasherInterfaceBase.cpp +++ b/Src/DasherCore/DasherInterfaceBase.cpp @@ -6,6 +6,7 @@ #include "DasherInterfaceBase.h" +//#include "ActionButton.h" #include "CustomColours.h" #include "DasherViewSquare.h" #include "ControlManager.h" @@ -119,6 +120,7 @@ void CDasherInterfaceBase::Realize() { CreateFactories(); CreateInputFilter(); + SetupActionButtons(); // FIXME - need to rationalise this sort of thing. InvalidateContext(true); @@ -506,6 +508,8 @@ void CDasherInterfaceBase::Redraw(bool bRedrawNodes) { bDecorationsChanged = m_pInputFilter->DecorateView(m_pDasherView); } + DrawActionButtons(); + if(bRedrawNodes || bDecorationsChanged) m_pDasherView->Display(); } @@ -581,6 +585,7 @@ void CDasherInterfaceBase::ChangeScreen(CDasherScreen *NewScreen) { ChangeView(); } + PositionActionButtons(); ScheduleRedraw(); } @@ -905,3 +910,52 @@ void CDasherInterfaceBase::StartShutdown() { bool CDasherInterfaceBase::GetModuleSettings(const std::string &strName, SModuleSettings **pSettings, int *iCount) { return GetModuleByName(strName)->GetSettings(pSettings, iCount); } + +void CDasherInterfaceBase::SetupActionButtons() { + m_vLeftButtons.push_back(new CActionButton); + m_vLeftButtons.push_back(new CActionButton); + + m_vRightButtons.push_back(new CActionButton); + m_vRightButtons.push_back(new CActionButton); +} + +void CDasherInterfaceBase::DestroyActionButtons() { + // TODO: implement and call this +} + +void CDasherInterfaceBase::PositionActionButtons() { + if(!m_DasherScreen) + return; + + int iCurrentOffset(0); + + for(std::vector::iterator it(m_vLeftButtons.begin()); it != m_vLeftButtons.end(); ++it) { + (*it)->SetPosition(0, iCurrentOffset, 32, 32); + iCurrentOffset += 32; + } + + iCurrentOffset = 0; + + for(std::vector::iterator it(m_vRightButtons.begin()); it != m_vRightButtons.end(); ++it) { + (*it)->SetPosition(m_DasherScreen->GetWidth() - 128, iCurrentOffset, 128, 32); + iCurrentOffset += 32; + } +} + +void CDasherInterfaceBase::DrawActionButtons() { + if(!m_DasherScreen) + return; + + for(std::vector::iterator it(m_vLeftButtons.begin()); it != m_vLeftButtons.end(); ++it) + (*it)->Draw(m_DasherScreen); + + for(std::vector::iterator it(m_vRightButtons.begin()); it != m_vRightButtons.end(); ++it) + (*it)->Draw(m_DasherScreen); +} + + +void CDasherInterfaceBase::HandleClickUp(int iX, int iY) { +} + +void CDasherInterfaceBase::HandleClickDown(int iX, int iY) { +} diff --git a/Src/DasherCore/DasherInterfaceBase.h b/Src/DasherCore/DasherInterfaceBase.h index e5874829..aa4dd936 100644 --- a/Src/DasherCore/DasherInterfaceBase.h +++ b/Src/DasherCore/DasherInterfaceBase.h @@ -15,6 +15,7 @@ #include "CustomColours.h" #include "ColourIO.h" #include "ModuleManager.h" +#include "ActionButton.h" #include "AutoSpeedControl.h" @@ -299,7 +300,10 @@ public: }; void CheckRedraw(); - + + void HandleClickUp(int iX, int iY); + void HandleClickDown(int iX, int iY); + protected: void WriteTrainFileFull(); void WriteTrainFilePartial(); @@ -334,7 +338,7 @@ protected: bool m_bRedrawScheduled; private: - // To be implemented by child class + // To be implemented by child class (TODO - should these be private?) virtual void ScanAlphabetFiles(std::vector &vFileList) = 0; virtual void ScanColourFiles(std::vector &vFileList) = 0; virtual void SetupPaths() = 0; @@ -350,8 +354,15 @@ protected: void Redraw(bool bRedrawNodes); // correct speed. + void SetupActionButtons(); + void DestroyActionButtons(); + void PositionActionButtons(); + void DrawActionButtons(); std::deque m_deGameModeStrings; + + std::vector m_vLeftButtons; + std::vector m_vRightButtons; }; #endif /* #ifndef __DasherInterfaceBase_h__ */ diff --git a/Src/DasherCore/Makefile.am b/Src/DasherCore/Makefile.am dissimilarity index 87% index fd57d660..a92a3019 100644 --- a/Src/DasherCore/Makefile.am +++ b/Src/DasherCore/Makefile.am @@ -1,129 +1,132 @@ -SUBDIRS = LanguageModelling Alphabet - -noinst_LIBRARIES = libdashercore.a -libdashercore_a_SOURCES = AlphabetManager.cpp \ - AlphabetManager.h \ - AlphabetManagerFactory.cpp \ - AlphabetManagerFactory.h \ - AutoSpeedControl.cpp \ - AutoSpeedControl.h \ - BasicLog.cpp \ - BasicLog.h \ - CannaConversionHelper.cpp \ - CannaConversionHelper.h \ - CircleStartHandler.cpp \ - CircleStartHandler.h \ - ClickFilter.cpp \ - ClickFilter.h \ - ColourIO.cpp \ - ColourIO.h \ - ControlManager.cpp \ - ControlManager.h \ - ControlManagerFactory.cpp \ - ControlManagerFactory.h \ - ConversionHelper.h \ - ConversionManager.cpp \ - ConversionManager.h \ - ConversionManagerFactory.cpp \ - ConversionManagerFactory.h \ - CustomColours.cpp \ - CustomColours.h \ - DasherAppInterface.h \ - DasherButtons.cpp \ - DasherButtons.h \ - DasherComponent.cpp \ - DasherComponent.h \ - DasherInput.h \ - DasherInterfaceBase.cpp \ - DasherInterfaceBase.h \ - DasherModel.cpp \ - DasherModel.h \ - DasherModule.cpp \ - DasherModule.h \ - DasherNode.cpp \ - DasherNode.h \ - DasherScreen.h \ - DasherSettingsInterface.cpp \ - DasherSettingsInterface.h \ - DasherTypes.h \ - DasherView.cpp \ - DasherView.h \ - DasherView.inl \ - DasherViewSquare.cpp \ - DasherViewSquare.h \ - DasherViewSquare.inl \ - DasherWidgetInterface.h \ - DefaultFilter.cpp \ - DefaultFilter.h \ - DelayedDraw.cpp \ - DynamicFilter.h \ - DynamicFilter.cpp \ - Event.h \ - EventHandler.cpp \ - EventHandler.h \ - EyetrackerFilter.cpp \ - EyetrackerFilter.h \ - FileLogger.cpp \ - FileLogger.h \ - FrameRate.h \ - GnomeSettingsStore.cpp \ - GnomeSettingsStore.h \ - InputFilter.h \ - MemoryLeak.cpp \ - MemoryLeak.h \ - ModuleFactory.h \ - ModuleManager.cpp \ - ModuleManager.h \ - NodeManager.h \ - NodeManagerFactory.h \ - OneDimensionalFilter.cpp \ - OneDimensionalFilter.h \ - Parameters.h \ - PinYinConversionHelper.cpp \ - PinYinConversionHelper.h \ - SettingsStore.cpp \ - SettingsStore.h \ - SimpleTimer.cpp \ - SimpleTimer.h \ - SocketInput.cpp \ - SocketInput.h \ - SocketInputBase.cpp \ - SocketInputBase.h \ - StartHandler.h \ - StylusFilter.cpp \ - StylusFilter.h \ - TimeSpan.cpp \ - TimeSpan.h \ - TwoBoxStartHandler.cpp \ - TwoBoxStartHandler.h \ - TwoButtonDynamicFilter.cpp \ - TwoButtonDynamicFilter.h \ - UserButton.cpp \ - UserButton.h \ - UserLocation.cpp \ - UserLocation.h \ - UserLog.cpp \ - UserLog.h \ - UserLogBase.h \ - UserLogParam.cpp \ - UserLogParam.h \ - UserLogTrial.cpp \ - UserLogTrial.h \ - View/DelayedDraw.h \ - WrapperFactory.cpp \ - WrapperFactory.h \ - XMLUtil.cpp \ - XMLUtil.h - -AM_CXXFLAGS = $(GTK2_CFLAGS) $(SETTINGS_CFLAGS) $(gnome_speech_CFLAGS) $(gnome_a11y_CFLAGS) $(glade_CFLAGS) $(gnome_CFLAGS) $(wnck_CFLAGS) -DWNCK_I_KNOW_THIS_IS_UNSTABLE -I$(srcdir)/../DasherCore -DPROGDATA=\"$(pkgdatadir)\" -I../../intl -I$(top_srcdir)/intl - -EXTRA_DIST = \ - LanguageModelling/BigramLanguageModel.cpp \ - LanguageModelling/BigramLanguageModel.h \ - LanguageModelling/KanjiConversionIME.cpp \ - LanguageModelling/KanjiConversionIME.h \ - DasherCore.vcproj \ - DasherCore_vc70.vcproj \ - DasherCore_vc71.vcproj \ - IMEConversionHelper.cpp \ - IMEConversionHelper.h +SUBDIRS = LanguageModelling Alphabet + +noinst_LIBRARIES = libdashercore.a +libdashercore_a_SOURCES = \ + ActionButton.cpp \ + ActionButton.h \ + AlphabetManager.cpp \ + AlphabetManager.h \ + AlphabetManagerFactory.cpp \ + AlphabetManagerFactory.h \ + AutoSpeedControl.cpp \ + AutoSpeedControl.h \ + BasicLog.cpp \ + BasicLog.h \ + CannaConversionHelper.cpp \ + CannaConversionHelper.h \ + CircleStartHandler.cpp \ + CircleStartHandler.h \ + ClickFilter.cpp \ + ClickFilter.h \ + ColourIO.cpp \ + ColourIO.h \ + ControlManager.cpp \ + ControlManager.h \ + ControlManagerFactory.cpp \ + ControlManagerFactory.h \ + ConversionHelper.h \ + ConversionManager.cpp \ + ConversionManager.h \ + ConversionManagerFactory.cpp \ + ConversionManagerFactory.h \ + CustomColours.cpp \ + CustomColours.h \ + DasherAppInterface.h \ + DasherButtons.cpp \ + DasherButtons.h \ + DasherComponent.cpp \ + DasherComponent.h \ + DasherInput.h \ + DasherInterfaceBase.cpp \ + DasherInterfaceBase.h \ + DasherModel.cpp \ + DasherModel.h \ + DasherModule.cpp \ + DasherModule.h \ + DasherNode.cpp \ + DasherNode.h \ + DasherScreen.h \ + DasherSettingsInterface.cpp \ + DasherSettingsInterface.h \ + DasherTypes.h \ + DasherView.cpp \ + DasherView.h \ + DasherView.inl \ + DasherViewSquare.cpp \ + DasherViewSquare.h \ + DasherViewSquare.inl \ + DasherWidgetInterface.h \ + DefaultFilter.cpp \ + DefaultFilter.h \ + DelayedDraw.cpp \ + DynamicFilter.h \ + DynamicFilter.cpp \ + Event.h \ + EventHandler.cpp \ + EventHandler.h \ + EyetrackerFilter.cpp \ + EyetrackerFilter.h \ + FileLogger.cpp \ + FileLogger.h \ + FrameRate.h \ + GnomeSettingsStore.cpp \ + GnomeSettingsStore.h \ + InputFilter.h \ + MemoryLeak.cpp \ + MemoryLeak.h \ + ModuleFactory.h \ + ModuleManager.cpp \ + ModuleManager.h \ + NodeManager.h \ + NodeManagerFactory.h \ + OneDimensionalFilter.cpp \ + OneDimensionalFilter.h \ + Parameters.h \ + PinYinConversionHelper.cpp \ + PinYinConversionHelper.h \ + SettingsStore.cpp \ + SettingsStore.h \ + SimpleTimer.cpp \ + SimpleTimer.h \ + SocketInput.cpp \ + SocketInput.h \ + SocketInputBase.cpp \ + SocketInputBase.h \ + StartHandler.h \ + StylusFilter.cpp \ + StylusFilter.h \ + TimeSpan.cpp \ + TimeSpan.h \ + TwoBoxStartHandler.cpp \ + TwoBoxStartHandler.h \ + TwoButtonDynamicFilter.cpp \ + TwoButtonDynamicFilter.h \ + UserButton.cpp \ + UserButton.h \ + UserLocation.cpp \ + UserLocation.h \ + UserLog.cpp \ + UserLog.h \ + UserLogBase.h \ + UserLogParam.cpp \ + UserLogParam.h \ + UserLogTrial.cpp \ + UserLogTrial.h \ + View/DelayedDraw.h \ + WrapperFactory.cpp \ + WrapperFactory.h \ + XMLUtil.cpp \ + XMLUtil.h + +AM_CXXFLAGS = $(GTK2_CFLAGS) $(SETTINGS_CFLAGS) $(gnome_speech_CFLAGS) $(gnome_a11y_CFLAGS) $(glade_CFLAGS) $(gnome_CFLAGS) $(wnck_CFLAGS) -DWNCK_I_KNOW_THIS_IS_UNSTABLE -I$(srcdir)/../DasherCore -DPROGDATA=\"$(pkgdatadir)\" -I../../intl -I$(top_srcdir)/intl + +EXTRA_DIST = \ + LanguageModelling/BigramLanguageModel.cpp \ + LanguageModelling/BigramLanguageModel.h \ + LanguageModelling/KanjiConversionIME.cpp \ + LanguageModelling/KanjiConversionIME.h \ + DasherCore.vcproj \ + DasherCore_vc70.vcproj \ + DasherCore_vc71.vcproj \ + IMEConversionHelper.cpp \ + IMEConversionHelper.h diff --git a/Src/DasherCore/PinYinConversionHelper.cpp b/Src/DasherCore/PinYinConversionHelper.cpp dissimilarity index 67% index 964fda42..167ff72b 100644 --- a/Src/DasherCore/PinYinConversionHelper.cpp +++ b/Src/DasherCore/PinYinConversionHelper.cpp @@ -1,14 +1,127 @@ -#include "PinYinConversionHelper.h" - -bool CPinYinConversionHelper::Convert(const std::string &strSource, std::vector > &vResult) { - - std::vector vPhrase; - - vPhrase.push_back("hello"); - vPhrase.push_back("foo"); - vPhrase.push_back("fish"); - - vResult.push_back(vPhrase); - - return true; -} +#include "config.h" +#ifdef CHINESE + +#include +#include +#include "PinYinConversionHelper.h" + + +CPinYinConversionHelper::CPinYinConversionHelper(){ + + BuildDataBase(); + CEInitialise(); + + colourStore[0][0]=66;//light blue + colourStore[0][1]=64;//very light green + colourStore[0][2]=62;//light yellow + colourStore[1][0]=78;//light purple + colourStore[1][1]=81;//brownish + colourStore[1][2]=60;//red + + +} + +bool CPinYinConversionHelper::Convert(const std::string &strSource, SCENode ** pRoot, int * HZCount, int CMid) { + + SCENode * pStart; + + if(CEConvert (strSource.c_str(), &pStart, HZCount, CMid)){ + + *pRoot= pStart; + + return 1; + } + else{ + *pRoot = 0; + return 0; + } +} + + +bool CPinYinConversionHelper::GetPhraseList(int HZIndex, SCENode ** psOutput, int CMid){ + SCENode * pStart; + + if(CEGetPhraseList(HZIndex, &pStart, CMid)){ + + *psOutput= pStart; + + return 1; + } + else{ + *psOutput = 0; + return 0; + } +} + +void CPinYinConversionHelper::BuildDataBase(){ + + std::vector > > > >IndexStack; + std::vector > > >CandStack; + std::vector > > subIndexStack; + std::vector > subCandStack; + std::vector cell; + + vContextData.clear(); + cell.push_back(0); + subCandStack.push_back(cell); + + + for(int i(0); i cell; + cell.push_back(0); + + for(int i(0); ipChild->IsHeadAndCandNum)*/; j++){ + for(int k(0); k > > > > * CPinYinConversionHelper::GetDP(int CMid){ + + return &vContextData[CMid]; + +} + + +int CPinYinConversionHelper::AssignColour(int parentClr, SCENode* pNode, int childIndex){ + + int which = -1; + + + for (int i=0; i<2; i++) + for(int j=0; j<3; j++) + if (parentClr == colourStore[i][j]) + which = i; + + if(which == -1) + return colourStore[0][childIndex%3]; + else if(which == 0) + return colourStore[1][childIndex%3]; + else + return colourStore[0][childIndex%3]; +} + +#endif diff --git a/Src/DasherCore/PinYinConversionHelper.h b/Src/DasherCore/PinYinConversionHelper.h index 4463383d..0c69f06d 100644 --- a/Src/DasherCore/PinYinConversionHelper.h +++ b/Src/DasherCore/PinYinConversionHelper.h @@ -3,9 +3,43 @@ #include "ConversionHelper.h" + + class CPinYinConversionHelper : public CConversionHelper { public: - virtual bool Convert(const std::string &strSource, std::vector > &vResult); + + CPinYinConversionHelper(); + + virtual bool Convert(const std::string &strSource, SCENode ** pRoot, int * HZCount, int CMid); + + virtual bool GetPhraseList(int HZIndex, SCENode ** psOutput, int CMid); + + virtual void BuildDataBase(); + virtual void ClearData(int CMid); + + virtual std::vector > > > > * GetDP(int CMid);// get data pointer + + virtual int AssignColour(int parentClr, SCENode * pNode, int childIndex); + + + //CONTEXT DATA + std::vector > > > > >vContextData; +//THE DATA IS CONSTRUCTED OF UNITS OF SINGLE CELLS STORING CONTEXT SEQUENCE + //AND A CORRESPONDING SCORE + + //LEVEL 1 : HZ INDEX : NUMBER OF CHARACTERS CONVERTED + //LEVEL 2 : CAND INDEX : NUMBER OF CANDIDATES WITH EACH POSITION + //LEVEL 3 : SUB HZ INDEX :(COULD BE REDUNDANT) CORRESPONDES TO + // INDEX OF CHARACTERS WHICH WERE CONSISTED IN PHRASES + //LEVEL 4 : SUB CAND INDEX : WHICH CAND WAS IN THE PHRASE + //LEVLE 5 : CELL: STORING PHASES IN HZ INDEX AND ASSIGNED SCORE + // IN THE WAY: 1.SCORE 2.Z 3.Y 4.X FOR PHRASE XYZ + // PREVIOUSLY PROCESSED + + private: + + int colourStore[2][3]; + }; #endif diff --git a/Src/Makefile.am b/Src/Makefile.am index 183398b7..ba1653ce 100644 --- a/Src/Makefile.am +++ b/Src/Makefile.am @@ -8,7 +8,7 @@ bin_PROGRAMS = dasher if DOGTK2 -SUBDIRS = DasherCore Gtk2 Common Gtk2-Experimental Win32 +SUBDIRS = DasherCore Gtk2 Common Win32 dasher_SOURCES = main.cc AM_CXXFLAGS = \ diff --git a/configure.in b/configure.in index 55061d24..509028ee 100644 --- a/configure.in +++ b/configure.in @@ -93,11 +93,21 @@ AC_ARG_ENABLE([japanese], if test $enableval = "no"; then WITHJAPANESE=false; else - AC_CHECK_LIB(canna, RkBgnBun,, AC_MSG_ERROR([Canna library not found.])) + AC_CHECK_LIB(canna, RkBgnBun,, AC_MSG_ERROR([Canna library not found (required for Japanese).])) WITHJAPANESE=true; fi, WITHJAPANESE=false) +AC_ARG_ENABLE([chinese], + AC_HELP_STRING([--enable-chinese],[build with support for Chinese PinYin entry (experimental -- default is NO)]), + if test $enableval = "no"; then + WITHCHINESE=false; + else + AC_CHECK_LIB(ce, CEConvert, , AC_MSG_ERROR([CE library not found (required for Chinese).])) + WITHCHINESE=true; + fi, + WITHCHINESE=false) + AC_ARG_WITH([maemo], AC_HELP_STRING([--with-maemo],[build with Maemo support (default is NO)]), if test $withval = "yes"; then @@ -222,6 +232,10 @@ if [[ x"$WITHJAPANESE" = xtrue ]]; then AC_DEFINE([JAPANESE], 1, [Japanese support enabled]) fi +if [[ x"$WITHCHINESE" = xtrue ]]; then + AC_DEFINE([CHINESE], 1, [Chinese support enabled]) +fi + if [[ x"$WITHGPE" = xtrue ]]; then AC_DEFINE([WITH_GPE], 1, [gpe is present]) fi -- 2.11.4.GIT