2006-12-05 David Lodge <dave@cirt.net>
[dia.git] / objects / UML / class_dialog.c
blob932ffe219922ed80b242e3c7cc56fab88a476bbe
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 * File: class_dialog.c
20 * Purpose: This file contains the code the draws and handles the class
21 * dialog. This is the dialog box that is displayed when the
22 * class Icon is double clicked.
24 /*--------------------------------------------------------------------------**
25 * Copyright(c) 2005 David Klotzbach
26 ** **
27 ** Multi-Line Comments May 10, 2005 - Dave Klotzbach **
28 ** dklotzbach@foxvalley.net **
29 ** **
30 **--------------------------------------------------------------------------*/
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
36 #include <assert.h>
37 #include <gtk/gtk.h>
38 #include <math.h>
39 #include <string.h>
41 #include "object.h"
42 #include "objchange.h"
43 #include "intl.h"
44 #include "class.h"
47 typedef struct _Disconnect {
48 ConnectionPoint *cp;
49 DiaObject *other_object;
50 Handle *other_handle;
51 } Disconnect;
53 typedef struct _UMLClassState UMLClassState;
55 struct _UMLClassState {
56 char *name;
57 char *stereotype;
58 int abstract;
59 int suppress_attributes;
60 int suppress_operations;
61 int visible_attributes;
62 int visible_operations;
64 /* Attributes: */
65 GList *attributes;
67 /* Operators: */
68 GList *operations;
70 /* Template: */
71 int template;
72 GList *formal_params;
76 typedef struct _UMLClassChange UMLClassChange;
78 struct _UMLClassChange {
79 ObjectChange obj_change;
81 UMLClass *obj;
83 GList *added_cp;
84 GList *deleted_cp;
85 GList *disconnected;
87 int applied;
89 UMLClassState *saved_state;
92 static UMLClassState *umlclass_get_state(UMLClass *umlclass);
93 static ObjectChange *new_umlclass_change(UMLClass *obj, UMLClassState *saved_state,
94 GList *added, GList *deleted,
95 GList *disconnected);
96 static const gchar *get_comment(GtkTextView *);
97 static void set_comment(GtkTextView *, gchar *);
99 /**** Utility functions ******/
100 static void
101 umlclass_store_disconnects(UMLClassDialog *prop_dialog,
102 ConnectionPoint *cp)
104 Disconnect *dis;
105 DiaObject *connected_obj;
106 GList *list;
107 int i;
109 list = cp->connected;
110 while (list != NULL) {
111 connected_obj = (DiaObject *)list->data;
113 for (i=0;i<connected_obj->num_handles;i++) {
114 if (connected_obj->handles[i]->connected_to == cp) {
115 dis = g_new0(Disconnect, 1);
116 dis->cp = cp;
117 dis->other_object = connected_obj;
118 dis->other_handle = connected_obj->handles[i];
120 prop_dialog->disconnected_connections =
121 g_list_prepend(prop_dialog->disconnected_connections, dis);
124 list = g_list_next(list);
128 /********************************************************
129 ******************** CLASS *****************************
130 ********************************************************/
132 static void
133 class_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog)
135 const gchar *s;
137 if (umlclass->name != NULL)
138 g_free(umlclass->name);
140 s = gtk_entry_get_text (prop_dialog->classname);
141 if (s && s[0])
142 umlclass->name = g_strdup (s);
143 else
144 umlclass->name = NULL;
146 if (umlclass->stereotype != NULL)
147 g_free(umlclass->stereotype);
149 s = gtk_entry_get_text(prop_dialog->stereotype);
150 if (s && s[0])
151 umlclass->stereotype = g_strdup (s);
152 else
153 umlclass->stereotype = NULL;
155 if (umlclass->comment != NULL)
156 g_free (umlclass->comment);
158 s = get_comment(prop_dialog->comment);
159 if (s && s[0])
160 umlclass->comment = g_strdup (s);
161 else
162 umlclass->comment = NULL;
164 umlclass->abstract = prop_dialog->abstract_class->active;
165 umlclass->visible_attributes = prop_dialog->attr_vis->active;
166 umlclass->visible_operations = prop_dialog->op_vis->active;
167 umlclass->wrap_operations = prop_dialog->op_wrap->active;
168 umlclass->wrap_after_char = gtk_spin_button_get_value_as_int(prop_dialog->wrap_after_char);
169 umlclass->comment_line_length = gtk_spin_button_get_value_as_int(prop_dialog->comment_line_length);
170 umlclass->comment_tagging = prop_dialog->comment_tagging->active;
171 umlclass->visible_comments = prop_dialog->comments_vis->active;
172 umlclass->suppress_attributes = prop_dialog->attr_supp->active;
173 umlclass->suppress_operations = prop_dialog->op_supp->active;
174 dia_color_selector_get_color(GTK_WIDGET(prop_dialog->text_color), &umlclass->text_color);
175 dia_color_selector_get_color(GTK_WIDGET(prop_dialog->line_color), &umlclass->line_color);
176 dia_color_selector_get_color(GTK_WIDGET(prop_dialog->fill_color), &umlclass->fill_color);
178 umlclass->normal_font = dia_font_selector_get_font (prop_dialog->normal_font);
179 umlclass->polymorphic_font = dia_font_selector_get_font (prop_dialog->polymorphic_font);
180 umlclass->abstract_font = dia_font_selector_get_font (prop_dialog->abstract_font);
181 umlclass->classname_font = dia_font_selector_get_font (prop_dialog->classname_font);
182 umlclass->abstract_classname_font = dia_font_selector_get_font (prop_dialog->abstract_classname_font);
183 umlclass->comment_font = dia_font_selector_get_font (prop_dialog->comment_font);
185 umlclass->font_height = gtk_spin_button_get_value_as_float (prop_dialog->normal_font_height);
186 umlclass->abstract_font_height = gtk_spin_button_get_value_as_float (prop_dialog->abstract_font_height);
187 umlclass->polymorphic_font_height = gtk_spin_button_get_value_as_float (prop_dialog->polymorphic_font_height);
188 umlclass->classname_font_height = gtk_spin_button_get_value_as_float (prop_dialog->classname_font_height);
189 umlclass->abstract_classname_font_height = gtk_spin_button_get_value_as_float (prop_dialog->abstract_classname_font_height);
190 umlclass->comment_font_height = gtk_spin_button_get_value_as_float (prop_dialog->comment_font_height);
193 static void
194 class_fill_in_dialog(UMLClass *umlclass)
196 UMLClassDialog *prop_dialog;
198 prop_dialog = umlclass->properties_dialog;
200 if (umlclass->name)
201 gtk_entry_set_text(prop_dialog->classname, umlclass->name);
202 if (umlclass->stereotype != NULL)
203 gtk_entry_set_text(prop_dialog->stereotype, umlclass->stereotype);
204 else
205 gtk_entry_set_text(prop_dialog->stereotype, "");
207 if (umlclass->comment != NULL)
208 set_comment(prop_dialog->comment, umlclass->comment);
209 else
210 set_comment(prop_dialog->comment, "");
212 gtk_toggle_button_set_active(prop_dialog->abstract_class, umlclass->abstract);
213 gtk_toggle_button_set_active(prop_dialog->attr_vis, umlclass->visible_attributes);
214 gtk_toggle_button_set_active(prop_dialog->op_vis, umlclass->visible_operations);
215 gtk_toggle_button_set_active(prop_dialog->op_wrap, umlclass->wrap_operations);
216 gtk_spin_button_set_value (prop_dialog->wrap_after_char, umlclass->wrap_after_char);
217 gtk_spin_button_set_value (prop_dialog->comment_line_length, umlclass->comment_line_length);
218 gtk_toggle_button_set_active(prop_dialog->comment_tagging, umlclass->comment_tagging);
219 gtk_toggle_button_set_active(prop_dialog->comments_vis, umlclass->visible_comments);
220 gtk_toggle_button_set_active(prop_dialog->attr_supp, umlclass->suppress_attributes);
221 gtk_toggle_button_set_active(prop_dialog->op_supp, umlclass->suppress_operations);
222 dia_color_selector_set_color(GTK_WIDGET(prop_dialog->text_color), &umlclass->text_color);
223 dia_color_selector_set_color(GTK_WIDGET(prop_dialog->line_color), &umlclass->line_color);
224 dia_color_selector_set_color(GTK_WIDGET(prop_dialog->fill_color), &umlclass->fill_color);
225 dia_font_selector_set_font (prop_dialog->normal_font, umlclass->normal_font);
226 dia_font_selector_set_font (prop_dialog->polymorphic_font, umlclass->polymorphic_font);
227 dia_font_selector_set_font (prop_dialog->abstract_font, umlclass->abstract_font);
228 dia_font_selector_set_font (prop_dialog->classname_font, umlclass->classname_font);
229 dia_font_selector_set_font (prop_dialog->abstract_classname_font, umlclass->abstract_classname_font);
230 dia_font_selector_set_font (prop_dialog->comment_font, umlclass->comment_font);
231 gtk_spin_button_set_value (prop_dialog->normal_font_height, umlclass->font_height);
232 gtk_spin_button_set_value (prop_dialog->polymorphic_font_height, umlclass->polymorphic_font_height);
233 gtk_spin_button_set_value (prop_dialog->abstract_font_height, umlclass->abstract_font_height);
234 gtk_spin_button_set_value (prop_dialog->classname_font_height, umlclass->classname_font_height);
235 gtk_spin_button_set_value (prop_dialog->abstract_classname_font_height, umlclass->abstract_classname_font_height);
236 gtk_spin_button_set_value (prop_dialog->comment_font_height, umlclass->comment_font_height);
239 static void
240 create_font_props_row (GtkTable *table,
241 const char *kind,
242 gint row,
243 DiaFont *font,
244 real height,
245 DiaFontSelector **fontsel,
246 GtkSpinButton **heightsel)
248 GtkWidget *label;
249 GtkObject *adj;
251 label = gtk_label_new (kind);
252 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
253 gtk_table_attach_defaults (table, label, 0, 1, row, row+1);
254 *fontsel = DIAFONTSELECTOR (dia_font_selector_new ());
255 dia_font_selector_set_font (DIAFONTSELECTOR (*fontsel), font);
256 gtk_table_attach_defaults (GTK_TABLE (table), GTK_WIDGET(*fontsel), 1, 2, row, row+1);
258 adj = gtk_adjustment_new (height, 0.1, 10.0, 0.1, 1.0, 1.0);
259 *heightsel = GTK_SPIN_BUTTON (gtk_spin_button_new (GTK_ADJUSTMENT(adj), 1.0, 2));
260 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (*heightsel), TRUE);
261 gtk_table_attach_defaults (table, GTK_WIDGET (*heightsel), 2, 3, row, row+1);
264 static void
265 class_create_page(GtkNotebook *notebook, UMLClass *umlclass)
267 UMLClassDialog *prop_dialog;
268 GtkWidget *page_label;
269 GtkWidget *label;
270 GtkWidget *hbox;
271 GtkWidget *hbox2;
272 GtkWidget *vbox;
273 GtkWidget *entry;
274 GtkWidget *scrolledwindow;
275 GtkWidget *checkbox;
276 GtkWidget *text_color;
277 GtkWidget *fill_color;
278 GtkWidget *line_color;
279 GtkWidget *table;
280 GtkObject *adj;
282 prop_dialog = umlclass->properties_dialog;
284 /* Class page: */
285 page_label = gtk_label_new_with_mnemonic (_("_Class"));
287 vbox = gtk_vbox_new(FALSE, 5);
288 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
290 table = gtk_table_new (3, 2, FALSE);
291 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
293 label = gtk_label_new(_("Class name:"));
294 entry = gtk_entry_new();
295 prop_dialog->classname = GTK_ENTRY(entry);
296 gtk_widget_grab_focus(entry);
297 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
298 gtk_table_attach (GTK_TABLE (table), label, 0,1,0,1, GTK_FILL,0, 0,0);
299 gtk_table_attach (GTK_TABLE (table), entry, 1,2,0,1, GTK_FILL | GTK_EXPAND,0, 0,2);
301 label = gtk_label_new(_("Stereotype:"));
302 entry = gtk_entry_new();
303 prop_dialog->stereotype = GTK_ENTRY(entry);
304 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
305 gtk_table_attach (GTK_TABLE (table), label, 0,1,1,2, GTK_FILL,0, 0,0);
306 gtk_table_attach (GTK_TABLE (table), entry, 1,2,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
308 label = gtk_label_new(_("Comment:"));
309 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
310 gtk_table_attach (GTK_TABLE (table), scrolledwindow, 1, 2, 2, 3,
311 (GtkAttachOptions) (GTK_FILL),
312 (GtkAttachOptions) (GTK_FILL), 0, 0);
313 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
314 GTK_SHADOW_IN);
315 entry = gtk_text_view_new ();
316 prop_dialog->comment = GTK_TEXT_VIEW(entry);
317 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (entry), GTK_WRAP_WORD);
319 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
320 gtk_table_attach (GTK_TABLE (table), label, 0,1,2,3, GTK_FILL,0, 0,0);
321 gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
323 hbox = gtk_hbox_new(FALSE, 5);
324 checkbox = gtk_check_button_new_with_label(_("Abstract"));
325 prop_dialog->abstract_class = GTK_TOGGLE_BUTTON( checkbox );
326 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
327 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
329 hbox = gtk_hbox_new(FALSE, 5);
330 checkbox = gtk_check_button_new_with_label(_("Attributes visible"));
331 prop_dialog->attr_vis = GTK_TOGGLE_BUTTON( checkbox );
332 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
333 checkbox = gtk_check_button_new_with_label(_("Suppress Attributes"));
334 prop_dialog->attr_supp = GTK_TOGGLE_BUTTON( checkbox );
335 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
336 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
338 hbox = gtk_hbox_new(FALSE, 5);
339 checkbox = gtk_check_button_new_with_label(_("Operations visible"));
340 prop_dialog->op_vis = GTK_TOGGLE_BUTTON( checkbox );
341 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
342 checkbox = gtk_check_button_new_with_label(_("Suppress operations"));
343 prop_dialog->op_supp = GTK_TOGGLE_BUTTON( checkbox );
344 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
345 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
347 hbox = gtk_hbox_new(TRUE, 5);
348 hbox2 = gtk_hbox_new(FALSE, 5);
349 checkbox = gtk_check_button_new_with_label(_("Wrap Operations"));
350 prop_dialog->op_wrap = GTK_TOGGLE_BUTTON( checkbox );
351 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
352 adj = gtk_adjustment_new( umlclass->wrap_after_char, 0.0, 200.0, 1.0, 5.0, 1.0);
353 prop_dialog->wrap_after_char = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT( adj), 0.1, 0));
354 gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( prop_dialog->wrap_after_char), TRUE);
355 gtk_spin_button_set_snap_to_ticks( GTK_SPIN_BUTTON( prop_dialog->wrap_after_char), TRUE);
356 prop_dialog->max_length_label = GTK_LABEL( gtk_label_new( _("Wrap after this length: ")));
357 gtk_box_pack_start (GTK_BOX (hbox2), GTK_WIDGET( prop_dialog->max_length_label), FALSE, TRUE, 0);
358 gtk_box_pack_start (GTK_BOX (hbox2), GTK_WIDGET( prop_dialog->wrap_after_char), TRUE, TRUE, 0);
359 gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET( hbox2), TRUE, TRUE, 0);
360 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
362 hbox = gtk_hbox_new(TRUE, 5);
363 hbox2 = gtk_hbox_new(FALSE, 5);
364 checkbox = gtk_check_button_new_with_label(_("Comments visible"));
365 prop_dialog->comments_vis = GTK_TOGGLE_BUTTON( checkbox );
366 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
367 adj = gtk_adjustment_new( umlclass->comment_line_length, 17.0, 200.0, 1.0, 5.0, 1.0);
368 prop_dialog->comment_line_length = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT( adj), 0.1, 0));
369 gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( prop_dialog->comment_line_length), TRUE);
370 gtk_spin_button_set_snap_to_ticks( GTK_SPIN_BUTTON( prop_dialog->comment_line_length), TRUE);
371 prop_dialog->Comment_length_label = GTK_LABEL( gtk_label_new( _("Wrap comment after this length: ")));
372 gtk_box_pack_start (GTK_BOX (hbox2), GTK_WIDGET( prop_dialog->Comment_length_label), FALSE, TRUE, 0);
373 gtk_box_pack_start (GTK_BOX (hbox2), GTK_WIDGET( prop_dialog->comment_line_length), TRUE, TRUE, 0);
374 gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET( hbox2), TRUE, TRUE, 0);
375 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
377 hbox = gtk_hbox_new(FALSE, 5);
378 checkbox = gtk_check_button_new_with_label(_("Show documenation tag"));
379 prop_dialog->comment_tagging = GTK_TOGGLE_BUTTON( checkbox );
380 gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
381 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
383 /** Fonts and Colors selection **/
384 gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new(), FALSE, FALSE, 3);
386 table = gtk_table_new (5, 6, TRUE);
387 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
388 gtk_table_set_homogeneous (GTK_TABLE (table), FALSE);
390 /* head line */
391 label = gtk_label_new (_("Kind"));
392 /* L, R, T, B */
393 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
394 label = gtk_label_new (_("Font"));
395 gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
396 label = gtk_label_new (_("Size"));
397 gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 0, 1);
399 /* property rows */
400 create_font_props_row (GTK_TABLE (table), _("Normal"), 1,
401 umlclass->normal_font,
402 umlclass->font_height,
403 &(prop_dialog->normal_font),
404 &(prop_dialog->normal_font_height));
405 create_font_props_row (GTK_TABLE (table), _("Polymorphic"), 2,
406 umlclass->polymorphic_font,
407 umlclass->polymorphic_font_height,
408 &(prop_dialog->polymorphic_font),
409 &(prop_dialog->polymorphic_font_height));
410 create_font_props_row (GTK_TABLE (table), _("Abstract"), 3,
411 umlclass->abstract_font,
412 umlclass->abstract_font_height,
413 &(prop_dialog->abstract_font),
414 &(prop_dialog->abstract_font_height));
415 create_font_props_row (GTK_TABLE (table), _("Class Name"), 4,
416 umlclass->classname_font,
417 umlclass->classname_font_height,
418 &(prop_dialog->classname_font),
419 &(prop_dialog->classname_font_height));
420 create_font_props_row (GTK_TABLE (table), _("Abstract Class"), 5,
421 umlclass->abstract_classname_font,
422 umlclass->abstract_classname_font_height,
423 &(prop_dialog->abstract_classname_font),
424 &(prop_dialog->abstract_classname_font_height));
425 create_font_props_row (GTK_TABLE (table), _("Comment"), 6,
426 umlclass->comment_font,
427 umlclass->comment_font_height,
428 &(prop_dialog->comment_font),
429 &(prop_dialog->comment_font_height));
433 table = gtk_table_new (2, 3, TRUE);
434 gtk_box_pack_start (GTK_BOX (vbox),
435 table, FALSE, TRUE, 0);
436 /* should probably be refactored too. */
437 label = gtk_label_new(_("Text Color"));
438 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
439 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 2);
440 text_color = dia_color_selector_new();
441 dia_color_selector_set_color(text_color, &umlclass->text_color);
442 prop_dialog->text_color = (DiaColorSelector *)text_color;
443 gtk_table_attach (GTK_TABLE (table), text_color, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 3, 2);
445 label = gtk_label_new(_("Foreground Color"));
446 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
447 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 2);
448 line_color = dia_color_selector_new();
449 dia_color_selector_set_color(line_color, &umlclass->line_color);
450 prop_dialog->line_color = (DiaColorSelector *)line_color;
451 gtk_table_attach (GTK_TABLE (table), line_color, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 3, 2);
453 label = gtk_label_new(_("Background Color"));
454 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
455 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 2);
456 fill_color = dia_color_selector_new();
457 dia_color_selector_set_color(fill_color, &umlclass->fill_color);
458 prop_dialog->fill_color = (DiaColorSelector *)fill_color;
459 gtk_table_attach (GTK_TABLE (table), fill_color, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 3, 2);
461 gtk_widget_show_all (vbox);
462 gtk_widget_show (page_label);
463 gtk_notebook_append_page(notebook, vbox, page_label);
468 /************************************************************
469 ******************** ATTRIBUTES ****************************
470 ************************************************************/
472 static void
473 attributes_set_sensitive(UMLClassDialog *prop_dialog, gint val)
475 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_name), val);
476 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_type), val);
477 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_value), val);
478 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_comment), val);
479 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_visible_button), val);
480 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_visible), val);
481 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->attr_class_scope), val);
484 static void
485 attributes_set_values(UMLClassDialog *prop_dialog, UMLAttribute *attr)
487 gtk_entry_set_text(prop_dialog->attr_name, attr->name);
488 gtk_entry_set_text(prop_dialog->attr_type, attr->type);
489 if (attr->value != NULL)
490 gtk_entry_set_text(prop_dialog->attr_value, attr->value);
491 else
492 gtk_entry_set_text(prop_dialog->attr_value, "");
494 if (attr->comment != NULL)
495 set_comment(prop_dialog->attr_comment, attr->comment);
496 else
497 set_comment(prop_dialog->attr_comment, "");
500 gtk_option_menu_set_history(prop_dialog->attr_visible_button,
501 (gint)attr->visibility);
502 gtk_toggle_button_set_active(prop_dialog->attr_class_scope, attr->class_scope);
505 static void
506 attributes_clear_values(UMLClassDialog *prop_dialog)
508 gtk_entry_set_text(prop_dialog->attr_name, "");
509 gtk_entry_set_text(prop_dialog->attr_type, "");
510 gtk_entry_set_text(prop_dialog->attr_value, "");
511 set_comment(prop_dialog->attr_comment, "");
512 gtk_toggle_button_set_active(prop_dialog->attr_class_scope, FALSE);
515 static void
516 attributes_get_values (UMLClassDialog *prop_dialog, UMLAttribute *attr)
518 g_free (attr->name);
519 g_free (attr->type);
520 if (attr->value != NULL)
521 g_free (attr->value);
523 attr->name = g_strdup (gtk_entry_get_text (prop_dialog->attr_name));
524 attr->type = g_strdup (gtk_entry_get_text (prop_dialog->attr_type));
526 attr->value = g_strdup (gtk_entry_get_text(prop_dialog->attr_value));
527 attr->comment = g_strdup (get_comment(prop_dialog->attr_comment));
529 attr->visibility = (UMLVisibility)
530 GPOINTER_TO_INT (gtk_object_get_user_data (
531 GTK_OBJECT (gtk_menu_get_active (prop_dialog->attr_visible))));
533 attr->class_scope = prop_dialog->attr_class_scope->active;
536 static void
537 attributes_get_current_values(UMLClassDialog *prop_dialog)
539 UMLAttribute *current_attr;
540 GtkLabel *label;
541 char *new_str;
543 if (prop_dialog->current_attr != NULL) {
544 current_attr = (UMLAttribute *)
545 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_attr));
546 if (current_attr != NULL) {
547 attributes_get_values(prop_dialog, current_attr);
548 label = GTK_LABEL(GTK_BIN(prop_dialog->current_attr)->child);
549 new_str = uml_get_attribute_string(current_attr);
550 gtk_label_set_text (label, new_str);
551 g_free (new_str);
556 static void
557 attribute_list_item_destroy_callback(GtkWidget *list_item,
558 gpointer data)
560 UMLAttribute *attr;
562 attr = (UMLAttribute *) gtk_object_get_user_data(GTK_OBJECT(list_item));
564 if (attr != NULL) {
565 uml_attribute_destroy(attr);
566 /*printf("Destroying list_item's user_data!\n");*/
570 static void
571 attributes_list_selection_changed_callback(GtkWidget *gtklist,
572 UMLClass *umlclass)
574 GList *list;
575 UMLClassDialog *prop_dialog;
576 GtkObject *list_item;
577 UMLAttribute *attr;
579 /* Due to GtkList oddities, this may get called during destroy.
580 * But it'll reference things that are already dead and crash.
581 * Thus, we stop it before it gets that bad. See bug #156706 for
582 * one example.
584 if (umlclass->destroyed) return;
586 prop_dialog = umlclass->properties_dialog;
588 attributes_get_current_values(prop_dialog);
590 list = GTK_LIST(gtklist)->selection;
591 if (!list) { /* No selected */
592 attributes_set_sensitive(prop_dialog, FALSE);
593 attributes_clear_values(prop_dialog);
594 prop_dialog->current_attr = NULL;
595 return;
598 list_item = GTK_OBJECT(list->data);
599 attr = (UMLAttribute *)gtk_object_get_user_data(list_item);
600 attributes_set_values(prop_dialog, attr);
601 attributes_set_sensitive(prop_dialog, TRUE);
603 prop_dialog->current_attr = GTK_LIST_ITEM(list_item);
604 gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->attr_name));
607 static void
608 attributes_list_new_callback(GtkWidget *button,
609 UMLClass *umlclass)
611 GList *list;
612 UMLClassDialog *prop_dialog;
613 GtkWidget *list_item;
614 UMLAttribute *attr;
615 char *utfstr;
616 prop_dialog = umlclass->properties_dialog;
618 attributes_get_current_values(prop_dialog);
620 attr = uml_attribute_new();
621 /* need to make the new ConnectionPoint valid and remember them */
622 uml_attribute_ensure_connection_points (attr, &umlclass->element.object);
623 prop_dialog->added_connections =
624 g_list_prepend(prop_dialog->added_connections, attr->left_connection);
625 prop_dialog->added_connections =
626 g_list_prepend(prop_dialog->added_connections, attr->right_connection);
628 utfstr = uml_get_attribute_string (attr);
629 list_item = gtk_list_item_new_with_label (utfstr);
630 gtk_widget_show (list_item);
631 g_free (utfstr);
633 gtk_object_set_user_data(GTK_OBJECT(list_item), attr);
634 gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
635 GTK_SIGNAL_FUNC (attribute_list_item_destroy_callback),
636 NULL);
638 list = g_list_append(NULL, list_item);
639 gtk_list_append_items(prop_dialog->attributes_list, list);
641 if (prop_dialog->attributes_list->children != NULL)
642 gtk_list_unselect_child(prop_dialog->attributes_list,
643 GTK_WIDGET(prop_dialog->attributes_list->children->data));
644 gtk_list_select_child(prop_dialog->attributes_list, list_item);
647 static void
648 attributes_list_delete_callback(GtkWidget *button,
649 UMLClass *umlclass)
651 GList *list;
652 UMLClassDialog *prop_dialog;
653 GtkList *gtklist;
654 UMLAttribute *attr;
656 prop_dialog = umlclass->properties_dialog;
657 gtklist = GTK_LIST(prop_dialog->attributes_list);
659 if (gtklist->selection != NULL) {
660 attr = (UMLAttribute *)
661 gtk_object_get_user_data(GTK_OBJECT(gtklist->selection->data));
663 if (attr->left_connection != NULL) {
664 prop_dialog->deleted_connections =
665 g_list_prepend(prop_dialog->deleted_connections,
666 attr->left_connection);
667 prop_dialog->deleted_connections =
668 g_list_prepend(prop_dialog->deleted_connections,
669 attr->right_connection);
672 list = g_list_prepend(NULL, gtklist->selection->data);
673 gtk_list_remove_items(gtklist, list);
674 g_list_free(list);
675 attributes_clear_values(prop_dialog);
676 attributes_set_sensitive(prop_dialog, FALSE);
680 static void
681 attributes_list_move_up_callback(GtkWidget *button,
682 UMLClass *umlclass)
684 GList *list;
685 UMLClassDialog *prop_dialog;
686 GtkList *gtklist;
687 GtkWidget *list_item;
688 int i;
690 prop_dialog = umlclass->properties_dialog;
691 gtklist = GTK_LIST(prop_dialog->attributes_list);
693 if (gtklist->selection != NULL) {
694 list_item = GTK_WIDGET(gtklist->selection->data);
696 i = gtk_list_child_position(gtklist, list_item);
697 if (i>0)
698 i--;
700 gtk_widget_ref(list_item);
701 list = g_list_prepend(NULL, list_item);
702 gtk_list_remove_items(gtklist, list);
703 gtk_list_insert_items(gtklist, list, i);
704 gtk_widget_unref(list_item);
706 gtk_list_select_child(gtklist, list_item);
710 static void
711 attributes_list_move_down_callback(GtkWidget *button,
712 UMLClass *umlclass)
714 GList *list;
715 UMLClassDialog *prop_dialog;
716 GtkList *gtklist;
717 GtkWidget *list_item;
718 int i;
720 prop_dialog = umlclass->properties_dialog;
721 gtklist = GTK_LIST(prop_dialog->attributes_list);
723 if (gtklist->selection != NULL) {
724 list_item = GTK_WIDGET(gtklist->selection->data);
726 i = gtk_list_child_position(gtklist, list_item);
727 if (i<(g_list_length(gtklist->children)-1))
728 i++;
731 gtk_widget_ref(list_item);
732 list = g_list_prepend(NULL, list_item);
733 gtk_list_remove_items(gtklist, list);
734 gtk_list_insert_items(gtklist, list, i);
735 gtk_widget_unref(list_item);
737 gtk_list_select_child(gtklist, list_item);
741 static void
742 attributes_read_from_dialog(UMLClass *umlclass,
743 UMLClassDialog *prop_dialog,
744 int connection_index)
746 GList *list;
747 UMLAttribute *attr;
748 GtkWidget *list_item;
749 GList *clear_list;
750 DiaObject *obj;
752 obj = &umlclass->element.object;
754 /* if the currently select attribute is changed, update the state in the
755 * dialog info from widgets */
756 attributes_get_current_values(prop_dialog);
757 /* Free current attributes: */
758 list = umlclass->attributes;
759 while (list != NULL) {
760 attr = (UMLAttribute *)list->data;
761 uml_attribute_destroy(attr);
762 list = g_list_next(list);
764 g_list_free (umlclass->attributes);
765 umlclass->attributes = NULL;
767 /* Insert new attributes and remove them from gtklist: */
768 list = GTK_LIST (prop_dialog->attributes_list)->children;
769 clear_list = NULL;
770 while (list != NULL) {
771 list_item = GTK_WIDGET(list->data);
773 clear_list = g_list_prepend (clear_list, list_item);
774 attr = (UMLAttribute *)
775 gtk_object_get_user_data(GTK_OBJECT(list_item));
776 gtk_object_set_user_data(GTK_OBJECT(list_item), NULL);
777 umlclass->attributes = g_list_append(umlclass->attributes, attr);
779 if (attr->left_connection == NULL) {
780 uml_attribute_ensure_connection_points (attr, obj);
782 prop_dialog->added_connections =
783 g_list_prepend(prop_dialog->added_connections,
784 attr->left_connection);
785 prop_dialog->added_connections =
786 g_list_prepend(prop_dialog->added_connections,
787 attr->right_connection);
790 if ( (prop_dialog->attr_vis->active) &&
791 (!prop_dialog->attr_supp->active) ) {
792 obj->connections[connection_index] = attr->left_connection;
793 connection_index++;
794 obj->connections[connection_index] = attr->right_connection;
795 connection_index++;
796 } else {
797 umlclass_store_disconnects(prop_dialog, attr->left_connection);
798 object_remove_connections_to(attr->left_connection);
799 umlclass_store_disconnects(prop_dialog, attr->right_connection);
800 object_remove_connections_to(attr->right_connection);
803 list = g_list_next(list);
805 clear_list = g_list_reverse (clear_list);
806 gtk_list_remove_items (GTK_LIST (prop_dialog->attributes_list), clear_list);
807 g_list_free (clear_list);
809 #if 0 /* UMLClass is *known* to be in an incositent state here, check later or crash ... */
810 umlclass_sanity_check(umlclass, "Read from dialog");
811 #endif
814 static void
815 attributes_fill_in_dialog(UMLClass *umlclass)
817 UMLClassDialog *prop_dialog;
818 UMLAttribute *attr_copy;
819 GtkWidget *list_item;
820 GList *list;
821 int i;
823 umlclass_sanity_check(umlclass, "Filling in dialog");
825 prop_dialog = umlclass->properties_dialog;
827 /* copy in new attributes: */
828 if (prop_dialog->attributes_list->children == NULL) {
829 i = 0;
830 list = umlclass->attributes;
831 while (list != NULL) {
832 UMLAttribute *attr = (UMLAttribute *)list->data;
833 gchar *attrstr = uml_get_attribute_string(attr);
835 list_item = gtk_list_item_new_with_label (attrstr);
836 attr_copy = uml_attribute_copy(attr);
837 /* looks wrong but required for complicated ConnectionPoint memory management */
838 attr_copy->left_connection = attr->left_connection;
839 attr_copy->right_connection = attr->right_connection;
840 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer) attr_copy);
841 gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
842 GTK_SIGNAL_FUNC (attribute_list_item_destroy_callback),
843 NULL);
844 gtk_container_add (GTK_CONTAINER (prop_dialog->attributes_list), list_item);
845 gtk_widget_show (list_item);
847 list = g_list_next(list); i++;
848 g_free (attrstr);
850 /* set attributes non-sensitive */
851 prop_dialog->current_attr = NULL;
852 attributes_set_sensitive(prop_dialog, FALSE);
853 attributes_clear_values(prop_dialog);
857 static void
858 attributes_update(GtkWidget *widget, UMLClass *umlclass)
860 attributes_get_current_values(umlclass->properties_dialog);
863 static int
864 attributes_update_event(GtkWidget *widget, GdkEventFocus *ev, UMLClass *umlclass)
866 attributes_get_current_values(umlclass->properties_dialog);
867 return 0;
870 static void
871 attributes_create_page(GtkNotebook *notebook, UMLClass *umlclass)
873 UMLClassDialog *prop_dialog;
874 GtkWidget *page_label;
875 GtkWidget *label;
876 GtkWidget *hbox;
877 GtkWidget *vbox;
878 GtkWidget *vbox2;
879 GtkWidget *hbox2;
880 GtkWidget *table;
881 GtkWidget *entry;
882 GtkWidget *checkbox;
883 GtkWidget *scrolled_win;
884 GtkWidget *button;
885 GtkWidget *list;
886 GtkWidget *frame;
887 GtkWidget *omenu;
888 GtkWidget *menu;
889 GtkWidget *submenu;
890 GtkWidget *menuitem;
891 GtkWidget *scrolledwindow;
892 GSList *group;
894 prop_dialog = umlclass->properties_dialog;
896 /* Attributes page: */
897 page_label = gtk_label_new_with_mnemonic (_("_Attributes"));
899 vbox = gtk_vbox_new(FALSE, 5);
900 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
902 hbox = gtk_hbox_new(FALSE, 5);
904 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
905 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
906 GTK_POLICY_AUTOMATIC,
907 GTK_POLICY_AUTOMATIC);
908 gtk_box_pack_start (GTK_BOX (hbox), scrolled_win, TRUE, TRUE, 0);
909 gtk_widget_show (scrolled_win);
911 list = gtk_list_new ();
912 prop_dialog->attributes_list = GTK_LIST(list);
913 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
914 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
915 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
916 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
917 gtk_widget_show (list);
919 gtk_signal_connect (GTK_OBJECT (list), "selection_changed",
920 GTK_SIGNAL_FUNC(attributes_list_selection_changed_callback),
921 umlclass);
923 vbox2 = gtk_vbox_new(FALSE, 5);
925 button = gtk_button_new_with_mnemonic (_("_New"));
926 gtk_signal_connect (GTK_OBJECT (button), "clicked",
927 GTK_SIGNAL_FUNC(attributes_list_new_callback),
928 umlclass);
929 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
930 gtk_widget_show (button);
931 button = gtk_button_new_with_mnemonic (_("_Delete"));
932 gtk_signal_connect (GTK_OBJECT (button), "clicked",
933 GTK_SIGNAL_FUNC(attributes_list_delete_callback),
934 umlclass);
935 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
936 gtk_widget_show (button);
937 button = gtk_button_new_with_label (_("Move up"));
938 gtk_signal_connect (GTK_OBJECT (button), "clicked",
939 GTK_SIGNAL_FUNC(attributes_list_move_up_callback),
940 umlclass);
941 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
942 gtk_widget_show (button);
943 button = gtk_button_new_with_label (_("Move down"));
944 gtk_signal_connect (GTK_OBJECT (button), "clicked",
945 GTK_SIGNAL_FUNC(attributes_list_move_down_callback),
946 umlclass);
947 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
948 gtk_widget_show (button);
950 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
952 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
954 frame = gtk_frame_new(_("Attribute data"));
955 vbox2 = gtk_vbox_new(FALSE, 5);
956 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 10);
957 gtk_container_add (GTK_CONTAINER (frame), vbox2);
958 gtk_widget_show(frame);
959 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
961 table = gtk_table_new (5, 2, FALSE);
962 gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
964 label = gtk_label_new(_("Name:"));
965 entry = gtk_entry_new();
966 prop_dialog->attr_name = GTK_ENTRY(entry);
967 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
968 GTK_SIGNAL_FUNC (attributes_update_event), umlclass);
969 gtk_signal_connect (GTK_OBJECT (entry), "activate",
970 GTK_SIGNAL_FUNC (attributes_update), umlclass);
971 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
972 gtk_table_attach (GTK_TABLE (table), label, 0,1,0,1, GTK_FILL,0, 0,0);
973 gtk_table_attach (GTK_TABLE (table), entry, 1,2,0,1, GTK_FILL | GTK_EXPAND,0, 0,2);
975 label = gtk_label_new(_("Type:"));
976 entry = gtk_entry_new();
977 prop_dialog->attr_type = GTK_ENTRY(entry);
978 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
979 GTK_SIGNAL_FUNC (attributes_update_event), umlclass);
980 gtk_signal_connect (GTK_OBJECT (entry), "activate",
981 GTK_SIGNAL_FUNC (attributes_update), umlclass);
982 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
983 gtk_table_attach (GTK_TABLE (table), label, 0,1,1,2, GTK_FILL,0, 0,0);
984 gtk_table_attach (GTK_TABLE (table), entry, 1,2,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
986 label = gtk_label_new(_("Value:"));
987 entry = gtk_entry_new();
988 prop_dialog->attr_value = GTK_ENTRY(entry);
989 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
990 GTK_SIGNAL_FUNC (attributes_update_event), umlclass);
991 gtk_signal_connect (GTK_OBJECT (entry), "activate",
992 GTK_SIGNAL_FUNC (attributes_update), umlclass);
993 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
994 gtk_table_attach (GTK_TABLE (table), label, 0,1,2,3, GTK_FILL,0, 0,0);
995 gtk_table_attach (GTK_TABLE (table), entry, 1,2,2,3, GTK_FILL | GTK_EXPAND,0, 0,2);
997 label = gtk_label_new(_("Comment:"));
998 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
999 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
1000 GTK_SHADOW_IN);
1001 entry = gtk_text_view_new ();
1002 prop_dialog->attr_comment = GTK_TEXT_VIEW(entry);
1003 gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
1004 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (entry), GTK_WRAP_WORD);
1005 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (entry),TRUE);
1006 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
1007 GTK_SIGNAL_FUNC (attributes_update_event), umlclass);
1008 #if 0 /* while the GtkEntry has a "activate" signal, GtkTextView does not.
1009 * Maybe we should connect to "set-focus-child" instead?
1011 gtk_signal_connect (GTK_OBJECT (entry), "activate",
1012 GTK_SIGNAL_FUNC (attributes_update), umlclass);
1013 #endif
1014 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1015 gtk_table_attach (GTK_TABLE (table), label, 0,1,3,4, GTK_FILL,0, 0,0);
1016 gtk_table_attach (GTK_TABLE (table), scrolledwindow, 1,2,3,4, GTK_FILL | GTK_EXPAND,0, 0,2);
1019 label = gtk_label_new(_("Visibility:"));
1021 omenu = gtk_option_menu_new ();
1022 menu = gtk_menu_new ();
1023 prop_dialog->attr_visible = GTK_MENU(menu);
1024 prop_dialog->attr_visible_button = GTK_OPTION_MENU(omenu);
1025 submenu = NULL;
1026 group = NULL;
1028 menuitem = gtk_radio_menu_item_new_with_label (group, _("Public"));
1029 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1030 GTK_SIGNAL_FUNC (attributes_update), umlclass);
1031 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1032 GINT_TO_POINTER(UML_PUBLIC) );
1033 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1034 gtk_menu_append (GTK_MENU (menu), menuitem);
1035 gtk_widget_show (menuitem);
1036 menuitem = gtk_radio_menu_item_new_with_label (group, _("Private"));
1037 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1038 GTK_SIGNAL_FUNC (attributes_update), umlclass);
1039 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1040 GINT_TO_POINTER(UML_PRIVATE) );
1041 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1042 gtk_menu_append (GTK_MENU (menu), menuitem);
1043 gtk_widget_show (menuitem);
1044 menuitem = gtk_radio_menu_item_new_with_label (group, _("Protected"));
1045 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1046 GTK_SIGNAL_FUNC (attributes_update), umlclass);
1047 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1048 GINT_TO_POINTER(UML_PROTECTED) );
1049 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1050 gtk_menu_append (GTK_MENU (menu), menuitem);
1051 gtk_widget_show (menuitem);
1052 menuitem = gtk_radio_menu_item_new_with_label (group, _("Implementation"));
1053 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1054 GTK_SIGNAL_FUNC (attributes_update), umlclass);
1055 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1056 GINT_TO_POINTER(UML_IMPLEMENTATION) );
1057 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1058 gtk_menu_append (GTK_MENU (menu), menuitem);
1059 gtk_widget_show (menuitem);
1061 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
1064 GtkWidget * align;
1065 align = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
1066 gtk_container_add(GTK_CONTAINER(align), omenu);
1067 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1068 gtk_table_attach (GTK_TABLE (table), label, 0,1,4,5, GTK_FILL,0, 0,3);
1069 gtk_table_attach (GTK_TABLE (table), align, 1,2,4,5, GTK_FILL,0, 0,3);
1072 hbox2 = gtk_hbox_new(FALSE, 5);
1073 checkbox = gtk_check_button_new_with_label(_("Class scope"));
1074 prop_dialog->attr_class_scope = GTK_TOGGLE_BUTTON(checkbox);
1075 gtk_box_pack_start (GTK_BOX (hbox2), checkbox, TRUE, TRUE, 0);
1076 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, TRUE, 0);
1078 gtk_widget_show(vbox2);
1080 gtk_widget_show_all (vbox);
1081 gtk_widget_show (page_label);
1082 gtk_notebook_append_page(notebook, vbox, page_label);
1086 /*************************************************************
1087 ******************** OPERATIONS *****************************
1088 *************************************************************/
1090 /* Forward declaration: */
1091 static void operations_get_current_values(UMLClassDialog *prop_dialog);
1093 static void
1094 parameters_set_sensitive(UMLClassDialog *prop_dialog, gint val)
1096 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_name), val);
1097 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_type), val);
1098 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_value), val);
1099 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_comment), val);
1100 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_kind), val);
1101 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->param_kind_button), val);
1104 static void
1105 parameters_set_values(UMLClassDialog *prop_dialog, UMLParameter *param)
1107 gtk_entry_set_text(prop_dialog->param_name, param->name);
1108 gtk_entry_set_text(prop_dialog->param_type, param->type);
1109 if (param->value != NULL)
1110 gtk_entry_set_text(prop_dialog->param_value, param->value);
1111 else
1112 gtk_entry_set_text(prop_dialog->param_value, "");
1113 if (param->comment != NULL)
1114 set_comment(prop_dialog->param_comment, param->comment);
1115 else
1116 set_comment(prop_dialog->param_comment, "");
1118 gtk_option_menu_set_history(prop_dialog->param_kind_button,
1119 (gint)param->kind);
1122 static void
1123 parameters_clear_values(UMLClassDialog *prop_dialog)
1125 gtk_entry_set_text(prop_dialog->param_name, "");
1126 gtk_entry_set_text(prop_dialog->param_type, "");
1127 gtk_entry_set_text(prop_dialog->param_value, "");
1128 set_comment(prop_dialog->param_comment, "");
1129 gtk_option_menu_set_history(prop_dialog->param_kind_button,
1130 (gint) UML_UNDEF_KIND);
1134 static void
1135 parameters_get_values (UMLClassDialog *prop_dialog, UMLParameter *param)
1137 g_free(param->name);
1138 g_free(param->type);
1139 g_free(param->comment);
1140 if (param->value != NULL)
1141 g_free(param->value);
1143 param->name = g_strdup (gtk_entry_get_text (prop_dialog->param_name));
1144 param->type = g_strdup (gtk_entry_get_text (prop_dialog->param_type));
1146 param->value = g_strdup (gtk_entry_get_text(prop_dialog->param_value));
1147 param->comment = g_strdup (get_comment(prop_dialog->param_comment));
1149 param->kind = (UMLParameterKind) GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(gtk_menu_get_active(prop_dialog->param_kind))));
1152 static void
1153 parameters_get_current_values(UMLClassDialog *prop_dialog)
1155 UMLParameter *current_param;
1156 GtkLabel *label;
1157 char *new_str;
1159 if (prop_dialog->current_param != NULL) {
1160 current_param = (UMLParameter *)
1161 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_param));
1162 if (current_param != NULL) {
1163 parameters_get_values(prop_dialog, current_param);
1164 label = GTK_LABEL(GTK_BIN(prop_dialog->current_param)->child);
1165 new_str = uml_get_parameter_string(current_param);
1166 gtk_label_set_text(label, new_str);
1167 g_free(new_str);
1173 static void
1174 parameters_list_selection_changed_callback(GtkWidget *gtklist,
1175 UMLClass *umlclass)
1177 GList *list;
1178 UMLClassDialog *prop_dialog;
1179 GtkObject *list_item;
1180 UMLParameter *param;
1182 prop_dialog = umlclass->properties_dialog;
1184 parameters_get_current_values(prop_dialog);
1186 list = GTK_LIST(gtklist)->selection;
1187 if (!list) { /* No selected */
1188 parameters_set_sensitive(prop_dialog, FALSE);
1189 parameters_clear_values(prop_dialog);
1190 prop_dialog->current_param = NULL;
1191 return;
1194 list_item = GTK_OBJECT(list->data);
1195 param = (UMLParameter *)gtk_object_get_user_data(list_item);
1196 parameters_set_values(prop_dialog, param);
1197 parameters_set_sensitive(prop_dialog, TRUE);
1199 prop_dialog->current_param = GTK_LIST_ITEM(list_item);
1200 gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->param_name));
1203 static void
1204 parameters_list_new_callback(GtkWidget *button,
1205 UMLClass *umlclass)
1207 GList *list;
1208 UMLClassDialog *prop_dialog;
1209 GtkWidget *list_item;
1210 UMLOperation *current_op;
1211 UMLParameter *param;
1212 char *utf;
1214 prop_dialog = umlclass->properties_dialog;
1216 parameters_get_current_values(prop_dialog);
1218 current_op = (UMLOperation *)
1219 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_op));
1221 param = uml_parameter_new();
1223 utf = uml_get_parameter_string (param);
1224 list_item = gtk_list_item_new_with_label (utf);
1225 gtk_widget_show (list_item);
1226 g_free (utf);
1228 gtk_object_set_user_data(GTK_OBJECT(list_item), param);
1230 current_op->parameters = g_list_append(current_op->parameters,
1231 (gpointer) param);
1233 list = g_list_append(NULL, list_item);
1234 gtk_list_append_items(prop_dialog->parameters_list, list);
1236 if (prop_dialog->parameters_list->children != NULL)
1237 gtk_list_unselect_child(prop_dialog->parameters_list,
1238 GTK_WIDGET(prop_dialog->parameters_list->children->data));
1239 gtk_list_select_child(prop_dialog->parameters_list, list_item);
1241 prop_dialog->current_param = GTK_LIST_ITEM(list_item);
1244 static void
1245 parameters_list_delete_callback(GtkWidget *button,
1246 UMLClass *umlclass)
1248 GList *list;
1249 UMLClassDialog *prop_dialog;
1250 GtkList *gtklist;
1251 UMLOperation *current_op;
1252 UMLParameter *param;
1254 prop_dialog = umlclass->properties_dialog;
1255 gtklist = GTK_LIST(prop_dialog->parameters_list);
1258 if (gtklist->selection != NULL) {
1259 /* Remove from current operations parameter list: */
1260 current_op = (UMLOperation *)
1261 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_op));
1262 param = (UMLParameter *)
1263 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_param));
1265 current_op->parameters = g_list_remove(current_op->parameters,
1266 (gpointer) param);
1267 uml_parameter_destroy(param);
1269 /* Remove from gtk list: */
1270 list = g_list_prepend(NULL, prop_dialog->current_param);
1272 prop_dialog->current_param = NULL;
1274 gtk_list_remove_items(gtklist, list);
1275 g_list_free(list);
1279 static void
1280 parameters_list_move_up_callback(GtkWidget *button,
1281 UMLClass *umlclass)
1283 GList *list;
1284 UMLClassDialog *prop_dialog;
1285 GtkList *gtklist;
1286 GtkWidget *list_item;
1287 UMLOperation *current_op;
1288 UMLParameter *param;
1289 int i;
1291 prop_dialog = umlclass->properties_dialog;
1292 gtklist = GTK_LIST(prop_dialog->parameters_list);
1294 if (gtklist->selection != NULL) {
1295 list_item = GTK_WIDGET(gtklist->selection->data);
1297 i = gtk_list_child_position(gtklist, list_item);
1298 if (i>0)
1299 i--;
1301 param = (UMLParameter *) gtk_object_get_user_data(GTK_OBJECT(list_item));
1303 /* Move parameter in current operations list: */
1304 current_op = (UMLOperation *)
1305 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_op));
1307 current_op->parameters = g_list_remove(current_op->parameters,
1308 (gpointer) param);
1309 current_op->parameters = g_list_insert(current_op->parameters,
1310 (gpointer) param,
1313 /* Move parameter in gtk list: */
1314 gtk_widget_ref(list_item);
1315 list = g_list_prepend(NULL, list_item);
1316 gtk_list_remove_items(gtklist, list);
1317 gtk_list_insert_items(gtklist, list, i);
1318 gtk_widget_unref(list_item);
1320 gtk_list_select_child(gtklist, list_item);
1322 operations_get_current_values(prop_dialog);
1326 static void
1327 parameters_list_move_down_callback(GtkWidget *button,
1328 UMLClass *umlclass)
1330 GList *list;
1331 UMLClassDialog *prop_dialog;
1332 GtkList *gtklist;
1333 GtkWidget *list_item;
1334 UMLOperation *current_op;
1335 UMLParameter *param;
1336 int i;
1338 prop_dialog = umlclass->properties_dialog;
1339 gtklist = GTK_LIST(prop_dialog->parameters_list);
1341 if (gtklist->selection != NULL) {
1342 list_item = GTK_WIDGET(gtklist->selection->data);
1344 i = gtk_list_child_position(gtklist, list_item);
1345 if (i<(g_list_length(gtklist->children)-1))
1346 i++;
1348 param = (UMLParameter *) gtk_object_get_user_data(GTK_OBJECT(list_item));
1350 /* Move parameter in current operations list: */
1351 current_op = (UMLOperation *)
1352 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_op));
1354 current_op->parameters = g_list_remove(current_op->parameters,
1355 (gpointer) param);
1356 current_op->parameters = g_list_insert(current_op->parameters,
1357 (gpointer) param,
1360 /* Move parameter in gtk list: */
1361 gtk_widget_ref(list_item);
1362 list = g_list_prepend(NULL, list_item);
1363 gtk_list_remove_items(gtklist, list);
1364 gtk_list_insert_items(gtklist, list, i);
1365 gtk_widget_unref(list_item);
1367 gtk_list_select_child(gtklist, list_item);
1369 operations_get_current_values(prop_dialog);
1373 static void
1374 operations_set_sensitive(UMLClassDialog *prop_dialog, gint val)
1376 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_name), val);
1377 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_type), val);
1378 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_stereotype), val);
1379 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_comment), val);
1380 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_visible_button), val);
1381 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_visible), val);
1382 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_class_scope), val);
1383 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_inheritance_type), val);
1384 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_inheritance_type_button), val);
1385 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->op_query), val);
1387 gtk_widget_set_sensitive(prop_dialog->param_new_button, val);
1388 gtk_widget_set_sensitive(prop_dialog->param_delete_button, val);
1389 gtk_widget_set_sensitive(prop_dialog->param_down_button, val);
1390 gtk_widget_set_sensitive(prop_dialog->param_up_button, val);
1393 static void
1394 operations_set_values(UMLClassDialog *prop_dialog, UMLOperation *op)
1396 GList *list;
1397 UMLParameter *param;
1398 GtkWidget *list_item;
1399 gchar *str;
1401 gtk_entry_set_text(prop_dialog->op_name, op->name);
1402 if (op->type != NULL)
1403 gtk_entry_set_text(prop_dialog->op_type, op->type);
1404 else
1405 gtk_entry_set_text(prop_dialog->op_type, "");
1407 if (op->stereotype != NULL)
1408 gtk_entry_set_text(prop_dialog->op_stereotype, op->stereotype);
1409 else
1410 gtk_entry_set_text(prop_dialog->op_stereotype, "");
1412 if (op->comment != NULL)
1413 set_comment(prop_dialog->op_comment, op->comment);
1414 else
1415 set_comment(prop_dialog->op_comment, "");
1417 gtk_option_menu_set_history(prop_dialog->op_visible_button,
1418 (gint)op->visibility);
1419 gtk_toggle_button_set_active(prop_dialog->op_class_scope, op->class_scope);
1420 gtk_toggle_button_set_active(prop_dialog->op_query, op->query);
1421 gtk_option_menu_set_history(prop_dialog->op_inheritance_type_button,
1422 (gint)op->inheritance_type);
1424 gtk_list_clear_items(prop_dialog->parameters_list, 0, -1);
1425 prop_dialog->current_param = NULL;
1426 parameters_set_sensitive(prop_dialog, FALSE);
1428 list = op->parameters;
1429 while (list != NULL) {
1430 param = (UMLParameter *)list->data;
1432 str = uml_get_parameter_string (param);
1433 list_item = gtk_list_item_new_with_label (str);
1434 g_free (str);
1436 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer) param);
1437 gtk_container_add (GTK_CONTAINER (prop_dialog->parameters_list), list_item);
1438 gtk_widget_show (list_item);
1440 list = g_list_next(list);
1444 static void
1445 operations_clear_values(UMLClassDialog *prop_dialog)
1447 gtk_entry_set_text(prop_dialog->op_name, "");
1448 gtk_entry_set_text(prop_dialog->op_type, "");
1449 gtk_entry_set_text(prop_dialog->op_stereotype, "");
1450 set_comment(prop_dialog->op_comment, "");
1451 gtk_toggle_button_set_active(prop_dialog->op_class_scope, FALSE);
1452 gtk_toggle_button_set_active(prop_dialog->op_query, FALSE);
1454 gtk_list_clear_items(prop_dialog->parameters_list, 0, -1);
1455 prop_dialog->current_param = NULL;
1456 parameters_set_sensitive(prop_dialog, FALSE);
1460 static void
1461 operations_get_values(UMLClassDialog *prop_dialog, UMLOperation *op)
1463 const gchar *s;
1465 g_free(op->name);
1466 if (op->type != NULL)
1467 g_free(op->type);
1469 op->name = g_strdup(gtk_entry_get_text(prop_dialog->op_name));
1470 op->type = g_strdup (gtk_entry_get_text(prop_dialog->op_type));
1471 op->comment = g_strdup(get_comment(prop_dialog->op_comment));
1473 s = gtk_entry_get_text(prop_dialog->op_stereotype);
1474 if (s && s[0])
1475 op->stereotype = g_strdup (s);
1476 else
1477 op->stereotype = NULL;
1479 op->visibility = (UMLVisibility)
1480 GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(gtk_menu_get_active(prop_dialog->op_visible))));
1482 op->class_scope = prop_dialog->op_class_scope->active;
1483 op->inheritance_type = (UMLInheritanceType)
1484 GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(gtk_menu_get_active(prop_dialog->op_inheritance_type))));
1486 op->query = prop_dialog->op_query->active;
1490 static void
1491 operations_get_current_values(UMLClassDialog *prop_dialog)
1493 UMLOperation *current_op;
1494 GtkLabel *label;
1495 char *new_str;
1497 parameters_get_current_values(prop_dialog);
1499 if (prop_dialog->current_op != NULL) {
1500 current_op = (UMLOperation *)
1501 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_op));
1502 if (current_op != NULL) {
1503 operations_get_values(prop_dialog, current_op);
1504 label = GTK_LABEL(GTK_BIN(prop_dialog->current_op)->child);
1505 new_str = uml_get_operation_string(current_op);
1506 gtk_label_set_text (label, new_str);
1507 g_free (new_str);
1512 static void
1513 operations_list_item_destroy_callback(GtkWidget *list_item,
1514 gpointer data)
1516 UMLOperation *op;
1518 op = (UMLOperation *) gtk_object_get_user_data(GTK_OBJECT(list_item));
1520 if (op != NULL) {
1521 uml_operation_destroy(op);
1522 /*printf("Destroying operation list_item's user_data!\n");*/
1526 static void
1527 operations_list_selection_changed_callback(GtkWidget *gtklist,
1528 UMLClass *umlclass)
1530 GList *list;
1531 UMLClassDialog *prop_dialog;
1532 GtkObject *list_item;
1533 UMLOperation *op;
1535 prop_dialog = umlclass->properties_dialog;
1537 if (!prop_dialog)
1538 return; /* maybe hiding a bug elsewhere */
1540 operations_get_current_values(prop_dialog);
1542 list = GTK_LIST(gtklist)->selection;
1543 if (!list) { /* No selected */
1544 operations_set_sensitive(prop_dialog, FALSE);
1545 operations_clear_values(prop_dialog);
1546 prop_dialog->current_op = NULL;
1547 return;
1550 list_item = GTK_OBJECT(list->data);
1551 op = (UMLOperation *)gtk_object_get_user_data(list_item);
1552 operations_set_values(prop_dialog, op);
1553 operations_set_sensitive(prop_dialog, TRUE);
1555 prop_dialog->current_op = GTK_LIST_ITEM(list_item);
1556 gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->op_name));
1559 static void
1560 operations_list_new_callback(GtkWidget *button,
1561 UMLClass *umlclass)
1563 GList *list;
1564 UMLClassDialog *prop_dialog;
1565 GtkWidget *list_item;
1566 UMLOperation *op;
1567 char *utfstr;
1569 prop_dialog = umlclass->properties_dialog;
1571 operations_get_current_values(prop_dialog);
1573 op = uml_operation_new();
1574 /* need to make new ConnectionPoints valid and remember them */
1575 uml_operation_ensure_connection_points (op, &umlclass->element.object);
1576 prop_dialog->added_connections =
1577 g_list_prepend(prop_dialog->added_connections, op->left_connection);
1578 prop_dialog->added_connections =
1579 g_list_prepend(prop_dialog->added_connections, op->right_connection);
1582 utfstr = uml_get_operation_string (op);
1583 list_item = gtk_list_item_new_with_label (utfstr);
1584 gtk_widget_show (list_item);
1585 g_free (utfstr);
1587 gtk_object_set_user_data(GTK_OBJECT(list_item), op);
1588 gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
1589 GTK_SIGNAL_FUNC (operations_list_item_destroy_callback),
1590 NULL);
1592 list = g_list_append(NULL, list_item);
1593 gtk_list_append_items(prop_dialog->operations_list, list);
1595 if (prop_dialog->operations_list->children != NULL)
1596 gtk_list_unselect_child(prop_dialog->operations_list,
1597 GTK_WIDGET(prop_dialog->operations_list->children->data));
1598 gtk_list_select_child(prop_dialog->operations_list, list_item);
1601 static void
1602 operations_list_delete_callback(GtkWidget *button,
1603 UMLClass *umlclass)
1605 GList *list;
1606 UMLClassDialog *prop_dialog;
1607 GtkList *gtklist;
1608 UMLOperation *op;
1611 prop_dialog = umlclass->properties_dialog;
1612 gtklist = GTK_LIST(prop_dialog->operations_list);
1614 if (gtklist->selection != NULL) {
1615 op = (UMLOperation *)
1616 gtk_object_get_user_data(GTK_OBJECT(gtklist->selection->data));
1618 if (op->left_connection != NULL) {
1619 prop_dialog->deleted_connections =
1620 g_list_prepend(prop_dialog->deleted_connections,
1621 op->left_connection);
1622 prop_dialog->deleted_connections =
1623 g_list_prepend(prop_dialog->deleted_connections,
1624 op->right_connection);
1627 list = g_list_prepend(NULL, gtklist->selection->data);
1628 gtk_list_remove_items(gtklist, list);
1629 g_list_free(list);
1630 operations_clear_values(prop_dialog);
1631 operations_set_sensitive(prop_dialog, FALSE);
1635 static void
1636 operations_list_move_up_callback(GtkWidget *button,
1637 UMLClass *umlclass)
1639 GList *list;
1640 UMLClassDialog *prop_dialog;
1641 GtkList *gtklist;
1642 GtkWidget *list_item;
1643 int i;
1645 prop_dialog = umlclass->properties_dialog;
1646 gtklist = GTK_LIST(prop_dialog->operations_list);
1648 if (gtklist->selection != NULL) {
1649 list_item = GTK_WIDGET(gtklist->selection->data);
1651 i = gtk_list_child_position(gtklist, list_item);
1652 if (i>0)
1653 i--;
1655 gtk_widget_ref(list_item);
1656 list = g_list_prepend(NULL, list_item);
1657 gtk_list_remove_items(gtklist, list);
1658 gtk_list_insert_items(gtklist, list, i);
1659 gtk_widget_unref(list_item);
1661 gtk_list_select_child(gtklist, list_item);
1666 static void
1667 operations_list_move_down_callback(GtkWidget *button,
1668 UMLClass *umlclass)
1670 GList *list;
1671 UMLClassDialog *prop_dialog;
1672 GtkList *gtklist;
1673 GtkWidget *list_item;
1674 int i;
1676 prop_dialog = umlclass->properties_dialog;
1677 gtklist = GTK_LIST(prop_dialog->operations_list);
1679 if (gtklist->selection != NULL) {
1680 list_item = GTK_WIDGET(gtklist->selection->data);
1682 i = gtk_list_child_position(gtklist, list_item);
1683 if (i<(g_list_length(gtklist->children)-1))
1684 i++;
1686 gtk_widget_ref(list_item);
1687 list = g_list_prepend(NULL, list_item);
1688 gtk_list_remove_items(gtklist, list);
1689 gtk_list_insert_items(gtklist, list, i);
1690 gtk_widget_unref(list_item);
1692 gtk_list_select_child(gtklist, list_item);
1696 static void
1697 operations_read_from_dialog(UMLClass *umlclass,
1698 UMLClassDialog *prop_dialog,
1699 int connection_index)
1701 GList *list;
1702 UMLOperation *op;
1703 GtkWidget *list_item;
1704 GList *clear_list;
1705 DiaObject *obj;
1707 obj = &umlclass->element.object;
1709 /* if currently select op is changed in the entries, update from widgets */
1710 operations_get_current_values(prop_dialog);
1712 /* Free current operations: */
1713 list = umlclass->operations;
1714 while (list != NULL) {
1715 op = (UMLOperation *)list->data;
1716 uml_operation_destroy(op);
1717 list = g_list_next(list);
1719 g_list_free (umlclass->operations);
1720 umlclass->operations = NULL;
1722 /* Insert new operations and remove them from gtklist: */
1723 list = GTK_LIST (prop_dialog->operations_list)->children;
1724 clear_list = NULL;
1725 while (list != NULL) {
1726 list_item = GTK_WIDGET(list->data);
1728 clear_list = g_list_prepend (clear_list, list_item);
1729 op = (UMLOperation *)
1730 gtk_object_get_user_data(GTK_OBJECT(list_item));
1731 gtk_object_set_user_data(GTK_OBJECT(list_item), NULL);
1732 umlclass->operations = g_list_append(umlclass->operations, op);
1734 if (op->left_connection == NULL) {
1735 uml_operation_ensure_connection_points (op, obj);
1737 prop_dialog->added_connections =
1738 g_list_prepend(prop_dialog->added_connections,
1739 op->left_connection);
1740 prop_dialog->added_connections =
1741 g_list_prepend(prop_dialog->added_connections,
1742 op->right_connection);
1745 if ( (prop_dialog->op_vis->active) &&
1746 (!prop_dialog->op_supp->active) ) {
1747 obj->connections[connection_index] = op->left_connection;
1748 connection_index++;
1749 obj->connections[connection_index] = op->right_connection;
1750 connection_index++;
1751 } else {
1752 umlclass_store_disconnects(prop_dialog, op->left_connection);
1753 object_remove_connections_to(op->left_connection);
1754 umlclass_store_disconnects(prop_dialog, op->right_connection);
1755 object_remove_connections_to(op->right_connection);
1758 list = g_list_next(list);
1760 clear_list = g_list_reverse (clear_list);
1761 gtk_list_remove_items (GTK_LIST (prop_dialog->operations_list), clear_list);
1762 g_list_free (clear_list);
1765 static void
1766 operations_fill_in_dialog(UMLClass *umlclass)
1768 UMLClassDialog *prop_dialog;
1769 UMLOperation *op_copy;
1770 GtkWidget *list_item;
1771 GList *list;
1772 int i;
1774 prop_dialog = umlclass->properties_dialog;
1776 if (prop_dialog->operations_list->children == NULL) {
1777 i = 0;
1778 list = umlclass->operations;
1779 while (list != NULL) {
1780 UMLOperation *op = (UMLOperation *)list->data;
1781 gchar *opstr = uml_get_operation_string (op);
1783 list_item = gtk_list_item_new_with_label (opstr);
1784 op_copy = uml_operation_copy (op);
1785 /* Looks wrong but is required for the complicate connections memory management */
1786 op_copy->left_connection = op->left_connection;
1787 op_copy->right_connection = op->right_connection;
1788 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer) op_copy);
1789 gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
1790 GTK_SIGNAL_FUNC (operations_list_item_destroy_callback),
1791 NULL);
1792 gtk_container_add (GTK_CONTAINER (prop_dialog->operations_list), list_item);
1793 gtk_widget_show (list_item);
1795 list = g_list_next(list); i++;
1796 g_free (opstr);
1799 /* set operations non-sensitive */
1800 prop_dialog->current_op = NULL;
1801 operations_set_sensitive(prop_dialog, FALSE);
1802 operations_clear_values(prop_dialog);
1806 static void
1807 operations_update(GtkWidget *widget, UMLClass *umlclass)
1809 operations_get_current_values(umlclass->properties_dialog);
1812 static int
1813 operations_update_event(GtkWidget *widget, GdkEventFocus *ev, UMLClass *umlclass)
1815 operations_get_current_values(umlclass->properties_dialog);
1816 return 0;
1819 static void
1820 operations_create_page(GtkNotebook *notebook, UMLClass *umlclass)
1822 UMLClassDialog *prop_dialog;
1823 GtkWidget *page_label;
1824 GtkWidget *label;
1825 GtkWidget *hbox;
1826 GtkWidget *vbox;
1827 GtkWidget *table;
1828 GtkWidget *vbox2;
1829 GtkWidget *hbox2;
1830 GtkWidget *vbox3;
1831 GtkWidget *entry;
1832 GtkWidget *checkbox;
1833 GtkWidget *scrolled_win;
1834 GtkWidget *button;
1835 GtkWidget *list;
1836 GtkWidget *frame;
1837 GtkWidget *omenu;
1838 GtkWidget *menu;
1839 GtkWidget *submenu;
1840 GtkWidget *menuitem;
1841 GtkWidget *scrolledwindow;
1842 GSList *group;
1844 prop_dialog = umlclass->properties_dialog;
1846 /* Operations page: */
1847 page_label = gtk_label_new_with_mnemonic (_("_Operations"));
1849 vbox = gtk_vbox_new(FALSE, 5);
1850 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
1852 hbox = gtk_hbox_new(FALSE, 5);
1854 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1855 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
1856 GTK_POLICY_AUTOMATIC,
1857 GTK_POLICY_AUTOMATIC);
1858 gtk_box_pack_start (GTK_BOX (hbox), scrolled_win, TRUE, TRUE, 0);
1859 gtk_widget_show (scrolled_win);
1861 list = gtk_list_new ();
1862 prop_dialog->operations_list = GTK_LIST(list);
1863 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
1864 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
1865 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
1866 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
1867 gtk_widget_show (list);
1869 gtk_signal_connect (GTK_OBJECT (list), "selection_changed",
1870 GTK_SIGNAL_FUNC(operations_list_selection_changed_callback),
1871 umlclass);
1873 vbox2 = gtk_vbox_new(FALSE, 5);
1875 button = gtk_button_new_with_mnemonic (_("_New"));
1876 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1877 GTK_SIGNAL_FUNC(operations_list_new_callback),
1878 umlclass);
1879 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
1880 gtk_widget_show (button);
1881 button = gtk_button_new_with_mnemonic (_("_Delete"));
1882 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1883 GTK_SIGNAL_FUNC(operations_list_delete_callback),
1884 umlclass);
1885 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
1886 gtk_widget_show (button);
1887 button = gtk_button_new_with_label (_("Move up"));
1888 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1889 GTK_SIGNAL_FUNC(operations_list_move_up_callback),
1890 umlclass);
1891 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
1892 gtk_widget_show (button);
1893 button = gtk_button_new_with_label (_("Move down"));
1894 gtk_signal_connect (GTK_OBJECT (button), "clicked",
1895 GTK_SIGNAL_FUNC(operations_list_move_down_callback),
1896 umlclass);
1898 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
1899 gtk_widget_show (button);
1901 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
1903 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
1905 frame = gtk_frame_new(_("Operation data"));
1906 hbox = gtk_hbox_new(FALSE, 5);
1907 gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
1908 gtk_container_add (GTK_CONTAINER (frame), hbox);
1909 gtk_widget_show(frame);
1910 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
1912 vbox2 = gtk_vbox_new(FALSE, 5);
1914 table = gtk_table_new (3, 2, FALSE);
1915 gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
1917 label = gtk_label_new(_("Name:"));
1918 entry = gtk_entry_new();
1919 prop_dialog->op_name = GTK_ENTRY(entry);
1920 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
1921 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
1922 gtk_signal_connect (GTK_OBJECT (entry), "activate",
1923 GTK_SIGNAL_FUNC (operations_update), umlclass);
1924 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1925 gtk_table_attach (GTK_TABLE (table), label, 0,1,0,1, GTK_FILL,0, 0,0);
1926 gtk_table_attach (GTK_TABLE (table), entry, 1,2,0,1, GTK_FILL | GTK_EXPAND,0, 0,2);
1928 label = gtk_label_new(_("Type:"));
1929 entry = gtk_entry_new();
1930 prop_dialog->op_type = GTK_ENTRY(entry);
1931 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
1932 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
1933 gtk_signal_connect (GTK_OBJECT (entry), "activate",
1934 GTK_SIGNAL_FUNC (operations_update), umlclass);
1935 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1936 gtk_table_attach (GTK_TABLE (table), label, 0,1,1,2, GTK_FILL,0, 0,0);
1937 gtk_table_attach (GTK_TABLE (table), entry, 1,2,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
1939 label = gtk_label_new(_("Stereotype:"));
1940 entry = gtk_entry_new();
1941 prop_dialog->op_stereotype = GTK_ENTRY(entry);
1942 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
1943 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
1944 gtk_signal_connect (GTK_OBJECT (entry), "activate",
1945 GTK_SIGNAL_FUNC (operations_update), umlclass);
1946 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1947 gtk_table_attach (GTK_TABLE (table), label, 0,1,2,3, GTK_FILL,0, 0,0);
1948 gtk_table_attach (GTK_TABLE (table), entry, 1,2,2,3, GTK_FILL | GTK_EXPAND,0, 0,2);
1951 hbox2 = gtk_hbox_new(FALSE, 5);
1952 label = gtk_label_new(_("Visibility:"));
1954 omenu = gtk_option_menu_new ();
1955 menu = gtk_menu_new ();
1956 prop_dialog->op_visible = GTK_MENU(menu);
1957 prop_dialog->op_visible_button = GTK_OPTION_MENU(omenu);
1958 submenu = NULL;
1959 group = NULL;
1961 menuitem = gtk_radio_menu_item_new_with_label (group, _("Public"));
1962 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1963 GTK_SIGNAL_FUNC (operations_update), umlclass);
1964 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1965 GINT_TO_POINTER(UML_PUBLIC) );
1966 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1967 gtk_menu_append (GTK_MENU (menu), menuitem);
1968 gtk_widget_show (menuitem);
1969 menuitem = gtk_radio_menu_item_new_with_label (group, _("Private"));
1970 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1971 GTK_SIGNAL_FUNC (operations_update), umlclass);
1972 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1973 GINT_TO_POINTER(UML_PRIVATE) );
1974 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1975 gtk_menu_append (GTK_MENU (menu), menuitem);
1976 gtk_widget_show (menuitem);
1977 menuitem = gtk_radio_menu_item_new_with_label (group, _("Protected"));
1978 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1979 GTK_SIGNAL_FUNC (operations_update), umlclass);
1980 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1981 GINT_TO_POINTER(UML_PROTECTED) );
1982 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1983 gtk_menu_append (GTK_MENU (menu), menuitem);
1984 gtk_widget_show (menuitem);
1985 menuitem = gtk_radio_menu_item_new_with_label (group, _("Implementation"));
1986 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
1987 GTK_SIGNAL_FUNC (operations_update), umlclass);
1988 gtk_object_set_user_data(GTK_OBJECT(menuitem),
1989 GINT_TO_POINTER(UML_IMPLEMENTATION) );
1990 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
1991 gtk_menu_append (GTK_MENU (menu), menuitem);
1992 gtk_widget_show (menuitem);
1994 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
1996 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
1997 gtk_box_pack_start (GTK_BOX (hbox2), omenu, FALSE, TRUE, 0);
1998 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, TRUE, 0);
2000 hbox2 = gtk_hbox_new(FALSE, 5);
2001 checkbox = gtk_check_button_new_with_label(_("Class scope"));
2002 prop_dialog->op_class_scope = GTK_TOGGLE_BUTTON(checkbox);
2003 gtk_box_pack_start (GTK_BOX (hbox2), checkbox, TRUE, TRUE, 0);
2004 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, TRUE, 0);
2006 hbox2 = gtk_hbox_new(FALSE, 5);
2007 label = gtk_label_new(_("Inheritance type:"));
2009 omenu = gtk_option_menu_new ();
2010 menu = gtk_menu_new ();
2011 prop_dialog->op_inheritance_type = GTK_MENU(menu);
2012 prop_dialog->op_inheritance_type_button = GTK_OPTION_MENU(omenu);
2013 submenu = NULL;
2014 group = NULL;
2016 menuitem = gtk_radio_menu_item_new_with_label (group, _("Abstract"));
2017 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2018 GTK_SIGNAL_FUNC (operations_update), umlclass);
2019 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2020 GINT_TO_POINTER(UML_ABSTRACT) );
2021 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2022 gtk_menu_append (GTK_MENU (menu), menuitem);
2023 gtk_widget_show (menuitem);
2024 menuitem = gtk_radio_menu_item_new_with_label (group, _("Polymorphic (virtual)"));
2025 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2026 GTK_SIGNAL_FUNC (operations_update), umlclass);
2027 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2028 GINT_TO_POINTER(UML_POLYMORPHIC) );
2029 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2030 gtk_menu_append (GTK_MENU (menu), menuitem);
2031 gtk_widget_show (menuitem);
2032 menuitem = gtk_radio_menu_item_new_with_label (group, _("Leaf (final)"));
2033 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2034 GTK_SIGNAL_FUNC (operations_update), umlclass);
2035 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2036 GINT_TO_POINTER(UML_LEAF) );
2037 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2038 gtk_menu_append (GTK_MENU (menu), menuitem);
2039 gtk_widget_show (menuitem);
2041 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
2043 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
2044 gtk_box_pack_start (GTK_BOX (hbox2), omenu, FALSE, TRUE, 0);
2046 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, TRUE, 0);
2048 hbox2 = gtk_hbox_new(FALSE, 5);
2050 checkbox = gtk_check_button_new_with_label(_("Query"));
2051 prop_dialog->op_query = GTK_TOGGLE_BUTTON(checkbox);
2053 gtk_box_pack_start (GTK_BOX (hbox2), checkbox, TRUE, TRUE, 0);
2054 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, TRUE, 0);
2056 hbox2 = gtk_hbox_new(FALSE, 5);
2057 label = gtk_label_new(_("Comment:"));
2058 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
2059 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
2060 GTK_SHADOW_IN);
2061 entry = gtk_text_view_new ();
2062 prop_dialog->op_comment = GTK_TEXT_VIEW(entry);
2063 gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
2064 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (entry), GTK_WRAP_WORD);
2065 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (entry),TRUE);
2067 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2068 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
2069 #if 0 /* no "activate" signal on GtkTextView */
2070 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2071 GTK_SIGNAL_FUNC (operations_update), umlclass);
2072 #endif
2073 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
2074 gtk_box_pack_start (GTK_BOX (hbox2), scrolledwindow, TRUE, TRUE, 0);
2075 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, TRUE, 0);
2077 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
2079 vbox2 = gtk_vbox_new(FALSE, 5);
2081 hbox2 = gtk_hbox_new(FALSE, 5);
2083 label = gtk_label_new(_("Parameters:"));
2084 gtk_box_pack_start( GTK_BOX(hbox2), label, FALSE, TRUE, 0);
2086 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
2089 hbox2 = gtk_hbox_new(FALSE, 5);
2091 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
2092 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
2093 GTK_POLICY_AUTOMATIC,
2094 GTK_POLICY_AUTOMATIC);
2095 gtk_box_pack_start (GTK_BOX (hbox2), scrolled_win, TRUE, TRUE, 0);
2096 gtk_widget_show (scrolled_win);
2098 list = gtk_list_new ();
2099 prop_dialog->parameters_list = GTK_LIST(list);
2100 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
2101 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
2102 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
2103 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
2104 gtk_widget_show (list);
2106 gtk_signal_connect (GTK_OBJECT (list), "selection_changed",
2107 GTK_SIGNAL_FUNC(parameters_list_selection_changed_callback),
2108 umlclass);
2110 vbox3 = gtk_vbox_new(FALSE, 5);
2112 button = gtk_button_new_with_mnemonic (_("_New"));
2113 prop_dialog->param_new_button = button;
2114 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2115 GTK_SIGNAL_FUNC(parameters_list_new_callback),
2116 umlclass);
2117 gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
2118 gtk_widget_show (button);
2119 button = gtk_button_new_with_mnemonic (_("_Delete"));
2120 prop_dialog->param_delete_button = button;
2121 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2122 GTK_SIGNAL_FUNC(parameters_list_delete_callback),
2123 umlclass);
2124 gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
2125 gtk_widget_show (button);
2126 button = gtk_button_new_with_label (_("Move up"));
2127 prop_dialog->param_up_button = button;
2128 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2129 GTK_SIGNAL_FUNC(parameters_list_move_up_callback),
2130 umlclass);
2131 gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
2132 gtk_widget_show (button);
2133 button = gtk_button_new_with_label (_("Move down"));
2134 prop_dialog->param_down_button = button;
2135 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2136 GTK_SIGNAL_FUNC(parameters_list_move_down_callback),
2137 umlclass);
2138 gtk_box_pack_start (GTK_BOX (vbox3), button, FALSE, TRUE, 0);
2139 gtk_widget_show (button);
2141 gtk_box_pack_start (GTK_BOX (hbox2), vbox3, FALSE, TRUE, 0);
2143 gtk_box_pack_start (GTK_BOX (vbox2), hbox2, TRUE, TRUE, 0);
2145 frame = gtk_frame_new(_("Parameter data"));
2146 vbox3 = gtk_vbox_new(FALSE, 5);
2147 gtk_container_set_border_width (GTK_CONTAINER (vbox3), 10);
2148 gtk_container_add (GTK_CONTAINER (frame), vbox3);
2149 gtk_widget_show(frame);
2150 gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, TRUE, 0);
2152 table = gtk_table_new (5, 2, FALSE);
2153 gtk_box_pack_start (GTK_BOX (vbox3), table, FALSE, FALSE, 0);
2155 label = gtk_label_new(_("Name:"));
2156 entry = gtk_entry_new();
2157 prop_dialog->param_name = GTK_ENTRY(entry);
2158 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2159 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
2160 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2161 GTK_SIGNAL_FUNC (operations_update), umlclass);
2162 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2163 gtk_table_attach (GTK_TABLE (table), label, 0,1,0,1, GTK_FILL,0, 0,0);
2164 gtk_table_attach (GTK_TABLE (table), entry, 1,2,0,1, GTK_FILL | GTK_EXPAND,0, 0,2);
2166 label = gtk_label_new(_("Type:"));
2167 entry = gtk_entry_new();
2168 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2169 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
2170 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2171 GTK_SIGNAL_FUNC (operations_update), umlclass);
2172 prop_dialog->param_type = GTK_ENTRY(entry);
2173 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2174 gtk_table_attach (GTK_TABLE (table), label, 0,1,1,2, GTK_FILL,0, 0,0);
2175 gtk_table_attach (GTK_TABLE (table), entry, 1,2,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
2177 label = gtk_label_new(_("Def. value:"));
2178 entry = gtk_entry_new();
2179 prop_dialog->param_value = GTK_ENTRY(entry);
2180 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2181 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
2182 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2183 GTK_SIGNAL_FUNC (operations_update), umlclass);
2184 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2185 gtk_table_attach (GTK_TABLE (table), label, 0,1,2,3, GTK_FILL,0, 0,0);
2186 gtk_table_attach (GTK_TABLE (table), entry, 1,2,2,3, GTK_FILL | GTK_EXPAND,0, 0,2);
2188 label = gtk_label_new(_("Comment:"));
2189 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
2190 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
2191 GTK_SHADOW_IN);
2192 entry = gtk_text_view_new ();
2193 prop_dialog->param_comment = GTK_TEXT_VIEW(entry);
2194 gtk_container_add (GTK_CONTAINER (scrolledwindow), entry);
2195 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (entry), GTK_WRAP_WORD);
2196 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (entry),TRUE);
2198 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2199 GTK_SIGNAL_FUNC (operations_update_event), umlclass);
2200 #if 0 /* no "activate" signal on GtkTextView */
2201 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2202 GTK_SIGNAL_FUNC (operations_update), umlclass);
2203 #endif
2204 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2205 gtk_table_attach (GTK_TABLE (table), label, 0,1,3,4, GTK_FILL,0, 0,0);
2206 gtk_table_attach (GTK_TABLE (table), scrolledwindow, 1,2,3,4, GTK_FILL | GTK_EXPAND,0, 0,2);
2208 label = gtk_label_new(_("Direction:"));
2210 omenu = gtk_option_menu_new ();
2211 menu = gtk_menu_new ();
2212 prop_dialog->param_kind = GTK_MENU(menu);
2213 prop_dialog->param_kind_button = GTK_OPTION_MENU(omenu);
2214 submenu = NULL;
2215 group = NULL;
2217 menuitem = gtk_radio_menu_item_new_with_label (group, _("Undefined"));
2218 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2219 GTK_SIGNAL_FUNC (operations_update), umlclass);
2220 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2221 GINT_TO_POINTER(UML_UNDEF_KIND) );
2222 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2223 gtk_menu_append (GTK_MENU (menu), menuitem);
2224 gtk_widget_show (menuitem);
2225 menuitem = gtk_radio_menu_item_new_with_label (group, _("In"));
2226 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2227 GTK_SIGNAL_FUNC (operations_update), umlclass);
2228 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2229 GINT_TO_POINTER(UML_IN) );
2230 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2231 gtk_menu_append (GTK_MENU (menu), menuitem);
2232 gtk_widget_show (menuitem);
2234 menuitem = gtk_radio_menu_item_new_with_label (group, _("Out"));
2235 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2236 GTK_SIGNAL_FUNC (operations_update), umlclass);
2237 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2238 GINT_TO_POINTER(UML_OUT) );
2239 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2240 gtk_menu_append (GTK_MENU (menu), menuitem);
2241 gtk_widget_show (menuitem);
2243 menuitem = gtk_radio_menu_item_new_with_label (group, _("In & Out"));
2244 gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
2245 GTK_SIGNAL_FUNC (operations_update), umlclass);
2246 gtk_object_set_user_data(GTK_OBJECT(menuitem),
2247 GINT_TO_POINTER(UML_INOUT) );
2248 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2249 gtk_menu_append (GTK_MENU (menu), menuitem);
2250 gtk_widget_show (menuitem);
2252 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
2255 GtkWidget * align;
2256 align = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
2257 gtk_container_add(GTK_CONTAINER(align), omenu);
2258 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2259 gtk_table_attach (GTK_TABLE (table), label, 0,1,4,5, GTK_FILL,0, 0,3);
2260 gtk_table_attach (GTK_TABLE (table), align, 1,2,4,5, GTK_FILL,0, 0,3);
2263 gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
2265 gtk_widget_show_all (vbox);
2266 gtk_widget_show (page_label);
2267 gtk_notebook_append_page (notebook, vbox, page_label);
2271 /************************************************************
2272 ******************** TEMPLATES *****************************
2273 ************************************************************/
2275 static void
2276 templates_set_sensitive(UMLClassDialog *prop_dialog, gint val)
2278 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->templ_name), val);
2279 gtk_widget_set_sensitive(GTK_WIDGET(prop_dialog->templ_type), val);
2282 static void
2283 templates_set_values (UMLClassDialog *prop_dialog,
2284 UMLFormalParameter *param)
2286 if (param->name)
2287 gtk_entry_set_text(prop_dialog->templ_name, param->name);
2288 if (param->type != NULL)
2289 gtk_entry_set_text(prop_dialog->templ_type, param->type);
2292 static void
2293 templates_clear_values(UMLClassDialog *prop_dialog)
2295 gtk_entry_set_text(prop_dialog->templ_name, "");
2296 gtk_entry_set_text(prop_dialog->templ_type, "");
2299 static void
2300 templates_get_values(UMLClassDialog *prop_dialog, UMLFormalParameter *param)
2302 g_free(param->name);
2303 if (param->type != NULL)
2304 g_free(param->type);
2306 param->name = g_strdup (gtk_entry_get_text (prop_dialog->templ_name));
2307 param->type = g_strdup (gtk_entry_get_text (prop_dialog->templ_type));
2311 static void
2312 templates_get_current_values(UMLClassDialog *prop_dialog)
2314 UMLFormalParameter *current_param;
2315 GtkLabel *label;
2316 gchar* new_str;
2318 if (prop_dialog->current_templ != NULL) {
2319 current_param = (UMLFormalParameter *)
2320 gtk_object_get_user_data(GTK_OBJECT(prop_dialog->current_templ));
2321 if (current_param != NULL) {
2322 templates_get_values(prop_dialog, current_param);
2323 label = GTK_LABEL(GTK_BIN(prop_dialog->current_templ)->child);
2324 new_str = uml_get_formalparameter_string (current_param);
2325 gtk_label_set_text(label, new_str);
2326 g_free(new_str);
2331 static void
2332 templates_list_item_destroy_callback(GtkWidget *list_item,
2333 gpointer data)
2335 UMLFormalParameter *param;
2337 param = (UMLFormalParameter *)
2338 gtk_object_get_user_data(GTK_OBJECT(list_item));
2340 if (param != NULL) {
2341 uml_formalparameter_destroy(param);
2342 /*printf("Destroying list_item's user_data!\n"); */
2346 static void
2347 templates_list_selection_changed_callback(GtkWidget *gtklist,
2348 UMLClass *umlclass)
2350 GList *list;
2351 UMLClassDialog *prop_dialog;
2352 GtkObject *list_item;
2353 UMLFormalParameter *param;
2355 prop_dialog = umlclass->properties_dialog;
2357 templates_get_current_values(prop_dialog);
2359 list = GTK_LIST(gtklist)->selection;
2360 if (!list) { /* No selected */
2361 templates_set_sensitive(prop_dialog, FALSE);
2362 templates_clear_values(prop_dialog);
2363 prop_dialog->current_templ = NULL;
2364 return;
2367 list_item = GTK_OBJECT(list->data);
2368 param = (UMLFormalParameter *)gtk_object_get_user_data(list_item);
2369 templates_set_values(prop_dialog, param);
2370 templates_set_sensitive(prop_dialog, TRUE);
2372 prop_dialog->current_templ = GTK_LIST_ITEM(list_item);
2373 gtk_widget_grab_focus(GTK_WIDGET(prop_dialog->templ_name));
2376 static void
2377 templates_list_new_callback(GtkWidget *button,
2378 UMLClass *umlclass)
2380 GList *list;
2381 UMLClassDialog *prop_dialog;
2382 GtkWidget *list_item;
2383 UMLFormalParameter *param;
2384 char *utfstr;
2386 prop_dialog = umlclass->properties_dialog;
2388 templates_get_current_values(prop_dialog);
2390 param = uml_formalparameter_new();
2392 utfstr = uml_get_formalparameter_string (param);
2393 list_item = gtk_list_item_new_with_label (utfstr);
2394 gtk_widget_show (list_item);
2395 g_free (utfstr);
2397 gtk_object_set_user_data(GTK_OBJECT(list_item), param);
2398 gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
2399 GTK_SIGNAL_FUNC (templates_list_item_destroy_callback),
2400 NULL);
2402 list = g_list_append(NULL, list_item);
2403 gtk_list_append_items(prop_dialog->templates_list, list);
2405 if (prop_dialog->templates_list->children != NULL)
2406 gtk_list_unselect_child(prop_dialog->templates_list,
2407 GTK_WIDGET(prop_dialog->templates_list->children->data));
2408 gtk_list_select_child(prop_dialog->templates_list, list_item);
2411 static void
2412 templates_list_delete_callback(GtkWidget *button,
2413 UMLClass *umlclass)
2415 GList *list;
2416 UMLClassDialog *prop_dialog;
2417 GtkList *gtklist;
2419 prop_dialog = umlclass->properties_dialog;
2420 gtklist = GTK_LIST(prop_dialog->templates_list);
2422 if (gtklist->selection != NULL) {
2423 list = g_list_prepend(NULL, gtklist->selection->data);
2424 gtk_list_remove_items(gtklist, list);
2425 g_list_free(list);
2426 templates_clear_values(prop_dialog);
2427 templates_set_sensitive(prop_dialog, FALSE);
2431 static void
2432 templates_list_move_up_callback(GtkWidget *button,
2433 UMLClass *umlclass)
2435 GList *list;
2436 UMLClassDialog *prop_dialog;
2437 GtkList *gtklist;
2438 GtkWidget *list_item;
2439 int i;
2441 prop_dialog = umlclass->properties_dialog;
2442 gtklist = GTK_LIST(prop_dialog->templates_list);
2444 if (gtklist->selection != NULL) {
2445 list_item = GTK_WIDGET(gtklist->selection->data);
2447 i = gtk_list_child_position(gtklist, list_item);
2448 if (i>0)
2449 i--;
2451 gtk_widget_ref(list_item);
2452 list = g_list_prepend(NULL, list_item);
2453 gtk_list_remove_items(gtklist, list);
2454 gtk_list_insert_items(gtklist, list, i);
2455 gtk_widget_unref(list_item);
2457 gtk_list_select_child(gtklist, list_item);
2461 static void
2462 templates_list_move_down_callback(GtkWidget *button,
2463 UMLClass *umlclass)
2465 GList *list;
2466 UMLClassDialog *prop_dialog;
2467 GtkList *gtklist;
2468 GtkWidget *list_item;
2469 int i;
2471 prop_dialog = umlclass->properties_dialog;
2472 gtklist = GTK_LIST(prop_dialog->templates_list);
2474 if (gtklist->selection != NULL) {
2475 list_item = GTK_WIDGET(gtklist->selection->data);
2477 i = gtk_list_child_position(gtklist, list_item);
2478 if (i<(g_list_length(gtklist->children)-1))
2479 i++;
2481 gtk_widget_ref(list_item);
2482 list = g_list_prepend(NULL, list_item);
2483 gtk_list_remove_items(gtklist, list);
2484 gtk_list_insert_items(gtklist, list, i);
2485 gtk_widget_unref(list_item);
2487 gtk_list_select_child(gtklist, list_item);
2492 static void
2493 templates_read_from_dialog(UMLClass *umlclass, UMLClassDialog *prop_dialog)
2495 GList *list;
2496 UMLFormalParameter *param;
2497 GtkWidget *list_item;
2498 GList *clear_list;
2500 templates_get_current_values(prop_dialog); /* if changed, update from widgets */
2502 umlclass->template = prop_dialog->templ_template->active;
2504 /* Free current formal parameters: */
2505 list = umlclass->formal_params;
2506 while (list != NULL) {
2507 param = (UMLFormalParameter *)list->data;
2508 uml_formalparameter_destroy(param);
2509 list = g_list_next(list);
2511 g_list_free (umlclass->formal_params);
2512 umlclass->formal_params = NULL;
2514 /* Insert new formal params and remove them from gtklist: */
2515 list = GTK_LIST (prop_dialog->templates_list)->children;
2516 clear_list = NULL;
2517 while (list != NULL) {
2518 list_item = GTK_WIDGET(list->data);
2519 clear_list = g_list_prepend (clear_list, list_item);
2520 param = (UMLFormalParameter *)
2521 gtk_object_get_user_data(GTK_OBJECT(list_item));
2522 gtk_object_set_user_data(GTK_OBJECT(list_item), NULL);
2523 umlclass->formal_params = g_list_append(umlclass->formal_params, param);
2524 list = g_list_next(list);
2526 clear_list = g_list_reverse (clear_list);
2527 gtk_list_remove_items (GTK_LIST (prop_dialog->templates_list), clear_list);
2528 g_list_free (clear_list);
2531 static void
2532 templates_fill_in_dialog(UMLClass *umlclass)
2534 UMLClassDialog *prop_dialog;
2535 UMLFormalParameter *param_copy;
2536 GList *list;
2537 GtkWidget *list_item;
2538 int i;
2539 prop_dialog = umlclass->properties_dialog;
2541 gtk_toggle_button_set_active(prop_dialog->templ_template, umlclass->template);
2543 /* copy in new template-parameters: */
2544 if (prop_dialog->templates_list->children == NULL) {
2545 i = 0;
2546 list = umlclass->formal_params;
2547 while (list != NULL) {
2548 UMLFormalParameter *param = (UMLFormalParameter *)list->data;
2549 gchar *paramstr = uml_get_formalparameter_string(param);
2551 list_item = gtk_list_item_new_with_label (paramstr);
2552 param_copy = uml_formalparameter_copy(param);
2553 gtk_object_set_user_data(GTK_OBJECT(list_item),
2554 (gpointer) param_copy);
2555 gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
2556 GTK_SIGNAL_FUNC (templates_list_item_destroy_callback),
2557 NULL);
2558 gtk_container_add (GTK_CONTAINER (prop_dialog->templates_list),
2559 list_item);
2560 gtk_widget_show (list_item);
2562 list = g_list_next(list); i++;
2563 g_free (paramstr);
2565 /* set templates non-sensitive */
2566 prop_dialog->current_templ = NULL;
2567 templates_set_sensitive(prop_dialog, FALSE);
2568 templates_clear_values(prop_dialog);
2574 static void
2575 templates_update(GtkWidget *widget, UMLClass *umlclass)
2577 templates_get_current_values(umlclass->properties_dialog);
2580 static int
2581 templates_update_event(GtkWidget *widget, GdkEventFocus *ev, UMLClass *umlclass)
2583 templates_get_current_values(umlclass->properties_dialog);
2584 return 0;
2587 static void
2588 templates_create_page(GtkNotebook *notebook, UMLClass *umlclass)
2590 UMLClassDialog *prop_dialog;
2591 GtkWidget *page_label;
2592 GtkWidget *label;
2593 GtkWidget *hbox;
2594 GtkWidget *vbox;
2595 GtkWidget *vbox2;
2596 GtkWidget *hbox2;
2597 GtkWidget *table;
2598 GtkWidget *entry;
2599 GtkWidget *checkbox;
2600 GtkWidget *scrolled_win;
2601 GtkWidget *button;
2602 GtkWidget *list;
2603 GtkWidget *frame;
2605 prop_dialog = umlclass->properties_dialog;
2607 /* Templates page: */
2608 page_label = gtk_label_new_with_mnemonic (_("_Templates"));
2610 vbox = gtk_vbox_new(FALSE, 5);
2611 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
2613 hbox2 = gtk_hbox_new(FALSE, 5);
2614 checkbox = gtk_check_button_new_with_label(_("Template class"));
2615 prop_dialog->templ_template = GTK_TOGGLE_BUTTON(checkbox);
2616 gtk_box_pack_start (GTK_BOX (hbox2), checkbox, TRUE, TRUE, 0);
2617 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, TRUE, 0);
2619 hbox = gtk_hbox_new(FALSE, 5);
2621 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
2622 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
2623 GTK_POLICY_AUTOMATIC,
2624 GTK_POLICY_AUTOMATIC);
2625 gtk_box_pack_start (GTK_BOX (hbox), scrolled_win, TRUE, TRUE, 0);
2626 gtk_widget_show (scrolled_win);
2628 list = gtk_list_new ();
2629 prop_dialog->templates_list = GTK_LIST(list);
2630 gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
2631 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
2632 gtk_container_set_focus_vadjustment (GTK_CONTAINER (list),
2633 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_win)));
2634 gtk_widget_show (list);
2636 gtk_signal_connect (GTK_OBJECT (list), "selection_changed",
2637 GTK_SIGNAL_FUNC(templates_list_selection_changed_callback),
2638 umlclass);
2640 vbox2 = gtk_vbox_new(FALSE, 5);
2642 button = gtk_button_new_with_mnemonic (_("_New"));
2643 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2644 GTK_SIGNAL_FUNC(templates_list_new_callback),
2645 umlclass);
2646 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
2647 gtk_widget_show (button);
2648 button = gtk_button_new_with_mnemonic (_("_Delete"));
2649 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2650 GTK_SIGNAL_FUNC(templates_list_delete_callback),
2651 umlclass);
2652 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
2653 gtk_widget_show (button);
2654 button = gtk_button_new_with_label (_("Move up"));
2655 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2656 GTK_SIGNAL_FUNC(templates_list_move_up_callback),
2657 umlclass);
2658 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
2659 gtk_widget_show (button);
2660 button = gtk_button_new_with_label (_("Move down"));
2661 gtk_signal_connect (GTK_OBJECT (button), "clicked",
2662 GTK_SIGNAL_FUNC(templates_list_move_down_callback),
2663 umlclass);
2664 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, TRUE, 0);
2665 gtk_widget_show (button);
2667 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
2669 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2671 frame = gtk_frame_new(_("Formal parameter data"));
2672 vbox2 = gtk_vbox_new(FALSE, 5);
2673 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 10);
2674 gtk_container_add (GTK_CONTAINER (frame), vbox2);
2675 gtk_widget_show(frame);
2676 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
2678 table = gtk_table_new (2, 2, FALSE);
2679 gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
2681 label = gtk_label_new(_("Name:"));
2682 entry = gtk_entry_new();
2683 prop_dialog->templ_name = GTK_ENTRY(entry);
2684 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2685 GTK_SIGNAL_FUNC (templates_update_event), umlclass);
2686 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2687 GTK_SIGNAL_FUNC (templates_update), umlclass);
2688 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2689 gtk_table_attach (GTK_TABLE (table), label, 0,1,0,1, GTK_FILL,0, 0,0);
2690 gtk_table_attach (GTK_TABLE (table), entry, 1,2,0,1, GTK_FILL | GTK_EXPAND,0, 0,2);
2692 label = gtk_label_new(_("Type:"));
2693 entry = gtk_entry_new();
2694 prop_dialog->templ_type = GTK_ENTRY(entry);
2695 gtk_signal_connect (GTK_OBJECT (entry), "focus_out_event",
2696 GTK_SIGNAL_FUNC (templates_update_event), umlclass);
2697 gtk_signal_connect (GTK_OBJECT (entry), "activate",
2698 GTK_SIGNAL_FUNC (templates_update), umlclass);
2699 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2700 gtk_table_attach (GTK_TABLE (table), label, 0,1,1,2, GTK_FILL,0, 0,0);
2701 gtk_table_attach (GTK_TABLE (table), entry, 1,2,1,2, GTK_FILL | GTK_EXPAND,0, 0,2);
2703 gtk_widget_show(vbox2);
2705 /* TODO: Add stuff here! */
2707 gtk_widget_show_all (vbox);
2708 gtk_widget_show (page_label);
2709 gtk_notebook_append_page (notebook, vbox, page_label);
2714 /******************************************************
2715 ******************** ALL *****************************
2716 ******************************************************/
2718 static void
2719 switch_page_callback(GtkNotebook *notebook,
2720 GtkNotebookPage *page)
2722 UMLClass *umlclass;
2723 UMLClassDialog *prop_dialog;
2725 umlclass = (UMLClass *)
2726 gtk_object_get_user_data(GTK_OBJECT(notebook));
2728 prop_dialog = umlclass->properties_dialog;
2730 if (prop_dialog != NULL) {
2731 attributes_get_current_values(prop_dialog);
2732 operations_get_current_values(prop_dialog);
2733 templates_get_current_values(prop_dialog);
2737 static void
2738 destroy_properties_dialog (GtkWidget* widget,
2739 gpointer user_data)
2741 /* dialog gone, mark as such */
2742 UMLClass *umlclass = (UMLClass *)user_data;
2744 g_free (umlclass->properties_dialog);
2745 umlclass->properties_dialog = NULL;
2748 static void
2749 fill_in_dialog(UMLClass *umlclass)
2751 umlclass_sanity_check(umlclass, "Filling in dialog before attrs");
2752 class_fill_in_dialog(umlclass);
2753 attributes_fill_in_dialog(umlclass);
2754 operations_fill_in_dialog(umlclass);
2755 templates_fill_in_dialog(umlclass);
2758 ObjectChange *
2759 umlclass_apply_props_from_dialog(UMLClass *umlclass, GtkWidget *widget)
2761 UMLClassDialog *prop_dialog;
2762 DiaObject *obj;
2763 GList *list;
2764 int num_attrib, num_ops;
2765 GList *added, *deleted, *disconnected;
2766 UMLClassState *old_state = NULL;
2768 umlclass_sanity_check(umlclass, "Apply from dialog start");
2770 prop_dialog = umlclass->properties_dialog;
2772 old_state = umlclass_get_state(umlclass);
2774 /* Allocate enought connection points for attributes and operations. */
2775 /* (two per op/attr) */
2776 if ( (prop_dialog->attr_vis->active) && (!prop_dialog->attr_supp->active))
2777 num_attrib = g_list_length(prop_dialog->attributes_list->children);
2778 else
2779 num_attrib = 0;
2780 if ( (prop_dialog->op_vis->active) && (!prop_dialog->op_supp->active))
2781 num_ops = g_list_length(prop_dialog->operations_list->children);
2782 else
2783 num_ops = 0;
2784 obj = &umlclass->element.object;
2785 #ifdef UML_MAINPOINT
2786 obj->num_connections =
2787 UMLCLASS_CONNECTIONPOINTS + num_attrib*2 + num_ops*2 + 1;
2788 #else
2789 obj->num_connections =
2790 UMLCLASS_CONNECTIONPOINTS + num_attrib*2 + num_ops*2;
2791 #endif
2792 obj->connections =
2793 g_realloc(obj->connections,
2794 obj->num_connections*sizeof(ConnectionPoint *));
2796 /* Read from dialog and put in object: */
2797 class_read_from_dialog(umlclass, prop_dialog);
2798 attributes_read_from_dialog(umlclass, prop_dialog, UMLCLASS_CONNECTIONPOINTS);
2799 /* ^^^ attribs must be called before ops, to get the right order of the
2800 connectionpoints. */
2801 operations_read_from_dialog(umlclass, prop_dialog, UMLCLASS_CONNECTIONPOINTS+num_attrib*2);
2802 templates_read_from_dialog(umlclass, prop_dialog);
2804 /* Reestablish mainpoint */
2805 #ifdef UML_MAINPOINT
2806 obj->connections[obj->num_connections-1] =
2807 &umlclass->connections[UMLCLASS_CONNECTIONPOINTS];
2808 #endif
2810 /* unconnect from all deleted connectionpoints. */
2811 list = prop_dialog->deleted_connections;
2812 while (list != NULL) {
2813 ConnectionPoint *connection = (ConnectionPoint *) list->data;
2815 umlclass_store_disconnects(prop_dialog, connection);
2816 object_remove_connections_to(connection);
2818 list = g_list_next(list);
2821 deleted = prop_dialog->deleted_connections;
2822 prop_dialog->deleted_connections = NULL;
2824 added = prop_dialog->added_connections;
2825 prop_dialog->added_connections = NULL;
2827 disconnected = prop_dialog->disconnected_connections;
2828 prop_dialog->disconnected_connections = NULL;
2830 /* Update data: */
2831 umlclass_calculate_data(umlclass);
2832 umlclass_update_data(umlclass);
2834 /* Fill in class with the new data: */
2835 fill_in_dialog(umlclass);
2836 umlclass_sanity_check(umlclass, "Apply from dialog end");
2837 return new_umlclass_change(umlclass, old_state, added, deleted, disconnected);
2840 static void
2841 create_dialog_pages(GtkNotebook *notebook, UMLClass *umlclass)
2843 class_create_page(notebook, umlclass);
2844 attributes_create_page(notebook, umlclass);
2845 operations_create_page(notebook, umlclass);
2846 templates_create_page(notebook, umlclass);
2849 GtkWidget *
2850 umlclass_get_properties(UMLClass *umlclass, gboolean is_default)
2852 UMLClassDialog *prop_dialog;
2853 GtkWidget *vbox;
2854 GtkWidget *notebook;
2856 umlclass_sanity_check(umlclass, "Get properties start");
2857 if (umlclass->properties_dialog == NULL) {
2858 prop_dialog = g_new(UMLClassDialog, 1);
2859 umlclass->properties_dialog = prop_dialog;
2861 vbox = gtk_vbox_new(FALSE, 0);
2862 gtk_object_ref(GTK_OBJECT(vbox));
2863 gtk_object_sink(GTK_OBJECT(vbox));
2864 prop_dialog->dialog = vbox;
2866 prop_dialog->current_attr = NULL;
2867 prop_dialog->current_op = NULL;
2868 prop_dialog->current_param = NULL;
2869 prop_dialog->current_templ = NULL;
2870 prop_dialog->deleted_connections = NULL;
2871 prop_dialog->added_connections = NULL;
2872 prop_dialog->disconnected_connections = NULL;
2874 notebook = gtk_notebook_new ();
2875 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
2876 gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
2877 gtk_container_set_border_width (GTK_CONTAINER (notebook), 10);
2879 gtk_object_set_user_data(GTK_OBJECT(notebook), (gpointer) umlclass);
2881 gtk_signal_connect (GTK_OBJECT (notebook),
2882 "switch_page",
2883 GTK_SIGNAL_FUNC(switch_page_callback),
2884 (gpointer) umlclass);
2885 gtk_signal_connect (GTK_OBJECT (umlclass->properties_dialog->dialog),
2886 "destroy",
2887 GTK_SIGNAL_FUNC(destroy_properties_dialog),
2888 (gpointer) umlclass);
2890 create_dialog_pages(GTK_NOTEBOOK( notebook ), umlclass);
2892 gtk_widget_show (notebook);
2895 fill_in_dialog(umlclass);
2896 gtk_widget_show (umlclass->properties_dialog->dialog);
2898 return umlclass->properties_dialog->dialog;
2902 /****************** UNDO stuff: ******************/
2904 static void
2905 umlclass_free_state(UMLClassState *state)
2907 GList *list;
2909 g_free(state->name);
2910 g_free(state->stereotype);
2912 list = state->attributes;
2913 while (list) {
2914 uml_attribute_destroy((UMLAttribute *) list->data);
2915 list = g_list_next(list);
2917 g_list_free(state->attributes);
2919 list = state->operations;
2920 while (list) {
2921 uml_operation_destroy((UMLOperation *) list->data);
2922 list = g_list_next(list);
2924 g_list_free(state->operations);
2926 list = state->formal_params;
2927 while (list) {
2928 uml_formalparameter_destroy((UMLFormalParameter *) list->data);
2929 list = g_list_next(list);
2931 g_list_free(state->formal_params);
2934 static UMLClassState *
2935 umlclass_get_state(UMLClass *umlclass)
2937 UMLClassState *state = g_new0(UMLClassState, 1);
2938 GList *list;
2940 state->name = g_strdup(umlclass->name);
2941 state->stereotype = g_strdup(umlclass->stereotype);
2943 state->abstract = umlclass->abstract;
2944 state->suppress_attributes = umlclass->suppress_attributes;
2945 state->suppress_operations = umlclass->suppress_operations;
2946 state->visible_attributes = umlclass->visible_attributes;
2947 state->visible_operations = umlclass->visible_operations;
2950 state->attributes = NULL;
2951 list = umlclass->attributes;
2952 while (list != NULL) {
2953 UMLAttribute *attr = (UMLAttribute *)list->data;
2954 UMLAttribute *attr_copy;
2956 attr_copy = uml_attribute_copy(attr);
2957 /* Looks wrong, but needed fro proper restore */
2958 attr_copy->left_connection = attr->left_connection;
2959 attr_copy->right_connection = attr->right_connection;
2961 state->attributes = g_list_append(state->attributes, attr_copy);
2962 list = g_list_next(list);
2966 state->operations = NULL;
2967 list = umlclass->operations;
2968 while (list != NULL) {
2969 UMLOperation *op = (UMLOperation *)list->data;
2970 UMLOperation *op_copy;
2972 op_copy = uml_operation_copy(op);
2973 op_copy->left_connection = op->left_connection;
2974 op_copy->right_connection = op->right_connection;
2975 state->operations = g_list_append(state->operations, op_copy);
2976 list = g_list_next(list);
2980 state->template = umlclass->template;
2982 state->formal_params = NULL;
2983 list = umlclass->formal_params;
2984 while (list != NULL) {
2985 UMLFormalParameter *param = (UMLFormalParameter *)list->data;
2986 UMLFormalParameter *param_copy;
2988 param_copy = uml_formalparameter_copy(param);
2989 state->formal_params = g_list_append(state->formal_params, param_copy);
2991 list = g_list_next(list);
2994 return state;
2997 static void
2998 umlclass_update_connectionpoints(UMLClass *umlclass)
3000 int num_attrib, num_ops;
3001 DiaObject *obj;
3002 GList *list;
3003 int connection_index;
3004 UMLClassDialog *prop_dialog;
3006 prop_dialog = umlclass->properties_dialog;
3008 /* Allocate enought connection points for attributes and operations. */
3009 /* (two per op/attr) */
3010 if ( (umlclass->visible_attributes) && (!umlclass->suppress_attributes))
3011 num_attrib = g_list_length(umlclass->attributes);
3012 else
3013 num_attrib = 0;
3014 if ( (umlclass->visible_operations) && (!umlclass->suppress_operations))
3015 num_ops = g_list_length(umlclass->operations);
3016 else
3017 num_ops = 0;
3019 obj = &umlclass->element.object;
3020 #ifdef UML_MAINPOINT
3021 obj->num_connections = UMLCLASS_CONNECTIONPOINTS + num_attrib*2 + num_ops*2 + 1;
3022 #else
3023 obj->num_connections = UMLCLASS_CONNECTIONPOINTS + num_attrib*2 + num_ops*2;
3024 #endif
3025 obj->connections =
3026 g_realloc(obj->connections,
3027 obj->num_connections*sizeof(ConnectionPoint *));
3029 connection_index = UMLCLASS_CONNECTIONPOINTS;
3031 list = umlclass->attributes;
3032 while (list != NULL) {
3033 UMLAttribute *attr = (UMLAttribute *) list->data;
3035 if ( (umlclass->visible_attributes) &&
3036 (!umlclass->suppress_attributes)) {
3037 obj->connections[connection_index] = attr->left_connection;
3038 connection_index++;
3039 obj->connections[connection_index] = attr->right_connection;
3040 connection_index++;
3043 list = g_list_next(list);
3046 gtk_list_clear_items (GTK_LIST (prop_dialog->attributes_list), 0, -1);
3048 list = umlclass->operations;
3049 while (list != NULL) {
3050 UMLOperation *op = (UMLOperation *) list->data;
3052 if ( (umlclass->visible_operations) &&
3053 (!umlclass->suppress_operations)) {
3054 obj->connections[connection_index] = op->left_connection;
3055 connection_index++;
3056 obj->connections[connection_index] = op->right_connection;
3057 connection_index++;
3060 list = g_list_next(list);
3062 gtk_list_clear_items (GTK_LIST (prop_dialog->operations_list), 0, -1);
3064 #ifdef UML_MAINPOINT
3065 obj->connections[connection_index++] = &umlclass->connections[UMLCLASS_CONNECTIONPOINTS];
3066 #endif
3070 static void
3071 umlclass_set_state(UMLClass *umlclass, UMLClassState *state)
3073 umlclass->name = state->name;
3074 umlclass->stereotype = state->stereotype;
3076 umlclass->abstract = state->abstract;
3077 umlclass->suppress_attributes = state->suppress_attributes;
3078 umlclass->suppress_operations = state->suppress_operations;
3079 umlclass->visible_attributes = state->visible_attributes;
3080 umlclass->visible_operations = state->visible_operations;
3082 umlclass->attributes = state->attributes;
3083 umlclass->operations = state->operations;
3084 umlclass->template = state->template;
3085 umlclass->formal_params = state->formal_params;
3087 g_free(state);
3089 umlclass_update_connectionpoints(umlclass);
3091 umlclass_calculate_data(umlclass);
3092 umlclass_update_data(umlclass);
3095 static void
3096 umlclass_change_apply(UMLClassChange *change, DiaObject *obj)
3098 UMLClassState *old_state;
3099 GList *list;
3101 old_state = umlclass_get_state(change->obj);
3103 umlclass_set_state(change->obj, change->saved_state);
3105 list = change->disconnected;
3106 while (list) {
3107 Disconnect *dis = (Disconnect *)list->data;
3109 object_unconnect(dis->other_object, dis->other_handle);
3111 list = g_list_next(list);
3114 change->saved_state = old_state;
3115 change->applied = 1;
3118 static void
3119 umlclass_change_revert(UMLClassChange *change, DiaObject *obj)
3121 UMLClassState *old_state;
3122 GList *list;
3124 old_state = umlclass_get_state(change->obj);
3126 umlclass_set_state(change->obj, change->saved_state);
3128 list = change->disconnected;
3129 while (list) {
3130 Disconnect *dis = (Disconnect *)list->data;
3132 object_connect(dis->other_object, dis->other_handle, dis->cp);
3134 list = g_list_next(list);
3137 change->saved_state = old_state;
3138 change->applied = 0;
3141 static void
3142 umlclass_change_free(UMLClassChange *change)
3144 GList *list, *free_list;
3146 umlclass_free_state(change->saved_state);
3147 g_free(change->saved_state);
3149 /* Doesn't this mean only one of add, delete can be done in each apply? */
3150 if (change->applied)
3151 free_list = change->deleted_cp;
3152 else
3153 free_list = change->added_cp;
3155 list = free_list;
3156 while (list != NULL) {
3157 ConnectionPoint *connection = (ConnectionPoint *) list->data;
3159 g_assert(connection->connected == NULL); /* Paranoid */
3160 object_remove_connections_to(connection); /* Shouldn't be needed */
3161 g_free(connection);
3163 list = g_list_next(list);
3166 g_list_free(free_list);
3170 static ObjectChange *
3171 new_umlclass_change(UMLClass *obj, UMLClassState *saved_state,
3172 GList *added, GList *deleted, GList *disconnected)
3174 UMLClassChange *change;
3176 change = g_new0(UMLClassChange, 1);
3178 change->obj_change.apply =
3179 (ObjectChangeApplyFunc) umlclass_change_apply;
3180 change->obj_change.revert =
3181 (ObjectChangeRevertFunc) umlclass_change_revert;
3182 change->obj_change.free =
3183 (ObjectChangeFreeFunc) umlclass_change_free;
3185 change->obj = obj;
3186 change->saved_state = saved_state;
3187 change->applied = 1;
3189 change->added_cp = added;
3190 change->deleted_cp = deleted;
3191 change->disconnected = disconnected;
3193 return (ObjectChange *)change;
3196 get the contents of a comment text view.
3198 const gchar * get_comment(GtkTextView *view)
3200 GtkTextBuffer * buffer = gtk_text_view_get_buffer(view);
3201 GtkTextIter start;
3202 GtkTextIter end;
3204 gtk_text_buffer_get_start_iter(buffer, &start);
3205 gtk_text_buffer_get_end_iter(buffer, &end);
3207 return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
3210 void
3211 set_comment(GtkTextView *view, gchar *text)
3213 GtkTextBuffer * buffer = gtk_text_view_get_buffer(view);
3214 GtkTextIter start;
3215 GtkTextIter end;
3217 gtk_text_buffer_get_start_iter(buffer, &start);
3218 gtk_text_buffer_get_end_iter(buffer, &end);
3219 gtk_text_buffer_delete(buffer,&start,&end);
3220 gtk_text_buffer_get_start_iter(buffer, &start);
3221 gtk_text_buffer_insert( buffer, &start, text, strlen(text));