[dia/dia-next: 45/59] Fix reordering of parameters



commit 91e365cb500664b83906be00f0ba2c3d3072d78d
Author: Zander Brown <zbrown gnome org>
Date:   Wed Jan 2 12:51:34 2019 +0000

    Fix reordering of parameters
    
    Implement a simple GListModel of DiaUmlListData for use with DiaUmlListRow & GtkListBox

 data/dia-uml-class-editor.ui                       |   2 -
 ...ia-uml-operation-row.ui => dia-uml-list-row.ui} |   6 +-
 objects/UML/Makefile.am                            |   1 +
 objects/UML/class_dialog.c                         |   2 +-
 objects/UML/class_operations_dialog.c              |  23 ++-
 objects/UML/dia-uml-class.c                        |  94 ++++++++++--
 objects/UML/dia-uml-class.h                        |  73 ++-------
 objects/UML/editor/dia-uml-class-editor.c          |  95 +++---------
 objects/UML/editor/dia-uml-class-editor.h          |  11 --
 objects/UML/editor/dia-uml-list-row.c              |  53 ++++---
 objects/UML/editor/dia-uml-list-row.h              |  14 +-
 objects/UML/editor/dia-uml-list-store.c            | 169 +++++++++++++++++++++
 objects/UML/editor/dia-uml-list-store.h            |  24 +++
 13 files changed, 354 insertions(+), 213 deletions(-)
---
diff --git a/data/dia-uml-class-editor.ui b/data/dia-uml-class-editor.ui
index f7622d06..62b15087 100644
--- a/data/dia-uml-class-editor.ui
+++ b/data/dia-uml-class-editor.ui
@@ -108,8 +108,6 @@
                     <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>
diff --git a/data/dia-uml-operation-row.ui b/data/dia-uml-list-row.ui
similarity index 96%
rename from data/dia-uml-operation-row.ui
rename to data/dia-uml-list-row.ui
index e5f2c7d9..290300ad 100644
--- a/data/dia-uml-operation-row.ui
+++ b/data/dia-uml-list-row.ui
@@ -12,7 +12,7 @@
     <property name="can_focus">False</property>
     <property name="icon_name">go-down-symbolic</property>
   </object>
-  <template class="DiaUmlOperationRow" parent="GtkListBoxRow">
+  <template class="DiaUmlListRow" parent="GtkListBoxRow">
     <property name="visible">True</property>
     <property name="can_focus">True</property>
     <child>
@@ -49,7 +49,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="DiaUmlOperationRow" swapped="yes"/>
+                <signal name="clicked" handler="move_up" object="DiaUmlListRow" swapped="yes"/>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -63,7 +63,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="DiaUmlOperationRow" swapped="yes"/>
+                <signal name="clicked" handler="move_down" object="DiaUmlListRow" swapped="yes"/>
               </object>
               <packing>
                 <property name="expand">False</property>
diff --git a/objects/UML/Makefile.am b/objects/UML/Makefile.am
index 38774681..d8eb20b8 100644
--- a/objects/UML/Makefile.am
+++ b/objects/UML/Makefile.am
@@ -13,6 +13,7 @@ libuml_objects_la_SOURCES = \
                        class_dialog.c \
                        class_attributes_dialog.c \
                        editor/dia-uml-list-data.c \
+                       editor/dia-uml-list-store.c \
                        editor/dia-uml-list-row.c \
                        editor/dia-uml-class-editor.c \
                        editor/dia-uml-operation-dialog.c \
diff --git a/objects/UML/class_dialog.c b/objects/UML/class_dialog.c
index 89fbce5a..2ac8aad9 100644
--- a/objects/UML/class_dialog.c
+++ b/objects/UML/class_dialog.c
@@ -600,7 +600,7 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
     ( 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));
+    num_ops = g_list_model_get_n_items (dia_uml_class_get_operations (editor_state));
   } else {
     num_ops = 0;
   }
diff --git a/objects/UML/class_operations_dialog.c b/objects/UML/class_operations_dialog.c
index befe80f8..f8d38e6a 100644
--- a/objects/UML/class_operations_dialog.c
+++ b/objects/UML/class_operations_dialog.c
@@ -24,6 +24,7 @@
 #include "class_dialog.h"
 #include "dia_dirs.h"
 #include "editor/dia-uml-class-editor.h"
