[dia/dia-next: 41/59] Implement a large part of the new operations editor



commit 020d2914f7023c7c8777e81db1ae63d93296e2b8
Author: Zander Brown <zbrown gnome org>
Date:   Wed Jan 2 00:00:14 2019 +0000

    Implement a large part of the new operations editor
    
    Reordering is a little buggy but otherwise seems to work well

 data/dia-uml-class-editor.ui                       |  242 +++
 data/dia-uml-operation-dialog.ui                   |    1 +
 data/dia-uml-operation-parameter-row.ui            |   26 +-
 data/dia-uml-operation-row.ui                      |   88 ++
 objects/UML/Makefile.am                            |    7 +-
 objects/UML/class.c                                |   37 +-
 objects/UML/class_attributes_dialog.c              |    8 +-
 objects/UML/class_dialog.c                         |  320 +---
 objects/UML/class_dialog.h                         |   73 +-
 objects/UML/class_operations_dialog.c              | 1659 +-------------------
 objects/UML/class_templates_dialog.c               |   15 +-
 objects/UML/dia-uml-class.c                        |  240 +++
 objects/UML/dia-uml-class.h                        |   78 +
 objects/UML/editor/dia-uml-class-editor.c          |  283 ++++
 objects/UML/editor/dia-uml-class-editor.h          |   29 +
 objects/UML/editor/dia-uml-operation-dialog.c      |  328 ++++
 objects/UML/editor/dia-uml-operation-dialog.h      |   26 +
 .../UML/editor/dia-uml-operation-parameter-row.c   |  207 +++
 .../UML/editor/dia-uml-operation-parameter-row.h   |   24 +
 objects/UML/editor/dia-uml-operation-row.c         |  159 ++
 objects/UML/editor/dia-uml-operation-row.h         |   20 +
 objects/UML/uml.h                                  |   37 +-
 objects/UML/umloperation.c                         |   86 +-
 objects/UML/umlparameter.c                         |   18 +
 24 files changed, 2000 insertions(+), 2011 deletions(-)
---
diff --git a/data/dia-uml-class-editor.ui b/data/dia-uml-class-editor.ui
new file mode 100644
index 00000000..f7622d06
--- /dev/null
+++ b/data/dia-uml-class-editor.ui
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="DiaUmlClassEditor" parent="GtkScrolledWindow">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="propagate_natural_width">True</property>
+    <property name="propagate_natural_height">True</property>
+    <child>
+      <object class="GtkViewport">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="shadow_type">none</property>
+        <child>
+          <object class="GtkBox">
+            <property name="width_request">400</property>
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">center</property>
+            <property name="margin_left">16</property>
+            <property name="margin_right">16</property>
+            <property name="margin_top">16</property>
+            <property name="margin_bottom">16</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">8</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Attributes</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="label_yalign">0</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkListBox" id="attributes">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="selection_mode">none</property>
+                  </object>
+                </child>
+                <child type="label_item">
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="label" translatable="yes">Add Attribute</property>
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Operations</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="label_yalign">0</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkListBox" id="operations">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="selection_mode">none</property>
+                    <signal name="add" handler="operation_added" object="DiaUmlClassEditor" swapped="yes"/>
+                    <signal name="remove" handler="operation_removed" object="DiaUmlClassEditor" 
swapped="yes"/>
+                    <signal name="row-activated" handler="edit_operation" object="DiaUmlClassEditor" 
swapped="yes"/>
+                  </object>
+                </child>
+                <child type="label_item">
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="label" translatable="yes">Add Operation</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+                <signal name="clicked" handler="add_operation" object="DiaUmlClassEditor" swapped="yes"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Templates</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">6</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">16</property>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Template Class</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="pack_type">end</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">7</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="label_yalign">0</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkListBox" id="templates">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="selection_mode">none</property>
+                  </object>
+                </child>
+                <child type="label_item">
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">8</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="label" translatable="yes">Add Template</property>
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">9</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <style>
+      <class name="background"/>
+    </style>
+  </template>
+</interface>
diff --git a/data/dia-uml-operation-dialog.ui b/data/dia-uml-operation-dialog.ui
index b9d0962b..99c531cb 100644
--- a/data/dia-uml-operation-dialog.ui
+++ b/data/dia-uml-operation-dialog.ui
@@ -289,6 +289,7 @@
                             <property name="receives_default">True</property>
                             <property name="halign">end</property>
                             <property name="valign">center</property>
+                            <signal name="clicked" handler="remove_operation" object="DiaUmlOperationDialog" 
swapped="yes"/>
                             <style>
                               <class name="destructive-action"/>
                             </style>
diff --git a/data/dia-uml-operation-parameter-row.ui b/data/dia-uml-operation-parameter-row.ui
index 322da6b1..34bfe435 100644
--- a/data/dia-uml-operation-parameter-row.ui
+++ b/data/dia-uml-operation-parameter-row.ui
@@ -3,12 +3,24 @@
 <interface>
   <requires lib="gtk+" version="3.20"/>
   <object class="GtkTextBuffer" id="comment"/>
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">go-up-symbolic</property>
+  </object>
+  <object class="GtkImage" id="image2">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">go-down-symbolic</property>
+  </object>
   <template class="DiaUmlOperationParameterRow" parent="GtkListBoxRow">
     <property name="width_request">100</property>
     <property name="height_request">80</property>
     <property name="visible">True</property>
-    <property name="can_focus">True</property>
+    <property name="can_focus">False</property>
     <property name="hexpand">True</property>
+    <property name="activatable">False</property>
+    <property name="selectable">False</property>
     <child>
       <object class="GtkGrid">
         <property name="visible">True</property>
@@ -194,6 +206,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="image">image1</property>
+                    <signal name="clicked" handler="move_up" object="DiaUmlOperationParameterRow" 
swapped="yes"/>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -207,6 +220,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="image">image2</property>
+                    <signal name="clicked" handler="move_down" object="DiaUmlOperationParameterRow" 
swapped="yes"/>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -246,14 +260,4 @@
       </object>
     </child>
   </template>
-  <object class="GtkImage" id="image1">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="icon_name">go-up-symbolic</property>
-  </object>
-  <object class="GtkImage" id="image2">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="icon_name">go-down-symbolic</property>
-  </object>
 </interface>
diff --git a/data/dia-uml-operation-row.ui b/data/dia-uml-operation-row.ui
new file mode 100644
index 00000000..e5f2c7d9
--- /dev/null
+++ b/data/dia-uml-operation-row.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">go-up-symbolic</property>
+  </object>
+  <object class="GtkImage" id="image2">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">go-down-symbolic</property>
+  </object>
+  <template class="DiaUmlOperationRow" parent="GtkListBoxRow">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">8</property>
+        <property name="margin_right">8</property>
+        <property name="margin_top">8</property>
+        <property name="margin_bottom">8</property>
+        <property name="spacing">16</property>
+        <child>
+          <object class="GtkLabel" id="title">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Operation</property>
+            <property name="ellipsize">end</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">end</property>
+            <property name="valign">center</property>
+            <child>
+              <object class="GtkButton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="image">image1</property>
+                <signal name="clicked" handler="move_up" object="DiaUmlOperationRow" swapped="yes"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="image">image2</property>
+                <signal name="clicked" handler="move_down" object="DiaUmlOperationRow" swapped="yes"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <style>
+              <class name="linked"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/objects/UML/Makefile.am b/objects/UML/Makefile.am
index 1ea8e5e0..f8c208b6 100644
--- a/objects/UML/Makefile.am
+++ b/objects/UML/Makefile.am
@@ -4,11 +4,16 @@ pkglib_LTLIBRARIES =  libuml_objects.la
 libuml_objects_la_SOURCES = \
                        uml.h \
                        uml.c \
+                       dia-uml-class.c \
                        class.c \
                        class.h \
                        class_dialog.h \
                        class_dialog.c \
                        class_attributes_dialog.c \
+                       editor/dia-uml-class-editor.c \
+                       editor/dia-uml-operation-row.c \
+                       editor/dia-uml-operation-dialog.c \
+                       editor/dia-uml-operation-parameter-row.c \
                        class_operations_dialog.c \
                        class_templates_dialog.c \
                        note.c \
@@ -46,7 +51,7 @@ libuml_objects_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINE
 libuml_objects_la_LIBADD = $(CAIRO_LIBS) $(top_builddir)/lib/libdia.la
 
 AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(srcdir)/../../lib \
-       $(DEBUG_FLAGS) $(GTK_CFLAGS) $(PANGOFT2_CFLAGS) $(UNICODE_CFLAGS)
+       $(DEBUG_FLAGS) $(GTK_CFLAGS) $(PANGOFT2_CFLAGS) $(UNICODE_CFLAGS) -DG_LOG_DOMAIN=\"DimUml\"
 
 EXTRA_DIST = \
        pixmaps/actor.xpm \
diff --git a/objects/UML/class.c b/objects/UML/class.c
index 808600bf..7f4e957e 100644
--- a/objects/UML/class.c
+++ b/objects/UML/class.c
@@ -372,6 +372,7 @@ typedef struct _CommentState {
   ObjectState state;
   gboolean    visible_comments;
 } CommentState;
+
 static ObjectState*
 _comment_get_state (DiaObject *obj)
 {
@@ -380,6 +381,7 @@ _comment_get_state (DiaObject *obj)
   state->visible_comments = ((UMLClass *)obj)->visible_comments;
   return (ObjectState *)state;
 }
+
 static void
 _comment_set_state (DiaObject *obj, ObjectState *state)
 {
@@ -473,10 +475,10 @@ umlclass_set_props(UMLClass *umlclass, GPtrArray *props)
       DiaUmlOperation *op = (DiaUmlOperation *)list->data;
 
       dia_uml_operation_ensure_connection_points (op, obj);
-      obj->connections[i] = op->left_connection;
+      obj->connections[i] = op->l_connection;
       obj->connections[i]->object = obj;
       i++;
-      obj->connections[i] = op->right_connection;
+      obj->connections[i] = op->r_connection;
       obj->connections[i]->object = obj;
       i++;
       list = g_list_next(list);
@@ -548,6 +550,7 @@ umlclass_move(UMLClass *umlclass, Point *to)
 
   return NULL;
 }
+
 /**
  * underlines the text at the start point using the text to determine
  * the length of the underline. Draw a line under the text represented by
@@ -1308,12 +1311,12 @@ umlclass_update_data(UMLClass *umlclass)
   while (list != NULL) {
     DiaUmlOperation *op = (DiaUmlOperation *)list->data;
 
-    op->left_connection->pos.x = x;
-    op->left_connection->pos.y = y;
-    op->left_connection->directions = DIR_WEST;
-    op->right_connection->pos.x = x + elem->width;
-    op->right_connection->pos.y = y;
-    op->right_connection->directions = DIR_EAST;
+    op->l_connection->pos.x = x;
+    op->l_connection->pos.y = y;
+    op->l_connection->directions = DIR_WEST;
+    op->r_connection->pos.x = x + elem->width;
+    op->r_connection->pos.y = y;
+    op->r_connection->directions = DIR_EAST;
 
     if (op->needs_wrapping) { /* Wrapped */
       int lines = g_list_length(op->wrappos);
@@ -1782,6 +1785,7 @@ fill_in_fontdata(UMLClass *umlclass)
      umlclass->comment_font = dia_font_new_from_style(DIA_FONT_SANS | DIA_FONT_ITALIC, 0.7);
    }
 }
+
 /**
  * Create an object of type class
  * By default this will create a object of class UMLClass. Howerver there
@@ -1941,9 +1945,9 @@ umlclass_destroy(UMLClass *umlclass)
   list = umlclass->operations;
   while (list != NULL) {
     op = (DiaUmlOperation *)list->data;
-    g_free(op->left_connection);
-    g_free(op->right_connection);
-    g_object_unref (G_OBJECT (op));
+    g_free (op->l_connection);
+    g_free (op->r_connection);
+    g_object_unref (op);
     list = g_list_next(list);
   }
   g_list_free(umlclass->operations);
@@ -2100,8 +2104,8 @@ umlclass_copy(UMLClass *umlclass)
     list = newumlclass->operations;
     while (list != NULL) {
       DiaUmlOperation *op = (DiaUmlOperation *)list->data;
-      newobj->connections[i++] = op->left_connection;
-      newobj->connections[i++] = op->right_connection;
+      newobj->connections[i++] = op->l_connection;
+      newobj->connections[i++] = op->r_connection;
       
       list = g_list_next(list);
     }
@@ -2126,6 +2130,11 @@ umlclass_copy(UMLClass *umlclass)
   return &newumlclass->element.object;
 }
 
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+/* to/from file ------------------------------------------------------------ */
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
 
 static void
 umlclass_save(UMLClass *umlclass, ObjectNode obj_node,
@@ -2481,5 +2490,3 @@ umlclass_sanity_check(UMLClass *c, gchar *msg)
   }
   /* Check that operations are set up right. */
 }
-
-
diff --git a/objects/UML/class_attributes_dialog.c b/objects/UML/class_attributes_dialog.c
index 49296b8b..347259bd 100644
--- a/objects/UML/class_attributes_dialog.c
+++ b/objects/UML/class_attributes_dialog.c
@@ -198,7 +198,7 @@ attributes_list_new_callback(GtkWidget *button,
 
   if (dia_list_get_children (prop_dialog->attributes_list) != NULL)
     dia_list_unselect_child(prop_dialog->attributes_list,
-                           GTK_WIDGET(dia_list_get_children (prop_dialog->attributes_list)->data));
+                           DIA_LIST_ITEM (dia_list_get_children (prop_dialog->attributes_list)->data));
   dia_list_select_child(prop_dialog->attributes_list, list_item);
 }
 
@@ -272,14 +272,14 @@ attributes_list_move_down_callback(GtkWidget *button,
   GList *list;
   UMLClassDialog *prop_dialog;
   DiaList *gtklist;
-  GtkWidget *list_item;
+  DiaListItem *list_item;
   int i;
 
   prop_dialog = umlclass->properties_dialog;
   gtklist = prop_dialog->attributes_list;
 
   if (dia_list_get_selection (gtklist) != NULL) {
-    list_item = GTK_WIDGET(dia_list_get_selection (gtklist));
+    list_item = dia_list_get_selection (gtklist);
     
     i = dia_list_child_position (gtklist, list_item);
     if (i<(g_list_length (dia_list_get_children (gtklist))-1))
@@ -466,7 +466,7 @@ _attributes_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   list = dia_list_new ();
   prop_dialog->attributes_list = DIA_LIST(list);
   dia_list_set_selection_mode (DIA_LIST (list), GTK_SELECTION_SINGLE);
-  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
+  gtk_container_add (GTK_CONTAINER (scrolled_win), list);
   gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
                                       gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(scrolled_win)));
   gtk_widget_show (list);
diff --git a/objects/UML/class_dialog.c b/objects/UML/class_dialog.c
index 9e4431d5..834b1e81 100644
--- a/objects/UML/class_dialog.c
+++ b/objects/UML/class_dialog.c
@@ -42,6 +42,7 @@
 #include "class.h"
 #include "diaoptionmenu.h"
 #include "diafontselector.h"
+#include "dia-uml-class.h"
 
 #include "class_dialog.h"
 
@@ -60,56 +61,6 @@ typedef struct _Disconnect {
   Handle *other_handle;
 } Disconnect;
 
-typedef struct _UMLClassState UMLClassState;
-
-struct _UMLClassState {
-  real font_height;
-  real abstract_font_height;
-  real polymorphic_font_height;
-  real classname_font_height;
-  real abstract_classname_font_height;
-  real comment_font_height;
-
-  DiaFont *normal_font;
-  DiaFont *abstract_font;
-  DiaFont *polymorphic_font;
-  DiaFont *classname_font;
-  DiaFont *abstract_classname_font;
-  DiaFont *comment_font;
-  
-  char *name;
-  char *stereotype;
-  char *comment;
-
-  int abstract;
-  int suppress_attributes;
-  int suppress_operations;
-  int visible_attributes;
-  int visible_operations;
-  int visible_comments;
-
-  int wrap_operations;
-  int wrap_after_char;
-  int comment_line_length;
-  int comment_tagging;
-  
-  real line_width;
-  GdkRGBA line_color;
-  GdkRGBA fill_color;
-  GdkRGBA text_color;
-
-  /* Attributes: */
-  GList *attributes;
-
-  /* Operators: */
-  GList *operations;
-
-  /* Template: */
-  int template;
-  GList *formal_params;
-};
-
-
 typedef struct _UMLClassChange UMLClassChange;
 
 struct _UMLClassChange {
@@ -123,13 +74,15 @@ struct _UMLClassChange {
 
   int applied;
   
-  UMLClassState *saved_state;
+  DiaUmlClass *saved_state;
 };
 
-static UMLClassState *umlclass_get_state(UMLClass *umlclass);
-static ObjectChange *new_umlclass_change(UMLClass *obj, UMLClassState *saved_state,
-                                        GList *added, GList *deleted,
-                                        GList *disconnected);
+static ObjectChange *
+new_umlclass_change (UMLClass    *obj,
+                     DiaUmlClass *saved_state,
+                     GList       *added,
+                     GList       *deleted,
+                     GList       *disconnected);
 
 /**** Utility functions ******/
 void
@@ -289,7 +242,7 @@ create_font_props_row (GtkGrid    *table,
                        GtkSpinButton   **heightsel)
 {
   GtkWidget *label;
-  GObject *adj;
+  GtkAdjustment *adj;
 
   label = gtk_label_new (kind);
   gtk_label_set_xalign (GTK_LABEL (label), 0.0);
@@ -300,7 +253,7 @@ create_font_props_row (GtkGrid    *table,
   gtk_grid_attach (GTK_GRID (table), GTK_WIDGET(*fontsel), 1, row, 1, 1);
 
   adj = gtk_adjustment_new (height, 0.1, 10.0, 0.1, 1.0, 0);
-  *heightsel = GTK_SPIN_BUTTON (gtk_spin_button_new (GTK_ADJUSTMENT(adj), 1.0, 2));
+  *heightsel = GTK_SPIN_BUTTON (gtk_spin_button_new (adj, 1.0, 2));
   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (*heightsel), TRUE);
   gtk_grid_attach (table, GTK_WIDGET (*heightsel), 2, row, 1, 1);
 }
@@ -318,7 +271,7 @@ class_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   GtkWidget *scrolledwindow;
   GtkWidget *checkbox;
   GtkWidget *table;
-  GObject *adj;
+  GtkAdjustment *adj;
 
   prop_dialog = umlclass->properties_dialog;
 
@@ -398,8 +351,8 @@ class_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   checkbox = gtk_check_button_new_with_label(_("Wrap Operations"));
   prop_dialog->op_wrap = GTK_TOGGLE_BUTTON( checkbox );
   gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
-  adj = gtk_adjustment_new( umlclass->wrap_after_char, 0.0, 200.0, 1.0, 5.0, 0);
-  prop_dialog->wrap_after_char = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT( adj), 0.1, 0));
+  adj = gtk_adjustment_new (umlclass->wrap_after_char, 0.0, 200.0, 1.0, 5.0, 0);
+  prop_dialog->wrap_after_char = GTK_SPIN_BUTTON (gtk_spin_button_new (adj, 0.1, 0));
   gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( prop_dialog->wrap_after_char), TRUE);
   gtk_spin_button_set_snap_to_ticks( GTK_SPIN_BUTTON( prop_dialog->wrap_after_char), TRUE);
   prop_dialog->max_length_label = GTK_LABEL( gtk_label_new( _("Wrap after this length: ")));
@@ -414,8 +367,8 @@ class_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   checkbox = gtk_check_button_new_with_label(_("Comments visible"));
   prop_dialog->comments_vis = GTK_TOGGLE_BUTTON( checkbox );
   gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
