1 /* Modified version of gnome-propertybox from gnome-libs-1.4 */
2 /* Primarily removed the "help" button and changed the names.*/
3 /* -Jim Evins 11/25/2001 */
5 /* gnome-propertybox.c - Property dialog box.
7 Copyright (C) 1998 Tom Tromey
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License
11 as published by the Free Software Foundation; either version 2, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public
20 License along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 /* Note that the property box is constructed so that we could later
25 change how the buttons work. For instance, we could put an Apply
26 button inside each page; this kind of Apply button would only
27 affect the current page. Please do not change the API in a way
28 that would violate this goal. */
32 #include "propertybox.h"
33 #include <libgnome/gnome-util.h>
34 #include <libgnomeui/gnome-stock.h>
35 #include <libgnome/gnome-config.h>
37 #include <libgnomeui/gnome-preferences.h>
44 typedef void (*glPropertyBoxSignal) (GtkObject * object,
48 static void gl_property_box_class_init (glPropertyBoxClass * klass);
49 static void gl_property_box_init (glPropertyBox * property_box);
50 static void gl_property_box_marshal_signal (GtkObject * object,
54 static void gl_property_box_destroy (GtkObject * object);
57 * These four are called from dialog_clicked_cb(), depending
58 * on which button was clicked.
60 static void global_apply (glPropertyBox * property_box);
61 static void apply_and_close (glPropertyBox * property_box);
62 static void just_close (glPropertyBox * property_box);
64 static void dialog_clicked_cb (GnomeDialog * dialog,
68 static GnomeDialogClass *parent_class = NULL;
70 static gint property_box_signals[LAST_SIGNAL] = { 0 };
73 * gl_property_box_get_type:
75 * Internal routine that returns the GtkType of the
76 * glPropertyBox widget
79 gl_property_box_get_type (void)
81 static guint property_box_type = 0;
83 if (!property_box_type) {
84 GtkTypeInfo property_box_info = {
86 sizeof (glPropertyBox),
87 sizeof (glPropertyBoxClass),
88 (GtkClassInitFunc) gl_property_box_class_init,
89 (GtkObjectInitFunc) gl_property_box_init,
94 property_box_type = gtk_type_unique (gnome_dialog_get_type (),
98 return property_box_type;
102 gl_property_box_class_init (glPropertyBoxClass * klass)
104 GtkObjectClass *object_class;
105 GtkWidgetClass *widget_class;
106 GtkWindowClass *window_class;
108 object_class = (GtkObjectClass *) klass;
109 widget_class = (GtkWidgetClass *) klass;
110 window_class = (GtkWindowClass *) klass;
112 object_class->destroy = gl_property_box_destroy;
114 parent_class = gtk_type_class (gnome_dialog_get_type ());
116 property_box_signals[APPLY] =
117 gtk_signal_new ("apply",
120 GTK_SIGNAL_OFFSET (glPropertyBoxClass,
122 gl_property_box_marshal_signal,
123 GTK_TYPE_NONE, 1, GTK_TYPE_INT);
125 gtk_object_class_add_signals (object_class, property_box_signals,
132 gl_property_box_marshal_signal (GtkObject * object,
137 glPropertyBoxSignal rfunc;
139 rfunc = (glPropertyBoxSignal) func;
140 (*rfunc) (object, GTK_VALUE_INT (args[0]), func_data);
144 gl_property_box_init (glPropertyBox * property_box)
148 property_box->notebook = gtk_notebook_new ();
150 if (gnome_preferences_get_property_box_apply ()) {
151 gnome_dialog_append_buttons (GNOME_DIALOG (property_box),
152 GNOME_STOCK_BUTTON_OK,
153 GNOME_STOCK_BUTTON_APPLY,
154 GNOME_STOCK_BUTTON_CLOSE, NULL);
156 gnome_dialog_append_buttons (GNOME_DIALOG (property_box),
157 GNOME_STOCK_BUTTON_OK,
158 GNOME_STOCK_BUTTON_CANCEL, NULL);
161 gnome_dialog_set_default (GNOME_DIALOG (property_box), 0);
163 /* This is sort of unattractive */
165 button_list = GNOME_DIALOG (property_box)->buttons;
167 property_box->ok_button = GTK_WIDGET (button_list->data);
168 button_list = button_list->next;
170 if (gnome_preferences_get_property_box_apply ()) {
171 property_box->apply_button = GTK_WIDGET (button_list->data);
172 button_list = button_list->next;
173 gtk_widget_set_sensitive (property_box->apply_button, FALSE);
175 property_box->apply_button = 0;
177 property_box->cancel_button = GTK_WIDGET (button_list->data);
178 button_list = button_list->next;
180 gtk_signal_connect (GTK_OBJECT (property_box), "clicked",
181 GTK_SIGNAL_FUNC (dialog_clicked_cb), NULL);
183 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (property_box)->vbox),
184 property_box->notebook, TRUE, TRUE, 0);
186 gtk_widget_show (property_box->notebook);
190 gl_property_box_destroy (GtkObject * object)
192 glPropertyBox *property_box;
194 g_return_if_fail (object != NULL);
195 g_return_if_fail (GL_IS_PROPERTY_BOX (object));
197 property_box = GL_PROPERTY_BOX (object);
199 GTK_OBJECT_CLASS (parent_class)->destroy (object);
203 * gl_property_box_new: [constructor]
205 * Creates a new glPropertyBox widget. The PropertyBox widget
206 * is useful for making consistent configuration dialog boxes.
208 * When a setting has been made to a property in the PropertyBox
209 * your program needs to invoke the gl_property_box_changed to signal
210 * a change (this will enable the Ok/Apply buttons).
212 * Returns a newly created glPropertyBox widget.
215 gl_property_box_new (void)
217 return gtk_type_new (gl_property_box_get_type ());
221 dialog_clicked_cb (GnomeDialog * dialog,
228 gboolean dirty = FALSE;
230 g_return_if_fail (dialog != NULL);
231 g_return_if_fail (GL_IS_PROPERTY_BOX (dialog));
233 pbox = GL_PROPERTY_BOX (dialog);
235 if (GTK_NOTEBOOK (pbox->notebook)->cur_page != NULL) {
237 for (list = GTK_NOTEBOOK (pbox->notebook)->children;
238 list != NULL; list = list->next) {
239 GtkNotebookPage *page = list->data;
240 g_assert (page != NULL);
243 GPOINTER_TO_INT (gtk_object_get_data
244 (GTK_OBJECT (page->child),
245 GL_PROPERTY_BOX_DIRTY));
255 /* Choose which style we did */
256 if (pbox->apply_button) {
260 apply_and_close (GL_PROPERTY_BOX (dialog));
262 just_close (GL_PROPERTY_BOX (dialog));
265 global_apply (GL_PROPERTY_BOX (dialog));
268 just_close (GL_PROPERTY_BOX (dialog));
271 g_assert_not_reached ();
277 apply_and_close (GL_PROPERTY_BOX (dialog));
279 just_close (GL_PROPERTY_BOX (dialog));
282 just_close (GL_PROPERTY_BOX (dialog));
285 g_assert_not_reached ();
291 set_sensitive (glPropertyBox * property_box,
294 if (property_box->apply_button)
295 gtk_widget_set_sensitive (property_box->apply_button, dirty);
299 * gl_property_box_changed:
300 * @property_box: The glPropertyBox that contains the changed data
302 * When a setting has changed, the code needs to invoke this routine
303 * to make the Ok/Apply buttons sensitive.
306 gl_property_box_changed (glPropertyBox * property_box)
310 g_return_if_fail (property_box != NULL);
311 g_return_if_fail (GL_IS_PROPERTY_BOX (property_box));
312 g_return_if_fail (property_box->notebook);
313 g_return_if_fail (GTK_NOTEBOOK (property_box->notebook)->cur_page);
315 page = GTK_NOTEBOOK (property_box->notebook)->cur_page->child;
316 g_assert (page != NULL);
318 gtk_object_set_data (GTK_OBJECT (page),
319 GL_PROPERTY_BOX_DIRTY, GINT_TO_POINTER (1));
321 set_sensitive (property_box, 1);
325 * gl_property_box_set_modified:
326 * @property_box: The glPropertyBox that contains the changed data
327 * @state: The state. TRUE means modified, FALSE means unmodified.
329 * This sets the modified flag of the glPropertyBox to the value in @state.
330 * Affects whether the OK/Apply buttons are sensitive.
333 gl_property_box_set_modified (glPropertyBox * property_box,
338 g_return_if_fail (property_box != NULL);
339 g_return_if_fail (GL_IS_PROPERTY_BOX (property_box));
340 g_return_if_fail (property_box->notebook);
341 g_return_if_fail (GTK_NOTEBOOK (property_box->notebook)->cur_page);
343 page = GTK_NOTEBOOK (property_box->notebook)->cur_page->child;
344 g_assert (page != NULL);
346 gtk_object_set_data (GTK_OBJECT (page),
347 GL_PROPERTY_BOX_DIRTY,
348 GINT_TO_POINTER (state ? 1 : 0));
350 set_sensitive (property_box, state);
354 global_apply (glPropertyBox * property_box)
359 g_return_if_fail (GTK_NOTEBOOK (property_box->notebook)->children !=
362 for (list = GTK_NOTEBOOK (property_box->notebook)->children, n = 0;
363 list != NULL; list = g_list_next (list), n++) {
364 /* FIXME: there should be a way to report an error
365 during Apply. That way we could prevent closing
366 the window if there were a problem. */
367 GtkNotebookPage *page = list->data;
368 if (gtk_object_get_data (GTK_OBJECT (page->child),
369 GL_PROPERTY_BOX_DIRTY)) {
370 gtk_signal_emit (GTK_OBJECT (property_box),
371 property_box_signals[APPLY], n);
372 gtk_object_set_data (GTK_OBJECT (page->child),
373 GL_PROPERTY_BOX_DIRTY,
374 GINT_TO_POINTER (0));
378 /* Emit an apply signal with a button of -1. This means we
379 just finished a global apply. Is this a hack? */
380 gtk_signal_emit (GTK_OBJECT (property_box),
381 property_box_signals[APPLY], (gint) - 1);
383 /* Doesn't matter which item we use. */
384 set_sensitive (property_box, 0);
388 just_close (glPropertyBox * property_box)
390 gnome_dialog_close (GNOME_DIALOG (property_box));
394 apply_and_close (glPropertyBox * property_box)
396 global_apply (property_box);
397 just_close (property_box);
401 * gl_property_box_append_page:
402 * @property_box: The property box where we are inserting a new page
403 * @child: The widget that is being inserted
404 * @tab_label: The widget used as the label for this confiugration page
406 * Appends a new page to the glPropertyBox.
408 * Returns the assigned index of the page inside the glPropertyBox or
409 * -1 if one of the arguments is invalid.
412 gl_property_box_append_page (glPropertyBox * property_box,
414 GtkWidget * tab_label)
416 g_return_val_if_fail (property_box != NULL, -1);
417 g_return_val_if_fail (GL_IS_PROPERTY_BOX (property_box), -1);
418 g_return_val_if_fail (child != NULL, -1);
419 g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
420 g_return_val_if_fail (tab_label != NULL, -1);
421 g_return_val_if_fail (GTK_IS_WIDGET (tab_label), -1);
423 gtk_notebook_append_page (GTK_NOTEBOOK (property_box->notebook),
426 return g_list_length (GTK_NOTEBOOK (property_box->notebook)->children) -