Convert Sound prefs page to Glade.

Mon, 05 Aug 2019 02:12:36 -0400

author
Elliott Sales de Andrade <qulogic@pidgin.im>
date
Mon, 05 Aug 2019 02:12:36 -0400
changeset 39747
1dffb6dad206
parent 39743
5ecfa744bcfa
child 39748
afe5a040286c

Convert Sound prefs page to Glade.

pidgin/gtkprefs.c file | annotate | diff | comparison | revisions
pidgin/resources/Prefs/prefs.ui file | annotate | diff | comparison | revisions
--- a/pidgin/gtkprefs.c	Mon Aug 05 01:05:45 2019 +0000
+++ b/pidgin/gtkprefs.c	Mon Aug 05 02:12:36 2019 -0400
@@ -210,6 +210,22 @@
 		GtkWidget *password;
 	} proxy;
 
+	/* Sounds page */
+	struct {
+		PidginPrefCombo method;
+		GtkWidget *method_vbox;
+		GtkWidget *command;
+		GtkWidget *command_hbox;
+		GtkWidget *mute;
+		GtkWidget *conv_focus;
+		PidginPrefCombo while_status;
+		struct {
+			GtkWidget *view;
+			GtkListStore *store;
+		} event;
+		GtkWidget *entry;
+	} sound;
+
 	/* Away page */
 	struct {
 		PidginPrefCombo idle_reporting;
@@ -242,7 +258,6 @@
 static GtkWidget *keyring_apply = NULL;
 
 /* Sound theme specific */
-static GtkWidget *sound_entry = NULL;
 static int sound_row_sel = 0;
 static gboolean prefs_sound_themes_loading;
 
@@ -872,7 +887,6 @@
 	purple_prefs_disconnect_by_handle(prefs);
 
 	/* NULL-ify globals */
-	sound_entry = NULL;
 	sound_row_sel = 0;
 	prefs_sound_themes_loading = FALSE;
 
@@ -1492,6 +1506,7 @@
 static void
 prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data)
 {
+	PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(user_data);
 	gint i;
 	gchar *pref;
 	gchar *new_theme;
@@ -1514,7 +1529,7 @@
 		/* gets rid of the "(Custom)" from the last selection */
 		pref_sound_generate_markup();
 
-		gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)"));
+		gtk_entry_set_text(GTK_ENTRY(win->sound.entry), _("(default)"));
 
 		g_free(new_theme);
 	}
@@ -1648,7 +1663,7 @@
 }
 
 static GtkWidget *
-theme_page(void)
+theme_page(PidginPrefsWindow *win)
 {
 	GtkWidget *label;
 	GtkWidget *ret, *vbox;
@@ -1687,7 +1702,7 @@
 	/* Sound Themes */
 	prefs_sound_themes_combo_box = add_theme_prefs_combo(
 		vbox, combo_sg, label_sg, prefs_sound_themes,
-		(GCallback)prefs_set_sound_theme_cb, NULL,
+		(GCallback)prefs_set_sound_theme_cb, win,
 		_("Sound Theme:"), PIDGIN_PREFS_ROOT "/sound/theme", "sound");
 
 	/* Smiley Themes */
@@ -2604,6 +2619,38 @@
 
 /*** keyring page - end *************************************************/
 
+static gboolean
+sound_method_filter(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+	gboolean any = FALSE;
+	gboolean gstreamer = FALSE;
+	gboolean win32 = FALSE;
+
+	gtk_tree_model_get(model, iter, 2, &any, 3, &gstreamer, 4, &win32, -1);
+
+	if (any) {
+		return TRUE;
+	}
+
+	if (gstreamer) {
+#ifdef USE_GSTREAMER
+#ifdef _WIN32
+		return win32;
+#else
+		return !win32;
+#endif
+#else
+		return FALSE;
+#endif
+	}
+
+#ifdef _WIN32
+	return win32;
+#else
+	return !win32;
+#endif
+}
+
 static gint
 sound_cmd_yeah(GtkEntry *entry, gpointer d)
 {
@@ -2684,8 +2731,9 @@
  * Resets a sound file back to default.
  */
 static void
-reset_sound(GtkWidget *button, gpointer i_am_also_NULL)
+reset_sound(GtkWidget *button, gpointer data)
 {
+	PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
 	gchar *pref;
 
 	pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s",
@@ -2693,7 +2741,7 @@
 	purple_prefs_set_path(pref, "");
 	g_free(pref);
 
-	gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)"));
+	gtk_entry_set_text(GTK_ENTRY(win->sound.entry), _("(default)"));
 
 	pref_sound_generate_markup();
 }
@@ -2717,7 +2765,7 @@
 	 * sound, then update the box showing the file name.
 	 */
 	if (sound == sound_row_sel)
-		gtk_entry_set_text(GTK_ENTRY(sound_entry), filename);
+		gtk_entry_set_text(GTK_ENTRY(prefs->sound.entry), filename);
 
 	pref_sound_generate_markup();
 }
