GlsMenu
gls_menu_set.h
Go to the documentation of this file.
1 
41 #if !defined(GLS_MENUSET_H)
42 #define GLS_MENUSET_H
43 
44 #ifdef WIN32
45 #pragma warning (disable:4786)
46 #endif
47 
48 #include <string>
49 #include <fstream>
50 #include <FL/filename.H>
51 
52 #include "gls_menu_data.h"
53 #include "util.h"
54 
55 
56 
57 //----------------------------------------------------------------------------
66 //----------------------------------------------------------------------------
67 template <class MenuType_t, class DataFactory_t>
69 {
70 public:
71 
72  typedef MenuType_t Menu_t;
73 
74  //------------------------------------------------------------------------
78  //------------------------------------------------------------------------
80  _currentMenu(0),
81  _menuData(data),
82  _menus(new GlsMenuHandlerGroup_T<Menu_t>("Menus", data, _actionHandlers))
83  {
84  // Register a default action called ShowMenu that chooses a
85  // particular menu to currently show. This allows to navigate
86  // a menu system from the menu script files. A script can
87  // contain an action like:
88  // ShowMenu: SUB_MENU
89  // which will navigate to a menu named SUB_MENU
91  "ShowMenu",
93 
95  "Toggle",
98  "Set",
101  "Inc",
103 
104  // Deprecated callbacks, still here for backwards support
106  "ToggleData",
109  "SetData",
112  "SetDataNoExpand",
114 
115 
116  // Initialize the contents of a GlsMenuSet by adding attributes
117  // to its attribute dictionary. A menu set has the following
118  // "attributes", each of which are menu data:
119  // Data: this is a group of data items that are declared in the
120  // menu script and created at run-time
121  // Menus: this defines the menu structure.
122  _menuStructure.Add(new DataFactory_t("Data", _menuData));
123  _menuStructure.Add(_menus);
124  }
125 
126  //------------------------------------------------------------------------
130  //------------------------------------------------------------------------
131  virtual ~GlsMenuSet_T()
132  {
133  std::map<std::string, GlsMenuAction::ActionHandler_t*>::iterator iter;
134 
135  for (iter = _actionHandlers.begin(); iter != _actionHandlers.end(); ++iter)
136  {
137  GlsMenuAction::ActionHandler_t* actionHandler = iter->second;
138  if (actionHandler)
139  {
140  delete actionHandler;
141  actionHandler = NULL;
142  }
143  }
144 
145  _actionHandlers.clear();
146  }
147 
148  //------------------------------------------------------------------------
152  //------------------------------------------------------------------------
153  Menu_t* Current() const { return _currentMenu; }
154 
155  //------------------------------------------------------------------------
166  //------------------------------------------------------------------------
168  const std::string& name,
170  {
171  _actionHandlers[name] = handler;
172  }
173 
174  //------------------------------------------------------------------------
180  //------------------------------------------------------------------------
181  void SelectItem(const typename Menu_t::ItemId_t& itemId)
182  {
183  if (_currentMenu)
184  _currentMenu->SelectItem(itemId);
185  }
186 
187  //------------------------------------------------------------------------
193  //------------------------------------------------------------------------
194  virtual void Show(const std::string& menuName = "")
195  {
196  // Ensure there are no leading spaces
197  std::string::size_type start(menuName.find_first_not_of(' '));
198 
199  if (start == std::string::npos)
200  start = 0;
201 
202  // If the menu name is not empty, expand it in case it contains
203  // variables.
204  disti::AttributeName newMenuName(
205  menuName.empty() ?
206  _showMenuName : disti::DecodeString(menuName.substr(start)));
207 
208  // If there is no current menu or the current menu's name is not
209  // the desired menu to show
210  if (!_currentMenu || !(_currentMenu->Name() == newMenuName))
211  {
212  Menu_t* newMenu = _menus->Item(newMenuName);
213 
214  if (newMenu)
215  {
216  // Always invoke hide on the menu being hidden so its
217  // actions can be invoked if any.
218  if (_currentMenu)
219  _currentMenu->Hide();
220 
221  _currentMenu = newMenu;
222  _showMenuName = _currentMenu->Name();
223 
224  newMenu->Show();
225  }
226  }
227  }
228 
229  //------------------------------------------------------------------------
235  //------------------------------------------------------------------------
236  virtual void Read(std::istream& instr)
237  {
238  _menuStructure.Read(instr);
239  }
240 
241  //------------------------------------------------------------------------
247  //------------------------------------------------------------------------
248  void Read(const std::string& filename)
249  {
250  std::ifstream fstr;
251  fstr.open(filename.c_str());
252 
253  if (!fstr.is_open())
254  {
255  fprintf(stderr,"Unable to open file: %s\n", filename.c_str());
256  perror("Opening");
257  return;
258  }
259 
260  Read(fstr);
261  fstr.close();
262  }
263 
264  //------------------------------------------------------------------------
272  //------------------------------------------------------------------------
274  const std::string& directory,
275  const std::string& ext = "menu")
276  {
277  const std::string MENU_EXT(disti::Uppercase(ext));
278  int fileCount(0);
279  dirent** flist = 0;
280  std::string fileDir(directory);
281  disti::AppendTrailingSlash(fileDir);
282 
283  fileCount = fl_filename_list(fileDir.c_str(), &flist);
284 
285  // Go through the list of files looking for file
286  // of type *.{ext} regardless of capitalization.
287  for (int fileNum = 0; fileNum < fileCount; ++fileNum)
288  {
289  std::string fileExt = disti::GetExtension(flist[fileNum]->d_name);
290  if( !fileExt.empty() )
291  {
292  fileExt = disti::Uppercase(fileExt);
293  }
294  if (fileExt == MENU_EXT)
295  {
296  std::string menuFile(fileDir + flist[fileNum]->d_name);
297  Read(menuFile);
298 
299  } // end if
300  } // end for
301 
302  // Free the list of filename strings.
303  if (flist)
304  {
305  for (int i = fileCount - 1; i >= 0; --i)
306  {
307  free((void*)(flist[i]));
308  }
309 
310  free((void*)flist);
311  }
312  }
313 
314  //------------------------------------------------------------------------
320  //------------------------------------------------------------------------
321  void Write(std::ostream& outstr)
322  {
323  _menuStructure.Write(outstr);
324  }
325 
326  //------------------------------------------------------------------------
332  //------------------------------------------------------------------------
333  void Write(const std::string& filename)
334  {
335  std::fstream fstr;
336  fstr.open(filename.c_str(), std::ios::out);
337 
338  if (!fstr.is_open())
339  {
340  fprintf(stderr,"Unable to open file: %s\n",filename);
341  return;
342  }
343 
344  // Set some defaults
345  fstr.setf(std::ios_base::fixed, std::ios::floatfield);
346  fstr.precision(6);
347 
348  Write(fstr);
349  fstr.close();
350  }
351 
352 
353 protected:
354 
358 
361 
364 
365  std::string _showMenuName;
366 
368  Menu_t* _currentMenu;
369 
372 
373 private:
374 
375  //------------------------------------------------------------------------
379  //------------------------------------------------------------------------
380  void ShowMenu(std::istream& args)
381  {
382  std::string menuName;
383  std::getline(args, menuName);
384  Show(menuName);
385  }
386 
387  //------------------------------------------------------------------------
391  //------------------------------------------------------------------------
392  void ToggleData(std::istream& args) const
393  {
394  std::string nameStr;
395  std::string val1;
396  std::string val2;
397 
398  if ( GetQuoted(args, nameStr)
399  && GetQuoted(args, val1)
400  && GetQuoted(args, val2) )
401  {
402  disti::AttributeName name(nameStr);
403 
404  if (_menuData.ValueString(name) == val1)
405  _menuData.ValueString(name, val2);
406  else
407  _menuData.ValueString(name, val1);
408  }
409 
410  }
411 
412  //------------------------------------------------------------------------
416  //------------------------------------------------------------------------
417  void SetData(std::istream& args) const
418  {
419  std::string name;
420  std::string val;
421 
422  while ( GetQuoted(args, name)
423  && GetQuoted(args, val) )
424  {
425  _menuData.ValueString(
426  disti::AttributeName(name), val);
427  }
428  }
429 
430  //------------------------------------------------------------------------
434  //------------------------------------------------------------------------
435  void SetDataNoExpand(std::istream& args) const
436  {
437  std::string name;
438  std::string val;
439 
440  while ( GetQuoted(args, name)
441  && GetQuoted(args, val) )
442  {
443  _menuData.ValueString(
444  disti::AttributeName(name), val);
445  }
446 
447  }
448 
449  //------------------------------------------------------------------------
453  //------------------------------------------------------------------------
454  void IncData(std::istream& args) const
455  {
456  std::string name;
457 
458  if (GetQuoted(args, name))
459  {
460  int incBy(1);
461  args >> incBy;
462 
463  GlsMenuData* data =
464  dynamic_cast<GlsMenuData*>(
465  _menuData.Get(disti::AttributeName(name)));
466  if (data)
467  data->Inc(incBy);
468  }
469  }
470 
471  // = Unimplemented methods, disallow copies
472  GlsMenuSet_T (const GlsMenuSet_T&);
474 
475 }; // end GlsMenuSet_T
476 
477 
478 #endif // GLS_MENUSET_H
479 
This file defines all menu meta-data classes.
void RegisterAction(const std::string &name, GlsMenuAction::ActionHandler_t *handler)
Definition: gls_menu_set.h:167
virtual ~GlsMenuSet_T()
Definition: gls_menu_set.h:131
void SetDataNoExpand(std::istream &args) const
Definition: gls_menu_set.h:435
std::map< std::string, ActionHandler_t * > HandlerCont_t
Menu_t * _currentMenu
Currently displayed menu page.
Definition: gls_menu_set.h:368
bool GetQuoted(std::istream &instr, std::string &theString)
GlsMenuDictionary _menuStructure
Menu structure attribute dictionary contains structure of menu.
Definition: gls_menu_set.h:360
GlsMenuHandlerGroup_T< Menu_t > * _menus
Set of all menus.
Definition: gls_menu_set.h:371
void ShowMenu(std::istream &args)
Definition: gls_menu_set.h:380
void Write(std::ostream &outstr)
Definition: gls_menu_set.h:321
GlsMenuSet_T(GlsMenuDictionary &data)
Definition: gls_menu_set.h:79
void SelectItem(const typename Menu_t::ItemId_t &itemId)
Definition: gls_menu_set.h:181
void SetData(std::istream &args) const
Definition: gls_menu_set.h:417
std::string _showMenuName
Definition: gls_menu_set.h:365
GlsMenuDictionary & _menuData
Menu meta-data attribute dictionary contains variables and values.
Definition: gls_menu_set.h:363
void Write(const std::string &filename)
Definition: gls_menu_set.h:333
MenuType_t Menu_t
Definition: gls_menu_set.h:72
void ReadMenuFiles(const std::string &directory, const std::string &ext="menu")
Definition: gls_menu_set.h:273
void Read(const std::string &filename)
Definition: gls_menu_set.h:248
Menu_t * Current() const
Definition: gls_menu_set.h:153
GlsMenuSet_T & operator=(const GlsMenuSet_T &)
GlsMenuAction::HandlerCont_t _actionHandlers
Handlers for menu actions local to an instance of a menu set. Each menu set can have its own set of a...
Definition: gls_menu_set.h:357
virtual void Show(const std::string &menuName="")
Definition: gls_menu_set.h:194
void IncData(std::istream &args) const
Definition: gls_menu_set.h:454
void ToggleData(std::istream &args) const
Definition: gls_menu_set.h:392
GlsStaticMemberFunctor_T< T > * GlsFunctor(T(*f)())
Definition: gls_functor.h:100
virtual void Inc(long amount=1)
T * Item(const std::string &name) const
virtual void Read(std::istream &instr)
Definition: gls_menu_set.h:236