[dia] uml: port operations to GtkTreeView



commit 96453becc9efb8701d51f02b35caeaaa342df62a
Author: Zander Brown <zbrown gnome org>
Date:   Sat Oct 12 23:49:14 2019 +0100

    uml: port operations to GtkTreeView
    
    The operations tab is now free of deprecated widgets
    
    Preview text is now updated in real-time and has formatting similar to that used in the diagram itself

 objects/UML/class.c                   |    2 +-
 objects/UML/class_dialog.c            |   18 +-
 objects/UML/class_dialog.h            |    5 +-
 objects/UML/class_operations_dialog.c | 1112 ++++++++++++++++++++-------------
 objects/UML/uml.h                     |    3 +-
 objects/UML/umloperation.c            |   29 +-
 6 files changed, 701 insertions(+), 468 deletions(-)
---
diff --git a/objects/UML/class.c b/objects/UML/class.c
index 6c0508ee..3afb39f3 100644
--- a/objects/UML/class.c
+++ b/objects/UML/class.c
@@ -1969,7 +1969,7 @@ umlclass_destroy(UMLClass *umlclass)
     op = (UMLOperation *)list->data;
     g_free (op->left_connection);
     g_free (op->right_connection);
-    uml_operation_free (op);
+    uml_operation_unref (op);
     list = g_list_next (list);
   }
   g_list_free (umlclass->operations);
diff --git a/objects/UML/class_dialog.c b/objects/UML/class_dialog.c
index 8f14c4de..a1bca815 100644
--- a/objects/UML/class_dialog.c
+++ b/objects/UML/class_dialog.c
@@ -554,7 +554,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);
   }
 }
@@ -606,10 +605,12 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
     num_attrib = g_list_length(prop_dialog->attributes_list->children);
   else
     num_attrib = 0;
-  if ( (gtk_toggle_button_get_active (prop_dialog->op_vis)) && (!gtk_toggle_button_get_active 
(prop_dialog->op_supp)))
-    num_ops = g_list_length(prop_dialog->operations_list->children);
-  else
+  if (gtk_toggle_button_get_active (prop_dialog->op_vis) &&
+      (!gtk_toggle_button_get_active (prop_dialog->op_supp))) {
+    num_ops = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (prop_dialog->operations_store), NULL);
+  } else {
     num_ops = 0;
+  }
   obj = &umlclass->element.object;
 #ifdef UML_MAINPOINT
   obj->num_connections =
@@ -697,7 +698,6 @@ umlclass_get_properties(UMLClass *umlclass, gboolean is_default)
     prop_dialog->dialog = vbox;
 
     prop_dialog->current_attr = NULL;
-    prop_dialog->current_op = NULL;
     prop_dialog->current_templ = NULL;
     prop_dialog->deleted_connections = NULL;
     prop_dialog->added_connections = NULL;
@@ -756,7 +756,7 @@ umlclass_free_state(UMLClassState *state)
   }
   g_list_free(state->attributes);
 
-  g_list_free_full (state->operations, (GDestroyNotify) uml_operation_free);
+  g_list_free_full (state->operations, (GDestroyNotify) uml_operation_unref);
 
   list = state->formal_params;
   while (list) {
@@ -919,8 +919,10 @@ umlclass_update_connectionpoints(UMLClass *umlclass)
 
     list = g_list_next(list);
   }
-  if (prop_dialog)
-    gtk_list_clear_items (GTK_LIST (prop_dialog->operations_list), 0, -1);
+
+  if (prop_dialog) {
+    gtk_list_store_clear (prop_dialog->operations_store);
+  }
 
 #ifdef UML_MAINPOINT
   obj->connections[connection_index++] = &umlclass->connections[UMLCLASS_CONNECTIONPOINTS];
diff --git a/objects/UML/class_dialog.h b/objects/UML/class_dialog.h
index 341a264a..edb52ca2 100644
--- a/objects/UML/class_dialog.h
+++ b/objects/UML/class_dialog.h
@@ -54,12 +54,13 @@ struct _UMLClassDialog {
   GtkWidget *attr_visible;
   GtkToggleButton *attr_class_scope;
 
-  GtkList *operations_list;
-  GtkListItem *current_op;
+  GtkWidget *operations;
+  GtkListStore *operations_store;
   GtkEntry *op_name;
   GtkEntry *op_type;
   GtkEntry *op_stereotype;
   GtkTextView *op_comment;
+  GtkTextBuffer *op_comment_buffer;
 
   GtkWidget *op_visible;
   GtkToggleButton *op_class_scope;
diff --git a/objects/UML/class_operations_dialog.c b/objects/UML/class_operations_dialog.c
index 83be47d8..26fd74a1 100644
--- a/objects/UML/class_operations_dialog.c
+++ b/objects/UML/class_operations_dialog.c
@@ -16,10 +16,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#include <config.h>
 
-#include <assert.h>
-#undef GTK_DISABLE_DEPRECATED /* GtkList, ... */
+#include "config.h"
+
 #include <gtk/gtk.h>
 
 #include "class.h"
@@ -38,14 +37,132 @@ enum {
 };
 
 
+enum {
+  COL_OPER_TITLE,
+  COL_OPER_OPER,
+  COL_OPER_UNDERLINE,
+  COL_OPER_BOLD,
+  COL_OPER_ITALIC,
+  N_OPER_COLS
+};
+
+
+
+static gboolean
+get_current_operation (UMLClassDialog  *dialog,
+                       UMLOperation   **oper,
+                       GtkTreeIter     *c_iter)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeSelection *selection;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->operations));
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+    gtk_tree_model_get (model, &iter, COL_OPER_OPER, oper, -1);
+
+    if (c_iter) {
+      *c_iter = iter;
+    }
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+static void
+update_operation (UMLClassDialog *dialog,
+                  UMLOperation   *op,
+                  GtkTreeIter    *iter)
+{
+  PangoUnderline underline;
+  PangoStyle italic = PANGO_STYLE_NORMAL;
+  int weight = 400;
+  char *title;
+
+  underline = op->class_scope ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE;
+  if (op->inheritance_type != UML_LEAF) {
+    italic = PANGO_STYLE_ITALIC;
+    if (op->inheritance_type == UML_ABSTRACT) {
+      weight = 800;
+    }
+  }
+  title = uml_get_operation_string (op);
+
+  gtk_list_store_set (dialog->operations_store,
+                      iter,
+                      COL_OPER_OPER, op,
+                      COL_OPER_TITLE, title,
+                      COL_OPER_UNDERLINE, underline,
+                      COL_OPER_BOLD, weight,
+                      COL_OPER_ITALIC, italic,
+                      -1);
+
+  g_clear_pointer (&title, g_free);
+}
+
+
+static gboolean
+get_current_parameter (UMLClassDialog  *dialog,
+                       UMLParameter   **param,
+                       GtkTreeIter     *c_iter)
+{
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GtkTreeSelection *selection;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->parameters));
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, param, -1);
+
+    if (c_iter) {
+      *c_iter = iter;
+    }
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+static void
+update_parameter (UMLClassDialog *dialog,
+                  UMLParameter   *param,
+                  GtkTreeIter    *iter)
+{
+  UMLOperation *op;
+  GtkTreeIter op_iter;
+  char *title;
+
+  title = uml_parameter_get_string (param);
+
+  gtk_list_store_set (dialog->parameters_store,
+                      iter,
+                      COL_PARAM_PARAM, param,
+                      COL_PARAM_TITLE, title,
+                      -1);
+
+  if (get_current_operation (dialog, &op, &op_iter)) {
+    update_operation (dialog, op, &op_iter);
+
+    g_clear_pointer (&op, uml_operation_unref);
+  }
+
+  g_clear_pointer (&title, g_free);
+}
+
+
 static void
