Index: Fl_Type.cxx
===================================================================
--- Fl_Type.cxx	(revision 8095)
+++ Fl_Type.cxx	(working copy)
@@ -466,6 +466,7 @@
   selected = new_selected = 0;
   visible = 0;
   name_ = 0;
+  dirty_name_ = 0;
   label_ = 0;
   user_data_ = 0;
   user_data_type_ = 0;
@@ -622,6 +623,10 @@
   }
 }
 
+void Fl_Type::dirty_name(const char *n) {
+  storestring(n,dirty_name_);
+}
+
 void Fl_Type::label(const char *n) {
   if (storestring(n,label_,1)) {
     setlabel(label_);
@@ -658,6 +663,13 @@
   if (next) next->prev = prev; else last = prev;
   if (current == this) current = 0;
   if (parent) parent->remove_child(this);
+  if (name_) free((void*)name_);
+  if (dirty_name_) free((void*)dirty_name_);
+  if (label_) free((void*)label_);
+  if (callback_) free((void*)callback_);
+  if (user_data_) free((void*)user_data_);
+  if (user_data_type_) free((void*)user_data_type_);
+  if (comment_) free((void*)comment_);
 }
 
 int Fl_Type::is_parent() const {return 0;}
@@ -871,6 +883,11 @@
     write_word("comment");
     write_word(comment());
   }
+  if (dirty_name()) {
+    write_indent(level+1);
+    write_word("dirty_name");
+    write_word(dirty_name());
+  }
   if (is_parent() && open_) write_word("open");
   if (selected) write_word("selected");
 }
@@ -886,6 +903,8 @@
     callback(read_word());
   else if (!strcmp(c,"comment"))
     comment(read_word());
+  else if (!strcmp(c,"dirty_name"))
+    dirty_name(read_word());
   else if (!strcmp(c,"open"))
     open_ = 1;
   else if (!strcmp(c,"selected"))
Index: Fl_Type.h
===================================================================
--- Fl_Type.h	(revision 8095)
+++ Fl_Type.h	(working copy)
@@ -54,6 +54,7 @@
   Fl_Type();
 
   const char *name_;
+  const char *dirty_name_;
   const char *label_;
   const char *callback_;
   const char *user_data_;
@@ -97,6 +98,8 @@
 
   const char *name() const {return name_;}
   void name(const char *);
+  const char *dirty_name() const {return dirty_name_;}
+  void dirty_name(const char *);
   const char *label() const {return label_;}
   void label(const char *);
   const char *callback() const {return callback_;}
Index: Fl_Widget_Type.cxx
===================================================================
--- Fl_Widget_Type.cxx	(revision 8095)
+++ Fl_Widget_Type.cxx	(working copy)
@@ -45,6 +45,78 @@
 // instance, sets the widget pointers, and makes all the display
 // update correctly...
 
+char * replace(
+    char const * const original,
+    char const * const pattern,
+    char const * const replacement
+) {
+  size_t const replen = strlen(replacement);
+  size_t const patlen = strlen(pattern);
+  size_t const orilen = strlen(original);
+
+  size_t patcnt = 0;
+  const char * oriptr;
+  const char * patloc;
+
+  // find how many times the pattern occurs in the original string
+  for (oriptr = original; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
+  {
+    patcnt++;
+  }
+
+  {
+    // allocate memory for the new string
+    size_t const retlen = orilen + patcnt * (replen - patlen);
+    char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) );
+
+    if (returned != NULL)
+    {
+      // copy the original string,
+      // replacing all the instances of the pattern
+      char * retptr = returned;
+      for (oriptr = original; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
+      {
+        size_t const skplen = patloc - oriptr;
+        // copy the section until the occurence of the pattern
+        strncpy(retptr, oriptr, skplen);
+        retptr += skplen;
+        // copy the replacement
+        strncpy(retptr, replacement, replen);
+        retptr += replen;
+      }
+      // copy the rest of the string.
+      strcpy(retptr, oriptr);
+    }
+    return returned;
+  }
+}
+
+#ifdef USE_LUA
+#include "luacpp.h"
+extern lua::Lua *Lua;
+#endif
+
+#ifdef USE_STD_STRING
+#include <string>
+void searchAndReplace(std::string& value, std::string const& search,std::string const& replace)
+{
+    std::string::size_type  next;
+
+    for(next = value.find(search);        // Try and find the first match
+        next != std::string::npos;        // next is npos if nothing was found
+        next = value.find(search,next)    // search for the next match starting after
+                                          // the last match that was found.
+       )
+    {
+        // Inside the loop. So we found a match.
+        value.replace(next,search.length(),replace);   // Do the replacement.
+        next += replace.length();                      // Move to just after the replace
+                                                       // This is the point were we start
+                                                       // the next search from.
+    }
+}
+#endif
+
 extern int reading_file;
 int force_parent;
 extern int gridx;