-  adj = gtk_adjustment_new( umlclass->comment_line_length, 17.0, 200.0, 1.0, 5.0, 0);
-  prop_dialog->comment_line_length = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT( adj), 0.1, 0));
+  adj = gtk_adjustment_new (umlclass->comment_line_length, 17.0, 200.0, 1.0, 5.0, 0);
+  prop_dialog->comment_line_length = GTK_SPIN_BUTTON (gtk_spin_button_new (adj, 0.1, 0));
   gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( prop_dialog->comment_line_length), TRUE);
   gtk_spin_button_set_snap_to_ticks( GTK_SPIN_BUTTON( prop_dialog->comment_line_length), TRUE);
   prop_dialog->Comment_length_label = GTK_LABEL( gtk_label_new( _("Wrap comment after this length: ")));
@@ -449,7 +402,7 @@ style_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   GtkWidget *fill_color;
   GtkWidget *line_color;
   GtkWidget *table;
-  GObject *adj;
+  GtkAdjustment *adj;
 
   prop_dialog = umlclass->properties_dialog;
 
@@ -516,8 +469,8 @@ style_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   gtk_label_set_yalign (GTK_LABEL (label), 0.5);
   gtk_widget_set_hexpand (label, TRUE);
   gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
-  adj = gtk_adjustment_new(umlclass->line_width, 0.0, G_MAXFLOAT, 0.1, 1.0, 0);
-  line_width = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 1.0, 2);
+  adj = gtk_adjustment_new (umlclass->line_width, 0.0, G_MAXFLOAT, 0.1, 1.0, 0);
+  line_width = gtk_spin_button_new (adj, 1.0, 2);
   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (line_width), TRUE);
   prop_dialog->line_width = GTK_SPIN_BUTTON(line_width);
   gtk_widget_set_hexpand (line_width, TRUE);
@@ -585,7 +538,6 @@ switch_page_callback(GtkNotebook *notebook,
 
   if (prop_dialog != NULL) {
     _attributes_get_current_values(prop_dialog);
-    _operations_get_current_values(prop_dialog);
     _templates_get_current_values(prop_dialog);
   }
 }
@@ -609,7 +561,7 @@ fill_in_dialog(UMLClass *umlclass)
 #endif
   class_fill_in_dialog(umlclass);
   _attributes_fill_in_dialog(umlclass);
-  _operations_fill_in_dialog(umlclass);
+  /*_operations_fill_in_dialog(umlclass);*/
   _templates_fill_in_dialog(umlclass);
 }
 
@@ -621,7 +573,8 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
   GList *list;
   int num_attrib, num_ops;
   GList *added, *deleted, *disconnected;
-  UMLClassState *old_state = NULL;
+  DiaUmlClass *old_state = NULL;
+  DiaUmlClass *editor_state;
   
 #ifdef DEBUG
   umlclass_sanity_check(umlclass, "Apply from dialog start");
@@ -629,18 +582,28 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
 
   prop_dialog = umlclass->properties_dialog;
 
-  old_state = umlclass_get_state(umlclass);
+  old_state = dia_uml_class_new (umlclass);
+
+  editor_state = dia_uml_class_editor_get_class (DIA_UML_CLASS_EDITOR (prop_dialog->editor));
   
   /* Allocate enought connection points for attributes and operations. */
   /* (two per op/attr) */
-  if ( (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_vis))) && 
(!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_supp))))
+  if (
+    ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_vis ))) &&
+    (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_supp)))
+  ) {
     num_attrib = g_list_length(dia_list_get_children(prop_dialog->attributes_list));
-  else
+  } else {
     num_attrib = 0;
-  if ( (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_vis))) && 
(!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_supp))))
-    num_ops = g_list_length(dia_list_get_children(prop_dialog->operations_list));
-  else
+  }
+  if (
+    ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_vis ))) &&
+    (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_supp)))
+  ) {
+    num_ops = g_list_length (dia_uml_class_get_operations (editor_state));
+  } else {
     num_ops = 0;
+  }
   obj = &umlclass->element.object;
 #ifdef UML_MAINPOINT
   obj->num_connections =
@@ -652,7 +615,7 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
   obj->connections =
     g_realloc(obj->connections,
              obj->num_connections*sizeof(ConnectionPoint *));
-  
+
   /* Read from dialog and put in object: */
   class_read_from_dialog(umlclass, prop_dialog);
   _attributes_read_from_dialog(umlclass, prop_dialog, UMLCLASS_CONNECTIONPOINTS);
@@ -696,7 +659,7 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
 #ifdef DEBUG
   umlclass_sanity_check(umlclass, "Apply from dialog end");
 #endif
-  return  new_umlclass_change(umlclass, old_state, added, deleted, disconnected);
+  return new_umlclass_change(umlclass, old_state, added, deleted, disconnected);
 }
 
 static void
@@ -729,7 +692,6 @@ umlclass_get_properties(UMLClass *umlclass, gboolean is_default)
 
     prop_dialog->current_attr = NULL;
     prop_dialog->current_op = NULL;
-    prop_dialog->current_param = NULL;
     prop_dialog->current_templ = NULL;
     prop_dialog->deleted_connections = NULL;
     prop_dialog->added_connections = NULL;
@@ -761,127 +723,6 @@ umlclass_get_properties(UMLClass *umlclass, gboolean is_default)
 
 /****************** UNDO stuff: ******************/
 
-static void
-umlclass_free_state(UMLClassState *state)
-{
-  GList *list;
-
-  g_object_unref (state->normal_font);
-  g_object_unref (state->abstract_font);
-  g_object_unref (state->polymorphic_font);
-  g_object_unref (state->classname_font);
-  g_object_unref (state->abstract_classname_font);
-  g_object_unref (state->comment_font);
-  
-  g_free(state->name);
-  g_free(state->stereotype);
-  g_free(state->comment);
-
-  list = state->attributes;
-  while (list) {
-    uml_attribute_destroy((UMLAttribute *) list->data);
-    list = g_list_next(list);
-  }
-  g_list_free(state->attributes);
-
-  list = state->operations;
-  while (list) {
-    g_object_unref (G_OBJECT (list->data));
-    list = g_list_next(list);
-  }
-  g_list_free(state->operations);
-
-  list = state->formal_params;
-  while (list) {
-    uml_formalparameter_destroy((UMLFormalParameter *) list->data);
-    list = g_list_next(list);
-  }
-  g_list_free(state->formal_params);
-}
-
-static UMLClassState *
-umlclass_get_state(UMLClass *umlclass)
-{
-  UMLClassState *state = g_new0(UMLClassState, 1);
-  GList *list;
-
-  state->font_height = umlclass->font_height;
-  state->abstract_font_height = umlclass->abstract_font_height;
-  state->polymorphic_font_height = umlclass->polymorphic_font_height;
-  state->classname_font_height = umlclass->classname_font_height;
-  state->abstract_classname_font_height = umlclass->abstract_classname_font_height;
-  state->comment_font_height = umlclass->comment_font_height;
-
-  state->normal_font = g_object_ref (umlclass->normal_font);
-  state->abstract_font = g_object_ref (umlclass->abstract_font);
-  state->polymorphic_font = g_object_ref (umlclass->polymorphic_font);
-  state->classname_font = g_object_ref (umlclass->classname_font);
-  state->abstract_classname_font = g_object_ref (umlclass->abstract_classname_font);
-  state->comment_font = g_object_ref (umlclass->comment_font);
-  
-  state->name = g_strdup(umlclass->name);
-  state->stereotype = g_strdup(umlclass->stereotype);
-  state->comment = g_strdup(umlclass->comment);
-
-  state->abstract = umlclass->abstract;
-  state->suppress_attributes = umlclass->suppress_attributes;
-  state->suppress_operations = umlclass->suppress_operations;
-  state->visible_attributes = umlclass->visible_attributes;
-  state->visible_operations = umlclass->visible_operations;
-  state->visible_comments = umlclass->visible_comments;
-
-  state->wrap_operations = umlclass->wrap_operations;
-  state->wrap_after_char = umlclass->wrap_after_char;
-  state->comment_line_length = umlclass->comment_line_length;
-  state->comment_tagging = umlclass->comment_tagging;
-
-  state->line_color = umlclass->line_color;
-  state->fill_color = umlclass->fill_color;
-  state->text_color = umlclass->text_color;
-  
-  state->attributes = NULL;
-  list = umlclass->attributes;
-  while (list != NULL) {
-    UMLAttribute *attr = (UMLAttribute *)list->data;
-    UMLAttribute *attr_copy;
-      
-    attr_copy = uml_attribute_copy(attr);
-    /* Looks wrong, but needed fro proper restore */
-    attr_copy->left_connection = attr->left_connection;
-    attr_copy->right_connection = attr->right_connection;
-
-    state->attributes = g_list_append(state->attributes, attr_copy);
-    list = g_list_next(list);
-  }
-
-  /* TODO: Why? */
-  state->operations = NULL;
-  list = umlclass->operations;
-  while (list != NULL) {
-    DiaUmlOperation *op = (DiaUmlOperation *)list->data;
-
-    state->operations = g_list_append(state->operations, op);
-    list = g_list_next(list);
-  }
-
-
-  state->template = umlclass->template;
-  
-  state->formal_params = NULL;
-  list = umlclass->formal_params;
-  while (list != NULL) {
-    UMLFormalParameter *param = (UMLFormalParameter *)list->data;
-    UMLFormalParameter *param_copy;
-    
-    param_copy = uml_formalparameter_copy(param);
-    state->formal_params = g_list_append(state->formal_params, param_copy);
-    
-    list = g_list_next(list);
-  }
-
-  return state;
-}
-
 static void
 umlclass_update_connectionpoints(UMLClass *umlclass)
 {
@@ -940,16 +781,14 @@ umlclass_update_connectionpoints(UMLClass *umlclass)
     
     if ( (umlclass->visible_operations) &&
         (!umlclass->suppress_operations)) {
-      obj->connections[connection_index] = op->left_connection;
+      obj->connections[connection_index] = op->l_connection;
       connection_index++;
-      obj->connections[connection_index] = op->right_connection;
+      obj->connections[connection_index] = op->r_connection;
       connection_index++;
     }
     
     list = g_list_next(list);
   }
-  if (prop_dialog)
-    dia_list_empty (DIA_LIST (prop_dialog->operations_list));
 
 #ifdef UML_MAINPOINT
   obj->connections[connection_index++] = &umlclass->connections[UMLCLASS_CONNECTIONPOINTS];
@@ -958,55 +797,9 @@ umlclass_update_connectionpoints(UMLClass *umlclass)
 }
 
 static void
