[dia/dia-next: 47/59] Move attributes to the new editor



commit 130d76315ba0f8e7f86e907f6330a2e8eb24c6fa
Author: Zander Brown <zbrown gnome org>
Date:   Wed Jan 2 18:41:53 2019 +0000

    Move attributes to the new editor

 data/dia-uml-attribute-dialog.ui                   | 246 +++++++++
 data/dia-uml-class-editor.ui                       |   3 +-
 objects/UML/Makefile.am                            |   4 +-
 objects/UML/class.c                                |  54 +-
 objects/UML/class_attributes_dialog.c              | 609 ---------------------
 objects/UML/class_dialog.c                         |  20 +-
 objects/UML/class_dialog.h                         |  11 -
 objects/UML/class_operations_dialog.c              |  47 +-
 objects/UML/dia-uml-attribute.c                    | 388 +++++++++++++
 objects/UML/dia-uml-attribute.h                    |  38 ++
 objects/UML/dia-uml-class.c                        |  53 +-
 objects/UML/dia-uml-class.h                        |   8 +
 objects/UML/dia-uml-operation.h                    |  13 +-
 objects/UML/editor/dia-uml-attribute-dialog.c      | 203 +++++++
 objects/UML/editor/dia-uml-attribute-dialog.h      |  22 +
 objects/UML/editor/dia-uml-class-editor.c          |  60 +-
 objects/UML/editor/dia-uml-operation-dialog.c      |  29 +-
 objects/UML/editor/dia-uml-operation-dialog.h      |   3 +-
 .../UML/editor/dia-uml-operation-parameter-row.h   |   1 +
 objects/UML/uml.c                                  |   2 +
 objects/UML/uml.h                                  |  40 +-
 objects/UML/umlattribute.c                         | 250 ---------
 22 files changed, 1113 insertions(+), 991 deletions(-)
---
diff --git a/data/dia-uml-attribute-dialog.ui b/data/dia-uml-attribute-dialog.ui
new file mode 100644
index 00000000..89c320b5
--- /dev/null
+++ b/data/dia-uml-attribute-dialog.ui
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkTextBuffer" id="comment"/>
+  <template class="DiaUmlAttributeDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
+    <property name="title" translatable="yes">Attribute</property>
+    <property name="resizable">False</property>
+    <property name="type_hint">dialog</property>
+    <child>
+      <placeholder/>
+    </child>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">8</property>
+            <property name="margin_right">8</property>
+            <property name="margin_top">8</property>
+            <property name="margin_bottom">8</property>
+            <property name="row_spacing">8</property>
+            <property name="column_spacing">16</property>
+            <property name="row_homogeneous">True</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Name</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Type</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Value</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Comment</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Visibility</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">5</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Class scope</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">6</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTextView">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="left_margin">8</property>
+                    <property name="right_margin">8</property>
+                    <property name="top_margin">8</property>
+                    <property name="bottom_margin">8</property>
+                    <property name="buffer">comment</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">3</property>
+                <property name="height">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="name">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="valign">center</property>
+                <property name="hexpand">True</property>
+                <property name="width_chars">25</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="type">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="valign">center</property>
+                <property name="hexpand">True</property>
+                <property name="width_chars">25</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry" id="value">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="valign">center</property>
+                <property name="hexpand">True</property>
+                <property name="width_chars">25</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSwitch" id="scope">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">6</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBoxText" id="visibility">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+                <property name="active_id">public</property>
+                <items>
+                  <item id="public" translatable="yes">Public</item>
+                  <item id="private" translatable="yes">Private</item>
+                  <item id="protected" translatable="yes">Protected</item>
+                  <item id="implementation" translatable="yes">Implementation</item>
+                </items>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">5</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="label" translatable="yes">Delete</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+                <signal name="clicked" handler="remove_attribute" object="DiaUmlAttributeDialog" 
swapped="yes"/>
+                <style>
+                  <class name="destructive-action"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">7</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/data/dia-uml-class-editor.ui b/data/dia-uml-class-editor.ui
index 62b15087..0140bddc 100644
--- a/data/dia-uml-class-editor.ui
+++ b/data/dia-uml-class-editor.ui
@@ -52,6 +52,7 @@
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="selection_mode">none</property>
+                    <signal name="row-activated" handler="edit_attribute" object="DiaUmlClassEditor" 
swapped="yes"/>
                   </object>
                 </child>
                 <child type="label_item">
@@ -68,11 +69,11 @@
               <object class="GtkButton">
                 <property name="label" translatable="yes">Add Attribute</property>
                 <property name="visible">True</property>
-                <property name="sensitive">False</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="halign">end</property>
                 <property name="valign">center</property>
+                <signal name="clicked" handler="add_attribute" object="DiaUmlClassEditor" swapped="yes"/>
               </object>
               <packing>
                 <property name="expand">False</property>
diff --git a/objects/UML/Makefile.am b/objects/UML/Makefile.am
index d8eb20b8..794d63fe 100644
--- a/objects/UML/Makefile.am
+++ b/objects/UML/Makefile.am
@@ -7,17 +7,18 @@ libuml_objects_la_SOURCES = \
                        dia-uml-class.c \
                        dia-uml-operation.c \
                        dia-uml-parameter.c \
+                       dia-uml-attribute.c \
                        class.c \
                        class.h \
                        class_dialog.h \
                        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 \
                        editor/dia-uml-operation-parameter-row.c \
+                       editor/dia-uml-attribute-dialog.c \
                        class_operations_dialog.c \
                        class_templates_dialog.c \
                        note.c \
@@ -46,7 +47,6 @@ libuml_objects_la_SOURCES = \
                        stereotype.c \
                        stereotype.h \
                        transition.c \
-                       umlattribute.c \
                        umlformalparameter.c
 
 libuml_objects_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINED)
diff --git a/objects/UML/class.c b/objects/UML/class.c
index 7f4e957e..5f7347fe 100644
--- a/objects/UML/class.c
+++ b/objects/UML/class.c
@@ -43,6 +43,9 @@
 
 #include "debug.h"
 
+#include "dia-uml-attribute.h"
+#include "dia-uml-operation.h"
+
 #define UMLCLASS_BORDER 0.1
 #define UMLCLASS_UNDERLINEWIDTH 0.05
 #define UMLCLASS_TEMPLATE_OVERLAY_X 2.3
