From 019a7a186b01ed4d889421e9c22400752047f5b4 Mon Sep 17 00:00:00 2001
From: ehofman <ehofman>
Date: Tue, 29 Mar 2005 08:35:13 +0000
Subject: [PATCH] Melchior FRANZ:

showDialog() is careful not to create a new FGDialog() if a dialog with the
same name is already open (active). But at this point it is already too late:
newDialog(), which was called shortly before, has already overwritten the
dialog properties. This leads to animated garbage in the best case, and a
segfault in format_callback() in the worst case.

- GUI::newDialog(): Don't you overwrite properties of an active dialog!
- GUI::readDir(): You may do that, but delete the old dialog first!
  (necessary for reloading the GUI)

- FGDialog::makeObject(): only set format_callback() with setRenderCallback()
  if the property is "live". Otherwise, only call it once at construction
  time. This isn't only a performance improvement. Without this the label
  was growing until it hit the limit (256).
---
 src/GUI/dialog.cxx  | 19 +++++++++++++------
 src/GUI/new_gui.cxx | 14 ++++++++++----
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx
index bcafd67ae..f5d199d7a 100644
--- a/src/GUI/dialog.cxx
+++ b/src/GUI/dialog.cxx
@@ -101,7 +101,7 @@ format_callback(puObject *obj, int dx, int dy, void *n)
 {
     SGPropertyNode *node = (SGPropertyNode *)n;
     const char *format = node->getStringValue("format"), *f = format;
-    bool number;
+    bool number, l = false;
     // make sure the format matches '[ -+#]?\d*(\.\d*)?l?[fs]'
     for (; *f; f++) {
         if (*f == '%') {
@@ -123,13 +123,15 @@ format_callback(puObject *obj, int dx, int dy, void *n)
             f++;
     }
     if (*f == 'l')
-        f++;
+        l = true, f++;
 
     if (*f == 'f')
         number = true;
-    else if (*f == 's')
+    else if (*f == 's') {
+        if (l)
+            return;
         number = false;
-    else
+    } else
         return;
 
     for (++f; *f; f++) {
@@ -420,8 +422,13 @@ FGDialog::makeObject (SGPropertyNode * props, int parentWidth, int parentHeight)
         puText * text = new puText(x, y);
         setupObject(text, props);
 
-        if (props->getNode("format"))
-            text->setRenderCallback(format_callback, props);
+        if (props->getNode("format")) {
+            SGPropertyNode *live = props->getNode("live");
+            if (live && live->getBoolValue())
+                text->setRenderCallback(format_callback, props);
+            else
+                format_callback(text, x, y, props);
+        }
         // Layed-out objects need their size set, and non-layout ones
         // get a different placement.
         if(presetSize) text->setSize(width, height);
diff --git a/src/GUI/new_gui.cxx b/src/GUI/new_gui.cxx
index 65bdd9add..fce518055 100644
--- a/src/GUI/new_gui.cxx
+++ b/src/GUI/new_gui.cxx
@@ -185,8 +185,9 @@ NewGUI::newDialog (SGPropertyNode* props)
         SG_LOG(SG_GENERAL, SG_ALERT, "New dialog has no <name> property");
         return;
     }
-    string name = props->getStringValue("name");
-    _dialog_props[name] = props;
+    string name = cname;
+    if(!_active_dialogs[name])
+        _dialog_props[name] = props;
 }
 
 void
@@ -218,13 +219,18 @@ NewGUI::readDir (const char * path)
                 delete props;
                 continue;
             }
-            if (!props->hasValue("name")) {
+            SGPropertyNode *nameprop = props->getNode("name");
+            if (!nameprop) {
                 SG_LOG(SG_INPUT, SG_WARN, "dialog " << subpath
                    << " has no name; skipping.");
                 delete props;
                 continue;
             }
-            newDialog(props);
+            string name = nameprop->getStringValue();
+            if (_dialog_props[name])
+                delete (SGPropertyNode *)_dialog_props[name];
+
+            _dialog_props[name] = props;
         }
     }
     ulCloseDir(dir);