-parameters_set_sensitive(UMLClassDialog *prop_dialog, gint val)
+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);
+  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);
 }
 
 
@@ -78,10 +195,10 @@ parameters_clear_values (UMLClassDialog *prop_dialog)
 
 
 static gboolean
-add_to_list (GtkTreeModel *model,
-             GtkTreePath *path,
-             GtkTreeIter *iter,
-             gpointer data)
+add_param_to_list (GtkTreeModel *model,
+                   GtkTreePath *path,
+                   GtkTreeIter *iter,
+                   gpointer data)
 {
   UMLOperation *op = data;
   UMLParameter *param = NULL;
@@ -102,7 +219,7 @@ sync_params_to_operation (GtkTreeModel *model,
   g_list_free_full (op->parameters, (GDestroyNotify) uml_parameter_unref);
   op->parameters = NULL;
 
-  gtk_tree_model_foreach (model, add_to_list, op);
+  gtk_tree_model_foreach (model, add_param_to_list, op);
 }
 
 
@@ -119,19 +236,17 @@ parameters_list_new_callback (GtkWidget *button,
 
   prop_dialog = umlclass->properties_dialog;
 
-  current_op = (UMLOperation *)
-    g_object_get_data (G_OBJECT (prop_dialog->current_op), "user_data");
+  if (!get_current_operation (prop_dialog, &current_op, NULL)) {
+    return;
+  }
 
   param = uml_parameter_new ();
 
   utf = uml_parameter_get_string (param);
 
   gtk_list_store_append (prop_dialog->parameters_store, &iter);
-  gtk_list_store_set (prop_dialog->parameters_store,
-                      &iter,
-                      COL_PARAM_TITLE, utf,
-                      COL_PARAM_PARAM, param,
-                      -1);
+  update_parameter (prop_dialog, param, &iter);
+
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
   gtk_tree_selection_select_iter (selection, &iter);
 
@@ -140,6 +255,7 @@ parameters_list_new_callback (GtkWidget *button,
 
   g_clear_pointer (&utf, g_free);
   g_clear_pointer (&param, uml_parameter_unref);
+  g_clear_pointer (&current_op, uml_operation_unref);
 }
 
 
@@ -151,24 +267,22 @@ parameters_list_delete_callback (GtkWidget *button,
   UMLOperation *current_op;
   UMLParameter *param;
   GtkTreeIter iter;
-  GtkTreeSelection *selection;
-  GtkTreeModel *model;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, &param, -1);
-
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
     /* Remove from current operations parameter list: */
-    current_op = (UMLOperation *)
-      g_object_get_data (G_OBJECT (prop_dialog->current_op), "user_data");
+    if (!get_current_operation (prop_dialog, &current_op, NULL)) {
+      return;
+    }
 
     gtk_list_store_remove (prop_dialog->parameters_store, &iter);
 
-    sync_params_to_operation (model, current_op);
+    sync_params_to_operation (GTK_TREE_MODEL (prop_dialog->parameters_store),
+                              current_op);
 
     g_clear_pointer (&param, uml_parameter_unref);
+    g_clear_pointer (&current_op, uml_operation_unref);
   }
 }
 
@@ -179,55 +293,65 @@ parameters_list_move_up_callback (GtkWidget *button,
 {
   UMLClassDialog *prop_dialog;
   UMLOperation *current_op;
+  UMLParameter *param;
   GtkTreeIter iter;
-  GtkTreeSelection *selection;
-  GtkTreeModel *model;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
+    GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (prop_dialog->parameters_store),
+                                                 &iter);
+    GtkTreeSelection *selection;
     GtkTreeIter prev;
+    GtkTreeIter op_iter;
 
     if (path != NULL && gtk_tree_path_prev (path)
-        && gtk_tree_model_get_iter (model, &prev, path)) {
+        && gtk_tree_model_get_iter (GTK_TREE_MODEL (prop_dialog->parameters_store), &prev, path)) {
       gtk_list_store_move_before (prop_dialog->parameters_store, &iter, &prev);
     } else {
       gtk_list_store_move_before (prop_dialog->parameters_store, &iter, NULL);
     }
     gtk_tree_path_free (path);
 
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
     gtk_tree_selection_select_iter (selection, &iter);
 
     /* Move parameter in current operations list: */
-    current_op = (UMLOperation *)
-      g_object_get_data (G_OBJECT (prop_dialog->current_op), "user_data");
+    if (get_current_operation (prop_dialog, &current_op, &op_iter)) {
+      sync_params_to_operation (GTK_TREE_MODEL (prop_dialog->parameters_store),
+                                current_op);
 
-    sync_params_to_operation (model, current_op);
+      update_operation (prop_dialog, current_op, &op_iter);
+
+      g_clear_pointer (&current_op, uml_operation_unref);
+    }
+
+    g_clear_pointer (&param, uml_parameter_unref);
   }
 }
 
+
 static void
 parameters_list_move_down_callback (GtkWidget *button,
                                     UMLClass  *umlclass)
 {
   UMLClassDialog *prop_dialog;
   UMLOperation *current_op;
+  UMLParameter *param;
   GtkTreeIter iter;
-  GtkTreeSelection *selection;
-  GtkTreeModel *model;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    GtkTreePath *path = gtk_tree_model_get_path (model,  &iter);
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
+    GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (prop_dialog->parameters_store),
+                                                 &iter);
+    GtkTreeSelection *selection;
     GtkTreeIter prev;