@@ -314,7 +386,10 @@
       snprintf(buf, sizeof(buf), "Widget Properties (%d widgets)", numselected);
       o->hide();
     } else {
-      o->static_value(current_widget->name());
+      o->static_value(
+			current_widget->dirty_name() ?
+			current_widget->dirty_name() :
+			current_widget->name());
       o->show();
       snprintf(buf, sizeof(buf), "%s Properties", current_widget->title());
     }
@@ -322,7 +397,11 @@
     the_panel->label(buf);
   } else {
     if (numselected == 1) {
-      current_widget->name(o->value());
+      const char *aname = o->value();
+      current_widget->dirty_name(aname);
+      char *aname_clean = replace(aname[0] == '@' ? aname+1 : aname, "@", "_");
+      current_widget->name(aname_clean);
+      free(aname_clean);
       // I don't update window title, as it probably is being closed
       // and wm2 (a window manager) barfs if you retitle and then
       // hide a window:
@@ -2071,10 +2150,12 @@
 void Fl_Widget_Type::write_code1() {
   const char* t = subclassname(this);
   const char *c = array_name(this);
+  const char *dn = dirty_name();
+  bool no_new = (dn && dn[0] == '@');
   if (c) {
     if (class_name(1)) {
       write_public(public_);
-      write_h("  %s *%s;\n", t, c);
+      write_h("  %s%s *%s;\n", no_new ? "//" : "", t, c);
     }
   }
   if (class_name(1) && callback() && !is_name(callback())) {
@@ -2128,19 +2209,27 @@
 
   write_c("%s{ ", indent());
   if (varused) write_c("%s* o = ", t);
-  if (name()) write_c("%s = ", name());
+  if (name()) write_c(no_new && varused ? "%s;\n" : "%s = ", c);
+  if(no_new){
+     write_c("%s  Fl_Group::current->add(%s);\n", indent(), c);
+     write_c("%s  %s->resize", indent(), c);
+  } else {
+      write_c("new %s", t);
+  }
   if (is_window()) {
     // Handle special case where user is faking a Fl_Group type as a window,
     // there is no 2-argument constructor in that case:
-    if (!strstr(t, "Window"))
-      write_c("new %s(0, 0, %d, %d", t, o->w(), o->h());
-    else
-      write_c("new %s(%d, %d", t, o->w(), o->h());
+    if (!strstr(t, "Window")){
+      write_c("(0, 0, %d, %d", int(o->w()), int(o->h()));
+    } else {
+      write_c("(%d, %d", int(o->w()), int(o->h()));
+    }
   } else {
-    write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
+    write_c("(%d, %d, %d, %d", int(o->x()), int(o->y()), int(o->w()), int(o->h()));
   }
   if (label() && *label()) {
-    write_c(", ");
+    if(no_new) write_c(");\n%s  %s->label(", indent(), c);
+    else write_c(", ");
     switch (i18n_type) {
     case 0 : /* None */
         write_cstring(label());
@@ -2366,9 +2455,30 @@
 }
 
 void Fl_Widget_Type::write_extra_code() {
-  for (int n=0; n < NUM_EXTRA_CODE; n++)
-    if (extra_code(n) && !isdeclare(extra_code(n)))
-      write_c("%s%s\n", indent(), extra_code(n));
+  for (int n=0; n < NUM_EXTRA_CODE; n++){
+    char *pc, *ec = (char*)extra_code(n);
+    if (ec && !isdeclare(ec)){
+      if(ec[0] == '='){ //do macro substitutions
+          pc = ++ec; //skip "=" 
+          const char *nm = name() ? nm : "o";
+          const char *nk = subclassname(this);
+		  const char *nd = dirty_name();
+          if(name()){
+            if(nd){
+              pc = ec = replace(ec, "$(dirty_name)", nd);
+            } else pc = 0;
+            ec = replace(ec, "$(name)", nm);
+            if(pc) free(pc);
+            pc = ec;
+          }
+          if(nk) pc = replace(ec, "$(class)", nk);
+          write_c("%s%s\n", indent(), pc);
+          if(nm) free(ec);
+          if(nk) free(pc);
+      }
+      else write_c("%s%s\n", indent(), ec);
+    }
+  }
 }
 
 void Fl_Widget_Type::write_block_close() {