@@ -459,9 +462,9 @@ umlclass_set_props(UMLClass *umlclass, GPtrArray *props)
     i = UMLCLASS_CONNECTIONPOINTS;
     list = (!umlclass->visible_attributes || umlclass->suppress_attributes) ? NULL : umlclass->attributes;
     while (list != NULL) {
-      UMLAttribute *attr = (UMLAttribute *)list->data;
+      DiaUmlAttribute *attr = (DiaUmlAttribute *)list->data;
 
-      uml_attribute_ensure_connection_points (attr, obj);
+      dia_uml_attribute_ensure_connection_points (attr, obj);
       obj->connections[i] = attr->left_connection;
       obj->connections[i]->object = obj;
       i++;
@@ -906,8 +909,8 @@ umlclass_draw_attributebox(UMLClass *umlclass, DiaRenderer *renderer, Element *e
     list = umlclass->attributes;
     while (list != NULL)
     {
-      UMLAttribute *attr   = (UMLAttribute *)list->data;
-      gchar        *attstr = uml_get_attribute_string(attr);
+      DiaUmlAttribute *attr   = (DiaUmlAttribute *)list->data;
+      gchar        *attstr = dia_uml_attribute_format(attr);
 
       if (attr->abstract)  {
         font = umlclass->abstract_font;
@@ -1279,7 +1282,7 @@ umlclass_update_data(UMLClass *umlclass)
 
   list = (!umlclass->visible_attributes || umlclass->suppress_attributes) ? NULL : umlclass->attributes;
   while (list != NULL) {
-    UMLAttribute *attr = (UMLAttribute *)list->data;
+    DiaUmlAttribute *attr = (DiaUmlAttribute *)list->data;
 
     attr->left_connection->pos.x = x;
     attr->left_connection->pos.y = y;
@@ -1445,8 +1448,8 @@ umlclass_calculate_attribute_data(UMLClass *umlclass)
     list = umlclass->attributes;
     while (list != NULL)
     {
-      UMLAttribute *attr   = (UMLAttribute *) list->data;
-      gchar        *attstr = uml_get_attribute_string(attr);
+      DiaUmlAttribute *attr   = (DiaUmlAttribute *) list->data;
+      gchar        *attstr = dia_uml_attribute_format(attr);
 
       if (attr->abstract)
       {
@@ -1909,7 +1912,7 @@ static void
 umlclass_destroy(UMLClass *umlclass)
 {
   GList *list;
-  UMLAttribute *attr;
+  DiaUmlAttribute *attr;
   DiaUmlOperation *op;
   UMLFormalParameter *param;
 
@@ -1934,13 +1937,13 @@ umlclass_destroy(UMLClass *umlclass)
 
   list = umlclass->attributes;
   while (list != NULL) {
-    attr = (UMLAttribute *)list->data;
-    g_free(attr->left_connection);
-    g_free(attr->right_connection);
-    uml_attribute_destroy(attr);
-    list = g_list_next(list);
+    attr = (DiaUmlAttribute *)list->data;
+    g_free (attr->left_connection);
+    g_free (attr->right_connection);
+    g_object_unref (attr);
+    list = g_list_next (list);
   }
-  g_list_free(umlclass->attributes);
+  g_list_free (umlclass->attributes);
   
   list = umlclass->operations;
   while (list != NULL) {
@@ -1950,7 +1953,7 @@ umlclass_destroy(UMLClass *umlclass)
     g_object_unref (op);
     list = g_list_next(list);
   }
-  g_list_free(umlclass->operations);
+  g_list_free (umlclass->operations);
 
   list = umlclass->formal_params;
   while (list != NULL) {
@@ -2039,13 +2042,12 @@ umlclass_copy(UMLClass *umlclass)
   newumlclass->attributes = NULL;
   list = umlclass->attributes;
   while (list != NULL) {
-    UMLAttribute *attr = (UMLAttribute *)list->data;
+    DiaUmlAttribute *attr = (DiaUmlAttribute *)list->data;
     /* not copying the connection, if there was one */
-    UMLAttribute *newattr = uml_attribute_copy(attr);
-    uml_attribute_ensure_connection_points (newattr, newobj);
+    DiaUmlAttribute *newattr = dia_uml_attribute_copy (attr);
+    dia_uml_attribute_ensure_connection_points (newattr, newobj);
     
-    newumlclass->attributes = g_list_append(newumlclass->attributes,
-                                           newattr);
+    newumlclass->attributes = g_list_append (newumlclass->attributes, newattr);
     list = g_list_next(list);
   }
 
@@ -2091,7 +2093,7 @@ umlclass_copy(UMLClass *umlclass)
        (!newumlclass->suppress_attributes)) {
     list = newumlclass->attributes;
     while (list != NULL) {
-      UMLAttribute *attr = (UMLAttribute *)list->data;
+      DiaUmlAttribute *attr = (DiaUmlAttribute *)list->data;
       newobj->connections[i++] = attr->left_connection;
       newobj->connections[i++] = attr->right_connection;
       
@@ -2140,7 +2142,7 @@ static void
 umlclass_save(UMLClass *umlclass, ObjectNode obj_node,
              DiaContext *ctx)
 {
-  UMLAttribute *attr;
+  DiaUmlAttribute *attr;
   DiaUmlOperation *op;
   UMLFormalParameter *formal_param;
   GList *list;
@@ -2218,7 +2220,7 @@ umlclass_save(UMLClass *umlclass, ObjectNode obj_node,
   attr_node = new_attribute(obj_node, "attributes");
   list = umlclass->attributes;
   while (list != NULL) {
-    attr = (UMLAttribute *) list->data;
+    attr = (DiaUmlAttribute *) list->data;
     uml_attribute_write(attr_node, attr, ctx);
     list = g_list_next(list);
   }
@@ -2349,10 +2351,10 @@ umlclass_load(ObjectNode obj_node, int version, DiaContext *ctx)
   /* Attribute info: */
   list = umlclass->attributes;
   while (list) {
-    UMLAttribute *attr = list->data;
+    DiaUmlAttribute *attr = list->data;
     g_assert(attr);
 
-    uml_attribute_ensure_connection_points (attr, obj);
+    dia_uml_attribute_ensure_connection_points (attr, obj);
     list = g_list_next(list);
   }
 
@@ -2452,7 +2454,7 @@ umlclass_sanity_check(UMLClass *c, gchar *msg)
   /* Check that attributes are set up right. */
   i = 0;
   for (attrs = c->attributes; attrs != NULL; attrs = g_list_next(attrs)) {
-    UMLAttribute *attr = (UMLAttribute *)attrs->data;
+    DiaUmlAttribute *attr = (DiaUmlAttribute *)attrs->data;
 
     dia_assert_true(attr->name != NULL,
                    "%s: %p attr %d has null name\n",
diff --git a/objects/UML/class_dialog.c b/objects/UML/class_dialog.c
index 2ac8aad9..d33e3840 100644
--- a/objects/UML/class_dialog.c
+++ b/objects/UML/class_dialog.c
@@ -537,7 +537,6 @@ switch_page_callback(GtkNotebook *notebook,
   prop_dialog = umlclass->properties_dialog;
 
   if (prop_dialog != NULL) {
-    _attributes_get_current_values(prop_dialog);
     _templates_get_current_values(prop_dialog);
   }
 }
@@ -560,8 +559,6 @@ fill_in_dialog(UMLClass *umlclass)
   umlclass_sanity_check(umlclass, "Filling in dialog before attrs");
 #endif
   class_fill_in_dialog(umlclass);
-  _attributes_fill_in_dialog(umlclass);
-  /*_operations_fill_in_dialog(umlclass);*/
   _templates_fill_in_dialog(umlclass);
 }
 
@@ -592,7 +589,7 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
     ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_vis ))) &&
     (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_supp)))
   ) {
-    num_attrib = g_list_length(dia_list_get_children(prop_dialog->attributes_list));
+    num_attrib = g_list_model_get_n_items (dia_uml_class_get_attributes (editor_state));
   } else {
     num_attrib = 0;
   }
@@ -618,10 +615,9 @@ umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
 
   /* Read from dialog and put in object: */
   class_read_from_dialog(umlclass, prop_dialog);
-  _attributes_read_from_dialog(umlclass, prop_dialog, UMLCLASS_CONNECTIONPOINTS);
   /* ^^^ attribs must be called before ops, to get the right order of the
      connectionpoints. */
-  _operations_read_from_dialog(umlclass, prop_dialog, UMLCLASS_CONNECTIONPOINTS+num_attrib*2);
+  _operations_read_from_dialog(umlclass, prop_dialog, UMLCLASS_CONNECTIONPOINTS);
   _templates_read_from_dialog(umlclass, prop_dialog);
 
   /* Reestablish mainpoint */
@@ -666,7 +662,6 @@ static void
 create_dialog_pages(GtkNotebook *notebook, UMLClass *umlclass)
 {
   class_create_page(notebook, umlclass);
-  _attributes_create_page(notebook, umlclass);
   _operations_create_page(notebook, umlclass);
   _templates_create_page(notebook, umlclass);
   style_create_page(notebook, umlclass);
@@ -690,7 +685,6 @@ umlclass_get_properties(UMLClass *umlclass, gboolean is_default)
     g_object_ref_sink(vbox);
     prop_dialog->dialog = vbox;
 
-    prop_dialog->current_attr = NULL;
     prop_dialog->current_templ = NULL;
     prop_dialog->deleted_connections = NULL;
     prop_dialog->added_connections = NULL;
@@ -729,9 +723,6 @@ umlclass_update_connectionpoints(UMLClass *umlclass)
   DiaObject *obj;
   GList *list;
   int connection_index;
-  UMLClassDialog *prop_dialog;
-
-  prop_dialog = umlclass->properties_dialog;
   
   /* Allocate enought connection points for attributes and operations. */
   /* (two per op/attr) */
@@ -758,7 +749,7 @@ umlclass_update_connectionpoints(UMLClass *umlclass)
   
   list = umlclass->attributes;
   while (list != NULL) {
-    UMLAttribute *attr = (UMLAttribute *) list->data;
+    DiaUmlAttribute *attr = (DiaUmlAttribute *) list->data;
     
     if ( (umlclass->visible_attributes) &&
         (!umlclass->suppress_attributes)) {
@@ -771,9 +762,6 @@ umlclass_update_connectionpoints(UMLClass *umlclass)
     list = g_list_next(list);
   }
   
-  if (prop_dialog)
-    dia_list_empty (DIA_LIST (prop_dialog->attributes_list));
-
   list = umlclass->operations;
   while (list != NULL) {
     DiaUmlOperation *op = (DiaUmlOperation *) list->data;
@@ -804,6 +792,8 @@ umlclass_set_state(UMLClass *umlclass, DiaUmlClass *state)
 
   umlclass_calculate_data(umlclass);
   umlclass_update_data(umlclass);
+  /* TODO: Fix undo
+  dia_uml_class_store (state, umlclass); */
 }
 
 static void
diff --git a/objects/UML/class_dialog.h b/objects/UML/class_dialog.h
index 5d6fe033..d7f0ae8d 100644
--- a/objects/UML/class_dialog.h
+++ b/objects/UML/class_dialog.h
@@ -49,14 +49,7 @@ struct _UMLClassDialog {
   GList *added_connections; 
   GList *deleted_connections; 
 
-  DiaList *attributes_list;
-  DiaListItem *current_attr;
-  GtkEntry *attr_name;
-  GtkEntry *attr_type;
-  GtkEntry *attr_value;
-  GtkTextView *attr_comment;
   GtkWidget *attr_visible;
-  GtkToggleButton *attr_class_scope;
 
   GtkWidget *editor;
 
@@ -72,16 +65,12 @@ void _umlclass_store_disconnects(UMLClassDialog *prop_dialog, ConnectionPoint *c
 const gchar *_class_get_comment(GtkTextView *);
 void _class_set_comment(GtkTextView *, gchar *);
 
-void _attributes_get_current_values(UMLClassDialog *prop_dialog);
 void _templates_get_current_values(UMLClassDialog *prop_dialog);
 
-void _attributes_fill_in_dialog(UMLClass *umlclass);
 void _templates_fill_in_dialog(UMLClass *umlclass);
 
-void _attributes_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog, int connection_index);
 void _operations_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog, int connection_index);
 void _templates_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog);
 
-void _attributes_create_page(GtkNotebook *notebook,  UMLClass *umlclass);
 void _operations_create_page(GtkNotebook *notebook,  UMLClass *umlclass);
 void _templates_create_page(GtkNotebook *notebook,  UMLClass *umlclass);
diff --git a/objects/UML/class_operations_dialog.c b/objects/UML/class_operations_dialog.c
index 4cd89a34..f96594ee 100644
--- a/objects/UML/class_operations_dialog.c
+++ b/objects/UML/class_operations_dialog.c
@@ -40,6 +40,7 @@ _operations_read_from_dialog (UMLClass *umlclass,
   DiaUmlListData *itm;
   DiaObject *obj;
   DiaUmlClass *editor_state;
+  gboolean attr_visible = TRUE;
   gboolean op_visible = TRUE;
   int i = 0;
 
@@ -48,19 +49,63 @@ _operations_read_from_dialog (UMLClass *umlclass,
 
   editor_state = dia_uml_class_editor_get_class (DIA_UML_CLASS_EDITOR (umlclass->properties_dialog->editor));
 
+  /* Free current attributes: */
+  g_list_free_full (umlclass->attributes, g_object_unref);
+  umlclass->attributes = NULL;
+
   /* Free current operations: */
   /* Clear those already stored */
   g_list_free_full (umlclass->operations, g_object_unref);
   umlclass->operations = NULL;
 
+  /* If attributes visible and not suppressed */
+  attr_visible = ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_vis ))) &&
+                 (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop_dialog->attr_supp)));
+
   /* If 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)));
 
+
+  /* Insert new attributes and remove them from gtklist: */
+  i = 0;
+  list_store = dia_uml_class_get_attributes (editor_state);
+  /* Insert new operations and remove them from gtklist: */
+  while ((itm = g_list_model_get_item (list_store, i))) {
+    DiaUmlAttribute *attr = DIA_UML_ATTRIBUTE (itm);
+
+    umlclass->attributes = g_list_append (umlclass->attributes, g_object_ref (attr));
+    
+    if (attr->left_connection == NULL) {
+      dia_uml_attribute_ensure_connection_points (attr, obj);
+
+      prop_dialog->added_connections = g_list_prepend (prop_dialog->added_connections,
+                                                       attr->left_connection);
+      prop_dialog->added_connections = g_list_prepend (prop_dialog->added_connections,
+                                                       attr->right_connection);
+    }
+
+    if (attr_visible) { 
+      obj->connections[connection_index] = attr->left_connection;
+      connection_index++;
+      obj->connections[connection_index] = attr->right_connection;
+      connection_index++;
+    } else {
+      _umlclass_store_disconnects(prop_dialog, attr->left_connection);
+      object_remove_connections_to(attr->left_connection);
+      _umlclass_store_disconnects(prop_dialog, attr->right_connection);
+      object_remove_connections_to(attr->right_connection);
+    }
+
+    i++;
+  }
+
+  i = 0;
   list_store = dia_uml_class_get_operations (editor_state);
   /* Insert new operations and remove them from gtklist: */
-  while ((itm = g_list_model_get_item (G_LIST_MODEL (list_store), i))) {
+  while ((itm = g_list_model_get_item (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) {
diff --git a/objects/UML/dia-uml-attribute.c b/objects/UML/dia-uml-attribute.c
new file mode 100644
index 00000000..8bb7baca
--- /dev/null
+++ b/objects/UML/dia-uml-attribute.c
@@ -0,0 +1,388 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * umlattribute.c : refactored from uml.c, class.c to final use StdProps
+ *                  PROP_TYPE_DARRAY, a list where each element is a set
+ *                  of properies described by the same StdPropDesc
+ * Copyright (C) 2005 Hans Breuer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "uml.h"
+#include "dia-uml-attribute.h"
+#include "editor/dia-uml-list-data.h"
+#include "properties.h"
+
+extern PropEnumData _uml_visibilities[];
+
+static PropDescription umlattribute_props[] = {
+  { "name", PROP_TYPE_STRING, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Name"), NULL, NULL },
+  { "type", PROP_TYPE_STRING, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Type"), NULL, NULL },
+  { "value", PROP_TYPE_STRING, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Value"), NULL, NULL },
+  { "comment", PROP_TYPE_MULTISTRING, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Comment"), NULL, NULL },
+  { "visibility", PROP_TYPE_ENUM, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Visibility"), NULL, _uml_visibilities },
+  /* Kept for backward compatibility, not sure what it is meant to be --hb */
+  { "abstract", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Abstract"), NULL, NULL },
+  { "class_scope", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE | PROP_FLAG_OPTIONAL,
+  N_("Scope"), NULL, N_("Class scope (C++ static class variable)") },
+
+  PROP_DESC_END
+};
+
+static PropOffset umlattribute_offsets[] = {
+  { "name", PROP_TYPE_STRING, offsetof(DiaUmlAttribute, name) },
+  { "type", PROP_TYPE_STRING, offsetof(DiaUmlAttribute, type) },
+  { "value", PROP_TYPE_STRING, offsetof(DiaUmlAttribute, value) },
+  { "comment", PROP_TYPE_MULTISTRING, offsetof(DiaUmlAttribute, comment) },
+  { "visibility", PROP_TYPE_ENUM, offsetof(DiaUmlAttribute, visibility) },
+  { "abstract", PROP_TYPE_BOOL, offsetof(DiaUmlAttribute, abstract) },
+  { "class_scope", PROP_TYPE_BOOL, offsetof(DiaUmlAttribute, class_scope) },
+  { NULL, 0, 0 },
+};
+
+
+PropDescDArrayExtra umlattribute_extra = {
+  { umlattribute_props, umlattribute_offsets, "umlattribute" },
+  (NewRecordFunc) dia_uml_attribute_new,
+  (FreeRecordFunc) g_object_unref
+};
+
+static void
+dia_uml_attribute_list_data_init (DiaUmlListDataInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (DiaUmlAttribute, dia_uml_attribute, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (DIA_UML_TYPE_LIST_DATA,
+                                                dia_uml_attribute_list_data_init))
+
+enum {
+  PROP_NAME = 1,
+  PROP_TYPE,
+  PROP_VALUE,
+  PROP_COMMENT,
+  PROP_VISIBILITY,
+  PROP_CLASS_SCOPE,
+  N_PROPS
+};
+static GParamSpec* properties[N_PROPS];
+
+
+static void
+dia_uml_attribute_finalize (GObject *object)
+{
+  DiaUmlAttribute *self = DIA_UML_ATTRIBUTE (object);
+
+  g_free (self->name);
+  g_free (self->type);
+  g_free (self->value);
+  g_free (self->comment);
+
+  /* free'd elsewhere */
+  /*
+  g_free(attr->left_connection);
+  g_free(attr->right_connection);
+  */
+}
+
+
+static void
+dia_uml_attribute_set_property (GObject      *object,
+                                guint         property_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  DiaUmlAttribute *self = DIA_UML_ATTRIBUTE (object);
+
+  switch (property_id) {
+    case PROP_NAME:
+      self->name = g_value_dup_string (value);
+      g_object_notify_by_pspec (object, properties[PROP_NAME]);
+      dia_uml_list_data_changed (DIA_UML_LIST_DATA (self));
+      break;
+    case PROP_TYPE:
+      self->type = g_value_dup_string (value);
+      g_object_notify_by_pspec (object, properties[PROP_TYPE]);
+      dia_uml_list_data_changed (DIA_UML_LIST_DATA (self));
+      break;
+    case PROP_VALUE:
+      self->value = g_value_dup_string (value);
+      g_object_notify_by_pspec (object, properties[PROP_VALUE]);
+      dia_uml_list_data_changed (DIA_UML_LIST_DATA (self));
+      break;
+    case PROP_COMMENT:
+      self->comment = g_value_dup_string (value);
+      g_object_notify_by_pspec (object, properties[PROP_COMMENT]);
+      dia_uml_list_data_changed (DIA_UML_LIST_DATA (self));
+      break;
+    case PROP_VISIBILITY:
+      self->visibility = g_value_get_int (value);
+      g_object_notify_by_pspec (object, properties[PROP_VISIBILITY]);
+      dia_uml_list_data_changed (DIA_UML_LIST_DATA (self));
+      break;
+    case PROP_CLASS_SCOPE:
+      self->class_scope = g_value_get_boolean (value);
+      g_object_notify_by_pspec (object, properties[PROP_CLASS_SCOPE]);
+      dia_uml_list_data_changed (DIA_UML_LIST_DATA (self));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_attribute_get_property (GObject    *object,
+                                guint       property_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  DiaUmlAttribute *self = DIA_UML_ATTRIBUTE (object);
+
+  switch (property_id) {
+    case PROP_NAME:
+      g_value_set_string (value, self->name);
+      break;
+    case PROP_TYPE:
+      g_value_set_string (value, self->type);
+      break;
+    case PROP_VALUE:
+      g_value_set_string (value, self->type);
+      break;
+    case PROP_COMMENT:
+      g_value_set_string (value, self->comment);
+      break;
+    case PROP_VISIBILITY:
+      g_value_set_int (value, self->visibility);
+      break;
+    case PROP_CLASS_SCOPE:
+      g_value_set_boolean (value, self->class_scope);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static const gchar *
+format (DiaUmlListData *self)
+{
+  return dia_uml_attribute_format (DIA_UML_ATTRIBUTE (self));
+}
+
+static void
+dia_uml_attribute_list_data_init (DiaUmlListDataInterface *iface)
+{
+  iface->format = format;
+}
+
+static void
+dia_uml_attribute_class_init (DiaUmlAttributeClass *klass)
+{
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = dia_uml_attribute_finalize;
+  object_class->set_property = dia_uml_attribute_set_property;
+  object_class->get_property = dia_uml_attribute_get_property;
+
+  properties[PROP_NAME] = g_param_spec_string ("name",
+                                               "Name",
+                                               "Function name",
+                                               "",
+                                               G_PARAM_READWRITE);
+  properties[PROP_TYPE] = g_param_spec_string ("type",
+                                               "Type",
+                                               "Attribute type",
+                                               "",
+                                               G_PARAM_READWRITE);
+  properties[PROP_VALUE] = g_param_spec_string ("value",
+                                                "Value",
+                                                "Default value",
+                                                "",
+                                                G_PARAM_READWRITE);
+  properties[PROP_COMMENT] = g_param_spec_string ("comment",
+                                                  "Comment",
+                                                  "Comment",
+                                                  "",
+                                                  G_PARAM_READWRITE);
+  properties[PROP_VISIBILITY] = g_param_spec_int ("visibility",
+                                                  "Visibility",
+                                                  "Visibility",
+                                                  UML_PUBLIC,
+                                                  UML_IMPLEMENTATION,
+                                                  UML_PUBLIC,
+                                                  G_PARAM_READWRITE);
+  properties[PROP_CLASS_SCOPE] = g_param_spec_boolean ("class-scope",
+                                                       "Class scope",
+                                                       "Class scope",
+                                                       FALSE,
+                                                       G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class,
+                                     N_PROPS,
+                                     properties);
+}
+
+static void
+dia_uml_attribute_init (DiaUmlAttribute *self)
+{
+  static gint next_id = 1;
+
+  self->internal_id = next_id++;
+  self->name = g_strdup("");
+  self->type = g_strdup("");
+  self->value = NULL;
+  self->comment = g_strdup("");
+  self->visibility = UML_PUBLIC;
+  self->abstract = FALSE;
+  self->class_scope = FALSE;
+  /* setup elsewhere */
+  /*
+  attr->left_connection = g_new0(ConnectionPoint, 1);
+  attr->right_connection = g_new0(ConnectionPoint, 1);
+  */
+}
+
+DiaUmlAttribute *
+dia_uml_attribute_new ()
+{
+  return g_object_new (DIA_UML_TYPE_ATTRIBUTE, NULL);
+}
+
+/** Copy the data of an attribute into another, but not the connections. 
+ * Frees up any strings in the attribute being copied into. */
+DiaUmlAttribute *
+dia_uml_attribute_copy (DiaUmlAttribute *self)
+{
+  DiaUmlAttribute *newattr = g_object_new (DIA_UML_TYPE_ATTRIBUTE, NULL);
+
+  newattr->internal_id = self->internal_id;
+  g_free(newattr->name);
+  newattr->name = g_strdup(self->name);
+  g_free(newattr->type);
+  newattr->type = g_strdup(self->type);
+
+  g_free(newattr->value);
+  newattr->value = g_strdup(self->value);
+  
+  g_free(newattr->comment);
+  newattr->comment = g_strdup (self->comment);
+  
+  newattr->visibility = self->visibility;
+  newattr->abstract = self->abstract;
+  newattr->class_scope = self->class_scope;
+
+  return newattr;
+}
+
+void
+uml_attribute_write(AttributeNode attr_node, DiaUmlAttribute *attr, DiaContext *ctx)
+{
+  DataNode composite;
+
+  composite = data_add_composite(attr_node, "umlattribute", ctx);
+
+  data_add_string(composite_add_attribute(composite, "name"),
+                 attr->name, ctx);
+  data_add_string(composite_add_attribute(composite, "type"),
+                 attr->type, ctx);
+  data_add_string(composite_add_attribute(composite, "value"),
+                 attr->value, ctx);
+  data_add_string(composite_add_attribute(composite, "comment"),
+                 attr->comment, ctx);
+  data_add_enum(composite_add_attribute(composite, "visibility"),
+               attr->visibility, ctx);
+  data_add_boolean(composite_add_attribute(composite, "abstract"),
+                 attr->abstract, ctx);
+  data_add_boolean(composite_add_attribute(composite, "class_scope"),
+                 attr->class_scope, ctx);
+}
+
+/* Warning, the following *must* be strictly ASCII characters (or fix the 
+   following code for UTF-8 cleanliness */
+
+char visible_char[] = { '+', '-', '#', ' ' };
+
+char *
+dia_uml_attribute_format (DiaUmlAttribute *attribute)
+{
+  int len;
+  char *str;
+
+  len = 1 + (attribute->name ? strlen (attribute->name) : 0) 
+          + (attribute->type ? strlen (attribute->type) : 0);
+  if (attribute->name && attribute->name[0] && attribute->type && attribute->type[0]) {
+    len += 2;
+  }
+  if (attribute->value != NULL && attribute->value[0] != '\0') {
+    len += 3 + strlen (attribute->value);
+  }
+  
+  str = g_malloc (sizeof (char) * (len + 1));
+
+  str[0] = visible_char[(int) attribute->visibility];
+  str[1] = 0;
+
+  strcat (str, attribute->name ? attribute->name : "");
+  if (attribute->name && attribute->name[0] && attribute->type && attribute->type[0]) {
+    strcat (str, ": ");
+  }
+  strcat (str, attribute->type ? attribute->type : "");
+  if (attribute->value != NULL && attribute->value[0] != '\0') {
+    strcat (str, " = ");
+    strcat (str, attribute->value);
+  }
+    
+  g_assert (strlen (str) == len);
+
+  return str;
+}
+
+/*!
+ * The ownership of these connection points is quite complicated. Instead of being part of
+ * the DiaUmlAttribute as one may expect at first, they are somewhat in between the DiaObject
+ * (see: DiaObject::connections and the concrete user, here UMLClass) and the DiaUmlAttribute.
+ *
+ * But with taking undo state mangement into account it gets even worse. Deleted (to be
+ * restored connection points) live inside the UMLClassChange until they get reverted back
+ * to the object *or* get free'd by umlclass_change_free()
+ *
+ * Since the implementation of attributes/operations being settable via StdProps there are
+ * more places to keep this stuff consitent. So here comes a tolerant helper.
+ *
+ * NOTE: Same function as uml_operation_ensure_connection_points(),
+ * with C++ it would be a template function ;)
+ */
+void
+dia_uml_attribute_ensure_connection_points (DiaUmlAttribute* attr, DiaObject* obj)
+{
+  if (!attr->left_connection)
+    attr->left_connection = g_new0(ConnectionPoint,1);
+  attr->left_connection->object = obj;
+  if (!attr->right_connection)
+    attr->right_connection = g_new0(ConnectionPoint,1);
+  attr->right_connection->object = obj;
+}
diff --git a/objects/UML/dia-uml-attribute.h b/objects/UML/dia-uml-attribute.h
new file mode 100644
index 00000000..984a6320
--- /dev/null
+++ b/objects/UML/dia-uml-attribute.h
@@ -0,0 +1,38 @@
+#include <glib-object.h>
+#include "uml.h"
+
+#ifndef UML_ATTR_H
+#define UML_ATTR_H
+
+#define DIA_UML_TYPE_ATTRIBUTE (dia_uml_attribute_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlAttribute, dia_uml_attribute, DIA_UML, ATTRIBUTE, GObject)
+
+/** \brief A list of DiaUmlAttribute is contained in UMLClass
+ * Some would call them member variables ;)
+ */
+struct _DiaUmlAttribute {
+  GObject parent;
+  gint internal_id; /**< Arbitrary integer to recognize attributes after 
+                    * the user has shuffled them in the dialog. */
+  gchar *name; /**< the member variables name */
+  gchar *type; /**< the return value */
+  gchar *value; /**< default parameter : Can be NULL => No default value */
+  gchar *comment; /**< comment */
+  UMLVisibility visibility; /**< attributes visibility */
+  int abstract; /**< not sure if this applicable */
+  int class_scope; /**< in C++ : static member */
+  
+  ConnectionPoint* left_connection; /**< left */
+  ConnectionPoint* right_connection; /**< right */
+};
+
+DiaUmlAttribute *dia_uml_attribute_new                      ();
+/** calculated the 'formated' representation */
+gchar           *dia_uml_attribute_format                   (DiaUmlAttribute *attribute);
+DiaUmlAttribute *dia_uml_attribute_copy                     (DiaUmlAttribute *attr);
+void             dia_uml_attribute_ensure_connection_points (DiaUmlAttribute *attr,
+                                                             DiaObject       *obj);
+
+void uml_attribute_write(AttributeNode attr_node, DiaUmlAttribute *attr, DiaContext *ctx);
+
+#endif
\ No newline at end of file
diff --git a/objects/UML/dia-uml-class.c b/objects/UML/dia-uml-class.c
index fc537b9d..909a5a45 100644
--- a/objects/UML/dia-uml-class.c
+++ b/objects/UML/dia-uml-class.c
@@ -1,4 +1,6 @@
 #include "dia-uml-class.h"
+#include "dia-uml-operation.h"
+#include "dia-uml-attribute.h"
 #include "editor/dia-uml-list-store.h"
 
 struct _DiaUmlClass {
@@ -42,7 +44,7 @@ struct _DiaUmlClass {
   /* Maybe we could use GListStore for these? */
 
   /* Attributes: */
-  GList *attributes;
+  DiaUmlListStore *attributes;
 
   /* Operators: */
   DiaUmlListStore *operations;
@@ -70,13 +72,7 @@ clear_attrs (DiaUmlClass *self)
   g_free (self->stereotype);
   g_free (self->comment);
 
-  list = self->attributes;
-  while (list) {
-    uml_attribute_destroy ((UMLAttribute *) list->data);
-    list = g_list_next (list);
-  }
-  g_list_free (self->attributes);
-
+  g_clear_object (&self->attributes);
   g_clear_object (&self->operations);
 
   list = self->formal_params;
@@ -164,18 +160,18 @@ dia_uml_class_load (DiaUmlClass *self,
   self->fill_color = klass->fill_color;
   self->text_color = klass->text_color;
   
-  self->attributes = NULL;
   list = klass->attributes;
+  self->attributes = dia_uml_list_store_new ();
   while (list != NULL) {
-    UMLAttribute *attr = (UMLAttribute *)list->data;
-    UMLAttribute *attr_copy;
+    DiaUmlAttribute *attr = (DiaUmlAttribute *)list->data;
+    DiaUmlAttribute *attr_copy;
       
-    attr_copy = uml_attribute_copy(attr);
+    attr_copy = dia_uml_attribute_copy (attr);
     /* Looks wrong, but needed fro proper restore */
     attr_copy->left_connection = attr->left_connection;
     attr_copy->right_connection = attr->right_connection;
 
-    self->attributes = g_list_append(self->attributes, attr_copy);
+    dia_uml_list_store_add (self->attributes, DIA_UML_LIST_DATA (attr_copy));
     list = g_list_next(list);
   }
 
@@ -258,7 +254,13 @@ dia_uml_class_store (DiaUmlClass *self,
   klass->text_color = self->text_color;
 
   /* TODO: List stuff */
-  klass->attributes = self->attributes;
+  list = NULL;
+  while ((itm = g_list_model_get_item (G_LIST_MODEL (self->attributes), i))) {
+    list = g_list_append (list, itm);
+    i++;
+  }
+  klass->attributes = list;
+
 
   list = NULL;
   while ((itm = g_list_model_get_item (G_LIST_MODEL (self->operations), i))) {
@@ -271,6 +273,12 @@ dia_uml_class_store (DiaUmlClass *self,
   klass->formal_params = self->formal_params;
 }
 
+GListModel *
+dia_uml_class_get_attributes (DiaUmlClass *self)
+{
+  return G_LIST_MODEL (self->attributes);
+}
+
 GListModel *
 dia_uml_class_get_operations (DiaUmlClass *self)
 {
@@ -278,7 +286,7 @@ dia_uml_class_get_operations (DiaUmlClass *self)
 }
 
 /*
- * Don't rely on these two being called!
+ * Don't rely on these four being called!
  * 
  * The DiaUmlListStore can/will be edited directly (e.g. by DiaUmlClassEditor)
  * so connect to items-changed if you want to observe these!
@@ -298,3 +306,18 @@ dia_uml_class_remove_operation (DiaUmlClass     *self,
 {
   dia_uml_list_store_remove (self->operations, DIA_UML_LIST_DATA (operation));
 }
+
+void
+dia_uml_class_insert_attribute (DiaUmlClass     *self,
+                                DiaUmlAttribute *attribute,
+                                int              index)
+{
+  dia_uml_list_store_insert (self->attributes, DIA_UML_LIST_DATA (attribute), index);
+}
+
+void
+dia_uml_class_remove_attribute (DiaUmlClass     *self,
+                                DiaUmlAttribute *attribute)
+{
+  dia_uml_list_store_remove (self->attributes, DIA_UML_LIST_DATA (attribute));
+}
diff --git a/objects/UML/dia-uml-class.h b/objects/UML/dia-uml-class.h
index 09bc091e..240762ec 100644
--- a/objects/UML/dia-uml-class.h
+++ b/objects/UML/dia-uml-class.h
@@ -1,6 +1,8 @@
 #include <gtk/gtk.h>
 #include "uml.h"
 #include "class.h"
+#include "dia-uml-attribute.h"
+#include "dia-uml-operation.h"
 
 #ifndef UML_CLASS_H
 #define UML_CLASS_H
@@ -15,6 +17,12 @@ void             dia_uml_class_load             (DiaUmlClass     *self,
                                                  UMLClass        *klass);
 void             dia_uml_class_store            (DiaUmlClass     *self,
                                                  UMLClass        *klass);
+GListModel      *dia_uml_class_get_attributes   (DiaUmlClass     *self);
+void             dia_uml_class_remove_attribute (DiaUmlClass     *self,
+                                                 DiaUmlAttribute *attribute);
+void             dia_uml_class_insert_attribute (DiaUmlClass     *self,
+                                                 DiaUmlAttribute *attribute,
+                                                 int              index);
 GListModel      *dia_uml_class_get_operations   (DiaUmlClass     *self);
 void             dia_uml_class_remove_operation (DiaUmlClass     *self,
                                                  DiaUmlOperation *operation);
diff --git a/objects/UML/dia-uml-operation.h b/objects/UML/dia-uml-operation.h
index 79df9337..b6263bdd 100644
--- a/objects/UML/dia-uml-operation.h
+++ b/objects/UML/dia-uml-operation.h
@@ -6,16 +6,6 @@
 #ifndef UML_OP_H
 #define UML_OP_H
 
-/* TODO: enums as GEnum for _spec_enum ext */
-
-/** the visibility (allowed acces) of (to) various UML sub elements */
-typedef enum _UMLVisibility {
-  UML_PUBLIC, /**< everyone can use it */
-  UML_PRIVATE, /**< only accessible inside the class itself */
-  UML_PROTECTED, /**< the class and its inheritants ca use this */
-  UML_IMPLEMENTATION /**< ?What's this? Means implementation decision */
-} UMLVisibility;
-
 /** In some languages there are different kinds of class inheritances */
 typedef enum _UMLInheritanceType {
   UML_ABSTRACT, /**< Pure virtual method: an object of this class cannot be instanciated */
@@ -69,4 +59,7 @@ void             dia_uml_operation_remove_parameter         (DiaUmlOperation *se
                                                              DiaUmlParameter *parameter);
 GListModel      *dia_uml_operation_get_parameters           (DiaUmlOperation *self);
 
+void uml_operation_write(AttributeNode attr_node, DiaUmlOperation *op, DiaContext *ctx);
+
+
 #endif
\ No newline at end of file
diff --git a/objects/UML/editor/dia-uml-attribute-dialog.c b/objects/UML/editor/dia-uml-attribute-dialog.c
new file mode 100644
index 00000000..05e52692
--- /dev/null
+++ b/objects/UML/editor/dia-uml-attribute-dialog.c
@@ -0,0 +1,203 @@
+#include <gtk/gtk.h>
+
+#include "dia-uml-attribute-dialog.h"
+#include "dia_dirs.h"
+#include "uml.h"
+
+G_DEFINE_TYPE (DiaUmlAttributeDialog, dia_uml_attribute_dialog, GTK_TYPE_DIALOG)
+
+enum {
+  PROP_ATTRIBUTE = 1,
+  N_PROPS
+};
+static GParamSpec* properties[N_PROPS];
+
+enum {
+  ATTRIBUTE_DELETED,
+  LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+dia_uml_attribute_dialog_finalize (GObject *object)
+{
+  DiaUmlAttributeDialog *self = DIA_UML_ATTRIBUTE_DIALOG (object);
+
+  g_object_unref (self->attribute);
+}
+
+static gboolean
+visibility_to (GBinding *binding,
+               const GValue *from_value,
+               GValue *to_value,
+               gpointer user_data)
+{
+  const gchar *name = g_value_get_string (from_value);
+
+  if (g_strcmp0 (name, "private") == 0) {
+    g_value_set_int (to_value, UML_PRIVATE);
+  } else if (g_strcmp0 (name, "protected") == 0) {
+    g_value_set_int (to_value, UML_PROTECTED);
+  } else if (g_strcmp0 (name, "implementation") == 0) {
+    g_value_set_int (to_value, UML_IMPLEMENTATION);
+  } else {
+    g_value_set_int (to_value, UML_PUBLIC);
+  }
+  
+  return TRUE;
+}
+
+static gboolean
+visibility_from (GBinding *binding,
+                 const GValue *from_value,
+                 GValue *to_value,
+                 gpointer user_data)
+{
+  int mode = g_value_get_int (from_value);
+
+  if (mode == UML_PRIVATE) {
+    g_value_set_static_string (to_value, "private");
+  } else if (mode == UML_PROTECTED) {
+    g_value_set_static_string (to_value, "protected");
+  } else if (mode == UML_IMPLEMENTATION) {
+    g_value_set_static_string (to_value, "implementation");
+  } else {
+    g_value_set_static_string (to_value, "public");
+  }
+  
+  return TRUE;
+}
+
+static void
+dia_uml_attribute_dialog_set_property (GObject      *object,
+                                       guint         property_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+  DiaUmlAttributeDialog *self = DIA_UML_ATTRIBUTE_DIALOG (object);
+
+  switch (property_id) {
+    case PROP_ATTRIBUTE:
+      self->attribute = g_value_dup_object (value);
+      g_object_bind_property (G_OBJECT (self->attribute), "name",
+                              G_OBJECT (self->name), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->attribute), "type",
+                              G_OBJECT (self->type), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->attribute), "value",
+                              G_OBJECT (self->value), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      g_object_bind_property (G_OBJECT (self->attribute), "comment",
+                              G_OBJECT (self->comment), "text",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+      g_object_bind_property_full (G_OBJECT (self->attribute), "visibility",
+                                   G_OBJECT (self->visibility), "active-id",
+                                   G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
+                                   visibility_from,
+                                   visibility_to,
+                                   NULL, NULL);
+
+      g_object_bind_property (G_OBJECT (self->attribute), "class-scope",
+                              G_OBJECT (self->scope), "active",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+dia_uml_attribute_dialog_get_property (GObject    *object,
+                                       guint       property_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+  DiaUmlAttributeDialog *self = DIA_UML_ATTRIBUTE_DIALOG (object);
+  switch (property_id) {
+    case PROP_ATTRIBUTE:
+      g_value_set_object (value, self->attribute);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+  }
+}
+
+static void
+remove_attribute (DiaUmlAttributeDialog *self)
+{
+  g_signal_emit (G_OBJECT (self),
+                 signals[ATTRIBUTE_DELETED], 0,
+                 self->attribute);
+  gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+static void
+dia_uml_attribute_dialog_class_init (DiaUmlAttributeDialogClass *klass)
+{
+  GFile *template_file;
+  GBytes *template;
+  GError *err = NULL;
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = dia_uml_attribute_dialog_finalize;
+  object_class->set_property = dia_uml_attribute_dialog_set_property;
+  object_class->get_property = dia_uml_attribute_dialog_get_property;
+
+  properties[PROP_ATTRIBUTE] =
+    g_param_spec_object ("attribute",
+                         "Attribute",
+                         "Attribute this editor controls",
+                         DIA_UML_TYPE_ATTRIBUTE,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+  g_object_class_install_properties (object_class,
+                                     N_PROPS,
+                                     properties);
+
+  signals[ATTRIBUTE_DELETED] = g_signal_new ("attribute-deleted",
+                                             G_TYPE_FROM_CLASS (klass),
+                                             G_SIGNAL_RUN_FIRST,
+                                             0, NULL, NULL, NULL,
+                                             G_TYPE_NONE, 1,
+                                             DIA_UML_TYPE_ATTRIBUTE);
+
+  /* TODO: Use GResource */
+  template_file = g_file_new_for_path (build_ui_filename ("ui/dia-uml-attribute-dialog.ui"));
+  template = g_file_load_bytes (template_file, NULL, NULL, &err);
+
+  if (err)
+    g_critical ("Failed to load template: %s", err->message);
+
+  gtk_widget_class_set_template (widget_class, template);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlAttributeDialog, name);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlAttributeDialog, type);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlAttributeDialog, value);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlAttributeDialog, comment);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlAttributeDialog, visibility);
+  gtk_widget_class_bind_template_child (widget_class, DiaUmlAttributeDialog, scope);
+  gtk_widget_class_bind_template_callback (widget_class, remove_attribute);
+
+  g_object_unref (template_file);
+}
+
+static void
+dia_uml_attribute_dialog_init (DiaUmlAttributeDialog *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+GtkWidget *
+dia_uml_attribute_dialog_new (GtkWindow       *parent,
+                              DiaUmlAttribute *attr)
+{
+  return g_object_new (DIA_UML_TYPE_ATTRIBUTE_DIALOG,
+                       "attribute", attr,
+                       "transient-for", parent,
+                       "modal", TRUE,
+                       NULL);
+}
diff --git a/objects/UML/editor/dia-uml-attribute-dialog.h b/objects/UML/editor/dia-uml-attribute-dialog.h
new file mode 100644
index 00000000..7994c42f
--- /dev/null
+++ b/objects/UML/editor/dia-uml-attribute-dialog.h
@@ -0,0 +1,22 @@
+#include <gtk/gtk.h>
+#include "uml.h"
+#include "dia-uml-attribute.h"
+
+#define DIA_UML_TYPE_ATTRIBUTE_DIALOG (dia_uml_attribute_dialog_get_type ())
+G_DECLARE_FINAL_TYPE (DiaUmlAttributeDialog, dia_uml_attribute_dialog, DIA_UML, ATTRIBUTE_DIALOG, GtkDialog)
+
+struct _DiaUmlAttributeDialog {
+  GtkDialog parent;
+
+  GtkWidget *name;
+  GtkWidget *type;
+  GtkWidget *value;
+  GtkWidget *visibility;
+  GtkWidget *scope;
+  GtkTextBuffer *comment;
+
+  DiaUmlAttribute *attribute;
+};
+
+GtkWidget *dia_uml_attribute_dialog_new (GtkWindow       *parent,
+                                         DiaUmlAttribute *attr);
diff --git a/objects/UML/editor/dia-uml-class-editor.c b/objects/UML/editor/dia-uml-class-editor.c
index 228d0393..2a5e8b6d 100644
--- a/objects/UML/editor/dia-uml-class-editor.c
+++ b/objects/UML/editor/dia-uml-class-editor.c
@@ -2,6 +2,7 @@
 #include "dia-uml-list-row.h"
 #include "dia-uml-list-store.h"
 #include "dia-uml-operation-dialog.h"
+#include "dia-uml-attribute-dialog.h"
 #include "dia_dirs.h"
 
 struct _DiaUmlClassEditor {
@@ -23,9 +24,16 @@ enum {
 static GParamSpec* uml_cedit_properties[UML_CEDIT_N_PROPS];
 
 static void
-build_list (DiaUmlClassEditor *self)
+build_lists (DiaUmlClassEditor *self)
 {
-  GListModel *store = dia_uml_class_get_operations (self->klass);
+  GListModel *store;
+
+  store = dia_uml_class_get_attributes (self->klass);
+  gtk_list_box_bind_model (GTK_LIST_BOX (self->attributes), store,
+                           (GtkListBoxCreateWidgetFunc) dia_uml_list_row_new,
+                           store, NULL);
+
+  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);
@@ -75,6 +83,50 @@ edit_operation (DiaUmlClassEditor *self,
   g_object_unref (op);
 }
 
+static void
+remove_attr (DiaUmlAttributeDialog *dlg,
+             DiaUmlAttribute       *attr,
+             DiaUmlClassEditor     *self)
+{
+  dia_uml_class_remove_attribute (self->klass, attr);
+}
+
+static void
+add_attribute (DiaUmlClassEditor *self)
+{
+  DiaUmlAttribute *attr;
+  GtkWidget *edit;
+  GtkWidget *parent;
+
+  attr = dia_uml_attribute_new ();
+  dia_uml_class_insert_attribute (self->klass, attr, -1);
+
+  parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
+  edit = dia_uml_attribute_dialog_new (GTK_WINDOW (parent), attr);
+  g_signal_connect (edit, "attribute-deleted", G_CALLBACK (remove_attr), self);
+
+  gtk_widget_show (edit);
+}
+
+static void
+edit_attribute (DiaUmlClassEditor *self,
+                GtkListBoxRow     *row)
+{
+  GtkWidget *dlg;
+  GtkWidget *parent;
+  DiaUmlAttribute *attr;
+
+  if (!DIA_UML_IS_LIST_ROW (row))
+    return;
+  
+  parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
+  attr = DIA_UML_ATTRIBUTE (dia_uml_list_row_get_data (DIA_UML_LIST_ROW (row)));
+  dlg = dia_uml_attribute_dialog_new (GTK_WINDOW (parent), attr);
+  g_signal_connect (dlg, "attribute-deleted", G_CALLBACK (remove_attr), self);
+  gtk_widget_show (dlg);
+  g_object_unref (attr);
+}
+
 static void
 dia_uml_class_editor_finalize (GObject *object)
 {
@@ -94,7 +146,7 @@ dia_uml_class_editor_set_property (GObject      *object,
   switch (property_id) {
     case UML_CEDIT_PROP_CLASS:
       self->klass = g_value_dup_object (value);
-      build_list (self);
+      build_lists (self);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -154,6 +206,8 @@ dia_uml_class_editor_class_init (DiaUmlClassEditorClass *klass)
   gtk_widget_class_bind_template_child (widget_class, DiaUmlClassEditor, attributes);
   gtk_widget_class_bind_template_child (widget_class, DiaUmlClassEditor, operations);
   gtk_widget_class_bind_template_child (widget_class, DiaUmlClassEditor, templates);
+  gtk_widget_class_bind_template_callback (widget_class, add_attribute);
+  gtk_widget_class_bind_template_callback (widget_class, edit_attribute);
   gtk_widget_class_bind_template_callback (widget_class, add_operation);
   gtk_widget_class_bind_template_callback (widget_class, edit_operation);
 
diff --git a/objects/UML/editor/dia-uml-operation-dialog.c b/objects/UML/editor/dia-uml-operation-dialog.c
index b64cf4be..92c1cff7 100644
--- a/objects/UML/editor/dia-uml-operation-dialog.c
+++ b/objects/UML/editor/dia-uml-operation-dialog.c
@@ -54,12 +54,14 @@ visibility_from (GBinding *binding,
 {
   int mode = g_value_get_int (from_value);
 
-  if (mode == UML_ABSTRACT) {
-    g_value_set_static_string (to_value, "abstract");
-  } else if (mode == UML_POLYMORPHIC) {
-    g_value_set_static_string (to_value, "poly");
+  if (mode == UML_PRIVATE) {
+    g_value_set_static_string (to_value, "private");
+  } else if (mode == UML_PROTECTED) {
+    g_value_set_static_string (to_value, "protected");
+  } else if (mode == UML_IMPLEMENTATION) {
+    g_value_set_static_string (to_value, "implementation");
   } else {
-    g_value_set_static_string (to_value, "leaf");
+    g_value_set_static_string (to_value, "public");
   }
   
   return TRUE;
@@ -92,18 +94,15 @@ inheritance_from (GBinding *binding,
 {
   int mode = g_value_get_int (from_value);
 
-  if (mode == UML_PRIVATE) {
-    g_value_set_static_string (to_value, "private");
-  } else if (mode == UML_PROTECTED) {
-    g_value_set_static_string (to_value, "protected");
-  } else if (mode == UML_IMPLEMENTATION) {
-    g_value_set_static_string (to_value, "implementation");
+  if (mode == UML_ABSTRACT) {
+    g_value_set_static_string (to_value, "abstract");
+  } else if (mode == UML_POLYMORPHIC) {
+    g_value_set_static_string (to_value, "poly");
   } else {
-    g_value_set_static_string (to_value, "public");
+    g_value_set_static_string (to_value, "leaf");
   }
   
-  return TRUE;
-}
+  return TRUE;}
 
 static void
 dia_uml_operation_dialog_set_property (GObject      *object,
@@ -151,12 +150,10 @@ dia_uml_operation_dialog_set_property (GObject      *object,
                               G_OBJECT (self->scope), "active",
                               G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 
-      self->building = TRUE;
       paras = dia_uml_operation_get_parameters (self->operation);
       gtk_list_box_bind_model (GTK_LIST_BOX (self->list), paras,
                               (GtkListBoxCreateWidgetFunc) dia_uml_operation_parameter_row_new,
                               paras, NULL);
-      self->building = FALSE;
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
diff --git a/objects/UML/editor/dia-uml-operation-dialog.h b/objects/UML/editor/dia-uml-operation-dialog.h
index e2c907ca..2ba11e10 100644
--- a/objects/UML/editor/dia-uml-operation-dialog.h
+++ b/objects/UML/editor/dia-uml-operation-dialog.h
@@ -1,5 +1,6 @@
 #include <gtk/gtk.h>
 #include "uml.h"
+#include "dia-uml-operation.h"
 
 #define DIA_UML_TYPE_OPERATION_DIALOG (dia_uml_operation_dialog_get_type ())
 G_DECLARE_FINAL_TYPE (DiaUmlOperationDialog, dia_uml_operation_dialog, DIA_UML, OPERATION_DIALOG, GtkDialog)
@@ -17,8 +18,6 @@ struct _DiaUmlOperationDialog {
   GtkTextBuffer *comment;
   GtkWidget *list;
 
-  gboolean building;
-
   DiaUmlOperation *operation;
 };
 
diff --git a/objects/UML/editor/dia-uml-operation-parameter-row.h 
b/objects/UML/editor/dia-uml-operation-parameter-row.h
index 255b3460..1400af3c 100644
--- a/objects/UML/editor/dia-uml-operation-parameter-row.h
+++ b/objects/UML/editor/dia-uml-operation-parameter-row.h
@@ -1,5 +1,6 @@
 #include <gtk/gtk.h>
 #include "uml.h"
+#include "dia-uml-list-store.h"
 
 G_BEGIN_DECLS
 
diff --git a/objects/UML/uml.c b/objects/UML/uml.c
index ccf98ac8..2d7ce2dc 100644
--- a/objects/UML/uml.c
+++ b/objects/UML/uml.c
@@ -30,6 +30,8 @@
 #include "plug-ins.h"
 #include "properties.h"
 
+#include "dia-uml-operation.h"
+
 extern DiaObjectType umlclass_type;
 extern DiaObjectType umlclass_template_type;
 extern DiaObjectType note_type;
diff --git a/objects/UML/uml.h b/objects/UML/uml.h
index e6417df4..bb354056 100644
--- a/objects/UML/uml.h
+++ b/objects/UML/uml.h
@@ -26,28 +26,18 @@
 #include "intl.h"
 #include "connectionpoint.h"
 #include "dia_xml.h"
-#include "dia-uml-operation.h"
 
-typedef struct _UMLAttribute UMLAttribute;
-typedef struct _UMLFormalParameter UMLFormalParameter;
+/* TODO: enums as GEnum for _spec_enum ext */
 
-/** \brief A list of UMLAttribute is contained in UMLClass
- * Some would call them member variables ;)
- */
-struct _UMLAttribute {
-  gint internal_id; /**< Arbitrary integer to recognize attributes after 
-                    * the user has shuffled them in the dialog. */
-  gchar *name; /**< the member variables name */
-  gchar *type; /**< the return value */
-  gchar *value; /**< default parameter : Can be NULL => No default value */
-  gchar *comment; /**< comment */
-  UMLVisibility visibility; /**< attributes visibility */
-  int abstract; /**< not sure if this applicable */
-  int class_scope; /**< in C++ : static member */
-  
-  ConnectionPoint* left_connection; /**< left */
-  ConnectionPoint* right_connection; /**< right */
-};
+/** the visibility (allowed acces) of (to) various UML sub elements */
+typedef enum _UMLVisibility {
+  UML_PUBLIC, /**< everyone can use it */
+  UML_PRIVATE, /**< only accessible inside the class itself */
+  UML_PROTECTED, /**< the class and its inheritants ca use this */
+  UML_IMPLEMENTATION /**< ?What's this? Means implementation decision */
+} UMLVisibility;
+
+typedef struct _UMLFormalParameter UMLFormalParameter;
 
 /** \brief A list of UMLFormalParameter is contained in DiaUmlOperation
  * Some would call them template parameters ;)
@@ -63,23 +53,13 @@ struct _UMLFormalParameter {
 /** end stereotype symbol(like \xbb) for local locale */
 #define UML_STEREOTYPE_END _(">>")
 
-/** calculated the 'formated' representation */
-gchar *uml_get_attribute_string (UMLAttribute *attribute);
 /** calculated the 'formated' representation */
 gchar *uml_get_formalparameter_string(UMLFormalParameter *parameter);
-void uml_attribute_copy_into(UMLAttribute *srcattr, UMLAttribute *destattr);
-UMLAttribute *uml_attribute_copy(UMLAttribute *attr);
 UMLFormalParameter *uml_formalparameter_copy(UMLFormalParameter *param);
-void uml_attribute_destroy(UMLAttribute *attribute);
 void uml_formalparameter_destroy(UMLFormalParameter *param);
-UMLAttribute *uml_attribute_new(void);
 
 UMLFormalParameter *uml_formalparameter_new(void);
 
-void uml_attribute_ensure_connection_points (UMLAttribute *attr, DiaObject* obj);
-
-void uml_attribute_write(AttributeNode attr_node, UMLAttribute *attr, DiaContext *ctx);
-void uml_operation_write(AttributeNode attr_node, DiaUmlOperation *op, DiaContext *ctx);
 void uml_formalparameter_write(AttributeNode attr_node, UMLFormalParameter *param, DiaContext *ctx);
 
 void list_box_separators (GtkListBoxRow *row,


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