-umlclass_set_state(UMLClass *umlclass, UMLClassState *state)
+umlclass_set_state(UMLClass *umlclass, DiaUmlClass *state)
 {
-  umlclass->font_height = state->font_height;
-  umlclass->abstract_font_height = state->abstract_font_height;
-  umlclass->polymorphic_font_height = state->polymorphic_font_height;
-  umlclass->classname_font_height = state->classname_font_height;
-  umlclass->abstract_classname_font_height = state->abstract_classname_font_height;
-  umlclass->comment_font_height = state->comment_font_height;
-
-  /* transfer ownership, but don't leak the previous font */
-  g_object_unref (umlclass->normal_font);
-  umlclass->normal_font = state->normal_font;
-  g_object_unref (umlclass->abstract_font);
-  umlclass->abstract_font = state->abstract_font;
-  g_object_unref (umlclass->polymorphic_font);
-  umlclass->polymorphic_font = state->polymorphic_font;
-  g_object_unref (umlclass->classname_font);
-  umlclass->classname_font = state->classname_font;
-  g_object_unref (umlclass->abstract_classname_font);
-  umlclass->abstract_classname_font = state->abstract_classname_font;
-  g_object_unref (umlclass->comment_font);
-  umlclass->comment_font = state->comment_font;
-  
-  umlclass->name = state->name;
-  umlclass->stereotype = state->stereotype;
-  umlclass->comment = state->comment;
-
-  umlclass->abstract = state->abstract;
-  umlclass->suppress_attributes = state->suppress_attributes;
-  umlclass->suppress_operations = state->suppress_operations;
-  umlclass->visible_attributes = state->visible_attributes;
-  umlclass->visible_operations = state->visible_operations;
-  umlclass->visible_comments = state->visible_comments;
-
-  umlclass->wrap_operations = state->wrap_operations;
-  umlclass->wrap_after_char = state->wrap_after_char;
-  umlclass->comment_line_length = state->comment_line_length;
-  umlclass->comment_tagging = state->comment_tagging;
-
-  umlclass->line_color = state->line_color;
-  umlclass->fill_color = state->fill_color;
-  umlclass->text_color = state->text_color;
-
-  umlclass->attributes = state->attributes;
-  umlclass->operations = state->operations;
-  umlclass->template = state->template;
-  umlclass->formal_params = state->formal_params;
-
-  g_free(state);
+  g_object_unref (state);
 
   umlclass_update_connectionpoints(umlclass);
 
@@ -1017,10 +810,10 @@ umlclass_set_state(UMLClass *umlclass, UMLClassState *state)
 static void
 umlclass_change_apply(UMLClassChange *change, DiaObject *obj)
 {
-  UMLClassState *old_state;
+  DiaUmlClass *old_state;
   GList *list;
   
-  old_state = umlclass_get_state(change->obj);
+  old_state = dia_uml_class_new (change->obj);
 
   umlclass_set_state(change->obj, change->saved_state);
 
@@ -1040,10 +833,10 @@ umlclass_change_apply(UMLClassChange *change, DiaObject *obj)
 static void
 umlclass_change_revert(UMLClassChange *change, DiaObject *obj)
 {
-  UMLClassState *old_state;
+  DiaUmlClass *old_state;
   GList *list;
   
-  old_state = umlclass_get_state(change->obj);
+  old_state = dia_uml_class_new(change->obj);
 
   umlclass_set_state(change->obj, change->saved_state);
   
@@ -1065,8 +858,7 @@ umlclass_change_free(UMLClassChange *change)
 {
   GList *list, *free_list;
 
-  umlclass_free_state(change->saved_state);
-  g_free(change->saved_state);
+  g_object_unref (change->saved_state);
 
   /* Doesn't this mean only one of add, delete can be done in each apply? */
   if (change->applied) 
@@ -1090,19 +882,19 @@ umlclass_change_free(UMLClassChange *change)
 }
 
 static ObjectChange *
-new_umlclass_change(UMLClass *obj, UMLClassState *saved_state,
-                   GList *added, GList *deleted, GList *disconnected)
+new_umlclass_change (UMLClass    *obj,
+                     DiaUmlClass *saved_state,
+                     GList       *added,
+                     GList       *deleted,
+                     GList       *disconnected)
 {
   UMLClassChange *change;
 
   change = g_new0(UMLClassChange, 1);
   
-  change->obj_change.apply =
-    (ObjectChangeApplyFunc) umlclass_change_apply;
-  change->obj_change.revert =
-    (ObjectChangeRevertFunc) umlclass_change_revert;
-  change->obj_change.free =
-    (ObjectChangeFreeFunc) umlclass_change_free;
+  change->obj_change.apply = (ObjectChangeApplyFunc) umlclass_change_apply;
+  change->obj_change.revert = (ObjectChangeRevertFunc) umlclass_change_revert;
+  change->obj_change.free = (ObjectChangeFreeFunc) umlclass_change_free;
 
   change->obj = obj;
   change->saved_state = saved_state;
diff --git a/objects/UML/class_dialog.h b/objects/UML/class_dialog.h
index 36e6386d..6374d83d 100644
--- a/objects/UML/class_dialog.h
+++ b/objects/UML/class_dialog.h
@@ -1,6 +1,7 @@
 #include "widgets.h"
 #include "widgets/dialist.h"
 #include "diafontselector.h"
+#include "editor/dia-uml-class-editor.h"
 
 /**
  * \brief Very special user interface for UMLClass parametrization
@@ -56,8 +57,13 @@ struct _UMLClassDialog {
   GtkTextView *attr_comment;
   GtkWidget *attr_visible;
   GtkToggleButton *attr_class_scope;
-  
-  DiaList *operations_list;
+
+  /* ------------------------------------- */
+  /* ------------------------------------- */
+  /* <<<<<<<<<<<<<<<<< Old operator dialog */
+  /* ------------------------------------- */
+  /* ------------------------------------- */
+
   DiaListItem *current_op;
   GtkEntry *op_name;
   GtkEntry *op_type;
@@ -69,18 +75,15 @@ struct _UMLClassDialog {
   GtkWidget *op_inheritance_type;
   GtkToggleButton *op_query;  
   
-  DiaList *parameters_list;
-  DiaListItem *current_param;
-  GtkEntry *param_name;
-  GtkEntry *param_type;
-  GtkEntry *param_value;
-  GtkTextView *param_comment;
-  GtkWidget *param_kind;
-  GtkWidget *param_new_button;
-  GtkWidget *param_delete_button;
-  GtkWidget *param_up_button;
-  GtkWidget *param_down_button;
-  
+  /* ------------------------------------- */
+  /* ------------------------------------- */
+  /* Old operator dialog >>>>>>>>>>>>>>>>> */
+  /* ------------------------------------- */
+  /* ------------------------------------- */
+
+  GtkWidget *editor;
+
+
   DiaList *templates_list;
   DiaListItem *current_templ;
   GtkToggleButton *templ_template;
@@ -94,11 +97,9 @@ const gchar *_class_get_comment(GtkTextView *);
 void _class_set_comment(GtkTextView *, gchar *);
 
 void _attributes_get_current_values(UMLClassDialog *prop_dialog);
-void _operations_get_current_values(UMLClassDialog *prop_dialog);
 void _templates_get_current_values(UMLClassDialog *prop_dialog);
 
 void _attributes_fill_in_dialog(UMLClass *umlclass);
-void _operations_fill_in_dialog(UMLClass *umlclass);
 void _templates_fill_in_dialog(UMLClass *umlclass);
 
 void _attributes_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog, int connection_index);
@@ -108,43 +109,3 @@ void _templates_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog
 void _attributes_create_page(GtkNotebook *notebook,  UMLClass *umlclass);
 void _operations_create_page(GtkNotebook *notebook,  UMLClass *umlclass);
 void _templates_create_page(GtkNotebook *notebook,  UMLClass *umlclass);
-
-#define DIA_UML_TYPE_OPERATION_DIALOG (dia_uml_operation_dialog_get_type ())
-G_DECLARE_FINAL_TYPE (DiaUmlOperationDialog, dia_uml_operation_dialog, DIA_UML, OPERATION_DIALOG, GtkDialog)
-
-struct _DiaUmlOperationDialog {
-  GtkDialog parent;
-
-  GtkWidget *name;
-  GtkWidget *type;
-  GtkWidget *stereotype;
-  GtkWidget *visibility;
-  GtkWidget *inheritance;
-  GtkWidget *scope;
-  GtkWidget *query;
-  GtkTextBuffer *comment;
-  GtkWidget *list;
-
-  DiaUmlOperation *operation;
-};
-
-GtkWidget *dia_uml_operation_dialog_new (GtkWindow       *parent,
-                                         DiaUmlOperation *op);
-
-#define DIA_UML_TYPE_OPERATION_PARAMETER_ROW (dia_uml_operation_parameter_row_get_type ())
-G_DECLARE_FINAL_TYPE (DiaUmlOperationParameterRow, dia_uml_operation_parameter_row, DIA_UML, 
OPERATION_PARAMETER_ROW, GtkListBoxRow)
-
-struct _DiaUmlOperationParameterRow {
-  GtkListBoxRow parent;
-
-  GtkWidget *name;
-  GtkWidget *type;
-  GtkWidget *value;
-  GtkWidget *direction;
-  GtkTextBuffer *comment;
-
-  DiaUmlParameter *parameter;
-};
-
-GtkWidget       *dia_uml_operation_parameter_row_new           (DiaUmlParameter             *parameter);
-DiaUmlParameter *dia_uml_operation_parameter_row_get_parameter (DiaUmlOperationParameterRow *self);
diff --git a/objects/UML/class_operations_dialog.c b/objects/UML/class_operations_dialog.c
index b4e58e3f..befe80f8 100644
--- a/objects/UML/class_operations_dialog.c
+++ b/objects/UML/class_operations_dialog.c
@@ -18,1659 +18,112 @@
  */
 #include <config.h>
 
-#include <assert.h>
 #include <gtk/gtk.h>
 
 #include "class.h"
-#include "diaoptionmenu.h"
-
 #include "class_dialog.h"
 #include "dia_dirs.h"
-
-G_DEFINE_TYPE (DiaUmlOperationParameterRow, dia_uml_operation_parameter_row, GTK_TYPE_LIST_BOX_ROW)
-
-enum {
-  UML_OP_PROW_PROP_PARAMETER = 1,
-  UML_OP_PROW_N_PROPS
-};
-static GParamSpec* uml_op_prow_properties[UML_OP_PROW_N_PROPS];
-
-static void
-dia_uml_operation_parameter_row_finalize (GObject *object)
-{
-  DiaUmlOperationParameterRow *self = DIA_UML_OPERATION_PARAMETER_ROW (object);
-
-  g_object_unref (G_OBJECT (self->parameter));
-}
-
-gboolean
-direction_to (GBinding *binding,
-              const GValue *from_value,
-              GValue *to_value,
-              gpointer user_data)
-{
-  gchar *name = g_value_get_string (from_value);
-
-  if (g_strcmp0 (name, "in") == 0) {
-    g_value_set_int (to_value, UML_IN);
-  } else if (g_strcmp0 (name, "out") == 0) {
-    g_value_set_int (to_value, UML_OUT);
-  } else if (g_strcmp0 (name, "inout") == 0) {
-    g_value_set_int (to_value, UML_INOUT);
-  } else {
-    g_value_set_int (to_value, UML_UNDEF_KIND);
-  }
-  
-  return TRUE;
-}
-
-gboolean
-direction_from (GBinding *binding,
-                const GValue *from_value,
-                GValue *to_value,
-                gpointer user_data)
-{
-  int mode = g_value_get_int (from_value);
-
-  if (mode == UML_IN) {
-    g_value_set_static_string (to_value, "in");
-  } else if (mode == UML_OUT) {
-    g_value_set_static_string (to_value, "out");
-  } else if (mode == UML_INOUT) {
-    g_value_set_static_string (to_value, "inout");
-  } else {
-    g_value_set_static_string (to_value, "undefined");
-  }
-  
-  return TRUE;
-}
-
-static void
-dia_uml_operation_parameter_row_set_property (GObject      *object,
-                                       guint         property_id,
-                                       const GValue *value,
-                                       GParamSpec   *pspec)
-{
-  DiaUmlOperationParameterRow *self = DIA_UML_OPERATION_PARAMETER_ROW (object);
-  switch (property_id) {
-    case UML_OP_PROW_PROP_PARAMETER:
-      self->parameter = g_value_dup_object (value);
-      g_object_bind_property (G_OBJECT (self->parameter), "name",
-                              G_OBJECT (self->name), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-      g_object_bind_property (G_OBJECT (self->parameter), "type",
-                              G_OBJECT (self->type), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-      g_object_bind_property (G_OBJECT (self->parameter), "value",
-                              G_OBJECT (self->value), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
-      g_object_bind_property_full (G_OBJECT (self->parameter), "kind",
-                                   G_OBJECT (self->direction), "active-id",
-                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
-                                   direction_from,
-                                   direction_to,
-                                   NULL, NULL);
-
-      g_object_bind_property (G_OBJECT (self->parameter), "comment",
-                              G_OBJECT (self->comment), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-  }
-}
-
-static void
-dia_uml_operation_parameter_row_get_property (GObject    *object,
-                                              guint       property_id,
-                                              GValue     *value,
-                                              GParamSpec *pspec)
-{
-  DiaUmlOperationParameterRow *self = DIA_UML_OPERATION_PARAMETER_ROW (object);
-  switch (property_id) {
-    case UML_OP_PROW_PROP_PARAMETER:
-      g_value_set_object (value, self->parameter);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-  }
-}
-
-static void
-dia_uml_operation_parameter_row_class_init (DiaUmlOperationParameterRowClass *klass)
-{
-  GFile *template_file;
-  GBytes *template;
-  GError *err = NULL;
-  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
-  object_class->finalize = dia_uml_operation_parameter_row_finalize;
-  object_class->set_property = dia_uml_operation_parameter_row_set_property;
-  object_class->get_property = dia_uml_operation_parameter_row_get_property;
-
-  uml_op_prow_properties[UML_OP_PROW_PROP_PARAMETER] =
-    g_param_spec_object ("parameter",
-                         "Parameter",
-                         "Parameter this editor controls",
-                         DIA_UML_TYPE_PARAMETER,
-                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
-  g_object_class_install_properties (object_class,
-                                     UML_OP_PROW_N_PROPS,
-                                     uml_op_prow_properties);
-
-  /* TODO: Use GResource */
-  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-operation-parameter-row.ui"));
-  template = g_file_load_bytes (template_file, NULL, NULL, &err);
-
-  if (err)
-    g_critical ("Failed to load template: %s", err->message);
-
-  gtk_widget_class_set_template (widget_class, template);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, name);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, type);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, value);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, direction);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, comment);
-
-  g_object_unref (template_file);
-}
-
-static void
-dia_uml_operation_parameter_row_init (DiaUmlOperationParameterRow *self)
-{
-  gtk_widget_init_template (GTK_WIDGET (self));
-}
-
-GtkWidget *
-dia_uml_operation_parameter_row_new (DiaUmlParameter *op)
-{
-  return g_object_new (DIA_UML_TYPE_OPERATION_PARAMETER_ROW,
-                       "parameter", op, 
-                       NULL);
-}
-
-G_DEFINE_TYPE (DiaUmlOperationDialog, dia_uml_operation_dialog, GTK_TYPE_DIALOG)
-
-enum {
-  UML_OP_DLG_PROP_OPERATION = 1,
-  UML_OP_DLG_N_PROPS
-};
-static GParamSpec* uml_op_dlg_properties[UML_OP_DLG_N_PROPS];
-
-static void
-dia_uml_operation_dialog_finalize (GObject *object)
-{
-  DiaUmlOperationDialog *self = DIA_UML_OPERATION_DIALOG (object);
-
-  g_object_unref (G_OBJECT (self->operation));
-}
-
-gboolean
-visibility_to (GBinding *binding,
-               const GValue *from_value,
-               GValue *to_value,
-               gpointer user_data)
-{
-  gchar *name = g_value_get_string (from_value);
-
-  if (g_strcmp0 (name, "private") == 0) {
-    g_value_set_int (to_value, UML_PRIVATE);
-  } else if (g_strcmp0 (name, "protected") == 0) {
-    g_value_set_int (to_value, UML_PROTECTED);
-  } else if (g_strcmp0 (name, "implementation") == 0) {
-    g_value_set_int (to_value, UML_IMPLEMENTATION);
-  } else {
-    g_value_set_int (to_value, UML_PUBLIC);
-  }
-  
-  return TRUE;
-}
-
-gboolean
-visibility_from (GBinding *binding,
-                 const GValue *from_value,
-                 GValue *to_value,
-                 gpointer user_data)
-{
-  int mode = g_value_get_int (from_value);
-
-  if (mode == UML_ABSTRACT) {
-    g_value_set_static_string (to_value, "abstract");
-  } else if (mode == UML_POLYMORPHIC) {
-    g_value_set_static_string (to_value, "poly");
-  } else {
-    g_value_set_static_string (to_value, "leaf");
-  }
-  
-  return TRUE;
-}
-
-gboolean
-inheritance_to (GBinding *binding,
-                const GValue *from_value,
-                GValue *to_value,
-                gpointer user_data)
-{
-  gchar *name = g_value_get_string (from_value);
-
-  if (g_strcmp0 (name, "abstract") == 0) {
-    g_value_set_int (to_value, UML_ABSTRACT);
-  } else if (g_strcmp0 (name, "poly") == 0) {
-    g_value_set_int (to_value, UML_POLYMORPHIC);
-  } else {
-    g_value_set_int (to_value, UML_LEAF);
-  }
-  
-  return TRUE;
-}
-
-gboolean
-inheritance_from (GBinding *binding,
-                  const GValue *from_value,
-                  GValue *to_value,
-                  gpointer user_data)
-{
-  int mode = g_value_get_int (from_value);
-
-  if (mode == UML_PRIVATE) {
-    g_value_set_static_string (to_value, "private");
-  } else if (mode == UML_PROTECTED) {
-    g_value_set_static_string (to_value, "protected");
-  } else if (mode == UML_IMPLEMENTATION) {
-    g_value_set_static_string (to_value, "implementation");
-  } else {
-    g_value_set_static_string (to_value, "public");
-  }
-  
-  return TRUE;
-}
-
-static void
-dia_uml_operation_dialog_set_property (GObject      *object,
-                                       guint         property_id,
-                                       const GValue *value,
-                                       GParamSpec   *pspec)
-{
-  DiaUmlOperationDialog *self = DIA_UML_OPERATION_DIALOG (object);
-  GList *paras;
-  GtkWidget *row;
-
-  switch (property_id) {
-    case UML_OP_DLG_PROP_OPERATION:
-      self->operation = g_value_dup_object (value);
-      g_object_bind_property (G_OBJECT (self->operation), "name",
-                              G_OBJECT (self->name), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-      g_object_bind_property (G_OBJECT (self->operation), "type",
-                              G_OBJECT (self->type), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-      g_object_bind_property (G_OBJECT (self->operation), "stereotype",
-                              G_OBJECT (self->stereotype), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-      g_object_bind_property (G_OBJECT (self->operation), "comment",
-                              G_OBJECT (self->comment), "text",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
-      g_object_bind_property_full (G_OBJECT (self->operation), "visibility",
-                                   G_OBJECT (self->visibility), "active-id",
-                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
-                                   visibility_from,
-                                   visibility_to,
-                                   NULL, NULL);
-
-      g_object_bind_property_full (G_OBJECT (self->operation), "inheritance-type",
-                                   G_OBJECT (self->inheritance), "active-id",
-                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
-                                   inheritance_from,
-                                   inheritance_to,
-                                   NULL, NULL);
-
-      g_object_bind_property (G_OBJECT (self->operation), "query",
-                              G_OBJECT (self->query), "active",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-      g_object_bind_property (G_OBJECT (self->operation), "class-scope",
-                              G_OBJECT (self->scope), "active",
-                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
-      paras = dia_uml_operation_get_parameters (self->operation);
-      for (; paras != NULL; paras = g_list_next (paras)) {
-        // do something with l->data
-        row = dia_uml_operation_parameter_row_new (DIA_UML_PARAMETER (paras->data));
-        gtk_widget_show (row);
-        gtk_container_add (GTK_CONTAINER (self->list), row);
-      }
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-  }
-}
-
-static void
-dia_uml_operation_dialog_get_property (GObject    *object,
-                                       guint       property_id,
-                                       GValue     *value,
-                                       GParamSpec *pspec)
-{
-  DiaUmlOperationDialog *self = DIA_UML_OPERATION_DIALOG (object);
-  switch (property_id) {
-    case UML_OP_DLG_PROP_OPERATION:
-      g_value_set_object (value, self->operation);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-      break;
-  }
-}
-
-static void
-dlg_add_parameter (DiaUmlOperationDialog *self)
-{
-  GtkWidget *row = dia_uml_operation_parameter_row_new (dia_uml_parameter_new ());
-
-  g_assert (DIA_UML_IS_OPERATION_DIALOG (self));
-  gtk_widget_show (row);
-  gtk_container_add (GTK_CONTAINER (self->list), row);
-}
-
-static void
-parameter_added (DiaUmlOperationDialog *self,
-                 GtkWidget             *row)
-{
-  DiaUmlParameter *para = NULL;
-  int index;
-
-  if (!DIA_UML_IS_OPERATION_PARAMETER_ROW (row))
-    return;
-
-  g_object_get (G_OBJECT (row),
-                "parameter", &para,
-                NULL);
-  index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row));
-
-  dia_uml_operation_insert_parameter (self->operation, para, index);
-}
-
-static void
-parameter_removed (DiaUmlOperationDialog *self,
-                   GtkWidget             *row)
-{
-  DiaUmlParameter *para = NULL;
-
-  if (!DIA_UML_IS_OPERATION_PARAMETER_ROW (row) || gtk_widget_in_destruction (GTK_WIDGET (self)))
-    return;
-
-  g_object_get (G_OBJECT (row),
-                "parameter", &para,
-                NULL);
-
-  dia_uml_operation_remove_parameter (self->operation, para);
-}
-
-static void
-dia_uml_operation_dialog_class_init (DiaUmlOperationDialogClass *klass)
-{
-  GFile *template_file;
-  GBytes *template;
-  GError *err = NULL;
-  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
-  object_class->finalize = dia_uml_operation_dialog_finalize;
-  object_class->set_property = dia_uml_operation_dialog_set_property;
-  object_class->get_property = dia_uml_operation_dialog_get_property;
-
-  uml_op_dlg_properties[UML_OP_DLG_PROP_OPERATION] =
-    g_param_spec_object ("operation",
-                         "Operation",
-                         "Operation this editor controls",
-                         DIA_UML_TYPE_OPERATION,
-                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
-  g_object_class_install_properties (object_class,
-                                     UML_OP_DLG_N_PROPS,
-                                     uml_op_dlg_properties);
-
-  /* TODO: Use GResource */
-  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-operation-dialog.ui"));
-  template = g_file_load_bytes (template_file, NULL, NULL, &err);
-
-  if (err)
-    g_critical ("Failed to load template: %s", err->message);
-
-  gtk_widget_class_set_template (widget_class, template);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, name);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, type);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, stereotype);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, visibility);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, inheritance);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, scope);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, query);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, comment);
-  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, list);
-  gtk_widget_class_bind_template_callback (widget_class, dlg_add_parameter);
-  gtk_widget_class_bind_template_callback (widget_class, parameter_added);
-  gtk_widget_class_bind_template_callback (widget_class, parameter_removed);
-
-  g_object_unref (template_file);
-}
-
-static void
-dia_uml_operation_dialog_init (DiaUmlOperationDialog *self)
-{
-  GtkWidget *box;
-  GtkWidget *widget;
-
-  gtk_widget_init_template (GTK_WIDGET (self));
-
-  box = g_object_new (GTK_TYPE_BOX,
-                      "orientation", GTK_ORIENTATION_VERTICAL,
-                      "spacing", 16,
-                      "margin", 16,
-                      NULL);
-  gtk_widget_show (box);
-
-  widget = gtk_label_new ("No parameters");
-  gtk_widget_show (widget);
-  gtk_container_add (GTK_CONTAINER (box), widget);
-
-  gtk_list_box_set_placeholder (GTK_LIST_BOX (self->list), box);
-}
-
-GtkWidget *
-dia_uml_operation_dialog_new (GtkWindow       *parent,
-                              DiaUmlOperation *op)
-{
-  return g_object_new (DIA_UML_TYPE_OPERATION_DIALOG,
-                       "operation", op,
-                       "transient-for", parent,
-                       "modal", TRUE,
-                       NULL);
-}
+#include "editor/dia-uml-class-editor.h"
+#include "dia-uml-class.h"
 
 /*************************************************************
  ******************** OPERATIONS *****************************
  *************************************************************/
 