@@ -2742,8 +2790,10 @@
 }
 
 static void
-prefs_sound_sel(GtkTreeSelection *sel, GtkTreeModel *model)
+prefs_sound_sel(GtkTreeSelection *sel, gpointer data)
 {
+	PidginPrefsWindow *win = PIDGIN_PREFS_WINDOW(data);
+	GtkTreeModel *model;
 	GtkTreeIter  iter;
 	GValue val;
 	const char *file;
@@ -2760,147 +2810,81 @@
 			pidgin_sound_get_event_option(sound_row_sel));
 	file = purple_prefs_get_path(pref);
 	g_free(pref);
-	if (sound_entry)
-		gtk_entry_set_text(GTK_ENTRY(sound_entry), (file && *file != '\0') ? file : _("(default)"));
+	if (win->sound.entry) {
+		gtk_entry_set_text(GTK_ENTRY(win->sound.entry),
+		                   (file && *file != '\0') ? file
+		                                           : _("(default)"));
+	}
 	g_value_unset (&val);
 
 	pref_sound_generate_markup();
 }
 
-
 static void
-mute_changed_cb(const char *pref_name,
-                PurplePrefType pref_type,
-                gconstpointer val,
-                gpointer data)
+bind_sound_page(PidginPrefsWindow *win)
 {
-	GtkToggleButton *button = data;
-	gboolean muted = GPOINTER_TO_INT(val);
-
-	g_return_if_fail(purple_strequal (pref_name, PIDGIN_PREFS_ROOT "/sound/mute"));
-
-	/* Block the handler that re-sets the preference. */
-	g_signal_handlers_block_matched(button, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (gpointer)pref_name);
-	gtk_toggle_button_set_active (button, muted);
-	g_signal_handlers_unblock_matched(button, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, (gpointer)pref_name);
-}
-
-
-static GtkWidget *
-sound_page(void)
-{
-	GtkWidget *ret;
-	GtkWidget *vbox, *vbox2, *button, *parent, *parent_parent, *parent_parent_parent;
-	GtkSizeGroup *sg;
-	GtkTreeIter iter;
-	GtkWidget *event_view;
-	GtkListStore *event_store;
-	GtkCellRenderer *rend;
-	GtkTreeViewColumn *col;
+	GtkTreeModel *model;
 	GtkTreeSelection *sel;
 	GtkTreePath *path;
-	GtkWidget *hbox;
 	int j;
 	const char *file;
 	char *pref;
-	GtkWidget *dd;
-	GtkWidget *entry;
 	const char *cmd;
 
-	ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_CAT_SPACE);
-	gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
-
-	sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-
-	vbox2 = pidgin_make_frame(ret, _("Sound Options"));
-
-	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox2), vbox, FALSE, FALSE, 0);
-
-	dd = pidgin_prefs_dropdown(vbox2, _("_Method:"), PURPLE_PREF_STRING,
-			PIDGIN_PREFS_ROOT "/sound/method",
-			_("Automatic"), "automatic",
-#ifdef USE_GSTREAMER
-#ifdef _WIN32
-/*			"WaveForm", "waveform", */
-			"DirectSound", "directsound",
-#else
-			"ESD", "esd",
-			"ALSA", "alsa",
-#endif /* _WIN32 */
-#endif /* USE_GSTREAMER */
-#ifdef _WIN32
-			"PlaySound", "playsoundw",
-#else
-			_("Console beep"), "beep",
-			_("Command"), "custom",
-#endif /* _WIN32 */
-			_("No sounds"), "none",
-			NULL);
-	gtk_size_group_add_widget(sg, dd);
-	gtk_label_set_xalign(GTK_LABEL(dd), 0.0);
-	gtk_label_set_yalign(GTK_LABEL(dd), 0.5);
-
-	entry = gtk_entry_new();
-	gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE);
+	win->sound.method.type = PURPLE_PREF_STRING;
+	win->sound.method.key = PIDGIN_PREFS_ROOT "/sound/method";
+	pidgin_prefs_bind_dropdown(&win->sound.method);
+	model = gtk_combo_box_get_model(GTK_COMBO_BOX(win->sound.method.combo));
+	gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model), sound_method_filter, NULL, NULL);
+	gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(model));
+
+	gtk_widget_set_sensitive(
+	        win->sound.method_vbox,
+	        !purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT
+	                                                 "/sound/method"),
+	                         "none"));
+	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
+	                              sound_changed2_cb,
+	                              win->sound.method_vbox);
+
+	gtk_widget_set_sensitive(
+	        win->sound.command_hbox,
+	        purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT
+	                                                "/sound/method"),
+	                        "custom"));
+	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
+	                              sound_changed1_cb,
+	                              win->sound.command_hbox);
+
 	cmd = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/sound/command");
