[sound-juicer/wip/gsettings: 2/3] Store/restore the window size using gsettings



commit b677a0ccb55947747a38a945f1be1f62ae688bfa
Author: Gert Michael Kulyk <gkulyk klio>
Date:   Sun Sep 2 03:07:57 2012 +0200

    Store/restore the window size using gsettings
    
    Part of the fixes for bgo #625897.

 src/Makefile.am       |    2 +
 src/sj-main.c         |   19 ++--
 src/sj-window-prefs.c |  336 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/sj-window-prefs.h |   76 +++++++++++
 4 files changed, 424 insertions(+), 9 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 37b2d9c..d11218c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,6 +16,8 @@ sound_juicer_SOURCES = \
        sj-inhibit.c \
        sj-genres.h \
        sj-genres.c \
+       sj-window-prefs.h \
+       sj-window-prefs.c \
        egg-play-preview.c \
        egg-play-preview.h
 
diff --git a/src/sj-main.c b/src/sj-main.c
index baf42cb..4d5d03c 100644
--- a/src/sj-main.c
+++ b/src/sj-main.c
@@ -52,6 +52,7 @@
 #include "sj-prefs.h"
 #include "sj-play.h"
 #include "sj-genres.h"
+#include "sj-window-prefs.h"
 
 gboolean on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data);
 
@@ -1315,9 +1316,9 @@ static void reread_cd (gboolean ignore_no_media)
 }
 
 static void