+    GtkTreeIter op_iter;
 
     if (path != NULL) {
       gtk_tree_path_next (path);
-      if (gtk_tree_model_get_iter (model, &prev, path)) {
+      if (gtk_tree_model_get_iter (GTK_TREE_MODEL (prop_dialog->parameters_store), &prev, path)) {
         gtk_list_store_move_after (prop_dialog->parameters_store, &iter, &prev);
       } else {
         gtk_list_store_move_after (prop_dialog->parameters_store, &iter, NULL);
@@ -237,32 +361,44 @@ parameters_list_move_down_callback (GtkWidget *button,
     }
     gtk_tree_path_free (path);
 
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
     gtk_tree_selection_select_iter (selection, &iter);
 
     /* Move parameter in current operations list: */
-    current_op = (UMLOperation *)
-      g_object_get_data (G_OBJECT (prop_dialog->current_op), "user_data");
+    if (get_current_operation (prop_dialog, &current_op, &op_iter)) {
+      sync_params_to_operation (GTK_TREE_MODEL (prop_dialog->parameters_store),
+                                current_op);
+
+      update_operation (prop_dialog, current_op, &op_iter);
+
+      g_clear_pointer (&current_op, uml_operation_unref);
+    }
 
-    sync_params_to_operation (model, current_op);
+    g_clear_pointer (&param, uml_parameter_unref);
   }
 }
 
+
 static void
-operations_set_sensitive(UMLClassDialog *prop_dialog, gint val)
+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);
+  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);
+
+  if (!val) {
+    parameters_set_sensitive (prop_dialog, FALSE);
+  }
 }
 
 
@@ -277,8 +413,9 @@ operations_set_values (UMLClassDialog *prop_dialog, UMLOperation *op)
   gtk_entry_set_text (prop_dialog->op_name, op->name? op->name : "");
   gtk_entry_set_text (prop_dialog->op_type, op->type? op->type : "");
   gtk_entry_set_text (prop_dialog->op_stereotype, op->stereotype? op->stereotype : "");
-
-  _class_set_comment (prop_dialog->op_comment, op->comment? op->comment : "");
+  gtk_text_buffer_set_text (prop_dialog->op_comment_buffer,
+                            op->comment? g_strdup (op->comment) : "",
+                            -1);
 
   dia_option_menu_set_active (DIA_OPTION_MENU (prop_dialog->op_visible),
                               op->visibility);
@@ -297,11 +434,7 @@ operations_set_values (UMLClassDialog *prop_dialog, UMLOperation *op)
     str = uml_parameter_get_string (param);
 
     gtk_list_store_append (prop_dialog->parameters_store, &iter);
-    gtk_list_store_set (prop_dialog->parameters_store,
-                        &iter,
-                        COL_PARAM_TITLE, str,
-                        COL_PARAM_PARAM, param,
-                        -1);
+    update_parameter (prop_dialog, param, &iter);
 
     g_free (str);
 
@@ -309,371 +442,407 @@ operations_set_values (UMLClassDialog *prop_dialog, UMLOperation *op)
   }
 }
 
+
 static void
-operations_clear_values(UMLClassDialog *prop_dialog)
+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);
+  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);
 
   gtk_list_store_clear (prop_dialog->parameters_store);
 
-  parameters_set_sensitive(prop_dialog, FALSE);
+  parameters_set_sensitive (prop_dialog, FALSE);
 }
 
 
 static void
-operations_get_values (UMLClassDialog *prop_dialog,
-                       UMLOperation   *op)
+operations_list_new_callback (GtkWidget *button,
+                              UMLClass  *umlclass)
 {
-  g_clear_pointer (&op->name, g_free);
-  g_clear_pointer (&op->type, g_free);
-  g_clear_pointer (&op->comment, g_free);
-  g_clear_pointer (&op->stereotype, g_free);
+  UMLClassDialog *prop_dialog;
+  UMLOperation *op;
+  GtkTreeIter iter;
+  GtkTreeSelection *selection;
 
-  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 = _class_get_comment (prop_dialog->op_comment);
-  op->stereotype = g_strdup (gtk_entry_get_text (prop_dialog->op_stereotype));
+  prop_dialog = umlclass->properties_dialog;
 
-  op->visibility = (UMLVisibility) dia_option_menu_get_active (DIA_OPTION_MENU (prop_dialog->op_visible));
+  op = uml_operation_new ();
 
-  op->class_scope = gtk_toggle_button_get_active (prop_dialog->op_class_scope);
-  op->inheritance_type = (UMLInheritanceType) dia_option_menu_get_active (DIA_OPTION_MENU 
(prop_dialog->op_inheritance_type));
+  /* need to make new ConnectionPoints valid and remember them */
+  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);
 
-  op->query = gtk_toggle_button_get_active (prop_dialog->op_query);
+  gtk_list_store_append (prop_dialog->operations_store, &iter);
+  update_operation (prop_dialog, op, &iter);
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->operations));
+  gtk_tree_selection_select_iter (selection, &iter);
+
+  g_clear_pointer (&op, uml_operation_unref);
 }
 
 
-void
-_operations_get_current_values (UMLClassDialog *prop_dialog)
+static void
+operations_list_delete_callback (GtkWidget *button,
+                                 UMLClass  *umlclass)
 {
-  UMLOperation *current_op;
-  GtkLabel *label;
-  char *new_str;
-
-  if (prop_dialog->current_op != NULL) {
-    current_op = (UMLOperation *)
-      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 = uml_get_operation_string (current_op);
-      gtk_label_set_text (label, new_str);
-      g_free (new_str);
+  UMLClassDialog *prop_dialog;
+  UMLOperation *op;
+  GtkTreeIter iter;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    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);
     }
+
+    gtk_list_store_remove (prop_dialog->operations_store, &iter);
+
+    g_clear_pointer (&op, uml_operation_unref);
   }
 }
 
 
 static void
-operations_list_item_destroy_callback(GtkWidget *list_item,
-                                     gpointer data)
+operations_list_move_up_callback (GtkWidget *button,
+                                  UMLClass  *umlclass)
 {
-  UMLOperation *op;
+  UMLClassDialog *prop_dialog;
+  UMLOperation *current_op;
+  GtkTreeIter iter;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  if (get_current_operation (prop_dialog, &current_op, &iter)) {
+    GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (prop_dialog->operations_store),
+                                                 &iter);
+    GtkTreeSelection *selection;
+    GtkTreeIter prev;
+
+    if (path != NULL && gtk_tree_path_prev (path)
+        && gtk_tree_model_get_iter (GTK_TREE_MODEL (prop_dialog->operations_store), &prev, path)) {
+      gtk_list_store_move_before (prop_dialog->operations_store, &iter, &prev);
+    } else {
+      gtk_list_store_move_before (prop_dialog->operations_store, &iter, NULL);
+    }
+    gtk_tree_path_free (path);
 
-  op = (UMLOperation *) g_object_get_data(G_OBJECT(list_item), "user_data");
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->operations));
+    gtk_tree_selection_select_iter (selection, &iter);
 
-  if (op != NULL) {
-    uml_operation_free (op);
-    /*printf("Destroying operation list_item's user_data!\n");*/
+    g_clear_pointer (&current_op, uml_operation_unref);
   }
 }
 
+
 static void
