gnome-media r4129 - in trunk: . gnome-volume-control gnome-volume-control/data gnome-volume-control/data/sounds gnome-volume-control/src



Author: mccann
Date: Mon Dec 22 00:55:04 2008
New Revision: 4129
URL: http://svn.gnome.org/viewvc/gnome-media?rev=4129&view=rev

Log:
2008-12-21  William Jon McCann  <jmccann redhat com>

	* data/Makefile.am:
	* data/sounds/Makefile.am:
	* data/sounds/gnome-sounds-default.xml.in.in:
	* src/Makefile.am:
	* src/gvc-mixer-dialog.c (gvc_mixer_dialog_constructor):
	* src/gvc-sound-theme-chooser.c (set_combox_for_theme_name),
	(xml_get_and_trim_names), (populate_model_from_node),
	(populate_model_from_file), (populate_model_from_dir),
	(save_alert_sounds), (update_alert_model), (update_alert),
	(on_alert_toggled), (play_preview_for_path),
	(create_alert_treeview), (get_file_type),
	(update_alerts_from_theme_name), (update_theme),
	(gvc_sound_theme_chooser_init):
	* src/sound-theme-file-utils.c (custom_theme_dir_is_empty),
	(delete_old_files), (delete_disabled_files), (add_disabled_file),
	(add_custom_file), (create_custom_theme):
	* src/sound-theme-file-utils.h:
	Add sound set.  Properly set the active alert sound in the
	model.



Added:
   trunk/gnome-volume-control/data/sounds/
   trunk/gnome-volume-control/data/sounds/Makefile.am
   trunk/gnome-volume-control/data/sounds/bark.ogg   (contents, props changed)
   trunk/gnome-volume-control/data/sounds/gnome-sounds-default.xml.in.in   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/gnome-volume-control/ChangeLog
   trunk/gnome-volume-control/data/Makefile.am
   trunk/gnome-volume-control/src/Makefile.am
   trunk/gnome-volume-control/src/gvc-mixer-dialog.c
   trunk/gnome-volume-control/src/gvc-sound-theme-chooser.c
   trunk/gnome-volume-control/src/sound-theme-file-utils.c
   trunk/gnome-volume-control/src/sound-theme-file-utils.h

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Mon Dec 22 00:55:04 2008
@@ -94,6 +94,7 @@
         gio-2.0
         gconf-2.0 >= $GCONF_REQUIRED_VERSION
         libcanberra-gtk >= $CANBERRA_REQUIRED_VERSION
+        libxml-2.0
 )
 AC_SUBST(VOLUME_CONTROL_CFLAGS)
 AC_SUBST(VOLUME_CONTROL_LIBS)
@@ -652,6 +653,7 @@
 gnome-volume-control/data/icons/scalable/Makefile
 gnome-volume-control/data/icons/scalable/apps/Makefile
 gnome-volume-control/data/icons/scalable/status/Makefile
+gnome-volume-control/data/sounds/Makefile
 gnome-volume-control/src/Makefile
 vu-meter/Makefile
 cddb-slave2/Makefile

Modified: trunk/gnome-volume-control/data/Makefile.am
==============================================================================
--- trunk/gnome-volume-control/data/Makefile.am	(original)
+++ trunk/gnome-volume-control/data/Makefile.am	Mon Dec 22 00:55:04 2008
@@ -2,6 +2,7 @@
 
 SUBDIRS =			\
 	icons			\
+	sounds			\
 	$(NULL)
 
 @INTLTOOL_DESKTOP_RULE@