-static void
-parameters_set_sensitive(UMLClassDialog *prop_dialog, gint val)
-{
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_name), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_type), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_value), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_comment), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_kind), val);
-}
-
-static void
-parameters_set_values(UMLClassDialog *prop_dialog, DiaUmlParameter *param)
-{
-  gtk_entry_set_text(prop_dialog->param_name, param->name);
-  gtk_entry_set_text(prop_dialog->param_type, param->type);
-  if (param->value != NULL)
-    gtk_entry_set_text(prop_dialog->param_value, param->value);
-  else
-    gtk_entry_set_text(prop_dialog->param_value, "");
-  if (param->comment != NULL)
-    _class_set_comment(prop_dialog->param_comment, param->comment);
-  else
-    _class_set_comment(prop_dialog->param_comment, "");
-
-  dia_option_menu_set_active(prop_dialog->param_kind, param->kind);
-}
-
-static void
-parameters_clear_values(UMLClassDialog *prop_dialog)
-{
-  gtk_entry_set_text(prop_dialog->param_name, "");
-  gtk_entry_set_text(prop_dialog->param_type, "");
-  gtk_entry_set_text(prop_dialog->param_value, "");
-  _class_set_comment(prop_dialog->param_comment, "");
-  dia_option_menu_set_active(prop_dialog->param_kind, UML_UNDEF_KIND);
-
-}
-
-static void
-parameters_get_values (UMLClassDialog *prop_dialog, DiaUmlParameter *param)
-{
-  g_free(param->name);
-  g_free(param->type);
-  g_free(param->comment);
-  if (param->value != NULL)
-    g_free(param->value);
-  
-  param->name = g_strdup (gtk_entry_get_text (prop_dialog->param_name));
-  param->type = g_strdup (gtk_entry_get_text (prop_dialog->param_type));
-  
-  param->value = g_strdup (gtk_entry_get_text(prop_dialog->param_value));
-  param->comment = g_strdup (_class_get_comment(prop_dialog->param_comment));
-
-  param->kind = (UMLParameterKind) dia_option_menu_get_active(prop_dialog->param_kind);
-}
-
-static void
-parameters_get_current_values(UMLClassDialog *prop_dialog)
-{
-  DiaUmlParameter *current_param;
-  GtkLabel *label;
-  char *new_str;
-
-  if (prop_dialog->current_param != NULL) {
-    current_param = (DiaUmlParameter *)
-      g_object_get_data(G_OBJECT(prop_dialog->current_param), "user_data");
-    if (current_param != NULL) {
-      parameters_get_values(prop_dialog, current_param);
-      label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(prop_dialog->current_param)));
-      new_str = dia_uml_parameter_format(current_param);
-      gtk_label_set_text(label, new_str);
-      g_free(new_str);
-    }
-  }
-}
-
-
-static void
-parameters_list_selection_changed_callback(GtkWidget *gtklist,
-                                          UMLClass *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  GObject *list_item;
-  DiaUmlParameter *param;
-
-  prop_dialog = umlclass->properties_dialog;
-
-  if (!prop_dialog)
-    return; /* maybe hiding a bug elsewhere */
-
-  parameters_get_current_values(prop_dialog);
-  
-  list_item = dia_list_get_selection (DIA_LIST (gtklist));
-  if (!list_item) { /* No selected */
-    parameters_set_sensitive(prop_dialog, FALSE);
-    parameters_clear_values(prop_dialog);
-    prop_dialog->current_param = NULL;
-    return;
-  }
-  
-  param = (DiaUmlParameter *)g_object_get_data(G_OBJECT(list_item), "user_data");
-  parameters_set_values(prop_dialog, param);
-  parameters_set_sensitive(prop_dialog, TRUE);
-
-  prop_dialog->current_param = DIA_LIST_ITEM(list_item);
-  gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->param_name));
-}
-
-static void
-parameters_list_new_callback(GtkWidget *button,
-                            UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  GtkWidget *list_item;
-  DiaUmlOperation *current_op;
-  DiaUmlParameter *param;
-  char *utf;
-
-  prop_dialog = umlclass->properties_dialog;
-
-  parameters_get_current_values(prop_dialog);
-
-  current_op = (DiaUmlOperation *)
-    g_object_get_data(G_OBJECT(prop_dialog->current_op), "user_data");
-  
-  param = dia_uml_parameter_new();
-
-  utf = dia_uml_parameter_format (param);
-  list_item = dia_list_item_new_with_label (utf);
-  gtk_widget_show (list_item);
-  g_free (utf);
-
-  g_object_set_data(G_OBJECT(list_item), "user_data", param);
-
-  current_op->parameters = g_list_append(current_op->parameters,
-                                        (gpointer) param);
-  
-  list = g_list_append(NULL, list_item);
-  dia_list_append_items(prop_dialog->parameters_list, list);
-
-  if (dia_list_get_children (DIA_LIST (prop_dialog->parameters_list)) != NULL)
-    dia_list_unselect_child(prop_dialog->parameters_list,
-                           GTK_WIDGET(dia_list_get_children (DIA_LIST 
(prop_dialog->parameters_list))->data));
-  dia_list_select_child(prop_dialog->parameters_list, list_item);
-
-  prop_dialog->current_param = DIA_LIST_ITEM(list_item);
-}
-
-static void
-parameters_list_delete_callback(GtkWidget *button,
-                               UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  DiaUmlOperation *current_op;
-  DiaUmlParameter *param;
-  
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->parameters_list);
-
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    /* Remove from current operations parameter list: */
-    current_op = (DiaUmlOperation *)
-      g_object_get_data(G_OBJECT(prop_dialog->current_op), "user_data");
-    param = (DiaUmlParameter *)
-      g_object_get_data(G_OBJECT(prop_dialog->current_param), "user_data");
-    
-    current_op->parameters = g_list_remove(current_op->parameters,
-                                          (gpointer) param);
-    g_object_unref (G_OBJECT (param));
-    
-    /* Remove from gtk list: */
-    list = g_list_prepend(NULL, prop_dialog->current_param);
-
-    prop_dialog->current_param = NULL;
-
-    dia_list_remove_items(gtklist, list);
-    g_list_free(list);
-  }
-}
-
-static void
-parameters_list_move_up_callback(GtkWidget *button,
-                                UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  DiaListItem *list_item;
-  DiaUmlOperation *current_op;
-  DiaUmlParameter *param;
-  int i;
-  
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->parameters_list);
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    list_item = dia_list_get_selection (DIA_LIST (gtklist));
-    
-    i = dia_list_child_position(gtklist, list_item);
-    if (i>0)
-      i--;
-
-    param = (DiaUmlParameter *) g_object_get_data(G_OBJECT(list_item), "user_data");
-
-    /* Move parameter in current operations list: */
-    current_op = (DiaUmlOperation *)
-      g_object_get_data(G_OBJECT(prop_dialog->current_op), "user_data");
-    
-    current_op->parameters = g_list_remove(current_op->parameters,
-                                          (gpointer) param);
-    current_op->parameters = g_list_insert(current_op->parameters,
-                                          (gpointer) param,
-                                          i);
-
-    /* Move parameter in gtk list: */
-    g_object_ref(list_item);
-    list = g_list_prepend(NULL, list_item);
-    dia_list_remove_items(gtklist, list);
-    dia_list_insert_items(gtklist, list, i);
-    g_object_unref(list_item);
-
-    dia_list_select_child(gtklist, list_item);
-
-    _operations_get_current_values(prop_dialog);
-  }
-}
-
-static void
-parameters_list_move_down_callback(GtkWidget *button,
-                                  UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  DiaListItem *list_item;
-  DiaUmlOperation *current_op;
-  DiaUmlParameter *param;
-  int i;
-  
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->parameters_list);
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    list_item = dia_list_get_selection (DIA_LIST (gtklist));
-    
-    i = dia_list_child_position(gtklist, list_item);
-    if (i<(g_list_length(dia_list_get_children (DIA_LIST (gtklist)))-1))
-      i++;
-
-    param = (DiaUmlParameter *) g_object_get_data(G_OBJECT(list_item), "user_data");
-
-    /* Move parameter in current operations list: */
-    current_op = (DiaUmlOperation *)
-      g_object_get_data(G_OBJECT(prop_dialog->current_op), "user_data");
-    
-    current_op->parameters = g_list_remove(current_op->parameters,
-                                          (gpointer) param);
-    current_op->parameters = g_list_insert(current_op->parameters,
-                                          (gpointer) param,
-                                          i);
-
-    /* Move parameter in gtk list: */
-    g_object_ref(list_item);
-    list = g_list_prepend(NULL, list_item);
-    dia_list_remove_items(gtklist, list);
-    dia_list_insert_items(gtklist, list, i);
-    g_object_unref(list_item);
-
-    dia_list_select_child(gtklist, list_item);
-
-    _operations_get_current_values(prop_dialog);
-  }
-}
-
-static void
-operations_set_sensitive(UMLClassDialog *prop_dialog, gint val)
-{
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_name), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_type), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_stereotype), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_comment), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_visible), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_class_scope), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_inheritance_type), val);
-  gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_query), val);
-
-  gtk_widget_set_sensitive(prop_dialog->param_new_button, val);
-  gtk_widget_set_sensitive(prop_dialog->param_delete_button, val);
-  gtk_widget_set_sensitive(prop_dialog->param_down_button, val);
-  gtk_widget_set_sensitive(prop_dialog->param_up_button, val);
-}
-
-static void
-operations_set_values(UMLClassDialog *prop_dialog, DiaUmlOperation *op)
-{
-  GList *list;
-  DiaUmlParameter *param;
-  GtkWidget *list_item;
-  gchar *str;
-
-  gtk_entry_set_text(prop_dialog->op_name, op->name);
-  if (op->type != NULL)
-    gtk_entry_set_text(prop_dialog->op_type, op->type);
-  else
-    gtk_entry_set_text(prop_dialog->op_type, "");
-
-  if (op->stereotype != NULL)
-    gtk_entry_set_text(prop_dialog->op_stereotype, op->stereotype);
-  else
-    gtk_entry_set_text(prop_dialog->op_stereotype, "");
-
-  if (op->comment != NULL)
-    _class_set_comment(prop_dialog->op_comment, op->comment);
-  else
-    _class_set_comment(prop_dialog->op_comment, "");
-
-  dia_option_menu_set_active(prop_dialog->op_visible, op->visibility);
-  gtk_toggle_button_set_active(prop_dialog->op_class_scope, op->class_scope);
-  gtk_toggle_button_set_active(prop_dialog->op_query, op->query);
-  dia_option_menu_set_active(prop_dialog->op_inheritance_type, op->inheritance_type);
-
-  dia_list_empty (prop_dialog->parameters_list);
-  prop_dialog->current_param = NULL;
-  parameters_set_sensitive(prop_dialog, FALSE);
-
-  list = op->parameters;
-  while (list != NULL) {
-    param = (DiaUmlParameter *)list->data;
-
-    str = dia_uml_parameter_format (param);
-    list_item = dia_list_item_new_with_label (str);
-    g_free (str);
-
-    g_object_set_data(G_OBJECT(list_item), "user_data", (gpointer) param);
-    gtk_container_add (GTK_CONTAINER (prop_dialog->parameters_list), list_item);
-    gtk_widget_show (list_item);
-    
-    list = g_list_next(list);
-  }
-}
-
-static void
-operations_clear_values(UMLClassDialog *prop_dialog)
-{
-  gtk_entry_set_text(prop_dialog->op_name, "");
-  gtk_entry_set_text(prop_dialog->op_type, "");
-  gtk_entry_set_text(prop_dialog->op_stereotype, "");
-  _class_set_comment(prop_dialog->op_comment, "");
-  gtk_toggle_button_set_active(prop_dialog->op_class_scope, FALSE);
-  gtk_toggle_button_set_active(prop_dialog->op_query, FALSE);
-
-  dia_list_empty (prop_dialog->parameters_list);
-  prop_dialog->current_param = NULL;
-  parameters_set_sensitive(prop_dialog, FALSE);
-}
-
-
-static void
-operations_get_values(UMLClassDialog *prop_dialog, DiaUmlOperation *op)
-{
-  const gchar *s;
-
-  g_free(op->name);
-  if (op->type != NULL)
-         g_free(op->type);
-
-  op->name = g_strdup(gtk_entry_get_text(prop_dialog->op_name));
-  op->type = g_strdup (gtk_entry_get_text(prop_dialog->op_type));
-  op->comment = g_strdup(_class_get_comment(prop_dialog->op_comment));
-
-  s = gtk_entry_get_text(prop_dialog->op_stereotype);
-  if (s && s[0])
-    op->stereotype = g_strdup (s);
-  else
-    op->stereotype = NULL;
-
-  op->visibility = (UMLVisibility)dia_option_menu_get_active(prop_dialog->op_visible);
-    
-  op->class_scope = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_class_scope));
-  op->inheritance_type = (UMLInheritanceType)dia_option_menu_get_active(prop_dialog->op_inheritance_type);
-
-  op->query = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_query));
-
-}
-
 void
-_operations_get_current_values(UMLClassDialog *prop_dialog)
-{
-  DiaUmlOperation *current_op;
-  GtkLabel *label;
-  char *new_str;
-
-  parameters_get_current_values(prop_dialog);
-
-  if (prop_dialog->current_op != NULL) {
-    current_op = (DiaUmlOperation *)
-      g_object_get_data(G_OBJECT(prop_dialog->current_op), "user_data");
-    if (current_op != NULL) {
-      operations_get_values(prop_dialog, current_op);
-      label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(prop_dialog->current_op)));
-      new_str = dia_uml_operation_format(current_op);
-      gtk_label_set_text (label, new_str);
-      g_free (new_str);
-    }
-  }
-}
-
-static void
-operations_list_item_destroy_callback(GtkWidget *list_item,
-                                     gpointer data)
-{
-  DiaUmlOperation *op;
-
-  op = (DiaUmlOperation *) g_object_get_data(G_OBJECT(list_item), "user_data");
-
-  if (op != NULL) {
-    g_object_unref (G_OBJECT (op));
-    /*printf("Destroying operation list_item's user_data!\n");*/
-  }
-}
-
-static void
-operations_list_selection_changed_callback(GtkWidget *gtklist,
-                                          UMLClass *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  GObject *list_item;
-  DiaUmlOperation *op;
-
-  prop_dialog = umlclass->properties_dialog;
-
-  if (!prop_dialog)
-    return; /* maybe hiding a bug elsewhere */
-
-  _operations_get_current_values(prop_dialog);
-  
-  list_item = dia_list_get_selection (DIA_LIST (gtklist));
-  if (!list_item) { /* No selected */
-    operations_set_sensitive(prop_dialog, FALSE);
-    operations_clear_values(prop_dialog);
-    prop_dialog->current_op = NULL;
-    return;
-  }
-  
-  op = (DiaUmlOperation *)g_object_get_data(G_OBJECT(list_item), "user_data");
-  operations_set_values(prop_dialog, op);
-  operations_set_sensitive(prop_dialog, TRUE);
-
-  prop_dialog->current_op = DIA_LIST_ITEM(list_item);
-  gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->op_name));
-}
-
-static void
-operations_list_new_callback(GtkWidget *button,
-                            UMLClass *umlclass)
+_operations_read_from_dialog (UMLClass *umlclass,
+                              UMLClassDialog *prop_dialog,
+                              int connection_index)
 {
   GList *list;
-  UMLClassDialog *prop_dialog;
-  GtkWidget *list_item;
   DiaUmlOperation *op;
-  char *utfstr;
-
-  prop_dialog = umlclass->properties_dialog;
-
-  _operations_get_current_values(prop_dialog);
-
-  op = dia_uml_operation_new();
-  /* need to make new ConnectionPoints valid and remember them */
-  dia_uml_operation_ensure_connection_points (op, &umlclass->element.object);
-  prop_dialog->added_connections = 
-    g_list_prepend(prop_dialog->added_connections, op->left_connection);
-  prop_dialog->added_connections = 
-    g_list_prepend(prop_dialog->added_connections, op->right_connection);
-
-
-  utfstr = dia_uml_operation_format (op);
-  list_item = dia_list_item_new_with_label (utfstr);
-  gtk_widget_show (list_item);
-  g_free (utfstr);
-
-  g_object_set_data(G_OBJECT(list_item), "user_data", op);
-  g_signal_connect (G_OBJECT (list_item), "destroy",
-                   G_CALLBACK (operations_list_item_destroy_callback), NULL);
-  
-  list = g_list_append(NULL, list_item);
-  dia_list_append_items(prop_dialog->operations_list, list);
-
-  if (dia_list_get_children (DIA_LIST (prop_dialog->operations_list)) != NULL)
-    dia_list_unselect_child(prop_dialog->operations_list,
-                           GTK_WIDGET(dia_list_get_children (DIA_LIST 
(prop_dialog->operations_list))->data));
-  dia_list_select_child(prop_dialog->operations_list, list_item);
-}
-
-static void
-operations_list_delete_callback(GtkWidget *button,
-                               UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  DiaUmlOperation *op;
-  
-
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->operations_list);
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    op = (DiaUmlOperation *)
-      g_object_get_data (G_OBJECT (dia_list_get_selection (DIA_LIST (gtklist))), "user_data");
-
-    if (op->left_connection != NULL) {
-      prop_dialog->deleted_connections =
-       g_list_prepend(prop_dialog->deleted_connections,
-                      op->left_connection);
-      prop_dialog->deleted_connections =
-       g_list_prepend(prop_dialog->deleted_connections,
-                      op->right_connection);
-    }
-
-    list = g_list_prepend(NULL, dia_list_get_selection (DIA_LIST (gtklist)));
-    dia_list_remove_items(gtklist, list);
-    g_list_free(list);
-    operations_clear_values(prop_dialog);
-    operations_set_sensitive(prop_dialog, FALSE);
-  }
-}
-
-static void
-operations_list_edit_callback (GtkWidget *button,
-                               UMLClass  *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  DiaUmlOperation *op;
-  GtkWidget *edit;
-  
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->operations_list);
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    op = (DiaUmlOperation *)
-      g_object_get_data (G_OBJECT (dia_list_get_selection (DIA_LIST (gtklist))), "user_data");
-
-    edit = dia_uml_operation_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (prop_dialog->dialog)), op);
-    gtk_widget_show (edit);
-  }
-}
-
-static void
-operations_list_move_up_callback(GtkWidget *button,
-                                UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  GtkWidget *list_item;
-  int i;
-  
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->operations_list);
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    DiaListItem *list_item = dia_list_get_selection (DIA_LIST (gtklist));
-    
-    i = dia_list_child_position (gtklist, list_item);
-    if (i>0)
-      i--;
-
-    g_object_ref(list_item);
-    list = g_list_prepend (NULL, list_item);
-    dia_list_remove_items (gtklist, list);
-    dia_list_insert_items (gtklist, list, i);
-    g_object_unref (list_item);
-
-    dia_list_select_child (gtklist, list_item);
-  }
-
-}
-
-static void
-operations_list_move_down_callback(GtkWidget *button,
-                                  UMLClass *umlclass)
-{
-  GList *list;
-  UMLClassDialog *prop_dialog;
-  DiaList *gtklist;
-  DiaListItem *list_item;
-  int i;
-  
-  prop_dialog = umlclass->properties_dialog;
-  gtklist = DIA_LIST(prop_dialog->operations_list);
-
-  if (dia_list_get_selection (DIA_LIST (gtklist)) != NULL) {
-    list_item = dia_list_get_selection (DIA_LIST (gtklist));
-    
-    i = dia_list_child_position(gtklist, list_item);
-    if (i<(g_list_length(dia_list_get_children (DIA_LIST (gtklist)))-1))
-      i++;
-
-    g_object_ref(list_item);
-    list = g_list_prepend(NULL, list_item);
-    dia_list_remove_items(gtklist, list);
-    dia_list_insert_items(gtklist, list, i);
-    g_object_unref(list_item);
-
-    dia_list_select_child(gtklist, list_item);
-  }
-}
-
-void
-_operations_read_from_dialog(UMLClass *umlclass,
-                           UMLClassDialog *prop_dialog,
-                           int connection_index)
-{
-  GList *list;
-  DiaUmlOperation *op;
-  GtkWidget *list_item;
-  GList *clear_list;
   DiaObject *obj;
+  DiaUmlClass *editor_state;
+  gboolean op_visible = TRUE;
 
+  /* Cast to DiaObject (UMLClass -> Element -> DiaObject) */
   obj = &umlclass->element.object;
 
-  /* if currently select op is changed in the entries, update from widgets */
-  _operations_get_current_values(prop_dialog);
+  editor_state = dia_uml_class_editor_get_class (DIA_UML_CLASS_EDITOR (umlclass->properties_dialog->editor));
 
   /* Free current operations: */
+  /* Clear those already stored */
   list = umlclass->operations;
   while (list != NULL) {
-    op = (DiaUmlOperation *)list->data;
-    g_object_unref (G_OBJECT (op));
+    op = list->data;
+    g_object_unref (op);
     list = g_list_next(list);
   }
   g_list_free (umlclass->operations);
   umlclass->operations = NULL;
 
+  /* If operations visible and not suppressed */
+  op_visible = ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_vis ))) &&
+               (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_supp)));
+
+  list = dia_uml_class_get_operations (editor_state);
   /* Insert new operations and remove them from gtklist: */
-  list =dia_list_get_children (DIA_LIST (prop_dialog->operations_list));
-  clear_list = NULL;
   while (list != NULL) {
-    list_item = GTK_WIDGET(list->data);
-    
-    clear_list = g_list_prepend (clear_list, list_item);
-    op = (DiaUmlOperation *)
-      g_object_get_data(G_OBJECT(list_item), "user_data");
-    g_object_set_data(G_OBJECT(list_item), "user_data", NULL);
-    umlclass->operations = g_list_append(umlclass->operations, op);
+    op = list->data;
     
-    if (op->left_connection == NULL) {
+    umlclass->operations = g_list_append(umlclass->operations, g_object_ref (op));
+
+    if (op->l_connection == NULL) {
       dia_uml_operation_ensure_connection_points (op, obj);
       
-      prop_dialog->added_connections =
-       g_list_prepend(prop_dialog->added_connections,
-                      op->left_connection);
-      prop_dialog->added_connections =
-       g_list_prepend(prop_dialog->added_connections,
-                      op->right_connection);
+      prop_dialog->added_connections = g_list_prepend (prop_dialog->added_connections,
+                                                       op->l_connection);
+      prop_dialog->added_connections = g_list_prepend (prop_dialog->added_connections,
+                                                       op->r_connection);
     }
-    
-    if ( (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_vis))) &&
-        (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->op_supp))) ) { 
-      obj->connections[connection_index] = op->left_connection;
+
+    if (op_visible) { 
+      obj->connections[connection_index] = op->l_connection;
       connection_index++;
-      obj->connections[connection_index] = op->right_connection;
+      obj->connections[connection_index] = op->r_connection;
       connection_index++;
     } else {
-      _umlclass_store_disconnects(prop_dialog, op->left_connection);
-      object_remove_connections_to(op->left_connection);
-      _umlclass_store_disconnects(prop_dialog, op->right_connection);
-      object_remove_connections_to(op->right_connection);
+      _umlclass_store_disconnects(prop_dialog, op->l_connection);
+      object_remove_connections_to(op->l_connection);
+      _umlclass_store_disconnects(prop_dialog, op->r_connection);
+      object_remove_connections_to(op->r_connection);
     }
-    
-    list = g_list_next(list);
-  }
-  clear_list = g_list_reverse (clear_list);
-  dia_list_remove_items (DIA_LIST (prop_dialog->operations_list), clear_list);
-  g_list_free (clear_list);
-}
-
-void
-_operations_fill_in_dialog(UMLClass *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  DiaUmlOperation *op_copy;
-  GtkWidget *list_item;
-  GList *list;
-  int i;
-
-  prop_dialog = umlclass->properties_dialog;
 
-  if (dia_list_get_children (DIA_LIST (prop_dialog->operations_list)) == NULL) {
-    i = 0;
-    list = umlclass->operations;
-    while (list != NULL) {
-      DiaUmlOperation *op = (DiaUmlOperation *)list->data;
-      gchar *opstr = dia_uml_operation_format (op);
-
-      list_item = dia_list_item_new_with_label (opstr);
-      op_copy = dia_uml_operation_copy (op);
-      /* Looks wrong but is required for the complicate connections memory management */
-      op_copy->left_connection = op->left_connection;
-      op_copy->right_connection = op->right_connection;
-      g_object_set_data(G_OBJECT(list_item), "user_data", (gpointer) op_copy);
-      g_signal_connect (G_OBJECT (list_item), "destroy",
-                       G_CALLBACK (operations_list_item_destroy_callback), NULL);
-      gtk_container_add (GTK_CONTAINER (prop_dialog->operations_list), list_item);
-      gtk_widget_show (list_item);
-      
-      list = g_list_next(list); i++;
-      g_free (opstr);
-    }
-
-    /* set operations non-sensitive */
-    prop_dialog->current_op = NULL;
-    operations_set_sensitive(prop_dialog, FALSE);
-    operations_clear_values(prop_dialog);
+    list = g_list_next (list);
   }
 }
 