-operations_list_selection_changed_callback(GtkWidget *gtklist,
-                                          UMLClass *umlclass)
+operations_list_move_down_callback(GtkWidget *button,
+                                   UMLClass  *umlclass)
 {
-  GList *list;
   UMLClassDialog *prop_dialog;
-  GObject *list_item;
-  UMLOperation *op;
+  UMLOperation *current_op;
+  GtkTreeIter iter;
 
   prop_dialog = umlclass->properties_dialog;
 
-  if (!prop_dialog)
-    return; /* maybe hiding a bug elsewhere */
+  if (get_current_operation (prop_dialog, &current_op, &iter)) {
+    GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (prop_dialog->operations_store),
+                                                 &iter);
+    GtkTreeSelection *selection;
+    GtkTreeIter prev;
 
-  _operations_get_current_values(prop_dialog);
+    if (path != NULL) {
+      gtk_tree_path_next (path);
+      if (gtk_tree_model_get_iter (GTK_TREE_MODEL (prop_dialog->operations_store), &prev, path)) {
+        gtk_list_store_move_after (prop_dialog->operations_store, &iter, &prev);
+      } else {
+        gtk_list_store_move_after (prop_dialog->operations_store, &iter, NULL);
+      }
+    } else {
+      gtk_list_store_move_after (prop_dialog->operations_store, &iter, NULL);
+    }
+    gtk_tree_path_free (path);
 
-  list = GTK_LIST(gtklist)->selection;
-  if (!list) { /* No selected */
-    operations_set_sensitive(prop_dialog, FALSE);
-    operations_clear_values(prop_dialog);
-    prop_dialog->current_op = NULL;
-    return;
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->operations));
+    gtk_tree_selection_select_iter (selection, &iter);
+
+    g_clear_pointer (&current_op, uml_operation_unref);
+  }
+}
+
+
+struct AddOperData {
+  UMLClass       *class;
+  UMLClassDialog *dialog;
+  int             connection_index;
+};
+
+
+static gboolean
+add_oper_to_list (GtkTreeModel *model,
+                  GtkTreePath *path,
+                  GtkTreeIter *iter,
+                  gpointer udata)
+{
+  struct AddOperData *data = udata;
+  UMLOperation *op = NULL;
+
+  // Don't free op, transfering to the list
+  gtk_tree_model_get (model, iter, COL_OPER_OPER, &op, -1);
+
+  data->class->operations = g_list_append (data->class->operations, op);
+
+  if (op->left_connection == NULL) {
+    uml_operation_ensure_connection_points (op, DIA_OBJECT (data->class));
+
+    data->dialog->added_connections =
+      g_list_prepend (data->dialog->added_connections,
+                      op->left_connection);
+    data->dialog->added_connections =
+      g_list_prepend (data->dialog->added_connections,
+                      op->right_connection);
   }
 
-  list_item = G_OBJECT(list->data);
-  op = (UMLOperation *)g_object_get_data(G_OBJECT(list_item), "user_data");
-  operations_set_values(prop_dialog, op);
-  operations_set_sensitive(prop_dialog, TRUE);
+  if (gtk_toggle_button_get_active (data->dialog->op_vis) &&
+      (!gtk_toggle_button_get_active (data->dialog->op_supp))) {
+    DIA_OBJECT (data->class)->connections[data->connection_index] = op->left_connection;
+    data->connection_index++;
+    DIA_OBJECT (data->class)->connections[data->connection_index] = op->right_connection;
+    data->connection_index++;
+  } else {
+    _umlclass_store_disconnects (data->dialog, op->left_connection);
+    object_remove_connections_to (op->left_connection);
+    _umlclass_store_disconnects (data->dialog, op->right_connection);
+    object_remove_connections_to (op->right_connection);
+  }
 
-  prop_dialog->current_op = GTK_LIST_ITEM(list_item);
-  gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->op_name));
+  return FALSE;
 }
 
-static void
-operations_list_new_callback(GtkWidget *button,
-                            UMLClass *umlclass)
+
+void
+_operations_read_from_dialog (UMLClass       *umlclass,
+                              UMLClassDialog *prop_dialog,
+                              int             connection_index)
+{
+  struct AddOperData data;
+
+  /* Free current operations: */
+  g_list_free_full (umlclass->operations, (GDestroyNotify) uml_operation_unref);
+  umlclass->operations = NULL;
+
+  data.class = umlclass;
+  data.dialog = prop_dialog;
+  data.connection_index = connection_index;
+
+  gtk_tree_model_foreach (GTK_TREE_MODEL (prop_dialog->operations_store),
+                          add_oper_to_list,
+                          &data);
+  gtk_list_store_clear (prop_dialog->operations_store);
+  operations_set_sensitive (prop_dialog, FALSE);
+}
+
+
+void
+_operations_fill_in_dialog (UMLClass *umlclass)
 {
-  GList *list;
   UMLClassDialog *prop_dialog;
-  GtkWidget *list_item;
-  UMLOperation *op;
-  char *utfstr;
+  UMLOperation *op_copy;
+  GtkTreeIter iter;
+  GList *list;
 
   prop_dialog = umlclass->properties_dialog;
 
-  _operations_get_current_values(prop_dialog);
+  gtk_list_store_clear (prop_dialog->operations_store);
 
-  op = uml_operation_new();
-  /* need to make new ConnectionPoints valid and remember them */
-  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);
+  list = umlclass->operations;
+  while (list != NULL) {
+    UMLOperation *op = (UMLOperation *) list->data;
 
+    op_copy = uml_operation_copy (op);
 
-  utfstr = uml_get_operation_string (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;
 
-  list_item = gtk_list_item_new_with_label (utfstr);
-  gtk_widget_show (list_item);
-  g_free (utfstr);
+    gtk_list_store_append (prop_dialog->operations_store, &iter);
+    update_operation (prop_dialog, op_copy, &iter);
 
-  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_next (list);
 
-  list = g_list_append(NULL, list_item);
-  gtk_list_append_items(prop_dialog->operations_list, list);
+    g_clear_pointer (&op_copy, uml_operation_unref);
+  }
 
-  if (prop_dialog->operations_list->children != NULL)
-    gtk_list_unselect_child(prop_dialog->operations_list,
-                           GTK_WIDGET(prop_dialog->operations_list->children->data));
-  gtk_list_select_child(prop_dialog->operations_list, list_item);
+  operations_set_sensitive (prop_dialog, FALSE);
 }
 
+
 static void
-operations_list_delete_callback(GtkWidget *button,
-                               UMLClass *umlclass)
+oper_name_changed (GtkEntry *entry, UMLClass *umlclass)
 {
-  GList *list;
   UMLClassDialog *prop_dialog;
-  GtkList *gtklist;
   UMLOperation *op;
-
+  GtkTreeIter iter;
 
   prop_dialog = umlclass->properties_dialog;
-  gtklist = GTK_LIST(prop_dialog->operations_list);
 
-  if (gtklist->selection != NULL) {
-    op = (UMLOperation *)
-      g_object_get_data(G_OBJECT(gtklist->selection->data), "user_data");
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    g_clear_pointer (&op->name, g_free);
+    op->name = g_strdup (gtk_entry_get_text (entry));
 
-    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);
-    }
+    update_operation (prop_dialog, op, &iter);
 
