From d9338083192084613e5530b02710b796252d342b Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Thu, 12 Aug 2010 10:57:04 +0000
Subject: New scripting system part2.

---
 client/collapser.cc                   |  15 +-
 client/collapser.h                    |   2 +
 client/formatparser.cc                |  29 ++--
 client/formatparser.h                 |   4 +-
 client/icons/icon.png                 | Bin 6110 -> 40267 bytes
 client/lua.cc                         | 100 +++++-------
 client/lua.h                          |  18 +--
 client/luawidget.cc                   | 143 ++++++++++++-----
 client/macro.cc                       |   9 +-
 client/macro.h                        |   6 +-
 client/macrodrawer.cc                 |   5 +
 client/macrodrawer.h                  |   2 -
 client/macrowindow.cc                 | 261 ++++++++++--------------------
 client/macrowindow.h                  |  33 +---
 client/mainwindow.cc                  |   4 +
 client/mainwindow.h                   |   2 +-
 client/netcom.cc                      |  17 +-
 client/pracro.cc                      |   7 +-
 client/test.sh                        |   4 +
 client/test/testcomboboxedit.cc       |  23 ++-
 client/test/testcomboboxsearch.cc     |  44 +++---
 client/test/testcomboboxselect.cc     |  22 +--
 client/test/testlineedit.cc           |  10 +-
 client/test/util.cc                   |  17 +-
 client/test/util.h                    |  32 ++--
 client/widgetbuilder.cc               | 169 ++------------------
 client/widgetbuilder.h                |   9 +-
 client/widgets/altcombobox.cc         | 148 +++++++++--------
 client/widgets/altcombobox.h          |  25 +--
 client/widgets/button.cc              | 128 ++++-----------
 client/widgets/button.h               |  34 +---
 client/widgets/checkbox.cc            |  81 +++++-----
 client/widgets/checkbox.h             |  29 ++--
 client/widgets/combobox.cc            | 148 ++++++++---------
 client/widgets/combobox.h             |  31 ++--
 client/widgets/datetime.cc            | 107 +++++--------
 client/widgets/datetime.h             |  26 +--
 client/widgets/dbwidget.cc            | 162 ++++++-------------
 client/widgets/dbwidget.h             |  30 ++--
 client/widgets/frame.cc               |  42 ++---
 client/widgets/frame.h                |  19 ++-
 client/widgets/groupbox.cc            |  44 ++----
 client/widgets/groupbox.h             |  19 ++-
 client/widgets/label.cc               |  56 ++-----
 client/widgets/label.h                |  21 ++-
 client/widgets/lineedit.cc            | 126 ++++++---------
 client/widgets/lineedit.h             |  30 ++--
 client/widgets/listbox.cc             |  76 ++++-----
 client/widgets/listbox.h              |  30 ++--
 client/widgets/metawidget.cc          |  85 +++++-----
 client/widgets/metawidget.h           |  29 ++--
 client/widgets/multilist.cc           | 117 ++++++--------
 client/widgets/multilist.h            |  27 ++--
 client/widgets/radiobutton.cc         |   1 +
 client/widgets/radiobuttons.cc        | 102 +++++-------
 client/widgets/radiobuttons.h         |  34 ++--
 client/widgets/textedit.cc            |  98 +++++-------
 client/widgets/textedit.h             |  31 ++--
 client/widgets/widget.cc              | 290 +++++++++++++++++++++++++++++-----
 client/widgets/widget.h               |  90 +++++++----
 client/widgets/window.cc              |  45 ++----
 client/widgets/window.h               |  16 +-
 server/TODO                           |   6 +
 server/src/luaresume.cc               |   8 +-
 server/src/luaresume.h                |   2 +-
 server/src/macroparser.cc             |  65 ++++++--
 server/src/macroparser.h              |   3 +-
 server/src/resumeparser.cc            | 122 +++-----------
 server/src/template.h                 |   2 +
 server/xml/macros/test_button.xml     |   6 +-
 server/xml/macros/test_lineedit.xml   |  12 +-
 server/xml/macros/test_metawidget.xml |  13 +-
 server/xml/macros/test_resume.xml     |  85 ++++++++--
 73 files changed, 1630 insertions(+), 2058 deletions(-)

diff --git a/client/collapser.cc b/client/collapser.cc
index fd025c0..1d77c09 100644
--- a/client/collapser.cc
+++ b/client/collapser.cc
@@ -58,11 +58,12 @@ void Collapser::setWidgets(QWidget *collapsed, QWidget *expanded)
 
 void Collapser::setCollapsedWidget(QWidget *collapsed)
 {
+  /*
   if(this->collapsed) {
     delete this->collapsed;
     this->collapsed = NULL;
   }
-
+  */
   this->collapsed = collapsed;
 
   if(isCollapsed() == true && collapsed) {
@@ -73,11 +74,12 @@ void Collapser::setCollapsedWidget(QWidget *collapsed)
 
 void Collapser::setExpandedWidget(QWidget *expanded)
 {
+  /*
   if(this->expanded) {
     delete this->expanded;
     this->expanded = NULL;
   }
-
+  */
   this->expanded = expanded;
 
   if(isCollapsed() == false && expanded) {
@@ -183,7 +185,9 @@ void Collapser::anim()
       // show collapsed
       if(expanded) {
         expanded->setVisible(false);
-        qApp->processEvents(); // Make sure it is actualle invisble before removing it form the layout.
+        // Make sure it is actualle invisible before removing it from the 
+        // layout.
+        qApp->processEvents();
         layout()->removeWidget(expanded);
       }
       if(collapsed) {
@@ -192,8 +196,13 @@ void Collapser::anim()
       }
 
       setFixedHeight(c_height);
+
+      emit doneCollapsing();
+
     } else {
       setFixedHeight(e_height);
+
+      emit doneExpanding();
     }
 
   }
diff --git a/client/collapser.h b/client/collapser.h
index d74a4cf..03d74d7 100644
--- a/client/collapser.h
+++ b/client/collapser.h
@@ -56,6 +56,8 @@ public slots:
 signals:
   void collapsing();
   void expanding();
+  void doneCollapsing();
+  void doneExpanding();
 
 protected:
   //  void timerEvent(QTimerEvent *);
diff --git a/client/formatparser.cc b/client/formatparser.cc
index 62f0b21..71f80ee 100644
--- a/client/formatparser.cc
+++ b/client/formatparser.cc
@@ -31,15 +31,24 @@
 #include <string.h>
 
 #include "lua.h"
+#include "macrowindow.h"
+#include "widgets/widget.h"
 
-static QString format_parser_lua(QString format, QVector< Widget *> widgets)
+static QString format_parser_lua(QString format, Widget *w)
 {
-  LUA lua(&widgets);
+  /*
+  LUA lua(w);
 
   return lua.runParser(format);
+  */
+
+  format = format;
+  w = w;
+
+  return "FIXME: formatparser.cc:44";
 }
 
-static QString format_parser_pracro(QString format, QVector< Widget *> widgets)
+static QString format_parser_pracro(QString format, Widget *w)
 {
   QString resume;
   QString var;
@@ -64,12 +73,8 @@ static QString format_parser_pracro(QString format, QVector< Widget *> widgets)
           p++;
         }
         {
-          QVector< Widget* >::iterator i = widgets.begin();
-          while (i != widgets.end()) {
-            Widget* w = *i;
-            if(w->name() == var) resume += w->getValue();
-            i++;
-          }
+          Widget *widget = w->findWidget(var, true);
+          if(widget) resume += widget->value();
         }
         break;
 
@@ -182,9 +187,9 @@ QString format_parser(QString format, QSqlQuery &query)
   return resume;
 }
 
-QString format_parser(QString format, QVector< Widget *> widgets, QString language)
+QString format_parser(QString format, Widget *w, QString language)
 {
-  if(language == "pracro") return format_parser_pracro(format, widgets);
-  if(language == "lua") return format_parser_lua(format, widgets);
+  if(language == "pracro") return format_parser_pracro(format, w);
+  if(language == "lua") return format_parser_lua(format, w);
   return "";
 }
diff --git a/client/formatparser.h b/client/formatparser.h
index 92f978f..120709e 100644
--- a/client/formatparser.h
+++ b/client/formatparser.h
@@ -29,10 +29,10 @@
 
 #include <QString>
 #include <QVector>
-#include "widgets/widget.h"
 #include <QSqlQuery>
 
-QString format_parser(QString format, QVector< Widget *> widgets, QString language);
+class Widget;
+QString format_parser(QString format, Widget *w, QString language);
 QString format_parser(QString format, QSqlQuery &query);
 
 #endif/*__PRACRO_FORMATPARSER_H__*/
diff --git a/client/icons/icon.png b/client/icons/icon.png
index b18a880..2b39929 100644
Binary files a/client/icons/icon.png and b/client/icons/icon.png differ
diff --git a/client/lua.cc b/client/lua.cc
index 19b94c0..7dbdf75 100644
--- a/client/lua.cc
+++ b/client/lua.cc
@@ -58,7 +58,7 @@ static int get_widget(lua_State *L)
 
   Widget *widget = lua->getWidget(name);
 
-  printf("FIND: %s (%p)\n", name.toStdString().c_str(), widget);
+  //  printf("FIND: %s (%p)\n", name.toStdString().c_str(), widget);
 
   if(widget) {
     wdg_make_widget(L, widget);
@@ -66,15 +66,14 @@ static int get_widget(lua_State *L)
     lua_pushnil(L);
   }
 
-  printf("DONE\n");
+  //  printf("DONE\n");
 
   return 1;
 }
 
-LUA::LUA(QVector< Widget *> *widgets, QVector< Widget *> *auxwidgets)
+LUA::LUA(Widget **rootwidget)
 {
-  this->widgets = widgets;
-  this->auxwidgets = auxwidgets;
+  this->rootwidget = rootwidget;
 
   L = luaL_newstate();
   if(L == NULL) {
@@ -97,35 +96,21 @@ LUA::~LUA()
   lua_close(L);
 }
 
-bool LUA::runValidator(QString program, Widget *widget, QString name, QString value)
+QString LUA::runParser(QString program)
 {
   if(L == NULL) {
     error("LUA state not initialized!");
     return false;
   }
 
-  printf("Running %s on %s with value %s\n",
-         program.toStdString().c_str(),
-         name.toStdString().c_str(),
-         value.toStdString().c_str() );
-
-  lua_pushstring(L, value.toStdString().c_str());
-  lua_setglobal(L, "value");
-
-  lua_pushstring(L, name.toStdString().c_str());
-  lua_setglobal(L, "name");
-
-  if(widget) {
-    wdg_make_widget(L, widget);
-    lua_setglobal(L, "this");
-  }
+  printf("Running %s\n", program.toStdString().c_str());
 
-  //  int top = lua_gettop(L);
+  int top = lua_gettop(L);
 
   if(luaL_loadbuffer(L,
                      program.toStdString().c_str(),
                      program.size(),
-                     name.toStdString().c_str())) {
+                     "parser")) {
     error(lua_tostring(L, lua_gettop(L)));
     return false;
   }
@@ -136,24 +121,43 @@ bool LUA::runValidator(QString program, Widget *widget, QString name, QString va
     return false;
   }
 
-  return true;
+  if(top != lua_gettop(L) - 1) {
+    error("Program did not return a single value.\n");
+    return false;
+  }
+
+  if(lua_isstring(L, lua_gettop(L)) == false) {
+    error("Program did not return a boolean value.\n");
+    return false;
+  }
+
+  QString res = lua_tostring(L, lua_gettop(L));
+  lua_pop(L, 1);
+
+  return res;
 }
 
-QString LUA::runParser(QString program)
+bool LUA::runScript(QString script, Widget *widget, QString name)
 {
   if(L == NULL) {
     error("LUA state not initialized!");
     return false;
   }
 
-  printf("Running %s\n", program.toStdString().c_str());
+  printf("Running %s script %s on %s widget.\n",
+         name.toStdString().c_str(),
+         script.toStdString().c_str(),
+         widget?widget->name().toStdString().c_str():"NULL");
 
-  int top = lua_gettop(L);
+  if(widget) {
+    wdg_make_widget(L, widget);
+    lua_setglobal(L, "this");
+  }
 
   if(luaL_loadbuffer(L,
-                     program.toStdString().c_str(),
-                     program.size(),
-                     "parser")) {
+                     script.toStdString().c_str(),
+                     script.size(),
+                     name.toStdString().c_str())) {
     error(lua_tostring(L, lua_gettop(L)));
     return false;
   }
@@ -164,20 +168,7 @@ QString LUA::runParser(QString program)
     return false;
   }
 
-  if(top != lua_gettop(L) - 1) {
-    error("Program did not return a single value.\n");
-    return false;
-  }
-
-  if(lua_isstring(L, lua_gettop(L)) == false) {
-    error("Program did not return a boolean value.\n");
-    return false;
-  }
-
-  QString res = lua_tostring(L, lua_gettop(L));
-  lua_pop(L, 1);
-
-  return res;
+  return true;
 }
 
 void LUA::error(QString message)
@@ -187,23 +178,6 @@ void LUA::error(QString message)
 
 Widget *LUA::getWidget(QString name)
 {
-  QVector< Widget* >::iterator i = widgets->begin();
-  while (i != widgets->end()) {
-    Widget* w = *i;
-    if(name == w->name()) return w;
-    i++;
-  }
-
-  if(auxwidgets) {
-    QVector< Widget* >::iterator j = auxwidgets->begin();
-    while (j != auxwidgets->end()) {
-      Widget* w = *j;
-      if(name == w->name()) return w;
-      j++;
-    }
-  }
-  
-  printf("WARNING: Widget %s not found\n", name.toStdString().c_str());
-
-  return NULL;
+  if(*rootwidget) return (*rootwidget)->findWidget(name, true);
+  else return NULL;
 }
diff --git a/client/lua.h b/client/lua.h
index d12bc6e..d10aeb2 100644
--- a/client/lua.h
+++ b/client/lua.h
@@ -31,24 +31,17 @@
 #include <lauxlib.h>
 
 #include <QString>
+#include <QVector>
 
-#include "widgets/widget.h"
-
-class MacroWindow;
-
+class Widget;
 class LUA {
 public:
-  LUA(QVector< Widget *> *widgets, QVector< Widget *> *auxwidgets = NULL);
+  LUA(Widget **rootwidget);
   ~LUA();
   
-  bool runValidator(QString program, Widget *widget, QString name, QString value);
   QString runParser(QString program);
 
-  QString getValue(QString name);
-  void setValue(QString name, QString value);
-  void enable(QString name);
-  void disable(QString name);
-  void setVisible(QString name, bool value);
+  bool runScript(QString script, Widget *widget, QString name = "");
 
   void error(QString message);
 
@@ -56,8 +49,7 @@ public:
 
 private:
   lua_State *L;
-  QVector< Widget *> *widgets;
-  QVector< Widget *> *auxwidgets;
+  Widget **rootwidget;
 };
 
 #endif/*__PRACRO_LUA_H__*/
diff --git a/client/luawidget.cc b/client/luawidget.cc
index c8e6017..529984c 100644
--- a/client/luawidget.cc
+++ b/client/luawidget.cc
@@ -27,6 +27,29 @@
  */
 #include "luawidget.h"
 
+#include "widgets.h"
+
+#define LUA_SRC "lua"
+
+/**
+ ** Copied from lauxlib.c, but modified return NULL upon error instead of
+ ** casting a lua error.
+ **/
+LUALIB_API void *luaL_isudata (lua_State *L, int ud, const char *tname) {
+  void *p = lua_touserdata(L, ud);
+  if (p != NULL) {  /* value is a userdata? */
+    if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
+      lua_getfield(L, LUA_REGISTRYINDEX, tname);  /* get correct metatable */
+      if (lua_rawequal(L, -1, -2)) {  /* does it have the correct mt? */
+        lua_pop(L, 2);  /* remove both metatables */
+        return p;
+      }
+    }
+  }
+  //  luaL_typerror(L, ud, tname);  /* else error */
+  return NULL;  /* to avoid warnings */
+}
+
 #define luaL_checkbool(L, i) \
   (lua_isboolean(L,i) ? lua_toboolean(L,i) : luaL_checkint(L,i))
 