+#include "editor/dia-uml-list-store.h"
 #include "dia-uml-class.h"
 
 /*************************************************************
@@ -35,11 +36,12 @@ _operations_read_from_dialog (UMLClass *umlclass,
                               UMLClassDialog *prop_dialog,
                               int connection_index)
 {
-  GList *list;
-  DiaUmlOperation *op;
+  DiaUmlListStore *list_store;
+  DiaUmlListData *itm;
   DiaObject *obj;
   DiaUmlClass *editor_state;
   gboolean op_visible = TRUE;
+  int i = 0;
 
   /* Cast to DiaObject (UMLClass -> Element -> DiaObject) */
   obj = &umlclass->element.object;
@@ -48,24 +50,17 @@ _operations_read_from_dialog (UMLClass *umlclass,
 
   /* Free current operations: */
   /* Clear those already stored */
-  list = umlclass->operations;
-  while (list != NULL) {
-    op = list->data;
-    g_object_unref (op);
-    list = g_list_next(list);
-  }
-  g_list_free (umlclass->operations);
+  g_list_free_full (umlclass->operations, g_object_unref);
   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);
+  list_store = dia_uml_class_get_operations (editor_state);
   /* Insert new operations and remove them from gtklist: */
-  while (list != NULL) {
-    op = list->data;
-    
+  while ((itm = g_list_model_get_item (G_LIST_MODEL (list_store), i))) {
+    DiaUmlOperation *op = DIA_UML_OPERATION (itm);
     umlclass->operations = g_list_append(umlclass->operations, g_object_ref (op));
 
     if (op->l_connection == NULL) {
@@ -89,7 +84,7 @@ _operations_read_from_dialog (UMLClass *umlclass,
       object_remove_connections_to(op->r_connection);
     }
 
-    list = g_list_next (list);
+    i++;
   }
 }
 
diff --git a/objects/UML/dia-uml-class.c b/objects/UML/dia-uml-class.c
index 4153a15f..3d8be33e 100644
--- a/objects/UML/dia-uml-class.c
+++ b/objects/UML/dia-uml-class.c
@@ -1,4 +1,56 @@
 #include "dia-uml-class.h"
+#include "editor/dia-uml-list-store.h"
+
+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: */
+  DiaUmlListStore *operations;
+
+  /* Template: */
+  gboolean template_;
+  GList *formal_params;
+};
 
 G_DEFINE_TYPE (DiaUmlClass, dia_uml_class, G_TYPE_OBJECT)
 
@@ -25,12 +77,7 @@ clear_attrs (DiaUmlClass *self)
   }
   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);