Added: trunk/gnome-volume-control/data/sounds/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/gnome-volume-control/data/sounds/Makefile.am	Mon Dec 22 00:55:04 2008
@@ -0,0 +1,24 @@
+NULL =
+
+sounddir = $(datadir)/sounds/gnome/default/alerts
+
+sound_DATA =			\
+	bark.ogg		\
+	$(NULL)
+
+metadata_in_files = gnome-sounds-default.xml.in
+metadatadir = $(pkgdatadir)/sounds
+metadata_DATA = $(metadata_in_files:.xml.in=.xml)
+ INTLTOOL_XML_RULE@
+
+noinst_DATA = gnome-sounds-default.xml.in
+CLEANFILES = gnome-sounds-default.xml gnome-sounds-default.xml.in
+
+EXTRA_DIST = $(sound_DATA) gnome-sounds-default.xml.in.in
+
+gnome-sounds-default.xml.in: gnome-sounds-default.xml.in.in Makefile
+	sed -e 's^\ datadir\@^$(datadir)^g' < $(srcdir)/gnome-sounds-default.xml.in.in > gnome-sounds-default.xml.in.tmp \
+	&& mv gnome-sounds-default.xml.in.tmp gnome-sounds-default.xml.in
+
+MAINTAINERCLEANFILES = \
+	Makefile.in

Added: trunk/gnome-volume-control/data/sounds/bark.ogg
==============================================================================
Binary file. No diff available.

Added: trunk/gnome-volume-control/data/sounds/gnome-sounds-default.xml.in.in
==============================================================================
--- (empty file)
+++ trunk/gnome-volume-control/data/sounds/gnome-sounds-default.xml.in.in	Mon Dec 22 00:55:04 2008
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<sounds>
+  <sound deleted="false">
+    <!-- Translators: This is the name of an audio file that sounds like the bark of a dog.
+         You might want to translate it into the equivalent words of your language.  -->
+    <_name>Bark</_name>
+    <filename>@datadir@/sounds/gnome/default/alerts/bark.ogg</filename>
+  </sound>
+</sounds>

Modified: trunk/gnome-volume-control/src/Makefile.am
==============================================================================
--- trunk/gnome-volume-control/src/Makefile.am	(original)
+++ trunk/gnome-volume-control/src/Makefile.am	Mon Dec 22 00:55:04 2008
@@ -13,6 +13,7 @@
 	-DLIBEXECDIR=\"$(libexecdir)\"		\
 	-DGLADEDIR=\""$(pkgdatadir)"\"		\
 	-DSOUND_DATA_DIR="\"$(datadir)/sounds\"" \
+	-DSOUND_SET_DIR="\"$(pkgdatadir)/sounds\"" \
 	-DICON_DATA_DIR="\"$(pkgdatadir)/icons\"" \
 	$(NULL)
 

Modified: trunk/gnome-volume-control/src/gvc-mixer-dialog.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-mixer-dialog.c	(original)
+++ trunk/gnome-volume-control/src/gvc-mixer-dialog.c	Mon Dec 22 00:55:04 2008
@@ -1026,7 +1026,7 @@
         self->priv->sound_theme_chooser = gvc_sound_theme_chooser_new ();
         gtk_box_pack_start (GTK_BOX (self->priv->sound_effects_box),
                             self->priv->sound_theme_chooser,
-                            TRUE, TRUE, 0);
+                            TRUE, TRUE, 6);
 
         /* Input page */
         self->priv->input_box = gtk_vbox_new (FALSE, 12);

Modified: trunk/gnome-volume-control/src/gvc-sound-theme-chooser.c
==============================================================================
--- trunk/gnome-volume-control/src/gvc-sound-theme-chooser.c	(original)
+++ trunk/gnome-volume-control/src/gvc-sound-theme-chooser.c	Mon Dec 22 00:55:04 2008
@@ -29,6 +29,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <canberra-gtk.h>
+#include <libxml/tree.h>
 
 #include <gconf/gconf-client.h>
 