@@ -38,7 +61,8 @@ static int wdg_name(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
   lua_pushstring(L, wdgu->widget->name().toStdString().c_str());
@@ -50,7 +74,8 @@ static int wdg_type(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
   // return error code
@@ -63,10 +88,11 @@ static int wdg_value(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
-  lua_pushstring(L, wdgu->widget->getValue().toStdString().c_str());
+  lua_pushstring(L, wdgu->widget->value().toStdString().c_str());
 
   return 1;
 }
@@ -75,12 +101,13 @@ static int wdg_set_value(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
   const char *val = luaL_checkstring(L, 2);
 
-  wdgu->widget->setValue(val);
+  wdgu->widget->setValue(val, LUA_SRC);
 
   return 0;
 }
@@ -89,10 +116,11 @@ static int wdg_enabled(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
-  lua_pushboolean(L, wdgu->widget->isDisabled() == false);
+  lua_pushboolean(L, wdgu->widget->enabled());
 
   return 1;
 }
@@ -101,13 +129,13 @@ static int wdg_set_enabled(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
   bool val = luaL_checkbool(L, 2);
 
-  if(val) wdgu->widget->enable();
-  else wdgu->widget->disable();
+  wdgu->widget->setEnabled(val);
   
   return 0;
 }
@@ -116,10 +144,11 @@ static int wdg_visible(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
-  lua_pushboolean(L, wdgu->widget->getVisibility());
+  lua_pushboolean(L, wdgu->widget->visible());
 
   return 1;
 }
@@ -128,12 +157,13 @@ static int wdg_set_visible(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
   bool val = luaL_checkbool(L, 2);
 
-  wdgu->widget->setVisibility(val);
+  wdgu->widget->setVisible(val);
   
   return 0;
 }
@@ -142,10 +172,11 @@ static int wdg_valid(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
-  lua_pushboolean(L, wdgu->widget->isValid());
+  lua_pushboolean(L, wdgu->widget->valid());
 
   return 1;
 }
@@ -154,7 +185,8 @@ static int wdg_set_valid(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "Widget");
+  if(!wdgu) wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
   luaL_argcheck(L, wdgu, 1, "widget expected");
 
   bool val = luaL_checkbool(L, 2);
@@ -164,35 +196,58 @@ static int wdg_set_valid(lua_State *L)
   return 0;
 }
 
-static int wdg_close(lua_State *L)
+static int wdg_checked(lua_State *L)
 {
   wdg_userdata *wdgu;
 
-  wdgu = (wdg_userdata *)luaL_checkudata(L, 1, "Widget");
-  luaL_argcheck(L, wdgu, 1, "widget expected");
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
+  luaL_argcheck(L, wdgu, 1, "checkbox expected");
 
-  return 0;
+  CheckBox *cmb = (CheckBox*)wdgu->widget;
+  lua_pushboolean(L, cmb->checked());
+
+  return 1;
 }
 
-static const struct luaL_reg wdg_meths[] =
+static int wdg_set_checked(lua_State *L)
 {
-  {"name", wdg_name},
-  {"type", wdg_type},
-
-  {"value", wdg_value},
-  {"setValue", wdg_set_value},
+  wdg_userdata *wdgu;
 
-  {"enabled", wdg_enabled},
-  {"setEnabled", wdg_set_enabled},
+  wdgu = (wdg_userdata *)luaL_isudata(L, 1, "CheckBox");
+  luaL_argcheck(L, wdgu, 1, "checkbox expected");
 
-  {"visible", wdg_visible},
-  {"setVisible", wdg_set_visible},
+  bool val = luaL_checkbool(L, 2);
 
-  {"valid", wdg_valid},
-  {"setValid", wdg_set_valid},
+  CheckBox *cmb = (CheckBox*)wdgu->widget;
+  cmb->setChecked(val);
+  
+  return 0;
+}
 
-  {"close", wdg_close},
-  {"__gc", wdg_close},
+#define WDG_METHS \
+  {"name", wdg_name},\
+  {"type", wdg_type},\
+  {"value", wdg_value},\
+  {"setValue", wdg_set_value},\
+  {"enabled", wdg_enabled},\
+  {"setEnabled", wdg_set_enabled},\
+  {"visible", wdg_visible},\
+  {"setVisible", wdg_set_visible},\
+  {"valid", wdg_valid},\
+  {"setValid", wdg_set_valid}
+
+#define WDG_CHKBOX_METHS \
+  {"checked", wdg_checked},\
+  {"setChecked", wdg_set_checked}
+
+static const struct luaL_Reg wdg_meths[] = {
+  WDG_METHS, {NULL, NULL} };
+
+static const struct luaL_Reg wdg_chkbox_meths[] = {
+  WDG_METHS, WDG_CHKBOX_METHS, {NULL, NULL} };
+
+static const struct luaL_Reg wdg_chk_meths[] =
+{
   {NULL, NULL}
 };
 
@@ -201,7 +256,12 @@ int wdg_make_widget(lua_State *L, Widget *widget)
   wdg_userdata *wdgu;
   wdgu = (wdg_userdata *)lua_newuserdata(L, sizeof(wdg_userdata));
 
-  luaL_getmetatable(L, "Widget");
+  if(widget->type() == "checkbox") {
+    luaL_getmetatable(L, "CheckBox");
+  } else {
+    luaL_getmetatable(L, "Widget");
+  }
+
   lua_setmetatable(L, -2);
 
   wdgu->widget = widget;
@@ -212,11 +272,16 @@ int wdg_make_widget(lua_State *L, Widget *widget)
 void register_widget(lua_State *L)
 {
   luaL_newmetatable(L, "Widget");
+  lua_pushliteral(L, "__index");
+  lua_pushvalue(L, -2);
+  lua_rawset(L, -3);
+  luaL_register(L, NULL, wdg_meths);
 
-  // metatable.__index = metatable
+  luaL_newmetatable(L, "CheckBox");
   lua_pushliteral(L, "__index");
   lua_pushvalue(L, -2);
   lua_rawset(L, -3);
+  luaL_register(L, NULL, wdg_chkbox_meths);
 
-  luaL_openlib(L, NULL, wdg_meths, 0);
 }
+
diff --git a/client/macro.cc b/client/macro.cc
index d207474..0037044 100644
--- a/client/macro.cc
+++ b/client/macro.cc
@@ -30,7 +30,10 @@
 #include <QDomElement>
 #include <QHBoxLayout>
 #include <QApplication>
+#include <QLabel>
+
 #include "macrodrawer.h"
+#include "macrowindow.h"
 
 Macro::Macro(QDomNode &n)
 {
@@ -53,7 +56,8 @@ void Macro::update(QDomNode &n)
   iscompleted = xml_elem.attribute("completed", "false") == "true";
 }
 
-void Macro::init(QBoxLayout *layout, Macros &macros, bool initialising, NetCom &netcom, QString templ)
+void Macro::init(QBoxLayout *layout, Macros &macros,
+                 bool initialising, NetCom &netcom, QString templ)
 {
   QDomElement xml_elem = node.toElement();
 
@@ -64,7 +68,8 @@ void Macro::init(QBoxLayout *layout, Macros &macros, bool initialising, NetCom &
 
   if(xml_elem.hasAttribute("requires")) {
     // Read and parse requirement list.
-    requires = xml_elem.attribute("requires").split(QRegExp("\\W+"), QString::SkipEmptyParts);
+    requires = xml_elem.attribute("requires").split(QRegExp("\\W+"),
+                                                    QString::SkipEmptyParts);
   }
 
   //  if(xml_elem.hasAttribute("header")) {
diff --git a/client/macro.h b/client/macro.h
index 20a4e14..b1b8032 100644
--- a/client/macro.h
+++ b/client/macro.h
@@ -34,9 +34,10 @@
 #include <QDomNode>
 #include <QBoxLayout>
 
-#include "macrowindow.h"
+#include "netcom.h"
 
 class Macro;
+class MacroWindow;
 typedef QMap<QString, Macro> Macros;
 
 class MacroDrawer;
@@ -46,7 +47,8 @@ public:
   Macro() {}
   Macro(QDomNode &node);
 
-  void init(QBoxLayout *layout, Macros &macros, bool initialising, NetCom &netcom, QString templ);
+  void init(QBoxLayout *layout, Macros &macros, bool initialising,
+            NetCom &netcom, QString templ);
 
   void update(QDomNode &node);
 
diff --git a/client/macrodrawer.cc b/client/macrodrawer.cc
index 89bd255..a28e7da 100644
--- a/client/macrodrawer.cc
+++ b/client/macrodrawer.cc
@@ -31,6 +31,11 @@
 #include <QSvgRenderer>
 #include <QPainter>
 #include <QImage>
+#include <QEvent>
+#include <QCloseEvent>
+#include <QMouseEvent>
+
+#include "macro.h"
 
 MacroDrawer::MacroDrawer(Macro *macro, QString title, QWidget *edge)
 {
diff --git a/client/macrodrawer.h b/client/macrodrawer.h
index 7aaf2ec..18d16d7 100644
--- a/client/macrodrawer.h
+++ b/client/macrodrawer.h
@@ -30,10 +30,8 @@
 #include <QGroupBox>
 #include <QString>
 #include <QPushButton>
-#include "macro.h"
 
 class Macro;
-
 class MacroDrawer : public QGroupBox {
 Q_OBJECT
 public:
diff --git a/client/macrowindow.cc b/client/macrowindow.cc
index 4c51c07..efabbd1 100644
--- a/client/macrowindow.cc
+++ b/client/macrowindow.cc
@@ -29,15 +29,14 @@
 #include <QVBoxLayout>
 #include <QDomDocument>
 #include <QDomElement>
-#include <QDomNode>
 #include <QByteArray>
 
 #include "messagebox.h"
-
 #include "widgets/widget.h"
 #include "widgets/window.h"
 #include "widgetbuilder.h"
 #include "lua.h"
+#include "resumewidget.h"
 
 extern QString cpr;
 extern QString user;
@@ -48,36 +47,38 @@ MacroWindow::MacroWindow(NetCom &n, QDomNode &xml_doc, QString templ,
                          bool collapsed, bool compact)
   : Collapser(), netcom(n)
 {
+  mainwidget = NULL;
+
   waschanged = false;
 
   this->templ = templ;
 
   setCollapsedWidget(new ResumeWidget(compact));
 
-  this->lua = new LUA(&this->widgets, &this->auxwidgets);
+  this->lua = new LUA(&mainwidget);
 
   update(xml_doc);
 
   setCollapsed(collapsed);
   active = true;
+
+  connect(this, SIGNAL(doneCollapsing()), this, SLOT(collapsed()));
+  connect(this, SIGNAL(doneExpanding()), this, SLOT(expanded()));
 }
 
 MacroWindow::~MacroWindow()
 {
+  clear();
   delete lua;
 }
 
 void MacroWindow::update(QDomNode &node)
 {
-  mainwidget = NULL;
-
-  widgets.clear();
-  auxwidgets.clear();
-  luaprograms.clear();
-
+  //  clear();
   initMacro(node);
 
-  if(mainwidget) setExpandedWidget(mainwidget);
+  if(mainwidget) setExpandedWidget(mainwidget->qwidget());
+  else setExpandedWidget(NULL);
 }
 
 void MacroWindow::initMacro(QDomNode &node)
@@ -85,9 +86,10 @@ void MacroWindow::initMacro(QDomNode &node)
   QDomElement xml_elem = node.toElement();
 
   if(xml_elem.tagName() == "macro") {
+
     // Assign the macro name and version to QStrings for use when comitting
-    if(xml_elem.hasAttribute("name")) macro = xml_elem.attribute("name");
-    if(xml_elem.hasAttribute("version")) version = xml_elem.attribute("version");
+    macro = xml_elem.attribute("name", "");
+    version = xml_elem.attribute("version", "");
 
   } else if(xml_elem.tagName() == "scripts") {
     // Nothing to do here
@@ -106,33 +108,42 @@ void MacroWindow::initMacro(QDomNode &node)
     if(xml_elem.hasAttribute("language") &&
        xml_elem.attribute("language") == "lua") {
       //      luaprograms.push_back(xml_elem.text());
-      this->lua->runValidator(xml_elem.text(), NULL, "preload", "");
+      this->lua->runScript(xml_elem.text(), NULL, "preload");
     } else {
-      printf("Unknown script type %s\n", xml_elem.attribute("language").toStdString().c_str());
+      printf("Unknown script type %s\n",
+             xml_elem.attribute("language").toStdString().c_str());
     }
 
   } else if(xml_elem.tagName() == "widgets") {
+
+    if(mainwidget) {
+      printf("ERROR!!!!!!\n\tmainwidget already exists!\n");
+    }
+
     Window *window = new Window(xml_elem, this);
+    connect(window, SIGNAL(wasChanged()), this, SLOT(macroChanged()));
     macrotitle = xml_elem.attribute("caption");
+    //clear();
+    /*
+    if(mainwidget) {
+      setExpandedWidget(NULL);
+      delete mainwidget;
+      mainwidget = NULL;
+    }
+    */
     mainwidget = window;
 
     QDomNodeList children = node.childNodes();
 
-    // Build widgets
-    for (int i=0; i<children.count();i++) {
-      QDomNode child = children.at(i);
-      widgets += widgetBuilder(child, mainwidget, this);
-    }
-
     // Insert their values (this must be done last for scripts to work properly)
     for (int i=0; i<children.count();i++) {
       QDomNode child = children.at(i);
-      setValues(child, this);
+      setValues(child, mainwidget);
     }
 
     if(waschanged == true) macroChanged();
 
-    return;
+    return; // No further recursion.
   }
 
   QDomNodeList children = node.childNodes();
@@ -143,21 +154,12 @@ void MacroWindow::initMacro(QDomNode &node)
   }
 }
 
+#include <QApplication>
 bool MacroWindow::doCommit()
 {
-  // Check for, and count, errors on all entries before comitting
-  int faulty = 0; // 0 initial errors
-
-  QVector< Widget* >::iterator i = widgets.begin();
-  while (i != widgets.end()) {
-    Widget* w = *i;
-    if(!w->isDisabled() && !w->isValid()) faulty++; // Regexp check, returns valid if entry passed
-    i++;
-  }
-
-  // If all entries passed validation, continue commit
-  if(faulty == 0) {
-    QDomDocument doc = netcom.send(widgets, templ, macro, version);
+  if(mainwidget->valid()) {
+    QDomDocument doc = netcom.send(mainwidget->widgetList(),
+                                   templ, macro, version);
 
     QDomNodeList nl = doc.documentElement().childNodes();
     QDomNode n = nl.at(0); // There can be only one! (Swush, flomp)
@@ -169,7 +171,9 @@ bool MacroWindow::doCommit()
     }
 
     emit updateOnCommit();
+
     setCollapsed(true);
+
     return true;
   } else {
     MessageBox::critical(NULL, "Fejl",
@@ -181,157 +185,32 @@ bool MacroWindow::doCommit()
   }
 }
 
-void MacroWindow::close()
-{
-  //  mainwidget->close();
-  isclosed = true;
-}
-
 void MacroWindow::commit()
 {
   doCommit();
 }
 
-void MacroWindow::reset()
-{
-  /*
-  MessageBox::warning(NULL, tr("Reset"),
-                   tr("Du har valgt at nulstille de indtastede data.\n"
-                      "Er du sikker?"),
-                   MessageBox::Yes | MessageBox::Cancel);
-  printf("MacroWindow -> resetting...\n");
-  */
-  QVector< Widget* >::iterator i = widgets.begin();
-  while (i != widgets.end()) {
-    Widget* w = *i;
-    w->reset();
-    i++;
-  }
-
-  QVector< Widget* >::iterator j = auxwidgets.begin();
-  while (j != auxwidgets.end()) {
-    Widget* w = *j;
-    w->reset();
-    j++;
-  }
-
-  waschanged = false;
-}
-
 void MacroWindow::cancel()
 {
   collapseWrapper();
 }
 
-void MacroWindow::cont(QString name)
-{
-  QString macro;
-  QVector< Widget* >::iterator i=widgets.begin();
-  while (i != widgets.end()) {
-    Widget* w = *i;
-    if(w->name() == name) {
-      macro = w->getValue();
-    }
-    i++;
-  }
-  if(doCommit()) {
-
-    // FIXME: Hack to prevent XML clotching.
-    // The server could not differentiate the commit and the request.
-
-    // TODO: Where to get the template var??
-    //    new_macro("example", macro);
-    //    close();
-  } else {
-   MessageBox::critical(NULL, "Fejl",
-			 "Makroen " + macrotitle + " er ikke udfyldt korrekt, pr�v igen.\n",
-			 MessageBox::Ok);
-  }
-  printf("%s : MacroWindow -> continuing...\n", macro.toStdString().c_str());
-}
-
-void MacroWindow::cont_nocommit(QString name)
-{
-  QString macro;
-  QVector< Widget* >::iterator i=widgets.begin();
-  while (i != widgets.end()) {
-    Widget* w = *i;
-    if(w->name() == name) {
-      macro = w->getValue();
-    }
-    i++;
-  }
-  if(true/*doCommit()*/) {
-
-    // FIXME: Hack to prevent XML clotching.
-    // The server could not differentiate the commit and the request.
-
-    // TODO: Where to get the template var??
-    //    new_macro("example", macro);
-    //    close();
-  } else {
-   MessageBox::critical(NULL, "Fejl",
-			 "Makroen " + macrotitle + " er ikke udfyldt korrekt, pr�v igen.\n",
-			 MessageBox::Ok);
-  }
-  printf("%s : MacroWindow -> continuing...\n", macro.toStdString().c_str());
-}
-
-bool MacroWindow::isClosed()
-{
-  return isclosed || mainwidget->isVisible() == false;
-}
-
-Widget *MacroWindow::getWidget(QString name)
-{
-  QVector< Widget* >::iterator i = widgets.begin();
-  while (i != widgets.end()) {
-    Widget* w = *i;
-    if(name == w->name()) return w;
-    i++;
-  }
-
-  QVector< Widget* >::iterator j = auxwidgets.begin();
-  while (j != auxwidgets.end()) {
-    Widget* w = *j;
-    if(name == w->name()) return w;
-    j++;
-  }
-  
-  printf("WARNING: Widget %s not found\n", name.toStdString().c_str());
-
-  return NULL;
-}
-
-void MacroWindow::addAuxWidgets(QVector< Widget* > ws)
-{
-  auxwidgets += ws;
-}
-
-void MacroWindow::addWidgets(QVector< Widget* > ws)
-{
-  widgets += ws;
-}
-
 void MacroWindow::expandWrapper()
 {
   if(!isCollapsed()) return;
 
-  widgets.clear();
-  auxwidgets.clear();
-  luaprograms.clear();
+  //  clear();
+
   waschanged = false;
   
   QDomDocument xml_doc = netcom.send(templ, macro);
   
-  //
-  // TODO: This is where the dependency checking should occur.
-  //
-  
   // Initiate the new macro window with the xml document and push
   //  it to the window list
   QDomNodeList templates = xml_doc.documentElement().childNodes();
-  QDomNode templatenode = templates.at(0); // There can be only one! (Swush, flomp)
+
+  // There can be only one! (Swush, flomp)
+  QDomNode templatenode = templates.at(0);
   QDomNodeList macronodes = templatenode.childNodes();
   for(int j = 0; j < macronodes.count(); j++) {
     QDomNode macronode = macronodes.at(j);
@@ -353,15 +232,18 @@ void MacroWindow::expandWrapper()
       }
     }
   }
-  setExpandedWidget(mainwidget);
+  if(mainwidget) setExpandedWidget(mainwidget->qwidget());
   expand();
 
+  // Set keyboard focus on the first focusable widget in the macro.
+  QVector< Widget* > widgets = mainwidget->widgetList(true);
   QVector< Widget* >::iterator i = widgets.begin();
   while (i != widgets.end()) {
     Widget* w = *i;
     if(w->setKeyboardFocus()) break;
     i++;
   }
+
 }
 
 void MacroWindow::collapseWrapper()
@@ -370,24 +252,27 @@ void MacroWindow::collapseWrapper()
 
   if(waschanged) {
     switch(MessageBox::warning(NULL,
-                                "Gem �ndringerne i makroen?",
-                                "Du har valgt at lukke makroen " + macrotitle + ".\n"
-                                "�nsker du at gemme inden du lukker?",
-                                MessageBox::Save | MessageBox::Close | MessageBox::Cancel)) {
+                               "Gem �ndringerne i makroen?",
+                               "Du har valgt at ukke makroen " +
+                               macrotitle + ".\n"
+                               "�nsker du at gemme inden du lukker?",
+                               MessageBox::Save | MessageBox::Close |
+                               MessageBox::Cancel)) {
     case MessageBox::Save:
-      if(doCommit()) setCollapsed(true);
-      else MessageBox::critical(NULL,
-                                 "Fejl",
-                                 "Makroen " + macrotitle + "  er ikke udfyldt korrekt, pr�v igen.\n",
-                                 MessageBox::Ok);
-      
+      if(doCommit()) {
+        setCollapsed(true);
+      } else {
+        MessageBox::critical(NULL, "Fejl",
+                             "Makroen " + macrotitle +
+                             "  er ikke udfyldt korrekt, pr�v igen.\n",
+                             MessageBox::Ok);
+      }
       break;
     case MessageBox::Close:
       collapse();
       break;
     case MessageBox::Cancel:
     default:
-      //      emit expanding(); // signal the other to close again (if any)
       break;
     }
   } else {
@@ -421,3 +306,25 @@ void MacroWindow::setActive(bool active)
 
   emit activationChanged(active);
 }
+
+void MacroWindow::clear()
+{
+  if(mainwidget) delete mainwidget;
+  mainwidget = NULL;
+
+  setExpandedWidget(NULL);
+
+  luaprograms.clear();
+}
+
+void MacroWindow::collapsed()
+{
+  printf("======== Collapsed ========\n");
+
+  clear();
+}
+
+void MacroWindow::expanded()
+{
+  printf("======== Expanded ========\n");
+}
diff --git a/client/macrowindow.h b/client/macrowindow.h
index 279394f..803bf62 100644
--- a/client/macrowindow.h
+++ b/client/macrowindow.h
@@ -27,22 +27,15 @@
 #ifndef __PRACRO_MACROWINDOW_H__
 #define __PRACRO_MACROWINDOW_H__
 
-#include <QDomDocument>
-#include <QWidget>
 #include <QDomNode>
-#include <QObject>
 #include <QVector>
-#include <QMap>
-#include <QLabel>
 
 #include "collapser.h"
 #include "netcom.h"
-#include "resumewidget.h"
 
-class NetCom;
 class LUA;
 class Widget;
-
+class ResumeWidget;
 class MacroWindow : public Collapser
 {
 Q_OBJECT
@@ -51,19 +44,11 @@ public:
               bool collapsed = true, bool compact = false);
   ~MacroWindow();
 
-  bool isClosed();
-
   QVector< QString > luaprograms;
                 
   LUA *lua;
 
-  Widget *getWidget(QString name);
-
-  // Add a widget that can be seen from script, and will be committed, and validated.
-  void addWidgets(QVector< Widget* >);
-
-  // Add a widget that can only be seen from scripts, but will not be committed or validated.
-  void addAuxWidgets(QVector< Widget* >);
+  //  Widget *getWidget(QString name);
 
   void update(QDomNode &xml_doc);
 
@@ -73,10 +58,7 @@ public:
 
 public slots:
   void commit();
-  void reset();
   void cancel();
-  void cont(QString name);
-  void cont_nocommit(QString name);
 
   void toggleMacro();
 
@@ -85,6 +67,9 @@ public slots:
   void collapseWrapper();
   void expandWrapper();
 
+  void collapsed();
+  void expanded();
+
 signals:
   void updateOnCommit();
   void macroHasChanged();
@@ -94,16 +79,14 @@ private:
   void initMacro(QDomNode &node);
 
   bool doCommit();
-  QVector< Widget* > widgets;
-  QVector< Widget* > auxwidgets;
+
   QString macro;
   QString templ;
   QString version;
-  QWidget *mainwidget;
+  Widget *mainwidget;
   ResumeWidget *resumewidget;
 
-  bool isclosed;
-  void close();
+  void clear();
 
   NetCom &netcom;
 
diff --git a/client/mainwindow.cc b/client/mainwindow.cc
index 40daad8..d88ae5e 100644
--- a/client/mainwindow.cc
+++ b/client/mainwindow.cc
@@ -40,8 +40,11 @@
 #include <QMessageBox>
 #include <QToolBar>
 #include <QAction>
+#include <QEvent>
+#include <QCloseEvent>
 
 #include "macrodrawer.h"
+#include "macrowindow.h"
 
 MainWindow::MainWindow(QString cpr, QString templ, QString host,
                        quint16 port, QString user)
@@ -56,6 +59,7 @@ MainWindow::MainWindow(QString cpr, QString templ, QString host,
   this->user = user;
 
   setWindowTitle("Pracro - " + cpr);
+  setWindowIcon(QIcon(":/icons/icon.png"));
 
   QStatusBar *status = statusBar();
   status->addPermanentWidget(new QLabel("Pracro v."VERSION));
diff --git a/client/mainwindow.h b/client/mainwindow.h
index afc9d08..a9fb596 100644
--- a/client/mainwindow.h
+++ b/client/mainwindow.h
@@ -34,10 +34,10 @@
 #include <QFont>
 
 #include "netcom.h"
-#include "macrowindow.h"
 #include "sessions.h"
 #include "macro.h"
 
+class QLabel;
 class MainWindow : public QMainWindow {
 Q_OBJECT
 public:
diff --git a/client/netcom.cc b/client/netcom.cc
index f569a6f..9056ec3 100644
--- a/client/netcom.cc
+++ b/client/netcom.cc
@@ -33,6 +33,8 @@
 
 #include <QHttp>
 
+#include <QWidget>
+
 #include "widgets/widget.h"
 
 #ifdef USE_SSL
@@ -46,6 +48,9 @@
 #endif
 #endif
 
+//#define DEBUG(fmt...) printf(fmt)
+#define DEBUG(ftm...)
+
 NetCom::NetCom(QString host, quint16 port)
 {
   //
@@ -80,7 +85,7 @@ void NetCom::replyFinished(QNetworkReply *reply)
 QDomDocument NetCom::makeTransfer(QDomDocument &doc,
                                   bool commit, bool lockgui, bool discard)
 {
-  printf("\nMaking transfer:\n%s", doc.toString().toStdString().c_str());
+  DEBUG("\nMaking transfer:\n%s", doc.toString().toStdString().c_str());
 
   if(lockgui && qApp->activeWindow()) qApp->activeWindow()->setEnabled(false);
   if(lockgui) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
@@ -107,13 +112,13 @@ QDomDocument NetCom::makeTransfer(QDomDocument &doc,
   QDomDocument res_doc;
   res_doc.setContent(data);
 
-  printf("\nRecieved reponse:\n%s", data.data());
+  DEBUG("\nRecieved reponse:\n%s", data.data());
 
-  printf("\nRecieved reponse (Parsed):\n%s", res_doc.toByteArray().data());
+  DEBUG("\nRecieved reponse (Parsed):\n%s", res_doc.toByteArray().data());
 
   if(reply->hasRawHeader("SessionID")) {
     sessionid = reply->rawHeader("SessionID");
-    printf("SESSION ID: %s\n", sessionid.toStdString().c_str());
+    DEBUG("SESSION ID: %s\n", sessionid.toStdString().c_str());
   }
 
   if(lockgui) QApplication::restoreOverrideCursor();
@@ -189,10 +194,10 @@ QDomDocument NetCom::send(QVector< Widget* > widgets, QString templ,
   while (i != widgets.end()) {
     Widget* w = *i;
     
-    if(!w->isDisabled() && w->name() != "") {
+    if(w->enabled() && w->name() != "" && w->local() == false) {
       QDomElement field_elem = doc.createElement("field");
       field_elem.setAttribute("name", w->name());
-      field_elem.setAttribute("value", w->getValue());
+      field_elem.setAttribute("value", w->value());
       commit_elem.appendChild(field_elem);
     }
 
diff --git a/client/pracro.cc b/client/pracro.cc
index ad46085..76cd4df 100644
--- a/client/pracro.cc
+++ b/client/pracro.cc
@@ -24,8 +24,6 @@
  *  along with Pracro; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
-#ifndef TESTING
-
 #include <QApplication>
 #include <QObject>
 #include <QEvent>
@@ -53,8 +51,11 @@ QString config = CONFIG_DEFAULT;
 QString host;
 quint16 port;
 
-QFont *fixedfont;
 QWidget *viewer = NULL;
+QFont *fixedfont = NULL;
+
+#ifndef TESTING
+
 static void print_usage()
 {
   printf("Usage: pracro -m MACRO -c CPR -U USER\n");
diff --git a/client/test.sh b/client/test.sh
index cbd0184..b2ad68d 100755
--- a/client/test.sh
+++ b/client/test.sh
@@ -35,6 +35,7 @@ do
 	
 	echo -n "* Running   $TEST test"
 	echo Running $TEST test: >> $OUTPUT
+	cp -f $TEST_APP $TEST.bin
 	if ./$TEST_APP 2>&1 >> $OUTPUT ; then
 	    echo -e "\r\t\t\t\t\t\t[\033[1;32mSuccess\033[0;2m]"
 	    echo "[Success]" >> $OUTPUT
@@ -50,3 +51,6 @@ do
     rm -f $MAKEFILE $TEST_PRO $TEST_APP
 done
 
+# Make sure that a 'normal' compile will compile pracro.cc
+# without the TESTING flag set
+touch pracro.cc
diff --git a/client/test/testcomboboxedit.cc b/client/test/testcomboboxedit.cc
index 7fdbfb1..76a9792 100644
--- a/client/test/testcomboboxedit.cc
+++ b/client/test/testcomboboxedit.cc
@@ -36,10 +36,10 @@ private slots:
 	{
 		QDomDocument doc;	doc.setContent(xml_search);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 
-    QTest::keyClicks(&cmb, "Item 2");
-    QCOMPARE(cmb.getValue(), QString("Item 2"));
+    QTest::keyClicks(cmb.qwidget(), "Item 2");
+    QCOMPARE(cmb.value(), QString("Item 2"));
   }
 
   void arrowSelect()
@@ -47,22 +47,21 @@ private slots:
 		QDomDocument doc;	doc.setContent(xml_select);
     QDomElement e = doc.documentElement();
 
-    ComboBox cmb(e, NULL);
-
-		cmb.setFocus();
-    QTest::keyPress(&cmb, Qt::Key_Down);
-    QTest::keyPress(&cmb, Qt::Key_Down);
-    QTest::keyPress(&cmb, Qt::Key_Enter);
-    QCOMPARE(cmb.getValue(), QString("item3"));
+    ComboBox cmb(e, createMacroWindow());
+		cmb.qwidget()->setFocus();
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Down);
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Down);
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Enter);
+    QCOMPARE(cmb.value(), QString("item3"));
   }
 
 	void changeEmits()
 	{
 		QDomDocument doc;	doc.setContent(xml_search);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 		QSignalSpy spy(&cmb, SIGNAL(wasChanged()));
-    QTest::keyClicks(&cmb, "I");
+    QTest::keyClicks(cmb.qwidget(), "I");
 		QCOMPARE(spy.count(), 1);
 	}
 };
diff --git a/client/test/testcomboboxsearch.cc b/client/test/testcomboboxsearch.cc
index 7ac0db4..ff737db 100644
--- a/client/test/testcomboboxsearch.cc
+++ b/client/test/testcomboboxsearch.cc
@@ -4,6 +4,7 @@
 #include "combobox.h"
 #include <QAbstractItemView>
 #include <QCompleter>
+#include <QComboBox>
 
 static QString xml = 
 	"<combobox name=\"mycombobox\" type=\"search\">\n"
@@ -34,47 +35,48 @@ private slots:
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 
 		// Full item search
-    QTest::keyClicks(&cmb, "Item 2");
-    QCOMPARE(cmb.getValue(), QString("Item 2"));
+    QTest::keyClicks(cmb.qwidget(), "Item 2");
+    QCOMPARE(cmb.value(), QString("Item 2"));
   }
 
   void searchPrefix()
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 
+    QComboBox *qcmb = (QComboBox *)cmb.qwidget();
 		// Item prefix search
-    QTest::keyClicks(&cmb, "T");
-		QCOMPARE(cmb.completer()->currentCompletion(), QString("Thingy"));
+    QTest::keyClicks(cmb.qwidget(), "T");
+		QCOMPARE(qcmb->completer()->currentCompletion(), QString("Thingy"));
 
-    QTest::keyClicks(&cmb, cmb.completer()->currentCompletion());
-    QCOMPARE(cmb.getValue(), QString("Thingy"));
+    QTest::keyClicks(cmb.qwidget(), qcmb->completer()->currentCompletion());
+    QCOMPARE(cmb.value(), QString("Thingy"));
   }
 
   void searchNegative()
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 
 		// Negative search
-    QTest::keyClicks(&cmb, "A");
-    QCOMPARE(cmb.getValue(), QString(""));
+    QTest::keyClicks(cmb.qwidget(), "A");
+    QCOMPARE(cmb.value(), QString(""));
   }
 
   void arrowSelect()
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
-    QTest::keyPress(&cmb, Qt::Key_Down);
-    QTest::keyPress(&cmb, Qt::Key_Down);
-    QTest::keyPress(&cmb, Qt::Key_Enter);
-    QCOMPARE(cmb.getValue(), QString("item3"));
+    ComboBox cmb(e, createMacroWindow());
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Down);
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Down);
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Enter);
+    QCOMPARE(cmb.value(), QString("item3"));
   }
 	/* // It is set in MacroWindow generation .. not directly in the Widget.
   void defaultValue()
@@ -82,16 +84,16 @@ private slots:
 		QDomDocument doc;	doc.setContent(xml_default);
     QDomElement e = doc.documentElement();
     ComboBox cmb(e, NULL);
-    QCOMPARE(cmb.getValue(), QString("item2"));
+    QCOMPARE(cmb.value(), QString("item2"));
   }
 	*/
 	void changeEmitUser()
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 		QSignalSpy spy(&cmb, SIGNAL(wasChanged()));
-    QTest::keyClicks(&cmb, "I");
+    QTest::keyClicks(cmb.qwidget(), "I");
 		QCOMPARE(spy.count(), 1);
 	}
 