-	if(cmd)
-		gtk_entry_set_text(GTK_ENTRY(entry), cmd);
-	g_signal_connect(G_OBJECT(entry), "changed",
-					 G_CALLBACK(sound_cmd_yeah), NULL);
-
-	hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Sound c_ommand:\n(%s for filename)"), sg, entry, TRUE, NULL);
-	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
-								sound_changed1_cb, hbox);
-	gtk_widget_set_sensitive(hbox,
-			purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"),
-					"custom"));
-
-	button = pidgin_prefs_checkbox(_("M_ute sounds"), PIDGIN_PREFS_ROOT "/sound/mute", vbox);
-	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/mute", mute_changed_cb, button);
-
-	pidgin_prefs_checkbox(_("Sounds when conversation has _focus"),
-				   PIDGIN_PREFS_ROOT "/sound/conv_focus", vbox);
-	pidgin_prefs_dropdown(vbox, _("_Enable sounds:"),
-				 PURPLE_PREF_INT, "/purple/sound/while_status",
-				_("Only when available"), PURPLE_SOUND_STATUS_AVAILABLE,
-				_("Only when not available"), PURPLE_SOUND_STATUS_AWAY,
-				_("Always"), PURPLE_SOUND_STATUS_ALWAYS,
-				NULL);
-
-	gtk_widget_set_sensitive(vbox,
-			!purple_strequal(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), "none"));
-	purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method",
-								sound_changed2_cb, vbox);
-	vbox = pidgin_make_frame(ret, _("Sound Events"));
-
-	/* The following is an ugly hack to make the frame expand so the
-	 * sound events list is big enough to be usable */
-	parent = gtk_widget_get_parent(vbox);
-	parent_parent = gtk_widget_get_parent(parent);
-	parent_parent_parent = gtk_widget_get_parent(parent_parent);
-	gtk_box_set_child_packing(GTK_BOX(parent), vbox, TRUE, TRUE, 0,
-			GTK_PACK_START);
-	gtk_box_set_child_packing(GTK_BOX(parent_parent),
-			parent, TRUE, TRUE, 0, GTK_PACK_START);
-	gtk_box_set_child_packing(GTK_BOX(parent_parent_parent),
-			parent_parent, TRUE, TRUE, 0, GTK_PACK_START);
+	if (cmd) {
+		gtk_entry_set_text(GTK_ENTRY(win->sound.command), cmd);
+	}
+
+	pidgin_prefs_bind_checkbox(PIDGIN_PREFS_ROOT "/sound/mute",
+	                           win->sound.mute);
+
+	pidgin_prefs_bind_checkbox(PIDGIN_PREFS_ROOT "/sound/conv_focus",
+	                           win->sound.conv_focus);
+
+	win->sound.while_status.type = PURPLE_PREF_INT;
+	win->sound.while_status.key = "/purple/sound/while_status";
+	pidgin_prefs_bind_dropdown(&win->sound.while_status);
 
 	/* SOUND SELECTION */
