[yelp] [yelp-application] Store window geometry per-document



commit ce9025fffd63568305313cd7fddbd17fd8e058f5
Author: Shaun McCance <shaunm gnome org>
Date:   Tue Apr 27 20:34:13 2010 -0500

    [yelp-application] Store window geometry per-document
    
    The width and height of the window are stored and set per-document, using
    distinct paths with GSettings. We also use a timeout to so that we don't
    keep setting the settings over and over while we resize.

 data/org.gnome.yelp.gschema.xml |    7 +++-
 src/yelp-application.c          |   67 +++++++++++++++++++++++++++++++++++++-
 src/yelp-window.c               |   68 ++++++++++++++++++++++++++++++++++++---
 src/yelp-window.h               |   14 ++++---
 4 files changed, 142 insertions(+), 14 deletions(-)
---
diff --git a/data/org.gnome.yelp.gschema.xml b/data/org.gnome.yelp.gschema.xml
index 94b0adc..046f9d5 100644
--- a/data/org.gnome.yelp.gschema.xml
+++ b/data/org.gnome.yelp.gschema.xml
@@ -1,5 +1,5 @@
 <schemalist>
-<schema id="org.gnome.yelp" path="/org/gnome/yelp">
+<schema id="org.gnome.yelp" path="/org/gnome/yelp/">
   <key name="show-cursor" type="b">
     <default>false</default>
   </key>
@@ -16,4 +16,9 @@
     -->
   </key>
 </schema>
+<schema id="org.gnome.yelp.documents">
+  <key name="geometry" type="(ii)">
+    <default>(520,580)</default>
+  </key>
+</schema>
 </schemalist>
diff --git a/src/yelp-application.c b/src/yelp-application.c
index cea71b1..341c00a 100644
--- a/src/yelp-application.c
+++ b/src/yelp-application.c
@@ -73,6 +73,9 @@ static void          application_adjust_font           (GtkAction             *a
                                                         YelpApplication       *app);
 static void          application_set_font_sensitivity  (YelpApplication       *app);
 
+static gboolean      window_resized                    (YelpWindow            *window,
+                                                        YelpApplication       *app);
+
 G_DEFINE_TYPE (YelpApplication, yelp_application, G_TYPE_OBJECT);
 #define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_APPLICATION, YelpApplicationPrivate))
 
@@ -85,7 +88,9 @@ struct _YelpApplicationPrivate {
 
     GtkActionGroup *action_group;
 
+    gchar *gsettings_context; /* static, do not free */
     GSettings *gsettings;
+    GHashTable *docsettings;
 };
 
 static const GtkActionEntry action_entries[] = {
@@ -104,6 +109,10 @@ static const GtkActionEntry action_entries[] = {
 static void
 yelp_application_init (YelpApplication *app)
 {
+    YelpApplicationPrivate *priv = GET_PRIV (app);
+    priv->docsettings = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                               (GDestroyNotify) g_free,
+                                               (GDestroyNotify) g_object_unref);
 }
 
 static void
@@ -149,6 +158,7 @@ yelp_application_finalize (GObject *object)
     YelpApplicationPrivate *priv = GET_PRIV (object);
 
     g_hash_table_destroy (priv->windows_by_document);
+    g_hash_table_destroy (priv->docsettings);
 
     G_OBJECT_CLASS (yelp_application_parent_class)->finalize (object);
 }
@@ -170,8 +180,10 @@ application_setup (YelpApplication *app)
         gchar *keyfile = g_build_filename (g_get_user_config_dir (),
                                            "yelp", "yelp.cfg",
                                            NULL);