@@ -99,7 +101,7 @@ private slots:
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 		QSignalSpy spy(&cmb, SIGNAL(wasChanged()));
 		cmb.setValue("some value", "pentominos");
 		QCOMPARE(spy.count(), 1);
@@ -109,7 +111,7 @@ private slots:
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 		QSignalSpy spy(&cmb, SIGNAL(wasChanged()));
 		cmb.setValue("some value", "pracro");
 		QCOMPARE(spy.count(), 0);
diff --git a/client/test/testcomboboxselect.cc b/client/test/testcomboboxselect.cc
index 1439440..3eaac00 100644
--- a/client/test/testcomboboxselect.cc
+++ b/client/test/testcomboboxselect.cc
@@ -36,10 +36,10 @@ private slots:
 	{
 		QDomDocument doc;	doc.setContent(xml_search);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 
-    QTest::keyClicks(&cmb, "Item 2");
-    QCOMPARE(cmb.getValue(), QString("Item 2"));
+    QTest::keyClicks(cmb.qwidget(), "Item 2");
+    QCOMPARE(cmb.value(), QString("Item 2"));
   }
 
   void arrowSelect()
@@ -47,22 +47,22 @@ private slots:
 		QDomDocument doc;	doc.setContent(xml_select);
     QDomElement e = doc.documentElement();
 
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 
-		cmb.setFocus();
-    QTest::keyPress(&cmb, Qt::Key_Down);
-    QTest::keyPress(&cmb, Qt::Key_Down);
-    QTest::keyPress(&cmb, Qt::Key_Enter);
-    QCOMPARE(cmb.getValue(), QString("item3"));
+		cmb.qwidget()->setFocus();
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Down);
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Down);
+    QTest::keyPress(cmb.qwidget(), Qt::Key_Enter);
+    QCOMPARE(cmb.value(), QString("item3"));
   }
 
 	void changeEmits()
 	{
 		QDomDocument doc;	doc.setContent(xml_search);
     QDomElement e = doc.documentElement();
-    ComboBox cmb(e, NULL);
+    ComboBox cmb(e, createMacroWindow());
 		QSignalSpy spy(&cmb, SIGNAL(wasChanged()));
-    QTest::keyClicks(&cmb, "I");
+    QTest::keyClicks(cmb.qwidget(), "I");
 		QCOMPARE(spy.count(), 1);
 	}
 };
diff --git a/client/test/testlineedit.cc b/client/test/testlineedit.cc
index 8b30295..0cf70fd 100644
--- a/client/test/testlineedit.cc
+++ b/client/test/testlineedit.cc
@@ -16,19 +16,19 @@ private slots:
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    LineEdit le(e, NULL);
+    LineEdit le(e, createMacroWindow());
 		QString teststring("hello");
-    QTest::keyClicks(&le, teststring);
-    QCOMPARE(le.getValue(), teststring);
+    QTest::keyClicks(le.qwidget(), teststring);
+    QCOMPARE(le.value(), teststring);
   }
 
 	void changeEmits()
 	{
 		QDomDocument doc;	doc.setContent(xml);
     QDomElement e = doc.documentElement();
-    LineEdit le(e, NULL);
+    LineEdit le(e, createMacroWindow());
 		QSignalSpy spy(&le, SIGNAL(wasChanged()));
-    QTest::keyClicks(&le, "h");
+    QTest::keyClicks(le.qwidget(), "h");
 		QCOMPARE(spy.count(), 1);
 	}
 };
diff --git a/client/test/util.cc b/client/test/util.cc
index 257b561..1fd09d4 100644
--- a/client/test/util.cc
+++ b/client/test/util.cc
@@ -1,10 +1,25 @@
 #include "util.h"
 #include <QDomDocument>
+#include <QSettings>
+#include <QDomNode>
+
+#include "netcom.h"
+
+#define CONFIG_DEFAULT "pracro.ini"
 
 MacroWindow *createMacroWindow()
 {
   MacroWindow *m;
-  m = NULL;
+
+  QSettings settings("pracro.ini", QSettings::IniFormat);
+  settings.beginGroup("server");
+  QString host = settings.value("host").toString();
+  int port = settings.value("port").toInt();
+  settings.endGroup();
+
+	NetCom netcom(host, port);
+	QDomNode node;
+  m = new MacroWindow(netcom, node, "test");
   return m;
 }
 