@@ -79,6 +80,8 @@
 };
 
 enum {
+        SOUND_TYPE_UNSET,
+        SOUND_TYPE_OFF,
         SOUND_TYPE_DEFAULT_FROM_THEME,
         SOUND_TYPE_BUILTIN,
         SOUND_TYPE_CUSTOM
@@ -227,8 +230,6 @@
         GtkTreeModel *model;
         gboolean      found;
 
-        g_debug ("setting theme %s", name ? name : "(null)");
-
         /* If the name is empty, use "freedesktop" */
         if (name == NULL || *name == '\0') {
                 name = "freedesktop";
@@ -268,41 +269,6 @@
 }
 
 static void
-update_theme (GvcSoundThemeChooser *chooser)
-{
-        char        *theme_name;
-        gboolean     events_enabled;
-        gboolean     bell_enabled;
-        GConfClient *client;
-        gboolean     feedback_enabled;
-
-        client = gconf_client_get_default ();
-
-        bell_enabled = gconf_client_get_bool (client, AUDIO_BELL_KEY, NULL);
-        //set_audible_bell_enabled (chooser, bell_enabled);
-
-        feedback_enabled = gconf_client_get_bool (client, INPUT_SOUNDS_KEY, NULL);
-        set_input_feedback_enabled (chooser, feedback_enabled);
-
-        events_enabled = gconf_client_get_bool (client, EVENT_SOUNDS_KEY, NULL);
-        if (events_enabled) {
-                theme_name = gconf_client_get_string (client, SOUND_THEME_KEY, NULL);
-        } else {
-                theme_name = g_strdup (NO_SOUNDS_THEME_NAME);
-        }
-
-        gtk_widget_set_sensitive (chooser->priv->selection_box, events_enabled);
-
-        set_combox_for_theme_name (chooser, theme_name);
-
-        /* FIXME: update alerts */
-
-        g_free (theme_name);
-
-        g_object_unref (client);
-}
-
-static void
 setup_theme_selector (GvcSoundThemeChooser *chooser)
 {
         GHashTable           *hash;
@@ -377,6 +343,310 @@
                           chooser);
 }
 
