[glade] Implemented GladePreferences dialog. Fixes bug 588981 "Catalog support in GUI preferences instead of



commit 3ec8a9ab1913bebe192f15d281eae4d1b9d24127
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date:   Fri May 4 20:39:41 2012 -0300

    Implemented GladePreferences dialog.
    Fixes bug 588981 "Catalog support in GUI preferences instead of using environment var"

 src/Makefile.am         |    7 ++-
 src/glade-preferences.c |  190 +++++++++++++++++++++++++++++++++++++++++++++
 src/glade-preferences.h |   45 +++++++++++
 src/glade-window.c      |   36 ++++++---
 src/glade.glade         |  198 ++++++++++++++++++++++++++++++++++++++++-------
 5 files changed, 435 insertions(+), 41 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 71d40d3..478bf63 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,10 +29,15 @@ glade_SOURCES = \
 	glade-close-button.h \
 	glade-resources.c \
 	glade-callbacks.h \
+	glade-preferences.c \
+	glade-preferences.h \
 	main.c
 
 noinst_HEADERS = \
-	glade-resources.h
+	glade-window.h \
+	glade-close-button.h \
+	glade-resources.h \
+	glade-preferences.h
 
 # This could be split in two, but its better to rebuild both, sources and header
 # each time the xml or the actual resources files change, just in case. 
