/* * Copyright (C) 2012 Juan Pablo Ugarte. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Authors: * Juan Pablo Ugarte */ #include #include "glade-preferences.h" #include #include #define CONFIG_GROUP "Preferences" enum { COLUMN_PATH = 0, COLUMN_CANONICAL_PATH }; struct _GladePreferencesPrivate { GtkTreeModel *catalog_path_store; GtkTreeSelection *selection; GtkWidget *remove_catalog_button; GtkWidget *create_backups_toggle; GtkWidget *autosave_toggle; GtkWidget *autosave_spin; GtkWidget *versioning_toggle; GtkWidget *deprecations_toggle; GtkWidget *unrecognized_toggle; GladeSettings *settings; }; enum { PROP_SETTINGS = 1, N_PROPERTIES }; static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; G_DEFINE_TYPE_WITH_PRIVATE (GladePreferences, glade_preferences, GTK_TYPE_DIALOG) /******************************************************** * CALLBACKS * ********************************************************/ static void autosave_toggled (GtkToggleButton *button, GladePreferences *prefs) { gtk_widget_set_sensitive (prefs->priv->autosave_spin, gtk_toggle_button_get_active (button)); } static gboolean find_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gchar **directory = data; gchar *string; gtk_tree_model_get (model, iter, COLUMN_CANONICAL_PATH, &string, -1); if (g_strcmp0 (string, *directory) == 0) { g_free (*directory); *directory = NULL; return TRUE; } return FALSE; } static void remove_catalog_clicked (GtkButton *button, GladePreferences *preferences) { GladePreferencesPrivate *priv = preferences->priv; GtkTreeIter iter; if (gtk_tree_selection_get_selected (priv->selection, NULL, &iter)) { gchar *path = NULL; gtk_tree_model_get (priv->catalog_path_store, &iter, COLUMN_CANONICAL_PATH, &path, -1); if (path) { glade_catalog_remove_path (path); g_free (path); } gtk_list_store_remove (GTK_LIST_STORE (priv->catalog_path_store), &iter); } } static void catalog_selection_changed (GtkTreeSelection *selection, GladePreferences *preferences) { gboolean selected = gtk_tree_selection_get_selected (selection, NULL, NULL); /* Make the button sensitive if anything is selected */ gtk_widget_set_sensitive (preferences->priv->remove_catalog_button, selected); } static gboolean glade_preferences_transform_to (GBinding *binding, const GValue *from_value, GValue *to_value, gpointer user_data) { GladeVerifyFlags flag = (GladeVerifyFlags) user_data; g_value_set_boolean (to_value, g_value_get_flags (from_value) & flag); return TRUE; } static gboolean glade_preferences_transform_from (GBinding *binding, const GValue *from_value, GValue *to_value, gpointer user_data) { GladeVerifyFlags flag = (GladeVerifyFlags) user_data; GladeVerifyFlags previous_flags = glade_settings_get_verify_flags (GLADE_SETTINGS (g_binding_get_source (binding))); if (g_value_get_boolean (from_value)) g_value_set_flags (to_value, previous_flags | flag); else g_value_set_flags (to_value, previous_flags & ~flag); return TRUE; } static void glade_preferences_set_settings (GladePreferences *self, GladeSettings *settings) { const GList *paths, *l; self->priv->settings = settings; g_object_bind_property (settings, "backup", self->priv->create_backups_toggle, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (settings, "autosave", self->priv->autosave_spin, "sensitive", G_BINDING_SYNC_CREATE); g_object_bind_property (settings, "autosave", self->priv->autosave_toggle, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (settings, "autosave-seconds", self->priv->autosave_spin, "value", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property_full (settings, "verify-flags", self->priv->versioning_toggle, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE, glade_preferences_transform_to, glade_preferences_transform_from, (void *)GLADE_VERIFY_VERSIONS, NULL); g_object_bind_property_full (settings, "verify-flags", self->priv->deprecations_toggle, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE, glade_preferences_transform_to, glade_preferences_transform_from, (void *)GLADE_VERIFY_DEPRECATIONS, NULL); g_object_bind_property_full (settings, "verify-flags", self->priv->unrecognized_toggle, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE, glade_preferences_transform_to, glade_preferences_transform_from, (void *)GLADE_VERIFY_UNRECOGNIZED, NULL); paths = glade_catalog_get_extra_paths (); gtk_list_store_clear (GTK_LIST_STORE (self->priv->catalog_path_store)); for (l = paths; l != NULL; l = l->next) { const gchar *path = (const gchar *)(l->data); gchar *display = glade_utils_replace_home_dir_with_tilde (path); GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE (self->priv->catalog_path_store), &iter); gtk_list_store_set (GTK_LIST_STORE (self->priv->catalog_path_store), &iter, COLUMN_PATH, display, COLUMN_CANONICAL_PATH, path, -1); g_free (display); } } static void glade_preferences_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GladePreferences *self = GLADE_PREFERENCES (object); switch (property_id) { case PROP_SETTINGS: glade_preferences_set_settings (self, GLADE_SETTINGS (g_value_get_object (value))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void glade_preferences_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GladePreferences *self = GLADE_PREFERENCES (object); switch (property_id) { case PROP_SETTINGS: g_value_set_object (value, self->priv->settings); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void on_add_catalog_button_clicked (GtkButton *button, GladePreferences *preferences) { GladePreferencesPrivate *priv = preferences->priv; GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new (_("Select a catalog search path"), GTK_WINDOW (preferences), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, NULL); if ((gtk_dialog_run (GTK_DIALOG (dialog))) == GTK_RESPONSE_ACCEPT) { g_autofree gchar *path = NULL, *canonical = NULL, *display = NULL; path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); canonical = glade_util_canonical_path (path); display = glade_utils_replace_home_dir_with_tilde (canonical); gtk_tree_model_foreach (priv->catalog_path_store, find_row, &canonical); if (canonical) { GtkTreeIter iter; glade_catalog_add_path (canonical); /* Force user templates reload */ glade_catalog_load_all (); gtk_list_store_append (GTK_LIST_STORE (priv->catalog_path_store), &iter); gtk_list_store_set (GTK_LIST_STORE (priv->catalog_path_store), &iter, COLUMN_PATH, display, COLUMN_CANONICAL_PATH, canonical, -1); } } gtk_widget_destroy (dialog); } /******************************************************** * Class/Instance Init * ********************************************************/ static void glade_preferences_init (GladePreferences *preferences) { preferences->priv = glade_preferences_get_instance_private (preferences); gtk_widget_init_template (GTK_WIDGET (preferences)); } static void glade_preferences_class_init (GladePreferencesClass *klass) { GtkWidgetClass *widget_class; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = glade_preferences_set_property; object_class->get_property = glade_preferences_get_property; obj_properties[PROP_SETTINGS] = g_param_spec_object ("settings", "Settings", "Settings object.", GLADE_TYPE_SETTINGS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties); widget_class = GTK_WIDGET_CLASS (klass); /* Setup the template GtkBuilder xml for this class */ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/glade/glade-preferences.glade"); /* Define the relationship of the private entry and the entry defined in the xml */ gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, catalog_path_store); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, remove_catalog_button); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, selection); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, create_backups_toggle); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, autosave_toggle); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, autosave_spin); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, versioning_toggle); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, deprecations_toggle); gtk_widget_class_bind_template_child_private (widget_class, GladePreferences, unrecognized_toggle); /* Declare the callback ports that this widget class exposes, to bind with * connections defined in the GtkBuilder xml */ gtk_widget_class_bind_template_callback (widget_class, autosave_toggled); gtk_widget_class_bind_template_callback (widget_class, on_add_catalog_button_clicked); gtk_widget_class_bind_template_callback (widget_class, catalog_selection_changed); gtk_widget_class_bind_template_callback (widget_class, remove_catalog_clicked); } /******************************************************** * API * ********************************************************/ GtkWidget * glade_preferences_new (GladeSettings *settings) { return g_object_new (GLADE_TYPE_PREFERENCES, "use-header-bar", TRUE, "settings", settings, NULL); }