+#define GVC_SOUND_SOUND    (xmlChar *) "sound"
+#define GVC_SOUND_NAME     (xmlChar *) "name"
+#define GVC_SOUND_FILENAME (xmlChar *) "filename"
+
+/* Adapted from yelp-toc-pager.c */
+static xmlChar *
+xml_get_and_trim_names (xmlNodePtr node)
+{
+        xmlNodePtr cur, keep = NULL;
+        xmlChar *keep_lang = NULL;
+        xmlChar *value;
+        int j, keep_pri = INT_MAX;
+
+        const gchar * const * langs = g_get_language_names ();
+
+        value = NULL;
+
+        for (cur = node->children; cur; cur = cur->next) {
+                if (! xmlStrcmp (cur->name, GVC_SOUND_NAME)) {
+                        xmlChar *cur_lang = NULL;
+                        int cur_pri = INT_MAX;
+
+                        cur_lang = xmlNodeGetLang (cur);
+
+                        if (cur_lang) {
+                                for (j = 0; langs[j]; j++) {
+                                        if (g_str_equal (cur_lang, langs[j])) {
+                                                cur_pri = j;
+                                                break;
+                                        }
+                                }
+                        } else {
+                                cur_pri = INT_MAX - 1;
+                        }
+
+                        if (cur_pri <= keep_pri) {
+                                if (keep_lang)
+                                        xmlFree (keep_lang);
+                                if (value)
+                                        xmlFree (value);
+
+                                value = xmlNodeGetContent (cur);
+
+                                keep_lang = cur_lang;
+                                keep_pri = cur_pri;
+                                keep = cur;
+                        } else {
+                                if (cur_lang)
+                                        xmlFree (cur_lang);
+                        }
+                }
+        }
+
+        /* Delete all GVC_SOUND_NAME nodes */
+        cur = node->children;
+        while (cur) {
+                xmlNodePtr this = cur;
+                cur = cur->next;
+                if (! xmlStrcmp (this->name, GVC_SOUND_NAME)) {
+                        xmlUnlinkNode (this);
+                        xmlFreeNode (this);
+                }
+        }
+
+        return value;
+}
+
+static void
+populate_model_from_node (GvcSoundThemeChooser *chooser,
+                          GtkTreeModel         *model,
+                          xmlNodePtr            node)
+{
+        xmlNodePtr child;
+        xmlChar   *filename;
+        xmlChar   *name;
+
+        filename = NULL;
+        name = xml_get_and_trim_names (node);
+        for (child = node->children; child; child = child->next) {
+                if (xmlNodeIsText (child)) {
+                        continue;
+                }
+
+                if (xmlStrcmp (child->name, GVC_SOUND_FILENAME) == 0) {
+                        filename = xmlNodeGetContent (child);
+                } else if (xmlStrcmp (child->name, GVC_SOUND_NAME) == 0) {
+                        /* EH? should have been trimmed */
+                }
+        }
+
+        if (filename != NULL && name != NULL) {
+                gtk_list_store_insert_with_values (GTK_LIST_STORE (model),
+                                                   NULL,
+                                                   G_MAXINT,
+                                                   ALERT_IDENTIFIER_COL, filename,
+                                                   ALERT_DISPLAY_COL, name,
+                                                   ALERT_SOUND_TYPE_COL, _("Built-in"),
+                                                   ALERT_ACTIVE_COL, FALSE,
+                                                   -1);
+        }
+
+        xmlFree (filename);
+        xmlFree (name);
+}
+
+static void
+populate_model_from_file (GvcSoundThemeChooser *chooser,
+                          GtkTreeModel         *model,
+                          const char           *filename)
+{
+        xmlDocPtr  doc;
+        xmlNodePtr root;
+        xmlNodePtr child;
+        gboolean   exists;
+
+        exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+        if (! exists) {
+                return;
+        }
+
+        doc = xmlParseFile (filename);
+        if (doc == NULL) {
+                return;
+        }
+
+        root = xmlDocGetRootElement (doc);
+
+        for (child = root->children; child; child = child->next) {
+                if (xmlNodeIsText (child)) {
+                        continue;
+                }
+                if (xmlStrcmp (child->name, GVC_SOUND_SOUND) != 0) {
+                        continue;
+                }
+
+                populate_model_from_node (chooser, model, child);
+        }
+
+        xmlFreeDoc (doc);
+}
+
+static void
+populate_model_from_dir (GvcSoundThemeChooser *chooser,
+                         GtkTreeModel         *model,
+                         const char           *dirname)
+{
+        GDir       *d;
+        const char *name;
+
+        d = g_dir_open (dirname, 0, NULL);
+        if (d == NULL) {
+                return;
+        }
+
+        while ((name = g_dir_read_name (d)) != NULL) {
+                char *path;
+
+                if (! g_str_has_suffix (name, ".xml")) {
+                        continue;
+                }
+
+                path = g_build_filename (dirname, name, NULL);
+                populate_model_from_file (chooser, model, path);
+                g_free (path);
+        }
+}
+
+static gboolean
+save_alert_sounds (GvcSoundThemeChooser  *chooser,
+                   const char            *id)
+{
+        const char *sounds[3] = { "bell-terminal", "bell-window-system", NULL };
+
+        if (strcmp (id, DEFAULT_ALERT_ID) == 0) {
+                delete_old_files (sounds);
+                delete_disabled_files (sounds);
+        } else {
+                delete_old_files (sounds);
+                delete_disabled_files (sounds);
+                add_custom_file (sounds, id);
+        }
+
+        return FALSE;
+}
+
+
+static void
+update_alert_model (GvcSoundThemeChooser  *chooser,
+                    const char            *id)
+{
+        GtkTreeModel *model;
+        GtkTreeIter   iter;
+
+        model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
+        gtk_tree_model_get_iter_first (model, &iter);
+        do {
+                gboolean toggled;
+                char    *this_id;
+
+                gtk_tree_model_get (model, &iter,
+                                    ALERT_IDENTIFIER_COL, &this_id,
+                                    -1);
+
+                if (strcmp (this_id, id) == 0) {
+                        toggled = TRUE;
+                } else {
+                        toggled = FALSE;
+                }
+                g_free (this_id);
+
+                gtk_list_store_set (GTK_LIST_STORE (model),
+                                    &iter,
+                                    ALERT_ACTIVE_COL, toggled,
+                                    -1);
+        } while (gtk_tree_model_iter_next (model, &iter));
+}
+
+static void
+update_alert (GvcSoundThemeChooser *chooser,
+              const char           *alert_id)
+{
+        GtkTreeModel *theme_model;
+        GtkTreeIter   iter;
+        char         *theme;
+        char         *parent;
+        gboolean      is_custom;
+        gboolean      is_default;
+        gboolean      add_custom;
+        gboolean      remove_custom;
+
+        theme_model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser->priv->combo_box));
+        /* Get the current theme's name, and set the parent */
+        if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser->priv->combo_box), &iter) == FALSE) {
+                return;
+        }
+
+        gtk_tree_model_get (theme_model, &iter,
+                            THEME_IDENTIFIER_COL, &theme,
+                            THEME_IDENTIFIER_COL, &parent,
+                            -1);
+        is_custom = strcmp (theme, CUSTOM_THEME_NAME) == 0;
+        is_default = strcmp (alert_id, DEFAULT_ALERT_ID) == 0;
+
+        /* So a few possibilities:
+         * 1. Named theme, default alert selected: noop
+         * 2. Named theme, alternate alert selected: create new custom with sound
+         * 3. Custom theme, default alert selected: remove sound and possibly custom
+         * 4. Custom theme, alternate alert selected: update custom sound
+         */
+        add_custom = FALSE;
+        remove_custom = FALSE;
+        if (! is_custom && is_default) {
+                /* remove custom just in case */
+                remove_custom = TRUE;
+        } else if (! is_custom && ! is_default) {
+                create_custom_theme (parent);
+                save_alert_sounds (chooser, alert_id);
+                add_custom = TRUE;
+        } else if (is_custom && is_default) {
+                save_alert_sounds (chooser, alert_id);
+                /* after removing files check if it is empty */
+                if (custom_theme_dir_is_empty ()) {
+                        remove_custom = TRUE;
+                }
+        } else if (is_custom && ! is_default) {
+                save_alert_sounds (chooser, alert_id);
+        }
+
+        if (add_custom) {
+                gtk_list_store_insert_with_values (GTK_LIST_STORE (theme_model),
+                                                   NULL,
+                                                   G_MAXINT,
+                                                   THEME_DISPLAY_COL, _("Custom"),
+                                                   THEME_IDENTIFIER_COL, CUSTOM_THEME_NAME,
+                                                   THEME_PARENT_ID_COL, theme,
+                                                   -1);
+                set_combox_for_theme_name (chooser, CUSTOM_THEME_NAME);
+        } else if (remove_custom) {
+                gtk_tree_model_get_iter_first (theme_model, &iter);
+                do {
+                        char *this_parent;
+
+                        gtk_tree_model_get (theme_model, &iter,
+                                            THEME_PARENT_ID_COL, &this_parent,
+                                            -1);
+                        if (this_parent != NULL && strcmp (this_parent, CUSTOM_THEME_NAME) != 0) {
+                                g_free (this_parent);
+                                gtk_list_store_remove (GTK_LIST_STORE (theme_model), &iter);
+                                break;
+                        }
+                        g_free (this_parent);
+                } while (gtk_tree_model_iter_next (theme_model, &iter));
+
+                delete_custom_theme_dir ();
+
+                set_combox_for_theme_name (chooser, parent);
+        }
+
+        update_alert_model (chooser, alert_id);
+
+        g_free (theme);
+        g_free (parent);
+}
+
 static void
 on_alert_toggled (GtkCellRendererToggle *renderer,
                   char                  *path_str,
@@ -402,7 +672,7 @@
 
         toggled ^= 1;
         if (toggled) {
-                g_debug ("Default input selected: %s", id);
+                update_alert (chooser, id);
         }
 
         g_free (id);
@@ -414,9 +684,10 @@
 {
         GtkTreeModel *model;
         GtkTreeIter   iter;
+        GtkTreeIter   theme_iter;
         char         *id;
-        char         *filename;
         ca_context   *ctx;
+        char         *parent_theme;
 
         model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
         if (gtk_tree_model_get_iter (model, &iter, path) == FALSE) {
@@ -431,24 +702,55 @@
                 return;
         }
 
-        filename = NULL;
+        parent_theme = NULL;
+        if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser->priv->combo_box), &theme_iter)) {
+                GtkTreeModel *theme_model;
+                char         *theme_id;
+                char         *parent_id;
+
+                theme_model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser->priv->combo_box));
+                theme_id = NULL;
+                parent_id = NULL;
+                gtk_tree_model_get (theme_model, &theme_iter,
+                                    THEME_IDENTIFIER_COL, &theme_id,
+                                    THEME_PARENT_ID_COL, &parent_id, -1);
+                if (theme_id && strcmp (theme_id, CUSTOM_THEME_NAME) == 0) {
+                        parent_theme = g_strdup (parent_id);
+                }
+                g_free (theme_id);
+                g_free (parent_id);
+        }
 