diff --git a/src/glade-preferences.c b/src/glade-preferences.c
new file mode 100644
index 0000000..6e25b5f
--- /dev/null
+++ b/src/glade-preferences.c
@@ -0,0 +1,190 @@
+/*
+ * 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 <juanpablougarte gmail com>
+ */
+
+#include "glade-preferences.h"
+#include <gladeui/glade-catalog.h>
+
+struct _GladePreferences
+{
+  GObject *toplevel;
+  GtkComboBoxText *catalog_path_combo;
+};
+
+#define CONFIG_GROUP "Preferences"
+#define CONFIG_KEY_CATALOG_PATHS "catalog-paths"
+
+static void
+combo_box_text_init_cell (GtkCellLayout *cell)
+{
+  GList *l, *cels = gtk_cell_layout_get_cells (cell);
+
+  for (l = cels; l; l = g_list_next (l))
+    {
+      g_object_set (l->data,
+                    "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
+                    "ellipsize-set", TRUE,
+                    "max-width-chars", 128,
+                    "width-chars", 32,
+                    NULL);
+    }
+
+  g_list_free (cels);
+}
+
+GladePreferences *
+glade_preferences_new (GtkBuilder *builder)
+{
+  GladePreferences *prefs = g_new0 (GladePreferences, 1);
+
+  prefs->toplevel = gtk_builder_get_object (builder, "preferences_dialog");
+  prefs->catalog_path_combo = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "catalog_path_comboboxtext"));
+  combo_box_text_init_cell (GTK_CELL_LAYOUT (prefs->catalog_path_combo));
+  
+  return prefs;
+}
+
+void
+glade_preferences_destroy (GladePreferences *prefs)
+{
+  g_object_unref (prefs->toplevel);
+  g_free (prefs);
+}
+
+void
+glade_preferences_config_save (GladePreferences *prefs, GKeyFile *config)
+{
+  GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (prefs->catalog_path_combo));
+  gint column = gtk_combo_box_get_entry_text_column (GTK_COMBO_BOX (prefs->catalog_path_combo));
+  GString *string = g_string_new ("");
+  GtkTreeIter iter;
+  gboolean valid;
+
+  valid = gtk_tree_model_get_iter_first (model, &iter);
+  while (valid)
+    {
+      gchar *path;
+
+      gtk_tree_model_get (model, &iter, column, &path, -1);
+      valid = gtk_tree_model_iter_next (model, &iter);
+      
+      g_string_append (string, path);
+      if (valid) g_string_append (string, ":");
+      
+      g_free (path);
+    }
+  
+  g_key_file_set_string (config, CONFIG_GROUP, CONFIG_KEY_CATALOG_PATHS, string->str);
+
+  g_string_free (string, TRUE);
+}
+
+void
+glade_preferences_config_load (GladePreferences *prefs, GKeyFile *config)
+{
+  gchar *string;
+  
+  string = g_key_file_get_string (config, CONFIG_GROUP, CONFIG_KEY_CATALOG_PATHS, NULL);
+
+  if (string && g_strcmp0 (string, ""))
+    {
+      GtkComboBoxText *combo = prefs->catalog_path_combo;
+      gchar **paths, **path;
+
+      gtk_combo_box_text_remove_all (combo);
+      glade_catalog_remove_path (NULL);
+
+      paths = g_strsplit (string, ":", -1);
+
+      path = paths;
+      do
+        {
+          glade_catalog_add_path (*path);
+          gtk_combo_box_text_append (combo, *path, *path);
+        } while (*++path);
+
+      gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+      g_strfreev (paths);
+    }
+
+  g_free (string);
+}
+
+/* Callbacks */
+
+static gboolean 
+find_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+{
+  gchar **directory = data;
+  gchar *string;
+  
+  gtk_tree_model_get (model, iter, 1, &string, -1);
+
+  if (g_strcmp0 (string, *directory) == 0)
+    {
+      g_free (*directory);
+      *directory = NULL;
+      return TRUE;
+    }
+  
+  return FALSE;
+}
+
+void
+on_preferences_filechooserdialog_response (GtkDialog *dialog,
+                                           gint response_id,
+                                           GtkComboBoxText *combo)
+{
+  gtk_widget_hide (GTK_WIDGET (dialog));
+
+  if (response_id == GTK_RESPONSE_ACCEPT)
+    {
+      gchar *directory = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+      GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+      
+      gtk_tree_model_foreach (model, find_row, &directory);
+
+      if (directory)
+        {
+          glade_catalog_add_path (directory);
+          gtk_combo_box_text_append (combo, directory, directory);
+          gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+          g_free (directory);
+        }
+    }
+}
+
+void
+on_catalog_path_remove_button_clicked (GtkButton *button, GtkComboBoxText *combo)
+{
+  gint active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
+
+  if (active >= 0)
+    {
+      gchar *directory = gtk_combo_box_text_get_active_text (combo);
+      glade_catalog_remove_path (directory);
+      g_free (directory);
+
+      gtk_combo_box_text_remove (combo, active);
+
+      if (--active < 0) active = 0;
+      gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
+    }
+}
diff --git a/src/glade-preferences.h b/src/glade-preferences.h
new file mode 100644
index 0000000..7abc0ba
--- /dev/null
+++ b/src/glade-preferences.h
@@ -0,0 +1,45 @@
+/*
+ * 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 <juanpablougarte gmail com>
+ */
+
+#ifndef __GLADE_PREFERENCES_H__
+#define __GLADE_PREFERENCES_H__
+
+#include <gtk/gtk.h>
+
+typedef struct _GladePreferences GladePreferences;
+
+GladePreferences *glade_preferences_new     (GtkBuilder *builder);
+void              glade_preferences_destroy (GladePreferences *prefs);
+
+void glade_preferences_config_save (GladePreferences *prefs,
+                                    GKeyFile *config);
+void glade_preferences_config_load (GladePreferences *prefs,
+                                    GKeyFile *config);
+
+/* Callbacks */
+
+void on_preferences_filechooserdialog_response (GtkDialog *dialog,
+                                                gint response_id,
+                                                GtkComboBoxText *combo);
+void on_catalog_path_remove_button_clicked     (GtkButton *button,
+                                                GtkComboBoxText *combo);
+
+#endif /* __GLADE_PREFERENCES_H__ */
diff --git a/src/glade-window.c b/src/glade-window.c
index 4815e5a..178beb7 100644
--- a/src/glade-window.c
+++ b/src/glade-window.c
@@ -30,6 +30,7 @@
 #include "glade-close-button.h"
 #include "glade-resources.h"
 #include "glade-callbacks.h"
+#include "glade-preferences.h"
 
 #include <gladeui/glade.h>
 #include <gladeui/glade-popup.h>
@@ -104,7 +105,7 @@ struct _GladeWindowPrivate
   gint num_tabs;
 
   GtkWindow *about_dialog;
-  GtkWindow *preferences_dialog;
+  GladePreferences *preferences;
   
   GtkWidget *palettes_notebook;         /* Cached per project palettes */
   GtkWidget *inspectors_notebook;       /* Cached per project inspectors */