+  g_clear_object (&self->operations);
 
   list = self->formal_params;
   while (list) {
@@ -133,8 +180,8 @@ dia_uml_class_load (DiaUmlClass *self,
   }
 
   /* TODO: Why? */
-  self->operations = NULL;
   list = klass->operations;
+  self->operations = dia_uml_list_store_new ();
   while (list != NULL) {
     DiaUmlOperation *op = (DiaUmlOperation *)list->data;
     DiaUmlOperation *copy = dia_uml_operation_copy (op);
@@ -143,7 +190,7 @@ dia_uml_class_load (DiaUmlClass *self,
     copy->l_connection = op->l_connection;
     copy->r_connection = op->r_connection;
 
-    self->operations = g_list_append(self->operations, copy);
+    dia_uml_list_store_add (self->operations, DIA_UML_LIST_DATA (copy));
     list = g_list_next(list);
   }
 
@@ -167,6 +214,10 @@ void
 dia_uml_class_store (DiaUmlClass *self,
                      UMLClass    *klass)
 {
+  GList *list;
+  DiaUmlListData *itm;
+  int i = 0;
+
   klass->font_height = self->font_height;
   klass->abstract_font_height = self->abstract_font_height;
   klass->polymorphic_font_height = self->polymorphic_font_height;
@@ -210,31 +261,42 @@ dia_uml_class_store (DiaUmlClass *self,
 
   /* TODO: List stuff */
   klass->attributes = self->attributes;
-  klass->operations = self->operations;
+
+  list = NULL;
+  while ((itm = g_list_model_get_item (G_LIST_MODEL (self->operations), i))) {
+    list = g_list_append (list, itm);
+    i++;
+  }
+  klass->operations = list;
+
   klass->template = self->template_;
   klass->formal_params = self->formal_params;
 }
 
-GList *
+GListModel *
 dia_uml_class_get_operations (DiaUmlClass *self)
 {
-  return self->operations;
+  return G_LIST_MODEL (self->operations);
 }
 
+/*
+ * Don't rely on these two being called!
+ * 
+ * The DiaUmlListStore can/will be edited directly (e.g. by DiaUmlClassEditor)
+ * so connect to items-changed if you want to observe these!
+ */
+
 void
 dia_uml_class_insert_operation (DiaUmlClass     *self,
                                 DiaUmlOperation *operation,
                                 int              index)
 {
-  self->operations = g_list_insert (self->operations,
-                                    g_object_ref (operation),
-                                    index);
+  dia_uml_list_store_insert (self->operations, DIA_UML_LIST_DATA (operation), index);
 }
 
 void
 dia_uml_class_remove_operation (DiaUmlClass     *self,
                                 DiaUmlOperation *operation)
 {
-  self->operations = g_list_remove (self->operations, operation);
-  g_object_unref (operation);
+  dia_uml_list_store_remove (self->operations, DIA_UML_LIST_DATA (operation));
 }
diff --git a/objects/UML/dia-uml-class.h b/objects/UML/dia-uml-class.h
index e086a0c0..09bc091e 100644
--- a/objects/UML/dia-uml-class.h
+++ b/objects/UML/dia-uml-class.h
@@ -10,68 +10,17 @@ 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);
+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);
+GListModel      *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
 
diff --git a/objects/UML/editor/dia-uml-class-editor.c b/objects/UML/editor/dia-uml-class-editor.c
index d0cfee3b..228d0393 100644
--- a/objects/UML/editor/dia-uml-class-editor.c
+++ b/objects/UML/editor/dia-uml-class-editor.c
@@ -1,8 +1,19 @@
 #include "dia-uml-class-editor.h"
 #include "dia-uml-list-row.h"
+#include "dia-uml-list-store.h"
 #include "dia-uml-operation-dialog.h"
 #include "dia_dirs.h"
 
+struct _DiaUmlClassEditor {
+  GtkScrolledWindow parent;
+
+  GtkWidget *attributes;
+  GtkWidget *operations;
+  GtkWidget *templates;
+
+  DiaUmlClass *klass;
+};
+
 G_DEFINE_TYPE (DiaUmlClassEditor, dia_uml_class_editor, GTK_TYPE_SCROLLED_WINDOW)
 
 enum {
@@ -14,36 +25,10 @@ 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_list_row_new (DIA_UML_LIST_DATA (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 (dia_uml_list_row_get_data (DIA_UML_LIST_ROW (row)));
-
-  if (op == curr_row)
-    gtk_widget_destroy (row);
-
-  g_object_unref (curr_row);
+  GListModel *store = dia_uml_class_get_operations (self->klass);
+  gtk_list_box_bind_model (GTK_LIST_BOX (self->operations), store,
+                           (GtkListBoxCreateWidgetFunc) dia_uml_list_row_new,
+                           store, NULL);
 }
 
 static void
@@ -51,24 +36,18 @@ remove_op (DiaUmlOperationDialog *dlg,
            DiaUmlOperation       *op,
            DiaUmlClassEditor     *self)
 {
-  gtk_container_foreach (GTK_CONTAINER (self->operations),
-                         (GtkCallback *) remove_op_row,
-                         op);
+  dia_uml_class_remove_operation (self->klass, op);
 }
 
 static void
 add_operation (DiaUmlClassEditor *self)
 {
   DiaUmlOperation *op;
-  GtkWidget *row;
   GtkWidget *edit;
   GtkWidget *parent;
 
   op = dia_uml_operation_new ();
-  row = dia_uml_list_row_new (DIA_UML_LIST_DATA (op));
-
-  gtk_widget_show (row);
-  gtk_container_add (GTK_CONTAINER (self->operations), row);
+  dia_uml_class_insert_operation (self->klass, op, -1);
 
   parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
   edit = dia_uml_operation_dialog_new (GTK_WINDOW (parent), op);
@@ -96,38 +75,6 @@ edit_operation (DiaUmlClassEditor *self,
   g_object_unref (op);
 }
 
-static void
-operation_added (DiaUmlClassEditor *self,
-                 GtkListBoxRow     *row)
-{
-  DiaUmlOperation *op;
-  int index;
-
-  if (self->building_ops || !DIA_UML_IS_LIST_ROW (row))
-    return;
-
-  op = DIA_UML_OPERATION (dia_uml_list_row_get_data (DIA_UML_LIST_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_LIST_ROW (row) || gtk_widget_in_destruction (GTK_WIDGET (row)))
-    return;
-  
-  op = DIA_UML_OPERATION (dia_uml_list_row_get_data (DIA_UML_LIST_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)
 {
@@ -209,8 +156,6 @@ dia_uml_class_editor_class_init (DiaUmlClassEditorClass *klass)
   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);
 }
@@ -223,8 +168,6 @@ dia_uml_class_editor_init (DiaUmlClassEditor *self)
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  self->building_ops = FALSE;
-
   box = g_object_new (GTK_TYPE_BOX,
                       "orientation", GTK_ORIENTATION_VERTICAL,
                       "spacing", 16,
@@ -276,8 +219,8 @@ dia_uml_class_editor_new (DiaUmlClass *klass)
                        NULL);
 }
 
-DiaUmlClass 
-*dia_uml_class_editor_get_class (DiaUmlClassEditor *self)
+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
index 0363114d..0bb55201 100644
--- a/objects/UML/editor/dia-uml-class-editor.h
+++ b/objects/UML/editor/dia-uml-class-editor.h
@@ -10,17 +10,6 @@ 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);
 
diff --git a/objects/UML/editor/dia-uml-list-row.c b/objects/UML/editor/dia-uml-list-row.c
index 477a0750..e7226ffa 100644
--- a/objects/UML/editor/dia-uml-list-row.c
+++ b/objects/UML/editor/dia-uml-list-row.c
@@ -2,10 +2,20 @@
 #include "dia-uml-list-row.h"
 #include "dia_dirs.h"
 
+struct _DiaUmlListRow {
+  GtkListBoxRow parent;
+
+  GtkWidget *title;
+
+  DiaUmlListData *data;
+  DiaUmlListStore *model;
+};
+
 G_DEFINE_TYPE (DiaUmlListRow, dia_uml_list_row, GTK_TYPE_LIST_BOX_ROW)
 
 enum {
   PROP_DATA = 1,
+  PROP_MODEL,
   N_PROPS
 };
 static GParamSpec* properties[N_PROPS];
@@ -16,6 +26,7 @@ dia_uml_list_row_finalize (GObject *object)
   DiaUmlListRow *self = DIA_UML_LIST_ROW (object);
 
   g_clear_object (&self->data);
+  g_clear_object (&self->model);
 }
 
 static void
@@ -40,6 +51,9 @@ dia_uml_list_row_set_property (GObject      *object,
                         G_CALLBACK (display_op), self);
       display_op (self->data, self);
       break;
+    case PROP_MODEL:
+      self->model = g_value_dup_object (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -57,6 +71,9 @@ dia_uml_list_row_get_property (GObject    *object,
     case PROP_DATA:
       g_value_set_object (value, self->data);
       break;
+    case PROP_MODEL:
+      g_value_set_object (value, self->model);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -66,36 +83,27 @@ dia_uml_list_row_get_property (GObject    *object,
 static void
 move_up (DiaUmlListRow *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);
+  g_object_ref (self->data);
+  dia_uml_list_store_remove (self->model, self->data);
+  dia_uml_list_store_insert (self->model, self->data, index - 1);
+  g_object_unref (self->data);
 }
 
 static void
 move_down (DiaUmlListRow *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);
+  g_object_ref (self->data);
+  dia_uml_list_store_remove (self->model, self->data);
+  dia_uml_list_store_insert (self->model, self->data, index + 1);
+  g_object_unref (self->data);
 }
 
 static void
@@ -118,6 +126,13 @@ dia_uml_list_row_class_init (DiaUmlListRowClass *klass)
                          DIA_UML_TYPE_LIST_DATA,
                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
 
+  properties[PROP_MODEL] =
+    g_param_spec_object ("model",
+                         "Model",
+                         "Model this row belongs to",
+                         DIA_UML_TYPE_LIST_STORE,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
   g_object_class_install_properties (object_class,
                                      N_PROPS,
                                      properties);
@@ -144,10 +159,12 @@ dia_uml_list_row_init (DiaUmlListRow *self)
 }
 
 GtkWidget *
-dia_uml_list_row_new (DiaUmlListData *data)
+dia_uml_list_row_new (DiaUmlListData  *data,
+                      DiaUmlListStore *model)
 {
   return g_object_new (DIA_UML_TYPE_LIST_ROW,
                        "data", data, 
+                       "model", model,
                        NULL);
 }
 
diff --git a/objects/UML/editor/dia-uml-list-row.h b/objects/UML/editor/dia-uml-list-row.h
index 3105c3bd..64fca0df 100644
--- a/objects/UML/editor/dia-uml-list-row.h
+++ b/objects/UML/editor/dia-uml-list-row.h
@@ -1,20 +1,14 @@
 #include <gtk/gtk.h>
 #include "dia-uml-list-data.h"
+#include "dia-uml-list-store.h"
 
 G_BEGIN_DECLS
 
 #define DIA_UML_TYPE_LIST_ROW (dia_uml_list_row_get_type ())
 G_DECLARE_FINAL_TYPE (DiaUmlListRow, dia_uml_list_row, DIA_UML, LIST_ROW, GtkListBoxRow)
 
-struct _DiaUmlListRow {
-  GtkListBoxRow parent;
-
-  GtkWidget *title;
-
-  DiaUmlListData *data;
-};
-
-GtkWidget      *dia_uml_list_row_new      (DiaUmlListData *data);
-DiaUmlListData *dia_uml_list_row_get_data (DiaUmlListRow  *self);
+GtkWidget      *dia_uml_list_row_new      (DiaUmlListData  *data,
+                                           DiaUmlListStore *model);
+DiaUmlListData *dia_uml_list_row_get_data (DiaUmlListRow   *self);
 
 G_END_DECLS
diff --git a/objects/UML/editor/dia-uml-list-store.c b/objects/UML/editor/dia-uml-list-store.c
new file mode 100644
index 00000000..d547a1a8
--- /dev/null
+++ b/objects/UML/editor/dia-uml-list-store.c
@@ -0,0 +1,169 @@
+#include "dia-uml-list-store.h"
+#include <glib.h>
+#include <gio/gio.h>
+
+struct _DiaUmlListStore
+{
+  GObject parent_instance;
+
+  GList *data;
+};
+
+enum
+{
+  PROP_0,
+  PROP_ITEM_TYPE,
+  N_PROPERTIES
+};
+
+static void dia_uml_list_store_iface_init (GListModelInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (DiaUmlListStore, dia_uml_list_store, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, dia_uml_list_store_iface_init));
+
+static void
+dia_uml_list_store_dispose (GObject *object)
+{
+  DiaUmlListStore *store = DIA_UML_LIST_STORE (object);
+
+  g_list_free_full (store->data, g_object_unref);
+
+  G_OBJECT_CLASS (dia_uml_list_store_parent_class)->dispose (object);
+}
+
+static void
+dia_uml_list_store_get_property (GObject    *object,
+                                 guint       property_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  switch (property_id) {
+    case PROP_ITEM_TYPE:
+      g_value_set_gtype (value, DIA_UML_TYPE_LIST_DATA);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+dia_uml_list_store_class_init (DiaUmlListStoreClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = dia_uml_list_store_dispose;
+  object_class->get_property = dia_uml_list_store_get_property;
+
+  g_object_class_install_property (object_class, PROP_ITEM_TYPE,
+    g_param_spec_gtype ("item-type", "", "", DIA_UML_TYPE_LIST_DATA,
+                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+}
+
+static GType
+dia_uml_list_store_get_item_type (GListModel *list)
+{
+  return DIA_UML_TYPE_LIST_DATA;
+}
+
+static guint
+dia_uml_list_store_get_n_items (GListModel *list)
+{
+  DiaUmlListStore *store = DIA_UML_LIST_STORE (list);
+
+  return g_list_length (store->data);
+}
+
+static gpointer
+dia_uml_list_store_get_item (GListModel *list,
+                             guint       position)
+{
+  DiaUmlListStore *store = DIA_UML_LIST_STORE (list);
+  DiaUmlListData *item;
+
+  item = g_list_nth_data (store->data, position);
+
+  if (item)
+    return g_object_ref (item);
+  else
+    return NULL;
+}
+
+static void
+dia_uml_list_store_iface_init (GListModelInterface *iface)
+{
+  iface->get_item_type = dia_uml_list_store_get_item_type;
+  iface->get_n_items = dia_uml_list_store_get_n_items;
+  iface->get_item = dia_uml_list_store_get_item;
+}
+
+static void
+dia_uml_list_store_init (DiaUmlListStore *store)
+{
+  store->data = NULL;
+}
+
+DiaUmlListStore *
+dia_uml_list_store_new ()
+{
+  return g_object_new (DIA_UML_TYPE_LIST_STORE, NULL);
+}
+
+void
+dia_uml_list_store_insert (DiaUmlListStore *store,
+                           DiaUmlListData  *item,
+                           int              index)
+{
+  g_return_if_fail (DIA_UML_IS_LIST_STORE (store));
+
+  if (index >= g_list_length (store->data)) {
+    dia_uml_list_store_add (store, item);
+    return;
+  }
+
+  store->data = g_list_insert (store->data, g_object_ref (item), index);
+
+  g_list_model_items_changed (G_LIST_MODEL (store), index, 0, 1);
+}
+
+void
+dia_uml_list_store_add (DiaUmlListStore *store,
+                        DiaUmlListData  *item)
+{
+  guint n_items;
+
+  g_return_if_fail (DIA_UML_IS_LIST_STORE (store));
+
+  n_items = g_list_length (store->data);
+  store->data = g_list_append (store->data, g_object_ref (item));
+
+  g_list_model_items_changed (G_LIST_MODEL (store), n_items, 0, 1);
+}
+
+void
+dia_uml_list_store_remove (DiaUmlListStore *store,
+                           DiaUmlListData  *item)
+{
+  int index;
+
+  g_return_if_fail (DIA_UML_IS_LIST_STORE (store));
+
+  index = g_list_index (store->data, item);
+  store->data = g_list_remove (store->data, item);
+  g_object_unref (item);
+
+  g_list_model_items_changed (G_LIST_MODEL (store), index, 1, 0);
+}
+
+void
+dia_uml_list_store_empty (DiaUmlListStore *store)
+{
+  guint n_items;
+
+  g_return_if_fail (DIA_UML_IS_LIST_STORE (store));
+
+  n_items = g_list_length (store->data);
+  g_list_free_full (store->data, g_object_unref);
+  store->data = NULL;
+
+  g_list_model_items_changed (G_LIST_MODEL (store), 0, n_items, 0);
+}
diff --git a/objects/UML/editor/dia-uml-list-store.h b/objects/UML/editor/dia-uml-list-store.h
new file mode 100644
index 00000000..abf0c8a9
--- /dev/null
+++ b/objects/UML/editor/dia-uml-list-store.h
@@ -0,0 +1,24 @@
+#include <glib-object.h>
+#include "dia-uml-list-data.h"
+
+#ifndef UML_LIST_STORE_H
+#define UML_LIST_STORE_H
+
+G_BEGIN_DECLS
+
+#define DIA_UML_TYPE_LIST_STORE (dia_uml_list_store_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlListStore, dia_uml_list_store, DIA_UML, LIST_STORE, GObject)
+
+DiaUmlListStore *dia_uml_list_store_new    ();
+void             dia_uml_list_store_insert (DiaUmlListStore *store,
+                                            DiaUmlListData  *item,
+                                            int              index);
+void             dia_uml_list_store_add    (DiaUmlListStore *store,
+                                            DiaUmlListData  *item);
+void             dia_uml_list_store_remove (DiaUmlListStore *store,
+                                            DiaUmlListData  *item);
+void             dia_uml_list_store_empty  (DiaUmlListStore *store);
+
+G_END_DECLS
+
+#endif


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