Updated Spanish translation
[anjuta-git-plugin.git] / libanjuta / anjuta-preferences.c
blob13b1cdf767643ca394c314fce9f68be695042400
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * preferences.c
4 * Copyright (C) 2000 - 2003 Naba Kumar <naba@gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /**
22 * SECTION:anjuta-preferences
23 * @short_description: Anjuta Prefereces system.
24 * @see_also: #AnjutaPreferencesDialog
25 * @stability: Unstable
26 * @include: libanjuta/anjuta-preferences.h
28 * #AnjutaPreferences is a way to let plugins register their preferences. There
29 * are mainly two ways a plugin could register its preferences in Anjuta.
31 * First is to not use #AnjutaPreferences at all. Simply register a
32 * preferences page in #AnjutaPreferencesDialog using the function
33 * anjuta_preferences_dialog_add_page(). The plugin should take
34 * care of loading, saving and widgets synchronization of the
35 * preferences values. It is particularly useful if the plugin
36 * uses gconf system for its preferences. Also no "changed"
37 * signal will be emitted from it.
39 * Second is to use anjuta_preferences_add_page(), which will
40 * automatically register the preferences keys and values from
41 * a glade xml file. The glade xml file contains a preferences
42 * page of the plugin. The widget names in the page are
43 * given in a particular way (see anjuta_preferences_add_page()) to
44 * let it know property key details. Loading, saving and
45 * widget synchronization are automatically done. "changed" signal is
46 * emitted when a preference is changed.
48 * anjuta_preferences_register_all_properties_from_glade_xml() only registers
49 * the preferences propery keys for automatic loading, saving and widget
50 * syncrhronization, but does not add the page in preferences dialog. It
51 * is useful if the plugin wants to show the preferences page somewhere else.
53 * anjuta_preferences_register_property_from_string() is similar to
54 * anjuta_preferences_register_all_properties_from_glade_xml(), but it only
55 * registers one property, the detail of which is given in its arguments.
56 * anjuta_preferences_register_property_custom() is used to register a
57 * property that uses a widget which is not supported by #AnjutaPreferences.
60 #ifdef HAVE_CONFIG_H
61 # include <config.h>
62 #endif
64 #include <sys/stat.h>
65 #include <unistd.h>
66 #include <string.h>
68 #include <glade/glade-parser.h>
69 #include <gconf/gconf-client.h>
71 #include <libanjuta/anjuta-preferences.h>
72 #include <libanjuta/anjuta-utils.h>
73 #include <libanjuta/resources.h>
74 #include <libanjuta/anjuta-debug.h>
75 #include <libanjuta/interfaces/ianjuta-preferences.h>
77 struct _AnjutaProperty
79 GtkWidget *object;
80 gchar *key;
81 gchar *default_value;
82 guint flags;
83 gint notify_id;
84 GConfClient *gclient;
86 /* Set true if custom set/get to be used */
87 gboolean custom;
89 /* For inbuilt generic objects */
90 AnjutaPropertyObjectType object_type;
91 AnjutaPropertyDataType data_type;
93 /* For custom objects */
94 void (*set_property) (AnjutaProperty *prop, const gchar *value);
95 gchar * (*get_property) (AnjutaProperty *prop);
99 struct _AnjutaPreferencesPriv
101 GConfClient *gclient;
102 GHashTable *properties;
103 GtkWidget *prefs_dialog;
104 AnjutaPluginManager *plugin_manager;
105 gboolean is_showing;
108 /* Internal structure for anjuta_preferences_foreach */
109 struct _AnjutaPreferencesForeachData
111 AnjutaPreferences *pr;
112 AnjutaPreferencesFilterType filter;
113 AnjutaPreferencesCallback callback;
114 gpointer callback_data;
117 #define PREFERENCE_PROPERTY_PREFIX "preferences_"
118 #define GCONF_KEY_PREFIX "/apps/anjuta/preferences"
120 static const gchar *
121 build_key (const gchar *key)
123 static gchar buffer[1024];
124 snprintf (buffer, 1024, "%s/%s", GCONF_KEY_PREFIX, key);
125 return buffer;
129 * anjuta_preferences_get:
130 * @pr: A #AnjutaPreferences object
131 * @key: Property key
133 * Gets the value of @key as string. Returned string should be g_freed() when not
134 * required.
136 * Return value: Key value as string or NULL if the key is not defined.
138 #ifdef __GNUC__
139 inline
140 #endif
141 gchar *
142 anjuta_preferences_get (AnjutaPreferences *pr, const gchar *key)
144 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), NULL);
145 g_return_val_if_fail (key != NULL, NULL);
147 return gconf_client_get_string (pr->priv->gclient, build_key (key), NULL);
151 * anjuta_preferences_get_list:
152 * @pr: A #AnjutaPreferences object
153 * @key: Property key
154 * @list_type: Type of each list element
156 * Gets the list of @key.
158 * Return value: Key list or NULL if the key is not defined.
160 #ifdef __GNUC__
161 inline
162 #endif
163 GSList *
164 anjuta_preferences_get_list (AnjutaPreferences *pr, const gchar *key,
165 GConfValueType list_type)
167 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), NULL);
168 g_return_val_if_fail (key != NULL, NULL);
170 return gconf_client_get_list(pr->priv->gclient, build_key (key), list_type, NULL);
174 * anjuta_preferences_get_pair:
175 * @pr: A #AnjutaPreferences object
176 * @key: Property key
177 * @car_type: Desired type of the pair's first field (car).
178 * @cdr_type: Desired type of the pair's second field (cdr).
179 * @car_retloc: Address of a return location for the car.
180 * @cdr_retloc: Address of a return location for the cdr.
182 * Gets the pair of @key.
184 * Return value: TRUE or FALSE.
186 #ifdef __GNUC__
187 inline
188 #endif
189 gboolean
190 anjuta_preferences_get_pair (AnjutaPreferences *pr, const gchar *key,
191 GConfValueType car_type, GConfValueType cdr_type,
192 gpointer car_retloc, gpointer cdr_retloc)
194 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), FALSE);
195 g_return_val_if_fail (key != NULL, FALSE);
197 return gconf_client_get_pair(pr->priv->gclient, build_key (key),
198 car_type, cdr_type,
199 car_retloc, cdr_retloc, NULL);
203 * anjuta_preferences_get_int:
204 * @pr: A #AnjutaPreferences object
205 * @key: Property key
207 * Gets the value of @key as integer.
209 * Return value: Key value as integer or 0 if the key is not defined.
211 #ifdef __GNUC__
212 inline
213 #endif
214 gint
215 anjuta_preferences_get_int (AnjutaPreferences *pr, const gchar *key)
217 gint ret_val;
218 GConfValue *value;
220 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), 0);
221 g_return_val_if_fail (key != NULL, 0);
223 ret_val = 0;
224 value = gconf_client_get (pr->priv->gclient, build_key (key), NULL);
225 if (value)
227 switch (value->type)
229 case GCONF_VALUE_INT:
230 ret_val = gconf_value_get_int (value);
231 break;
232 case GCONF_VALUE_BOOL:
233 ret_val = gconf_value_get_bool (value);
234 break;
235 default:
236 g_warning ("Invalid gconf type for key: %s", key);
238 gconf_value_free (value);
240 /* else
241 g_warning ("The preference key %s is not defined", key); */
242 return ret_val;
246 * anjuta_preferences_get_int_with_default:
247 * @pr: A #AnjutaPreferences object
248 * @key: Property key
249 * @default_value: Default value to return if the key is not defined.
251 * Gets the value of @key as integer.
253 * Return value: Key value as integer or @default_value if the
254 * key is not defined.
256 #ifdef __GNUC__
257 inline
258 #endif
259 gint
260 anjuta_preferences_get_int_with_default (AnjutaPreferences *pr,
261 const gchar *key, gint default_value)
263 gint ret_val;
264 GConfValue *value;
266 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), 0);
267 g_return_val_if_fail (key != NULL, 0);
269 ret_val = default_value;
270 value = gconf_client_get (pr->priv->gclient, build_key (key), NULL);
271 if (value)
273 switch (value->type)
275 case GCONF_VALUE_INT:
276 ret_val = gconf_value_get_int (value);
277 break;
278 case GCONF_VALUE_BOOL:
279 ret_val = gconf_value_get_bool (value);
280 break;
281 default:
282 g_warning ("Invalid gconf type for key: %s", key);
284 gconf_value_free (value);
286 return ret_val;
290 * anjuta_preferences_default_get:
291 * @pr: A #AnjutaPreferences object
292 * @key: Property key
294 * Gets the default value of @key as string. The default value of the key
295 * is the value defined in System defaults (generally installed during
296 * program installation). Returned value must be g_freed() when not required.
298 * Return value: Default key value as string or NULL if not defined.
300 #ifdef __GNUC__
301 inline
302 #endif
303 gchar *
304 anjuta_preferences_default_get (AnjutaPreferences * pr, const gchar * key)
306 GConfValue *val;
307 gchar *str;
308 GError *err = NULL;
310 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), NULL);
311 g_return_val_if_fail (key != NULL, NULL);
313 val = gconf_client_get_default_from_schema (pr->priv->gclient, build_key (key), &err);
314 if (err) {
315 g_error_free (err);
316 return NULL;
318 str = g_strdup (gconf_value_get_string (val));
319 gconf_value_free (val);
320 return str;
324 * anjuta_preferences_default_get_int:
325 * @pr: A #AnjutaPreferences object
326 * @key: Property key
328 * Gets the default value of @key as integer. The default value of the key
329 * is the value defined in System defaults (generally installed during
330 * program installation).
332 * Return value: Default key value as integer or 0 if the key is not defined.
334 #ifdef __GNUC__
335 inline
336 #endif
337 gint
338 anjuta_preferences_default_get_int (AnjutaPreferences *pr, const gchar *key)
340 GConfValue *val;
341 gint ret;
342 GError *err = NULL;
344 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), 0);
345 g_return_val_if_fail (key != NULL, 0);
346 val = gconf_client_get_default_from_schema (pr->priv->gclient, build_key (key), &err);
347 if (err) {
348 g_error_free (err);
349 return 0;
351 ret = gconf_value_get_int (val);
352 gconf_value_free (val);
353 return ret;
357 * anjuta_preferences_set:
358 * @pr: A #AnjutaPreferences object.
359 * @key: Property key.
360 * @value: Value of the key.
362 * Sets the value of @key in current session.
364 #ifdef __GNUC__
365 inline
366 #endif
367 void
368 anjuta_preferences_set (AnjutaPreferences *pr, const gchar *key,
369 const gchar *value)
371 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
372 g_return_if_fail (key != NULL);
374 if (value && (strlen (value) > 0))
376 gconf_client_set_string (pr->priv->gclient, build_key (key), value, NULL);
378 else
380 gconf_client_set_string (pr->priv->gclient, build_key (key), "", NULL);
385 * anjuta_preferences_set_list:
386 * @pr: A #AnjutaPreferences object.
387 * @key: Property key.
388 * @list_type: Type of each element.
389 * @list: New value of the key.
391 * Sets a list in current session.
393 #ifdef __GNUC__
394 inline
395 #endif
396 void
397 anjuta_preferences_set_list (AnjutaPreferences *pr, const gchar *key,
398 GConfValueType list_type, GSList *list)
400 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
401 g_return_if_fail (key != NULL);
403 gconf_client_set_list(pr->priv->gclient, build_key (key),
404 list_type, list, NULL);
408 * anjuta_preferences_set_pair:
409 * @pr: A #AnjutaPreferences object.
410 * @key: Property key.
411 * @car_type: Type of the pair's first field (car).
412 * @cdr_type: Type of the pair's second field (cdr).
413 * @address_of_car: Address of the car.
414 * @address_of_cdr: Address of the cdr.
417 #ifdef __GNUC__
418 inline
419 #endif
420 gboolean
421 anjuta_preferences_set_pair (AnjutaPreferences *pr, const gchar *key,
422 GConfValueType car_type, GConfValueType cdr_type,
423 gconstpointer address_of_car,
424 gconstpointer address_of_cdr)
426 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), FALSE);
427 g_return_val_if_fail (key != NULL, FALSE);
429 return gconf_client_set_pair (pr->priv->gclient, build_key (key),
430 car_type, cdr_type,
431 address_of_car, address_of_cdr,
432 NULL);
436 * anjuta_preferences_set_int:
437 * @pr: A #AnjutaPreferences object.
438 * @key: Property key.
439 * @value: Integer value of the key.
441 * Sets the value of @key in current session.
443 #ifdef __GNUC__
444 inline
445 #endif
446 void
447 anjuta_preferences_set_int (AnjutaPreferences *pr, const gchar *key,
448 gint value)
450 GConfValue *gvalue;
452 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
453 g_return_if_fail (key != NULL);
455 gvalue = gconf_client_get (pr->priv->gclient, build_key (key), NULL);
456 if (gvalue)
458 switch (gvalue->type)
460 case GCONF_VALUE_BOOL:
461 gconf_client_set_bool (pr->priv->gclient, build_key (key),
462 value, NULL);
463 break;
464 case GCONF_VALUE_INT:
465 gconf_client_set_int (pr->priv->gclient, build_key (key),
466 value, NULL);
467 break;
468 default:
469 g_warning ("Invalid gconf type for key: %s", key);
471 gconf_value_free (gvalue);
473 else
475 /* g_warning ("The preference key %s is not defined", key); */
476 gconf_client_set_int (pr->priv->gclient, build_key (key),
477 value, NULL);
481 static void
482 property_destroy (AnjutaProperty *property)
484 g_return_if_fail (property);
485 if (property->key) g_free (property->key);
486 if (property->default_value) g_free (property->default_value);
487 g_object_unref (property->object);
488 gconf_client_notify_remove (property->gclient, property->notify_id);
489 g_free (property);
493 * anjuta_property_get_widget:
494 * @prop: an #AnjutaProperty reference
496 * Gets the widget associated with the property.
498 * Returns: a #GtkWidget object associated with the property.
500 GtkWidget*
501 anjuta_property_get_widget (AnjutaProperty *prop)
503 return prop->object;
506 static AnjutaPropertyObjectType
507 get_object_type_from_string (const gchar* object_type)
509 if (strcmp (object_type, "entry") == 0)
510 return ANJUTA_PROPERTY_OBJECT_TYPE_ENTRY;
511 else if (strcmp (object_type, "combo") == 0)
512 return ANJUTA_PROPERTY_OBJECT_TYPE_COMBO;
513 else if (strcmp (object_type, "spin") == 0)
514 return ANJUTA_PROPERTY_OBJECT_TYPE_SPIN;
515 else if (strcmp (object_type, "toggle") == 0)
516 return ANJUTA_PROPERTY_OBJECT_TYPE_TOGGLE;
517 else if (strcmp (object_type, "text") == 0)
518 return ANJUTA_PROPERTY_OBJECT_TYPE_TEXT;
519 else if (strcmp (object_type, "color") == 0)
520 return ANJUTA_PROPERTY_OBJECT_TYPE_COLOR;
521 else if (strcmp (object_type, "font") == 0)
522 return ANJUTA_PROPERTY_OBJECT_TYPE_FONT;
523 else if (strcmp (object_type, "file") == 0)
524 return ANJUTA_PROPERTY_OBJECT_TYPE_FILE;
525 else if (strcmp (object_type, "folder") == 0)
526 return ANJUTA_PROPERTY_OBJECT_TYPE_FOLDER;
527 else
528 return (AnjutaPropertyObjectType)(-1);
531 static AnjutaPropertyDataType
532 get_data_type_from_string (const gchar* data_type)
534 if (strcmp (data_type, "bool") == 0)
535 return ANJUTA_PROPERTY_DATA_TYPE_BOOL;
536 else if (strcmp (data_type, "int") == 0)
537 return ANJUTA_PROPERTY_DATA_TYPE_INT;
538 else if (strcmp (data_type, "text") == 0)
539 return ANJUTA_PROPERTY_DATA_TYPE_TEXT;
540 else if (strcmp (data_type, "color") == 0)
541 return ANJUTA_PROPERTY_DATA_TYPE_COLOR;
542 else if (strcmp (data_type, "font") == 0)
543 return ANJUTA_PROPERTY_DATA_TYPE_FONT;
544 else
545 return (AnjutaPropertyDataType)(-1);
548 static gchar*
549 get_property_value_as_string (AnjutaProperty *prop)
551 gint int_value;
552 gchar** values;
553 gchar *text_value = NULL;
555 if (prop->custom)
557 if (prop->get_property != NULL)
558 return prop->get_property (prop);
559 else
561 g_warning ("%s: Undefined get_property() for custom object",
562 prop->key);
563 return NULL;
566 switch (prop->object_type)
568 case ANJUTA_PROPERTY_OBJECT_TYPE_TOGGLE:
569 int_value =
570 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->object));
571 text_value = g_strdup_printf ("%d", int_value);
572 break;
574 case ANJUTA_PROPERTY_OBJECT_TYPE_SPIN:
575 int_value =
576 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (prop->object));
577 text_value = g_strdup_printf ("%d", int_value);
578 break;
580 case ANJUTA_PROPERTY_OBJECT_TYPE_ENTRY:
581 text_value =
582 gtk_editable_get_chars (GTK_EDITABLE (prop->object), 0, -1);
583 break;
584 case ANJUTA_PROPERTY_OBJECT_TYPE_COMBO:
586 gint idx;
587 values = g_object_get_data(G_OBJECT(prop->object), "untranslated");
588 idx = gtk_combo_box_get_active(GTK_COMBO_BOX(prop->object));
589 if (values[idx] != NULL)
590 text_value = g_strdup(values[idx]);
591 break;
593 case ANJUTA_PROPERTY_OBJECT_TYPE_TEXT:
595 GtkTextBuffer *buffer;
596 GtkTextIter start_iter;
597 GtkTextIter end_iter;
598 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (prop->object));
599 gtk_text_buffer_get_start_iter (buffer, &start_iter);
600 gtk_text_buffer_get_end_iter (buffer, &end_iter);
601 text_value =
602 gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, TRUE);
603 break;
605 case ANJUTA_PROPERTY_OBJECT_TYPE_COLOR:
607 GdkColor color;
608 gtk_color_button_get_color(GTK_COLOR_BUTTON (prop->object),
609 &color);
610 text_value = anjuta_util_string_from_color (color.red, color.green, color.blue);
612 break;
613 case ANJUTA_PROPERTY_OBJECT_TYPE_FONT:
615 const gchar *font;
616 font = gtk_font_button_get_font_name (GTK_FONT_BUTTON
617 (prop->object));
618 text_value = g_strdup (font);
620 break;
621 case ANJUTA_PROPERTY_OBJECT_TYPE_FOLDER:
622 text_value = gtk_file_chooser_get_current_folder (
623 GTK_FILE_CHOOSER (prop->object));
624 break;
625 case ANJUTA_PROPERTY_OBJECT_TYPE_FILE:
626 text_value = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (prop->object));
627 break;
629 if (text_value && (strlen (text_value) == 0))
631 g_free (text_value);
632 text_value = NULL;
634 return text_value;
637 static gint
638 get_property_value_as_int (AnjutaProperty *prop)
640 gint int_value;
641 gchar *text_value;
642 text_value = get_property_value_as_string (prop);
643 int_value = atoi (text_value);
644 g_free (text_value);
645 return int_value;
648 static void
649 set_property_value_as_string (AnjutaProperty *prop, const gchar *value)
651 gint int_value;
652 char** values;
653 gint i;
655 if (prop->custom)
657 if (prop->set_property != NULL)
659 prop->set_property (prop, value);
660 return;
662 else
664 g_warning ("%s: Undefined set_property() for custom object",
665 prop->key);
666 return;
669 switch (prop->object_type)
671 case ANJUTA_PROPERTY_OBJECT_TYPE_TOGGLE:
672 if (value)
673 int_value = atoi (value);
674 else
675 int_value = 0;
677 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->object),
678 int_value);
679 break;
681 case ANJUTA_PROPERTY_OBJECT_TYPE_SPIN:
682 if (value)
683 int_value = atoi (value);
684 else
685 int_value = 0;
687 gtk_spin_button_set_value (GTK_SPIN_BUTTON (prop->object), int_value);
688 break;
690 case ANJUTA_PROPERTY_OBJECT_TYPE_ENTRY:
691 if (value)
692 gtk_entry_set_text (GTK_ENTRY (prop->object), value);
693 else
694 gtk_entry_set_text (GTK_ENTRY (prop->object), "");
695 break;
696 case ANJUTA_PROPERTY_OBJECT_TYPE_COMBO:
697 values = g_object_get_data(G_OBJECT(prop->object), "untranslated");
698 if (value != NULL)
700 for (i=0; values[i] != NULL; i++)
702 if (strcmp(value, values[i]) == 0)
704 gtk_combo_box_set_active(GTK_COMBO_BOX(prop->object), i);
705 break;
709 break;
710 case ANJUTA_PROPERTY_OBJECT_TYPE_TEXT:
712 GtkTextBuffer *buffer;
713 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (prop->object));
714 if (value)
715 gtk_text_buffer_set_text (buffer, value, -1);
716 else
717 gtk_text_buffer_set_text (buffer, "", -1);
719 break;
721 case ANJUTA_PROPERTY_OBJECT_TYPE_COLOR:
723 GdkColor color;
725 if (value)
726 anjuta_util_color_from_string (value, &color.red, &color.green, &color.blue);
728 gtk_color_button_set_color(GTK_COLOR_BUTTON(prop->object), &color);
730 break;
732 case ANJUTA_PROPERTY_OBJECT_TYPE_FONT:
733 if (value)
735 /* If the font name is Xfont name, convert it into
736 Pango font description text -- Just take the family name :) */
737 if (value[0] == '-')
739 /* Font is xfont name */
740 gchar *font_name, *tmp;
741 const gchar *end, *start;
742 start = value;
743 start = g_strstr_len (&start[1], strlen (&start[1]), "-");
744 end = g_strstr_len (&start[1], strlen (&start[1]), "-");
745 font_name = g_strndup (&start[1], end-start-1);
746 tmp = font_name;
748 /* Set font size to (arbitrary) 12 points */
749 font_name = g_strconcat (tmp, " 12", NULL);
750 g_free (tmp);
752 /* DEBUG_PRINT ("Font set as: %s", font_name); */
754 gtk_font_button_set_font_name (GTK_FONT_BUTTON
755 (prop->object), font_name);
756 g_free (font_name);
758 else
760 gtk_font_button_set_font_name (GTK_FONT_BUTTON
761 (prop->object), value);
764 /* FIXME: Set a standard font as default.
765 else
767 gnome_font_picker_set_font_name (GNOME_FONT_PICKER (prop->object),
768 "A standard font");
770 break;
772 case ANJUTA_PROPERTY_OBJECT_TYPE_FOLDER:
773 if (value)
774 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (prop->object), value);
775 break;
776 case ANJUTA_PROPERTY_OBJECT_TYPE_FILE:
777 if (value)
779 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (prop->object),
780 value);
782 break;
786 static void
787 set_property_value_as_int (AnjutaProperty *prop, gint value)
789 gchar *text_value;
790 text_value = g_strdup_printf ("%d", value);
791 set_property_value_as_string (prop, text_value);
792 g_free (text_value);
795 static gboolean
796 update_property_on_event_str (GtkWidget *widget, GdkEvent *event,
797 gpointer user_data)
799 AnjutaPreferences *pr;
800 AnjutaProperty *p;
801 gchar *val;
803 pr = ANJUTA_PREFERENCES (g_object_get_data (G_OBJECT (widget),
804 "AnjutaPreferences"));
805 p = (AnjutaProperty *) user_data;
806 val = get_property_value_as_string (p);
807 anjuta_preferences_set (pr, p->key, val);
808 g_free (val);
809 return FALSE;
812 static void
813 update_property_on_change_str (GtkWidget *widget, gpointer user_data)
815 AnjutaPreferences *pr;
816 AnjutaProperty *p;
817 gchar *val;
819 pr = ANJUTA_PREFERENCES (g_object_get_data (G_OBJECT (widget),
820 "AnjutaPreferences"));
821 p = (AnjutaProperty *) user_data;
822 val = get_property_value_as_string (p);
823 anjuta_preferences_set (pr, p->key, val);
824 g_free (val);
827 static gboolean
828 block_update_property_on_change_str (GtkWidget *widget, GdkEvent *event,
829 gpointer user_data)
831 AnjutaProperty *p = (AnjutaProperty *) user_data;
833 gtk_signal_handler_block_by_func (GTK_OBJECT(p->object), G_CALLBACK (update_property_on_change_str), p);
834 return FALSE;
837 static gboolean
838 unblock_update_property_on_change_str (GtkWidget *widget, GdkEvent *event,
839 gpointer user_data)
841 AnjutaProperty *p = (AnjutaProperty *) user_data;
843 gtk_signal_handler_unblock_by_func (GTK_OBJECT(p->object), G_CALLBACK (update_property_on_change_str), p);
844 return FALSE;
847 static void
848 update_property_on_change_int (GtkWidget *widget, gpointer user_data)
850 AnjutaPreferences *pr;
851 AnjutaProperty *p;
852 gint val;
854 pr = ANJUTA_PREFERENCES (g_object_get_data (G_OBJECT (widget),
855 "AnjutaPreferences"));
856 p = (AnjutaProperty *) user_data;
857 val = get_property_value_as_int (p);
858 anjuta_preferences_set_int (pr, p->key, val);
861 static void
862 update_property_on_change_color (GtkWidget *widget, gpointer user_data)
864 AnjutaPreferences *pr;
865 AnjutaProperty *p;
866 gchar *val;
868 pr = ANJUTA_PREFERENCES (g_object_get_data (G_OBJECT (widget),
869 "AnjutaPreferences"));
870 p = (AnjutaProperty *) user_data;
871 val = get_property_value_as_string (p);
872 anjuta_preferences_set (pr, p->key, val);
873 g_free (val);
876 static void
877 update_property_on_change_font (GtkWidget *widget,
878 gpointer user_data)
880 AnjutaPreferences *pr;
881 AnjutaProperty *p;
882 gchar *val;
884 pr = ANJUTA_PREFERENCES (g_object_get_data (G_OBJECT (widget),
885 "AnjutaPreferences"));
886 p = (AnjutaProperty *) user_data;
887 val = get_property_value_as_string (p);
888 anjuta_preferences_set (pr, p->key, val);
889 g_free (val);
892 static void
893 unregister_preferences_key (GtkWidget *widget,
894 gpointer user_data)
896 AnjutaProperty *p;
897 AnjutaPreferences *pr;
898 gchar *key;
900 p = (AnjutaProperty *) user_data;
901 pr = g_object_get_data (G_OBJECT (widget),
902 "AnjutaPreferences");
903 key = g_strdup (p->key);
905 g_hash_table_remove (pr->priv->properties, key);
906 g_free (key);
909 static void
910 get_property (GConfClient *gclient, guint cnxt_id,
911 GConfEntry *entry, gpointer user_data)
913 const gchar *key;
914 GConfValue *value;
916 AnjutaProperty *p = (AnjutaProperty *) user_data;
917 key = gconf_entry_get_key (entry);
918 value = gconf_entry_get_value (entry);
919 /* DEBUG_PRINT ("Preference changed %s", key); */
921 if (p->data_type == ANJUTA_PROPERTY_DATA_TYPE_BOOL)
923 gboolean gconf_value;
925 gconf_value = gconf_value_get_bool (value);
926 set_property_value_as_int (p, gconf_value);
928 else if (p->data_type == ANJUTA_PROPERTY_DATA_TYPE_INT)
930 int gconf_value;
932 gconf_value = gconf_value_get_int (value);
933 set_property_value_as_int (p, gconf_value);
935 else
937 const gchar *gconf_value;
938 gconf_value = gconf_value_get_string (value);
939 set_property_value_as_string (p, gconf_value);
943 static void
944 register_callbacks (AnjutaPreferences *pr, AnjutaProperty *p)
946 GConfClient *gclient;
947 gchar *key_error_msg;
949 gclient = pr->priv->gclient;
950 g_object_set_data (G_OBJECT (p->object), "AnjutaPreferences", pr);
951 switch (p->object_type) {
952 case ANJUTA_PROPERTY_OBJECT_TYPE_ENTRY:
953 g_signal_connect (G_OBJECT(p->object), "changed",
954 G_CALLBACK (update_property_on_change_str), p);
955 g_signal_connect (G_OBJECT(p->object), "focus_out_event",
956 G_CALLBACK (update_property_on_event_str), p);
957 g_signal_connect (G_OBJECT(p->object), "focus_out_event",
958 G_CALLBACK (unblock_update_property_on_change_str), p);
959 g_signal_connect (G_OBJECT(p->object), "focus_in_event",
960 G_CALLBACK (block_update_property_on_change_str), p);
961 break;
962 case ANJUTA_PROPERTY_OBJECT_TYPE_SPIN:
963 g_signal_connect (G_OBJECT(p->object), "value-changed",
964 G_CALLBACK (update_property_on_change_int), p);
965 break;
966 case ANJUTA_PROPERTY_OBJECT_TYPE_FONT:
967 g_signal_connect (G_OBJECT(p->object), "font-set",
968 G_CALLBACK (update_property_on_change_font), p);
969 break;
970 case ANJUTA_PROPERTY_OBJECT_TYPE_TEXT:
971 g_signal_connect (G_OBJECT(p->object), "focus_out_event",
972 G_CALLBACK (update_property_on_event_str), p);
973 break;
974 case ANJUTA_PROPERTY_OBJECT_TYPE_COMBO:
975 g_signal_connect (G_OBJECT(p->object), "changed",
976 G_CALLBACK (update_property_on_change_str), p);
977 break;
978 case ANJUTA_PROPERTY_OBJECT_TYPE_TOGGLE:
979 g_signal_connect (G_OBJECT(p->object), "toggled",
980 G_CALLBACK (update_property_on_change_int), p);
981 break;
982 case ANJUTA_PROPERTY_OBJECT_TYPE_COLOR:
983 g_signal_connect (G_OBJECT(p->object), "color-set",
984 G_CALLBACK (update_property_on_change_color), p);
985 break;
986 case ANJUTA_PROPERTY_OBJECT_TYPE_FILE:
987 g_signal_connect (G_OBJECT(p->object), "file-set",
988 G_CALLBACK (update_property_on_change_str), p);
989 break;
990 case ANJUTA_PROPERTY_OBJECT_TYPE_FOLDER:
991 g_signal_connect (G_OBJECT(p->object), "current-folder-changed",
992 G_CALLBACK (update_property_on_change_str), p);
993 break;
994 default:
995 break;
997 if (!gconf_valid_key (build_key (p->key), &key_error_msg))
999 g_warning ("Invalid key \"%s\": Error: \"%s\"", build_key (p->key),
1000 key_error_msg);
1001 g_free (key_error_msg);
1003 p->notify_id = gconf_client_notify_add (gclient, build_key (p->key),
1004 get_property, p, NULL, NULL);
1006 /* Connect to widget destroy signal so we can automatically unregister
1007 * keys so there aren't any potential conflicts or references to
1008 * nonexistent widgets on subsequent uses of the prefs dialog. */
1009 g_signal_connect (G_OBJECT (p->object), "destroy",
1010 G_CALLBACK (unregister_preferences_key),
1014 static gboolean
1015 preferences_foreach_callback (gchar *key, struct _AnjutaProperty *p,
1016 struct _AnjutaPreferencesForeachData *data)
1018 if (p->object_type != ANJUTA_PROPERTY_OBJECT_TYPE_COMBO)
1020 if (data->filter == ANJUTA_PREFERENCES_FILTER_NONE)
1021 return data->callback (data->pr, key, data->callback_data);
1022 else if (p->flags & data->filter)
1023 return data->callback (data->pr, key, data->callback_data);
1026 return TRUE;
1029 static void
1030 connect_prop_to_object (AnjutaPreferences *pr, AnjutaProperty *p)
1032 int gconf_value;
1033 gchar *value;
1035 if (p->data_type == ANJUTA_PROPERTY_DATA_TYPE_BOOL ||
1036 p->data_type == ANJUTA_PROPERTY_DATA_TYPE_INT)
1038 gconf_value = anjuta_preferences_get_int (pr, p->key);
1039 value = g_strdup_printf ("%d", gconf_value);
1040 set_property_value_as_string (p, value);
1042 else
1044 value = anjuta_preferences_get (pr, p->key);
1045 set_property_value_as_string (p, value);
1046 g_free (value);
1052 * anjuta_preferences_register_property_raw:
1053 * @pr: a #AnjutaPreferences object
1054 * @object: Widget to register
1055 * @key: Property key
1056 * @default_value: Default value of the key
1057 * @flags: Flags
1058 * @object_type: Object type of widget
1059 * @data_type: Data type of the property
1061 * This also registers only one widget, but instead of supplying the property
1062 * parameters as a single parsable string (as done in previous method), it
1063 * takes them separately.
1065 * Return value: TRUE if sucessful.
1067 gboolean
1068 anjuta_preferences_register_property_raw (AnjutaPreferences *pr,
1069 GtkWidget *object,
1070 const gchar *key,
1071 const gchar *default_value,
1072 guint flags,
1073 AnjutaPropertyObjectType object_type,
1074 AnjutaPropertyDataType data_type)
1076 AnjutaProperty *p;
1077 GConfValue *value;
1079 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), FALSE);
1080 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
1081 g_return_val_if_fail (key != NULL, FALSE);
1082 g_return_val_if_fail (strlen(key) > 0, FALSE);
1084 p = g_new0 (AnjutaProperty, 1);
1085 g_object_ref (object);
1086 p->object = object;
1087 p->object_type = object_type;
1088 p->data_type = data_type;
1089 p->key = g_strdup (key);
1090 p->gclient = pr->priv->gclient;
1092 value = gconf_client_get (pr->priv->gclient,
1093 build_key (p->key), NULL);
1094 if (value)
1096 /* Verify key type. Unset key if type mismatch. */
1097 if (!((value->type == GCONF_VALUE_BOOL &&
1098 data_type == ANJUTA_PROPERTY_DATA_TYPE_BOOL) ||
1099 (value->type == GCONF_VALUE_INT &&
1100 data_type == ANJUTA_PROPERTY_DATA_TYPE_INT) ||
1101 (value->type == GCONF_VALUE_STRING &&
1102 data_type != ANJUTA_PROPERTY_DATA_TYPE_BOOL &&
1103 data_type != ANJUTA_PROPERTY_DATA_TYPE_INT)))
1105 gconf_client_unset (pr->priv->gclient, build_key (key), NULL);
1107 gconf_value_free (value);
1109 if (default_value)
1111 p->default_value = g_strdup (default_value);
1112 if (strlen (default_value) > 0)
1114 /* For combo, initialize the untranslated strings */
1115 if (object_type == ANJUTA_PROPERTY_OBJECT_TYPE_COMBO)
1117 gchar *old_value;
1118 gchar **vstr;
1120 vstr = g_strsplit (default_value, ",", 100);
1121 g_object_set_data(G_OBJECT(p->object), "untranslated",
1122 vstr);
1123 old_value = anjuta_preferences_get (pr, p->key);
1124 if (old_value == NULL && vstr[0])
1126 /* DEBUG_PRINT ("Setting default pref value: %s = %s",
1127 p->key, default_value); */
1128 anjuta_preferences_set (pr, p->key, vstr[0]);
1130 if (old_value)
1131 g_free (old_value);
1133 else if (p->data_type != ANJUTA_PROPERTY_DATA_TYPE_BOOL &&
1134 p->data_type != ANJUTA_PROPERTY_DATA_TYPE_INT)
1136 gchar *old_value;
1137 old_value = anjuta_preferences_get (pr, p->key);
1138 if (old_value == NULL)
1140 /* DEBUG_PRINT ("Setting default pref value: %s = %s",
1141 p->key, default_value);*/
1142 anjuta_preferences_set (pr, p->key, default_value);
1144 if (old_value)
1145 g_free (old_value);
1147 else
1149 value = gconf_client_get (pr->priv->gclient,
1150 build_key (p->key), NULL);
1151 if (value == NULL)
1153 /* DEBUG_PRINT ("Setting default pref value: %s = %s",
1154 p->key, default_value);*/
1155 if (p->data_type == ANJUTA_PROPERTY_DATA_TYPE_INT)
1156 gconf_client_set_int (pr->priv->gclient,
1157 build_key (p->key),
1158 atoi (default_value), NULL);
1159 else
1160 gconf_client_set_bool (pr->priv->gclient,
1161 build_key (p->key),
1162 atoi (default_value), NULL);
1164 if (value)
1165 gconf_value_free (value);
1169 p->flags = flags;
1170 p->custom = FALSE;
1171 p->set_property = NULL;
1172 p->get_property = NULL;
1174 g_hash_table_insert (pr->priv->properties, g_strdup (key), p);
1175 connect_prop_to_object (pr, p);
1176 register_callbacks (pr, p);
1177 return TRUE;
1181 * anjuta_preferences_register_property_custom:
1182 * @pr: a #AnjutaPreferences object.
1183 * @object: Object to register.
1184 * @key: Property key.
1185 * @default_value: Default value of the key.
1186 * @data_type: property data type.
1187 * @flags: Flags
1188 * @set_property: Set property to widget callback.
1189 * @get_property: Get property from widget callback.
1191 * This is meant for complex widgets which can not be set/get with the
1192 * standard object set/get methods. Custom set/get methods are passed for
1193 * the property to set/get the value to/from the widget.
1195 * Return value: TRUE if sucessful.
1197 gboolean
1198 anjuta_preferences_register_property_custom (AnjutaPreferences *pr,
1199 GtkWidget *object,
1200 const gchar *key,
1201 const gchar *default_value,
1202 AnjutaPropertyDataType data_type,
1203 guint flags,
1204 void (*set_property) (AnjutaProperty *prop, const gchar *value),
1205 gchar * (*get_property) (AnjutaProperty *))
1207 AnjutaProperty *p;
1208 GConfValue *value;
1210 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), FALSE);
1211 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
1212 g_return_val_if_fail (key != NULL, FALSE);
1213 g_return_val_if_fail (strlen(key) > 0, FALSE);
1215 p = g_new0 (AnjutaProperty, 1);
1216 g_object_ref (object);
1217 p->object = object;
1218 p->object_type = (AnjutaPropertyObjectType) 0;
1219 p->data_type = data_type;
1220 p->key = g_strdup (key);
1221 p->gclient = pr->priv->gclient;
1223 value = gconf_client_get (pr->priv->gclient,
1224 build_key (p->key), NULL);
1225 if (value)
1227 /* Verify key type. Unset key if type mismatch. */
1228 if (!((value->type == GCONF_VALUE_BOOL &&
1229 data_type == ANJUTA_PROPERTY_DATA_TYPE_BOOL) ||
1230 (value->type == GCONF_VALUE_INT &&
1231 data_type == ANJUTA_PROPERTY_DATA_TYPE_INT) ||
1232 (value->type == GCONF_VALUE_STRING &&
1233 data_type != ANJUTA_PROPERTY_DATA_TYPE_BOOL &&
1234 data_type != ANJUTA_PROPERTY_DATA_TYPE_INT)))
1236 gconf_client_unset (pr->priv->gclient, build_key (key), NULL);
1238 gconf_value_free (value);
1240 if (default_value)
1242 p->default_value = g_strdup (default_value);
1243 if (p->data_type != ANJUTA_PROPERTY_DATA_TYPE_BOOL &&
1244 p->data_type != ANJUTA_PROPERTY_DATA_TYPE_INT)
1246 gchar *old_value;
1247 old_value = anjuta_preferences_get (pr, p->key);
1248 if (old_value == NULL)
1250 /* DEBUG_PRINT ("Setting default pref value: %s = %s",
1251 p->key, default_value); */
1252 anjuta_preferences_set (pr, p->key, default_value);
1254 if (old_value)
1255 g_free (old_value);
1257 else
1259 value = gconf_client_get (pr->priv->gclient,
1260 build_key (p->key), NULL);
1261 if (value == NULL)
1263 /* DEBUG_PRINT ("Setting default pref value: %s = %s",
1264 p->key, default_value);*/
1265 if (p->data_type == ANJUTA_PROPERTY_DATA_TYPE_INT)
1266 gconf_client_set_int (pr->priv->gclient,
1267 build_key (p->key),
1268 atoi (default_value), NULL);
1269 else
1270 gconf_client_set_bool (pr->priv->gclient,
1271 build_key (p->key),
1272 atoi (default_value), NULL);
1274 if (value)
1275 gconf_value_free (value);
1278 p->custom = TRUE;
1279 p->flags = flags;
1280 p->set_property = set_property;
1281 p->get_property = get_property;
1283 g_hash_table_insert (pr->priv->properties, g_strdup (key), p);
1285 /* Connect to widget destroy signal so we can automatically unregister
1286 * keys so there aren't any potential conflicts or references to
1287 * nonexistent widgets on subsequent uses of the prefs dialog. */
1288 g_object_set_data (G_OBJECT (p->object), "AnjutaPreferences", pr);
1289 g_signal_connect (G_OBJECT (p->object), "destroy",
1290 G_CALLBACK (unregister_preferences_key),
1292 return TRUE;
1296 * anjuta_preferences_register_property_from_string:
1297 * @pr: a #AnjutaPreferences object
1298 * @object: Widget to register
1299 * @property_desc: Property description (see anjuta_preferences_add_page())
1301 * This registers only one widget. The widget could be shown elsewhere.
1302 * the property_description should be of the form described before.
1304 * Return value: TRUE if sucessful.
1306 gboolean
1307 anjuta_preferences_register_property_from_string (AnjutaPreferences *pr,
1308 GtkWidget *object,
1309 const gchar *property_desc)
1311 gchar **fields;
1312 gint n_fields;
1314 AnjutaPropertyObjectType object_type;
1315 AnjutaPropertyDataType data_type;
1316 gchar *key;
1317 gchar *default_value;
1318 gint flags;
1320 g_return_val_if_fail (ANJUTA_IS_PREFERENCES(pr), FALSE);
1321 g_return_val_if_fail ((GTK_IS_WIDGET (object)), FALSE);
1322 g_return_val_if_fail (property_desc != NULL, FALSE);
1324 fields = g_strsplit (property_desc, ":", 5);
1325 g_return_val_if_fail (fields, FALSE);
1326 for (n_fields = 0; fields[n_fields]; n_fields++);
1327 if (n_fields != 5)
1329 g_strfreev (fields);
1330 return FALSE;
1332 object_type = get_object_type_from_string (fields[0]);
1333 data_type = get_data_type_from_string (fields[1]);
1334 default_value = fields[2];
1335 flags = atoi (fields[3]);
1336 key = fields[4];
1337 if (object_type < 0)
1339 g_warning ("Invalid property object type in property description");
1340 g_strfreev (fields);
1341 return FALSE;
1343 if (data_type < 0)
1345 g_warning ("Invalid property data type in property description");
1346 g_strfreev (fields);
1347 return FALSE;
1349 anjuta_preferences_register_property_raw (pr, object, key, default_value,
1350 flags, object_type,
1351 data_type);
1352 g_strfreev (fields);
1353 return TRUE;
1357 * anjuta_preferences_register_all_properties_from_glade_xml:
1358 * @pr: a #AnjutaPreferences Object
1359 * @gxml: GladeXML object containing the properties widgets.
1360 * @parent: Parent widget in the gxml object
1362 * This will register all the properties names of the format described above
1363 * without considering the UI. Useful if you have the widgets shown elsewhere
1364 * but you want them to be part of preferences system.
1366 void
1367 anjuta_preferences_register_all_properties_from_glade_xml (AnjutaPreferences *pr,
1368 GladeXML *gxml,
1369 GtkWidget *parent)
1371 GList *widgets;
1372 GList *node;
1374 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
1375 g_return_if_fail (gxml != NULL);
1377 widgets = glade_xml_get_widget_prefix (gxml, "preferences_");
1378 node = widgets;
1379 while (node)
1381 const gchar *name;
1382 GtkWidget *widget, *p;
1383 gboolean cont_flag = FALSE;
1385 widget = node->data;
1387 p = gtk_widget_get_parent (widget);
1388 /* Added only if it's a desendend child of the parent */
1389 while (p != parent)
1391 if (p == NULL)
1393 cont_flag = TRUE;
1394 break;
1396 p = gtk_widget_get_parent (p);
1398 if (cont_flag == TRUE)
1400 node = g_list_next (node);
1401 continue;
1404 name = glade_get_widget_name (widget);
1405 if (strncmp (name, PREFERENCE_PROPERTY_PREFIX,
1406 strlen (PREFERENCE_PROPERTY_PREFIX)) == 0)
1408 const gchar *property = &name[strlen (PREFERENCE_PROPERTY_PREFIX)];
1409 anjuta_preferences_register_property_from_string (pr, widget,
1410 property);
1412 node = g_list_next (node);
1417 * anjuta_preferences_reset_defaults:
1418 * @pr: a #AnjutaPreferences object.
1420 * Resets the default values into the keys
1422 void
1423 anjuta_preferences_reset_defaults (AnjutaPreferences * pr)
1425 GtkWidget *dlg;
1427 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
1429 dlg = gtk_message_dialog_new (GTK_WINDOW (pr),
1430 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
1431 GTK_BUTTONS_NONE,
1432 _("Are you sure you want to reset the preferences to\n"
1433 "their default settings?"));
1434 gtk_dialog_add_button (GTK_DIALOG (dlg), GTK_STOCK_CANCEL,
1435 GTK_RESPONSE_CANCEL);
1436 anjuta_util_dialog_add_button (GTK_DIALOG (dlg), _("_Reset"),
1437 GTK_STOCK_REVERT_TO_SAVED,
1438 GTK_RESPONSE_YES);
1439 if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_YES)
1441 /* FIXME: Reset preferences to built-in default values. */
1443 gtk_widget_destroy (dlg);
1447 * anjuta_preferences_foreach:
1448 * @pr: A #AnjutaPreferences object.
1449 * @filter: Keys to filter out from the loop.
1450 * @callback: User callback function.
1451 * @data: User data passed to @callback
1453 * Calls @callback function for each of the registered property keys. Keys
1454 * with matching @filter flags are left out of the loop. If @filter is
1455 * ANJUTA_PREFERENCES_FILTER_NONE, all properties are selected for the loop.
1457 void
1458 anjuta_preferences_foreach (AnjutaPreferences *pr,
1459 AnjutaPreferencesFilterType filter,
1460 AnjutaPreferencesCallback callback,
1461 gpointer data)
1463 struct _AnjutaPreferencesForeachData foreach_data;
1465 foreach_data.pr = pr;
1466 foreach_data.filter = filter;
1467 foreach_data.callback = callback;
1468 foreach_data.callback_data = data;
1470 g_hash_table_find (pr->priv->properties,
1471 (GHRFunc) preferences_foreach_callback,
1472 &foreach_data);
1477 * anjuta_preferences_add_page:
1478 * @pr: a #AnjutaPreferences object
1479 * @gxml: #GladeXML object containing the preferences page
1480 * @glade_widget_name: Page widget name (as give with glade interface editor).
1481 * The widget will be searched with the given name and detached
1482 * (that is, removed from the container, if present) from it's parent.
1483 * @icon_filename: File name (of the form filename.png) of the icon representing
1484 * the preference page.
1486 * Add a page to the preferences sytem.
1487 * gxml is the GladeXML object of the glade dialog containing the page widget.
1488 * The glade dialog will contain the layout of the preferences widgets.
1489 * The widgets which are preference widgets (e.g. toggle button) should have
1490 * widget names of the form:
1492 * <programlisting>
1493 * preferences_OBJECTTYPE:DATATYPE:DEFAULT:FLAGS:PROPERTYKEY
1494 * where,
1495 * OBJECTTYPE is 'toggle', 'spin', 'entry', 'text', 'color', 'font' or 'file' .
1496 * DATATYPE is 'bool', 'int', 'float', 'text', 'color' or 'font'.
1497 * DEFAULT is the default value (in the appropriate format). The format
1498 * for color is '#XXXXXX' representing RGB value and for
1499 * font, it is the pango font description.
1500 * FLAGS is any flag associated with the property. Currently it
1501 * has only two values -- 0 and 1. For normal preference
1502 * property which is saved/retrieved globally, the flag = 0.
1503 * For preference property which is also saved/retrieved
1504 * along with the project, the flag = 1.
1505 * PROPERTYKEY is the property key. e.g - 'tab.size'.
1506 * </programlisting>
1508 * All widgets having the above names in the gxml tree will be registered
1509 * and will become part of auto saving/loading. For example, refer to
1510 * anjuta preferences dialogs and study the widget names.
1512 void
1513 anjuta_preferences_add_page (AnjutaPreferences* pr, GladeXML *gxml,
1514 const gchar* glade_widget_name,
1515 const gchar* title,
1516 const gchar *icon_filename)
1518 GtkWidget *parent;
1519 GtkWidget *page;
1520 GdkPixbuf *pixbuf;
1521 gchar *image_path;
1523 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
1524 g_return_if_fail (glade_widget_name != NULL);
1525 g_return_if_fail (icon_filename != NULL);
1527 page = glade_xml_get_widget (gxml, glade_widget_name);
1528 g_object_ref (page);
1529 g_return_if_fail (GTK_IS_WIDGET (page));
1530 parent = gtk_widget_get_parent (page);
1531 if (parent && GTK_IS_CONTAINER (parent))
1533 if (GTK_IS_NOTEBOOK (parent))
1535 gint page_num;
1537 page_num = gtk_notebook_page_num (GTK_NOTEBOOK (parent), page);
1538 gtk_notebook_remove_page (GTK_NOTEBOOK (parent), page_num);
1540 else
1542 gtk_container_remove (GTK_CONTAINER (parent), page);
1545 image_path = anjuta_res_get_pixmap_file (icon_filename);
1546 pixbuf = gdk_pixbuf_new_from_file (image_path, NULL);
1547 anjuta_preferences_dialog_add_page (ANJUTA_PREFERENCES_DIALOG (pr->priv->prefs_dialog),
1548 glade_widget_name, title, pixbuf, page);
1549 anjuta_preferences_register_all_properties_from_glade_xml (pr, gxml, page);
1550 g_object_unref (page);
1551 g_free (image_path);
1552 g_object_unref (pixbuf);
1555 void
1556 anjuta_preferences_remove_page (AnjutaPreferences *pr,
1557 const gchar *page_name)
1559 if (pr->priv->prefs_dialog)
1561 anjuta_preferences_dialog_remove_page (ANJUTA_PREFERENCES_DIALOG (pr->priv->prefs_dialog),
1562 page_name);
1566 static void
1567 on_preferences_dialog_destroyed (GtkWidget *preferencess_dialog,
1568 AnjutaPreferences *pr)
1570 GList *plugins;
1571 GList *current_plugin;
1573 plugins = anjuta_plugin_manager_get_active_plugin_objects (pr->priv->plugin_manager);
1574 current_plugin = plugins;
1576 while (current_plugin)
1578 if (IANJUTA_IS_PREFERENCES (current_plugin->data))
1580 ianjuta_preferences_unmerge (IANJUTA_PREFERENCES (current_plugin->data),
1581 pr, NULL);
1584 current_plugin = g_list_next (current_plugin);
1588 g_object_unref (pr->priv->prefs_dialog);
1590 g_list_free (plugins);
1591 pr->priv->prefs_dialog = NULL;
1594 GtkWidget *
1595 anjuta_preferences_get_dialog (AnjutaPreferences *pr)
1597 GList *plugins;
1598 GList *current_plugin;
1600 if (pr->priv->prefs_dialog)
1601 return pr->priv->prefs_dialog;
1602 else
1604 pr->priv->prefs_dialog = anjuta_preferences_dialog_new ();
1606 g_signal_connect (G_OBJECT (pr->priv->prefs_dialog), "destroy",
1607 G_CALLBACK (on_preferences_dialog_destroyed),
1608 pr);
1610 plugins = anjuta_plugin_manager_get_active_plugin_objects (pr->priv->plugin_manager);
1611 current_plugin = plugins;
1613 while (current_plugin)
1615 if (IANJUTA_IS_PREFERENCES (current_plugin->data))
1617 ianjuta_preferences_merge (IANJUTA_PREFERENCES (current_plugin->data),
1618 pr, NULL);
1621 current_plugin = g_list_next (current_plugin);
1624 g_list_free (plugins);
1626 return g_object_ref_sink (pr->priv->prefs_dialog);
1630 static void anjuta_preferences_class_init (AnjutaPreferencesClass *class);
1631 static void anjuta_preferences_instance_init (AnjutaPreferences *pr);
1633 GType
1634 anjuta_preferences_get_type ()
1636 static GType obj_type = 0;
1638 if (!obj_type)
1640 static const GTypeInfo obj_info =
1642 sizeof (AnjutaPreferencesClass),
1643 (GBaseInitFunc) NULL,
1644 (GBaseFinalizeFunc) NULL,
1645 (GClassInitFunc) anjuta_preferences_class_init,
1646 (GClassFinalizeFunc) NULL,
1647 NULL, /* class_data */
1648 sizeof (AnjutaPreferencesClass),
1649 0, /* n_preallocs */
1650 (GInstanceInitFunc) anjuta_preferences_instance_init,
1651 NULL /* value_table */
1653 obj_type = g_type_register_static (G_TYPE_OBJECT,
1654 "AnjutaPreferences", &obj_info, 0);
1656 return obj_type;
1659 static void
1660 anjuta_preferences_dispose (GObject *obj)
1662 AnjutaPreferences *pr = ANJUTA_PREFERENCES (obj);
1664 if (pr->priv->properties)
1666 /* This will release the refs on property objects */
1667 g_hash_table_destroy (pr->priv->properties);
1668 pr->priv->properties = NULL;
1672 static void
1673 anjuta_preferences_instance_init (AnjutaPreferences *pr)
1675 pr->priv = g_new0 (AnjutaPreferencesPriv, 1);
1677 pr->priv->properties = g_hash_table_new_full (g_str_hash, g_str_equal,
1678 g_free,
1679 (GDestroyNotify) property_destroy);
1681 pr->priv->gclient = gconf_client_get_default();
1682 gconf_client_add_dir (pr->priv->gclient, GCONF_KEY_PREFIX,
1683 GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
1687 static void
1688 anjuta_preferences_finalize (GObject *obj)
1690 AnjutaPreferences *pr = ANJUTA_PREFERENCES (obj);
1692 if (pr->priv->prefs_dialog)
1693 gtk_widget_destroy (pr->priv->prefs_dialog);
1695 g_object_unref (pr->priv->plugin_manager);
1696 g_free (pr->priv);
1699 static void
1700 anjuta_preferences_class_init (AnjutaPreferencesClass *class)
1702 GObjectClass *object_class = G_OBJECT_CLASS (class);
1704 object_class->dispose = anjuta_preferences_dispose;
1705 object_class->finalize = anjuta_preferences_finalize;
1709 * anjuta_preferences_new:
1711 * Creates a new #AnjutaPreferences object
1713 * Return value: A #AnjutaPreferences object.
1715 AnjutaPreferences *
1716 anjuta_preferences_new (AnjutaPluginManager *plugin_manager)
1718 AnjutaPreferences *pr;
1720 pr = g_object_new (ANJUTA_TYPE_PREFERENCES, NULL);
1721 pr->priv->plugin_manager = g_object_ref (plugin_manager);
1723 return pr;
1728 * anjuta_preferences_notify_add:
1729 * @pr: A #AnjutaPreferences object.
1730 * @key: Key to monitor.
1731 * @func: User callback function.
1732 * @data: User data passed to @func
1733 * @destroy_notify: Destroy notify function - called when notify is removed.
1735 * This is similar to gconf_client_notify_add(), except that the key is not
1736 * given as full path. Only anjuta preference key is given. The key prefix
1737 * is added internally.
1739 * Return value: Notify ID.
1741 guint
1742 anjuta_preferences_notify_add (AnjutaPreferences *pr,
1743 const gchar *key,
1744 GConfClientNotifyFunc func,
1745 gpointer data,
1746 GFreeFunc destroy_notify)
1748 return gconf_client_notify_add (pr->priv->gclient,
1749 build_key (key),
1750 func, data, destroy_notify, NULL);
1754 * anjuta_preferences_notify_remove:
1755 * @pr: A #AnjutaPreferences object.
1756 * @notify_id: Notify ID returned by anjuta_preferences_notify_add().
1758 * Removes the notify callback added with anjuta_preferences_notify_add().
1760 void
1761 anjuta_preferences_notify_remove (AnjutaPreferences *pr, guint notify_id)
1763 gconf_client_notify_remove (pr->priv->gclient, notify_id);
1767 * anjuta_preferences_get_prefix:
1768 * @pr: A #AnjutaPreferences object.
1770 * Returns the gconf key prefix used by anjuta to store its preferences.
1772 * Return value: preferences keys prefix.
1774 const gchar*
1775 anjuta_preferences_get_prefix (AnjutaPreferences *pr)
1777 return PREFERENCE_PROPERTY_PREFIX;
1781 * anjuta_preferences_dir_exists:
1782 * @pr: A #AnjutaPreferences object.
1783 * @dir: Directory to checkfor.
1785 * Returns TRUE if dir exists.
1787 #ifdef __GNUC__
1788 inline
1789 #endif
1790 gboolean
1791 anjuta_preferences_dir_exists (AnjutaPreferences *pr, const gchar *dir)
1793 g_return_val_if_fail (ANJUTA_IS_PREFERENCES (pr), FALSE);
1794 g_return_val_if_fail (dir != NULL, FALSE);
1796 return gconf_client_dir_exists(pr->priv->gclient, build_key (dir), NULL);
1800 * anjuta_preferences_add_dir:
1801 * @pr: A #AnjutaPreferences object.
1802 * @dir: Directory to add to the list.
1803 * @preload: Degree of preload.
1805 * Add a directory to the list of directories the GConfClient.
1807 #ifdef __GNUC__
1808 inline
1809 #endif
1810 void
1811 anjuta_preferences_add_dir (AnjutaPreferences *pr, const gchar *dir,
1812 GConfClientPreloadType preload)
1814 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
1815 g_return_if_fail (dir != NULL);
1817 gconf_client_add_dir(pr->priv->gclient, build_key (dir),
1818 preload, NULL);
1822 * anjuta_preferences_remove_dir:
1823 * @pr: A #AnjutaPreferences object.
1824 * @dir: Directory to remove from the list.
1826 * Remove a directory from the list of directories.
1828 #ifdef __GNUC__
1829 inline
1830 #endif
1831 void
1832 anjuta_preferences_remove_dir (AnjutaPreferences *pr, const gchar *dir)
1834 g_return_if_fail (ANJUTA_IS_PREFERENCES (pr));
1835 g_return_if_fail (dir != NULL);
1837 gconf_client_remove_dir(pr->priv->gclient, build_key (dir), NULL);