-static void
-operations_update(GtkWidget *widget, UMLClass *umlclass)
-{
-  _operations_get_current_values(umlclass->properties_dialog);
-}
-
-static int
-operations_update_event(GtkWidget *widget, GdkEventFocus *ev, UMLClass *umlclass)
-{
-  _operations_get_current_values(umlclass->properties_dialog);
-  return 0;
-}
-
-static GtkWidget*
-operations_data_create_hbox (UMLClass *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  GtkWidget *hbox;
-  GtkWidget *vbox2;
-  GtkWidget *table;
-  GtkWidget *label;
-  GtkWidget *entry;
-  GtkWidget *omenu;
-  GtkWidget *scrolledwindow;
-  GtkWidget *checkbox;
-
-  prop_dialog = umlclass->properties_dialog;
-
-  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
-  gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-
-  vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-
-  /* table containing operation 'name' up to 'query' and also the comment */
-  table = gtk_grid_new ();
-  gtk_grid_set_column_spacing (GTK_GRID (table), 5);
-  gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
-
-  label = gtk_label_new(_("Name:"));
-  entry = gtk_entry_new();
-  prop_dialog->op_name = GTK_ENTRY(entry);
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-  g_signal_connect (G_OBJECT (entry), "activate",
-                   G_CALLBACK (operations_update), umlclass);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
-
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_grid_attach (GTK_GRID (table), entry, 1, 0, 1, 1);
-
-  label = gtk_label_new(_("Type:"));
-  entry = gtk_entry_new();
-  prop_dialog->op_type = GTK_ENTRY(entry);
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-  g_signal_connect (G_OBJECT (entry), "activate",
-                   G_CALLBACK (operations_update), umlclass);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
-
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_grid_attach (GTK_GRID (table), entry, 1, 1, 1, 1);
-
-
-  label = gtk_label_new(_("Stereotype:"));
-  entry = gtk_entry_new();
-  prop_dialog->op_stereotype = GTK_ENTRY(entry);
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-  g_signal_connect (G_OBJECT (entry), "activate",
-                   G_CALLBACK (operations_update), umlclass);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
-
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_grid_attach (GTK_GRID (table), entry, 1, 2, 1, 1);
-
-
-  label = gtk_label_new(_("Visibility:"));
-
-  prop_dialog->op_visible = omenu = dia_option_menu_new ();
-  g_signal_connect (G_OBJECT (omenu), "changed",
-                   G_CALLBACK (operations_update), umlclass);
-  dia_option_menu_add_item(omenu, _("Public"), UML_PUBLIC);
-  dia_option_menu_add_item(omenu, _("Private"), UML_PRIVATE);
-  dia_option_menu_add_item(omenu, _("Protected"), UML_PROTECTED);
-  dia_option_menu_add_item(omenu, _("Implementation"), UML_IMPLEMENTATION);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 2, 0, 1, 1);
-
-  gtk_widget_set_hexpand (omenu, TRUE);
-  gtk_grid_attach (GTK_GRID (table), omenu, 3, 0, 1, 1);
-
-  /* end: Visibility */
-
-  label = gtk_label_new(_("Inheritance type:"));
-
-  prop_dialog->op_inheritance_type = omenu = dia_option_menu_new ();
-  g_signal_connect (G_OBJECT (omenu), "changed",
-                   G_CALLBACK (operations_update), umlclass);
-  dia_option_menu_add_item(omenu, _("Abstract"), UML_ABSTRACT);
-  dia_option_menu_add_item(omenu, _("Polymorphic (virtual)"), UML_POLYMORPHIC);
-  dia_option_menu_add_item(omenu, _("Leaf (final)"), UML_LEAF);
-
-  gtk_grid_attach (GTK_GRID (table), label, 2, 1, 1, 1);
-
-  gtk_widget_set_hexpand (omenu, TRUE);
-  gtk_grid_attach (GTK_GRID (table), omenu, 3, 1, 1, 1);
-
-  /* end: Inheritance type */
-
-  checkbox = gtk_check_button_new_with_label(_("Class scope"));
-  prop_dialog->op_class_scope = GTK_TOGGLE_BUTTON(checkbox);
-  gtk_grid_attach (GTK_GRID (table), checkbox, 2, 2, 1, 1);
-
-  checkbox = gtk_check_button_new_with_label(_("Query"));
-  prop_dialog->op_query = GTK_TOGGLE_BUTTON(checkbox);
-  gtk_grid_attach (GTK_GRID (table), checkbox, 3, 2, 1, 1);
-
-  label = gtk_label_new(_("Comment:"));
-  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN);
-  /* with GTK_POLICY_NEVER the comment filed gets smaller unti l text is entered; than it would resize the 
dialog! */
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, 
GTK_POLICY_AUTOMATIC);
-
-  entry = gtk_text_view_new ();
-  prop_dialog->op_comment = GTK_TEXT_VIEW(entry);
-  gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
-  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (entry), GTK_WRAP_WORD);
-  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (entry),TRUE);
-
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-
-  gtk_grid_attach (GTK_GRID (table), label, 4, 0, 1, 1);
-
-  gtk_widget_set_hexpand (scrolledwindow, TRUE);
-  gtk_grid_attach (GTK_GRID (table), scrolledwindow, 4, 1, 1, 2);
-  gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
-
-  return hbox;  
-}
-
-static GtkWidget*
-operations_parameters_editor_create_vbox (UMLClass *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  GtkWidget *vbox2;
-  GtkWidget *hbox2;
-  GtkWidget *vbox3;
-  GtkWidget *label;
-  GtkWidget *scrolled_win;
-  GtkWidget *list;
-  GtkWidget *button;
-
-  prop_dialog = umlclass->properties_dialog;
-
-  vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-  /* Parameters list label */
-  hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
-
-  label = gtk_label_new(_("Parameters:"));
-  gtk_box_pack_start( GTK_BOX(hbox2), label, FALSE, TRUE, 0);
-  
-  gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
-
-  /* Parameters list editor - with of list at least width of buttons*/
-  hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-  gtk_box_set_homogeneous (GTK_BOX (hbox2), TRUE);
-  
-  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
-                                 GTK_POLICY_AUTOMATIC, 
-                                 GTK_POLICY_AUTOMATIC);
-  gtk_box_pack_start (GTK_BOX (hbox2), scrolled_win, TRUE, TRUE, 0);
-  gtk_widget_show (scrolled_win);
-
-  list = dia_list_new ();
-  prop_dialog->parameters_list = DIA_LIST(list);
-  dia_list_set_selection_mode (DIA_LIST (list), GTK_SELECTION_SINGLE);
-  gtk_container_add (GTK_CONTAINER (scrolled_win), list);
-  gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
-                                      gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(scrolled_win)));
-  gtk_widget_show (list);
-
-  g_signal_connect (G_OBJECT (list), "selection_changed",
-                   G_CALLBACK(parameters_list_selection_changed_callback),
-                   umlclass);
-
-  vbox3 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-
-  button = gtk_button_new_with_label (_("New"));
-  prop_dialog->param_new_button = button;
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(parameters_list_new_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-  button = gtk_button_new_with_label (_("Delete"));
-  prop_dialog->param_delete_button = button;
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(parameters_list_delete_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-  button = gtk_button_new_with_label (_("Up"));
-  prop_dialog->param_up_button = button;
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(parameters_list_move_up_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-  button = gtk_button_new_with_label (_("Down"));
-  prop_dialog->param_down_button = button;
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(parameters_list_move_down_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-
-  gtk_box_pack_start (GTK_BOX (hbox2), vbox3, FALSE, TRUE, 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
-  /* end: Parameter list editor */
-  
-  return vbox2;
-}
-
-static GtkWidget*
-operations_parameters_data_create_vbox (UMLClass *umlclass)
-{
-  UMLClassDialog *prop_dialog;
-  GtkWidget *vbox2;
-  GtkWidget *frame;
-  GtkWidget *vbox3;
-  GtkWidget *table;
-  GtkWidget *label;
-  GtkWidget *entry;
-  GtkWidget *scrolledwindow;
-  GtkWidget *omenu;
-  
-  prop_dialog = umlclass->properties_dialog;
-
-  vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-  frame = gtk_frame_new(_("Parameter data"));
-  vbox3 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox3), 5);
-  gtk_container_add (GTK_CONTAINER (frame), vbox3);
-  gtk_widget_show(frame);
-  gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, TRUE, 0);
-  
-  table = gtk_grid_new ();
-  gtk_grid_set_column_spacing (GTK_GRID (table), 5);
-  gtk_box_pack_start (GTK_BOX (vbox3), table, FALSE, FALSE, 0);
-
-  label = gtk_label_new(_("Name:"));
-  entry = gtk_entry_new();
-  prop_dialog->param_name = GTK_ENTRY(entry);
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-  g_signal_connect (G_OBJECT (entry), "activate",
-                   G_CALLBACK (operations_update), umlclass);
-  
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
-  
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_grid_attach (GTK_GRID (table), entry, 1, 0, 1, 1);
-
-  label = gtk_label_new(_("Type:"));
-  entry = gtk_entry_new();
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-  g_signal_connect (G_OBJECT (entry), "activate",
-                   G_CALLBACK (operations_update), umlclass);
-  prop_dialog->param_type = GTK_ENTRY(entry);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
-
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_grid_attach (GTK_GRID (table), entry, 1, 1, 1, 1);
-
-  label = gtk_label_new(_("Def. value:"));
-  entry = gtk_entry_new();
-  prop_dialog->param_value = GTK_ENTRY(entry);
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-  g_signal_connect (G_OBJECT (entry), "activate",
-                   G_CALLBACK (operations_update), umlclass);
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
-
-  gtk_widget_set_hexpand (entry, TRUE);
-  gtk_grid_attach (GTK_GRID (table), entry, 1, 2, 1, 1);
-
-  label = gtk_label_new(_("Comment:"));
-  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
-                                      GTK_SHADOW_IN);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), 
-                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
-  entry = gtk_text_view_new ();
-  prop_dialog->param_comment = GTK_TEXT_VIEW(entry);
-  gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
-  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (entry), GTK_WRAP_WORD);
-  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (entry),TRUE);
-
-  g_signal_connect (G_OBJECT (entry), "focus_out_event",
-                   G_CALLBACK (operations_update_event), umlclass);
-
-  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-  gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-  gtk_grid_attach (GTK_GRID (table), label, 2, 1, 1, 1);
-
-  gtk_widget_set_hexpand (scrolledwindow, TRUE);
-  gtk_grid_attach (GTK_GRID (table), scrolledwindow, 3, 1, 1, 2);
-
-  label = gtk_label_new(_("Direction:"));
-
-  prop_dialog->param_kind = omenu = dia_option_menu_new ();    
-  g_signal_connect (G_OBJECT (omenu), "changed",
-                   G_CALLBACK (operations_update), umlclass);
-  dia_option_menu_add_item(omenu, _("Undefined"), UML_UNDEF_KIND);
-  dia_option_menu_add_item(omenu, _("In"), UML_IN);
-  dia_option_menu_add_item(omenu, _("Out"), UML_OUT);
-  dia_option_menu_add_item(omenu, _("In & Out"), UML_INOUT);
-
-  { 
-    GtkWidget * align;
-    align = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
-    gtk_container_add (GTK_CONTAINER (align), omenu);
-    gtk_label_set_xalign (GTK_LABEL (label), 0.0);
-    gtk_label_set_yalign (GTK_LABEL (label), 0.5);
-    gtk_grid_attach (GTK_GRID (table), label, 2, 0, 1, 1);
-    gtk_grid_attach (GTK_GRID (table), align, 3, 0, 1, 1);
-  }
-
-  return vbox2;
-}
-
 void 
-_operations_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
+_operations_create_page(GtkNotebook *notebook, UMLClass *umlclass)
 {
-  UMLClassDialog *prop_dialog;
   GtkWidget *page_label;
-  GtkWidget *hbox;
-  GtkWidget *vbox;
-  GtkWidget *vbox2;
-  GtkWidget *vbox3;
-  GtkWidget *scrolled_win;
-  GtkWidget *button;
-  GtkWidget *list;
-  GtkWidget *frame;
-
-  prop_dialog = umlclass->properties_dialog;
 
   /* Operations page: */
   page_label = gtk_label_new_with_mnemonic (_("_Operations"));
-  
-  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
-
-  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
-  
-  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
-                                 GTK_POLICY_AUTOMATIC, 
-                                 GTK_POLICY_AUTOMATIC);
-  gtk_box_pack_start (GTK_BOX (hbox), scrolled_win, TRUE, TRUE, 0);
-  gtk_widget_show (scrolled_win);
-
-  list = dia_list_new ();
-  prop_dialog->operations_list = DIA_LIST(list);
-  dia_list_set_selection_mode (DIA_LIST (list), GTK_SELECTION_SINGLE);
-  gtk_container_add (GTK_CONTAINER (scrolled_win), list);
-  gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
-                                      gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(scrolled_win)));
-  gtk_widget_show (list);
+  umlclass->properties_dialog->editor = dia_uml_class_editor_new (dia_uml_class_new (umlclass));
 
-  g_signal_connect (G_OBJECT (list), "selection_changed",
-                   G_CALLBACK(operations_list_selection_changed_callback),
-                   umlclass);
-
-  vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
-
-  button = gtk_button_new_with_label (_("New"));
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(operations_list_new_callback),
-                   umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-  button = gtk_button_new_with_label (_("Delete"));
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(operations_list_delete_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-  button = gtk_button_new_with_label (_("Up"));
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(operations_list_move_up_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-
-  button = gtk_button_new_with_label (_("Edit"));
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(operations_list_edit_callback), umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
-
-  button = gtk_button_new_with_label (_("Down"));
-  g_signal_connect (G_OBJECT (button), "clicked",
-                   G_CALLBACK(operations_list_move_down_callback), umlclass);
-
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
-  gtk_widget_show (button);
+  gtk_widget_show (page_label);
+  gtk_widget_show (umlclass->properties_dialog->editor);
 
-  gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
+  gtk_notebook_append_page (notebook, umlclass->properties_dialog->editor, page_label);
+}
 
-  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+void
+list_box_separators (GtkListBoxRow *row,
+                     GtkListBoxRow *before,
+                     gpointer       user_data)
+{
+  GtkWidget *current;
 
-  frame = gtk_frame_new(_("Operation data"));
-  vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-  hbox = operations_data_create_hbox (umlclass);
-  gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 0);
-  gtk_container_add (GTK_CONTAINER (frame), vbox2);
-  gtk_widget_show(frame);
-  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
-  
-  /* parameter stuff below operation stuff */
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-  vbox3 = operations_parameters_editor_create_vbox (umlclass);
-  gtk_box_pack_start (GTK_BOX (hbox), vbox3, TRUE, TRUE, 5);
+  if (before == NULL) {
+    gtk_list_box_row_set_header (row, NULL);
+    return;
+  }
 
-  vbox3 = operations_parameters_data_create_vbox (umlclass);
-  gtk_box_pack_start (GTK_BOX (hbox), vbox3, TRUE, TRUE, 5);
-  
-  gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, TRUE, 5);
- 
-  gtk_widget_show_all (vbox);
-  gtk_widget_show (page_label);
-  gtk_notebook_append_page (notebook, vbox, page_label);
+  current = gtk_list_box_row_get_header (row);
+  if (current == NULL) {
+    current = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+    gtk_widget_show (current);
+    gtk_list_box_row_set_header (row, current);
+  }
 }