-        g_settings_backend_setup_keyfile ("yelp-", keyfile);
-        priv->gsettings = g_settings_new_with_context ("org.gnome.yelp", "yelp-");
+        g_settings_backend_setup_keyfile ("yelp", keyfile);
+        priv->gsettings_context = "yelp";
+        priv->gsettings = g_settings_new_with_context ("org.gnome.yelp",
+                                                       priv->gsettings_context);
         g_free (keyfile);
     }
     else {
@@ -411,13 +423,38 @@ application_uri_resolved (YelpUri             *uri,
         window = g_hash_table_lookup (priv->windows_by_document, doc_uri);
 
     if (window == NULL) {
+        gint width, height;
+        GSettings *settings = g_hash_table_lookup (priv->docsettings, doc_uri);
+        if (settings == NULL) {
+            gchar *tmp;
+            gchar *settings_path;
+            tmp = g_uri_escape_string (doc_uri, "", FALSE);
+            settings_path = g_strconcat ("/apps/yelp/documents/", tmp, "/", NULL);
+            g_free (tmp);
+            if (priv->gsettings_context)
+                settings = g_settings_new_with_context_and_path ("org.gnome.yelp.documents",
+                                                                 priv->gsettings_context,
+                                                                 settings_path);
+            else
+                settings = g_settings_new_with_path ("org.gnome.yelp.document",
+                                                     settings_path);
+            g_hash_table_insert (priv->docsettings, g_strdup (doc_uri), settings);
+            g_free (settings_path);
+        }
+
+        g_settings_get (settings, "geometry", "(ii)", &width, &height);
         window = yelp_window_new (data->app);
+        gtk_window_set_default_size (GTK_WINDOW (window), width, height);
+        g_signal_connect (window, "resized", window_resized, data->app);
         priv->windows = g_slist_prepend (priv->windows, window);
 
         if (!data->new) {
             g_hash_table_insert (priv->windows_by_document, doc_uri, window);
             g_object_set_data (G_OBJECT (window), "doc_uri", doc_uri);
         }
+        else {
+            g_free (doc_uri);
+        }
         g_signal_connect (window, "delete-event",
                           G_CALLBACK (application_window_deleted), data->app);
     }
@@ -522,3 +559,29 @@ yelp_application_install_package (YelpApplication  *app,
                              G_TYPE_STRING, "",
                              G_TYPE_INVALID, G_TYPE_INVALID);
 }
+
+static gboolean
+window_resized (YelpWindow        *window,
+                YelpApplication   *app)
+{
+    YelpApplicationPrivate *priv = GET_PRIV (app);
+    gint width, height;
+    YelpUri *uri;
+    gchar *doc_uri;
+    GSettings *settings;
+
+    uri = yelp_window_get_uri (window);
+    doc_uri = yelp_uri_get_document_uri (uri);
+    settings = g_hash_table_lookup (priv->docsettings, doc_uri);
+
+    if (settings) {
+        gint width, height;
+        yelp_window_get_geometry (window, &width, &height);
+        g_settings_set (settings, "geometry", "(ii)", width, height);
+    }
+
+    g_free (doc_uri);
+    g_object_unref (uri);
+
+    return FALSE;
+}
diff --git a/src/yelp-window.c b/src/yelp-window.c
index ef2dd1e..b5233d6 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -52,6 +52,10 @@ static void          yelp_window_set_property     (GObject            *object,
 static void          window_construct             (YelpWindow         *window);
 static void          window_new                   (GtkAction          *action,
                                                    YelpWindow         *window);
+static gboolean      window_configure_event       (YelpWindow         *window,
+                                                   GdkEventConfigure  *event,
+                                                   gpointer            user_data);
+static gboolean      window_resize_signal         (YelpWindow         *window);
 static void          window_close                 (GtkAction          *action,
                                                    YelpWindow         *window);
 static void          window_open_location         (GtkAction          *action,
@@ -104,6 +108,13 @@ enum {
     PROP_APPLICATION
 };
 
+enum {
+    RESIZE_EVENT,
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 G_DEFINE_TYPE (YelpWindow, yelp_window, GTK_TYPE_WINDOW);
 #define GET_PRIV(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_WINDOW, YelpWindowPrivate))
 
@@ -179,6 +190,10 @@ struct _YelpWindowPrivate {
     gboolean back_load;
 
     gulong entry_location_selected;
+
+    guint resize_signal;
+    gint width;
+    gint height;
 };
 
 static const GtkActionEntry entries[] = {
@@ -216,6 +231,7 @@ static const GtkActionEntry entries[] = {
 static void
 yelp_window_init (YelpWindow *window)
 {
+    g_signal_connect (window, "configure-event", window_configure_event, NULL);
 }
 
 static void
@@ -238,6 +254,14 @@ yelp_window_class_init (YelpWindowClass *klass)
 							  G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
 							  G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 
+    signals[RESIZE_EVENT] =
+        g_signal_new ("resized",
+                      G_OBJECT_CLASS_TYPE (klass),
+                      G_SIGNAL_RUN_LAST,
+                      0, NULL, NULL,
+                      g_cclosure_marshal_VOID__VOID,
+                      G_TYPE_NONE, 0);
+
     g_type_class_add_private (klass, sizeof (YelpWindowPrivate));
 }
 
@@ -320,12 +344,10 @@ window_construct (YelpWindow *window)
 {
     GtkWidget *vbox, *scroll;
     GtkAction *action;
-    GError *error = NULL;
     GtkTreeIter iter;
     YelpWindowPrivate *priv = GET_PRIV (window);
 
     gtk_window_set_icon_name (GTK_WINDOW (window), "help-browser");
-    gtk_window_set_default_size (GTK_WINDOW (window), 520, 580);
 
     vbox = gtk_vbox_new (FALSE, 0);
     gtk_container_add (GTK_CONTAINER (window), vbox);
@@ -461,12 +483,23 @@ yelp_window_load_uri (YelpWindow  *window,
     yelp_view_load_uri (priv->view, uri);
 }
 
-GtkActionGroup *
-yelp_window_get_action_group (YelpWindow *window)
+YelpUri *
+yelp_window_get_uri (YelpWindow *window)
 {
+    YelpUri *uri;
     YelpWindowPrivate *priv = GET_PRIV (window);
+    g_object_get (G_OBJECT (priv->view), "yelp-uri", &uri, NULL);
+    return uri;
+}
 
-    return priv->action_group;
+void
+yelp_window_get_geometry (YelpWindow  *window,
+                          gint        *width,
+                          gint        *height)
+{
+    YelpWindowPrivate *priv = GET_PRIV (window);
+    *width = priv->width;
+    *height = priv->height;
 }
 
 /******************************************************************************/
@@ -485,6 +518,31 @@ window_new (GtkAction *action, YelpWindow *window)
     g_free (uri);
 }
 
+static gboolean
+window_configure_event (YelpWindow         *window,
+                        GdkEventConfigure  *event,
+                        gpointer            user_data)
+{
+    YelpWindowPrivate *priv = GET_PRIV (window);
+    priv->width = event->width;
+    priv->height = event->height;
+    if (priv->resize_signal > 0)
+        g_source_remove (priv->resize_signal);
+    priv->resize_signal = g_timeout_add (200,
+                                         (GSourceFunc) window_resize_signal,
+                                         window);
+    return FALSE;
+}
+
+static gboolean
+window_resize_signal (YelpWindow *window)
+{
+    YelpWindowPrivate *priv = GET_PRIV (window);
+    g_signal_emit (window, signals[RESIZE_EVENT], 0);
+    priv->resize_signal = 0;
+    return FALSE;
+}
+
 static void
 window_close (GtkAction *action, YelpWindow *window)
 {
diff --git a/src/yelp-window.h b/src/yelp-window.h
index 58084dc..6231e16 100644
--- a/src/yelp-window.h
+++ b/src/yelp-window.h
@@ -46,11 +46,13 @@ struct _YelpWindowClass
     GtkWindowClass  parent_class;
 };
 
-GType             yelp_window_get_type    (void);
-YelpWindow *      yelp_window_new         (YelpApplication *app);
-void              yelp_window_load_uri    (YelpWindow      *window,
-                                           YelpUri         *uri);
-
-GtkActionGroup *  yelp_window_get_action_group  (YelpWindow  *window);
+GType             yelp_window_get_type     (void);
+YelpWindow *      yelp_window_new          (YelpApplication *app);
+void              yelp_window_load_uri     (YelpWindow      *window,
+                                            YelpUri         *uri);
+YelpUri *         yelp_window_get_uri      (YelpWindow      *window);
+void              yelp_window_get_geometry (YelpWindow      *window,
+                                            gint            *width,
+                                            gint            *height);
 
 #endif /* __YELP_WINDOW_H__ */



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