-media_added_cb (BraseroMediumMonitor   *drive,
-               BraseroMedium           *medium,
-                gpointer                data)
+media_added_cb (BraseroMediumMonitor  *drive,
+                BraseroMedium         *medium,
+                gpointer               data)
 {
   if (extracting == TRUE) {
     /* FIXME: recover? */
@@ -1328,9 +1329,9 @@ media_added_cb (BraseroMediumMonitor      *drive,
 }
 
 static void
-media_removed_cb (BraseroMediumMonitor *drive,
-                 BraseroMedium         *medium,
-                  gpointer           data)
+media_removed_cb (BraseroMediumMonitor  *drive,
+                  BraseroMedium         *medium,
+                  gpointer               data)
 {
   if (extracting == TRUE) {
     /* FIXME: recover? */
@@ -1943,8 +1944,8 @@ is_cd_duplication_available()
 
   /* Now check that there is at least one cd recorder available */
   BraseroMediumMonitor     *monitor;
-  GSList                  *drives;
-  GSList                  *iter;
+  GSList                   *drives;
+  GSList                   *iter;
 
   monitor = brasero_medium_monitor_get_default ();
   drives = brasero_medium_monitor_get_drives (monitor, BRASERO_DRIVE_TYPE_ALL);
@@ -2299,7 +2300,7 @@ startup_cb (GApplication *app, gpointer user_data)
   set_action_enabled ("duplicate", FALSE);
   duplication_enabled = is_cd_duplication_available();
 
-  /*gconf_bridge_bind_window_size(gconf_bridge_get(), GCONF_WINDOW, GTK_WINDOW (main_window));*/
+  sj_window_prefs_bind_window_size(sj_window_prefs_get(), GTK_WINDOW (main_window));
 
   gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (main_window));
   gtk_widget_show (main_window);
diff --git a/src/sj-window-prefs.c b/src/sj-window-prefs.c
new file mode 100644
index 0000000..886aebf
--- /dev/null
+++ b/src/sj-window-prefs.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2005 OpenedHand Ltd.
+ * Copyright (C) 2012 Gert Michael Kulyk <gkulyk yahoo de>
+ *
+ * Sound Juicer - sj-window-prefs.c
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Jorn Baayen <jorn openedhand com>
+ *          Gert Michael Kulyk <gkulyk yahoo de>
+ *
+ * This file is based on gconf-prefs.c, (C) 2005 OpenedHand Ltd.
+ * Original Author: Jorn Baayen <jorn openedhand com>
+ *
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "sj-window-prefs.h"
+
+struct _SJWindowPrefs {
+        GSettings *settings;
+
+        GHashTable *bindings;
+};
+
+typedef enum {
+        BINDING_PROP,
+        BINDING_WINDOW,
+        BINDING_LIST_STORE
+} BindingType;
+
+typedef struct {
+        BindingType type;
+        guint id;
+
+        gboolean bind_size;
+        gboolean bind_pos;
+
+        GtkWindow *window;
+        gulong configure_event_id;
+        gulong unmap_id;
+        guint sync_timeout_id;
+} WindowBinding;
+
+static SJWindowPrefs *prefs = NULL; /* Global SJWindowPrefs object */
+
+/* Generate an ID for a new binding */
+static guint
+new_id (void)
+{
+        static guint id_counter = 0;
+
+        id_counter++;
+
+        return id_counter;
+}
+
+/*
+ * Window bindings
+ */
+
+/* Performs a scheduled dimensions-to-prefs sync for a window binding */
+static gboolean
+window_binding_perform_scheduled_sync (WindowBinding *binding)
+{
+        if (binding->bind_size) {
+                int width, height;
+                GdkWindowState state;
+
+                state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (binding->window)));
+
+                if (state & GDK_WINDOW_STATE_MAXIMIZED) {
+                        g_settings_set_boolean (prefs->settings, "maximized", TRUE);
+                } else {
+                        gtk_window_get_size (binding->window, &width, &height);
+
+                        g_settings_set_int (prefs->settings, "width", width);
+
+                        g_settings_set_int (prefs->settings, "height", height);
+
+                        g_settings_set_boolean (prefs->settings, "maximized", FALSE);
+                }
+        }
+
+        if (binding->bind_pos) {
+                int x, y;
+
+                gtk_window_get_position (binding->window, &x, &y);
+
+                g_settings_set_int (prefs->settings, "position-x", x);
+
+                g_settings_set_int (prefs->settings, "position-y", y);
+        }
+
+        binding->sync_timeout_id = 0;
+
+        return FALSE;
+}
+
+#define WINDOW_BINDING_SYNC_DELAY 1000 /* Delay before syncing new window
+                                          dimensions to GSettings, in ms */
+
+/* Called when the window han been resized or moved */
+static gboolean
+window_binding_configure_event_cb (GtkWindow         *window,
+                                   GdkEventConfigure *event,
+                                   WindowBinding     *binding)
+{
+        /* Schedule a sync */
+        if (binding->sync_timeout_id == 0) {
+                binding->sync_timeout_id =
+                        g_timeout_add (WINDOW_BINDING_SYNC_DELAY,
+                                       (GSourceFunc)
+                                          window_binding_perform_scheduled_sync,
+                                       binding);
+        }
+
+        return FALSE;
+}
+
+/* Called when the window state is being changed */
+static gboolean
+window_binding_state_event_cb (GtkWindow           *window,
+                               GdkEventWindowState *event,
+                               WindowBinding       *binding)
+{
+        window_binding_perform_scheduled_sync (binding);
+
+        return FALSE;
+}
+
+/* Called when the window is being unmapped */
+static gboolean
+window_binding_unmap_cb (GtkWindow     *window,
+                         WindowBinding *binding)
+{
+        /* Force sync */
+        if (binding->sync_timeout_id > 0)
+                g_source_remove (binding->sync_timeout_id);
+
+        window_binding_perform_scheduled_sync (binding);
+
+        return FALSE;
+}
+
+/* Called when a window is destroyed */
+static void
+window_binding_window_destroyed (gpointer user_data,
+                                 GObject *where_the_object_was)
+{
+        WindowBinding *binding;
+
+        binding = (WindowBinding *) user_data;
+        binding->window = NULL; /* Don't do anything with the window
+                                   at unbind() */
+
+        g_hash_table_remove (prefs->bindings,
+                             GUINT_TO_POINTER (binding->id));
+}
+
+/**
+ * sj_window_prefs_bind_window
+ * @prefs: A #SJWindowPrefs
+ * @window: A #GtkWindow
+ * @bind_size: TRUE to bind the size of @window
+ * @bind_pos: TRUE to bind the position of @window
+ *
+ * On calling this function @window will be resized to the values
+ * specified by "@key_prefix<!-- -->_width" and "@key_prefix<!-- -->_height"
+ * and maximixed if "@key_prefix<!-- -->_maximized is TRUE if
+ * @bind_size is TRUE, and moved to the values specified by
+ * "@key_prefix<!-- -->_x" and "@key_prefix<!-- -->_y" if @bind_pos is TRUE.
+ * The respective GSettings keys will be updated when the window is resized
+ * and/or moved.
+ *
+ * Return value: The ID of the new binding.
+ **/
+guint
+sj_window_prefs_bind_window (SJWindowPrefs *prefs,
+                          GtkWindow   *window,
+                          gboolean     bind_size,
+                          gboolean     bind_pos)
+{
+        WindowBinding *binding;
+
+        g_return_val_if_fail (prefs != NULL, 0);
+        g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
+
+        /* Create new binding. */
+        binding = g_new (WindowBinding, 1);
+
+        binding->type = BINDING_WINDOW;
+        binding->id = new_id ();
+        binding->bind_size = bind_size;
+        binding->bind_pos = bind_pos;
+        binding->window = window;
+        binding->sync_timeout_id = 0;
+
+        /* Set up keys & sync window to GSettings values */
+        if (bind_size) {
+                int width_val, height_val;
+                gboolean maximized_val;
+
+                width_val = g_settings_get_int (prefs->settings, "width");
+
+                height_val = g_settings_get_int (prefs->settings, "height");
+
+                maximized_val = g_settings_get_boolean (prefs->settings, "maximized");
+
+                if (width_val && height_val) {
+                        gtk_window_resize (window, width_val, height_val);
+                }
+
+                if (maximized_val) {
+                        if (maximized_val) {
+                                gtk_window_maximize (window);
+                        }
+                }
+        }
+
+        if (bind_pos) {
+                int x_val, y_val;
+
+                x_val = g_settings_get_int (prefs->settings, "position-x");
+
+                y_val = g_settings_get_int (prefs->settings, "position-y");
+
+                if (x_val && y_val) {
+                        gtk_window_move (window, x_val, y_val);
+                }
+        }
+
+        /* Connect to window size change notifications */
+        binding->configure_event_id =
+                g_signal_connect (window,
+                                  "configure-event",
+                                  G_CALLBACK
+                                        (window_binding_configure_event_cb),
+                                  binding);
+
+        binding->configure_event_id =
+                g_signal_connect (window,
+                                  "window_state_event",
+                                  G_CALLBACK
+                                        (window_binding_state_event_cb),
+                                  binding);
+        binding->unmap_id =
+                g_signal_connect (window,
+                                  "unmap",
+                                  G_CALLBACK (window_binding_unmap_cb),
+                                  binding);
+
+        /* Handle case where window gets destroyed */
+        g_object_weak_ref (G_OBJECT (window),
+                           window_binding_window_destroyed, binding);
+
+        /* Insert binding */
+        g_hash_table_insert (prefs->bindings,
+                             GUINT_TO_POINTER (binding->id), binding);
+
+        /* Done */
+        return binding->id;
+}
+
+/* Unbinds a window binding */
+static void
+window_binding_unbind (WindowBinding *binding)
+{
+        if (binding->sync_timeout_id > 0)
+                g_source_remove (binding->sync_timeout_id);
+
+        /* The window might have been destroyed .. */
+        if (binding->window) {
+                g_signal_handler_disconnect (binding->window,
+                                             binding->configure_event_id);
+                g_signal_handler_disconnect (binding->window,
+                                             binding->unmap_id);
+
+                g_object_weak_unref (G_OBJECT (binding->window),
+                                     window_binding_window_destroyed, binding);
+        }
+        g_free (binding);
+}
+
+/* Free up all resources allocated by the SJWindowPrefs. Called on exit. */
+static void
+destroy_prefs (void)
+{
+    g_hash_table_destroy (prefs->bindings);
+
+    if (prefs->settings)
+        g_object_unref (prefs->settings);
+
+    g_free (prefs);
+}
+
+/**
+ * sj_window_prefs_get
+ *
+ * Returns the #SJWindowPrefs. This is a singleton object.
+ *
+ * Return value: The #SJWindowPrefs.
+ **/
+SJWindowPrefs *
+sj_window_prefs_get (void)
+{
+        if (prefs)
+            return prefs;
+
+        prefs = g_new (SJWindowPrefs, 1);
+
+        prefs->settings = g_settings_new ("org.gnome.SoundJuicer");
+        prefs->bindings = g_hash_table_new_full (NULL, NULL, NULL,
+                                                (GDestroyNotify) window_binding_unbind);
+
+        atexit (destroy_prefs);
+
+        return prefs;
+}
diff --git a/src/sj-window-prefs.h b/src/sj-window-prefs.h
new file mode 100644
index 0000000..884de7b
--- /dev/null
+++ b/src/sj-window-prefs.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2005 OpenedHand Ltd.
+ * Copyright (C) 2012 Gert Michael Kulyk <gkulyk yahoo de>
+ *
+ * Sound Juicer - sj-window-prefs.h
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: Jorn Baayen <jorn openedhand com>
+ *          Gert Michael Kulyk <gkulyk yahoo de>
+ *
+ * This file is based on gconf-prefs.c, (C) 2005 OpenedHand Ltd.
+ * Original Author: Jorn Baayen <jorn openedhand com>
+ *
+ */
+
+#ifndef __SJ_WINDOW_PREFS_H__
+#define __SJ_WINDOW_PREFS_H__
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _SJWindowPrefs SJWindowPrefs;
+
+SJWindowPrefs *sj_window_prefs_get           (void);
+
+guint        sj_window_prefs_bind_window        (SJWindowPrefs  *prefs,
+                                                  GtkWindow    *window,
+                                                  gboolean      bind_size,
+                                                  gboolean      bind_pos);
+
+/**
+ * sj_window_prefs_bind_window_size
+ * @prefs: A #SJWindowPrefs
+ * @window: A #GtkWindow
+ *
+ * On calling this function @window will be resized to the values specified by
+ * "width" and "height".  The respective
+ * GSettings values will be updated when the window is resized. See
+ * #sj_window_prefs_bind_window for more details.
+ **/
+#define sj_window_prefs_bind_window_size(prefs, window) \
+        sj_window_prefs_bind_window ((prefs), (window), TRUE, FALSE)
+
+/**
+ * sj_window_prefs_bind_window_pos
+ * @prefs: A #SJWindowPrefs
+ * @window: A #GtkWindow
+ *
+ * On calling this function @window will be moved to the values specified by
+ * "position-x" and "position-y". The respective
+ * values will be updated when the window is moved. See
+ * #sj_window_prefs_bind_window for more details.
+ **/
+#define sj_window_prefs_bind_window_pos(prefs, window) \
+        sj_window_prefs_bind_window ((prefs), (window), FALSE, TRUE)
+
+
+G_END_DECLS
+
+#endif /* __SJ_WINDOW_PREFS_H__ */


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