Index: libglade/src/xml.hg
===================================================================
--- libglade/src/xml.hg	(revision 2071)
+++ libglade/src/xml.hg	(working copy)
@@ -44,6 +44,85 @@
 };
 
 
+#define _STR(x) #x
+#define STR(x) _STR(x)
+#define GLADEMM_SLOT(n, s) __register_slot(STR(s), &n::s)
+#define GLADEMM_DECLARE_SLOTS(...) \
+virtual void __init_slots(void) \
+{ \
+    __VA_ARGS__; \
+}
+
+class NoSlotException : public Glib::Exception
+{
+public:
+  NoSlotException(const Glib::ustring& name) { str = name; }
+  virtual ~NoSlotException(void) throw() {}
+  virtual Glib::ustring what() const
+  {
+    return str;
+  }
+
+protected:
+  Glib::ustring str;
+};
+
+class Slots : public Glib::Object
+{
+public:
+
+  virtual ~Slots(void)
+  {
+    for (std::map<Glib::ustring, sigc::slot_base*>::iterator it =
+	    slot_map.begin(); it != slot_map.end(); it++) {
+	delete it->second;
+    }
+    slot_map.clear();
+  }
+
+  template <class T_class>
+  T_class get_slot(const Glib::ustring name)
+  {
+    if (slot_map.empty())
+	__init_slots();
+    std::map<Glib::ustring, sigc::slot_base*>::iterator it =
+	    slot_map.find(name);
+    if (it == slot_map.end())
+	throw NoSlotException(name);
+    T_class *sl = dynamic_cast<T_class*>(it->second);
+    if (!sl)
+	throw Glib::Error(g_quark_from_static_string("wrong_handler_type"), -1,
+		"Wrong handler type");
+    return *sl;
+  }
+
+  template <class T_sig>
+  void connect(T_sig sig, const Glib::ustring& name)
+  {
+    sig.connect(get_slot<typename T_sig::SlotType>(name));
+  }
+
+protected:
+  virtual void __init_slots(void) = 0;
+  template <typename T_ret, class T_class>
+  void __register_slot(const Glib::ustring& name,
+	T_ret(T_class::*handler)(void))
+  {
+    T_class *self = dynamic_cast<T_class*>(this);
+    g_assert(self);
+    slot_map[name] = new sigc::slot<T_ret>(sigc::mem_fun(*self, handler));
+  }
+  template <typename T_ret, class T_class, typename T_arg>
+  void __register_slot(const Glib::ustring& name,
+	T_ret(T_class::*handler)(T_arg))
+  {
+    T_class *self = dynamic_cast<T_class*>(this);
+    g_assert(self);
+    slot_map[name] = new sigc::slot<T_ret, T_arg>(sigc::mem_fun(*self, handler));
+  }
+  std::map<Glib::ustring, sigc::slot_base*> slot_map;
+};
+
 class Xml : public Glib::Object
 {
   _CLASS_GOBJECT(Xml, GladeXML, GLADE_XML, Glib::Object, GObject)
Index: examples/basic/basic.cc
===================================================================
--- examples/basic/basic.cc	(revision 2071)
+++ examples/basic/basic.cc	(working copy)
@@ -4,14 +4,24 @@
 
 Gtk::Dialog* pDialog = 0;
 
+class MySlots : public Gnome::Glade::Slots
+{
+private:
+GLADEMM_DECLARE_SLOTS(
+  GLADEMM_SLOT(MySlots, on_button_clicked)
+);
+
 void on_button_clicked()
 {
   if(pDialog)
     pDialog->hide(); //hide() will cause main::run() to end.
 }
 
+};
+
 int main (int argc, char **argv)
 {
+  MySlots slots;
   Gtk::Main kit(argc, argv);
 
   //Load the Glade file and instiate its widgets:
@@ -37,7 +47,6 @@
 #endif
 
   //Get the Glade-instantiated Dialog:
-  
   refXml->get_widget("DialogBasic", pDialog);
   if(pDialog)
   {
@@ -46,7 +55,7 @@
     refXml->get_widget("quit_button", pButton);
     if(pButton)
     {
-      pButton->signal_clicked().connect( sigc::ptr_fun(on_button_clicked) );
+      slots.connect( pButton->signal_clicked(), "on_button_clicked" );
     }
 
     kit.run(*pDialog);