-	event_store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
-
 	for (j=0; j < PURPLE_NUM_SOUNDS; j++) {
 		char *pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/enabled/%s",
 					     pidgin_sound_get_event_option(j));
 		const char *label = pidgin_sound_get_event_label(j);
+		GtkTreeIter iter;
 
 		if (label == NULL) {
 			g_free(pref);
 			continue;
 		}
 
-		gtk_list_store_append (event_store, &iter);
-		gtk_list_store_set(event_store, &iter,
+		gtk_list_store_append(win->sound.event.store, &iter);
+		gtk_list_store_set(win->sound.event.store, &iter,
 				   0, purple_prefs_get_bool(pref),
 				   1, _(label),
 				   2, pref,
@@ -2909,63 +2893,17 @@
 		g_free(pref);
 	}
 
-	event_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(event_store));
-
-	rend = gtk_cell_renderer_toggle_new();
-	sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (event_view));
-	g_signal_connect (G_OBJECT (sel), "changed",
-			  G_CALLBACK (prefs_sound_sel),
-			  NULL);
-	g_signal_connect (G_OBJECT(rend), "toggled",
-			  G_CALLBACK(event_toggled), event_store);
+	sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(win->sound.event.view));
 	path = gtk_tree_path_new_first();
 	gtk_tree_selection_select_path(sel, path);
 	gtk_tree_path_free(path);
 
-	col = gtk_tree_view_column_new_with_attributes (_("Play"),
-							rend,
-							"active", 0,
-							NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col);
-
-	rend = gtk_cell_renderer_text_new();
-	col = gtk_tree_view_column_new_with_attributes (_("Event"),
-							rend,
-							"text", 1,
-							NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col);
-	g_object_unref(G_OBJECT(event_store));
-	gtk_box_pack_start(GTK_BOX(vbox),
-		pidgin_make_scrollable(event_view, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 100),
-		TRUE, TRUE, 0);
-
-	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-	sound_entry = gtk_entry_new();
 	pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s",
 			       pidgin_sound_get_event_option(0));
 	file = purple_prefs_get_path(pref);
 	g_free(pref);
-	gtk_entry_set_text(GTK_ENTRY(sound_entry), (file && *file != '\0') ? file : _("(default)"));
-	gtk_editable_set_editable(GTK_EDITABLE(sound_entry), FALSE);
-	gtk_box_pack_start(GTK_BOX(hbox), sound_entry, FALSE, FALSE, PIDGIN_HIG_BOX_SPACE);
-
-	button = gtk_button_new_with_mnemonic(_("_Browse..."));
-	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(select_sound), NULL);
-	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1);
-
-	button = gtk_button_new_with_mnemonic(_("Pre_view"));
-	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(test_sound), NULL);
-	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1);
-
-	button = gtk_button_new_with_mnemonic(_("_Reset"));
-	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(reset_sound), NULL);
-	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 1);
-
-	gtk_widget_show_all(ret);
-	g_object_unref(sg);
-
-	return ret;
+	gtk_entry_set_text(GTK_ENTRY(win->sound.entry),
+	                   (file && *file != '\0') ? file : _("(default)"));
 }
 
 
@@ -3641,10 +3579,11 @@
 	notebook_page++;
 	prefs_notebook_add_page(notebook, _("Password Storage"), keyring_page(), notebook_page++);
 
-	prefs_notebook_add_page(notebook, _("Sounds"), sound_page(), notebook_page++);
+	bind_sound_page(win);
+	notebook_page++;
 	bind_away_page(win);
 	notebook_page++;
-	prefs_notebook_add_page(notebook, _("Themes"), theme_page(), notebook_page++);
+	prefs_notebook_add_page(notebook, _("Themes"), theme_page(win), notebook_page++);
 #ifdef USE_VV
 	prefs_notebook_add_page(notebook, _("Voice/Video"), vv_page(win), notebook_page++);
 #endif
@@ -3862,6 +3801,34 @@
 	gtk_widget_class_bind_template_callback(widget_class,
 			proxy_print_option);
 