@@ -940,7 +941,7 @@ refresh_projects_list_menu (GladeWindow *window)
 
       /* Remove MenuItems */
       for (p = proxies; p; p = g_slist_next (p))
-        if (GTK_IS_MENU_ITEM (p->data)) gtk_widget_destroy (p->data);
+        if (GTK_IS_MENU_ITEM (p->data)) g_object_unref (p->data);
 
       g_signal_handlers_disconnect_by_func (action,
                                             G_CALLBACK (projects_list_menu_activate_cb),
@@ -2658,6 +2659,8 @@ glade_window_config_save (GladeWindow * window)
   save_paned_position (config, window->priv->left_pane, "left_pane");
   save_paned_position (config, window->priv->right_pane, "right_pane");
 
+  glade_preferences_config_save (window->priv->preferences, config);
+
   glade_app_config_save ();
 }
 
@@ -2840,6 +2843,8 @@ glade_window_config_load (GladeWindow *window)
   load_paned_position (config, window->priv->left_pane, "left_pane", 200);
   load_paned_position (config, window->priv->center_pane, "center_pane", 400);
   load_paned_position (config, window->priv->right_pane, "right_pane", 220);
+
+  glade_preferences_config_load (window->priv->preferences, config);
 }
 
 static gboolean
@@ -2944,8 +2949,8 @@ glade_window_init (GladeWindow *window)
 
   priv->default_path = NULL;
 
-  priv->app = glade_app_new ();
-
+  /* We need this for the icons to be available */
+  glade_init ();
 }
 
 #define GET_OBJECT(b,c,o) c(gtk_builder_get_object(b,o)) /*;g_warn_if_fail(gtk_builder_get_object(b,o))*/
@@ -2997,11 +3002,13 @@ glade_window_constructed (GObject *object)
       gtk_recent_chooser_set_filter (GET_OBJECT (builder, GTK_RECENT_CHOOSER, "open_recent_action"),
                                      filter);
     }
+
+  /* Init preferences */
+  priv->preferences = glade_preferences_new (builder);
   
   /* Fetch pointers */
   vbox = GET_OBJECT (builder, GTK_WIDGET, "main_box");
   priv->about_dialog   = GET_OBJECT (builder, GTK_WINDOW, "about_dialog");
-  priv->preferences_dialog = GET_OBJECT (builder, GTK_WINDOW, "preferences_dialog");
 
   priv->center_pane = GET_OBJECT (builder, GTK_WIDGET, "center_paned");
   priv->left_pane = GET_OBJECT (builder, GTK_WIDGET, "left_paned");
@@ -3089,17 +3096,22 @@ glade_window_constructed (GObject *object)
   g_signal_connect (G_OBJECT (window), "key-press-event",
                     G_CALLBACK (glade_utils_hijack_key_press), window);
 
-  /* Clipboard signals */
-  g_signal_connect (G_OBJECT (glade_app_get_clipboard ()),
-                    "notify::has-selection",
-                    G_CALLBACK (clipboard_notify_handler_cb), window);
-
-  glade_app_set_window (GTK_WIDGET (window));
-
   gtk_builder_connect_signals (builder, window);
 
+  /* Load configuration, we need the list of extra catalog paths before creating
+   * the GladeApp
+   */
   glade_window_config_load (window);
+  
+  /* Create GladeApp singleton, this will load all catalogs */
+  priv->app = glade_app_new ();
+  glade_app_set_window (GTK_WIDGET (window));
 
