Updated German translation
[dasher.git] / Src / DasherCore / NodeCreationManager.cpp
blobf2145c586763886f1977adfa60b13a95a63f9006
1 #include "DasherNode.h"
2 #include "DasherInterfaceBase.h"
3 #include "NodeCreationManager.h"
4 #include "MandarinAlphMgr.h"
5 #include "RoutingAlphMgr.h"
6 #include "ConvertingAlphMgr.h"
7 #include "ControlManager.h"
8 #include "Observable.h"
10 #include <string.h>
12 using namespace Dasher;
14 //Wraps the ParseFile of a provided Trainer, to setup progress notification
15 // - and then passes self, as a ProgressIndicator, to the Trainer's ParseFile method.
16 class ProgressNotifier : public AbstractParser, private CTrainer::ProgressIndicator {
17 public:
18 ProgressNotifier(CDasherInterfaceBase *pInterface, CTrainer *pTrainer)
19 : AbstractParser(pInterface), m_bSystem(false), m_bUser(false), m_pInterface(pInterface), m_pTrainer(pTrainer) { }
20 void bytesRead(off_t n) {
21 int iNewPercent = ((m_iStart + n)*100)/m_iStop;
22 if (iNewPercent != m_iPercent) {
23 m_pInterface->SetLockStatus(m_strDisplay, m_iPercent = iNewPercent);
26 bool ParseFile(const string &strFilename, bool bUser) {
27 m_iStart = 0;
28 m_iStop = m_pInterface->GetFileSize(strFilename);
29 if (m_iStop==0) return false;
30 return AbstractParser::ParseFile(strFilename, bUser);
32 bool Parse(const string &strUrl, istream &in, bool bUser) {
33 m_strDisplay = bUser ? _("Training on User Text") : _("Training on System Text");
34 m_pInterface->SetLockStatus(m_strDisplay, m_iPercent=0);
35 m_pTrainer->SetProgressIndicator(this);
36 if (!m_pTrainer->Parse(strUrl, in, bUser)) return false;
37 if (bUser) m_bUser=true; else m_bSystem=true;
38 return true;
40 bool m_bSystem, m_bUser;
41 private:
42 CDasherInterfaceBase *m_pInterface;
43 CTrainer *m_pTrainer;
44 off_t m_iStart, m_iStop;
45 int m_iPercent;
46 string m_strDisplay;
49 CNodeCreationManager::CNodeCreationManager(
50 CSettingsUser *pCreateFrom,
51 Dasher::CDasherInterfaceBase *pInterface,
52 const Dasher::CAlphIO *pAlphIO,
53 const Dasher::CControlBoxIO *pControlBoxIO
54 ) : CSettingsUserObserver(pCreateFrom),
55 m_pInterface(pInterface), m_pControlManager(NULL), m_pScreen(NULL) {
57 const Dasher::CAlphInfo *pAlphInfo(pAlphIO->GetInfo(GetStringParameter(SP_ALPHABET_ID)));
59 switch (pAlphInfo->m_iConversionID) {
60 default:
61 //TODO: Error reporting here
62 //fall through to
63 case 0: // No conversion required
64 m_pAlphabetManager = new CAlphabetManager(this, pInterface, this, pAlphInfo);
65 break;
66 case 2:
67 //Mandarin Dasher!
68 //(ACL) Modify AlphabetManager for Mandarin Dasher
69 m_pAlphabetManager = new CMandarinAlphMgr(this, pInterface, this, pAlphInfo);
70 break;
71 case 3: //these differ only in that conversion id 3 assumes the route by which
72 case 4: //the user writes a symbol, is not dependent on context (e.g. just user preference),
73 //whereas 4 assumes it does depend on context (e.g. phonetic chinese)
74 m_pAlphabetManager = new CRoutingAlphMgr(this, pInterface, this, pAlphInfo);
75 break;
76 //TODO: we could even just switch from standard alphmgr, to case 3, automatically
77 // if the alphabet has repeated symbols; and thus do away with much of the "conversionid"
78 // tag (just a flag for context-sensitivity, and maybe the start/stop delimiters?)
80 //all other configuration changes, etc., that might be necessary for a particular conversion mode,
81 // are implemented by AlphabetManager subclasses overriding the following two methods:
82 m_pAlphabetManager->Setup();
83 m_pTrainer = m_pAlphabetManager->GetTrainer();
85 if (!pAlphInfo->GetTrainingFile().empty()) {
86 ProgressNotifier pn(pInterface, m_pTrainer);
87 pInterface->ScanFiles(&pn,pAlphInfo->GetTrainingFile());
88 if (!pn.m_bUser) {
89 ///TRANSLATORS: These 3 messages will be displayed when the user has just chosen a new alphabet. The %s parameter will be the name of the alphabet.
90 const char *msg = pn.m_bSystem ? _("No user training text found - if you have written in \"%s\" before, this means Dasher may not be learning from previous sessions")
91 : _("No training text (user or system) found for \"%s\". Dasher will still work but entry will be slower. We suggest downloading a training text file from the Dasher website, or constructing your own.");
92 pInterface->FormatMessageWithString(msg, pAlphInfo->GetID().c_str());
94 //3. Finished, so unlock.
95 m_pInterface->SetLockStatus("", -1);
96 } else {
97 pInterface->FormatMessageWithString(_("\"%s\" does not specify training file. Dasher will work but entry will be slower. Check you have the latest version of the alphabet definition."), pAlphInfo->GetID().c_str());
99 #ifdef DEBUG_LM_READWRITE
101 //test...
102 pLanguageModel->WriteToFile("test.model");
103 CPPMLanguageModel *pLan = (CPPMLanguageModel *)pLanguageModel;
104 CPPMLanguageModel *pLM2 = new CPPMLanguageModel(pEventHandler, pSettingsStore, pAlphInfo);
105 pLM2->ReadFromFile("test.model");
106 if (!pLan->eq(pLM2)) {
107 std::cout << "Not equal!" << std::endl;
108 pLM2->WriteToFile("test2.model");
110 delete pLM2;
112 #endif
114 HandleEvent(LP_ORIENTATION);
115 CreateControlBox(pControlBoxIO);
118 CNodeCreationManager::~CNodeCreationManager() {
119 delete m_pAlphabetManager;
120 delete m_pTrainer;
122 delete m_pControlManager;
125 void CNodeCreationManager::ChangeScreen(CDasherScreen *pScreen) {
126 if (m_pScreen == pScreen) return;
127 m_pScreen = pScreen;
128 m_pAlphabetManager->MakeLabels(pScreen);
129 if (m_pControlManager) m_pControlManager->ChangeScreen(pScreen);
132 void CNodeCreationManager::CreateControlBox(const CControlBoxIO* pControlIO) {
133 delete m_pControlManager;
134 unsigned long iControlSpace;
135 //don't allow a control manager during Game Mode
136 if (GetBoolParameter(BP_CONTROL_MODE) && !m_pInterface->GetGameModule()) {
137 auto id = GetStringParameter(SP_CONTROL_BOX_ID);
138 m_pControlManager = pControlIO->CreateControlManager(id, this, this, m_pInterface);
139 if (m_pScreen) m_pControlManager->ChangeScreen(m_pScreen);
140 iControlSpace = CDasherModel::NORMALIZATION / 20;
141 } else {
142 m_pControlManager = NULL;
143 iControlSpace = 0;
145 m_iAlphNorm = CDasherModel::NORMALIZATION-iControlSpace;
148 void CNodeCreationManager::AddExtras(CDasherNode *pParent) {
149 //control mode:
150 DASHER_ASSERT(pParent->GetChildren().back()->Hbnd() == m_iAlphNorm);
151 if (m_pControlManager) {
152 //ACL leave offset as is - like its groupnode parent, but unlike its alphnode siblings,
153 //the control node does not enter a symbol....
154 CDasherNode *ctl = m_pControlManager->GetRoot(pParent, pParent->offset());
155 ctl->Reparent(pParent, pParent->GetChildren().back()->Hbnd(), CDasherModel::NORMALIZATION);
159 void
160 CNodeCreationManager::ImportTrainingText(const std::string &strPath) {
161 ProgressNotifier pn(m_pInterface, m_pTrainer);
162 pn.ParseFile(strPath, true);