-    list = g_list_prepend(NULL, gtklist->selection->data);
-    gtk_list_remove_items(gtklist, list);
-    g_list_free(list);
-    operations_clear_values(prop_dialog);
-    operations_set_sensitive(prop_dialog, FALSE);
+    g_clear_pointer (&op, uml_operation_unref);
   }
 }
 
+
 static void
-operations_list_move_up_callback(GtkWidget *button,
-                                UMLClass *umlclass)
+oper_type_changed (GtkEntry *entry, UMLClass *umlclass)
 {
-  GList *list;
   UMLClassDialog *prop_dialog;
-  GtkList *gtklist;
-  GtkWidget *list_item;
-  int i;
+  UMLOperation *op;
+  GtkTreeIter iter;
 
   prop_dialog = umlclass->properties_dialog;
-  gtklist = GTK_LIST(prop_dialog->operations_list);
-
-  if (gtklist->selection != NULL) {
-    list_item = GTK_WIDGET(gtklist->selection->data);
 
-    i = gtk_list_child_position(gtklist, list_item);
-    if (i>0)
-      i--;
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    g_clear_pointer (&op->type, g_free);
+    op->type = g_strdup (gtk_entry_get_text (entry));
 
-    g_object_ref(list_item);
-    list = g_list_prepend(NULL, list_item);
-    gtk_list_remove_items(gtklist, list);
-    gtk_list_insert_items(gtklist, list, i);
-    g_object_unref(list_item);
+    update_operation (prop_dialog, op, &iter);
 
-    gtk_list_select_child(gtklist, list_item);
+    g_clear_pointer (&op, uml_operation_unref);
   }
-
 }
 
+
 static void
-operations_list_move_down_callback(GtkWidget *button,
-                                  UMLClass *umlclass)
+oper_stereotype_changed (GtkEntry *entry, UMLClass *umlclass)
 {
-  GList *list;
   UMLClassDialog *prop_dialog;
-  GtkList *gtklist;
-  GtkWidget *list_item;
-  int i;
+  UMLOperation *op;
+  GtkTreeIter iter;
 
   prop_dialog = umlclass->properties_dialog;
-  gtklist = GTK_LIST(prop_dialog->operations_list);
-
-  if (gtklist->selection != NULL) {
-    list_item = GTK_WIDGET(gtklist->selection->data);
 
-    i = gtk_list_child_position(gtklist, list_item);
-    if (i<(g_list_length(gtklist->children)-1))
-      i++;
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    g_clear_pointer (&op->stereotype, g_free);
+    op->stereotype = g_strdup (gtk_entry_get_text (entry));
 
-    g_object_ref(list_item);
-    list = g_list_prepend(NULL, list_item);
-    gtk_list_remove_items(gtklist, list);
-    gtk_list_insert_items(gtklist, list, i);
-    g_object_unref(list_item);
+    update_operation (prop_dialog, op, &iter);
 
-    gtk_list_select_child(gtklist, list_item);
+    g_clear_pointer (&op, uml_operation_unref);
   }
 }
 
-void
-_operations_read_from_dialog(UMLClass *umlclass,
-                           UMLClassDialog *prop_dialog,
-                           int connection_index)
+
+static void
+oper_visible_changed (DiaOptionMenu *selector, UMLClass *umlclass)
 {
-  GList *list;
+  UMLClassDialog *prop_dialog;
   UMLOperation *op;
-  GtkWidget *list_item;
-  GList *clear_list;
-  DiaObject *obj;
+  GtkTreeIter iter;
+
+  prop_dialog = umlclass->properties_dialog;
 
-  obj = &umlclass->element.object;
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    op->visibility = (UMLVisibility) dia_option_menu_get_active (selector);
 
-  /* if currently select op is changed in the entries, update from widgets */
-  _operations_get_current_values (prop_dialog);
+    update_operation (prop_dialog, op, &iter);
 
-  /* Free current operations: */
-  g_list_free_full (umlclass->operations, (GDestroyNotify) uml_operation_free);
-  umlclass->operations = NULL;
+    g_clear_pointer (&op, uml_operation_unref);
+  }
+}
 
-  /* Insert new operations and remove them from gtklist: */
-  list = GTK_LIST (prop_dialog->operations_list)->children;
-  clear_list = NULL;
-  while (list != NULL) {
-    list_item = GTK_WIDGET(list->data);
-
-    clear_list = g_list_prepend (clear_list, list_item);
-    op = (UMLOperation *)
-      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);
-
-    if (op->left_connection == NULL) {
-      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);
-    }
 
-    if ( (gtk_toggle_button_get_active (prop_dialog->op_vis)) &&
-         (!gtk_toggle_button_get_active (prop_dialog->op_supp)) ) {
-      obj->connections[connection_index] = op->left_connection;
-      connection_index++;
-      obj->connections[connection_index] = op->right_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);
-    }
+static void
+oper_inheritance_changed (DiaOptionMenu *selector, UMLClass *umlclass)
+{
+  UMLClassDialog *prop_dialog;
+  UMLOperation *op;
+  GtkTreeIter iter;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    op->inheritance_type = (UMLInheritanceType) dia_option_menu_get_active (selector);
 
-    list = g_list_next(list);
+    update_operation (prop_dialog, op, &iter);
+
+    g_clear_pointer (&op, uml_operation_unref);
   }
-  clear_list = g_list_reverse (clear_list);
-  gtk_list_remove_items (GTK_LIST (prop_dialog->operations_list), clear_list);
-  g_list_free (clear_list);
 }
 
-void
-_operations_fill_in_dialog(UMLClass *umlclass)
+
+static void
+oper_comment_changed (GtkTextBuffer *buffer, UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
-  UMLOperation *op_copy;
-  GtkWidget *list_item;
-  GList *list;
-  int i;
+  UMLOperation *op;
 
   prop_dialog = umlclass->properties_dialog;
 
-  if (prop_dialog->operations_list->children == NULL) {
-    i = 0;
-    list = umlclass->operations;
-    while (list != NULL) {
-      UMLOperation *op = (UMLOperation *)list->data;
-      gchar *opstr = uml_get_operation_string (op);
-
-      list_item = gtk_list_item_new_with_label (opstr);
-      op_copy = 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);
-    }
+  if (get_current_operation (prop_dialog, &op, NULL)) {
+    g_clear_pointer (&op->comment, g_free);
+    op->comment = buffer_get_text (buffer);
 
-    /* set operations non-sensitive */
-    prop_dialog->current_op = NULL;
-    operations_set_sensitive(prop_dialog, FALSE);
-    operations_clear_values(prop_dialog);
+    g_clear_pointer (&op, uml_operation_unref);
   }
 }
 
 
 static void
