#include <plib/pu.h>
#include <plib/ul.h>
-#include <simgear/misc/exception.hxx>
+#include <simgear/compiler.h>
+#include <simgear/structure/exception.hxx>
+
#include <Main/fg_props.hxx>
#include "menubar.hxx"
#include "dialog.hxx"
+SG_USING_STD(map);
\f
////////////////////////////////////////////////////////////////////////
NewGUI::~NewGUI ()
{
- delete _menubar;
+ clear();
}
void
ulMakePath(path1, globals->get_fg_root().c_str(), "gui");
ulMakePath(path2, path1, "dialogs");
readDir(path2);
-#if !defined(FG_OLD_MENUBAR)
_menubar->init();
-#endif
}
void
NewGUI::reinit ()
{
unbind();
-
-#if !defined(FG_OLD_MENUBAR)
- delete _menubar;
+ clear();
_menubar = new FGMenuBar;
-#endif
- _dialog_props.clear();
-
init();
bind();
}
SG_LOG(SG_GENERAL, SG_ALERT, "Dialog " << name << " not defined");
return false;
} else {
- new FGDialog(_dialog_props[name]); // it will be deleted by a callback
+ if(!_active_dialogs[name])
+ _active_dialogs[name] = new FGDialog(_dialog_props[name]);
return true;
}
}
bool
NewGUI::closeActiveDialog ()
{
- if (_active_dialog == 0) {
+ if (_active_dialog == 0)
return false;
- } else {
- delete _active_dialog;
- _active_dialog = 0;
+
+ // Kill any entries in _active_dialogs... Is there an STL
+ // algorithm to do (delete map entries by value, not key)? I hate
+ // the STL :) -Andy
+ map<string,FGDialog *>::iterator iter = _active_dialogs.begin();
+ for(/**/; iter != _active_dialogs.end(); iter++)
+ if(iter->second == _active_dialog)
+ _active_dialogs.erase(iter);
+
+ delete _active_dialog;
+ _active_dialog = 0;
+ return true;
+}
+
+bool
+NewGUI::closeDialog (const string& name)
+{
+ if(_active_dialogs.find(name) != _active_dialogs.end()) {
+ if(_active_dialog == _active_dialogs[name])
+ _active_dialog = 0;
+ delete _active_dialogs[name];
+ _active_dialogs.erase(name);
return true;
}
+ return false; // dialog wasn't open...
}
void
_menubar->hide();
}
+void
+NewGUI::clear ()
+{
+ delete _menubar;
+ _menubar = 0;
+ _dialog_props.clear();
+}
+
+static bool
+test_extension (const char * path, const char * ext)
+{
+ int pathlen = strlen(path);
+ int extlen = strlen(ext);
+
+ for (int i = 1; i <= pathlen && i <= extlen; i++) {
+ if (path[pathlen-i] != ext[extlen-i])
+ return false;
+ }
+ return true;
+}
+
+void
+NewGUI::newDialog (SGPropertyNode* props)
+{
+ const char* cname = props->getStringValue("name");
+ if(!cname) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "New dialog has no <name> property");
+ return;
+ }
+ string name = props->getStringValue("name");
+ _dialog_props[name] = props;
+}
+
void
NewGUI::readDir (const char * path)
{
return;
}
- ulDirEnt * dirEnt = ulReadDir(dir);
- while (dirEnt != 0) {
+ for (ulDirEnt * dirEnt = ulReadDir(dir);
+ dirEnt != 0;
+ dirEnt = ulReadDir(dir)) {
+
char subpath[1024];
ulMakePath(subpath, path, dirEnt->d_name);
- if (dirEnt->d_isdir && dirEnt->d_name[0] != '.') {
- readDir(subpath);
- } else {
- SGPropertyNode_ptr props = new SGPropertyNode;
+ if (!dirEnt->d_isdir && test_extension(subpath, ".xml")) {
+ SGPropertyNode * props = new SGPropertyNode;
try {
readProperties(subpath, props);
} catch (const sg_exception &ex) {
- SG_LOG(SG_INPUT, SG_ALERT, "Error parsing GUI file "
+ SG_LOG(SG_INPUT, SG_ALERT, "Error parsing dialog "
<< subpath);
+ delete props;
+ continue;
}
if (!props->hasValue("name")) {
- SG_LOG(SG_INPUT, SG_WARN, "GUI file " << subpath
+ SG_LOG(SG_INPUT, SG_WARN, "dialog " << subpath
<< " has no name; skipping.");
- } else {
- string name = props->getStringValue("name");
- SG_LOG(SG_INPUT, SG_BULK, "Saving GUI node " << name);
- _dialog_props[name] = props;
+ delete props;
+ continue;
}
+ newDialog(props);
}
- dirEnt = ulReadDir(dir);
}
ulCloseDir(dir);
}