+	/* Sounds page */
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.method.combo);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.method_vbox);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.command);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.command_hbox);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.mute);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.conv_focus);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.while_status.combo);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.event.view);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.event.store);
+	gtk_widget_class_bind_template_child(widget_class, PidginPrefsWindow,
+	                                     sound.entry);
+	gtk_widget_class_bind_template_callback(widget_class, sound_cmd_yeah);
+	gtk_widget_class_bind_template_callback(widget_class, prefs_sound_sel);
+	gtk_widget_class_bind_template_callback(widget_class, event_toggled);
+	gtk_widget_class_bind_template_callback(widget_class, select_sound);
+	gtk_widget_class_bind_template_callback(widget_class, test_sound);
+	gtk_widget_class_bind_template_callback(widget_class, reset_sound);
+
 	/* Away page */
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginPrefsWindow,
--- a/pidgin/resources/Prefs/prefs.ui	Mon Aug 05 01:05:45 2019 +0000
+++ b/pidgin/resources/Prefs/prefs.ui	Mon Aug 05 02:12:36 2019 -0400
@@ -279,6 +279,115 @@
       </row>
     </data>
   </object>
+  <object class="GtkListStore" id="sound.event.store">
+    <columns>
+      <!-- column-name active -->
+      <column type="gboolean"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name pref -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="guint"/>
+    </columns>
+  </object>
+  <object class="GtkListStore" id="sound.method.store_raw">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name value -->
+      <column type="gchararray"/>
+      <!-- column-name any -->
+      <column type="gboolean"/>
+      <!-- column-name gstreamer -->
+      <column type="gboolean"/>
+      <!-- column-name win32 -->
+      <column type="gboolean"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Automatic</col>
+        <col id="1">automatic</col>
+        <col id="2">True</col>
+        <col id="3">False</col>
+        <col id="4">False</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">DirectSound</col>
+        <col id="1">directsound</col>
+        <col id="2">False</col>
+        <col id="3">True</col>
+        <col id="4">True</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">ESD</col>
+        <col id="1">esd</col>
+        <col id="2">False</col>
+        <col id="3">True</col>
+        <col id="4">False</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">ALSA</col>
+        <col id="1">alsa</col>
+        <col id="2">False</col>
+        <col id="3">True</col>
+        <col id="4">False</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">PlaySound</col>
+        <col id="1">playsoundw</col>
+        <col id="2">False</col>
+        <col id="3">False</col>
+        <col id="4">True</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Console beep</col>
+        <col id="1">beep</col>
+        <col id="2">False</col>
+        <col id="3">False</col>
+        <col id="4">False</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Command</col>
+        <col id="1">custom</col>
+        <col id="2">False</col>
+        <col id="3">False</col>
+        <col id="4">False</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">No sounds</col>
+        <col id="1">none</col>
+        <col id="2">True</col>
+        <col id="3">False</col>
+        <col id="4">False</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkTreeModelFilter" id="sound.method.store">
+    <property name="child_model">sound.method.store_raw</property>
+  </object>
+  <object class="GtkListStore" id="sound.while_status.store">
+    <columns>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name value -->
+      <column type="gint"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Only when available</col>
+        <col id="1">1</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Only when not available</col>
+        <col id="1">2</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Always</col>
+        <col id="1">3</col>
+      </row>
+    </data>
+  </object>
   <template class="PidginPrefsWindow" parent="GtkDialog">
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Preferences</property>
@@ -2430,6 +2539,401 @@
               </packing>
             </child>
             <child>