+  /* Clipboard signals */
+  g_signal_connect (G_OBJECT (glade_app_get_clipboard ()),
+                    "notify::has-selection",
+                    G_CALLBACK (clipboard_notify_handler_cb), window);
+  
 #ifdef MAC_INTEGRATION
 	{
 	  /* Fix up the menubar for MacOSX Quartz builds */
diff --git a/src/glade.glade b/src/glade.glade
index f8af740..23f8749 100644
--- a/src/glade.glade
+++ b/src/glade.glade
@@ -1134,11 +1134,15 @@ Andreas Nilsson &lt;andreas andreasn se&gt;</property>
     </child>
   </object>
   <object class="GtkDialog" id="preferences_dialog">
+    <property name="width_request">320</property>
+    <property name="height_request">200</property>
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
+    <property name="title" translatable="yes">Glade Preferences</property>
     <property name="type_hint">dialog</property>
-    <signal name="close" handler="gtk_widget_hide" swapped="no"/>
+    <signal name="delete-event" handler="gtk_widget_hide" swapped="no"/>
     <signal name="delete-event" handler="gtk_true" swapped="no"/>
+    <signal name="response" handler="gtk_widget_hide" swapped="no"/>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
@@ -1149,10 +1153,7 @@ Andreas Nilsson &lt;andreas andreasn se&gt;</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
             <child>
-              <placeholder/>
-            </child>
-            <child>
-              <object class="GtkButton" id="button1">
+              <object class="GtkButton" id="preferences_close_button">
                 <property name="label">gtk-close</property>
                 <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
@@ -1164,7 +1165,7 @@ Andreas Nilsson &lt;andreas andreasn se&gt;</property>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="position">1</property>
+                <property name="position">2</property>
               </packing>
             </child>
           </object>
@@ -1180,38 +1181,107 @@ Andreas Nilsson &lt;andreas andreasn se&gt;</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <child>
-              <object class="GtkGrid" id="grid1">
+              <object class="GtkBox" id="box1">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="border_width">4</property>
-                <property name="row_spacing">6</property>
-                <property name="column_spacing">6</property>
+                <property name="orientation">vertical</property>
                 <child>
-                  <object class="GtkLabel" id="label4">
+                  <object class="GtkFrame" id="frame1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Extra catalog paths:</property>
+                    <property name="label_xalign">0</property>
+                    <child>
+                      <object class="GtkGrid" id="grid1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="row_spacing">6</property>
+                        <property name="column_spacing">6</property>
+                        <child>
+                          <object class="GtkButton" id="catalog_path_remove_button">
+                            <property name="use_action_appearance">False</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="tooltip_text" translatable="yes">Removes the selected catalog path</property>
+                            <property name="use_action_appearance">False</property>
+                            <signal name="clicked" handler="on_catalog_path_remove_button_clicked" object="catalog_path_comboboxtext" swapped="no"/>
+                            <child>
+                              <object class="GtkImage" id="image1">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="stock">gtk-remove</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkComboBoxText" id="catalog_path_comboboxtext">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                            <property name="entry_text_column">0</property>
+                            <property name="id_column">1</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="catalog_path_add_button">
+                            <property name="use_action_appearance">False</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="tooltip_text" translatable="yes">Add a new catalog path</property>
+                            <property name="use_action_appearance">False</property>
+                            <signal name="clicked" handler="gtk_widget_show" object="preferences_filechooserdialog" swapped="yes"/>
+                            <child>
+                              <object class="GtkImage" id="image2">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="stock">gtk-add</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">2</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Extra catalog paths</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkEntry" id="catalog_path_entry">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="tooltip_text" translatable="yes">Coma separated list of paths where to look catalogs</property>
-                    <property name="invisible_char">â</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
-                  </packing>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
                 </child>
               </object>
             </child>
@@ -1235,7 +1305,79 @@ Andreas Nilsson &lt;andreas andreasn se&gt;</property>
       </object>
     </child>
     <action-widgets>
-      <action-widget response="0">button1</action-widget>
+      <action-widget response="-7">preferences_close_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkFileChooserDialog" id="preferences_filechooserdialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Select a catalog search path</property>
+    <property name="modal">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="transient_for">preferences_dialog</property>
+    <property name="action">select-folder</property>
+    <signal name="delete-event" handler="gtk_widget_hide" swapped="no"/>
+    <signal name="delete-event" handler="gtk_true" swapped="no"/>
+    <signal name="response" handler="on_preferences_filechooserdialog_response" object="catalog_path_comboboxtext" swapped="no"/>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="filechooserdialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="filechooserdialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button3">
+                <property name="label">gtk-cancel</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button4">
+                <property name="label">gtk-open</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">button3</action-widget>
+      <action-widget response="-3">button4</action-widget>
     </action-widgets>
   </object>
 </interface>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]