diff --git a/client/test/util.h b/client/test/util.h
index 89a887d..abf7df5 100644
--- a/client/test/util.h
+++ b/client/test/util.h
@@ -10,24 +10,24 @@ QDomElement getWidgetElement(QString type = "",
 //
 // Predefined tests
 //
-#define TEST_CREATION(W)				\
+#define TEST_CREATION(W)                            \
   QDomElement n = getWidgetElement(#W, "mywidget");	\
-  MacroWindow *wnd = createMacroWindow();		\
-  W wgd(n, wnd);					\
+  MacroWindow *wnd = createMacroWindow();           \
+  W wgd(n, wnd);
 
-#define TEST_DISABLE(W)					\
+#define TEST_DISABLE(W)                             \
   QDomElement n = getWidgetElement(#W, "mywidget");	\
-  MacroWindow *wnd = createMacroWindow();		\
-  W wdg(n, wnd);					\
-  wdg.disable();					\
-  QCOMPARE(wdg.isDisabled(), true);			\
-  wdg.enable();						\
-  QCOMPARE(wdg.isDisabled(), false);
+  MacroWindow *wnd = createMacroWindow();           \
+  W wdg(n, wnd);                                    \
+  wdg.setEnabled(false);                            \
+  QCOMPARE(wdg.enabled(), false);                   \
+  wdg.setEnabled(true);                             \
+  QCOMPARE(wdg.enabled(), true);
   
-#define TEST_VALUE(W)					\
+#define TEST_VALUE(W)                               \
   QDomElement n = getWidgetElement(#W, "mywidget");	\
-  MacroWindow *wnd = createMacroWindow();		\
-  W wdg(n, wnd);					\
-  QCOMPARE(wdg.getValue(), QString(""));		\
-  wdg.setValue("hello", "source");			\
-  QCOMPARE(wdg.getValue(), QString("hello"));
+  MacroWindow *wnd = createMacroWindow();           \
+  W wdg(n, wnd);                                    \
+  QCOMPARE(wdg.value(), QString(""));               \
+  wdg.setValue("hello", "source");                  \
+  QCOMPARE(wdg.value(), QString("hello"));
diff --git a/client/widgetbuilder.cc b/client/widgetbuilder.cc
index 0c9f3b3..e61ecd5 100644
--- a/client/widgetbuilder.cc
+++ b/client/widgetbuilder.cc
@@ -25,162 +25,14 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "widgetbuilder.h"
-#include <QLayout>
-#include "widgets.h"
-
-QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent, 
-                                 MacroWindow *macrowindow, bool watchChanges)
-{
-  QVector< Widget* > widgets;
-
-  QDomElement xml_elem = xml_node.toElement();
-
-  if(xml_elem.hasAttribute("prefilled") &&
-     xml_elem.attribute("prefilled") != "pracro") {
-    macrowindow->macroChanged();
-  }
-
-  QWidget *widget = NULL;
-  if(xml_elem.tagName() == "spacer") {
-    if(parent && parent->layout()) { 
-      ((QBoxLayout*)parent->layout())->addStretch();
-    }
-  } else if(xml_elem.tagName() == "frame") {
-    if(xml_elem.hasAttribute("caption")) {
-      GroupBox *frame = new GroupBox(xml_elem, macrowindow);
-      widgets.push_back(frame);
-      widget = frame;
-    } else {
-      Frame *frame = new Frame(xml_elem, macrowindow);
-      widgets.push_back(frame);
-      widget = frame;
-    }
-
-  } else if(xml_elem.tagName() == "label") {
-    Label *label = new Label(xml_elem, macrowindow);
-    widget = label;
-
-  } else if(xml_elem.tagName() == "lineedit") {
-    LineEdit *lineedit = new LineEdit(xml_elem, macrowindow);
-    widgets.push_back(lineedit);
-    widget = lineedit;
-    if(watchChanges)
-      lineedit->connectFrom(SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-  } else if(xml_elem.tagName() == "datetime") {
-    DateTime *datetime = new DateTime(xml_elem, macrowindow);
-    widgets.push_back(datetime);
-    widget = datetime;
-    if(watchChanges)
-      datetime->connectFrom(SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-  } else if(xml_elem.tagName() == "button") {
-    Button *button = new Button(xml_elem, macrowindow);
-    //macrowindow->connect(pushbutton, SIGNAL(act_continue()), main, SLOT(get_macro()));
-    QObject::connect(button, SIGNAL(act_commit()), macrowindow, SLOT(commit()));
-    QObject::connect(button, SIGNAL(act_reset()), macrowindow, SLOT(reset()));
-    QObject::connect(button, SIGNAL(act_cancel()), macrowindow, SLOT(cancel()));
-    QObject::connect(button, SIGNAL(act_continue(QString)), macrowindow, SLOT(cont(QString)));
-    QObject::connect(button, SIGNAL(act_continue_nocommit(QString)),
-                     macrowindow, SLOT(cont_nocommit(QString)));
-    QObject::connect(macrowindow, SIGNAL(macroHasChanged()), button, SLOT(do_enable()));
-    widget = button;
-
-  } else if(xml_elem.tagName() == "textedit") {
-    TextEdit *textedit = new TextEdit(xml_elem, macrowindow);
-    widgets.push_back(textedit);
-    widget = textedit;
-    if(watchChanges)
-      QObject::connect(textedit, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-  } else if(xml_elem.tagName() == "checkbox") {
-    CheckBox *checkbox = new CheckBox(xml_elem, macrowindow);
-    widgets.push_back(checkbox);
-    widget = checkbox;
-    if(watchChanges)
-      QObject::connect(checkbox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-  } else if(xml_elem.tagName() == "radiobuttons") {
-    RadioButtons *radiobuttons = new RadioButtons(xml_elem, macrowindow);
-    widgets.push_back(radiobuttons);
-    widget = radiobuttons;
-    if(watchChanges)
-      QObject::connect(radiobuttons, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-    //return; // Don't iterate children
-
-  } else if(xml_elem.tagName() == "combobox") {
-    ComboBox *combobox = new ComboBox(xml_elem, macrowindow);
-    widgets.push_back(combobox);
-    widget = combobox;
-    if(watchChanges)
-      QObject::connect(combobox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-    //return; // Don't iterate children
 
-  } else if(xml_elem.tagName() == "dbwidget") {
-    DBWidget *dbwidget = new DBWidget(xml_elem, macrowindow);
-    widgets.push_back(dbwidget);
-    widget = dbwidget;
-    if(watchChanges)
-      QObject::connect(dbwidget, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-  } else if(xml_elem.tagName() == "listbox") {
-    ListBox *listbox = new ListBox(xml_elem, macrowindow);
-    widgets.push_back(listbox);
-    widget = listbox;
-    if(watchChanges)
-      QObject::connect(listbox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-    //return; // Don't iterate children
-
-  } else if(xml_elem.tagName() == "multilist") {
-    MultiList *multilist = new MultiList(xml_elem, macrowindow);
-    widgets.push_back(multilist);
-    widget = multilist;
-    if(watchChanges)
-      QObject::connect(multilist, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-    if(parent && widget && parent->layout()) parent->layout()->addWidget(widget);
-    if(widget) widget->show();
-    
-    return widgets; // Don't iterate children
-
-  } else if(xml_elem.tagName() == "altcombobox") {
-    AltComboBox *altcombobox = new AltComboBox(xml_elem, macrowindow);
-    widgets.push_back(altcombobox);
-    widget = altcombobox;
-    if(watchChanges)
-      QObject::connect(altcombobox, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-    if(parent && widget && parent->layout()) parent->layout()->addWidget(widget);
-    if(widget) widget->show();
-    
-    return widgets; // Don't iterate children
-  } else if(xml_elem.tagName() == "metawidget") {
-    MetaWidget *metawidget = new MetaWidget(xml_elem, macrowindow);
-    widgets.push_back(metawidget);
-    widget = metawidget;
-    if(watchChanges)
-      QObject::connect(metawidget, SIGNAL(wasChanged()), macrowindow, SLOT(macroChanged()));
-
-    if(parent && widget && parent->layout()) parent->layout()->addWidget(widget);
-    if(widget) widget->show();
-    
-    return widgets; // Don't iterate children
-  }
-
-  QDomNodeList children = xml_node.childNodes();
-
-  for (int i=0; i<children.count();i++) {
-    QDomNode child = children.at(i);
-    widgets += widgetBuilder(child, widget, macrowindow, watchChanges);
-  }
-
-  if(parent && widget && parent->layout()) parent->layout()->addWidget(widget);
-  if(widget) widget->show();
+#include <QLayout>
+#include <QObject>
 
-  return widgets;
-}
+#include "widgets.h"
+#include "macrowindow.h"
 
-void setValues(QDomNode xml_node, MacroWindow *macrowindow)
+void setValues(QDomNode &xml_node, Widget *rootwidget)
 {
   QDomElement xml_elem = xml_node.toElement();
 
@@ -188,15 +40,18 @@ void setValues(QDomNode xml_node, MacroWindow *macrowindow)
      xml_elem.tagName() == "radiobutton") return;
 
   if(xml_elem.hasAttribute("name") && xml_elem.hasAttribute("value")) {
-    Widget *widget = macrowindow->getWidget(xml_elem.attribute("name"));
-    if(widget && widget->hasInitialValue() == false) // Don't set the value if it is already set indirectly (altcombobox)
-      widget->setValue(xml_elem.attribute("value"), xml_elem.attribute("prefilled", ""));
+    Widget *widget = rootwidget->findWidget(xml_elem.attribute("name"), true);
+    if(widget && widget->hasInitialValue() == false) {
+      // Don't set the value if it is already set indirectly (altcombobox)
+      widget->setValue(xml_elem.attribute("value"),
+                       xml_elem.attribute("prefilled", ""));
+    }
   }
 
   QDomNodeList children = xml_node.childNodes();
 
   for (int i=0; i<children.count();i++) {
     QDomNode child = children.at(i);
-    setValues(child, macrowindow);
+    setValues(child, rootwidget);
   }
 }
diff --git a/client/widgetbuilder.h b/client/widgetbuilder.h
index 7b77e67..7622aec 100644
--- a/client/widgetbuilder.h
+++ b/client/widgetbuilder.h
@@ -29,12 +29,11 @@
 
 #include <QVector>
 #include <QDomNode>
-#include <QWidget>
 #include "widgets/widget.h"
-#include "macrowindow.h"
 
-QVector< Widget* > widgetBuilder(QDomNode xml_node, QWidget *parent,
-                                 MacroWindow *macrowindow, bool watchChanges = true);
-void setValues(QDomNode xml_node, MacroWindow *macrowindow);
+//class MacroWindow;
+//void widgetBuilder(QDomNode xml_node, Widget *parent, MacroWindow *macrowindow);
+
+void setValues(QDomNode &xml_node, Widget *rootwidget);
 
 #endif/*__PRACRO_WIDGETBUILDER_H__*/
diff --git a/client/widgets/altcombobox.cc b/client/widgets/altcombobox.cc
index 352cd19..66eb444 100644
--- a/client/widgets/altcombobox.cc
+++ b/client/widgets/altcombobox.cc
@@ -26,33 +26,39 @@
  */
 #include "altcombobox.h"
 
+#include <QFrame>
 #include <QHBoxLayout>
 #include <QVBoxLayout>
+#include <QComboBox>
 
 #include "common.h"
 #include "widgetbuilder.h"
-
-#include <QObject>
 #include "multilist.h"
+#include "macrowindow.h"
 
 AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow)
-  : QFrame(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  frame = new QFrame();
+  widget = frame;
+
+  hideChildren = true;
+
   innerwidget = NULL;
 
-  setCommonAttributes(this, node);
-  setCommonLayout(this, node);
+  setCommonAttributes(frame, node);
+  setCommonLayout(frame, node);
   
   combobox = new ComboBox(node, macrowindow);
-  layout()->addWidget(combobox);
-  combobox->show();
+  frame->layout()->addWidget(combobox->qwidget());
+  combobox->qwidget()->show();
 
   altframerepl = new QFrame();
   QHBoxLayout *l = new QHBoxLayout();
   altframerepl->setLayout(l);
   l->addStretch();
   altframe = new QFrame();
-  layout()->addWidget(altframe);
+  frame->layout()->addWidget(altframe);
 
   QVector< Widget* > widgets;
 
@@ -67,13 +73,15 @@ AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow)
       if(item.hasAttribute("value")) {
         altvalue = item.attribute("value");
       } else {
-        printf("ERROR: altitem tag is missing the value attribute, in altcombobox!\n");
+        printf("ERROR: altitem tag is missing the value attribute, "
+               "in altcombobox!\n");
       }
 
       if(item.hasAttribute("innerwidget")) {
         iwname = item.attribute("innerwidget");
       } else {
-        printf("ERROR: altitem tag is missing the innerwidget attribute, in altcombobox!\n");
+        printf("ERROR: altitem tag is missing the innerwidget attribute, "
+               "in altcombobox!\n");
       }
 
       if(item.hasAttribute("layout")) {
@@ -89,72 +97,70 @@ AltComboBox::AltComboBox(QDomNode &node, MacroWindow *macrowindow)
         altframe->setLayout(layout);
       }
 
-      QDomNodeList children = item.childNodes();
-      for(int i = 0; i < children.count(); i++) {
-        QDomNode child = children.at(i);
-        widgets += widgetBuilder(child, altframe, macrowindow, false);
-      }
+      addChildren(item);
+
     }
 
   }
-  macrowindow->addAuxWidgets(widgets);
-  /*
-  QVector< Widget* >::iterator ws = widgets.begin();
-  while(ws != widgets.end()) {
-    if((*ws)->getName() == iwname) innerwidget = *ws;
-    ws++;
-  }
-  */
 
-  innerwidget = macrowindow->getWidget(iwname);
+  innerwidget = findWidget(iwname, true);
 
   if(innerwidget == NULL) {
-    printf("ERROR: Inner Widget %s not found (in multilist)!\n",
+    printf("ERROR: Inner Widget %s not found (in altcombobox)!\n",
            iwname.toStdString().c_str());
   }
 
   // To detect if the altvalue has been selected:
-  connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(onValueChange(int)));
-  connect(combobox, SIGNAL(editTextChanged(const QString&)), this, SLOT(onValueChange(const QString&)));
+  connect(combobox->qwidget(), SIGNAL(currentIndexChanged(int)),
+          this, SLOT(onValueChange(int)));
+  connect(combobox->qwidget(), SIGNAL(editTextChanged(const QString&)),
+          this, SLOT(onValueChange(const QString&)));
 
   // To react to changes in any of the children:
   connect(combobox, SIGNAL(wasChanged()), this, SLOT(onChildChange()));
-  innerwidget->connectFrom(SIGNAL(wasChanged()), this, SLOT(onChildChange()));
+  if(innerwidget)
+    connect(innerwidget, SIGNAL(wasChanged()), this, SLOT(onChildChange()));
 
-  layout()->setContentsMargins(0,0,0,0);
+  frame->layout()->setContentsMargins(0,0,0,0);
   altframe->layout()->setContentsMargins(0,0,0,0);
 
-  show(); // Force altframe to get resized to its real size.
+  frame->show(); // Force altframe to get resized to its real size.
   altframerepl->setFixedHeight(altframe->height());
 }
 
+AltComboBox::~AltComboBox()
+{
+  // delete frame;
+}
 
-bool AltComboBox::isValid()
+bool AltComboBox::preValid()
 {
-  if(!combobox->isValid()) return false;
+  if(!combobox->valid()) return false;
 
-  if(innerwidget && combobox->getValue() == altvalue) {
-    if(!innerwidget->isValid()) return false;
+  if(innerwidget && combobox->value() == altvalue) {
+    if(!innerwidget->valid()) return false;
   }
 
-  return regexpValidator() && luaValidator();
+  return true;
 }
 
-QString AltComboBox::getValue()
+QString AltComboBox::value()
 {
-  if(combobox->getValue() == altvalue) {
-    if(innerwidget) return innerwidget->getValue();
+  if(combobox->value() == altvalue) {
+    if(innerwidget) return innerwidget->value();
     else return "";
   } else {
-    return combobox->getValue();
+    return combobox->value();
   }
 }
 
 void AltComboBox::setValue(QString value, QString source)
 {
-  //  if(isUserSource(source)) emit wasChanged(); // No need for this, it will be enitted by the children.
+  // No need for this, it will be enitted by the children.
+  // if(isUserSource(source)) emit wasChanged();
 
-  if(combobox->findData(value) != -1) {
+  QComboBox *cmb = (QComboBox*)combobox->qwidget();
+  if(cmb->findData(value) != -1) {
 
     combobox->setValue(value, source);
 
@@ -171,63 +177,39 @@ void AltComboBox::setValue(QString value, QString source)
 
 void AltComboBox::onValueChange(int index)
 {
-  if(combobox->itemData(index).toString() == altvalue) {
+  QComboBox *cmb = (QComboBox*)combobox->qwidget();
+  if(cmb->itemData(index).toString() == altvalue) {
     //    altframe->setEnabled(true);
     altframerepl->setVisible(false);
-    layout()->removeWidget(altframerepl);
+    frame->layout()->removeWidget(altframerepl);
 
-    layout()->addWidget(altframe);
+    frame->layout()->addWidget(altframe);
     altframe->setVisible(true);
   } else {
     //    altframe->setEnabled(false);
     altframe->setVisible(false);
-    layout()->removeWidget(altframe);
+    frame->layout()->removeWidget(altframe);
 
-    layout()->addWidget(altframerepl);
+    frame->layout()->addWidget(altframerepl);
     altframerepl->setVisible(true);
   }
 }
 
 void AltComboBox::onValueChange(const QString &text)
 {
-  onValueChange(combobox->findText(text));
-}
-
-void AltComboBox::enable()
-{
-  setEnabled(true);
-}
-
-void AltComboBox::disable()
-{
-  setEnabled(false);
-}
-
-bool AltComboBox::isDisabled()
-{
-  return isEnabled() == false;
+  QComboBox *cmb = (QComboBox*)combobox->qwidget();
+  onValueChange(cmb->findText(text));
 }
 
 void AltComboBox::onChildChange()
 {
   emit wasChanged();
-}
-
-void AltComboBox::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void AltComboBox::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
+  eventOnChange();
 }
 
 bool AltComboBox::setKeyboardFocus()
 {
-  if(combobox->getValue() == altvalue) {
+  if(combobox->value() == altvalue) {
     if(innerwidget) return innerwidget->setKeyboardFocus();
   }
 
@@ -235,7 +217,19 @@ bool AltComboBox::setKeyboardFocus()
   return true;
 }
 
-void AltComboBox::setVisibility(bool visible)
+void AltComboBox::setWdgValid(bool valid)
 {
-  setVisible(visible);
+  QPalette palette;
+
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
+
+  frame->setPalette(palette);
+  combobox->qwidget()->setPalette(palette);
+  if(innerwidget) innerwidget->setWdgValid(valid);
 }
diff --git a/client/widgets/altcombobox.h b/client/widgets/altcombobox.h
index c52bd20..9f90f8b 100644
--- a/client/widgets/altcombobox.h
+++ b/client/widgets/altcombobox.h
@@ -31,43 +31,32 @@
 
 #include "combobox.h"
 
-#include <QFrame>
 #include <QDomNode>
 #include <QMap>
 
-class AltComboBox : public QFrame, public Widget
+class QFrame;
+class AltComboBox : public Widget
 {
 Q_OBJECT
 public:
   AltComboBox(QDomNode &node, MacroWindow *macrowindow);
+  ~AltComboBox();
 
-  bool isValid();
-
-  QString getValue();
+  QString value();
   void setValue(QString value, QString source = "");
 
-  void disable();
-  void enable();
-  bool isDisabled();
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
+  bool preValid();
+  void setWdgValid(bool valid);
 
   bool setKeyboardFocus();
-  void setVisibility(bool visible);
 
 public slots:
   void onValueChange(int index);
   void onValueChange(const QString &text);
   void onChildChange();
 
-signals:
-  void wasChanged();
-
 private:
+  QFrame *frame;
   ComboBox *combobox;
   Widget *innerwidget;
   QString altvalue;
diff --git a/client/widgets/button.cc b/client/widgets/button.cc
index 963242c..3234296 100644
--- a/client/widgets/button.cc
+++ b/client/widgets/button.cc
@@ -25,70 +25,53 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "button.h"
+
 #include <stdio.h>
+#include <QPushButton>
 
 #include "common.h"
 
+#include "macrowindow.h"
+
 Button::Button(QDomNode &node, MacroWindow *macrowindow)
-  : QPushButton(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  resetToDisabled = false;
-  setCommonAttributes(this, node);
+  button = new QPushButton();
+  widget = button;
 
-  QDomElement elem = node.toElement();
+  setCommonAttributes(button, node);
 
-  if(elem.hasAttribute("field")) {
-    field = elem.attribute("field");
-  }
+  QDomElement elem = node.toElement();
   
-  if(elem.hasAttribute("caption")) {
-    setText(elem.attribute("caption"));
-  } else {
-    setText("");
-  }
+  button->setText(elem.attribute("caption", ""));
 
   if(elem.hasAttribute("action")) {
     if(elem.attribute("action") == "commit") {
-      connect(this, SIGNAL(clicked()), this, SLOT(commit()));
-      setIcon(QPixmap(":icons/add.png"));
-      setEnabled(false);
-
-      //
-      // Hack to re-disable the commit button when the macro is reset.
-      //
-      resetToDisabled = true;
-      widget_name = "commit_button_" + QString::number((int)this);
-      QVector< Widget* > ws;
-      ws.push_back(this);
-      macrowindow->addAuxWidgets(ws);
-
-    } else if(elem.attribute("action") == "reset") {
-      connect(this, SIGNAL(clicked()), this, SLOT(_reset()));
-      setIcon(QPixmap(":icons/del.png"));
+      connect(button, SIGNAL(clicked()), this, SLOT(commit()));
+      button->setIcon(QPixmap(":icons/add.png"));
+      button->setEnabled(false);
     } else if(elem.attribute("action") == "cancel") {
-      connect(this, SIGNAL(clicked()), this, SLOT(cancel()));
-      setIcon(QPixmap(":icons/del.png"));
-    } else if(elem.attribute("action") == "continue") {
-      connect(this, SIGNAL(clicked()), this, SLOT(cont()));
-      setIcon(QPixmap(":icons/add.png"));
-    } else if(elem.attribute("action") == "continue_nocommit") {
-      connect(this, SIGNAL(clicked()), this, SLOT(cont_nocommit()));
-    } 
-  } else {
-    setEnabled(false);
+      connect(button, SIGNAL(clicked()), this, SLOT(cancel()));
+      button->setIcon(QPixmap(":icons/del.png"));
+    }
   }
+
+  connect(this, SIGNAL(act_commit()), macrowindow, SLOT(commit()));
+  connect(this, SIGNAL(act_cancel()), macrowindow, SLOT(cancel()));
+  connect(macrowindow, SIGNAL(macroHasChanged()), this, SLOT(do_enable()));
+
 }
 
-void Button::commit()
+Button::~Button()
 {
-  emit act_commit();
-  printf("Emit: commit\n");
+  printf("Delete (Button) %p\n", this); fflush(stdout);
+  //  delete button;
 }
 
-void Button::_reset()
+void Button::commit()
 {
-  emit act_reset();
-  printf("Emit: reset\n");
+  emit act_commit();
+  printf("Emit: commit\n");
 }
 
 void Button::cancel()
@@ -97,62 +80,7 @@ void Button::cancel()
   printf("Emit: cancel\n");
 }
 
-void Button::cont()
-{
-  emit act_continue(field);
-  printf("Emit: continue\n");
-}
-
-void Button::cont_nocommit()
-{
-  emit act_continue_nocommit(field);
-  printf("Emit: continue_nocommit\n");
-}
-
 void Button::do_enable()
 {
-  setEnabled(true);
-}
-
-void Button::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void Button::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
-void Button::setVisibility(bool visible)
-{
-  setVisible(visible);
-}
-
-bool Button::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
-
-void Button::reset()
-{
-  if(resetToDisabled) setEnabled(false);
-}
-
-void Button::enable()
-{
-  setEnabled(true);
-}
-
-void Button::disable()
-{
-  setEnabled(false);
-}
-
-bool Button::isDisabled()
-{
-  return isEnabled() == false;
+  button->setEnabled(true);
 }
diff --git a/client/widgets/button.h b/client/widgets/button.h
index 64d51f9..80594db 100644
--- a/client/widgets/button.h
+++ b/client/widgets/button.h
@@ -28,49 +28,31 @@
 #define __PRACRO_BUTTON_H__
 
 #include "widget.h"
-#include <QPushButton>
-#include <QWidget>
+
 #include <QDomNode>
 
-class Button : public QPushButton, public Widget
+class QPushButton;
+class Button : public Widget
 {
 Q_OBJECT
 public:
   Button(QDomNode &node, MacroWindow *macrowindow);
-  QString field;
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  void setVisibility(bool visible);
-
-  bool setKeyboardFocus();
-
-  void reset();
+  ~Button();
 
-  void disable();
-  void enable();
-  bool isDisabled();
+  QString value() { return ""; }
+  void setValue(QString, QString) {}
+  void setWdgValid(bool) {}
 
 public slots:
   void commit();
-  void _reset();
   void cancel();
-  void cont();
-  void cont_nocommit();
   void do_enable();
 
 signals:
   void act_commit();
-  void act_reset();
   void act_cancel();
-  void act_continue(QString);
-  void act_continue_nocommit(QString);
 
 private:
-  bool resetToDisabled;
+  QPushButton *button;
 };
 #endif/*__PRACRO_BUTTON_H__*/
diff --git a/client/widgets/checkbox.cc b/client/widgets/checkbox.cc
index e550289..19b59e6 100644
--- a/client/widgets/checkbox.cc
+++ b/client/widgets/checkbox.cc
@@ -26,19 +26,24 @@
  */
 #include "checkbox.h"
 
+#include <QCheckBox>
+
 #include "common.h"
 
 CheckBox::CheckBox(QDomNode &node, MacroWindow *macrowindow)
-  : QCheckBox(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  checkbox = new QCheckBox();
+  widget = checkbox;
+
   changedByUser = true;
   
-  setCommonAttributes(this, node);
+  setCommonAttributes(checkbox, node);
 
   QDomElement elem = node.toElement();
 
   if(elem.hasAttribute("caption")) {
-    setText(elem.attribute("caption"));
+    checkbox->setText(elem.attribute("caption"));
   }
 
   if(elem.hasAttribute("truevalue")) {
@@ -53,12 +58,18 @@ CheckBox::CheckBox(QDomNode &node, MacroWindow *macrowindow)
     falsevalue = "false";
   }
   
-  connect(this, SIGNAL(stateChanged(int)), this, SLOT(state_change(int)));
+  connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(state_change(int)));
+}
+
+CheckBox::~CheckBox()
+{
+  printf("Delete (CheckBox) %p\n", this); fflush(stdout);
+  //  delete checkbox;
 }
 
-QString CheckBox::getValue()
+QString CheckBox::value()
 {
-  if(isChecked()) return truevalue;
+  if(checkbox->isChecked()) return truevalue;
   return falsevalue;
 }
 
@@ -68,69 +79,51 @@ void CheckBox::setValue(QString value, QString source)
 
   changedByUser = false;
 
-  bool old = isChecked();
+  bool old = checkbox->isChecked();
 
   if(value == truevalue) {
-    setChecked(true);
+    checkbox->setChecked(true);
   } else if(value == falsevalue) {
-    setChecked(false);
+    checkbox->setChecked(false);
   } else {
     printf("Unknown checkbox value: %s\n", value.toStdString().c_str());
   }
 
   // If set operation did not change the value we must invocate the code manually.
-  if(old == isChecked()) state_change(0);
+  if(old == checkbox->isChecked()) state_change(0);
 
   setInitialValue(value);
 
   changedByUser = true;
 }
-/*
-bool CheckBox::isValid()
-{
-  return luaValidator();
-}
-*/
+
 void CheckBox::state_change(int)
 {
   if(changedByUser) emit wasChanged();
-  luaValidator();
+  eventOnChange();
 }
 
-void CheckBox::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
+bool CheckBox::checked()
 {
-  connect(this, signal, receiver, method);
+  return value() == truevalue;
 }
 
-void CheckBox::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
+void CheckBox::setChecked(bool checked)
 {
-  connect(sender, signal, this, method);
+  setValue(checked ? truevalue : falsevalue);
 }
 
-void CheckBox::setVisibility(bool visible)
+void CheckBox::setWdgValid(bool valid)
 {
-  setVisible(visible);
-}
+  QPalette palette;
 
-bool CheckBox::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
-
-void CheckBox::enable()
-{
-  setEnabled(true);
-}
-
-void CheckBox::disable()
-{
-  setEnabled(false);
-}
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
 
-bool CheckBox::isDisabled()
-{
-  return isEnabled() == false;
+  checkbox->setPalette(palette);
 }
diff --git a/client/widgets/checkbox.h b/client/widgets/checkbox.h
index 5131f56..7cf2651 100644
--- a/client/widgets/checkbox.h
+++ b/client/widgets/checkbox.h
@@ -29,44 +29,33 @@
 
 #include "widget.h"
 #include <QDomNode>
-#include <QCheckBox>
 
-class CheckBox : public QCheckBox, public Widget
+class QCheckBox;
+class CheckBox : public Widget
 {
 Q_OBJECT
 public:
   CheckBox(QDomNode &node, MacroWindow *macrowindow);
+  ~CheckBox();
 
-  //  bool isValid();
-
-  QString getValue();
+  QString value();
   void setValue(QString value, QString source = "");
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  void setVisibility(bool visible);
+  void setWdgValid(bool valid);
 
-  bool setKeyboardFocus();
-
-  void enable();
-  void disable();
-  bool isDisabled();
+  bool checked();
+  void setChecked(bool checked);
 
 public slots:
   void state_change(int);
 
-signals:
-  void wasChanged();
-
 private:
   QString truevalue;
   QString falsevalue;
 
   bool changedByUser;
+  
+  QCheckBox *checkbox;
 };
 
 #endif/*__PRACRO_CHECKBOX_H__*/
diff --git a/client/widgets/combobox.cc b/client/widgets/combobox.cc
index f81d989..5980400 100644
--- a/client/widgets/combobox.cc
+++ b/client/widgets/combobox.cc
@@ -25,6 +25,9 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "combobox.h"
+
+#include <QComboBox>
+
 #include <QDomNodeList>
 #include <QCompleter>
 #include <QRegExpValidator>
@@ -32,6 +35,9 @@
 #include <QLineEdit>
 #include <QCoreApplication>
 
+#include <QEvent>
+#include <QWheelEvent>
+
 #include "common.h"
 
 // Enable this to make the combobox drawn in windows style.
@@ -44,15 +50,18 @@ QWindowsStyle s;
 #endif/*STYLE_HACK*/
 
 ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow)
-  : QComboBox(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setCommonAttributes(this, node);
+  combobox = new QComboBox();
+  widget = combobox;
+
+  setCommonAttributes(combobox, node);
 
 #ifdef STYLE_HACK
-  setStyle(&s);
+  combobox->setStyle(&s);
 #endif/*STYLE_HACK*/
 
-  setInsertPolicy(QComboBox::InsertAlphabetically);
+  combobox->setInsertPolicy(QComboBox::InsertAlphabetically);
 
   QDomNodeList children = node.childNodes();
   QStringList itemlist;
@@ -61,15 +70,16 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow)
     QDomNode child = children.at(i);
     QDomElement combo_elem = child.toElement();
     if(combo_elem.hasAttribute("caption") && combo_elem.hasAttribute("value")) {
-      addItem(combo_elem.attribute("caption"), combo_elem.attribute("value"));
+      combobox->addItem(combo_elem.attribute("caption"),
+                        combo_elem.attribute("value"));
       itemlist << combo_elem.attribute("caption");
     } else {
-      printf("XML Error!!! Combobox item is missing one or more attributes...\n");
+      printf("XML Error!!! Combobox is missing one or more attributes...\n");
     }
   }
 
   // Make empty default selection.
-  setCurrentIndex(-1);
+  combobox->setCurrentIndex(-1);
 
   QDomElement elem = node.toElement();
 
@@ -82,25 +92,26 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow)
 
   switch(combotype) {
   case SELECT:
-    setEditable(false);
+    combobox->setEditable(false);
 
 #ifndef STYLE_HACK
-    setEditable(true);
-    lineEdit()->setReadOnly(true);
-    lineEdit()->installEventFilter(this);
+    combobox->setEditable(true);
+    combobox->lineEdit()->setReadOnly(true);
+    combobox->lineEdit()->installEventFilter(this);
 #endif/*STYLE_HACK*/
 
-    connect(this, SIGNAL(currentIndexChanged(QString)), this, SLOT(changed()));
+    connect(combobox, SIGNAL(currentIndexChanged(QString)),
+            this, SLOT(changed()));
     break;
 
   case EDIT:
-    setEditable(true);
+    combobox->setEditable(true);
 
-    connect(this, SIGNAL(editTextChanged(QString)), this, SLOT(changed()));
+    connect(combobox, SIGNAL(editTextChanged(QString)), this, SLOT(changed()));
     break;
 
   case SEARCH:
-    setEditable(true);
+    combobox->setEditable(true);
     {
       QString rxs = "(";
       for(int i = 0; i < itemlist.size(); i++) {
@@ -115,11 +126,11 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow)
       QCompleter *completer = new QCompleter(itemlist, this);
       completer->setCaseSensitivity(Qt::CaseInsensitive);
       completer->setCompletionMode(QCompleter::PopupCompletion);
-      setCompleter(completer);
-      setValidator(new QRegExpValidator(rx, this));
+      combobox->setCompleter(completer);
+      combobox->setValidator(new QRegExpValidator(rx, this));
     }
 
-    connect(this, SIGNAL(editTextChanged(QString)), this, SLOT(changed()));
+    connect(combobox, SIGNAL(editTextChanged(QString)), this, SLOT(changed()));
     break;
   }
 
@@ -128,14 +139,20 @@ ComboBox::ComboBox(QDomNode &node, MacroWindow *macrowindow)
   ischangingbyuser = true;
 }
 
-QString ComboBox::getValue()
+ComboBox::~ComboBox()
+{
+  // delete combobox;
+}
+
+QString ComboBox::value()
 {
   QString value;
 
-  int idx = currentIndex();
+  int idx = combobox->currentIndex();
   
-  if(idx != -1 && itemText(idx) == currentText()) value = itemData(idx).toString();
-  else value = currentText();
+  if(idx != -1 && combobox->itemText(idx) == combobox->currentText())
+    value = combobox->itemData(idx).toString();
+  else value = combobox->currentText();
 
   return value;
 }
@@ -144,93 +161,38 @@ void ComboBox::setValue(QString value, QString source)
 {
   if(isUserSource(source)) emit wasChanged();
 
-  int idx = findData(value);
+  int idx = combobox->findData(value);
 
   //  printf("setValue(\"%s\") - %d\n", value.toStdString().c_str(), idx);
 
   ischangingbyuser = false;
-  setCurrentIndex(idx);
+  combobox->setCurrentIndex(idx);
   ischangingbyuser = true;
 
   setInitialValue(value);
 
 }
 
-bool ComboBox::isValid()
+bool ComboBox::preValid()
 {
   if(combotype == SELECT) {
-    if(currentIndex() != -1) return true;
+    if(combobox->currentIndex() != -1) return true;
     else return false;
   }
-  return rx.exactMatch(currentText()) && luaValidator();
+  return true;
 }
 
 void ComboBox::changed()
 {
   if(ischangingbyuser) emit wasChanged();
-
-  QPalette palette;
-
-  if(isEnabled()) {
-    if(isValid() && luaValidator()) {
-      // valid string
-      palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-    } else {
-      // invalid string
-      palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
-    }
-  } else {
-    // valid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-  }
-
-  if(lineEdit()) lineEdit()->setPalette(palette);
-  else setPalette(palette);
-}
-
-void ComboBox::enable()
-{
-  setEnabled(true);
-}
-
-void ComboBox::disable()
-{
-  setEnabled(false);
-}
-
-bool ComboBox::isDisabled()
-{
-  return isEnabled() == false;
-}
-
-void ComboBox::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void ComboBox::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
-bool ComboBox::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
-
-void ComboBox::setVisibility(bool visible)
-{
-  setVisible(visible);
+  eventOnChange();
 }
 
 bool ComboBox::eventFilter(QObject *obj, QEvent *event)
 {
   if(combotype == SELECT) {
     if(event->type() == QEvent::MouseButtonRelease) {
-      showPopup();
+      combobox->showPopup();
     }
   }
 
@@ -239,7 +201,7 @@ bool ComboBox::eventFilter(QObject *obj, QEvent *event)
 
 void ComboBox::wheelEvent(QWheelEvent *e)
 {
-  QCoreApplication::sendEvent(nativeParentWidget(), e);
+  QCoreApplication::sendEvent(combobox->nativeParentWidget(), e);
 }
 
 void ComboBox::changeEvent(QEvent *event)
@@ -248,3 +210,19 @@ void ComboBox::changeEvent(QEvent *event)
     changed();
   }
 }
+
+void ComboBox::setWdgValid(bool valid)
+{
+  QPalette palette;
+
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
+
+  if(combobox->lineEdit()) combobox->lineEdit()->setPalette(palette);
+  combobox->setPalette(palette);
+}
diff --git a/client/widgets/combobox.h b/client/widgets/combobox.h
index 8059e81..a706075 100644
--- a/client/widgets/combobox.h
+++ b/client/widgets/combobox.h
@@ -27,47 +27,36 @@
 #ifndef __PRACRO_COMBOBOX_H__
 #define __PRACRO_COMBOBOX_H__
 
-#include "widget.h"
 #include <QDomNode>
-#include <QComboBox>
 #include <QRegExp>
 
+#include "widget.h"
+
 typedef enum {
   SELECT,
   EDIT,
   SEARCH
 } types_t;
 
-class ComboBox : public QComboBox, public Widget
+class QComboBox;
+class QWheelEvent;
+class ComboBox : public Widget
 {
 Q_OBJECT
 public:
   ComboBox(QDomNode &node, MacroWindow *macrowindow);
+  ~ComboBox();
 
-  bool isValid();
-
-  QString getValue();
+  QString value();
   void setValue(QString value, QString source = "");
 
-  void disable();
-  void enable();
-  bool isDisabled();
+  bool preValid();
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  bool setKeyboardFocus();
-  void setVisibility(bool visible);
+  void setWdgValid(bool valid);
 
 public slots:
   void changed();
 
-signals:
-  void wasChanged();
-
 protected:
   bool eventFilter(QObject *obj, QEvent *event);
   void wheelEvent(QWheelEvent *);
@@ -78,6 +67,8 @@ private:
   QString combo_value;
   types_t combotype;
   bool ischangingbyuser;
+
+  QComboBox *combobox;
 };
 
 #endif/*__PRACRO_COMBOBOX_H__*/
diff --git a/client/widgets/datetime.cc b/client/widgets/datetime.cc
index 0b91a40..b97178f 100644
--- a/client/widgets/datetime.cc
+++ b/client/widgets/datetime.cc
@@ -26,87 +26,89 @@
  */
 #include "datetime.h"
 
+#include <QDateTimeEdit>
+
 #include "common.h"
 
 DateTime::DateTime(QDomNode &node, MacroWindow *macrowindow)
-  : QDateTimeEdit(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  datetimeedit = new QDateTimeEdit();
+  widget = datetimeedit;
+
   changedByUser = true;
-  setCommonAttributes(this, node);
+  setCommonAttributes(datetimeedit, node);
 
-  setCalendarPopup(true);
+  datetimeedit->setCalendarPopup(true);
 //  setMinimumDateTime(QDateTime::fromTime_t(0));
-  setMinimumDate(QDate(1900,1,1));
-  setMinimumTime(QTime(0,0));
+  datetimeedit->setMinimumDate(QDate(1900,1,1));
+  datetimeedit->setMinimumTime(QTime(0,0));
 
   QDomElement elem = node.toElement();
 
   switch(elem.attribute("fuzziness", "5").toLong()) {
   case 1:
-    setDisplayFormat("yyyy");
+    datetimeedit->setDisplayFormat("yyyy");
     break;
 
   case 2:
-    setDisplayFormat("MMMM yyyy");
+    datetimeedit->setDisplayFormat("MMMM yyyy");
     break;
 
   case 3:
-    setDisplayFormat("dd MMMM yyyy");
+    datetimeedit->setDisplayFormat("dd MMMM yyyy");
     break;
 
   case 4:
-    setDisplayFormat("dd MMMM yyyy hh");
+    datetimeedit->setDisplayFormat("dd MMMM yyyy hh");
     break;
 
   case 5:
-    setDisplayFormat("dd MMMM yyyy hh:mm");
+    datetimeedit->setDisplayFormat("dd MMMM yyyy hh:mm");
     break;
 
   case 6:
-    setDisplayFormat("dd MMMM yyyy hh:mm:ss");
+    datetimeedit->setDisplayFormat("dd MMMM yyyy hh:mm:ss");
     break;
 
   case 7:
   default:
-    setDisplayFormat("dd MMMM yyyy hh:mm:ss:zzz");
+    datetimeedit->setDisplayFormat("dd MMMM yyyy hh:mm:ss:zzz");
     break;
   }
     
   /*
   if(elem.hasAttribute("readonly")) {
-    if(elem.attribute("readonly") == "true" || elem.attribute("readonly") == "1") {
+    if(elem.attribute("readonly") == "true" ||
+       elem.attribute("readonly") == "1") {
       setReadOnly(true);
-    } else if(elem.attribute("readonly") == "false" || elem.attribute("readonly") == "0") {
+    } else if(elem.attribute("readonly") == "false" ||
+              elem.attribute("readonly") == "0") {
       setReadOnly(false);
     } else {
-      printf("Unknown value of readonly: %s\n", elem.attribute("readonly").toStdString().c_str());
+      printf("Unknown value of readonly: %s\n",
+             elem.attribute("readonly").toStdString().c_str());
     }
   }
   */
-  connect(this, SIGNAL(dateTimeChanged(const QDateTime &)),
+  connect(datetimeedit, SIGNAL(dateTimeChanged(const QDateTime &)),
           this, SLOT(changed(const QDateTime &)));
 }
 
-void DateTime::changed(const QDateTime &)
+DateTime::~DateTime()
 {
-  QPalette palette;
-
-  if(luaValidator()) {
-    // valid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-  } else {
-    // invalid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(200, 230, 200)));
-  }
-
-  setPalette(palette);
+  // delete datetimeedit;
+}
 
+void DateTime::changed(const QDateTime &)
+{
   if(changedByUser) emit wasChanged(); 
+  eventOnChange();
 }
 
-QString DateTime::getValue()
+QString DateTime::value()
 {
-  return QString::number(dateTime().toUTC().toTime_t());
+  return QString::number(datetimeedit->dateTime().toUTC().toTime_t());
 }
 
 void DateTime::setValue(QString value, QString source)
@@ -114,46 +116,23 @@ void DateTime::setValue(QString value, QString source)
   changedByUser = false;
   if(isUserSource(source)) emit wasChanged();
 
-  setDateTime(QDateTime::fromTime_t(value.toUInt()));
+  datetimeedit->setDateTime(QDateTime::fromTime_t(value.toUInt()));
 
   setInitialValue(value);
   changedByUser = true;
 }
 
-void DateTime::enable()
-{
-  setEnabled(true);
-}
-
-void DateTime::disable()
-{
-  setEnabled(false);
-}
-
-bool DateTime::isDisabled()
-{
-  return isEnabled() == false;
-}
-
-void DateTime::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
+void DateTime::setWdgValid(bool valid)
 {
-  connect(this, signal, receiver, method);
-}
-
-void DateTime::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
+  QPalette palette;
 
-bool DateTime::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(200, 230, 200)));
+  }
 
-void DateTime::setVisibility(bool visible)
-{
-  setVisible(visible);
+  datetimeedit->setPalette(palette);
 }
diff --git a/client/widgets/datetime.h b/client/widgets/datetime.h
index 8699816..b6e2d36 100644
--- a/client/widgets/datetime.h
+++ b/client/widgets/datetime.h
@@ -28,39 +28,29 @@
 #define __PRACRO_DATETIME_H__
 
 #include "widget.h"
-#include <QDateTimeEdit>
+
 #include <QDomNode>
+#include <QDateTime>
 
-class DateTime : public QDateTimeEdit, public Widget
+class QDateTimeEdit;
+class DateTime : public Widget
 {
 Q_OBJECT
 public:
   DateTime(QDomNode &node, MacroWindow *macrowindow);
+  ~DateTime();
 
-  QString getValue();
+  QString value();
   void setValue(QString value, QString source = "");
 
-  void disable();
-  void enable();
-  bool isDisabled();
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  bool setKeyboardFocus();
-  void setVisibility(bool visible);
+  void setWdgValid(bool valid);
 
 public slots:
   void changed(const QDateTime &);
 
-signals:
-  void wasChanged();
-
 private:
   bool changedByUser;
+  QDateTimeEdit *datetimeedit;
 };
 
 #endif/*__PRACRO_DATETIME_H__*/
diff --git a/client/widgets/dbwidget.cc b/client/widgets/dbwidget.cc
index 31a6a42..3852b21 100644
--- a/client/widgets/dbwidget.cc
+++ b/client/widgets/dbwidget.cc
@@ -34,12 +34,19 @@
 #include <QSqlQuery>
 #include <QSqlError>
 #include <QLineEdit>
+#include <QComboBox>
+
 #include "formatparser.h"
 #include "common.h"
 
+#define EMPTY_STRING "Write something in the searchfield"
+
 DBWidget::DBWidget(QDomNode &node, MacroWindow *macrowindow)
-  : QComboBox(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  combobox = new QComboBox();
+  widget = combobox;
+
   changedByUser = true;
 
   QDomElement elem = node.toElement();
@@ -72,24 +79,25 @@ DBWidget::DBWidget(QDomNode &node, MacroWindow *macrowindow)
     printf("DB connect failed!\n");
   }
 
-  setCommonAttributes(this, node);
+  setCommonAttributes(combobox, node);
 
-  setInsertPolicy(QComboBox::InsertAlphabetically);
-  setEditable(true);
+  combobox->setInsertPolicy(QComboBox::InsertAlphabetically);
+  combobox->setEditable(true);
 
   // Make empty default selection.
-  addItem(tr("Write something in the searchfield"));
-  setCurrentIndex(-1);
+  combobox->addItem(tr("Write something in the searchfield"));
+  combobox->setCurrentIndex(-1);
 
   QStringListModel *strlst = new QStringListModel();
   QCompleter *completer = new QCompleter(this);
   completer->setCaseSensitivity(Qt::CaseInsensitive);
   completer->setCompletionMode(QCompleter::PopupCompletion);
   completer->setModel(strlst);
-  setCompleter(completer);
+  combobox->setCompleter(completer);
 
-  connect(this, SIGNAL(editTextChanged(QString)), this, SLOT(changed()));
-  connect((QWidget*)lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(update_list(QString)));
+  connect(combobox, SIGNAL(editTextChanged(QString)), this, SLOT(changed()));
+  connect((QWidget*)combobox->lineEdit(), SIGNAL(textEdited(QString)),
+          this, SLOT(update_list(QString)));
 
   changed();
 }
@@ -98,14 +106,15 @@ DBWidget::~DBWidget()
 {
   db.close();
   db = QSqlDatabase();
+  // delete combobox;
 }
 
 
-QString DBWidget::getValue()
+QString DBWidget::value()
 {
   QString value;
 
-  value = currentText();
+  value = combobox->currentText();
 
   return value;
 }
@@ -115,52 +124,39 @@ void DBWidget::setValue(QString value, QString source)
   changedByUser = false;
   if(isUserSource(source)) emit wasChanged();
 
-  setEditText(value);
+  combobox->setEditText(value);
 
   setInitialValue(value);
   changedByUser = true;
 }
 
-bool DBWidget::isValid()
+bool DBWidget::preValid()
 {
-  
-  return currentText() != tr("Write something in the searchfield")
-    && findText(currentText()) != -1;
-
-  /*
-  QSqlQuery query = db.exec("SELECT " + select + " FROM " + from + " WHERE LOWER(" + where + ") = '" + currentText().toLower() + "';");
-
-  return query.size() != 0;
-  */
+  return combobox->currentText() != tr(EMPTY_STRING) &&
+    combobox->currentText() != "" &&
+    combobox->findText(combobox->currentText()) != -1
+    ;
 }
 
 void DBWidget::changed()
 {
-  QPalette palette;
-
-  if(isValid() && luaValidator()) {
-    // valid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-  } else {
-    // invalid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
-  }
-
-  lineEdit()->setPalette(palette);
-
   if(changedByUser) emit wasChanged();
+  eventOnChange();
 }
 
 void DBWidget::update_list(QString prefix)
 {
   if(prefix == "") {
-    clear();
-    addItem(tr("Write something in the searchfield"));
-    setCurrentIndex(-1);
+    combobox->clear();
+    combobox->addItem(tr(EMPTY_STRING));
+    combobox->setCurrentIndex(-1);
     return;
   }
 
-  QSqlQuery query = db.exec("SELECT " + select + " FROM " + from + " WHERE LOWER(" + where + ") LIKE '" + prefix.toLower() + "%';");
+  QSqlQuery query = db.exec("SELECT " + select +
+                            " FROM " + from + 
+                            " WHERE LOWER(" + where + ")"
+                            " LIKE '" + prefix.toLower() + "%';");
 
   QStringList lst;
   while(query.next()) {
@@ -169,88 +165,30 @@ void DBWidget::update_list(QString prefix)
 
   lst.sort();
 
-  QStringListModel *mdl = (QStringListModel *)completer()->model();
+  QStringListModel *mdl = (QStringListModel *)combobox->completer()->model();
   if(mdl->stringList() != lst) {
-    QString val = currentText();
-    clear();
+    QString val = combobox->currentText();
+    combobox->clear();
     if(lst.size() == 0) lst << "S�gningen passede ikke p� noget.";
-    addItems(lst);
-    setEditText(val);
+    combobox->addItems(lst);
+    combobox->setEditText(val);
     mdl->setStringList(lst);
     //showPopup();
   }
 }
 
-void DBWidget::enable()
+void DBWidget::setWdgValid(bool valid)
 {
-  setEnabled(true);
-}
-
-void DBWidget::disable()
-{
-  setEnabled(false);
-}
-
-bool DBWidget::isDisabled()
-{
-  return isEnabled() == false;
-}
-
-void DBWidget::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void DBWidget::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
+  QPalette palette;
 
-bool DBWidget::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
 
-void DBWidget::setVisibility(bool visible)
-{
-  setVisible(visible);
+  combobox->lineEdit()->setPalette(palette);
+  combobox->setPalette(palette);
 }
-/*
-$ psql -h sensei -d lms -U postgres
-===================================================================
-         List of relations
- Schema | Name  | Type  |  Owner   
---------+-------+-------+----------
- public | lms01 | table | postgres
-(1 row)
-
-lms=# \d lms01
-                       Table "public.lms01"
-            Column             |         Type          | Modifiers 
--------------------------------+-----------------------+-----------
- drugid                        | character varying(32) | 
- producttype                   | character varying(14) | 
- productsubtype                | character varying(14) | 
- sequencetext                  | character varying(28) | 
- specialitynumber              | character varying(20) | 
- drugname                      | character varying(70) | 
- dosageform_text               | character varying(50) | 
- dosageform_code               | character varying(24) | 
- further_dos_info              | character varying(24) | 
- strength_text                 | character varying(50) | 
- strength_numeric              | character varying(30) | 
- strength_unit                 | character varying(16) | 
- marketing_authorisation_owner | character varying(22) | 
- importer                      | character varying(22) | 
- atc                           | character varying(26) | 
- route_of_administration       | character varying(26) | 
- traffic_warning               | character varying(12) | 
- substitution                  | character varying(12) | 
- substitution_group            | character varying(18) | 
- dose_dispensing               | character varying(12) | 
- deregistration_date           | character varying(26) | 
- quarantine_date               | character varying(26) | 
-*/
diff --git a/client/widgets/dbwidget.h b/client/widgets/dbwidget.h
index ce2b596..3eb8f94 100644
--- a/client/widgets/dbwidget.h
+++ b/client/widgets/dbwidget.h
@@ -28,46 +28,32 @@
 #define __PRACRO_DBWIDGET_H__
 
 #include "widget.h"
+
 #include <QDomNode>
-#include <QComboBox>
+
 #include <QRegExp>
 #include <QSqlDatabase>
 
 #include <QEvent>
 
-class DBWidget : public QComboBox, public Widget
+class QComboBox;
+class DBWidget : public Widget
 {
 Q_OBJECT
 public:
   DBWidget(QDomNode &node, MacroWindow *macrowindow);
   ~DBWidget();
 
-  bool isValid();
-
-  QString getValue();
+  QString value();
   void setValue(QString value, QString source = "");
 
-  void disable();
-  void enable();
-  bool isDisabled();
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  void setVisibility(bool visible);
-
-  bool setKeyboardFocus();
+  void setWdgValid(bool valid);
+  bool preValid();
 
 public slots:
   void changed();
   void update_list(QString prefix);
 
-signals:
-  void wasChanged();
-
 protected:
   //  void focusInEvent(QFocusEvent *);
   
@@ -80,6 +66,8 @@ private:
   QString format;
 
   bool changedByUser;
+
+  QComboBox *combobox;
 };
 
 #endif/*__PRACRO_DBWIDGET_H__*/
diff --git a/client/widgets/frame.cc b/client/widgets/frame.cc
index d6f4fb2..e117467 100644
--- a/client/widgets/frame.cc
+++ b/client/widgets/frame.cc
@@ -25,48 +25,28 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "frame.h"
+
 #include <QVBoxLayout>
 #include <QHBoxLayout>
+#include <QFrame>
 
 #include "common.h"
 
 Frame::Frame(QDomNode &node, MacroWindow *macrowindow)
-  : QFrame(), Widget(node, macrowindow)
-{
-  setCommonAttributes(this, node);
-  setCommonLayout(this, node);
-
-  layout()->setContentsMargins(0,0,0,0);
-}
-
-void Frame::enable()
-{
-  setEnabled(true);
-}
-
-void Frame::disable()
+  : Widget(node, macrowindow)
 {
-  setEnabled(false);
-}
+  frame = new QFrame();
+  widget = frame;
 
-bool Frame::isDisabled()
-{
-  return isEnabled() == false;
-}
+  setCommonAttributes(frame, node);
+  setCommonLayout(frame, node);
 
-void Frame::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
+  frame->layout()->setContentsMargins(0,0,0,0);
 
-void Frame::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
+  addChildren(node);
 }
 
-void Frame::setVisibility(bool visible)
+Frame::~Frame()
 {
-  setVisible(visible);
+  // delete frame;
 }
diff --git a/client/widgets/frame.h b/client/widgets/frame.h
index 3f83fc4..fe57a0f 100644
--- a/client/widgets/frame.h
+++ b/client/widgets/frame.h
@@ -28,24 +28,23 @@
 #define __PRACRO_FRAME_H__
 
 #include "widget.h"
-#include <QFrame>
+
 #include <QDomNode>
 
-class Frame : public QFrame, public Widget
+class QFrame;
+class Frame : public Widget
 {
 public:
   Frame(QDomNode &node, MacroWindow *macrowindow);
+  ~Frame();
 
-  void disable();
-  void enable();
-  bool isDisabled();
+  QString value() { return ""; }
+  void setValue(QString, QString) {}
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
+  void setWdgValid(bool) {}
 
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-  void setVisibility(bool visible);
+private:
+  QFrame *frame;
 };
 
 #endif/*__PRACRO_FRAME_H__*/
diff --git a/client/widgets/groupbox.cc b/client/widgets/groupbox.cc
index e6f8b97..085a876 100644
--- a/client/widgets/groupbox.cc
+++ b/client/widgets/groupbox.cc
@@ -25,6 +25,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "groupbox.h"
+
+#include <QGroupBox>
 #include <QVBoxLayout>
 #include <QHBoxLayout>
 
@@ -33,46 +35,24 @@
 #include "common.h"
 
 GroupBox::GroupBox(QDomNode &node, MacroWindow *macrowindow)
-  : QGroupBox(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setCommonAttributes(this, node);
-  setCommonLayout(this, node);
+  groupbox = new QGroupBox();
+  widget = groupbox;
+
+  setCommonAttributes(groupbox, node);
+  setCommonLayout(groupbox, node);
 
   QDomElement elem = node.toElement();
 
   if(elem.hasAttribute("caption")) {
-    setTitle(elem.attribute("caption"));
+    groupbox->setTitle(elem.attribute("caption"));
   }
-}
-
-void GroupBox::enable()
-{
-  setEnabled(true);
-}
-
-void GroupBox::disable()
-{
-  setEnabled(false);
-}
-
-bool GroupBox::isDisabled()
-{
-  return isEnabled() == false;
-}
 
-void GroupBox::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void GroupBox::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
+  addChildren(node);
 }
 
-void GroupBox::setVisibility(bool visible)
+GroupBox::~GroupBox()
 {
-  setVisible(visible);
+  //  delete groupbox;
 }
diff --git a/client/widgets/groupbox.h b/client/widgets/groupbox.h
index ed848f7..bf12765 100644
--- a/client/widgets/groupbox.h
+++ b/client/widgets/groupbox.h
@@ -28,24 +28,23 @@
 #define __PRACRO_GROUPBOX_H__
 
 #include "widget.h"
-#include <QGroupBox>
+
 #include <QDomNode>
 
-class GroupBox : public QGroupBox, public Widget
+class QGroupBox;
+class GroupBox : public Widget
 {
 public:
   GroupBox(QDomNode &node, MacroWindow *macrowindow);
+  ~GroupBox();
 
-  void disable();
-  void enable();
-  bool isDisabled();
+  QString value() { return ""; }
+  void setValue(QString, QString) {}
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
+  void setWdgValid(bool) {}
 
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-  void setVisibility(bool visible);
+private:
+  QGroupBox *groupbox;
 };
 
 #endif/*__PRACRO_GROUPBOX_H__*/
diff --git a/client/widgets/label.cc b/client/widgets/label.cc
index fc81099..d9a5814 100644
--- a/client/widgets/label.cc
+++ b/client/widgets/label.cc
@@ -27,68 +27,46 @@
 #include "label.h"
 #include <stdio.h>
 
+#include <QLabel>
+
 #include "common.h"
 
 Label::Label(QDomNode &node, MacroWindow *macrowindow)
-  : QLabel(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  label = new QLabel();
+  widget = label;
+
   QDomElement elem = node.toElement();
 
-  setCommonAttributes(this, node);
+  setCommonAttributes(label, node);
 
-  setWordWrap(true);
+  label->setWordWrap(true);
 
   if(elem.hasAttribute("caption")) {
-    setText(elem.attribute("caption"));
+    label->setText(elem.attribute("caption"));
   } else {
-    setText(elem.attribute(""));
+    label->setText(elem.attribute(""));
   }
 
   // Check for horizontal alignment and set it up accordingly
   if(elem.hasAttribute("alignment")) {
     if(elem.attribute("alignment") == "left") {
-      setAlignment(Qt::AlignLeft);
+      label->setAlignment(Qt::AlignLeft);
     } else if (elem.attribute("alignment") == "center") {
-      setAlignment(Qt::AlignHCenter);
+      label->setAlignment(Qt::AlignHCenter);
     } else if (elem.attribute("alignment") == "right") {
-      setAlignment(Qt::AlignRight);
+      label->setAlignment(Qt::AlignRight);
     }
   } else {
-    setAlignment(Qt::AlignLeft);
+    label->setAlignment(Qt::AlignLeft);
   }
   
   // Always center vertically in the addressed space
-  setAlignment(Qt::AlignVCenter);
-}
-
-void Label::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void Label::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
-void Label::setVisibility(bool visible)
-{
-  setVisible(visible);
-}
-
-void Label::enable()
-{
-  setEnabled(true);
-}
-
-void Label::disable()
-{
-  setEnabled(false);
+  label->setAlignment(Qt::AlignVCenter);
 }
 
-bool Label::isDisabled()
+Label::~Label()
 {
-  return isEnabled() == false;
+  // delete label;
 }
diff --git a/client/widgets/label.h b/client/widgets/label.h
index ff905a7..529a79e 100644
--- a/client/widgets/label.h
+++ b/client/widgets/label.h
@@ -28,27 +28,24 @@
 #define __PRACRO_LABEL_H__
 
 #include "widget.h"
-#include <QWidget>
-#include <QLabel>
+
 #include <QDomNode>
 
-class Label : public QLabel, public Widget
+class QLabel;
+class Label : public Widget
 {
 Q_OBJECT
 public:
   Label(QDomNode &node, MacroWindow *macrowindow);
+  ~Label();
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
+  QString value() { return ""; }
+  void setValue(QString, QString) {}
 
-  void setVisibility(bool visible);
+  void setWdgValid(bool) {}
 
-  void disable();
-  void enable();
-  bool isDisabled();
+private:
+  QLabel *label;
 };
 
 #endif/*__PRACRO_LABEL_H__*/
diff --git a/client/widgets/lineedit.cc b/client/widgets/lineedit.cc
index c3a799a..918f152 100644
--- a/client/widgets/lineedit.cc
+++ b/client/widgets/lineedit.cc
@@ -27,119 +27,78 @@
 #include "lineedit.h"
 #include <stdio.h>
 
+#include <QCoreApplication>
+#include <QLineEdit>
+#include <QEvent>
+#include <QKeyEvent>
+
 #include "common.h"
 
 LineEdit::LineEdit(QDomNode &node, MacroWindow *macrowindow)
-  : QLineEdit(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setCommonAttributes(this, node);
+  lineedit = new QLineEdit();
+  widget = lineedit;
+
+  setCommonAttributes(lineedit, node);
 
   QDomElement elem = node.toElement();
 
   if(elem.hasAttribute("readonly")) {
-    if(elem.attribute("readonly") == "true" || elem.attribute("readonly") == "1") {
-      setReadOnly(true);
-    } else if(elem.attribute("readonly") == "false" || elem.attribute("readonly") == "0") {
-      setReadOnly(false);
+    if(elem.attribute("readonly") == "true" ||
+       elem.attribute("readonly") == "1") {
+      lineedit->setReadOnly(true);
+    } else if(elem.attribute("readonly") == "false" ||
+              elem.attribute("readonly") == "0") {
+      lineedit->setReadOnly(false);
     } else {
-      printf("Unknown value of readonly: %s\n", elem.attribute("readonly").toStdString().c_str());
+      printf("Unknown value of readonly: %s\n",
+             elem.attribute("readonly").toStdString().c_str());
     }
   }
   
-  connect(this, SIGNAL(textChanged(QString)), this, SLOT(changed()));
-  connect(this, SIGNAL(textEdited(QString)), this, SLOT(user_changed()));
+  connect(lineedit, SIGNAL(textChanged(QString)), this, SLOT(changed()));
+  connect(lineedit, SIGNAL(textEdited(QString)), this, SLOT(user_changed()));
 
-  installEventFilter(this); // Detect keyboard input.
+  installEventFilter(lineedit); // Detect keyboard input.
 }
 
-void LineEdit::changed()
+LineEdit::~LineEdit()
 {
-  QPalette palette;
-
-  if(isEnabled()) {
-    if(regexpValidator()) {
-      if(luaValidator()) {
-        // valid string
-        palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-      } else {
-        // invalid string
-        palette.setBrush(QPalette::Base, QBrush(QColor(200, 230, 200)));
-      }
-    } else {
-      // invalid string
-      palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
-    }
-  } else {
-    // valid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-  }
+  printf("Delete (LineEdit) %p\n", this); fflush(stdout);
+  //  delete lineedit;
+}
 
-  setPalette(palette);
+void LineEdit::changed()
+{
+  eventOnChange();
 }
 
 void LineEdit::user_changed()
 {
   emit wasChanged(); 
+  eventOnChange();
 }
 
-QString LineEdit::getValue()
+QString LineEdit::value()
 {
-  return text();
+  return lineedit->text();
 }
 
 void LineEdit::setValue(QString value, QString source)
 {
   if(isUserSource(source)) emit wasChanged();
 
-  if(text() == value) setText(value + " "); // Hack to make sure the textChanged signal is emitted.
-  setText(value);
+  if(lineedit->text() == value)
+    lineedit->setText(value + " "); // Hack to make sure the textChanged signal is emitted.
+  lineedit->setText(value);
 
   setInitialValue(value);
 }
 
-void LineEdit::enable()
-{
-  setEnabled(true);
-}
-
-void LineEdit::disable()
-{
-  setEnabled(false);
-}
-
-bool LineEdit::isDisabled()
-{
-  return isEnabled() == false;
-}
-
-void LineEdit::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void LineEdit::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
-bool LineEdit::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
-
-void LineEdit::setVisibility(bool visible)
-{
-  setVisible(visible);
-}
-
-
-#include <QCoreApplication>
 bool LineEdit::eventFilter(QObject *, QEvent *event)
 {
-  if (event->type() == QEvent::KeyPress) {
+  if(event->type() == QEvent::KeyPress) {
     QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
     if(keyEvent->key() == Qt::Key_Return ||
        keyEvent->key() == Qt::Key_Enter) {
@@ -156,3 +115,18 @@ void LineEdit::changeEvent(QEvent *event)
     changed();
   }
 }
+
+void LineEdit::setWdgValid(bool valid)
+{
+  QPalette palette;
+
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
+
+  lineedit->setPalette(palette);
+}
diff --git a/client/widgets/lineedit.h b/client/widgets/lineedit.h
index 556e52c..90fac75 100644
--- a/client/widgets/lineedit.h
+++ b/client/widgets/lineedit.h
@@ -28,44 +28,32 @@
 #define __PRACRO_LINEEDIT_H__
 
 #include "widget.h"
-#include <QLineEdit>
-#include <QWidget>
-#include <QDomNode>
 
-class LineEdit : public QLineEdit, public Widget
+class QLineEdit;
+class QEvent;
+class LineEdit : public Widget
 {
 Q_OBJECT
 public:
   LineEdit(QDomNode &node, MacroWindow *macrowindow);
+  ~LineEdit();
 
-  QString getValue();
-  void setValue(QString value, QString source = "");
+  QString value();
+  void setValue(QString value, QString source);
 
-  void enable();
-  void disable();
-  bool isDisabled();
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  bool setKeyboardFocus();
-  void setVisibility(bool visible);
+  void setWdgValid(bool valid);
 
 public slots:
   void changed();
   void user_changed();
 
-signals:
-  void wasChanged();
-
 protected:
   void changeEvent(QEvent *event);
 
 private:
   bool eventFilter(QObject *, QEvent *event);
+
+  QLineEdit *lineedit;
 };
 
 #endif/*__PRACRO_LINEEDIT_H__*/
diff --git a/client/widgets/listbox.cc b/client/widgets/listbox.cc
index bddc34f..da234ab 100644
--- a/client/widgets/listbox.cc
+++ b/client/widgets/listbox.cc
@@ -25,7 +25,9 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "listbox.h"
+
 #include <QListWidgetItem>
+#include <QListWidget>
 
 #include "common.h"
 
@@ -69,32 +71,41 @@ static QListWidgetItem *createItem(QDomElement &elem)
 }
 
 ListBox::ListBox(QDomNode &node, MacroWindow *macrowindow)
-  : QListWidget(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  listwidget = new QListWidget();
+  widget = listwidget;
+
   valueIsChangingByComputer = false;
 
-  setCommonAttributes(this, node);
+  setCommonAttributes(listwidget, node);
 
   QDomNodeList children = node.childNodes();
 
   for (int i=0; i < children.count(); i++) {
     QDomNode child = children.at(i);
     QDomElement list_elem = child.toElement();
-    addItem(createItem(list_elem));
+    listwidget->addItem(createItem(list_elem));
   }
 
-  connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(changed()));
+  connect(listwidget, SIGNAL(itemSelectionChanged()), this, SLOT(changed()));
+}
+
+ListBox::~ListBox()
+{
+  // delete listwidget;
 }
 
-bool ListBox::isValid()
+bool ListBox::preValid()
 {
-  return selectedItems().size() != 0;
+  return listwidget->selectedItems().size() != 0;
 }
 
-QString ListBox::getValue()
+QString ListBox::value()
 {
   QString value = "none";
-  if(currentRow() != -1) value = currentItem()->data(Qt::UserRole).toString();
+  if(listwidget->currentRow() != -1)
+    value = listwidget->currentItem()->data(Qt::UserRole).toString();
   return value;
 }
 
@@ -105,56 +116,33 @@ void ListBox::setValue(QString value, QString source)
   valueIsChangingByComputer = true;
   int sel = -1; // -1 is default for none selected
 
-  for(int i = 0; i < count(); i++) {
-    QListWidgetItem *listitem = item(i);
+  for(int i = 0; i < listwidget->count(); i++) {
+    QListWidgetItem *listitem = listwidget->item(i);
     if(listitem->data(Qt::UserRole).toString() == value) sel = i;
   }
 
-  setCurrentRow(sel);
+  listwidget->setCurrentRow(sel);
 
   setInitialValue(value);
   valueIsChangingByComputer = false;
 }
 
-void ListBox::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void ListBox::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
-void ListBox::setVisibility(bool visible)
-{
-  setVisible(visible);
-}
-
 void ListBox::changed()
 {
   if(!valueIsChangingByComputer) emit wasChanged();
 }
 
-bool ListBox::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
-
-void ListBox::enable()
+void ListBox::setWdgValid(bool valid)
 {
-  setEnabled(true);
-}
+  QPalette palette;
 
-void ListBox::disable()
-{
-  setEnabled(false);
-}
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
 
-bool ListBox::isDisabled()
-{
-  return isEnabled() == false;
+  listwidget->setPalette(palette);
 }
diff --git a/client/widgets/listbox.h b/client/widgets/listbox.h
index b48e258..d775655 100644
--- a/client/widgets/listbox.h
+++ b/client/widgets/listbox.h
@@ -28,41 +28,29 @@
 #define __PRACRO_LISTBOX_H__
 
 #include "widget.h"
+
 #include <QDomNode>
-#include <QListWidget>
 
-class ListBox : public QListWidget, public Widget
+class QListWidget;
+class ListBox : public Widget
 {
 Q_OBJECT
 public:
   ListBox(QDomNode &node, MacroWindow *macrowindow);
+  ~ListBox();
 
-  bool isValid();
-  QString getValue();
-  void setValue(QString value, QString source = "");
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
+  QString value();
+  void setValue(QString value, QString source);
 
-  void setVisibility(bool visible);
-
-  bool setKeyboardFocus();
-
-  void disable();
-  void enable();
-  bool isDisabled();
+  bool preValid();
+  void setWdgValid(bool valid);
 
 public slots:
   void changed();
 
-signals:
-  void wasChanged();
-
 private:
   bool valueIsChangingByComputer;
+  QListWidget *listwidget;
 };
 
 #endif/*__PRACRO_LISTBOX_H__*/
diff --git a/client/widgets/metawidget.cc b/client/widgets/metawidget.cc
index 5933212..9634c76 100644
--- a/client/widgets/metawidget.cc
+++ b/client/widgets/metawidget.cc
@@ -28,19 +28,24 @@
 
 #include <QHBoxLayout>
 #include <QVBoxLayout>
+#include <QFrame>
 
 #include "messagebox.h"
-
 #include "widgetbuilder.h"
 #include "formatparser.h"
-
+#include "macrowindow.h"
 #include "common.h"
 
 MetaWidget::MetaWidget(QDomNode &node, MacroWindow *macrowindow)
-  : QFrame(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setCommonAttributes(this, node);
-  setCommonLayout(this, node);
+  frame = new QFrame();
+  widget = frame;
+
+  setCommonAttributes(frame, node);
+  setCommonLayout(frame, node);
+
+  hideChildren = true;
   
   QDomElement elem = node.toElement();
   storechildren = elem.attribute("storechildren", "false") == "true";
@@ -49,10 +54,8 @@ MetaWidget::MetaWidget(QDomNode &node, MacroWindow *macrowindow)
   QDomNodeList children = node.childNodes();
   for (int i=0; i<children.count();i++) {
     QDomNode child = children.at(i);
-    widgets += widgetBuilder(child, this, macrowindow, false);
+    widgetBuilder(child);
   }
-  if(storechildren) macrowindow->addWidgets(widgets);
-  else macrowindow->addAuxWidgets(widgets);
 
   // Setup format string
   if(elem.hasAttribute("formatlanguage")) {
@@ -73,23 +76,30 @@ MetaWidget::MetaWidget(QDomNode &node, MacroWindow *macrowindow)
     }
   }
 
+  addChildren(node);
+
   // Connect all children wasChanged signal, to catch changes.
   QVector< Widget* >::iterator i = widgets.begin();
   while (i != widgets.end()) {
     Widget* w = *i;
-    w->connectFrom(SIGNAL(wasChanged()), this, SLOT(changed()));
+    connect(w, SIGNAL(wasChanged()), this, SLOT(changed()));
     i++;
   }
 }
 
+MetaWidget::~MetaWidget()
+{
+  // delete frame;
+}
+
 void MetaWidget::changed()
 {
   emit wasChanged();
 }
 
-QString MetaWidget::getValue()
+QString MetaWidget::value()
 {
-  return format_parser(format, widgets, formatlanguage);
+  return format_parser(format, this, formatlanguage);
 }
 
 void MetaWidget::setValue(QString, QString)
@@ -97,52 +107,25 @@ void MetaWidget::setValue(QString, QString)
   // Nothing reasonable we can do here.
 }
 
-void MetaWidget::enable()
-{
-  setEnabled(true);
-}
-
-void MetaWidget::disable()
-{
-  setEnabled(false);
-}
-
-bool MetaWidget::isDisabled()
-{
-  return isEnabled() == false;
-}
-
-bool MetaWidget::isValid()
+bool MetaWidget::preValid()
 {
   // If children are stored they will validate themselves.
   if(!storechildren) {
     QVector< Widget* >::iterator i = widgets.begin();
     while (i != widgets.end()) {
       Widget* w = *i;
-      if(w->isValid() == false) {
+      if(w->enabled() && !w->local() && !w->valid()) {
         MessageBox::critical(NULL, "Fejl",
-                              "Et af inputfelterne (" + w->name()
-                              + ") er ikke udfyldt korrekt, pr�v igen.\n"
-                              , MessageBox::Ok);
+                             "Et af inputfelterne (" + w->name()
+                             + ") er ikke udfyldt korrekt, pr�v igen.\n",
+                             MessageBox::Ok);
         return false;
       }
       i++;
     }
   }
 
-  return regexpValidator() && luaValidator();
-}
-
-void MetaWidget::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void MetaWidget::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
+  return true;
 }
 
 bool MetaWidget::setKeyboardFocus()