+              <object class="GtkBox" id="sound.page">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_left">12</property>
+                <property name="margin_right">12</property>
+                <property name="margin_top">12</property>
+                <property name="margin_bottom">12</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">18</property>
+                <child>
+                  <object class="GtkFrame">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkAlignment">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkBox">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkLabel" id="label15">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">_Method:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="xalign">0</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkComboBox" id="sound.method.combo">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="model">sound.method.store</property>
+                                    <property name="id_column">1</property>
+                                    <child>
+                                      <object class="GtkCellRendererText"/>
+                                      <attributes>
+                                        <attribute name="text">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </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="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="sound.method_vbox">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkBox" id="sound.command_hbox">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="spacing">6</property>
+                                    <child>
+                                      <object class="GtkLabel" id="label17">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes">Sound c_ommand:
+(%s for filename)</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="mnemonic_widget">sound.command</property>
+                                        <property name="xalign">0</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkEntry" id="sound.command">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <signal name="changed" handler="sound_cmd_yeah" swapped="no"/>
+                                      </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="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="sound.mute">
+                                    <property name="label" translatable="yes">M_ute sounds</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="draw_indicator">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="sound.conv_focus">
+                                    <property name="label" translatable="yes">Sounds when conversation has _focus</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="draw_indicator">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkBox">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="spacing">6</property>
+                                    <child>
+                                      <object class="GtkLabel" id="label16">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes">_Enable sounds:</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="xalign">0</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkComboBox" id="sound.while_status.combo">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="model">sound.while_status.store</property>
+                                        <child>
+                                          <object class="GtkCellRendererText"/>
+                                          <attributes>
+                                            <attribute name="text">0</attribute>
+                                          </attributes>
+                                        </child>
+                                      </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="position">3</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="margin_bottom">6</property>
+                        <property name="label" translatable="yes">Sound Options</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkFrame">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkAlignment">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkScrolledWindow">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="hscrollbar_policy">never</property>
+                                <property name="shadow_type">in</property>
+                                <property name="min_content_height">100</property>
+                                <child>
+                                  <object class="GtkTreeView" id="sound.event.view">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="model">sound.event.store</property>
+                                    <child internal-child="selection">
+                                      <object class="GtkTreeSelection">
+                                        <signal name="changed" handler="prefs_sound_sel" object="PidginPrefsWindow" swapped="no"/>
+                                      </object>
+                                    </child>
+                                    <child>
+                                      <object class="GtkTreeViewColumn">
+                                        <property name="title" translatable="yes">Play</property>
+                                        <child>
+                                          <object class="GtkCellRendererToggle">
+                                            <signal name="toggled" handler="event_toggled" object="sound.event.store" swapped="no"/>
+                                          </object>
+                                          <attributes>
+                                            <attribute name="active">0</attribute>
+                                          </attributes>
+                                        </child>
+                                      </object>
+                                    </child>
+                                    <child>
+                                      <object class="GtkTreeViewColumn">
+                                        <property name="title" translatable="yes">Event</property>
+                                        <child>
+                                          <object class="GtkCellRendererText"/>
+                                          <attributes>
+                                            <attribute name="text">1</attribute>
+                                          </attributes>
+                                        </child>
+                                      </object>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkEntry" id="sound.entry">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="editable">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkButton">
+                                    <property name="label" translatable="yes">_Browse...</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="use_underline">True</property>
+                                    <signal name="clicked" handler="select_sound" swapped="no"/>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkButton">
+                                    <property name="label" translatable="yes">Pre_view</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="use_underline">True</property>
+                                    <signal name="clicked" handler="test_sound" swapped="no"/>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">2</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkButton">
+                                    <property name="label" translatable="yes">_Reset</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <property name="use_underline">True</property>
+                                    <signal name="clicked" handler="reset_sound" object="PidginPrefsWindow" swapped="no"/>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">3</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="margin_bottom">6</property>
+                        <property name="label" translatable="yes">Sound Events</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">6</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Sounds</property>
+              </object>
+              <packing>
+                <property name="position">6</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkBox" id="away.page">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
@@ -2758,7 +3262,7 @@
                 </child>
               </object>
               <packing>
-                <property name="position">6</property>
+                <property name="position">7</property>
               </packing>
             </child>
             <child type="tab">
@@ -2768,7 +3272,7 @@
                 <property name="label" translatable="yes">Status / Idle</property>
               </object>
               <packing>
-                <property name="position">6</property>
+                <property name="position">7</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
@@ -2815,4 +3319,11 @@
       <widget name="label11"/>
     </widgets>
   </object>
+  <object class="GtkSizeGroup" id="sound.sg">
+    <widgets>
+      <widget name="label15"/>
+      <widget name="label16"/>
+      <widget name="label17"/>
+    </widgets>
+  </object>
 </interface>

mercurial