-operations_update (GtkWidget *widget, UMLClass *umlclass)
+oper_scope_changed (GtkToggleButton *toggle, UMLClass *umlclass)
 {
-  _operations_get_current_values (umlclass->properties_dialog);
+  UMLClassDialog *prop_dialog;
+  UMLOperation *op;
+  GtkTreeIter iter;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    op->class_scope = gtk_toggle_button_get_active (toggle);
+
+    update_operation (prop_dialog, op, &iter);
+
+    g_clear_pointer (&op, uml_operation_unref);
+  }
 }
 
 
-static int
-operations_update_event (GtkWidget     *widget,
-                         GdkEventFocus *ev,
-                         UMLClass      *umlclass)
+static void
+oper_query_changed (GtkToggleButton *toggle, UMLClass *umlclass)
 {
-  _operations_get_current_values (umlclass->properties_dialog);
+  UMLClassDialog *prop_dialog;
+  UMLOperation *op;
+  GtkTreeIter iter;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  if (get_current_operation (prop_dialog, &op, &iter)) {
+    op->query = gtk_toggle_button_get_active (toggle);
 
-  return 0;
+    update_operation (prop_dialog, op, &iter);
+
+    g_clear_pointer (&op, uml_operation_unref);
+  }
 }
 
+
 static GtkWidget*
 operations_data_create_hbox (UMLClass *umlclass)
 {
@@ -689,45 +858,45 @@ operations_data_create_hbox (UMLClass *umlclass)
 
   prop_dialog = umlclass->properties_dialog;
 
-  hbox = gtk_hbox_new(FALSE, 5);
+  hbox = gtk_hbox_new (FALSE, 6);
   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
 
-  vbox2 = gtk_vbox_new(FALSE, 0);
+  vbox2 = gtk_vbox_new (FALSE, 0);
 
   /* table containing operation 'name' up to 'query' and also the comment */
   table = gtk_table_new (5, 3, FALSE);
   gtk_table_set_col_spacings (GTK_TABLE (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);
+  label = gtk_label_new (_("Name:"));
+  entry = gtk_entry_new ();
+  prop_dialog->op_name = GTK_ENTRY (entry);
+  g_signal_connect (entry,
+                    "changed",
+                    G_CALLBACK (oper_name_changed),
+                    umlclass);
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
   gtk_table_attach (GTK_TABLE (table), label, 0,1,0,1, GTK_FILL,0, 0,0);
   gtk_table_attach (GTK_TABLE (table), entry, 1,2,0,1, GTK_FILL | GTK_EXPAND,0, 0,2);
 
-  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);
+  label = gtk_label_new (_("Type:"));
+  entry = gtk_entry_new ();
+  prop_dialog->op_type = GTK_ENTRY (entry);
+  g_signal_connect (entry,
+                    "changed",
+                    G_CALLBACK (oper_type_changed),
+                    umlclass);
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
   gtk_table_attach (GTK_TABLE (table), label, 0,1,1,2, GTK_FILL,0, 0,0);
   gtk_table_attach (GTK_TABLE (table), entry, 1,2,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
 
-  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);
+  label = gtk_label_new (_("Stereotype:"));
+  entry = gtk_entry_new ();
+  prop_dialog->op_stereotype = GTK_ENTRY (entry);
+  g_signal_connect (entry,
+                    "changed",
+                    G_CALLBACK (oper_stereotype_changed),
+                    umlclass);
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
   gtk_table_attach (GTK_TABLE (table), label, 0,1,2,3, GTK_FILL,0, 0,0);
   gtk_table_attach (GTK_TABLE (table), entry, 1,2,2,3, GTK_FILL | GTK_EXPAND,0, 0,2);
@@ -736,9 +905,9 @@ operations_data_create_hbox (UMLClass *umlclass)
   label = gtk_label_new(_("Visibility:"));
 
   prop_dialog->op_visible = omenu = dia_option_menu_new ();
-  g_signal_connect (G_OBJECT (omenu),
+  g_signal_connect (omenu,
                     "changed",
-                    G_CALLBACK (operations_update),
+                    G_CALLBACK (oper_visible_changed),
                     umlclass);
   dia_option_menu_add_item (DIA_OPTION_MENU (omenu), _("Public"), UML_PUBLIC);
   dia_option_menu_add_item (DIA_OPTION_MENU (omenu), _("Private"), UML_PRIVATE);
@@ -754,8 +923,10 @@ operations_data_create_hbox (UMLClass *umlclass)
   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);
+  g_signal_connect (omenu,
+                    "changed",
+                    G_CALLBACK (oper_inheritance_changed),
+                    umlclass);
   dia_option_menu_add_item (DIA_OPTION_MENU (omenu), _("Abstract"), UML_ABSTRACT);
   dia_option_menu_add_item (DIA_OPTION_MENU (omenu), _("Polymorphic (virtual)"), UML_POLYMORPHIC);
   dia_option_menu_add_item (DIA_OPTION_MENU (omenu), _("Leaf (final)"), UML_LEAF);
@@ -764,28 +935,40 @@ operations_data_create_hbox (UMLClass *umlclass)
   gtk_table_attach (GTK_TABLE (table), omenu, 3,4,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
   /* end: Inheritance type */
 
-  checkbox = gtk_check_button_new_with_label(_("Class scope"));
-  prop_dialog->op_class_scope = GTK_TOGGLE_BUTTON(checkbox);
+  checkbox = gtk_check_button_new_with_label (_("Class scope"));
+  g_signal_connect (checkbox,
+                    "toggled",
+                    G_CALLBACK (oper_scope_changed),
+                    umlclass);
+  prop_dialog->op_class_scope = GTK_TOGGLE_BUTTON (checkbox);
+
   gtk_table_attach (GTK_TABLE (table), checkbox, 2,3,2,3, GTK_FILL,0, 0,2);
 
-  checkbox = gtk_check_button_new_with_label(_("Query"));
-  prop_dialog->op_query = GTK_TOGGLE_BUTTON(checkbox);
+  checkbox = gtk_check_button_new_with_label (_("Query"));
+  g_signal_connect (checkbox,
+                    "toggled",
+                    G_CALLBACK (oper_query_changed),
+                    umlclass);
+  prop_dialog->op_query = GTK_TOGGLE_BUTTON (checkbox);
   gtk_table_attach (GTK_TABLE (table), checkbox, 3,4,2,3, GTK_FILL,0, 2,0);
 
-  label = gtk_label_new(_("Comment:"));
+  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);
+  prop_dialog->op_comment_buffer = gtk_text_buffer_new (NULL);
+  entry = gtk_text_view_new_with_buffer (prop_dialog->op_comment_buffer);
+  prop_dialog->op_comment = GTK_TEXT_VIEW (entry);
+  g_signal_connect (prop_dialog->op_comment_buffer,
+                    "changed",
+                    G_CALLBACK (oper_comment_changed),
+                    umlclass);
   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);