diff --git a/objects/UML/class_templates_dialog.c b/objects/UML/class_templates_dialog.c
index 78fa2a0e..25a7812d 100644
--- a/objects/UML/class_templates_dialog.c
+++ b/objects/UML/class_templates_dialog.c
@@ -105,9 +105,8 @@ static void
 templates_list_selection_changed_callback(GtkWidget *gtklist,
                                          UMLClass *umlclass)
 {
-  GList *list;
   UMLClassDialog *prop_dialog;
-  GObject *list_item;
+  DiaListItem *list_item;
   UMLFormalParameter *param;
 
   prop_dialog = umlclass->properties_dialog;
@@ -162,9 +161,9 @@ templates_list_new_callback(GtkWidget *button,
   dia_list_append_items(prop_dialog->templates_list, list);
 
   if (dia_list_get_children (prop_dialog->templates_list) != NULL)
-    dia_list_unselect_child(prop_dialog->templates_list,
-                           GTK_WIDGET(dia_list_get_children (prop_dialog->templates_list)->data));
-  dia_list_select_child(prop_dialog->templates_list, list_item);
+    dia_list_unselect_child (prop_dialog->templates_list,
+                             dia_list_get_children (prop_dialog->templates_list)->data);
+  dia_list_select_child (prop_dialog->templates_list, DIA_LIST_ITEM (list_item));
 }
 
 static void
@@ -194,14 +193,14 @@ templates_list_move_up_callback(GtkWidget *button,
   GList *list;
   UMLClassDialog *prop_dialog;
   DiaList *gtklist;
-  GtkWidget *list_item;
+  DiaListItem *list_item;
   int i;
   
   prop_dialog = umlclass->properties_dialog;
   gtklist = DIA_LIST(prop_dialog->templates_list);
 
   if (dia_list_get_selection (gtklist) != NULL) {
-    list_item = GTK_WIDGET(dia_list_get_selection (gtklist));
+    list_item = dia_list_get_selection (gtklist);
     
     i = dia_list_child_position(gtklist, list_item);
     if (i>0)
@@ -386,7 +385,7 @@ _templates_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   list = dia_list_new ();
   prop_dialog->templates_list = DIA_LIST(list);
   dia_list_set_selection_mode (DIA_LIST (list), GTK_SELECTION_SINGLE);
-  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
+  gtk_container_add (GTK_CONTAINER (scrolled_win), list);
   gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
                                       gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(scrolled_win)));
   gtk_widget_show (list);
diff --git a/objects/UML/dia-uml-class.c b/objects/UML/dia-uml-class.c
new file mode 100644
index 00000000..4153a15f
--- /dev/null
+++ b/objects/UML/dia-uml-class.c
@@ -0,0 +1,240 @@
+#include "dia-uml-class.h"
+
+G_DEFINE_TYPE (DiaUmlClass, dia_uml_class, G_TYPE_OBJECT)
+
+static void
+clear_attrs (DiaUmlClass *self)
+{
+  GList *list;
+
+  g_clear_object (&self->normal_font);
+  g_clear_object (&self->abstract_font);
+  g_clear_object (&self->polymorphic_font);
+  g_clear_object (&self->classname_font);
+  g_clear_object (&self->abstract_classname_font);
+  g_clear_object (&self->comment_font);
+  
+  g_free (self->name);
+  g_free (self->stereotype);
+  g_free (self->comment);
+
+  list = self->attributes;
+  while (list) {
+    uml_attribute_destroy ((UMLAttribute *) list->data);
+    list = g_list_next (list);
+  }
+  g_list_free (self->attributes);
+
+  list = self->operations;
+  while (list) {
+    g_object_unref (list->data);
+    list = g_list_next (list);
+  }
+  g_list_free (self->operations);
+
+  list = self->formal_params;
+  while (list) {
+    uml_formalparameter_destroy ((UMLFormalParameter *) list->data);
+    list = g_list_next (list);
+  }
+  g_list_free (self->formal_params);
+}
+
+static void
+dia_uml_class_finalize (GObject *object)
+{
+  DiaUmlClass *self = DIA_UML_CLASS (object);
+
+  clear_attrs (self);
+}
+
+static void
+dia_uml_class_class_init (DiaUmlClassClass *klass)
+{
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = dia_uml_class_finalize;
+}
+
+static void
+dia_uml_class_init (DiaUmlClass *self)
+{
+}
+
+DiaUmlClass *
+dia_uml_class_new (UMLClass *klass)
+{
+  DiaUmlClass *self = g_object_new (DIA_UML_TYPE_CLASS, NULL);
+
+  dia_uml_class_load (self, klass);
+
+  return self;
+}
+
+/* Sync from klass to self */
+void
+dia_uml_class_load (DiaUmlClass *self,
+                    UMLClass    *klass)
+{
+  GList *list;
+
+  clear_attrs (self);
+
+  self->font_height = klass->font_height;
+  self->abstract_font_height = klass->abstract_font_height;
+  self->polymorphic_font_height = klass->polymorphic_font_height;
+  self->classname_font_height = klass->classname_font_height;
+  self->abstract_classname_font_height = klass->abstract_classname_font_height;
+  self->comment_font_height = klass->comment_font_height;
+
+  self->normal_font = g_object_ref (klass->normal_font);
+  self->abstract_font = g_object_ref (klass->abstract_font);
+  self->polymorphic_font = g_object_ref (klass->polymorphic_font);
+  self->classname_font = g_object_ref (klass->classname_font);
+  self->abstract_classname_font = g_object_ref (klass->abstract_classname_font);
+  self->comment_font = g_object_ref (klass->comment_font);
+  
+  g_free (self->name);
+  self->name = g_strdup(klass->name);
+  g_free (self->stereotype);
+  self->stereotype = g_strdup(klass->stereotype);
+  g_free (self->comment);
+  self->comment = g_strdup(klass->comment);
+
+  self->abstract = klass->abstract;
+  self->suppress_attributes = klass->suppress_attributes;
+  self->suppress_operations = klass->suppress_operations;
+  self->visible_attributes = klass->visible_attributes;
+  self->visible_operations = klass->visible_operations;
+  self->visible_comments = klass->visible_comments;
+
+  self->wrap_operations = klass->wrap_operations;
+  self->wrap_after_char = klass->wrap_after_char;
+  self->comment_line_length = klass->comment_line_length;
+  self->comment_tagging = klass->comment_tagging;
+
+  self->line_color = klass->line_color;
+  self->fill_color = klass->fill_color;
+  self->text_color = klass->text_color;
+  
+  self->attributes = NULL;
+  list = klass->attributes;
+  while (list != NULL) {
+    UMLAttribute *attr = (UMLAttribute *)list->data;
+    UMLAttribute *attr_copy;
+      
+    attr_copy = uml_attribute_copy(attr);
+    /* Looks wrong, but needed fro proper restore */
+    attr_copy->left_connection = attr->left_connection;
+    attr_copy->right_connection = attr->right_connection;
+
+    self->attributes = g_list_append(self->attributes, attr_copy);
+    list = g_list_next(list);
+  }
+
+  /* TODO: Why? */
+  self->operations = NULL;
+  list = klass->operations;
+  while (list != NULL) {
+    DiaUmlOperation *op = (DiaUmlOperation *)list->data;
+    DiaUmlOperation *copy = dia_uml_operation_copy (op);
+
+    /* Looks wrong but is required for the complicate connections memory management */
+    copy->l_connection = op->l_connection;
+    copy->r_connection = op->r_connection;
+
+    self->operations = g_list_append(self->operations, copy);
+    list = g_list_next(list);
+  }
+
+  self->template_ = klass->template;
+  
+  self->formal_params = NULL;
+  list = klass->formal_params;
+  while (list != NULL) {
+    UMLFormalParameter *param = (UMLFormalParameter *) list->data;
+    UMLFormalParameter *param_copy;
+    
+    param_copy = uml_formalparameter_copy (param);
+    self->formal_params = g_list_append (self->formal_params, param_copy);
+    
+    list = g_list_next(list);
+  }
+}
+
+/* Sync from self to klass */
+void
+dia_uml_class_store (DiaUmlClass *self,
+                     UMLClass    *klass)
+{
+  klass->font_height = self->font_height;
+  klass->abstract_font_height = self->abstract_font_height;
+  klass->polymorphic_font_height = self->polymorphic_font_height;
+  klass->classname_font_height = self->classname_font_height;
+  klass->abstract_classname_font_height = self->abstract_classname_font_height;
+  klass->comment_font_height = self->comment_font_height;
+
+  /* transfer ownership, but don't leak the previous font */
+  g_clear_object (&klass->normal_font);
+  klass->normal_font = g_object_ref (self->normal_font);
+  g_clear_object (&klass->abstract_font);
+  klass->abstract_font = g_object_ref (self->abstract_font);
+  g_clear_object (&klass->polymorphic_font);
+  klass->polymorphic_font = g_object_ref (self->polymorphic_font);
+  g_clear_object (&klass->classname_font);
+  klass->classname_font = g_object_ref (self->classname_font);
+  g_clear_object (&klass->abstract_classname_font);
+  klass->abstract_classname_font = g_object_ref (self->abstract_classname_font);
+  g_clear_object (&klass->comment_font);
+  klass->comment_font = g_object_ref (self->comment_font);
+  
+  klass->name = self->name;
+  klass->stereotype = self->stereotype;
+  klass->comment = self->comment;
+
+  klass->abstract = self->abstract;
+  klass->suppress_attributes = self->suppress_attributes;
+  klass->suppress_operations = self->suppress_operations;
+  klass->visible_attributes = self->visible_attributes;
+  klass->visible_operations = self->visible_operations;
+  klass->visible_comments = self->visible_comments;
+
+  klass->wrap_operations = self->wrap_operations;
+  klass->wrap_after_char = self->wrap_after_char;
+  klass->comment_line_length = self->comment_line_length;
+  klass->comment_tagging = self->comment_tagging;
+
+  klass->line_color = self->line_color;
+  klass->fill_color = self->fill_color;
+  klass->text_color = self->text_color;
+
+  /* TODO: List stuff */
+  klass->attributes = self->attributes;
+  klass->operations = self->operations;
+  klass->template = self->template_;
+  klass->formal_params = self->formal_params;
+}
+
+GList *
+dia_uml_class_get_operations (DiaUmlClass *self)
+{
+  return self->operations;
+}
+
+void
+dia_uml_class_insert_operation (DiaUmlClass     *self,
+                                DiaUmlOperation *operation,
+                                int              index)
+{
+  self->operations = g_list_insert (self->operations,
+                                    g_object_ref (operation),
+                                    index);
+}
+
+void
+dia_uml_class_remove_operation (DiaUmlClass     *self,
+                                DiaUmlOperation *operation)
+{
+  self->operations = g_list_remove (self->operations, operation);
+  g_object_unref (operation);
+}
diff --git a/objects/UML/dia-uml-class.h b/objects/UML/dia-uml-class.h
new file mode 100644
index 00000000..e086a0c0
--- /dev/null
+++ b/objects/UML/dia-uml-class.h
@@ -0,0 +1,78 @@
+#include <gtk/gtk.h>
+#include "uml.h"
+#include "class.h"
+
+#ifndef UML_CLASS_H
+#define UML_CLASS_H
+
+G_BEGIN_DECLS
+
+#define DIA_UML_TYPE_CLASS (dia_uml_class_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlClass, dia_uml_class, DIA_UML, CLASS, GObject)
+
+struct _DiaUmlClass {
+  GObject parent;
+
+  double font_height;
+  double abstract_font_height;
+  double polymorphic_font_height;
+  double classname_font_height;
+  double abstract_classname_font_height;
+  double comment_font_height;
+
+  DiaFont *normal_font;
+  DiaFont *abstract_font;
+  DiaFont *polymorphic_font;
+  DiaFont *classname_font;
+  DiaFont *abstract_classname_font;
+  DiaFont *comment_font;
+  
+  char *name;
+  char *stereotype;
+  char *comment;
+
+  gboolean abstract;
+  gboolean suppress_attributes;
+  gboolean suppress_operations;
+  gboolean visible_attributes;
+  gboolean visible_operations;
+  gboolean visible_comments;
+
+  int wrap_operations;
+  int wrap_after_char;
+  int comment_line_length;
+  int comment_tagging;
+  
+  double line_width;
+  GdkRGBA line_color;
+  GdkRGBA fill_color;
+  GdkRGBA text_color;
+
+  /* Maybe we could use GListStore for these? */
+
+  /* Attributes: */
+  GList *attributes;
+
+  /* Operators: */
+  GList *operations;
+
+  /* Template: */
+  gboolean template_;
+  GList *formal_params;
+};
+
+DiaUmlClass *dia_uml_class_new              (UMLClass        *klass);
+void         dia_uml_class_load             (DiaUmlClass     *self,
+                                             UMLClass        *klass);
+void         dia_uml_class_store            (DiaUmlClass     *self,
+                                             UMLClass        *klass);
+GList       *dia_uml_class_get_operations   (DiaUmlClass     *self);
+void         dia_uml_class_remove_operation (DiaUmlClass     *self,
+                                             DiaUmlOperation *operation);
+void         dia_uml_class_insert_operation (DiaUmlClass     *self,
+                                             DiaUmlOperation *operation,
+                                             int              index);
+
+G_END_DECLS
+
+#endif
\ No newline at end of file
diff --git a/objects/UML/editor/dia-uml-class-editor.c b/objects/UML/editor/dia-uml-class-editor.c
new file mode 100644
index 00000000..4dd2cf13
--- /dev/null
+++ b/objects/UML/editor/dia-uml-class-editor.c
@@ -0,0 +1,283 @@
+#include "dia-uml-class-editor.h"
+#include "dia-uml-operation-row.h"
+#include "dia-uml-operation-dialog.h"
+#include "dia_dirs.h"
+
+G_DEFINE_TYPE (DiaUmlClassEditor, dia_uml_class_editor, GTK_TYPE_SCROLLED_WINDOW)
+
+enum {
+  UML_CEDIT_PROP_CLASS = 1,
+  UML_CEDIT_N_PROPS
+};
+static GParamSpec* uml_cedit_properties[UML_CEDIT_N_PROPS];
+
+static void
+build_list (DiaUmlClassEditor *self)
+{
+  GList *list;
+  GtkWidget *item;
+
+  gtk_container_foreach (GTK_CONTAINER (self->operations), (GtkCallback *) gtk_widget_destroy, NULL);
+
+  list = dia_uml_class_get_operations (self->klass);
+  self->building_ops = TRUE;
+  while (list != NULL) {
+    DiaUmlOperation *op = (DiaUmlOperation *)list->data;
+    item = dia_uml_operation_row_new (op);
+    gtk_widget_show (item);
+    gtk_container_add (GTK_CONTAINER (self->operations), item);
+    
+    list = g_list_next(list);
+  }
+  self->building_ops = FALSE;
+}
+
+static void
+remove_op_row (GtkWidget       *row,
+               DiaUmlOperation *op)
+{
+  DiaUmlOperation *curr_row;
+
+  curr_row = dia_uml_operation_row_get_operation (DIA_UML_OPERATION_ROW (row));
+
+  if (op == curr_row)
+    gtk_widget_destroy (row);
+
+  g_object_unref (curr_row);
+}
+
+static void
+remove_op (DiaUmlOperationDialog *dlg,
+           DiaUmlOperation       *op,
+           DiaUmlClassEditor     *self)
+{
+  gtk_container_foreach (GTK_CONTAINER (self->operations),
+                         (GtkCallback *) remove_op_row,
+                         op);
+}
+
+static void
+add_operation (DiaUmlClassEditor *self)
+{
+  DiaUmlOperation *op;
+  GtkWidget *row;
+  GtkWidget *edit;
+  GtkWidget *parent;
+
+  op = dia_uml_operation_new ();
+  row = dia_uml_operation_row_new (op);
+
+  gtk_widget_show (row);
+  gtk_container_add (GTK_CONTAINER (self->operations), row);
+
+  parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
+  edit = dia_uml_operation_dialog_new (GTK_WINDOW (parent), op);
+  g_signal_connect (edit, "operation-deleted", G_CALLBACK (remove_op), self);
+
+  gtk_widget_show (edit);
+}
+
+static void
+edit_operation (DiaUmlClassEditor *self,
+                GtkListBoxRow     *row)
+{
+  GtkWidget *dlg;
+  GtkWidget *parent;
+  DiaUmlOperation *op;
+
+  if (!DIA_UML_IS_OPERATION_ROW (row))
+    return;
+  
+  parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
+  op = dia_uml_operation_row_get_operation (DIA_UML_OPERATION_ROW (row));
+  dlg = dia_uml_operation_dialog_new (GTK_WINDOW (parent), op);
+  g_signal_connect (dlg, "operation-deleted", G_CALLBACK (remove_op), self);
+  gtk_widget_show (dlg);
+  g_object_unref (op);
+}
+
+static void
+operation_added (DiaUmlClassEditor *self,
+                 GtkListBoxRow     *row)
+{
+  DiaUmlOperation *op;
+  int index;
+
+  if (self->building_ops || !DIA_UML_IS_OPERATION_ROW (row))
+    return;
+
+  op = dia_uml_operation_row_get_operation (DIA_UML_OPERATION_ROW (row));
+  index = gtk_list_box_row_get_index (row);
+
+  dia_uml_class_insert_operation (self->klass, op, index);
+  g_object_unref (op);
+}
+
+static void
+operation_removed (DiaUmlClassEditor *self,
+                   GtkListBoxRow     *row)
+{
+  DiaUmlOperation *op;
+
+  if (!DIA_UML_IS_OPERATION_ROW (row) || gtk_widget_in_destruction (GTK_WIDGET (row)))
+    return;
+  
+  op = dia_uml_operation_row_get_operation (DIA_UML_OPERATION_ROW (row));
+
+  dia_uml_class_remove_operation (self->klass, op);
+  /* Don't unref op, we might be being moved so must give it the change to survive */
+}
+
+static void
+dia_uml_class_editor_finalize (GObject *object)
+{
+  DiaUmlClassEditor *self = DIA_UML_CLASS_EDITOR (object);
+
+  g_object_unref (self->klass);
+}
+
+static void
+dia_uml_class_editor_set_property (GObject      *object,
+                                   guint         property_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  DiaUmlClassEditor *self = DIA_UML_CLASS_EDITOR (object);
+
+  switch (property_id) {
+    case UML_CEDIT_PROP_CLASS:
+      self->klass = g_value_dup_object (value);
+      build_list (self);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_class_editor_get_property (GObject    *object,
+                                   guint       property_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  DiaUmlClassEditor *self = DIA_UML_CLASS_EDITOR (object);
+  switch (property_id) {
+    case UML_CEDIT_PROP_CLASS:
+      g_value_set_object (value, self->klass);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_class_editor_class_init (DiaUmlClassEditorClass *klass)
+{
+  GFile *template_file;
+  GBytes *template;
+  GError *err = NULL;
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->set_property = dia_uml_class_editor_set_property;
+  object_class->get_property = dia_uml_class_editor_get_property;
+  object_class->finalize = dia_uml_class_editor_finalize;
+
+  uml_cedit_properties[UML_CEDIT_PROP_CLASS] =
+    g_param_spec_object ("class",
+                         "Class",
+                         "Controlled class",
+                         DIA_UML_TYPE_CLASS,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+  g_object_class_install_properties (object_class,
+                                     UML_CEDIT_N_PROPS,
+                                     uml_cedit_properties);
+
+  /* TODO: Use GResource */
+  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-class-editor.ui"));
+  template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+  if (err)
+    g_critical ("Failed to load template: %s", err->message);
+
+  gtk_widget_class_set_template (widget_class, template);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlClassEditor, attributes);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlClassEditor, operations);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlClassEditor, templates);
+  gtk_widget_class_bind_template_callback (widget_class, add_operation);
+  gtk_widget_class_bind_template_callback (widget_class, edit_operation);
+  gtk_widget_class_bind_template_callback (widget_class, operation_added);
+  gtk_widget_class_bind_template_callback (widget_class, operation_removed);
+
+  g_object_unref (template_file);
+}
+
+static void
+dia_uml_class_editor_init (DiaUmlClassEditor *self)
+{
+  GtkWidget *box;
+  GtkWidget *label;
+
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  self->building_ops = FALSE;
+
+  box = g_object_new (GTK_TYPE_BOX,
+                      "orientation", GTK_ORIENTATION_VERTICAL,
+                      "spacing", 16,
+                      "margin", 16,
+                      NULL);
+  gtk_widget_show (box);
+
+  label = gtk_label_new ("No attributes");
+  gtk_widget_show (label);
+  gtk_container_add (GTK_CONTAINER (box), label);
+
+  gtk_list_box_set_placeholder (GTK_LIST_BOX (self->attributes), box);
+  gtk_list_box_set_header_func (GTK_LIST_BOX (self->attributes), list_box_separators, NULL, NULL);
+
+  box = g_object_new (GTK_TYPE_BOX,
+                      "orientation", GTK_ORIENTATION_VERTICAL,
+                      "spacing", 16,
+                      "margin", 16,
+                      NULL);
+  gtk_widget_show (box);
+
+  label = gtk_label_new ("No operations");
+  gtk_widget_show (label);
+  gtk_container_add (GTK_CONTAINER (box), label);
+
+  gtk_list_box_set_placeholder (GTK_LIST_BOX (self->operations), box);
+  gtk_list_box_set_header_func (GTK_LIST_BOX (self->operations), list_box_separators, NULL, NULL);
+
+  box = g_object_new (GTK_TYPE_BOX,
+                      "orientation", GTK_ORIENTATION_VERTICAL,
+                      "spacing", 16,
+                      "margin", 16,
+                      NULL);
+  gtk_widget_show (box);
+
+  label = gtk_label_new ("No templates");
+  gtk_widget_show (label);
+  gtk_container_add (GTK_CONTAINER (box), label);
+
+  gtk_list_box_set_placeholder (GTK_LIST_BOX (self->templates), box);
+  gtk_list_box_set_header_func (GTK_LIST_BOX (self->templates), list_box_separators, NULL, NULL);
+}
+
+GtkWidget *
+dia_uml_class_editor_new (DiaUmlClass *klass)
+{
+  return g_object_new (DIA_UML_TYPE_CLASS_EDITOR,
+                       "class", klass,
+                       NULL);
+}
+
+DiaUmlClass 
+*dia_uml_class_editor_get_class (DiaUmlClassEditor *self)
+{
+  return self->klass;
+}
\ No newline at end of file
diff --git a/objects/UML/editor/dia-uml-class-editor.h b/objects/UML/editor/dia-uml-class-editor.h
new file mode 100644
index 00000000..0363114d
--- /dev/null
+++ b/objects/UML/editor/dia-uml-class-editor.h
@@ -0,0 +1,29 @@
+#include <gtk/gtk.h>
+#include "uml.h"
+#include "dia-uml-class.h"
+
+#ifndef UML_CLASS_EDITOR_H
+#define UML_CLASS_EDITOR_H
+
+G_BEGIN_DECLS
+
+#define DIA_UML_TYPE_CLASS_EDITOR (dia_uml_class_editor_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlClassEditor, dia_uml_class_editor, DIA_UML, CLASS_EDITOR, GtkScrolledWindow)
+
+struct _DiaUmlClassEditor {
+  GtkScrolledWindow parent;
+
+  GtkWidget *attributes;
+  GtkWidget *operations;
+  gboolean building_ops;
+  GtkWidget *templates;
+
+  DiaUmlClass *klass;
+};
+
+GtkWidget   *dia_uml_class_editor_new       (DiaUmlClass       *klass);
+DiaUmlClass *dia_uml_class_editor_get_class (DiaUmlClassEditor *self);
+
+G_END_DECLS
+
+#endif
\ No newline at end of file
diff --git a/objects/UML/editor/dia-uml-operation-dialog.c b/objects/UML/editor/dia-uml-operation-dialog.c
new file mode 100644
index 00000000..3bc919bf
--- /dev/null
+++ b/objects/UML/editor/dia-uml-operation-dialog.c
@@ -0,0 +1,328 @@
+#include "dia-uml-operation-dialog.h"
+#include "dia-uml-operation-parameter-row.h"
+#include "dia_dirs.h"
+
+G_DEFINE_TYPE (DiaUmlOperationDialog, dia_uml_operation_dialog, GTK_TYPE_DIALOG)
+
+enum {
+  UML_OP_DLG_PROP_OPERATION = 1,
+  UML_OP_DLG_N_PROPS
+};
+static GParamSpec* uml_op_dlg_properties[UML_OP_DLG_N_PROPS];
+
+enum {
+  UML_OP_DLG_OPERATION_DELETED,
+  UML_OP_DLG_LAST_SIGNAL
+};
+static guint uml_op_dlg_signals[UML_OP_DLG_LAST_SIGNAL] = { 0 };
+
+static void
+dia_uml_operation_dialog_finalize (GObject *object)
+{
+  DiaUmlOperationDialog *self = DIA_UML_OPERATION_DIALOG (object);
+
+  g_object_unref (self->operation);
+}
+
+static gboolean
+visibility_to (GBinding *binding,
+               const GValue *from_value,
+               GValue *to_value,
+               gpointer user_data)
+{
+  const gchar *name = g_value_get_string (from_value);
+
+  if (g_strcmp0 (name, "private") == 0) {
+    g_value_set_int (to_value, UML_PRIVATE);
+  } else if (g_strcmp0 (name, "protected") == 0) {
+    g_value_set_int (to_value, UML_PROTECTED);
+  } else if (g_strcmp0 (name, "implementation") == 0) {
+    g_value_set_int (to_value, UML_IMPLEMENTATION);
+  } else {
+    g_value_set_int (to_value, UML_PUBLIC);
+  }
+  
+  return TRUE;
+}
+
+static gboolean
+visibility_from (GBinding *binding,
+                 const GValue *from_value,
+                 GValue *to_value,
+                 gpointer user_data)
+{
+  int mode = g_value_get_int (from_value);
+
+  if (mode == UML_ABSTRACT) {
+    g_value_set_static_string (to_value, "abstract");
+  } else if (mode == UML_POLYMORPHIC) {
+    g_value_set_static_string (to_value, "poly");
+  } else {
+    g_value_set_static_string (to_value, "leaf");
+  }
+  
+  return TRUE;
+}
+
+static gboolean
+inheritance_to (GBinding *binding,
+                const GValue *from_value,
+                GValue *to_value,
+                gpointer user_data)
+{
+  const gchar *name = g_value_get_string (from_value);
+
+  if (g_strcmp0 (name, "abstract") == 0) {
+    g_value_set_int (to_value, UML_ABSTRACT);
+  } else if (g_strcmp0 (name, "poly") == 0) {
+    g_value_set_int (to_value, UML_POLYMORPHIC);
+  } else {
+    g_value_set_int (to_value, UML_LEAF);
+  }
+  
+  return TRUE;
+}
+
+static gboolean
+inheritance_from (GBinding *binding,
+                  const GValue *from_value,
+                  GValue *to_value,
+                  gpointer user_data)
+{
+  int mode = g_value_get_int (from_value);
+
+  if (mode == UML_PRIVATE) {
+    g_value_set_static_string (to_value, "private");
+  } else if (mode == UML_PROTECTED) {
+    g_value_set_static_string (to_value, "protected");
+  } else if (mode == UML_IMPLEMENTATION) {
+    g_value_set_static_string (to_value, "implementation");
+  } else {
+    g_value_set_static_string (to_value, "public");
+  }
+  
+  return TRUE;
+}
+
+static void
+dia_uml_operation_dialog_set_property (GObject      *object,
+                                       guint         property_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+  DiaUmlOperationDialog *self = DIA_UML_OPERATION_DIALOG (object);
+  GList *paras;
+  GtkWidget *row;
+
+  switch (property_id) {
+    case UML_OP_DLG_PROP_OPERATION:
+      self->operation = g_value_dup_object (value);
+      g_object_bind_property (G_OBJECT (self->operation), "name",
+                              G_OBJECT (self->name), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->operation), "type",
+                              G_OBJECT (self->type), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->operation), "stereotype",
+                              G_OBJECT (self->stereotype), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->operation), "comment",
+                              G_OBJECT (self->comment), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+      g_object_bind_property_full (G_OBJECT (self->operation), "visibility",
+                                   G_OBJECT (self->visibility), "active-id",
+                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
+                                   visibility_from,
+                                   visibility_to,
+                                   NULL, NULL);
+
+      g_object_bind_property_full (G_OBJECT (self->operation), "inheritance-type",
+                                   G_OBJECT (self->inheritance), "active-id",
+                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
+                                   inheritance_from,
+                                   inheritance_to,
+                                   NULL, NULL);
+
+      g_object_bind_property (G_OBJECT (self->operation), "query",
+                              G_OBJECT (self->query), "active",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->operation), "class-scope",
+                              G_OBJECT (self->scope), "active",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+      self->building = TRUE;
+      paras = dia_uml_operation_get_parameters (self->operation);
+      for (; paras != NULL; paras = g_list_next (paras)) {
+        // do something with l->data
+        row = dia_uml_operation_parameter_row_new (DIA_UML_PARAMETER (paras->data));
+        gtk_widget_show (row);
+        gtk_container_add (GTK_CONTAINER (self->list), row);
+      }
+      self->building = FALSE;
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_operation_dialog_get_property (GObject    *object,
+                                       guint       property_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+  DiaUmlOperationDialog *self = DIA_UML_OPERATION_DIALOG (object);
+  switch (property_id) {
+    case UML_OP_DLG_PROP_OPERATION:
+      g_value_set_object (value, self->operation);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dlg_add_parameter (DiaUmlOperationDialog *self)
+{
+  GtkWidget *row = dia_uml_operation_parameter_row_new (dia_uml_parameter_new ());
+
+  g_assert (DIA_UML_IS_OPERATION_DIALOG (self));
+  gtk_widget_show (row);
+  gtk_container_add (GTK_CONTAINER (self->list), row);
+}
+
+static void
+parameter_added (DiaUmlOperationDialog *self,
+                 GtkWidget             *row)
+{
+  DiaUmlParameter *para = NULL;
+  int index;
+
+  if (!DIA_UML_IS_OPERATION_PARAMETER_ROW (row) || self->building)
+    return;
+
+  g_object_get (G_OBJECT (row),
+                "parameter", &para,
+                NULL);
+  index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (row));
+
+  dia_uml_operation_insert_parameter (self->operation, para, index);
+}
+
+static void
+parameter_removed (DiaUmlOperationDialog *self,
+                   GtkWidget             *row)
+{
+  DiaUmlParameter *para = NULL;
+
+  if (!DIA_UML_IS_OPERATION_PARAMETER_ROW (row) || gtk_widget_in_destruction (GTK_WIDGET (self)))
+    return;
+
+  g_object_get (G_OBJECT (row),
+                "parameter", &para,
+                NULL);
+
+  dia_uml_operation_remove_parameter (self->operation, para);
+}
+
+static void
+remove_operation (DiaUmlOperationDialog *self)
+{
+  g_signal_emit (G_OBJECT (self),
+                 uml_op_dlg_signals[UML_OP_DLG_OPERATION_DELETED], 0,
+                 self->operation);
+  gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+static void
+dia_uml_operation_dialog_class_init (DiaUmlOperationDialogClass *klass)
+{
+  GFile *template_file;
+  GBytes *template;
+  GError *err = NULL;
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = dia_uml_operation_dialog_finalize;
+  object_class->set_property = dia_uml_operation_dialog_set_property;
+  object_class->get_property = dia_uml_operation_dialog_get_property;
+
+  uml_op_dlg_properties[UML_OP_DLG_PROP_OPERATION] =
+    g_param_spec_object ("operation",
+                         "Operation",
+                         "Operation this editor controls",
+                         DIA_UML_TYPE_OPERATION,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+  g_object_class_install_properties (object_class,
+                                     UML_OP_DLG_N_PROPS,
+                                     uml_op_dlg_properties);
+
+  uml_op_dlg_signals[UML_OP_DLG_OPERATION_DELETED] = g_signal_new ("operation-deleted",
+                                                                   G_TYPE_FROM_CLASS (klass),
+                                                                   G_SIGNAL_RUN_FIRST,
+                                                                   0, NULL, NULL, NULL,
+                                                                   G_TYPE_NONE, 1,
+                                                                   DIA_UML_TYPE_OPERATION);
+
+  /* TODO: Use GResource */
+  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-operation-dialog.ui"));
+  template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+  if (err)
+    g_critical ("Failed to load template: %s", err->message);
+
+  gtk_widget_class_set_template (widget_class, template);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, name);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, type);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, stereotype);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, visibility);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, inheritance);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, scope);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, query);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, comment);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationDialog, list);
+  gtk_widget_class_bind_template_callback (widget_class, dlg_add_parameter);
+  gtk_widget_class_bind_template_callback (widget_class, parameter_added);
+  gtk_widget_class_bind_template_callback (widget_class, parameter_removed);
+  gtk_widget_class_bind_template_callback (widget_class, remove_operation);
+
+  g_object_unref (template_file);
+}
+
+static void
+dia_uml_operation_dialog_init (DiaUmlOperationDialog *self)
+{
+  GtkWidget *box;
+  GtkWidget *widget;
+
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  box = g_object_new (GTK_TYPE_BOX,
+                      "orientation", GTK_ORIENTATION_VERTICAL,
+                      "spacing", 16,
+                      "margin", 16,
+                      NULL);
+  gtk_widget_show (box);
+
+  widget = gtk_label_new ("No parameters");
+  gtk_widget_show (widget);
+  gtk_container_add (GTK_CONTAINER (box), widget);
+
+  gtk_list_box_set_placeholder (GTK_LIST_BOX (self->list), box);
+  gtk_list_box_set_header_func (GTK_LIST_BOX (self->list), list_box_separators, NULL, NULL);
+}
+
+GtkWidget *
+dia_uml_operation_dialog_new (GtkWindow       *parent,
+                              DiaUmlOperation *op)
+{
+  return g_object_new (DIA_UML_TYPE_OPERATION_DIALOG,
+                       "operation", op,
+                       "transient-for", parent,
+                       "modal", TRUE,
+                       NULL);
+}
diff --git a/objects/UML/editor/dia-uml-operation-dialog.h b/objects/UML/editor/dia-uml-operation-dialog.h
new file mode 100644
index 00000000..e2c907ca
--- /dev/null
+++ b/objects/UML/editor/dia-uml-operation-dialog.h
@@ -0,0 +1,26 @@
+#include <gtk/gtk.h>
+#include "uml.h"
+
+#define DIA_UML_TYPE_OPERATION_DIALOG (dia_uml_operation_dialog_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlOperationDialog, dia_uml_operation_dialog, DIA_UML, OPERATION_DIALOG, GtkDialog)
+
+struct _DiaUmlOperationDialog {
+  GtkDialog parent;
+
+  GtkWidget *name;
+  GtkWidget *type;
+  GtkWidget *stereotype;
+  GtkWidget *visibility;
+  GtkWidget *inheritance;
+  GtkWidget *scope;
+  GtkWidget *query;
+  GtkTextBuffer *comment;
+  GtkWidget *list;
+
+  gboolean building;
+
+  DiaUmlOperation *operation;
+};
+
+GtkWidget *dia_uml_operation_dialog_new (GtkWindow       *parent,
+                                         DiaUmlOperation *op);
diff --git a/objects/UML/editor/dia-uml-operation-parameter-row.c 
b/objects/UML/editor/dia-uml-operation-parameter-row.c
new file mode 100644
index 00000000..230eb168
--- /dev/null
+++ b/objects/UML/editor/dia-uml-operation-parameter-row.c
@@ -0,0 +1,207 @@
+#include "dia-uml-operation-parameter-row.h"
+#include "dia_dirs.h"
+
+G_DEFINE_TYPE (DiaUmlOperationParameterRow, dia_uml_operation_parameter_row, GTK_TYPE_LIST_BOX_ROW)
+
+enum {
+  UML_OP_PROW_PROP_PARAMETER = 1,
+  UML_OP_PROW_N_PROPS
+};
+static GParamSpec* uml_op_prow_properties[UML_OP_PROW_N_PROPS];
+
+static void
+dia_uml_operation_parameter_row_finalize (GObject *object)
+{
+  DiaUmlOperationParameterRow *self = DIA_UML_OPERATION_PARAMETER_ROW (object);
+
+  g_object_unref (self->parameter);
+}
+
+static gboolean
+direction_to (GBinding *binding,
+              const GValue *from_value,
+              GValue *to_value,
+              gpointer user_data)
+{
+  gchar *name = g_value_get_string (from_value);
+
+  if (g_strcmp0 (name, "in") == 0) {
+    g_value_set_int (to_value, UML_IN);
+  } else if (g_strcmp0 (name, "out") == 0) {
+    g_value_set_int (to_value, UML_OUT);
+  } else if (g_strcmp0 (name, "inout") == 0) {
+    g_value_set_int (to_value, UML_INOUT);
+  } else {
+    g_value_set_int (to_value, UML_UNDEF_KIND);
+  }
+  
+  return TRUE;
+}
+
+static gboolean
+direction_from (GBinding *binding,
+                const GValue *from_value,
+                GValue *to_value,
+                gpointer user_data)
+{
+  int mode = g_value_get_int (from_value);
+
+  if (mode == UML_IN) {
+    g_value_set_static_string (to_value, "in");
+  } else if (mode == UML_OUT) {
+    g_value_set_static_string (to_value, "out");
+  } else if (mode == UML_INOUT) {
+    g_value_set_static_string (to_value, "inout");
+  } else {
+    g_value_set_static_string (to_value, "undefined");
+  }
+  
+  return TRUE;
+}
+
+static void
+dia_uml_operation_parameter_row_set_property (GObject      *object,
+                                       guint         property_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+  DiaUmlOperationParameterRow *self = DIA_UML_OPERATION_PARAMETER_ROW (object);
+  switch (property_id) {
+    case UML_OP_PROW_PROP_PARAMETER:
+      self->parameter = g_value_dup_object (value);
+      g_object_bind_property (G_OBJECT (self->parameter), "name",
+                              G_OBJECT (self->name), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->parameter), "type",
+                              G_OBJECT (self->type), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->parameter), "value",
+                              G_OBJECT (self->value), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+      g_object_bind_property_full (G_OBJECT (self->parameter), "kind",
+                                   G_OBJECT (self->direction), "active-id",
+                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
+                                   direction_from,
+                                   direction_to,
+                                   NULL, NULL);
+
+      g_object_bind_property (G_OBJECT (self->parameter), "comment",
+                              G_OBJECT (self->comment), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_operation_parameter_row_get_property (GObject    *object,
+                                              guint       property_id,
+                                              GValue     *value,
+                                              GParamSpec *pspec)
+{
+  DiaUmlOperationParameterRow *self = DIA_UML_OPERATION_PARAMETER_ROW (object);
+  switch (property_id) {
+    case UML_OP_PROW_PROP_PARAMETER:
+      g_value_set_object (value, self->parameter);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+move_up (DiaUmlOperationParameterRow *self)
+{
+  GtkWidget *list;
+  int index;
+
+  /*
+   * If we ever find ourselves in something other than GtkListBox we are
+   * in trouble but as a GtkListBoxRow that shouldn't happen, storing the
+   * new state is left to the GtkListBox or it's owner
+   */
+  list = gtk_widget_get_parent (GTK_WIDGET (self));
+  index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (self));
+
+  g_object_ref (self);
+  gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (self));
+  gtk_list_box_insert (GTK_LIST_BOX (list), GTK_WIDGET (self), index - 1);
+  g_object_unref (self);
+}
+
+static void
+move_down (DiaUmlOperationParameterRow *self)
+{
+  GtkWidget *list;
+  int index;
+  
+  list = gtk_widget_get_parent (GTK_WIDGET (self));
+  index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (self));
+
+  g_object_ref (self);
+  gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (self));
+  gtk_list_box_insert (GTK_LIST_BOX (list), GTK_WIDGET (self), index + 1);
+  g_object_unref (self);
+}
+
+static void
+dia_uml_operation_parameter_row_class_init (DiaUmlOperationParameterRowClass *klass)
+{
+  GFile *template_file;
+  GBytes *template;
+  GError *err = NULL;
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = dia_uml_operation_parameter_row_finalize;
+  object_class->set_property = dia_uml_operation_parameter_row_set_property;
+  object_class->get_property = dia_uml_operation_parameter_row_get_property;
+
+  uml_op_prow_properties[UML_OP_PROW_PROP_PARAMETER] =
+    g_param_spec_object ("parameter",
+                         "Parameter",
+                         "Parameter this editor controls",
+                         DIA_UML_TYPE_PARAMETER,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+  g_object_class_install_properties (object_class,
+                                     UML_OP_PROW_N_PROPS,
+                                     uml_op_prow_properties);
+
+  /* TODO: Use GResource */
+  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-operation-parameter-row.ui"));
+  template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+  if (err)
+    g_critical ("Failed to load template: %s", err->message);
+
+  gtk_widget_class_set_template (widget_class, template);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, name);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, type);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, value);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, direction);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationParameterRow, comment);
+  gtk_widget_class_bind_template_callback (widget_class, move_up);
+  gtk_widget_class_bind_template_callback (widget_class, move_down);
+
+  g_object_unref (template_file);
+}
+
+static void
+dia_uml_operation_parameter_row_init (DiaUmlOperationParameterRow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GtkWidget *
+dia_uml_operation_parameter_row_new (DiaUmlParameter *op)
+{
+  return g_object_new (DIA_UML_TYPE_OPERATION_PARAMETER_ROW,
+                       "parameter", op, 
+                       NULL);
+}
diff --git a/objects/UML/editor/dia-uml-operation-parameter-row.h 
b/objects/UML/editor/dia-uml-operation-parameter-row.h
new file mode 100644
index 00000000..b766e8a1
--- /dev/null
+++ b/objects/UML/editor/dia-uml-operation-parameter-row.h
@@ -0,0 +1,24 @@
+#include <gtk/gtk.h>
+#include "uml.h"
+
+G_BEGIN_DECLS
+
+#define DIA_UML_TYPE_OPERATION_PARAMETER_ROW (dia_uml_operation_parameter_row_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlOperationParameterRow, dia_uml_operation_parameter_row, DIA_UML, 
OPERATION_PARAMETER_ROW, GtkListBoxRow)
+
+struct _DiaUmlOperationParameterRow {
+  GtkListBoxRow parent;
+
+  GtkWidget *name;
+  GtkWidget *type;
+  GtkWidget *value;
+  GtkWidget *direction;
+  GtkTextBuffer *comment;
+
+  DiaUmlParameter *parameter;
+};
+
+GtkWidget       *dia_uml_operation_parameter_row_new           (DiaUmlParameter             *parameter);
+DiaUmlParameter *dia_uml_operation_parameter_row_get_parameter (DiaUmlOperationParameterRow *self);
+
+G_END_DECLS
diff --git a/objects/UML/editor/dia-uml-operation-row.c b/objects/UML/editor/dia-uml-operation-row.c
new file mode 100644
index 00000000..6ff0a9c2
--- /dev/null
+++ b/objects/UML/editor/dia-uml-operation-row.c
@@ -0,0 +1,159 @@
+#include "dia-uml-operation-row.h"
+#include "dia_dirs.h"
+
+G_DEFINE_TYPE (DiaUmlOperationRow, dia_uml_operation_row, GTK_TYPE_LIST_BOX_ROW)
+
+enum {
+  UML_OP_PROW_PROP_OPERATION = 1,
+  UML_OP_PROW_N_PROPS
+};
+static GParamSpec* uml_op_prow_properties[UML_OP_PROW_N_PROPS];
+
+static void
+dia_uml_operation_row_finalize (GObject *object)
+{
+  DiaUmlOperationRow *self = DIA_UML_OPERATION_ROW (object);
+
+  G_DEBUG_HERE();
+
+  g_object_unref (self->operation);
+}
+
+static void
+display_op (DiaUmlOperation    *op,
+            DiaUmlOperationRow *row)
+{
+  gtk_label_set_label (GTK_LABEL (row->title),
+                       dia_uml_operation_format (op));
+}
+
+static void
+dia_uml_operation_row_set_property (GObject      *object,
+                                    guint         property_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  DiaUmlOperationRow *self = DIA_UML_OPERATION_ROW (object);
+  switch (property_id) {
+    case UML_OP_PROW_PROP_OPERATION:
+      self->operation = g_value_dup_object (value);
+      g_signal_connect (G_OBJECT (self->operation), "changed",
+                        G_CALLBACK (display_op), self);
+      display_op (self->operation, self);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_operation_row_get_property (GObject    *object,
+                                    guint       property_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  DiaUmlOperationRow *self = DIA_UML_OPERATION_ROW (object);
+  switch (property_id) {
+    case UML_OP_PROW_PROP_OPERATION:
+      g_value_set_object (value, self->operation);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+move_up (DiaUmlOperationRow *self)
+{
+  GtkWidget *list;
+  int index;
+
+  /*
+   * If we ever find ourselves in something other than GtkListBox we are
+   * in trouble but as a GtkListBoxRow that shouldn't happen, storing the
+   * new state is left to the GtkListBox or it's owner
+   */
+  list = gtk_widget_get_parent (GTK_WIDGET (self));
+  index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (self));
+
+  g_object_ref (self);
+  gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (self));
+  gtk_list_box_insert (GTK_LIST_BOX (list), GTK_WIDGET (self), index - 1);
+  g_object_unref (self);
+}
+
+static void
+move_down (DiaUmlOperationRow *self)
+{
+  GtkWidget *list;
+  int index;
+  
+  list = gtk_widget_get_parent (GTK_WIDGET (self));
+  index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (self));
+
+  g_object_ref (self);
+  gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (self));
+  gtk_list_box_insert (GTK_LIST_BOX (list), GTK_WIDGET (self), index + 1);
+  g_object_unref (self);
+}
+
+static void
+dia_uml_operation_row_class_init (DiaUmlOperationRowClass *klass)
+{
+  GFile *template_file;
+  GBytes *template;
+  GError *err = NULL;
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = dia_uml_operation_row_finalize;
+  object_class->set_property = dia_uml_operation_row_set_property;
+  object_class->get_property = dia_uml_operation_row_get_property;
+
+  uml_op_prow_properties[UML_OP_PROW_PROP_OPERATION] =
+    g_param_spec_object ("operation",
+                         "Operation",
+                         "Operation this editor controls",
+                         DIA_UML_TYPE_OPERATION,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+  g_object_class_install_properties (object_class,
+                                     UML_OP_PROW_N_PROPS,
+                                     uml_op_prow_properties);
+
+  /* TODO: Use GResource */
+  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-operation-row.ui"));
+  template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+  if (err)
+    g_critical ("Failed to load template: %s", err->message);
+
+  gtk_widget_class_set_template (widget_class, template);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlOperationRow, title);
+  gtk_widget_class_bind_template_callback (widget_class, move_up);
+  gtk_widget_class_bind_template_callback (widget_class, move_down);
+
+  g_object_unref (template_file);
+}
+
+static void
+dia_uml_operation_row_init (DiaUmlOperationRow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GtkWidget *
+dia_uml_operation_row_new (DiaUmlOperation *operation)
+{
+  return g_object_new (DIA_UML_TYPE_OPERATION_ROW,
+                       "operation", operation, 
+                       NULL);
+}
+
+DiaUmlOperation *
+dia_uml_operation_row_get_operation (DiaUmlOperationRow *self)
+{
+  return g_object_ref (self->operation);
+}
\ No newline at end of file
diff --git a/objects/UML/editor/dia-uml-operation-row.h b/objects/UML/editor/dia-uml-operation-row.h
new file mode 100644
index 00000000..f7e23714
--- /dev/null
+++ b/objects/UML/editor/dia-uml-operation-row.h
@@ -0,0 +1,20 @@
+#include <gtk/gtk.h>
+#include "uml.h"
+
+G_BEGIN_DECLS
+
+#define DIA_UML_TYPE_OPERATION_ROW (dia_uml_operation_row_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlOperationRow, dia_uml_operation_row, DIA_UML, OPERATION_ROW, GtkListBoxRow)
+
+struct _DiaUmlOperationRow {
+  GtkListBoxRow parent;
+
+  GtkWidget *title;
+
+  DiaUmlOperation *operation;
+};
+
+GtkWidget       *dia_uml_operation_row_new           (DiaUmlOperation    *operation);
+DiaUmlOperation *dia_uml_operation_row_get_operation (DiaUmlOperationRow *self);
+
+G_END_DECLS
diff --git a/objects/UML/uml.h b/objects/UML/uml.h
index c1e073a3..4677ccca 100644
--- a/objects/UML/uml.h
+++ b/objects/UML/uml.h
@@ -22,6 +22,7 @@
 #define UML_H
 
 #include <glib.h>
+#include <gtk/gtk.h>
 #include "intl.h"
 #include "connectionpoint.h"
 #include "dia_xml.h"
@@ -95,13 +96,13 @@ struct _DiaUmlOperation {
   int class_scope;
   GList *parameters; /**< List of DiaUmlParameter */
 
-  ConnectionPoint* left_connection; /**< left */
-  ConnectionPoint* right_connection; /**< right */
+  ConnectionPoint* l_connection; /**< left */
+  ConnectionPoint* r_connection; /**< right */
 
   gboolean needs_wrapping; /** Whether this operation needs wrapping */
   gint wrap_indent; /** The amount of indentation in chars */
   GList *wrappos; /** Absolute wrapping positions */
-  real ascent; /** The ascent amount used for line distance in wrapping */
+  double ascent; /** The ascent amount used for line distance in wrapping */
 };
 
 
@@ -136,15 +137,15 @@ struct _UMLFormalParameter {
 #define UML_STEREOTYPE_END _(">>")
 
 /** calculated the 'formated' representation */
-extern gchar *uml_get_attribute_string (UMLAttribute *attribute);
+gchar *uml_get_attribute_string (UMLAttribute *attribute);
 /** calculated the 'formated' representation */
-extern gchar *uml_get_formalparameter_string(UMLFormalParameter *parameter);
-extern void uml_attribute_copy_into(UMLAttribute *srcattr, UMLAttribute *destattr);
-extern UMLAttribute *uml_attribute_copy(UMLAttribute *attr);
-extern UMLFormalParameter *uml_formalparameter_copy(UMLFormalParameter *param);
-extern void uml_attribute_destroy(UMLAttribute *attribute);
-extern void uml_formalparameter_destroy(UMLFormalParameter *param);
-extern UMLAttribute *uml_attribute_new(void);
+gchar *uml_get_formalparameter_string(UMLFormalParameter *parameter);
+void uml_attribute_copy_into(UMLAttribute *srcattr, UMLAttribute *destattr);
+UMLAttribute *uml_attribute_copy(UMLAttribute *attr);
+UMLFormalParameter *uml_formalparameter_copy(UMLFormalParameter *param);
+void uml_attribute_destroy(UMLAttribute *attribute);
+void uml_formalparameter_destroy(UMLFormalParameter *param);
+UMLAttribute *uml_attribute_new(void);
 
 DiaUmlOperation *dia_uml_operation_new                      ();
 /** calculated the 'formated' representation */
@@ -165,13 +166,17 @@ DiaUmlParameter *dia_uml_parameter_new                      ();
 /** calculated the 'formated' representation */
 gchar           *dia_uml_parameter_format                   (DiaUmlParameter *param);
 
-extern UMLFormalParameter *uml_formalparameter_new(void);
+UMLFormalParameter *uml_formalparameter_new(void);
+
+void uml_attribute_ensure_connection_points (UMLAttribute *attr, DiaObject* obj);
 
-extern void uml_attribute_ensure_connection_points (UMLAttribute *attr, DiaObject* obj);
+void uml_attribute_write(AttributeNode attr_node, UMLAttribute *attr, DiaContext *ctx);
+void uml_operation_write(AttributeNode attr_node, DiaUmlOperation *op, DiaContext *ctx);
+void uml_formalparameter_write(AttributeNode attr_node, UMLFormalParameter *param, DiaContext *ctx);
 
-extern void uml_attribute_write(AttributeNode attr_node, UMLAttribute *attr, DiaContext *ctx);
-extern void uml_operation_write(AttributeNode attr_node, DiaUmlOperation *op, DiaContext *ctx);
-extern void uml_formalparameter_write(AttributeNode attr_node, UMLFormalParameter *param, DiaContext *ctx);
+void list_box_separators (GtkListBoxRow *row,
+                          GtkListBoxRow *before,
+                          gpointer       user_data);
 
 #endif /* UML_H */
 
diff --git a/objects/UML/umloperation.c b/objects/UML/umloperation.c
index 1378f2bd..7dac7f05 100644
--- a/objects/UML/umloperation.c
+++ b/objects/UML/umloperation.c
@@ -69,6 +69,12 @@ enum {
 };
 static GParamSpec* uml_op_properties[UML_OP_N_PROPS];
 
+enum {
+  OP_CHANGED,
+  OP_LAST_SIGNAL
+};
+static guint uml_op_signals[OP_LAST_SIGNAL] = { 0 };
+
 extern PropEnumData _uml_visibilities[];
 extern PropEnumData _uml_inheritances[];
 
@@ -167,26 +173,22 @@ dia_uml_operation_copy (DiaUmlOperation *srcop)
   list = destop->parameters;
   while (list != NULL) {
     param = (DiaUmlParameter *)list->data;
-    g_object_unref (G_OBJECT (param));
-    list = g_list_next(list);
+    dia_uml_operation_remove_parameter (destop, param);
+    list = g_list_next (list);
   }
   destop->parameters = NULL;
   list = srcop->parameters;
   while (list != NULL) {
     param = (DiaUmlParameter *)list->data;
 
-    newparam = g_new0(DiaUmlParameter, 1);
+    newparam = dia_uml_parameter_new ();
     newparam->name = g_strdup(param->name);
     newparam->type = g_strdup(param->type);
     newparam->comment = g_strdup(param->comment);
-
-    if (param->value != NULL)
-      newparam->value = g_strdup(param->value);
-    else
-      newparam->value = NULL;
+    newparam->value = g_strdup(param->value);
     newparam->kind = param->kind;
-    
-    destop->parameters = g_list_append(destop->parameters, newparam);
+
+    dia_uml_operation_insert_parameter (destop, newparam, -1);
     
     list = g_list_next(list);
   }
@@ -381,7 +383,7 @@ dia_uml_operation_format (DiaUmlOperation *operation)
     strcat(str, " const");
   }
 
-  g_assert (strlen (str) == len);
+  g_assert_cmpint (strlen (str), ==, len);
   
   return str;
 }