-        g_debug ("playing: %s", id);
         ctx = ca_gtk_context_get ();
+        /* special case: for the default item on custom themes
+         * play the alert for the parent theme */
         if (strcmp (id, DEFAULT_ALERT_ID) == 0) {
-                ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
-                                        CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
-                                        CA_PROP_EVENT_ID, "bell-window-system",
-                                        CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
-                                        CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+                if (parent_theme != NULL) {
+                        ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
+                                                CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+                                                CA_PROP_EVENT_ID, "bell-window-system",
+                                                CA_PROP_CANBERRA_XDG_THEME_NAME, parent_theme,
+                                                CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+                                                CA_PROP_CANBERRA_CACHE_CONTROL, "never",
 #ifdef CA_PROP_CANBERRA_ENABLE
-                                        CA_PROP_CANBERRA_ENABLE, "1",
+                                                CA_PROP_CANBERRA_ENABLE, "1",
 #endif
-                                        NULL);
+                                                NULL);
+                } else {
+                        ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
+                                                CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+                                                CA_PROP_EVENT_ID, "bell-window-system",
+                                                CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+                                                CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+#ifdef CA_PROP_CANBERRA_ENABLE
+                                                CA_PROP_CANBERRA_ENABLE, "1",
+#endif
+                                                NULL);
+                }
         } else {
                 ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
                                         CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
-                                        CA_PROP_MEDIA_FILENAME, filename,
+                                        CA_PROP_MEDIA_FILENAME, id,
                                         CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
                                         CA_PROP_CANBERRA_CACHE_CONTROL, "never",
 #ifdef CA_PROP_CANBERRA_ENABLE
@@ -457,7 +759,7 @@
                                         NULL);
 
         }