@@ -169,7 +152,17 @@ void MetaWidget::reset()
   }
 }
 
-void MetaWidget::setVisibility(bool visible)
+void MetaWidget::setWdgValid(bool valid)
 {
-  setVisible(visible);
+  QPalette palette;
+
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
+
+  frame->setPalette(palette);
 }
diff --git a/client/widgets/metawidget.h b/client/widgets/metawidget.h
index 022197a..dd32adf 100644
--- a/client/widgets/metawidget.h
+++ b/client/widgets/metawidget.h
@@ -28,50 +28,41 @@
 #define __PRACRO_METAWIDGET_H__
 
 #include "widget.h"
-#include <QFrame>
+
 #include <QDomNode>
 
 #include <QListWidget>
 #include <QVector>
 
-class MetaWidget : public QFrame, public Widget
+class QFrame;
+class MetaWidget : public Widget
 {
 Q_OBJECT
 public:
   MetaWidget(QDomNode &node, MacroWindow *macrowindow);
+  ~MetaWidget();
 
-  QString getValue();
-  void setValue(QString value, QString source = "");
-
-  bool isValid();
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
+  QString value();
+  void setValue(QString value, QString source);
 
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
+  bool preValid();
+  void setWdgValid(bool valid);
 
   bool setKeyboardFocus();
-  void setVisibility(bool visible);
 
   void reset();
 
-  void disable();
-  void enable();
-  bool isDisabled();
-
 public slots:
   void changed();
 
-signals:
-  void wasChanged();
-
 private:
   QListWidget *list;
   QVector< Widget* > widgets;
   QString format;
   QString formatlanguage;
   bool storechildren;
+
+  QFrame *frame;
 };
 
 #endif/*__PRACRO_METAWIDGET_H__*/