@@ -404,35 +406,25 @@ dia_uml_operation_format (DiaUmlOperation *operation)
 void
 dia_uml_operation_ensure_connection_points (DiaUmlOperation* op, DiaObject* obj)
 {
-  if (!op->left_connection)
-    op->left_connection = g_new0(ConnectionPoint,1);
-  op->left_connection->object = obj;
-  if (!op->right_connection)
-    op->right_connection = g_new0(ConnectionPoint,1);
-  op->right_connection->object = obj;
+  if (!op->l_connection)
+    op->l_connection = g_new0(ConnectionPoint,1);
+  op->l_connection->object = obj;
+  if (!op->r_connection)
+    op->r_connection = g_new0(ConnectionPoint,1);
+  op->r_connection->object = obj;
 }
 
 static void
 dia_uml_operation_finalize (GObject *object)
 {
-  GList *list;
-  DiaUmlParameter *param;
   DiaUmlOperation *self = DIA_UML_OPERATION (object);
-  
-  g_free (self->name);
-  if (self->type != NULL)
-    g_free (self->type);
-  if (self->stereotype != NULL)
-    g_free (self->stereotype);
 
+  g_free (self->name);
+  g_free (self->type);
+  g_free (self->stereotype);
   g_free (self->comment);
 
-  list = self->parameters;
-  while (list != NULL) {
-    param = (DiaUmlParameter *)list->data;
-    g_object_unref (G_OBJECT (param));
-    list = g_list_next(list);
-  }
+  g_list_free_full (self->parameters, g_object_unref);
   if (self->wrappos) {
     g_list_free (self->wrappos);
   }
@@ -457,34 +449,42 @@ dia_uml_operation_set_property (GObject      *object,
     case UML_OP_NAME:
       self->name = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_NAME]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_TYPE:
       self->type = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_TYPE]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_COMMENT:
       self->comment = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_COMMENT]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_STEREOTYPE:
       self->stereotype = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_STEREOTYPE]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_VISIBILITY:
       self->visibility = g_value_get_int (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_VISIBILITY]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_INHERITANCE_TYPE:
       self->inheritance_type = g_value_get_int (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_INHERITANCE_TYPE]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_QUERY:
       self->query = g_value_get_boolean (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_QUERY]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     case UML_OP_CLASS_SCOPE:
       self->class_scope = g_value_get_boolean (value);
       g_object_notify_by_pspec (object, uml_op_properties[UML_OP_CLASS_SCOPE]);