-
+        g_free (parent_theme);
         g_free (id);
 }
 
@@ -497,7 +799,6 @@
 static GtkWidget *
 create_alert_treeview (GvcSoundThemeChooser *chooser)
 {
-        GHashTable           *hash;
         GtkListStore         *store;
         GtkWidget            *treeview;
         GtkCellRenderer      *renderer;
@@ -517,14 +818,6 @@
                           G_CALLBACK (on_treeview_selection_changed),
                           chooser);
 
-        /* Add the theme names and their display name to a hash table,
-         * makes it easy to avoid duplicate themes */
-        hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
-
-        /* FIXME: need to read this from a set of deskop files */
-
-
         /* Setup the tree model, 3 columns:
          * - display name
          * - sound id
@@ -545,8 +838,7 @@
                                            ALERT_ACTIVE_COL, TRUE,
                                            -1);
 
-        g_hash_table_foreach (hash, (GHFunc) add_theme_to_store, store);
-        g_hash_table_destroy (hash);
+        populate_model_from_dir (chooser, GTK_TREE_MODEL (store), SOUND_SET_DIR);
 
         gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
                                  GTK_TREE_MODEL (store));
@@ -581,6 +873,95 @@
         return treeview;
 }
 
+static int
+get_file_type (const char *sound_name,
+               char      **linked_name)
+{
+        char *name, *filename;
+
+        *linked_name = NULL;
+
+        name = g_strdup_printf ("%s.disabled", sound_name);
+        filename = custom_theme_dir_path (name);
+        g_free (name);
+
+        if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) != FALSE) {
+                g_free (filename);
+                return SOUND_TYPE_OFF;
+        }
+        g_free (filename);
+
+        /* We only check for .ogg files because those are the
+         * only ones we create */
+        name = g_strdup_printf ("%s.ogg", sound_name);
+        filename = custom_theme_dir_path (name);
+        g_free (name);
+
+        if (g_file_test (filename, G_FILE_TEST_IS_SYMLINK) != FALSE) {
+                *linked_name = g_file_read_link (filename, NULL);
+                g_free (filename);
+                return SOUND_TYPE_CUSTOM;
+        }
+        g_free (filename);
+
+        return SOUND_TYPE_BUILTIN;
+}
+
+static void
+update_alerts_from_theme_name (GvcSoundThemeChooser *chooser,
+                               const char           *name)
+{
+        if (strcmp (name, CUSTOM_THEME_NAME) != 0) {
+                /* reset alert to default */
+                update_alert (chooser, DEFAULT_ALERT_ID);
+        } else {
+                int   sound_type;
+                char *linkname;
+
+                linkname = NULL;
+                sound_type = get_file_type ("bell-terminal", &linkname);
+                g_debug ("Found link: %s", linkname);
+                if (sound_type == SOUND_TYPE_CUSTOM) {
+                        update_alert (chooser, linkname);
+                }
+        }
+}
+
+static void
+update_theme (GvcSoundThemeChooser *chooser)
+{
+        char        *theme_name;
+        gboolean     events_enabled;
+        gboolean     bell_enabled;
+        GConfClient *client;
+        gboolean     feedback_enabled;
+
+        client = gconf_client_get_default ();
+
+        bell_enabled = gconf_client_get_bool (client, AUDIO_BELL_KEY, NULL);
+        //set_audible_bell_enabled (chooser, bell_enabled);
+
+        feedback_enabled = gconf_client_get_bool (client, INPUT_SOUNDS_KEY, NULL);
+        set_input_feedback_enabled (chooser, feedback_enabled);
+
+        events_enabled = gconf_client_get_bool (client, EVENT_SOUNDS_KEY, NULL);
+        if (events_enabled) {
+                theme_name = gconf_client_get_string (client, SOUND_THEME_KEY, NULL);
+        } else {
+                theme_name = g_strdup (NO_SOUNDS_THEME_NAME);
+        }
+
+        gtk_widget_set_sensitive (chooser->priv->selection_box, events_enabled);
+
+        set_combox_for_theme_name (chooser, theme_name);
+
+        update_alerts_from_theme_name (chooser, theme_name);
+
+        g_free (theme_name);
+
+        g_object_unref (client);
+}
+
 static GObject *
 gvc_sound_theme_chooser_constructor (GType                  type,
                                      guint                  n_construct_properties,
@@ -704,7 +1085,7 @@
         chooser->priv->selection_box = box = gtk_frame_new (_("Choose an alert sound:"));
         gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
 
-        gtk_box_pack_start (GTK_BOX (chooser), box, TRUE, TRUE, 0);
+        gtk_box_pack_start (GTK_BOX (chooser), box, TRUE, TRUE, 6);
 
         chooser->priv->treeview = create_alert_treeview (chooser);
 

Modified: trunk/gnome-volume-control/src/sound-theme-file-utils.c
==============================================================================
--- trunk/gnome-volume-control/src/sound-theme-file-utils.c	(original)
+++ trunk/gnome-volume-control/src/sound-theme-file-utils.c	Mon Dec 22 00:55:04 2008
@@ -19,8 +19,10 @@
 
 #include <config.h>
 #include <glib/gstdio.h>
+#include <glib/gi18n.h>
 #include <gio/gio.h>
 #include <utime.h>
+#include <strings.h>
 
 #include "sound-theme-file-utils.h"
 
@@ -99,7 +101,7 @@
  * A utility routine to delete files and/or directories,
  * including non-empty directories.
  **/
-gboolean
+static gboolean
 capplet_file_delete_recursive (GFile *file, GError **error)
 {
         GFileInfo *info;
@@ -138,6 +140,50 @@
         g_debug ("deleted the custom theme dir");
 }
 
+gboolean
+custom_theme_dir_is_empty (void)
+{
+        char            *dir;
+        GFile           *file;
+        gboolean         is_empty;
+        GFileEnumerator *enumerator;
+        GFileInfo       *info;
+        GError          *error;
+
+        dir = custom_theme_dir_path (NULL);
+        file = g_file_new_for_path (dir);
+        g_free (dir);
+
+        is_empty = TRUE;
+
+        enumerator = g_file_enumerate_children (file,
+                                                G_FILE_ATTRIBUTE_STANDARD_NAME ","
+                                                G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                                                G_FILE_QUERY_INFO_NONE,
+                                                NULL, &error);
+        if (enumerator == NULL) {
+                g_warning ("Unable to enumerate files: %s", error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        while (is_empty &&
+               (info = g_file_enumerator_next_file (enumerator, NULL, NULL))) {
+
+                if (strcmp ("index.theme", g_file_info_get_name (info)) != 0) {
+                        is_empty = FALSE;
+                }
+
+                g_object_unref (info);
+        }
+        g_file_enumerator_close (enumerator, NULL, NULL);
+
+ out:
+        g_object_unref (file);
+
+        return is_empty;
+}
+
 static void
 delete_one_file (const char *sound_name, const char *pattern)
 {
@@ -154,7 +200,7 @@
 }
 
 void
-delete_old_files (char **sounds)
+delete_old_files (const char **sounds)
 {
         guint i;
 
@@ -164,7 +210,7 @@
 }
 
 void
-delete_disabled_files (char **sounds)
+delete_disabled_files (const char **sounds)
 {
         guint i;
 
@@ -185,7 +231,7 @@
 }
 
 void
-add_disabled_file (char **sounds)
+add_disabled_file (const char **sounds)
 {
         guint i;
 
@@ -205,7 +251,7 @@
 }
 
 void
-add_custom_file (char **sounds, const char *filename)
+add_custom_file (const char **sounds, const char *filename)
 {
         guint i;
 
@@ -229,3 +275,31 @@
         }
 }
 
+void
+create_custom_theme (const char *parent)
+{
+        GKeyFile *keyfile;
+        char     *data;
+        char     *path;
+
+        /* Create the custom directory */
+        path = custom_theme_dir_path (NULL);
+        g_mkdir_with_parents (path, 0755);
+        g_free (path);
+
+        /* Set the data for index.theme */
+        keyfile = g_key_file_new ();
+        g_key_file_set_string (keyfile, "Sound Theme", "Name", _("Custom"));
+        g_key_file_set_string (keyfile, "Sound Theme", "Inherits", parent);
+        g_key_file_set_string (keyfile, "Sound Theme", "Directories", ".");
+        data = g_key_file_to_data (keyfile, NULL, NULL);
+        g_key_file_free (keyfile);
+
+        /* Save the index.theme */
+        path = custom_theme_dir_path ("index.theme");
+        g_file_set_contents (path, data, -1, NULL);
+        g_free (path);
+        g_free (data);
+
+        custom_theme_update_time ();
+}

Modified: trunk/gnome-volume-control/src/sound-theme-file-utils.h
==============================================================================
--- trunk/gnome-volume-control/src/sound-theme-file-utils.h	(original)
+++ trunk/gnome-volume-control/src/sound-theme-file-utils.h	Mon Dec 22 00:55:04 2008
@@ -22,13 +22,15 @@
 #include <gio/gio.h>
 
 char *custom_theme_dir_path (const char *child);
+gboolean custom_theme_dir_is_empty (void);
+void create_custom_theme (const char *parent);
 
 void delete_custom_theme_dir (void);
-void delete_old_files (char **sounds);
-void delete_disabled_files (char **sounds);
+void delete_old_files (const char **sounds);
+void delete_disabled_files (const char **sounds);
 
-void add_disabled_file (char **sounds);
-void add_custom_file (char **sounds, const char *filename);
+void add_disabled_file (const char **sounds);
+void add_custom_file (const char **sounds, const char *filename);
 
 void custom_theme_update_time (void);
 



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