diff --git a/client/widgets/multilist.cc b/client/widgets/multilist.cc
index 01a2d77..2c4438f 100644
--- a/client/widgets/multilist.cc
+++ b/client/widgets/multilist.cc
@@ -30,44 +30,52 @@
 #include <QVBoxLayout>
 #include <QGridLayout>
 #include <QPushButton>
+#include <QFrame>
+#include <QLabel>
+#include <QEvent>
+#include <QKeyEvent>
 
 #include "messagebox.h"
-
 #include "widgetbuilder.h"
-
 #include "common.h"
+#include "macrowindow.h"
 
 MultiList::MultiList(QDomNode &node, MacroWindow *macrowindow)
-  : QFrame(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
+  frame = new QFrame();
+  widget = frame;
+
+  hideChildren = true;
+
   innerwidget_has_changes = false;
 
-  setCommonAttributes(this, node);
+  setCommonAttributes(frame, node);
 
   QGridLayout *layout = new QGridLayout();
-  setLayout(layout);
+  frame->setLayout(layout);
 
-  list = new QListWidget(this);
+  list = new QListWidget(frame);
   layout->addWidget(list, 0, 0, 1, 2, Qt::AlignTop);
   list->installEventFilter(this);
 
-  QPushButton *add = new QPushButton(this);
+  QPushButton *add = new QPushButton(frame);
   connect(add, SIGNAL(clicked()), this, SLOT(add()));
   add->setText(tr("Add to list"));
   add->setIcon(QIcon(QPixmap(":icons/add.png")));
   layout->addWidget(add, 1, 0, 1, 1, Qt::AlignTop);
 
-  QPushButton *rem = new QPushButton(this);
+  QPushButton *rem = new QPushButton(frame);
   connect(rem, SIGNAL(clicked()), this, SLOT(remove()));
   rem->setText(tr("Remove from list"));
   rem->setIcon(QIcon(QPixmap(":icons/del.png")));
   layout->addWidget(rem, 1, 1, 1, 1, Qt::AlignTop);
 
-  QLabel *arrows = new QLabel();
+  QLabel *arrows = new QLabel(frame);
   arrows->setPixmap(QPixmap(":icons/arrows.png"));
   layout->addWidget(arrows, 2, 0, 1, 2, Qt::AlignHCenter);
   
-  QWidget *inputbox = new QWidget(this);
+  QWidget *inputbox = new QWidget(frame);
   inputbox->setContentsMargins(0,0,0,0);
   layout->addWidget(inputbox, 3, 0, 1, 2, Qt::AlignTop);
 
@@ -87,29 +95,16 @@ MultiList::MultiList(QDomNode &node, MacroWindow *macrowindow)
 
   inputbox->layout()->setContentsMargins(0,0,0,0);
   
-  QDomNodeList children = node.childNodes();
-
-  QVector< Widget* > widgets;
-  for (int i=0; i<children.count();i++) {
-    QDomNode child = children.at(i);
-    widgets += widgetBuilder(child, inputbox, macrowindow, false);
-  }
-  macrowindow->addAuxWidgets(widgets);
+  addChildren(node);
 
   innerwidget = NULL;
   if(elem.hasAttribute("innerwidget")) {
-    QString iwname = elem.attribute("innerwidget");
-    QVector< Widget* >::iterator ws = widgets.begin();
-    while(ws != widgets.end()) {
-      if((*ws)->name() == iwname) {
-        innerwidget = *ws;
-        innerwidget->connectFrom(SIGNAL(wasChanged()), this, SLOT(changed()));
-      }
-      ws++;
-    }
-    if(innerwidget == NULL) {
+    innerwidget = findWidget(elem.attribute("innerwidget"), true);
+    if(innerwidget) {
+      connect(innerwidget, SIGNAL(wasChanged()), this, SLOT(changed()));
+    } else {
       printf("ERROR: Inner Widget %s not found (in multilist)!\n",
-             iwname.toStdString().c_str());
+             elem.attribute("innerwidget").toStdString().c_str());
     }
   } else {
     printf("ERROR: Missing 'innerwidget' attribute on multilist!\n");
@@ -118,6 +113,11 @@ MultiList::MultiList(QDomNode &node, MacroWindow *macrowindow)
   layout->setContentsMargins(0,0,0,0);
 }
 
+MultiList::~MultiList()
+{
+  // delete frame;
+}
+
 void MultiList::changed()
 {
   innerwidget_has_changes = true;
@@ -125,7 +125,7 @@ void MultiList::changed()
 }
 
 
-bool MultiList::isValid()
+bool MultiList::preValid()
 {
   if(innerwidget_has_changes) {
     switch(MessageBox::warning(NULL,
@@ -134,7 +134,7 @@ bool MultiList::isValid()
                                "�nsker du at tilf�je �ndringen til listen inden du gemmer makroen?",
                                MessageBox::Save | MessageBox::Close | MessageBox::Cancel)) {
     case MessageBox::Save:
-      if(innerwidget && innerwidget->isValid()) {
+      if(innerwidget && innerwidget->valid()) {
         add();
       } else {
         return false;
@@ -150,10 +150,10 @@ bool MultiList::isValid()
     }
   }
 
-  return regexpValidator() && luaValidator();
+  return true;
 }
 
-QString MultiList::getValue()
+QString MultiList::value()
 {
   QString values;
 
@@ -186,7 +186,7 @@ void MultiList::setValue(QString values, QString source)
 
   setInitialValue(values);
 
-  luaValidator();
+  eventOnChange();
 }
 
 void MultiList::remove()
@@ -196,50 +196,23 @@ void MultiList::remove()
   if(item && item->isSelected()) {
     delete item;
     emit wasChanged();
-    luaValidator();
+    eventOnChange();
   }
 }
 
 void MultiList::add()
 {
-  if(innerwidget && innerwidget->isValid()) {
-    list->addItem(innerwidget->getValue());
+  if(innerwidget && innerwidget->valid()) {
+    list->addItem(innerwidget->value());
     emit wasChanged();
 
     innerwidget->reset();
     innerwidget_has_changes = false;
 
-    luaValidator();
+    eventOnChange();
   }
 }
 
-void MultiList::enable()
-{
-  setEnabled(true);
-}
-
-void MultiList::disable()
-{
-  setEnabled(false);
-}
-
-bool MultiList::isDisabled()
-{
-  return isEnabled() == false;
-}
-
-void MultiList::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void MultiList::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
 bool MultiList::setKeyboardFocus()
 {
   if(innerwidget) return innerwidget->setKeyboardFocus();
@@ -255,7 +228,17 @@ bool MultiList::eventFilter(QObject *obj, QEvent *event)
   return QObject::eventFilter(obj, event);
 }
 
-void MultiList::setVisibility(bool visible)
+void MultiList::setWdgValid(bool valid)
 {
-  setVisible(visible);
+  QPalette palette;
+
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
+
+  frame->setPalette(palette);
 }
diff --git a/client/widgets/multilist.h b/client/widgets/multilist.h
index 3b0f51e..8e806fa 100644
--- a/client/widgets/multilist.h
+++ b/client/widgets/multilist.h
@@ -28,44 +28,33 @@
 #define __PRACRO_MULTILIST_H__
 
 #include "widget.h"
-#include <QFrame>
+
 #include <QDomNode>
 
 #include <QListWidget>
 #include <QVector>
 
-class MultiList : public QFrame, public Widget
+class QFrame;
+class MultiList : public Widget
 {
 Q_OBJECT
 public:
   MultiList(QDomNode &node, MacroWindow *macrowindow);
+  ~MultiList();
 
-  QString getValue();
+  QString value();
   void setValue(QString value, QString source = "");
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
+  bool preValid();
+  void setWdgValid(bool valid);
 
   bool setKeyboardFocus();
-  void setVisibility(bool visible);
-
-  void disable();
-  void enable();
-  bool isDisabled();
-
-  bool isValid();
 
 public slots:
   void changed();
   void remove();
   void add();
 
-signals:
-  void wasChanged();
-
 protected:
   bool eventFilter(QObject *obj, QEvent *event);
 
@@ -74,6 +63,8 @@ private:
   Widget *innerwidget;
   QString format;
   bool innerwidget_has_changes;
+
+  QFrame *frame;
 };
 
 #endif/*__PRACRO_MULTILIST_H__*/
diff --git a/client/widgets/radiobutton.cc b/client/widgets/radiobutton.cc
index 6646f59..a315577 100644
--- a/client/widgets/radiobutton.cc
+++ b/client/widgets/radiobutton.cc
@@ -25,6 +25,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "radiobutton.h"
+
 #include <QRadioButton>
 
 #include "common.h"
diff --git a/client/widgets/radiobuttons.cc b/client/widgets/radiobuttons.cc
index e4555ff..7f1bda7 100644
--- a/client/widgets/radiobuttons.cc
+++ b/client/widgets/radiobuttons.cc
@@ -25,18 +25,23 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "radiobuttons.h"
-#include "radiobutton.h"
-#include <QRadioButton>
+
+#include <QEvent>
 #include <QHBoxLayout>
 #include <QVBoxLayout>
+#include <QFrame>
 
 #include "common.h"
+#include "radiobutton.h"
 
 RadioButtons::RadioButtons(QDomNode &node, MacroWindow *macrowindow)
-  : QFrame(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setCommonAttributes(this, node);
-  setCommonLayout(this, node);
+  frame = new QFrame();
+  widget = frame;
+
+  setCommonAttributes(frame, node);
+  setCommonLayout(frame, node);
 
   QDomNodeList children = node.childNodes();
 
@@ -46,17 +51,22 @@ RadioButtons::RadioButtons(QDomNode &node, MacroWindow *macrowindow)
     RadioButton *radiobutton = new RadioButton(child);
 
     // Create radiobutton from child, insert in this
-    layout()->addWidget(radiobutton);
+    frame->layout()->addWidget(radiobutton);
 
     connect(radiobutton, SIGNAL(clicked()), this, SLOT(childChanged()));
 
     radiobutton_list.push_back(radiobutton);
   }
   
-  layout()->setContentsMargins(0,0,0,0);
+  frame->layout()->setContentsMargins(0,0,0,0);
 }
 
-bool RadioButtons::setBGColor(bool valid)
+RadioButtons::~RadioButtons()
+{
+  // delete frame;
+}
+
+void RadioButtons::setWdgValid(bool valid)
 {
   QPalette palette;
 
@@ -72,35 +82,32 @@ bool RadioButtons::setBGColor(bool valid)
     RadioButton *widget = *i;
     widget->setPalette(palette);
   }
-
-  return valid;
 }
 
-bool RadioButtons::isValid()
+bool RadioButtons::preValid()
 {
-  if(!regexpValidator()) return setBGColor(false);
-  if(!luaValidator()) return setBGColor(false);
-
   QVector< RadioButton* >::iterator i;
   for (i = radiobutton_list.begin(); i != radiobutton_list.end(); ++i) {
-    RadioButton *widget = *i;
-    if(widget->isChecked()) {
-      return setBGColor(true);
+    RadioButton *rbtn = *i;
+    if(rbtn->isChecked()) {
+      return true;
     }
   }
-
-  return setBGColor(false);
+  return false;
 }
 
-QString RadioButtons::getValue()
+QString RadioButtons::value()
 {
   QVector< RadioButton* >::iterator i;
   QString value;
   for (i = radiobutton_list.begin(); i != radiobutton_list.end(); ++i) {
-    RadioButton *widget = *i;
-    if(widget->isChecked()) {
-      printf("Radiobutton returned: %s\n", widget->getValue().toStdString().c_str());
-      value = widget->getValue();
+    RadioButton *rbtn = *i;
+    if(rbtn->isChecked()) {
+      /*
+      printf("Radiobutton returned: %s\n",
+             rbtn->getValue().toStdString().c_str());
+      */
+      value = rbtn->getValue();
     }
   }
   return value;
@@ -112,29 +119,15 @@ void RadioButtons::setValue(QString value, QString source)
 
   QVector< RadioButton* >::iterator i;
   for (i = radiobutton_list.begin(); i != radiobutton_list.end(); ++i) {
-    RadioButton *widget = *i;
-    if(value == widget->getValue()) {
-      widget->setChecked(true);
+    RadioButton *rbtn = *i;
+    if(value == rbtn->getValue()) {
+      rbtn->setChecked(true);
     } else {
-      widget->setChecked(false);
+      rbtn->setChecked(false);
     }
   }
 
   setInitialValue(value);
-
-  isValid();
-}
-
-void RadioButtons::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void RadioButtons::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
 }
 
 bool RadioButtons::setKeyboardFocus()
@@ -157,36 +150,15 @@ bool RadioButtons::setKeyboardFocus()
   return false;
 }
 
-void RadioButtons::setVisibility(bool visible)
-{
-  setVisible(visible);
-}
-
 void RadioButtons::childChanged()
 {
-  isValid();
-
+  eventOnChange();
   emit wasChanged();
 }
 
-void RadioButtons::enable()
-{
-  setEnabled(true);
-}
-
-void RadioButtons::disable()
-{
-  setEnabled(false);
-}
-
-bool RadioButtons::isDisabled()
-{
-  return isEnabled() == false;
-}
-
 void RadioButtons::changeEvent(QEvent *event)
 {
   if(event->type() == QEvent::EnabledChange) {
-    setBGColor(isValid() || !isEnabled());
+    //    setWdgValid(valid() || !frame->isEnabled());
   }
 }
diff --git a/client/widgets/radiobuttons.h b/client/widgets/radiobuttons.h
index 9b165c9..b83f7a9 100644
--- a/client/widgets/radiobuttons.h
+++ b/client/widgets/radiobuttons.h
@@ -27,49 +27,39 @@
 #ifndef __PRACRO_RADIOBUTTONS_H__
 #define __PRACRO_RADIOBUTTONS_H__
 
-#include "widget.h"
-#include "widgets/radiobutton.h"
-#include <QFrame>
 #include <QDomNode>
 #include <QVector>
-#include <QRadioButton>
 
-class RadioButtons : public QFrame, public Widget
+#include "widget.h"
+
+class QFrame;
+class QEvent;
+class RadioButton;
+class RadioButtons : public Widget
 {
 Q_OBJECT
 public:
   RadioButtons(QDomNode &node, MacroWindow *macrowindow);
+  ~RadioButtons();
 
-  bool isValid();
-  QString getValue();
-  void setValue(QString value, QString source = "");
+  QString value();
+  void setValue(QString value, QString source);
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
+  bool preValid();
+  void setWdgValid(bool valid);
 
   bool setKeyboardFocus();
-  void setVisibility(bool visible);
-
-  void disable();
-  void enable();
-  bool isDisabled();
 
 public slots:
   void childChanged();
 
-signals:
-  void wasChanged();
-
 protected:
   void changeEvent(QEvent *event);
 
 private:
   QVector < RadioButton* > radiobutton_list;
 
-  bool setBGColor(bool valid);
+  QFrame *frame;
 };
 
 #endif/*__PRACRO_RADIOBUTTONS_H__*/
diff --git a/client/widgets/textedit.cc b/client/widgets/textedit.cc
index 83ef62a..0b7ddde 100644
--- a/client/widgets/textedit.cc
+++ b/client/widgets/textedit.cc
@@ -25,62 +25,59 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include "textedit.h"
-#include <QPalette>
 
+#include <QPalette>
+#include <QTextEdit>
 #include <stdio.h>
 
 #include "common.h"
 
 TextEdit::TextEdit(QDomNode &node, MacroWindow *macrowindow)
-  : QTextEdit(), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setCommonAttributes(this, node);
+  textedit = new QTextEdit();
+  widget = textedit;
+
+  setCommonAttributes(textedit, node);
 
   QDomElement elem = node.toElement();
 
   if(elem.hasAttribute("readonly")) {
-    if(elem.attribute("readonly") == "true" || elem.attribute("readonly") == "1") {
-      setReadOnly(true);
-    } else if(elem.attribute("readonly") == "false" || elem.attribute("readonly") == "0") {
-      setReadOnly(false);
+    if(elem.attribute("readonly") == "true" ||
+       elem.attribute("readonly") == "1") {
+      textedit->setReadOnly(true);
+    } else if(elem.attribute("readonly") == "false" ||
+              elem.attribute("readonly") == "0") {
+      textedit->setReadOnly(false);
     } else {
-      printf("Unknown value of readonly: %s\n", elem.attribute("readonly").toStdString().c_str());
+      printf("Unknown value of readonly: %s\n",
+             elem.attribute("readonly").toStdString().c_str());
     }
   }
 
-  connect(this, SIGNAL(textChanged()), this, SLOT(changed()));
-  installEventFilter(this); // Detect keyboard input.
+  connect(textedit, SIGNAL(textChanged()), this, SLOT(changed()));
+  textedit->installEventFilter(this); // Detect keyboard input.
 }
 
-void TextEdit::changed()
+TextEdit::~TextEdit()
 {
-  QPalette palette;
-
-  if(regexpValidator()) {
-    if(luaValidator()) {
-      // valid string
-      palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
-    } else {
-      // invalid string
-      palette.setBrush(QPalette::Base, QBrush(QColor(200, 230, 200)));
-    }
-  } else {
-    // invalid string
-    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
-  }
+  //delete textedit;
+}
 
-  setPalette(palette);
+void TextEdit::changed()
+{
+  eventOnChange();
 }
 
-QString TextEdit::getValue()
+QString TextEdit::value()
 {
-  return QTextEdit::toPlainText();
+  return textedit->toPlainText();
 }
 
 void TextEdit::setValue(QString value, QString source)
 {
   if(isUserSource(source)) emit wasChanged();
-  setText(value);
+  textedit->setText(value);
   setInitialValue(value);
 }
 
@@ -93,40 +90,17 @@ bool TextEdit::eventFilter(QObject *, QEvent *event)
   return false;
 }
 
-void TextEdit::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void TextEdit::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
+void TextEdit::setWdgValid(bool valid)
 {
-  connect(sender, signal, this, method);
-}
-
-bool TextEdit::setKeyboardFocus()
-{
-  setFocus();
-  return true;
-}
-
-void TextEdit::setVisibility(bool visible)
-{
-  setVisible(visible);
-}
-
-void TextEdit::enable()
-{
-  setEnabled(true);
-}
+  QPalette palette;
 
-void TextEdit::disable()
-{
-  setEnabled(false);
-}
+  if(valid) {
+    // valid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255)));
+  } else {
+    // invalid string
+    palette.setBrush(QPalette::Base, QBrush(QColor(230, 200, 200)));
+  }
 
-bool TextEdit::isDisabled()
-{
-  return isEnabled() == false;
+  textedit->setPalette(palette);
 }
diff --git a/client/widgets/textedit.h b/client/widgets/textedit.h
index f3e1989..86d6e42 100644
--- a/client/widgets/textedit.h
+++ b/client/widgets/textedit.h
@@ -28,36 +28,22 @@
 #define __PRACRO_TEXTEDIT_H__
 
 #include "widget.h"
-#include <QTextEdit>
-#include <QWidget>
+
 #include <QDomNode>
 #include <QKeyEvent>
 
-class TextEdit : public QTextEdit, public Widget
+class QTextEdit;
+class TextEdit : public Widget
 {
 Q_OBJECT
 public:
   TextEdit(QDomNode &node, MacroWindow *macrowindow);
+  ~TextEdit();
 
-  QString getValue();
-  void setValue(QString value, QString source = "");
-
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  bool setKeyboardFocus();
+  QString value();
+  void setValue(QString value, QString source);
 
-  void setVisibility(bool visible);
-
-  void disable();
-  void enable();
-  bool isDisabled();
-
-signals:
-  void wasChanged();
+  void setWdgValid(bool valid);
 
 public slots:
   void changed();
@@ -65,6 +51,9 @@ public slots:
 
 protected:
   bool eventFilter(QObject *obj, QEvent *event);
+
+private:
+  QTextEdit *textedit;
 };
 
 #endif/*__PRACRO_TEXTEDIT_H__*/
diff --git a/client/widgets/widget.cc b/client/widgets/widget.cc
index c17633f..af03843 100644
--- a/client/widgets/widget.cc
+++ b/client/widgets/widget.cc
@@ -26,43 +26,77 @@
  */
 #include "widget.h"
 
+#include "macrowindow.h"
+#include "lua.h"
+
+#include "../widgets.h"
+#include <QLayout>
+#include <QObject>
+
 Widget::Widget(QDomNode &node, MacroWindow *macrowindow)
 {
+  widget = NULL;
+
   QDomElement elem = node.toElement();
 
   this->macrowindow = macrowindow;
+  this->lua = macrowindow->lua;
 
   widget_type = elem.tagName();
 
   if(elem.hasAttribute("name")) {
     widget_name = elem.attribute("name");
-  } else {
-    if(elem.tagName() != "frame" && elem.tagName() != "label"
-       && elem.tagName() != "button" && elem.tagName() != "widgets")
-      printf("XML ERROR!! Unnamed widget of type: %s\n", 
-             elem.tagName().toStdString().c_str());
   }
 
+  widget_local = 
+    elem.hasAttribute("local") && elem.attribute("local") == "true";
+
   if(elem.hasAttribute("prefilled")) {
     prefilled = elem.attribute("prefilled");
   }
 
-  if(elem.hasAttribute("script")) {
-    luaprogram = elem.attribute("script");
-    hasluaprogram = true;
-  } else {
-    hasluaprogram = false;
+  has_initial_value = false;
+  initial_value = "";
+
+  if((hasOnChangeEvent = elem.hasAttribute("onChange"))) {
+    onChangeEventScript = elem.attribute("onChange");
   }
-  
-  if(elem.hasAttribute("regexp")) {
-    rx = QRegExp(elem.attribute("regexp"));
-    hasregexpvalidator = true;
-  } else {
-    hasregexpvalidator = false;
+
+  is_valid = true;
+
+  printf("Create Widget '%s' of type '%s'\n",
+         name().toStdString().c_str(),
+         type().toStdString().c_str());
+}
+
+Widget::~Widget()
+{
+  printf("Delete Widget '%s' of type '%s'\n",
+         name().toStdString().c_str(),
+         type().toStdString().c_str());
+
+  /* // This is done by Qt
+  if(widget) {
+    delete widget;
+    widget = NULL;
+  }
+  */
+  QVector< Widget* >::iterator i = children.begin();
+  while(i != children.end()) {
+    if(*i) delete *i;
+    i++;
   }
 
-  has_initial_value = false;
-  initial_value = "";
+  children.clear();
+}
+
+void Widget::addChildren(QDomNode &node)
+{
+  QDomNodeList children = node.childNodes();
+  for (int i=0; i<children.count();i++) {
+    QDomNode child = children.at(i);
+    widgetBuilder(child);
+  }
 }
 
 QString Widget::name()
@@ -75,29 +109,29 @@ QString Widget::type()
   return widget_type;
 }
 
-void Widget::setValue(QString, QString)
+bool Widget::local()
 {
+  return widget_local;
 }
 
-bool Widget::isValid()
+bool Widget::valid()
 {
-  return regexpValidator() && luaValidator();
-}
+  if(preValid() == false) return false;
+  if(is_valid == false) return false;
+  
+  QVector< Widget* >::iterator i = children.begin();
+  while(i != children.end()) {
+    if((*i)->valid() == false) return false;
+    i++;
+  }
 
-bool Widget::regexpValidator()
-{
-  return !hasregexpvalidator || rx.exactMatch(getValue());
+  return true;
 }
 
-bool Widget::luaValidator()
-{ 
-  if(!hasluaprogram) return true;
-
-  QString program = "";
-
-  program += luaprogram;
-
-  return macrowindow->lua->runValidator(program, this, name(), getValue());
+void Widget::setValid(bool valid)
+{
+  is_valid = valid;
+  setWdgValid(valid);
 }
 
 void Widget::setInitialValue(QString value)
@@ -113,8 +147,192 @@ bool Widget::hasInitialValue()
   return has_initial_value;
 }
 
-
 void Widget::reset()
 {
-  setValue(initial_value);
+  setValue(initial_value, "");
+}
+
+void Widget::eventOnChange()
+{
+  if(enabled() && hasOnChangeEvent)
+    lua->runScript(onChangeEventScript, this, "onChange");
+}
+
+void Widget::setEnabled(bool enabled)
+{
+  widget->setEnabled(enabled);
+}
+
+bool Widget::enabled()
+{
+  return widget->isEnabled();
+}
+
+void Widget::setVisible(bool visible)
+{
+  widget->setVisible(visible);
+}
+
+bool Widget::visible()
+{
+  return widget->isVisible();
+}
+
+bool Widget::setKeyboardFocus()
+{
+  widget->setFocus();
+  return true;
+}
+
+Widget *Widget::findWidget(QString n, bool deep)
+{
+  printf("Find Widget %p\n", this); fflush(stdout);
+
+  if(n == name()) return this;
+
+  if(hideChildren && deep == false) return NULL;
+
+  QVector< Widget* >::iterator i = children.begin();
+  while(i != children.end()) {
+    Widget *w = (*i)->findWidget(n, deep);
+    if(w) return w;
+    i++;
+  }
+
+  return NULL;
+}
+
+QVector< Widget* > Widget::widgetList(bool deep)
+{
+  printf("Widget List %p\n", this); fflush(stdout);
+
+  QVector< Widget* > lst = children;
+
+  if(hideChildren && deep == false) return lst;
+
+  QVector< Widget* >::iterator i = children.begin();
+  while(i != children.end()) {
+    lst += (*i)->widgetList(deep);
+    i++;
+  }
+
+  return lst;
+}
+
+void Widget::childWasChanged()
+{
+  emit wasChanged();
+}
+
+void Widget::addChild(Widget *widget)
+{
+  if(widget == NULL) {
+    printf("Trying to add NULL child to '%s'\n", name().toStdString().c_str());
+    return;
+  }
+  children.push_back(widget);
+  connect(widget, SIGNAL(wasChanged()), this, SLOT(childWasChanged()));
+}
+
+void Widget::widgetBuilder(QDomNode &xml_node)
+{
+  QDomElement xml_elem = xml_node.toElement();
+
+
+  // TODO: Why do we do this??
+  if(xml_elem.hasAttribute("prefilled") &&
+     xml_elem.attribute("prefilled") != "pracro") {
+    macrowindow->macroChanged();
+  }
+
+  Widget *widget = NULL;
+  if(xml_elem.tagName() == "spacer") {
+
+    if(qwidget() && qwidget()->layout()) { 
+      ((QBoxLayout*)qwidget()->layout())->addStretch();
+    }
+    return; // This is not a real widget.
+  } else if(xml_elem.tagName() == "frame") {
+
+    if(xml_elem.hasAttribute("caption")) {
+      GroupBox *frame = new GroupBox(xml_elem, macrowindow);
+      widget = frame;
+    } else {
+      Frame *frame = new Frame(xml_elem, macrowindow);
+      widget = frame;
+    }
+
+  } else if(xml_elem.tagName() == "label") {
+
+    Label *label = new Label(xml_elem, macrowindow);
+    widget = label;
+
+  } else if(xml_elem.tagName() == "lineedit") {
+
+    LineEdit *lineedit = new LineEdit(xml_elem, macrowindow);
+    widget = lineedit;
+
+  } else if(xml_elem.tagName() == "datetime") {
+
+    DateTime *datetime = new DateTime(xml_elem, macrowindow);
+    widget = datetime;
+
+  } else if(xml_elem.tagName() == "button") {
+
+    Button *button = new Button(xml_elem, macrowindow);
+    widget = button;
+
+  } else if(xml_elem.tagName() == "textedit") {
+
+    TextEdit *textedit = new TextEdit(xml_elem, macrowindow);
+    widget = textedit;
+
+  } else if(xml_elem.tagName() == "checkbox") {
+
+    CheckBox *checkbox = new CheckBox(xml_elem, macrowindow);
+    widget = checkbox;
+
+  } else if(xml_elem.tagName() == "radiobuttons") {
+
+    RadioButtons *radiobuttons = new RadioButtons(xml_elem, macrowindow);
+    widget = radiobuttons;
+
+  } else if(xml_elem.tagName() == "combobox") {
+
+    ComboBox *combobox = new ComboBox(xml_elem, macrowindow);
+    widget = combobox;
+
+  } else if(xml_elem.tagName() == "dbwidget") {
+
+    DBWidget *dbwidget = new DBWidget(xml_elem, macrowindow);
+    widget = dbwidget;
+
+  } else if(xml_elem.tagName() == "listbox") {
+
+    ListBox *listbox = new ListBox(xml_elem, macrowindow);
+    widget = listbox;
+
+  } else if(xml_elem.tagName() == "multilist") {
+
+    MultiList *multilist = new MultiList(xml_elem, macrowindow);
+    widget = multilist;
+
+  } else if(xml_elem.tagName() == "altcombobox") {
+
+    AltComboBox *altcombobox = new AltComboBox(xml_elem, macrowindow);
+    widget = altcombobox;
+
+  } else if(xml_elem.tagName() == "metawidget") {
+
+    MetaWidget *metawidget = new MetaWidget(xml_elem, macrowindow);
+    widget = metawidget;
+
+  }
+
+  addChild(widget);
+
+  if(qwidget() && qwidget()->layout())
+    qwidget()->layout()->addWidget(widget->qwidget());
+
+  if(widget && widget->qwidget()) widget->qwidget()->show();
 }
diff --git a/client/widgets/widget.h b/client/widgets/widget.h
index 732dce9..9e493d0 100644
--- a/client/widgets/widget.h
+++ b/client/widgets/widget.h
@@ -30,64 +30,88 @@
 #include <QString>
 #include <QDomNode>
 #include <QRegExp>
+#include <QObject>
+#include <QVector>
 
-#include "macrowindow.h"
 #include "lua.h"
 
-class Widget {
+class MacroWindow;
+class LUA;
+class Widget;
+class Widget : public QObject {
+Q_OBJECT
 public:
   Widget(QDomNode &node, MacroWindow *macrowindow);
-  virtual ~Widget(){}
+  virtual ~Widget();
 
-  virtual QString getValue() { return ""; }
-  virtual void setValue(QString value, QString source = "");
+  QString name();
+  QString type();
+  bool local();
 
-  virtual bool isValid();
-  virtual void setValid(bool valid) { valid = valid; }
+  virtual QString value() = 0;
+  virtual void setValue(QString value, QString source) = 0;
 
-  virtual void disable() {}
-  virtual void enable() {}
-  virtual bool isDisabled() { return false; }
+  bool valid();
+  void setValid(bool valid);
 
-  virtual void setVisibility(bool) {}
-  virtual bool getVisibility() { return true; }
-  
-  QString name();
-  QString type();
+  // Implement in subclasses to contribute to the validation.
+  virtual bool preValid() { return true; }
 
-  /**
-   * Connect some signal from this object to some slot in some other object.
-   */
-  virtual void connectFrom(const char *, const QObject *, const char *) {}
+  // Implement in subclasses to change widget according to validation status.
+  virtual void setWdgValid(bool valid) = 0;
 
-  /**
-   * Connect some signal from some other object to some slot in this object.
-   */
-  virtual void connectTo(const QObject *, const char *, const char *) {}
+  virtual void setEnabled(bool enabled);
+  virtual bool enabled();
+
+  virtual void setVisible(bool visible);
+  virtual bool visible();
 
-  virtual bool setKeyboardFocus() { return false; }
+  virtual bool setKeyboardFocus();
 
   void setInitialValue(QString value);
   bool hasInitialValue();
   virtual void reset();
 
+  QWidget *qwidget() { return widget; }
+  
+  // Set deep to true to find widgets inside altcombobox, multilist and
+  // metawidgets.
+  Widget *findWidget(QString name, bool deep = false);
+  QVector< Widget* > widgetList(bool deep = false);
+  void addChild(Widget *widget);
+
+signals:
+  void wasChanged();
+
+public slots:
+  void childWasChanged();
+
 protected:
-  QString widget_name;
-  QString widget_type;
+  /*
+   * LUA scripting events:
+   */
+  void eventOnChange();
+
+  QWidget *widget;
+  bool hideChildren;
 
-  bool luaValidator();
-  bool regexpValidator();
+  void widgetBuilder(QDomNode &xml_node);
+  void addChildren(QDomNode &xml_node);
 
 private:
-  QRegExp rx;
+  QVector< Widget* > children;
 
-  bool hasregexpvalidator;
-  bool hasluaprogram;
+  bool is_valid;
+  QString widget_name;
+  QString widget_type;
+  bool widget_local;
 
-  QString luaprogram;
   LUA *lua;
   MacroWindow *macrowindow;
-  
+
+  bool hasOnChangeEvent;
+  QString onChangeEventScript;
+
   QString initial_value;
   bool has_initial_value;
 
diff --git a/client/widgets/window.cc b/client/widgets/window.cc
index ea27321..f51cfd9 100644
--- a/client/widgets/window.cc
+++ b/client/widgets/window.cc
@@ -27,54 +27,39 @@
 #include "window.h"
 #include "common.h"
 
+#include <QWidget>
 #include <QIcon>
 
 Window::Window(QDomNode &node, MacroWindow *macrowindow)
-  : QWidget(NULL), Widget(node, macrowindow)
+  : Widget(node, macrowindow)
 {
-  setWindowFlags(Qt::WindowContextHelpButtonHint | Qt::WindowSystemMenuHint);
+  widget = new QWidget(NULL);
 
-  setWindowIcon(QIcon(":/icons/icon.png"));
+  widget->setWindowFlags(Qt::WindowContextHelpButtonHint |
+                         Qt::WindowSystemMenuHint);
 
-  setCommonAttributes(this, node);
-  setCommonLayout(this, node);
+  widget->setWindowIcon(QIcon(":/icons/icon.png"));
+
+  setCommonAttributes(widget, node);
+  setCommonLayout(widget, node);
 
   QDomElement elem = node.toElement();
 
   if(elem.hasAttribute("fixed")) {
     if(elem.attribute("fixed") == "true") {
-      setFixedSize(width(), height());
+      widget->setFixedSize(widget->width(), widget->height());
     }
   }
 
   if(elem.hasAttribute("caption")) {
-    setWindowTitle(elem.attribute("caption"));
+    widget->setWindowTitle(elem.attribute("caption"));
   }
-}
-
-void Window::connectFrom(const char *signal,
-                           const QObject *receiver, const char *method)
-{
-  connect(this, signal, receiver, method);
-}
-
-void Window::connectTo(const QObject *sender, const char *signal,
-                         const char *method)
-{
-  connect(sender, signal, this, method);
-}
-
-void Window::enable()
-{
-  setEnabled(true);
-}
 
-void Window::disable()
-{
-  setEnabled(false);
+  addChildren(node);
 }
 
-bool Window::isDisabled()
+Window::~Window()
 {
-  return isEnabled() == false;
+  printf("Delete (Window) %p\n", this); fflush(stdout);
+  // delete widget;
 }
diff --git a/client/widgets/window.h b/client/widgets/window.h
index 497c237..b7098d6 100644
--- a/client/widgets/window.h
+++ b/client/widgets/window.h
@@ -28,24 +28,18 @@
 #define __PRACRO_WINDOW_H__
 
 #include "widget.h"
-#include <QWidget>
 #include <QDomNode>
 
-class Window : public QWidget, public Widget
+class Window : public Widget
 {
 public:
   Window(QDomNode &node, MacroWindow *macrowindow);
+  ~Window();
 
-  void connectFrom(const char *signal,
-                   const QObject *receiver, const char *method);
-
-  void connectTo(const QObject *sender, const char *signal,
-                 const char *method);
-
-  void disable();
-  void enable();
-  bool isDisabled();
+  QString value() { return ""; }
+  void setValue(QString, QString) {}
 
+  void setWdgValid(bool) {}
 };
 
 #endif/*__PRACRO_WINDOW_H__*/
diff --git a/server/TODO b/server/TODO
index 1c15b68..59b0513 100644
--- a/server/TODO
+++ b/server/TODO
@@ -1,3 +1,9 @@
+server:
+  params in configfile (all, but -c)
+
+
+
+
 client:
 
 sessionid skal lagres lokalt med template navn.
diff --git a/server/src/luaresume.cc b/server/src/luaresume.cc
index eb6d90b..a74f1f5 100644
--- a/server/src/luaresume.cc
+++ b/server/src/luaresume.cc
@@ -34,7 +34,7 @@
 
 #define GLOBAL_POINTER "_pracroGlobalLUAObjectPointerThisShouldBeANameThatIsNotAccidentallyOverwritten"
 
-static int _getValue(lua_State *L)
+static int _value(lua_State *L)
 {
   Pracro::checkParameters(L,
                           Pracro::T_STRING,
@@ -51,7 +51,7 @@ static int _getValue(lua_State *L)
     return 1;
   }
 
-  std::string value = lua->getValue(name);
+  std::string value = lua->value(name);
   lua_pushstring(L, value.c_str());
 
   return 1;
@@ -71,7 +71,7 @@ LUAResume::LUAResume(Commit &c)
   lua_pushlightuserdata(L, this); // Push the pointer to 'this' instance
   lua_setglobal(L, GLOBAL_POINTER); // Assign it to a global lua var.
 
-  lua_register(L, "getValue", _getValue);
+  lua_register(L, "value", _value);
 }
 
 LUAResume::~LUAResume()
@@ -79,7 +79,7 @@ LUAResume::~LUAResume()
   lua_close(L);
 }
 
-std::string LUAResume::getValue(std::string name)
+std::string LUAResume::value(std::string name)
 {
   if(commit.fields.find(name) == commit.fields.end()) {
     ERR(luaresume, "LUAResume: No such field '%s'\n", name.c_str());
diff --git a/server/src/luaresume.h b/server/src/luaresume.h
index 5a1896e..1132f26 100644
--- a/server/src/luaresume.h
+++ b/server/src/luaresume.h
@@ -40,7 +40,7 @@ public:
   
   std::string run(std::string program);
 
-  std::string getValue(std::string name);
+  std::string value(std::string name);
 
   void error(std::string message);
 
diff --git a/server/src/macroparser.cc b/server/src/macroparser.cc
index fe7f6e3..2bd482e 100644
--- a/server/src/macroparser.cc
+++ b/server/src/macroparser.cc
@@ -84,6 +84,7 @@ MacroParser::MacroParser(std::string macrofile)
   m = NULL;
   current_map = NULL;
   current_script = NULL;
+  current_resume_script = NULL;
 
   file = macrofile;
 
@@ -101,9 +102,9 @@ MacroParser::~MacroParser()
 
 void MacroParser::characterData(std::string &data)
 {
-  if(state == RESUME) {
-    assert(m); // No macro present!
-    m->resume.attributes["format"].append(data);
+  if(state == RESUME_SCRIPT) {
+    assert(current_resume_script); // No macro present!
+    current_resume_script->code.append(data);
   }
 
   if(state == MAP) {
@@ -117,7 +118,8 @@ void MacroParser::characterData(std::string &data)
   }
 }
 
-void MacroParser::startTag(std::string name, std::map< std::string, std::string> attributes)
+void MacroParser::startTag(std::string name,
+                           std::map< std::string, std::string> attributes)
 {
   // Create macro and enable parsing of queries, maps and widgets
   if(name == "macro") {
@@ -203,18 +205,36 @@ void MacroParser::startTag(std::string name, std::map< std::string, std::string>
     return;
   }
 
-  // Create Query
+  // Create script
   if(name == "script") {
-    if(state != SCRIPTS) error("script found outside scripts.");
-    state = SCRIPT;
-
-    assert(m); // No macro is currently available, cannot create map!
-
-    Script s;
-    s.attributes = attributes;
-    m->scripts.push_back(s);
-    current_script = &(m->scripts.back());
 
+    assert(m); // No macro is currently available, cannot create script!
+
+    switch(state) {
+    case SCRIPTS:
+      {
+        state = SCRIPT;
+
+        Script s;
+        s.attributes = attributes;
+        m->scripts.push_back(s);
+        current_script = &(m->scripts.back());
+      }
+      break;
+    case RESUME:
+      {
+        state = RESUME_SCRIPT;
+
+        Script s;
+        s.attributes = attributes;
+        m->resume_scripts.push_back(s);
+        current_resume_script = &(m->resume_scripts.back());
+      }
+      break;
+    default:
+       error("<script> tag found outside <scripts> or <resume> tags.");
+       break;
+    }
     return;
   }
 
@@ -278,8 +298,21 @@ void MacroParser::endTag(std::string name)
   }
   if(name == "scripts") state = MACRO;
   if(name == "script") {
-    current_script = NULL;
-    state = SCRIPTS;
+    switch(state) {
+    case SCRIPT:
+      current_script = NULL;
+      state = SCRIPTS;
+      break;
+
+    case RESUME_SCRIPT:
+      current_resume_script = NULL;
+      state = RESUME;
+      break;
+
+    default:
+      // tag mismatch?
+      break;
+    }
   }
   if(name == "widgets") state = MACRO;
   
diff --git a/server/src/macroparser.h b/server/src/macroparser.h
index 86a1487..eaa5638 100644
--- a/server/src/macroparser.h
+++ b/server/src/macroparser.h
@@ -35,13 +35,13 @@ class MacroParser : public SAXParser {
     UNDEFINED,
     MACRO,
     RESUME,
+    RESUME_SCRIPT,
     QUERIES,
     QUERY,
     MAPS,
     MAP,
     WIDGETS,
     SCRIPTS,
-    SCRIPT_INCLUDE,
     SCRIPT
   } ParserState;
 
@@ -75,6 +75,7 @@ private:
   Macro *m;
   Map *current_map;
   Script *current_script;
+  Script *current_resume_script;
   std::vector< Widget* > widgetstack;
 
   // Error callback function.
diff --git a/server/src/resumeparser.cc b/server/src/resumeparser.cc
index 37b36f4..c80c2f0 100644
--- a/server/src/resumeparser.cc
+++ b/server/src/resumeparser.cc
@@ -31,110 +31,36 @@
 #include "luaresume.h"
 #include "configuration.h"
 
-static std::string resume_parser_format(Resume &r, Commit &commit)
+std::string resume_parser(Macro &macro, Commit &commit)
 {
-  const char* format = r.attributes["format"].c_str();
-
-  std::string resume;
-  std::string var;
+  LUAResume luaresume(commit);
 
-  const char *p = format;
-  const char *theend = p + strlen(format);
-  while(p < theend) {
-    switch(*p) {
-    case '$':
-      p++;
-      switch(*p) {
-      case '$':
-        resume.append(1, *p);
-        break;
+  std::string code;
 
-      case '{':
-        p++;
-        var = "";
-        // Parser
-        while(p < theend && *p != '}') {
-          var.append(1, *p);
-          p++;
+  std::vector< Script >::iterator spi = macro.resume_scripts.begin();
+  while(spi != macro.resume_scripts.end()) {
+    if(spi->attributes.find("src") != spi->attributes.end()) {
+      std::string src = spi->attributes["src"];
+      std::string file =
+        Conf::xml_basedir + "/include/" + src;
+      FILE *fp = fopen(file.c_str(), "r");
+      if(fp) {
+        char buf[64];
+        size_t sz;
+        std::string inc;
+        while((sz = fread(buf, 1, sizeof(buf), fp)) != 0) {
+          inc.append(buf, sz);
         }
-        //        p++;
-        //printf("[%s]\n", var.c_str());
-        //        resume += "var(" + var + ")";
-        resume += commit.fields[var];
-        break;
-
-      default:
-        resume.append(1, *p);
-       //       printf("Illigal $ command\n");
-        break;
-      }
-      p++;
-      break;
-
-    case '\\':
-      p++;
-      switch(*p) {
-      case 't':
-        resume.append(1, '\t');
-        break;
-      case 'n':
-        resume.append(1, '\n');
-        break;
-      case 'r':
-        resume.append(1, '\r');
-        break;
-      case '\\':
-      default:
-        resume.append(1, *p);
-        break;
+        fclose(fp);
+        code += "\n-- BEGIN INCLUDE: '" + src + "'\n";
+        code += inc;
+        code += "\n-- END INCLUDE: '" + src + "'\n";
       }
-      p++;
-     break;
-
-    default:
-      resume.append(1, *p);
-      p++;
-      break;
+    } else {
+      code += spi->code;
     }
+    spi++;
   }
 
-  return resume;
-}
-
-static std::string resume_parser_lua(Macro &macro, Commit &commit)
-{
-  LUAResume luaresume(commit);
-  std::string lua;
-  /*
-  std::vector< ScriptInclude >::iterator spii =
-    macro.script_includes.begin();
-  while(spii != macro.script_includes.end()) {
-    std::string file =
-      Conf::xml_basedir + "/include/" + spii->attributes["file"];
-    FILE *fp = fopen(file.c_str(), "r");
-    if(fp) {
-      char buf[64];
-      size_t sz;
-      std::string inc;
-      while((sz = fread(buf, 1, sizeof(buf), fp)) != 0) {
-        lua.append(buf, sz);
-      }
-      fclose(fp);
-    }
-    spii++;
-  }
-  */
-  lua += macro.resume.attributes["format"];
-
-  return luaresume.run(lua);
-}
-
-std::string resume_parser(Macro &macro, Commit &commit)
-{
-  if(macro.resume.attributes["language"] == "lua") {
-    return resume_parser_lua(macro, commit);
-  }
-
-  // Default to pracro format language.
-  return resume_parser_format(macro.resume, commit);
+  return luaresume.run(code);
 }
diff --git a/server/src/template.h b/server/src/template.h
index 1ca69ff..479e6ee 100644
--- a/server/src/template.h
+++ b/server/src/template.h
@@ -42,6 +42,7 @@ public:
 class Script {
 public:
   attr_t attributes;
+  std::string code;
 };
 
 class Map {
@@ -65,6 +66,7 @@ public:
   std::vector< Query > queries;
   maps_t maps;
   std::vector< Script > scripts;
+  std::vector< Script > resume_scripts;
   Widget widgets;
   attr_t attributes;
   Resume resume;
diff --git a/server/xml/macros/test_button.xml b/server/xml/macros/test_button.xml
index 9f01960..84f172e 100644
--- a/server/xml/macros/test_button.xml
+++ b/server/xml/macros/test_button.xml
@@ -1,6 +1,10 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <macro name="test_button" version="1.0">
-  <resume></resume>
+  <resume>
+		<script>
+			return value('dims')
+		</script>
+	</resume>
   <queries>
   </queries>
   <maps>
diff --git a/server/xml/macros/test_lineedit.xml b/server/xml/macros/test_lineedit.xml
index 783ad57..d706b50 100644
--- a/server/xml/macros/test_lineedit.xml
+++ b/server/xml/macros/test_lineedit.xml
@@ -7,18 +7,14 @@
   <maps>
   </maps>
   <scripts>
-    <script name="A" language="lua">
-      if ( value == '4' )
-      then
-        return true
-      end
-      return false
-    </script>
+    <script language="lua" src="regexp.lua"/>
   </scripts>
   <widgets caption="Test LineEdit"
           layout="vbox">
 
-    <lineedit name="dims" value="tester" script="A" map="test.data" regexp="[0-9]"/>
+    <lineedit name="dims" value="tester"
+	      map="test.data"
+	      onChange="this:setValid(regexp('^%d?%d?%d$'))"/>
 
     <frame layout="hbox">
       <spacer />
diff --git a/server/xml/macros/test_metawidget.xml b/server/xml/macros/test_metawidget.xml
index a2d51ea..3e78ebe 100644
--- a/server/xml/macros/test_metawidget.xml
+++ b/server/xml/macros/test_metawidget.xml
@@ -10,14 +10,19 @@
   <widgets caption="Test Metawidget"
           layout="vbox">
 
-    <metawidget layout="vbox" name="dims" format="${test1}: ${test2}" storechildren="true">
+    <metawidget layout="vbox" name="dims" format="${test1}: ${test2}"
+		storechildren="true">
       <lineedit name="test1" value="test"/>
-      <checkbox name="test2" value="ja" truevalue="ja" falsevalue="nej" caption="Og svaret er?"/>
+      <checkbox name="test2" value="ja" truevalue="ja" falsevalue="nej"
+		caption="Og svaret er?"/>
     </metawidget>
 
-    <metawidget layout="vbox" name="dims2" format="${a}: ${b}" storechildren="false">
+    <metawidget layout="vbox" name="dims2" format="${a}: ${b}"
+		storechildren="false">
       <lineedit name="a" value="test"/>
-      <checkbox name="b" value="ja" truevalue="ja" falsevalue="nej" caption="Og svaret er?"/>
+      <checkbox name="b" value="ja" truevalue="ja" falsevalue="nej"
+		caption="Og svaret er?"
+		onChange="w=widget('dims') w:setValid(this:checked())"/>
     </metawidget>
       
     <frame layout="hbox">
diff --git a/server/xml/macros/test_resume.xml b/server/xml/macros/test_resume.xml
index c3e3cbe..05afd3f 100644
--- a/server/xml/macros/test_resume.xml
+++ b/server/xml/macros/test_resume.xml
@@ -1,32 +1,85 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <macro name="test_resume" version="1.0">
-  <resume language="lua">
-    -- This is a LUA program!
-    if getValue('test2') == 'ja'
-    then
-      return getValue('dims') .. ' made out of ' .. getValue('test1') .. ' and ' .. getValue('test2')
-    else
-      return 'niksen'
-    end
+
+  <resume>
+		<script src="regexp.lua"/>
+		<script>
+			-- inline code
+			if(regexp('.+', ''))
+			then
+			  return 'a string'
+			else
+			  return 'another string'
+			end
+		</script>
   </resume>
+	
   <queries>
   </queries>
+
   <maps>
   </maps>
+
   <scripts>
+    <script language="lua" src="test.lua"/>
+    <script language="lua">
+      function bar(wdg)
+        w = widget(wdg)
+        w:setValid(this:checked())
+      end
+
+      function foo()
+        this:setValid((string.sub(this:value(), 1, 4) == 'test'))
+      end
+    </script>
   </scripts>
+
   <widgets caption="Test Resume"
           layout="vbox">
 
-    <metawidget layout="vbox" name="dims"
-		format="${test1}: ${test2}"
-		storechildren="true">
-      <lineedit name="test1" value="test"/>
-      <checkbox caption="Og svaret er?"
-		name="test2" value="ja"
-		truevalue="ja" falsevalue="nej"/>
-    </metawidget>
+    <lineedit name="test1" value="test"
+	      onChange="this:setValid(this:value()~='')"/>
+    <checkbox caption="Og svaret eer?"
+	      name="test2" value="ja"
+	      truevalue="ja" falsevalue="nej"
+	      onChange="bar('test1')"/>
+    <textedit name="test3" value="tjae"
+	      onChange="this:setValid(this:value() == 'a')"/>
       
+    <altcombobox name="dims" value="futtefejer" layout="vbox"
+		 onChange="this:setValid((string.sub(this:value(), 1, 4) == 'test'))">
+      <item caption="Test1" value="test1"/>
+      <item caption="Test2" value="test2"/>
+      <item caption="Test3" value="test3"/>
+      <altitem caption="Test[n]" value="test4" innerwidget="inner">
+	<lineedit name="inner"/>
+      </altitem>
+    </altcombobox>
+
+    <combobox name="combo1" type="select"
+				onChange="this:setValid((string.sub(this:value(), 1, 4) == 'test'))">
+      <item caption="Test1" value="test1"/>
+      <item caption="Test2" value="test2"/>
+      <item caption="Test3" value="test3"/>
+      <item caption="Test4" value="test4"/>
+    </combobox>
+
+    <combobox name="combo2" type="search"
+	      onChange="this:setValid((string.sub(this:value(), 1, 4) == 'test'))">
+      <item caption="Test1" value="test1"/>
+      <item caption="Test2" value="test2"/>
+      <item caption="Test3" value="test3"/>
+      <item caption="Test4" value="test4"/>
+    </combobox>
+
+    <combobox name="combo3" type="edit"
+	      onChange="this:setValid((string.sub(this:value(), 1, 4) == 'test'))">
+      <item caption="Test1" value="test1"/>
+      <item caption="Test2" value="test2"/>
+      <item caption="Test3" value="test3"/>
+      <item caption="Test4" value="test4"/>
+    </combobox>
+
     <frame layout="hbox">
       <spacer />
       <button caption="Reset" action="reset"/>
-- 
cgit v1.2.3