+      g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -588,6 +588,12 @@ dia_uml_operation_class_init (DiaUmlOperationClass *klass)
   g_object_class_install_properties (object_class,
                                      UML_OP_N_PROPS,
                                      uml_op_properties);
+
+  uml_op_signals[OP_CHANGED] = g_signal_new ("changed",
+                                             G_TYPE_FROM_CLASS (klass),
+                                             G_SIGNAL_RUN_FIRST,
+                                             0, NULL, NULL, NULL,
+                                             G_TYPE_NONE, 0);
 }
 
 static void
@@ -596,8 +602,11 @@ dia_uml_operation_init (DiaUmlOperation *self)
   static gint next_id = 1;
 
   self->internal_id = next_id++;
+
   self->name = g_strdup("");
   self->comment = g_strdup("");
+  self->type = g_strdup("");
+  self->stereotype = g_strdup("");
   self->visibility = UML_PUBLIC;
   self->inheritance_type = UML_LEAF;
 }
@@ -608,14 +617,23 @@ dia_uml_operation_new ()
   return g_object_new (DIA_UML_TYPE_OPERATION, NULL);
 }
 
+static void
+bubble (DiaUmlParameter *para,
+        DiaUmlOperation *self)
+{
+  g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
+}
+
 void
 dia_uml_operation_insert_parameter (DiaUmlOperation *self,
                                     DiaUmlParameter *parameter,
                                     int              index)
 {
   self->parameters = g_list_insert (self->parameters,
-                                    g_object_ref (G_OBJECT (parameter)),
+                                    g_object_ref (parameter),
                                     index);
+  g_signal_connect (G_OBJECT (parameter), "changed", G_CALLBACK (bubble), self);
+  g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
 }
 
 void
@@ -623,5 +641,7 @@ dia_uml_operation_remove_parameter (DiaUmlOperation *self,
                                     DiaUmlParameter *parameter)
 {
   self->parameters = g_list_remove (self->parameters, parameter);
-  g_object_unref (G_OBJECT (parameter));
+  g_signal_handlers_disconnect_by_func (G_OBJECT (parameter), G_CALLBACK (bubble), self);
+  g_object_unref (parameter);
+  g_signal_emit (G_OBJECT (self), uml_op_signals[OP_CHANGED], 0);
 }
diff --git a/objects/UML/umlparameter.c b/objects/UML/umlparameter.c
index d7a0fa9a..abc24f18 100644
--- a/objects/UML/umlparameter.c
+++ b/objects/UML/umlparameter.c
@@ -42,6 +42,12 @@ enum {
 };
 static GParamSpec* uml_para_properties[UML_PARA_N_PROPS];
 
+enum {
+  PARAM_CHANGED,
+  PARAM_LAST_SIGNAL
+};
+static guint uml_param_signals[PARAM_LAST_SIGNAL] = { 0 };
+
 static PropEnumData _uml_parameter_kinds[] = {
   { N_("Undefined"), UML_UNDEF_KIND} ,
   { N_("In"), UML_IN },
@@ -166,22 +172,27 @@ dia_uml_parameter_set_property (GObject      *object,
     case UML_PARA_NAME:
       self->name = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_para_properties[UML_PARA_NAME]);
+      g_signal_emit (G_OBJECT (self), uml_param_signals[PARAM_CHANGED], 0);
       break;
     case UML_PARA_TYPE:
       self->type = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_para_properties[UML_PARA_TYPE]);
+      g_signal_emit (G_OBJECT (self), uml_param_signals[PARAM_CHANGED], 0);
       break;
     case UML_PARA_VALUE:
       self->value = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_para_properties[UML_PARA_VALUE]);
+      g_signal_emit (G_OBJECT (self), uml_param_signals[PARAM_CHANGED], 0);
       break;
     case UML_PARA_COMMENT:
       self->comment = g_value_dup_string (value);
       g_object_notify_by_pspec (object, uml_para_properties[UML_PARA_COMMENT]);
+      g_signal_emit (G_OBJECT (self), uml_param_signals[PARAM_CHANGED], 0);
       break;
     case UML_PARA_KIND:
       self->kind = g_value_get_int (value);
       g_object_notify_by_pspec (object, uml_para_properties[UML_PARA_KIND]);
+      g_signal_emit (G_OBJECT (self), uml_param_signals[PARAM_CHANGED], 0);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -259,6 +270,13 @@ dia_uml_parameter_class_init (DiaUmlParameterClass *klass)
   g_object_class_install_properties (object_class,
                                      UML_PARA_N_PROPS,
                                      uml_para_properties);
+
+
+  uml_param_signals[PARAM_CHANGED] = g_signal_new ("changed",
+                                                   G_TYPE_FROM_CLASS (klass),
+                                                   G_SIGNAL_RUN_FIRST,
+                                                   0, NULL, NULL, NULL,
+                                                   G_TYPE_NONE, 0);
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]