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"
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
{
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
) {
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;
40 bool m_bSystem
, m_bUser
;
42 CDasherInterfaceBase
*m_pInterface
;
44 off_t m_iStart
, m_iStop
;
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
) {
61 //TODO: Error reporting here
63 case 0: // No conversion required
64 m_pAlphabetManager
= new CAlphabetManager(this, pInterface
, this, pAlphInfo
);
68 //(ACL) Modify AlphabetManager for Mandarin Dasher
69 m_pAlphabetManager
= new CMandarinAlphMgr(this, pInterface
, this, pAlphInfo
);
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
);
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());
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);
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
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");
114 HandleEvent(LP_ORIENTATION
);
115 CreateControlBox(pControlBoxIO
);
118 CNodeCreationManager::~CNodeCreationManager() {
119 delete m_pAlphabetManager
;
122 delete m_pControlManager
;
125 void CNodeCreationManager::ChangeScreen(CDasherScreen
*pScreen
) {
126 if (m_pScreen
== pScreen
) return;
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;
142 m_pControlManager
= NULL
;
145 m_iAlphNorm
= CDasherModel::NORMALIZATION
-iControlSpace
;
148 void CNodeCreationManager::AddExtras(CDasherNode
*pParent
) {
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
);
160 CNodeCreationManager::ImportTrainingText(const std::string
&strPath
) {
161 ProgressNotifier
pn(m_pInterface
, m_pTrainer
);
162 pn
.ParseFile(strPath
, true);