3 // Copyright (c) 2007 The Dasher Team
5 // This file is part of Dasher.
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 #ifndef __controlmanager_h__
22 #define __controlmanager_h__
24 #include "DasherNode.h"
26 #include "NodeManager.h"
27 #include "NodeCreationManager.h"
40 class CNodeCreationManager
;
44 class CDasherInterfaceBase
;
51 /// A node manager which deals with control nodes.
53 class CControlBase
: public CNodeManager
, protected CSettingsUser
{
58 class CContNode
: public CDasherNode
{
60 CControlBase
*mgr() const {return m_pMgr
;}
61 CContNode(int iOffset
, int iColour
, NodeTemplate
*pTemplate
, CControlBase
*pMgr
);
62 CDasherScreen::Label
*getLabel() { return m_pTemplate
->m_pLabel
; }
64 bool bShove() override
{return false;}
65 double SpeedMul() override
;
67 /// Provide children for the supplied node
70 virtual void PopulateChildren();
71 virtual int ExpectedNumChildren();
73 virtual void Output();
76 NodeTemplate
*m_pTemplate
;
82 virtual ~Action() = default;
83 virtual int calculateNewOffset(CControlBase::CContNode
*pNode
, int offsetBefore
) { return offsetBefore
; }
84 virtual void happen(CContNode
*pNode
) {}
86 class NodeTemplate
: public Action
{
88 NodeTemplate(const std::string
&strLabel
, int iColour
);
89 virtual ~NodeTemplate();
90 const std::string m_strLabel
;
92 std::list
<NodeTemplate
*> successors
;
95 friend class CControlBase
;
96 CDasherScreen::Label
*m_pLabel
;
99 NodeTemplate
*GetRootTemplate();
101 CControlBase(CSettingsUser
*pCreateFrom
, CDasherInterfaceBase
*pInterface
, CNodeCreationManager
*pNCManager
);
103 ///Make this manager ready to make nodes renderable on the screen by preallocating labels
104 virtual void ChangeScreen(CDasherScreen
*pScreen
);
107 /// Get a new root node owned by this manager
110 virtual CDasherNode
*GetRoot(CDasherNode
*pContext
, int iOffset
);
111 CDasherInterfaceBase
* GetDasherInterface() { return m_pInterface
; }
113 ///Sets the root - should be called by subclass constructor to make
114 /// superclass ready for use.
115 ///Note, may only be called once, and with a non-null pRoot, or will throw an error message.
116 void SetRootTemplate(NodeTemplate
*pRoot
);
118 CDasherInterfaceBase
*m_pInterface
;
119 CNodeCreationManager
*m_pNCManager
;
121 int getColour(NodeTemplate
*pTemplate
, CDasherNode
*pParent
);
122 CDasherScreen
*m_pScreen
;
125 NodeTemplate
*m_pRoot
;
128 ///Class reads node tree definitions from an XML file, linking together the NodeTemplates
129 /// according to defined names, nesting of <node/>s, and <ref/>s. Also handles the
130 /// <alph/> tag, meaning one child of the node is to escape back to the alphabet. Subclasses
131 /// may override parseAction to provide actions for the nodes to perform, also parseOther
132 /// to link with NodeTemplates from other sources.
133 class CControlParser
: public AbstractXMLParser
{
135 CControlParser(CMessageDisplay
*pMsgs
);
136 ///Loads all node definitions from the specified filename. Note that
137 /// system files will not be loaded if user files are (and user files will
138 /// clear out any nodes from system ones). However, multiple system or multiple
139 /// user files, will be concatenated. (However, files are processed separately:
140 /// e.g. names defined in one file will not be seen from another)
141 /// \param strFilename name+full-path of xml file to load
142 /// \param bUser true if from user-specific location (takes priority over system)
143 /// \return true if the file was opened successfully; false if not.
144 bool ParseFile(const std::string
&strFilename
, bool bUser
);
146 /// \return all node definitions that have been loaded by this CControlParser.
147 const list
<CControlBase::NodeTemplate
*> &parsedNodes();
148 ///Subclasses may override to parse other nodes (besides "node", "ref" and "alph").
149 ///The default implementation always returns NULL.
150 /// \return A node template, if the name was recognised; NULL if not recognised.
151 virtual CControlBase::NodeTemplate
*parseOther(const XML_Char
*name
, const XML_Char
**atts
) {
154 ///Subclasses may override to parse actions within nodes.
155 ///The default implementation always returns NULL.
156 /// \return A (new) action pointer, if the name+attributes were successfully parsed; NULL if not recognised.
157 virtual CControlBase::Action
*parseAction(const XML_Char
*name
, const XML_Char
**atts
) {
160 //TODO cleanup/deletion
161 void XmlStartHandler(const XML_Char
*name
, const XML_Char
**atts
);
162 void XmlEndHandler(const XML_Char
*szName
);
164 ///all top-level parsed nodes
165 std::list
<CControlBase::NodeTemplate
*> m_vParsed
;
166 ///whether parsed nodes were from user file or not
169 ///Following only used as temporary variables during parsing...
170 map
<string
,CControlBase::NodeTemplate
*> namedNodes
;
171 list
<pair
<CControlBase::NodeTemplate
**,string
> > unresolvedRefs
;
172 list
<CControlBase::NodeTemplate
*> nodeStack
;
175 ///subclass which we actually construct! Parses editing node definitions from a file,
176 /// then adds Pause and/or Stop, Speak, and Copy (to clipboard), all as children
177 /// of the "root" control node.
178 class CControlManager
: public CSettingsObserver
, public CControlBase
, public CControlParser
{
180 CControlManager(CSettingsUser
*pCreateFrom
, CNodeCreationManager
*pNCManager
, CDasherInterfaceBase
*pInterface
);
181 void HandleEvent(int iParameter
);
184 EDIT_CHAR
, EDIT_WORD
, EDIT_SENTENCE
, EDIT_PARAGRAPH
, EDIT_FILE
, EDIT_LINE
, EDIT_PAGE
, EDIT_SELECTION
,
187 ///Recomputes which of pause, stop, speak and copy the root control node should have amongst its children.
188 /// Automatically called whenever copy-on-stop/speak-on-stop or input filter changes;
189 /// subclasses of CDasherInterfaceBase should also call this if
190 /// (a) they override Stop() and hasStopTriggers() with additional actions, if these are enabled/disabled
191 /// and this causes the value returned by hasStopTriggers() to change;
192 /// (b) the values returned by SupportsSpeech() and/or SupportsClipboard() ever change.
193 void updateActions();
197 ///Override to allow a <root/> tag to include a fresh control root
198 NodeTemplate
*parseOther(const XML_Char
*name
, const XML_Char
**atts
);
199 ///Override to recognise <move/> and <delete/> tags as actions.
200 Action
*parseAction(const XML_Char
*name
, const XML_Char
**atts
);
203 map
<string
, CControlBase::Action
*> m_actions
;
204 ///group of statefull actions (all/new/repeat/...)
205 SpeechHeader
*m_pSpeech
;
210 class CControlBoxIO
: public AbstractXMLParser
{
212 CControlBoxIO(CMessageDisplay
*pMsgs
);
213 void GetControlBoxes(std::vector
< std::string
> *pList
) const;
214 CControlManager
* CreateControlManager(const std::string
& id
, CSettingsUser
*pCreateFrom
, CNodeCreationManager
*pNCManager
, CDasherInterfaceBase
*pInterface
) const;
215 bool ParseFile(const std::string
&strFilename
, bool bUser
) override
;
216 void XmlStartHandler(const XML_Char
*name
, const XML_Char
**atts
) override
;
217 void XmlEndHandler(const XML_Char
*szName
) override
{};
219 std::map
<std::string
, std::string
> m_controlFiles
;
220 std::string m_filename
;