1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * umlattribute.c : refactored from uml.c, class.c to final use StdProps
5 * PROP_TYPE_DARRAY, a list where each element is a set
6 * of properies described by the same StdPropDesc
7 * Copyright (C) 2005 Hans Breuer
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include "properties.h"
33 extern PropEnumData _uml_visibilities
[];
35 static PropDescription umlattribute_props
[] = {
36 { "name", PROP_TYPE_STRING
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
37 N_("Name"), NULL
, NULL
},
38 { "type", PROP_TYPE_STRING
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
39 N_("Type"), NULL
, NULL
},
40 { "value", PROP_TYPE_STRING
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
41 N_("Value"), NULL
, NULL
},
42 { "comment", PROP_TYPE_STRING
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
43 N_("Comment"), NULL
, NULL
},
44 { "visibility", PROP_TYPE_ENUM
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
45 N_("Visibility"), NULL
, _uml_visibilities
},
46 { "abstract", PROP_TYPE_BOOL
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
47 N_("Abstract (?)"), NULL
, NULL
},
48 { "class_scope", PROP_TYPE_BOOL
, PROP_FLAG_VISIBLE
| PROP_FLAG_OPTIONAL
,
49 N_("Class scope (static)"), NULL
, NULL
},
54 static PropOffset umlattribute_offsets
[] = {
55 { "name", PROP_TYPE_STRING
, offsetof(UMLAttribute
, name
) },
56 { "type", PROP_TYPE_STRING
, offsetof(UMLAttribute
, type
) },
57 { "value", PROP_TYPE_STRING
, offsetof(UMLAttribute
, value
) },
58 { "comment", PROP_TYPE_STRING
, offsetof(UMLAttribute
, comment
) },
59 { "visibility", PROP_TYPE_ENUM
, offsetof(UMLAttribute
, visibility
) },
60 { "abstract", PROP_TYPE_BOOL
, offsetof(UMLAttribute
, abstract
) },
61 { "class_scope", PROP_TYPE_BOOL
, offsetof(UMLAttribute
, class_scope
) },
66 PropDescDArrayExtra umlattribute_extra
= {
67 { umlattribute_props
, umlattribute_offsets
, "umlattribute" },
68 (NewRecordFunc
)uml_attribute_new
,
69 (FreeRecordFunc
)uml_attribute_destroy
74 uml_attribute_new(void)
77 static gint next_id
= 1;
79 attr
= g_new0(UMLAttribute
, 1);
80 attr
->internal_id
= next_id
++;
81 attr
->name
= g_strdup("");
82 attr
->type
= g_strdup("");
84 attr
->comment
= g_strdup("");
85 attr
->visibility
= UML_PUBLIC
;
86 attr
->abstract
= FALSE
;
87 attr
->class_scope
= FALSE
;
88 #if 0 /* setup elsewhere */
89 attr
->left_connection
= g_new0(ConnectionPoint
, 1);
90 attr
->right_connection
= g_new0(ConnectionPoint
, 1);
95 /** Copy the data of an attribute into another, but not the connections.
96 * Frees up any strings in the attribute being copied into. */
98 uml_attribute_copy_into(UMLAttribute
*attr
, UMLAttribute
*newattr
)
100 newattr
->internal_id
= attr
->internal_id
;
101 if (newattr
->name
!= NULL
) {
102 g_free(newattr
->name
);
104 newattr
->name
= g_strdup(attr
->name
);
105 if (newattr
->type
!= NULL
) {
106 g_free(newattr
->type
);
108 newattr
->type
= g_strdup(attr
->type
);
110 if (newattr
->value
!= NULL
) {
111 g_free(newattr
->value
);
113 if (attr
->value
!= NULL
) {
114 newattr
->value
= g_strdup(attr
->value
);
116 newattr
->value
= NULL
;
119 if (newattr
->comment
!= NULL
) {
120 g_free(newattr
->comment
);
122 if (attr
->comment
!= NULL
)
123 newattr
->comment
= g_strdup (attr
->comment
);
125 newattr
->comment
= NULL
;
127 newattr
->visibility
= attr
->visibility
;
128 newattr
->abstract
= attr
->abstract
;
129 newattr
->class_scope
= attr
->class_scope
;
132 /** Copy an attribute's content.
135 uml_attribute_copy(UMLAttribute
*attr
)
137 UMLAttribute
*newattr
;
139 newattr
= g_new0(UMLAttribute
, 1);
141 uml_attribute_copy_into(attr
, newattr
);
147 uml_attribute_destroy(UMLAttribute
*attr
)
151 if (attr
->value
!= NULL
)
153 if (attr
->comment
!= NULL
)
154 g_free(attr
->comment
);
155 #if 0 /* free'd elsewhere */
156 g_free(attr
->left_connection
);
157 g_free(attr
->right_connection
);
163 uml_attribute_write(AttributeNode attr_node
, UMLAttribute
*attr
)
167 composite
= data_add_composite(attr_node
, "umlattribute");
169 data_add_string(composite_add_attribute(composite
, "name"),
171 data_add_string(composite_add_attribute(composite
, "type"),
173 data_add_string(composite_add_attribute(composite
, "value"),
175 data_add_string(composite_add_attribute(composite
, "comment"),
177 data_add_enum(composite_add_attribute(composite
, "visibility"),
179 data_add_boolean(composite_add_attribute(composite
, "abstract"),
181 data_add_boolean(composite_add_attribute(composite
, "class_scope"),
185 /* Warning, the following *must* be strictly ASCII characters (or fix the
186 following code for UTF-8 cleanliness */
188 char visible_char
[] = { '+', '-', '#', ' ' };
191 uml_get_attribute_string (UMLAttribute
*attribute
)
196 len
= 1 + strlen (attribute
->name
) + strlen (attribute
->type
);
197 if (attribute
->name
[0] && attribute
->type
[0]) {
200 if (attribute
->value
!= NULL
&& attribute
->value
[0] != '\0') {
201 len
+= 3 + strlen (attribute
->value
);
204 str
= g_malloc (sizeof (char) * (len
+ 1));
206 str
[0] = visible_char
[(int) attribute
->visibility
];
209 strcat (str
, attribute
->name
);
210 if (attribute
->name
[0] && attribute
->type
[0]) {
213 strcat (str
, attribute
->type
);
214 if (attribute
->value
!= NULL
&& attribute
->value
[0] != '\0') {
216 strcat (str
, attribute
->value
);
219 g_assert (strlen (str
) == len
);
225 * The ownership of these connection points is quite complicated. Instead of being part of the UMLAttribute as one may expect
226 * at first, they are somewhat in between the DiaObject (see: DiaObject::connections and the concrete user, here UMLClass)
227 * and the UMLAttribute.
228 * But with taking undo state mangement into account it gets even worse. Deleted (to be restored connection points) live inside
229 * the UMLClassChange until they get reverted back to the object *or* get free'd by umlclass_change_free()
230 * Since the implementation of attributes/operations being settable via StdProps there are more places to keep this stuff
231 * consitent. So here comes a tolerant helper.
233 * NOTE: Same function as uml_operation_ensure_connection_points(), with C++ it would be a template function ;)
236 uml_attribute_ensure_connection_points (UMLAttribute
* attr
, DiaObject
* obj
)
238 if (!attr
->left_connection
)
239 attr
->left_connection
= g_new0(ConnectionPoint
,1);
240 attr
->left_connection
->object
= obj
;
241 if (!attr
->right_connection
)
242 attr
->right_connection
= g_new0(ConnectionPoint
,1);
243 attr
->right_connection
->object
= obj
;