[dia/dia-next: 47/59] Move attributes to the new editor
- From: Zander <zbrown src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia/dia-next: 47/59] Move attributes to the new editor
- Date: Wed, 9 Jan 2019 18:38:15 +0000 (UTC)
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]