+  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_table_attach (GTK_TABLE (table), label, 4,5,0,1, GTK_FILL,0, 0,0);
   gtk_table_attach (GTK_TABLE (table), scrolledwindow, 4,5,1,3, GTK_FILL | GTK_EXPAND,0, 0,0);
@@ -853,7 +1036,7 @@ operations_parameters_editor_create_vbox (UMLClass *umlclass)
   gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
 
   /* Parameters list editor - with of list at least width of buttons*/
-  hbox2 = gtk_vbox_new (FALSE, 6);
+  hbox2 = gtk_hbox_new (FALSE, 6);
 
   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
@@ -876,6 +1059,7 @@ operations_parameters_editor_create_vbox (UMLClass *umlclass)
   gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
 
   renderer = gtk_cell_renderer_text_new ();
+  g_object_set (renderer, "family", "monospace", NULL);
   column = gtk_tree_view_column_new_with_attributes (NULL,
                                                      renderer,
                                                      "text",
@@ -890,7 +1074,7 @@ operations_parameters_editor_create_vbox (UMLClass *umlclass)
   gtk_widget_show (prop_dialog->parameters);
 
 
-  vbox3 = gtk_hbox_new (TRUE, 6);
+  vbox3 = gtk_vbox_new (TRUE, 6);
 
 
   button = gtk_button_new ();
@@ -965,29 +1149,17 @@ static void
 param_name_changed (GtkWidget *entry, UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeSelection *selection;
   UMLParameter *param;
-  char *new_str;
+  GtkTreeIter iter;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, &param, -1);
-
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
     g_clear_pointer (&param->name, g_free);
     param->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
 
-    new_str = uml_parameter_get_string (param);
-
-    gtk_list_store_set (prop_dialog->parameters_store,
-                        &iter,
-                        COL_PARAM_TITLE, new_str,
-                        -1);
+    update_parameter (prop_dialog, param, &iter);
 
-    g_clear_pointer (&new_str, g_free);
     g_clear_pointer (&param, uml_parameter_unref);
   }
 }
@@ -998,28 +1170,16 @@ param_type_changed (GtkWidget *entry, UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
   GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeSelection *selection;
   UMLParameter *param;
-  char *new_str;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, &param, -1);
-
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
     g_clear_pointer (&param->type, g_free);
     param->type = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
 
-    new_str = uml_parameter_get_string (param);
-
-    gtk_list_store_set (prop_dialog->parameters_store,
-                        &iter,
-                        COL_PARAM_TITLE, new_str,
-                        -1);
+    update_parameter (prop_dialog, param, &iter);
 
-    g_clear_pointer (&new_str, g_free);
     g_clear_pointer (&param, uml_parameter_unref);
   }
 }
@@ -1030,28 +1190,16 @@ param_value_changed (GtkWidget *entry, UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
   GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeSelection *selection;
   UMLParameter *param;
-  char *new_str;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, &param, -1);
-
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
     g_clear_pointer (&param->value, g_free);
     param->value = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
 
-    new_str = uml_parameter_get_string (param);
+    update_parameter (prop_dialog, param, &iter);
 
-    gtk_list_store_set (prop_dialog->parameters_store,
-                        &iter,
-                        COL_PARAM_TITLE, new_str,
-                        -1);
-
-    g_clear_pointer (&new_str, g_free);
     g_clear_pointer (&param, uml_parameter_unref);
   }
 }
@@ -1061,17 +1209,11 @@ static void
 param_comment_changed (GtkTextBuffer *buffer, UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeSelection *selection;
   UMLParameter *param;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, &param, -1);
-
+  if (get_current_parameter (prop_dialog, &param, NULL)) {
     g_clear_pointer (&param->comment, g_free);
     param->comment = buffer_get_text (prop_dialog->param_comment_buffer);
 
@@ -1085,27 +1227,15 @@ param_kind_changed (DiaOptionMenu *selector, UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
   GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkTreeSelection *selection;
   UMLParameter *param;
-  char *new_str;
 
   prop_dialog = umlclass->properties_dialog;
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->parameters));
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-    gtk_tree_model_get (model, &iter, COL_PARAM_PARAM, &param, -1);
-
+  if (get_current_parameter (prop_dialog, &param, &iter)) {
     param->kind = (UMLParameterKind) dia_option_menu_get_active (selector);
 
-    new_str = uml_parameter_get_string (param);
-
-    gtk_list_store_set (prop_dialog->parameters_store,
-                        &iter,
-                        COL_PARAM_TITLE, new_str,
-                        -1);
+    update_parameter (prop_dialog, param, &iter);
 
-    g_clear_pointer (&new_str, g_free);
     g_clear_pointer (&param, uml_parameter_unref);
   }
 }
@@ -1213,8 +1343,33 @@ operations_parameters_data_create_vbox (UMLClass *umlclass)
   return vbox2;
 }
 
+
+static void
+operation_selected (GtkTreeSelection *selection,
+                    UMLClass         *umlclass)
+{
+  UMLClassDialog *prop_dialog;
+  UMLOperation *op;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  if (!prop_dialog)
+    return; /* maybe hiding a bug elsewhere */
+
+  if (get_current_operation (prop_dialog, &op, NULL)) {
+    operations_set_values (prop_dialog, op);
+    operations_set_sensitive (prop_dialog, TRUE);
+
+    gtk_widget_grab_focus (GTK_WIDGET (prop_dialog->op_name));
+  } else {
+    operations_set_sensitive (prop_dialog, FALSE);
+    operations_clear_values (prop_dialog);
+  }
+}
+
+
 void
-_operations_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
+_operations_create_page (GtkNotebook *notebook,  UMLClass *umlclass)
 {
   UMLClassDialog *prop_dialog;
   GtkWidget *page_label;
@@ -1224,8 +1379,11 @@ _operations_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
   GtkWidget *vbox3;
   GtkWidget *scrolled_win;
   GtkWidget *button;
-  GtkWidget *list;
+  GtkWidget *image;
   GtkWidget *frame;
+  GtkTreeSelection *select;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
 
   prop_dialog = umlclass->properties_dialog;
 
@@ -1239,49 +1397,105 @@ _operations_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
 
   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_POLICY_AUTOMATIC,
+                                  GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
+                                       GTK_SHADOW_IN);
   gtk_box_pack_start (GTK_BOX (hbox), scrolled_win, TRUE, TRUE, 0);
   gtk_widget_show (scrolled_win);
 
