Enabling UML mainpoint
[dia.git] / app / properties.c
blob3430bfb82acac4b48a77cbacc5857ba5b188e5ff
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.
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <gtk/gtk.h>
24 #include <gdk/gdkkeysyms.h>
26 #include "intl.h"
27 #include "properties.h"
28 #include "object_ops.h"
29 #include "connectionpoint_ops.h"
30 #include "undo.h"
31 #include "message.h"
32 #include <string.h>
34 static GtkWidget *dialog = NULL;
35 static GtkWidget *dialog_vbox = NULL;
36 static GtkWidget *object_part = NULL;
37 static DiaObject *current_obj = NULL;
38 static Diagram *current_dia = NULL;
40 static GtkWidget *no_properties_dialog = NULL;
42 static gint properties_respond(GtkWidget *widget,
43 gint response_id,
44 gpointer data);
45 static gboolean properties_key_event(GtkWidget *widget,
46 GdkEventKey *event,
47 gpointer data);
49 static void create_dialog()
51 /* GtkWidget *actionbox; */
52 /* GList *buttons; */
54 dialog = gtk_dialog_new_with_buttons(
55 _("Object properties"),
56 GTK_WINDOW (ddisplay_active()->shell),
57 GTK_DIALOG_DESTROY_WITH_PARENT,
58 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
59 GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
60 GTK_STOCK_OK, GTK_RESPONSE_OK,
61 NULL);
63 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK);
65 dialog_vbox = GTK_DIALOG(dialog)->vbox;
67 gtk_window_set_role(GTK_WINDOW (dialog), "properties_window");
69 g_signal_connect(G_OBJECT (dialog), "response",
70 G_CALLBACK (properties_respond), NULL);
71 g_signal_connect(G_OBJECT (dialog), "delete_event",
72 G_CALLBACK(gtk_widget_hide), NULL);
73 g_signal_connect(G_OBJECT (dialog), "destroy",
74 G_CALLBACK(gtk_widget_destroyed), &dialog);
75 g_signal_connect(G_OBJECT (dialog), "destroy",
76 G_CALLBACK(gtk_widget_destroyed), &dialog_vbox);
77 g_signal_connect(G_OBJECT (dialog), "key-release-event",
78 G_CALLBACK(properties_key_event), NULL);
80 no_properties_dialog = gtk_label_new(_("This object has no properties."));
81 gtk_widget_show (no_properties_dialog);
82 g_object_ref(G_OBJECT(no_properties_dialog));
83 gtk_object_sink(GTK_OBJECT(no_properties_dialog));
86 static gint
87 properties_part_destroyed(GtkWidget *widget, gpointer data)
89 if (widget == object_part) {
90 object_part = NULL;
91 current_obj = NULL;
92 current_dia = NULL;
94 return 0;
97 static gint
98 properties_dialog_destroyed(GtkWidget *widget, gpointer data)
100 dialog = NULL;
101 return 0;
104 static gboolean
105 properties_key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
107 /* These ought to be done automagically by GtkDialog, but aren't.
108 * Adding them this way makes use of Esc/Enter for other purposes in
109 * the dialog close the dialog -- not good.
112 if (event->keyval == GDK_Escape) {
113 gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
114 return TRUE;
116 if (event->keyval == GDK_Return) {
117 gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_OK);
120 return FALSE;
123 static gint
124 properties_respond(GtkWidget *widget,
125 gint response_id,
126 gpointer data)
128 ObjectChange *obj_change = NULL;
130 if ( response_id == GTK_RESPONSE_APPLY
131 || response_id == GTK_RESPONSE_OK) {
132 if ((current_obj != NULL) && (current_dia != NULL)) {
133 object_add_updates(current_obj, current_dia);
134 obj_change = current_obj->ops->apply_properties(current_obj, object_part);
135 object_add_updates(current_obj, current_dia);
137 diagram_update_connections_object(current_dia, current_obj, TRUE);
139 if (obj_change != NULL) {
140 undo_object_change(current_dia, current_obj, obj_change);
143 diagram_modified(current_dia);
145 diagram_object_modified(current_dia, current_obj);
147 diagram_update_extents(current_dia);
149 if (obj_change != NULL) {
150 undo_set_transactionpoint(current_dia->undo);
151 } else {
152 message_warning(_("This object doesn't support Undo/Redo.\n"
153 "Undo information erased."));
154 undo_clear(current_dia->undo);
157 diagram_flush(current_dia);
161 if (response_id != GTK_RESPONSE_APPLY)
162 gtk_widget_hide(widget);
164 return 0;
167 void
168 properties_show(Diagram *dia, DiaObject *obj)
170 GtkWidget *properties = NULL;
172 if (obj != NULL)
173 properties = obj->ops->get_properties(obj, FALSE);
175 if (dialog == NULL)
176 create_dialog();
178 if (obj==NULL) {
179 /* Hide dialog when no object is selected */
180 gtk_widget_hide(dialog);
181 return;
184 if (properties == NULL) { /* No properties or no object */
185 properties = no_properties_dialog;
186 obj = NULL;
187 dia = NULL;
190 if (object_part != NULL) {
191 gtk_container_remove(GTK_CONTAINER(dialog_vbox), object_part);
192 object_part = NULL;
193 current_obj = NULL;
194 current_dia = NULL;
197 if (obj != NULL) {
198 DiaObjectType *otype;
199 gchar *buf;
201 otype = obj->type;
202 buf = g_strconcat(_("Properties: "), otype->name, NULL);
203 gtk_window_set_title(GTK_WINDOW(dialog), buf);
204 g_free(buf);
205 } else {
206 gtk_window_set_title(GTK_WINDOW(dialog), _("Object properties:"));
209 g_signal_connect (G_OBJECT (properties), "destroy",
210 G_CALLBACK(properties_part_destroyed), NULL);
211 g_signal_connect (G_OBJECT (dialog), "destroy",
212 G_CALLBACK(properties_dialog_destroyed), NULL);
214 gtk_box_pack_start(GTK_BOX(dialog_vbox), properties, TRUE, TRUE, 0);
216 gtk_widget_show (properties);
218 if (obj != current_obj)
219 gtk_window_resize (GTK_WINDOW(dialog), 1, 1); /* resize to minimum */
220 gtk_window_set_transient_for(GTK_WINDOW(dialog),
221 GTK_WINDOW (ddisplay_active()->shell));
222 gtk_window_present (GTK_WINDOW (dialog));
223 object_part = properties;
224 current_obj = obj;
225 current_dia = dia;
228 void
229 properties_hide_if_shown(Diagram *dia, DiaObject *obj)
231 if (current_obj == obj) {
232 properties_show(dia, NULL);
236 void
237 properties_update_if_shown(Diagram *dia, DiaObject *obj)
239 if (current_obj == obj) {
240 properties_show(dia, obj);