-  list = gtk_list_new ();
-  prop_dialog->operations_list = GTK_LIST(list);
-  gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
-  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (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);
+  prop_dialog->operations_store = gtk_list_store_new (N_OPER_COLS,
+                                                      G_TYPE_STRING,
+                                                      DIA_UML_TYPE_OPERATION,
+                                                      PANGO_TYPE_UNDERLINE,
+                                                      PANGO_TYPE_STYLE,
+                                                      PANGO_TYPE_WEIGHT);
+  prop_dialog->operations = gtk_tree_view_new_with_model (GTK_TREE_MODEL (prop_dialog->operations_store));
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (prop_dialog->operations), FALSE);
+
+  select = gtk_tree_view_get_selection (GTK_TREE_VIEW (prop_dialog->operations));
+  g_signal_connect (G_OBJECT (select),
+                    "changed",
+                    G_CALLBACK (operation_selected),
+                    umlclass);
+  gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
+
+  renderer = gtk_cell_renderer_text_new ();
+  g_object_set (renderer, "family", "monospace", NULL);
+  column = gtk_tree_view_column_new_with_attributes (NULL,
+                                                     renderer,
+                                                     "text",
+                                                     COL_OPER_TITLE,
+                                                     "underline",
+                                                     COL_OPER_UNDERLINE,
+                                                     "weight",
+                                                     COL_OPER_BOLD,
+                                                     "style",
+                                                     COL_OPER_ITALIC,
+                                                     NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (prop_dialog->operations),
+                               column);
 
-  g_signal_connect (G_OBJECT (list), "selection_changed",
-                   G_CALLBACK(operations_list_selection_changed_callback),
-                   umlclass);
+  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), prop_dialog->operations);
+  gtk_container_set_focus_vadjustment (GTK_CONTAINER (prop_dialog->operations),
+                                       gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(scrolled_win)));
+  gtk_widget_show (prop_dialog->operations);
 
-  vbox2 = gtk_vbox_new(FALSE, 5);
+  vbox2 = gtk_vbox_new (FALSE, 6);
 
-  button = gtk_button_new_from_stock (GTK_STOCK_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);
+  button = gtk_button_new ();
+  image = gtk_image_new_from_icon_name ("list-add",
+                                        GTK_ICON_SIZE_SMALL_TOOLBAR);
+  gtk_widget_show (image);
+  gtk_container_add (GTK_CONTAINER (button), image);
+  gtk_widget_set_tooltip_text (button, _("Add Operation"));
+  g_signal_connect (G_OBJECT (button),
+                    "clicked",
+                    G_CALLBACK (operations_list_new_callback),
+                    umlclass);
+  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
   gtk_widget_show (button);
-  button = gtk_button_new_from_stock (GTK_STOCK_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);
+
+  button = gtk_button_new ();
+  image = gtk_image_new_from_icon_name ("list-remove",
+                                        GTK_ICON_SIZE_SMALL_TOOLBAR);
+  gtk_widget_show (image);
+  gtk_container_add (GTK_CONTAINER (button), image);
+  gtk_widget_set_tooltip_text (button, _("Remove Operation"));
+  g_signal_connect (G_OBJECT (button),
+                    "clicked",
+                    G_CALLBACK (operations_list_delete_callback),
+                    umlclass);
+  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
   gtk_widget_show (button);
-  button = gtk_button_new_from_stock (GTK_STOCK_GO_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);
+
+  button = gtk_button_new ();
+  image = gtk_image_new_from_icon_name ("go-up",
+                                        GTK_ICON_SIZE_SMALL_TOOLBAR);
+  gtk_widget_show (image);
+  gtk_container_add (GTK_CONTAINER (button), image);
+  gtk_widget_set_tooltip_text (button, _("Move Operation 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, FALSE, 0);
   gtk_widget_show (button);
-  button = gtk_button_new_from_stock (GTK_STOCK_GO_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);
+  button = gtk_button_new ();
+  image = gtk_image_new_from_icon_name ("go-down",
+                                        GTK_ICON_SIZE_SMALL_TOOLBAR);
+  gtk_widget_show (image);
+  gtk_container_add (GTK_CONTAINER (button), image);
+  gtk_widget_set_tooltip_text (button, _("Move Operation 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, FALSE, 0);
   gtk_widget_show (button);
 
-  gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
 
   gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
 
diff --git a/objects/UML/uml.h b/objects/UML/uml.h
index c5be896d..6d63b408 100644
--- a/objects/UML/uml.h
+++ b/objects/UML/uml.h
@@ -149,7 +149,8 @@ GType         uml_operation_get_type                 (void);
 UMLOperation *uml_operation_copy                     (UMLOperation  *op);
 void          uml_operation_copy_into                (UMLOperation  *srcop,
                                                       UMLOperation  *destop);
-void          uml_operation_free                     (UMLOperation  *op);
+UMLOperation *uml_operation_ref                      (UMLOperation  *self);
+void          uml_operation_unref                    (UMLOperation  *self);
 void          uml_operation_write                    (AttributeNode  attr_node,
                                                       UMLOperation  *op,
                                                       DiaContext    *ctx);
diff --git a/objects/UML/umloperation.c b/objects/UML/umloperation.c
index 34972f19..b643199c 100644
--- a/objects/UML/umloperation.c
+++ b/objects/UML/umloperation.c
@@ -94,11 +94,11 @@ static PropOffset umloperation_offsets[] = {
 
 PropDescDArrayExtra umloperation_extra = {
   { umloperation_props, umloperation_offsets, "umloperation" },
-  (NewRecordFunc)uml_operation_new,
-  (FreeRecordFunc)uml_operation_free
+  (NewRecordFunc) uml_operation_new,
+  (FreeRecordFunc) uml_operation_unref
 };
 
-G_DEFINE_BOXED_TYPE (UMLOperation, uml_operation, uml_operation_copy, uml_operation_free)
+G_DEFINE_BOXED_TYPE (UMLOperation, uml_operation, uml_operation_ref, uml_operation_unref)
 
 
 UMLOperation *
@@ -107,7 +107,7 @@ uml_operation_new (void)
   UMLOperation *op;
   static gint next_id = 1;
 
-  op = g_slice_new0 (UMLOperation);
+  op = g_rc_box_new0 (UMLOperation);
   op->internal_id = next_id++;
   op->name = g_strdup ("");
   op->type = g_strdup ("");
@@ -207,8 +207,17 @@ uml_operation_copy (UMLOperation *op)
 }
 
 
-void
-uml_operation_free (UMLOperation *op)
+UMLOperation *
+uml_operation_ref (UMLOperation *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return g_rc_box_acquire (self);
+}
+
+
+static void
+operation_free (UMLOperation *op)
 {
   g_free (op->name);
   if (op->type != NULL)
@@ -229,7 +238,13 @@ uml_operation_free (UMLOperation *op)
   g_free(op->left_connection);
   g_free(op->right_connection);
 #endif
-  g_slice_free (UMLOperation, op);
+}
+
+
+void
+uml_operation_unref (UMLOperation *self)
+{
+  g_rc_box_release_full (self, (GDestroyNotify) operation_free);
 }
 
 


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