Empathy freeze exception



Hi,

I'd like to request a freeze exception for a little feature in Empathy: the
possibility to delete conversation logs.

The change is fairly small: it adds an Edit->Delete All History menu entry in
the history window, which pops up a dialog that allows you to select one account
for which to delete logs, or "All Accounts".

It also makes accounts for which there are no logs insensitive in the history
window. The current situation is you can select them but nothing appears, which
is a bit confusing.

This has already been reviewed by other Empathy developers and I committed it to
the gnome-2-34 branch and not to master because of the freezes, but then I was
told I can request an exception, so here I am. :-)

Guillaume (Empathy maintainer) is fine with this exception.

I've tested this both in the gnome-2-34 branch and in master, so it should be
safe. In the case it wasn't, we can just revert it and nothing else would be
affected.

The history window doesn't appear in the user help, so that wouldn't need to be
fixed.

The bugs are:

https://bugzilla.gnome.org/show_bug.cgi?id=644914
https://bugzilla.gnome.org/show_bug.cgi?id=644844

My branch against master:

http://git.collabora.co.uk/?p=user/pochu/empathy.git;a=shortlog;h=refs/heads/clear-history

I've also attached an squashed diff. The .ui diff looks a bit scary, but that's
because the indentation changes because of a new GtkVBox.

Thanks for considering this change.

Emilio
diff --git a/libempathy-gtk/empathy-account-chooser.c b/libempathy-gtk/empathy-account-chooser.c
index 71baba4..cd36da0 100644
--- a/libempathy-gtk/empathy-account-chooser.c
+++ b/libempathy-gtk/empathy-account-chooser.c
@@ -312,6 +312,30 @@ empathy_account_chooser_new (void)
 	return chooser;
 }
 
+gboolean
+empathy_account_chooser_has_all_selected (EmpathyAccountChooser *chooser)
+{
+	EmpathyAccountChooserPriv *priv;
+	GtkTreeModel              *model;
+	GtkTreeIter                iter;
+	RowType                    type;
+
+	g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser), FALSE);
+
+	priv = GET_PRIV (chooser);
+
+	g_return_val_if_fail (priv->has_all_option == TRUE, FALSE);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser));
+	if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser), &iter)) {
+		return FALSE;
+	}
+
+	gtk_tree_model_get (model, &iter, COL_ACCOUNT_ROW_TYPE, &type, -1);
+
+	return type == ROW_ALL;
+}
+
 /**
  * empathy_account_chooser_dup_account:
  * @chooser: an #EmpathyAccountChooser
@@ -488,7 +512,7 @@ empathy_account_chooser_set_has_all_option (EmpathyAccountChooser *chooser,
 
 		gtk_list_store_prepend (store, &iter);
 		gtk_list_store_set (store, &iter,
-				    COL_ACCOUNT_TEXT, _("All"),
+				    COL_ACCOUNT_TEXT, _("All accounts"),
 				    COL_ACCOUNT_ENABLED, TRUE,
 				    COL_ACCOUNT_POINTER, NULL,
 				    COL_ACCOUNT_ROW_TYPE, ROW_ALL,
diff --git a/libempathy-gtk/empathy-account-chooser.h b/libempathy-gtk/empathy-account-chooser.h
index 62854b9..6ff28d0 100644
--- a/libempathy-gtk/empathy-account-chooser.h
+++ b/libempathy-gtk/empathy-account-chooser.h
@@ -84,6 +84,7 @@ gboolean       empathy_account_chooser_set_account        (EmpathyAccountChooser
 gboolean       empathy_account_chooser_get_has_all_option (EmpathyAccountChooser *chooser);
 void           empathy_account_chooser_set_has_all_option (EmpathyAccountChooser *chooser,
 							   gboolean               has_all_option);
+gboolean       empathy_account_chooser_has_all_selected   (EmpathyAccountChooser *chooser);
 void           empathy_account_chooser_set_filter         (EmpathyAccountChooser *chooser,
 							   EmpathyAccountChooserFilterFunc filter,
 							   gpointer               user_data);
diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c
index 0f91bf9..984f936 100644
--- a/libempathy-gtk/empathy-log-window.c
+++ b/libempathy-gtk/empathy-log-window.c
@@ -31,8 +31,12 @@
 #include <gtk/gtk.h>
 
 #include <telepathy-glib/account-manager.h>
+#include <telepathy-glib/proxy-subclass.h>
+
 #include <telepathy-logger/log-manager.h>
 
+#include <extensions/extensions.h>
+
 #include <libempathy/empathy-chatroom-manager.h>
 #include <libempathy/empathy-chatroom.h>
 #include <libempathy/empathy-message.h>
@@ -61,7 +65,7 @@ typedef struct {
 	GtkWidget         *button_previous;
 	GtkWidget         *button_next;
 
-	GtkWidget         *vbox_chats;
+	GtkWidget         *hbox_chats;
 	GtkWidget         *account_chooser_chats;
 	GtkWidget         *entry_chats;
 	GtkWidget         *calendar_chats;
@@ -118,6 +122,14 @@ static void     log_window_entry_chats_changed_cb          (GtkWidget        *en
 							    EmpathyLogWindow *window);
 static void     log_window_entry_chats_activate_cb         (GtkWidget        *entry,
 							    EmpathyLogWindow *window);
+static void     log_window_delete_menu_clicked_cb          (GtkMenuItem      *menuitem,
+							    EmpathyLogWindow *window);
+
+static void
+empathy_account_chooser_filter_has_logs (TpAccount *account,
+					 EmpathyAccountChooserFilterResultCallback callback,
+					 gpointer callback_data,
+					 gpointer user_data);
 
 enum {
 	COL_FIND_ACCOUNT_ICON,
@@ -164,13 +176,7 @@ account_manager_prepared_cb (GObject *source_object,
 	account_num = g_list_length (accounts);
 	g_list_free (accounts);
 
-	if (account_num > 1) {
-		gtk_widget_show (window->vbox_chats);
-		gtk_widget_show (window->account_chooser_chats);
-	} else {
-		gtk_widget_hide (window->vbox_chats);
-		gtk_widget_hide (window->account_chooser_chats);
-	}
+	gtk_widget_show_all (window->hbox_chats);
 }
 
 static void
@@ -220,6 +226,7 @@ empathy_log_window_show (TpAccount  *account,
 	gchar                  *filename;
 	EmpathyLogWindow       *window;
 	EmpathyThemeManager    *theme_mgr;
+	GtkWidget *menu_delete;
 
 	if (log_window != NULL) {
 		gtk_window_present (GTK_WINDOW (log_window->window));
@@ -241,6 +248,7 @@ empathy_log_window_show (TpAccount  *account,
 					"libempathy-gtk");
 	gui = empathy_builder_get_file (filename,
 				       "log_window", &window->window,
+				       "menu_delete", &menu_delete,
 				       "notebook", &window->notebook,
 				       "entry_find", &window->entry_find,
 				       "button_find", &window->button_find,
@@ -250,7 +258,7 @@ empathy_log_window_show (TpAccount  *account,
 				       "button_next", &window->button_next,
 				       "entry_chats", &window->entry_chats,
 				       "calendar_chats", &window->calendar_chats,
-				       "vbox_chats", &window->vbox_chats,
+				       "hbox_chats", &window->hbox_chats,
 				       "treeview_chats", &window->treeview_chats,
 				       "scrolledwindow_chats", &window->scrolledwindow_chats,
 				       NULL);
@@ -267,6 +275,7 @@ empathy_log_window_show (TpAccount  *account,
 			      "button_find", "clicked", log_window_button_find_clicked_cb,
 			      "entry_chats", "changed", log_window_entry_chats_changed_cb,
 			      "entry_chats", "activate", log_window_entry_chats_activate_cb,
+			      "menu_delete", "activate", log_window_delete_menu_clicked_cb,
 			      NULL);
 
 	g_object_unref (gui);
@@ -298,8 +307,10 @@ empathy_log_window_show (TpAccount  *account,
 
 	/* Account chooser for chats */
 	window->account_chooser_chats = empathy_account_chooser_new ();
+	empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats),
+					    empathy_account_chooser_filter_has_logs, NULL);
 
-	gtk_box_pack_start (GTK_BOX (window->vbox_chats),
+	gtk_box_pack_start (GTK_BOX (window->hbox_chats),
 			    window->account_chooser_chats,
 			    FALSE, TRUE, 0);
 
@@ -1382,3 +1393,165 @@ log_window_entry_chats_activate_cb (GtkWidget       *entry,
 					    FALSE);
 	}
 }
+
+typedef struct {
+	EmpathyAccountChooserFilterResultCallback callback;
+	gpointer                                  user_data;
+} FilterCallbackData;
+
+static void
+got_entities (GObject      *manager,
+	      GAsyncResult *result,
+	      gpointer      user_data)
+{
+	FilterCallbackData *data = user_data;
+	GList *entities;
+	GError *error;
+
+	if (!tpl_log_manager_get_entities_finish (TPL_LOG_MANAGER (manager), result, &entities, &error)) {
+		DEBUG ("Could not get entities: %s", error->message);
+		g_error_free (error);
+		data->callback (FALSE, data->user_data);
+	} else {
+		data->callback (entities != NULL, data->user_data);
+
+		g_list_free_full (entities, g_object_unref);
+	}
+
+	g_slice_free (FilterCallbackData, data);
+}
+
+static void
+empathy_account_chooser_filter_has_logs (TpAccount *account,
+					 EmpathyAccountChooserFilterResultCallback callback,
+					 gpointer callback_data,
+					 gpointer user_data)
+{
+	TplLogManager *manager = tpl_log_manager_dup_singleton ();
+	FilterCallbackData *cb_data = g_slice_new0 (FilterCallbackData);
+
+	cb_data->callback = callback;
+	cb_data->user_data = callback_data;
+
+	tpl_log_manager_get_entities_async (manager, account, got_entities, cb_data);
+
+	g_object_unref (manager);
+}
+
+static void
+log_window_logger_clear_account_cb (TpProxy *proxy,
+				    const GError *error,
+				    gpointer user_data,
+				    GObject *weak_object)
+{
+	EmpathyLogWindow *window = user_data;
+
+	if (error != NULL)
+		g_warning ("Error when clearing logs: %s", error->message);
+
+	/* Refresh the log viewer so the logs are cleared if the account
+	 * has been deleted */
+	empathy_chat_view_clear (window->chatview_chats);
+	log_window_chats_populate (window);
+
+	/* Re-filter the account chooser so the accounts without logs get greyed out */
+	empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats),
+					    empathy_account_chooser_filter_has_logs, NULL);
+}
+
+static void
+log_window_clear_logs_chooser_select_account (EmpathyAccountChooser *chooser,
+					      EmpathyLogWindow *window)
+{
+	empathy_account_chooser_set_account (chooser,
+		empathy_account_chooser_get_account (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats)));
+}
+
+static void
+log_window_delete_menu_clicked_cb (GtkMenuItem      *menuitem,
+				   EmpathyLogWindow *window)
+{
+	GtkWidget *dialog, *content_area, *hbox, *label;
+	EmpathyAccountChooser *account_chooser;
+	gint response_id;
+	TpDBusDaemon *bus;
+	TpProxy *logger;
+	GError *error = NULL;
+
+	account_chooser = (EmpathyAccountChooser *) empathy_account_chooser_new ();
+	empathy_account_chooser_set_has_all_option (account_chooser, TRUE);
+	empathy_account_chooser_set_filter (account_chooser, empathy_account_chooser_filter_has_logs, NULL);
+
+	/* Select the same account as in the history window */
+	if (empathy_account_chooser_is_ready (account_chooser))
+		log_window_clear_logs_chooser_select_account (account_chooser, window);
+	else
+		g_signal_connect (account_chooser, "ready",
+				  G_CALLBACK (log_window_clear_logs_chooser_select_account), window);
+
+	dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (window->window),
+		GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING,
+		GTK_BUTTONS_NONE,
+		_("Are you sure you want to delete all logs of previous conversations?"));
+
+	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		_("Clear All"), GTK_RESPONSE_APPLY,
+		NULL);
+
+	content_area = gtk_message_dialog_get_message_area (
+		GTK_MESSAGE_DIALOG (dialog));
+
+	hbox = gtk_hbox_new (FALSE, 6);
+	label = gtk_label_new (_("Delete from:"));
+	gtk_box_pack_start (GTK_BOX (hbox), label,
+		FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (account_chooser),
+		FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (content_area), hbox,
+		FALSE, FALSE, 0);
+
+	gtk_widget_show_all (hbox);
+
+	response_id = gtk_dialog_run (GTK_DIALOG (dialog));
+
+	if (response_id != GTK_RESPONSE_APPLY)
+		goto out;
+
+	bus = tp_dbus_daemon_dup (&error);
+	if (error != NULL) {
+		g_warning ("Could not delete logs: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	logger = g_object_new (TP_TYPE_PROXY,
+			       "bus-name", "org.freedesktop.Telepathy.Logger",
+			       "object-path", "/org/freedesktop/Telepathy/Logger",
+			       "dbus-daemon", bus,
+			       NULL);
+	g_object_unref (bus);
+
+	tp_proxy_add_interface_by_id (logger, EMP_IFACE_QUARK_LOGGER);
+
+	if (empathy_account_chooser_has_all_selected (account_chooser)) {
+		DEBUG ("Deleting logs for all the accounts");
+
+		emp_cli_logger_call_clear (logger, -1,
+					   log_window_logger_clear_account_cb,
+					   window, NULL, G_OBJECT (window->window));
+	} else {
+		TpAccount *account = empathy_account_chooser_get_account (account_chooser);
+
+		DEBUG ("Deleting logs for %s", tp_proxy_get_object_path (account));
+
+		emp_cli_logger_call_clear_account (logger, -1,
+						   tp_proxy_get_object_path (account),
+						   log_window_logger_clear_account_cb,
+						   window, NULL, G_OBJECT (window->window));
+	}
+
+	g_object_unref (logger);
+ out:
+	gtk_widget_destroy (dialog);
+}
diff --git a/libempathy-gtk/empathy-log-window.ui b/libempathy-gtk/empathy-log-window.ui
index 1f99cdd..d47d32d 100644
--- a/libempathy-gtk/empathy-log-window.ui
+++ b/libempathy-gtk/empathy-log-window.ui
@@ -1,382 +1,462 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <!-- interface-requires gtk+ 2.12 -->
-  <!-- interface-naming-policy toplevel-contextual -->
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-go-forward</property>
+  </object>
+  <object class="GtkImage" id="image2">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-go-back</property>
+  </object>
+  <object class="GtkImage" id="image3">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-missing-image</property>
+  </object>
   <object class="GtkWindow" id="log_window">
+    <property name="can_focus">False</property>
     <property name="title" translatable="yes">Previous Conversations</property>
     <property name="role">log</property>
     <property name="default_width">640</property>
     <property name="default_height">450</property>
     <property name="icon_name">document-open-recent</property>
     <child>
-      <object class="GtkNotebook" id="notebook">
+      <object class="GtkVBox" id="vbox1">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="border_width">2</property>
+        <property name="can_focus">False</property>
         <child>
-          <object class="GtkVBox" id="vbox192">
+          <object class="GtkMenuBar" id="menubar1">
             <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <property name="spacing">6</property>
+            <property name="can_focus">False</property>
             <child>
-              <object class="GtkHBox" id="hbox144">
+              <object class="GtkMenuItem" id="menuitem2">
                 <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <child>
-                  <object class="GtkLabel" id="label628">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes" comments="Searching *for* something">_For:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">entry_find</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="entry_find">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="has_focus">True</property>
-                    <property name="activates_default">True</property>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="button_find">
-                    <property name="label">gtk-find</property>
+                <property name="can_focus">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="label" translatable="yes">_Edit</property>
+                <property name="use_underline">True</property>
+                <child type="submenu">
+                  <object class="GtkMenu" id="menu2">
                     <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="can_default">True</property>
-                    <property name="has_default">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_stock">True</property>
-                    <property name="focus_on_click">False</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkImageMenuItem" id="menu_delete">
+                        <property name="label" translatable="yes">Delete All History...</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="image">image3</property>
+                        <property name="use_stock">False</property>
+                      </object>
+                    </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">2</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</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="GtkNotebook" id="notebook">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">2</property>
             <child>
-              <object class="GtkVPaned" id="vpaned1">
+              <object class="GtkVBox" id="vbox192">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="position">120</property>
+                <property name="can_focus">False</property>
+                <property name="border_width">12</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow14">
+                  <object class="GtkHBox" id="hbox144">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <property name="shadow_type">in</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
                     <child>
-                      <object class="GtkTreeView" id="treeview_find">
+                      <object class="GtkLabel" id="label628">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes" comments="Searching *for* something">_For:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">entry_find</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_find">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="enable_search">False</property>
+                        <property name="has_focus">True</property>
+                        <property name="activates_default">True</property>
                       </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="button_find">
+                        <property name="label">gtk-find</property>
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="can_default">True</property>
+                        <property name="has_default">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="use_stock">True</property>
+                        <property name="focus_on_click">False</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="resize">False</property>
-                    <property name="shrink">True</property>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="vbox215">
+                  <object class="GtkVPaned" id="vpaned1">
                     <property name="visible">True</property>
-                    <property name="spacing">6</property>
+                    <property name="can_focus">True</property>
+                    <property name="position">120</property>
                     <child>
-                      <object class="GtkScrolledWindow" id="scrolledwindow_find">
+                      <object class="GtkScrolledWindow" id="scrolledwindow14">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="hscrollbar_policy">never</property>
                         <property name="shadow_type">in</property>
                         <child>
-                          <placeholder/>
+                          <object class="GtkTreeView" id="treeview_find">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="enable_search">False</property>
+                          </object>
                         </child>
                       </object>
                       <packing>
-                        <property name="position">0</property>
+                        <property name="resize">False</property>
+                        <property name="shrink">True</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkHBox" id="hbox171">
+                      <object class="GtkVBox" id="vbox215">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">6</property>
                         <child>
-                          <placeholder/>
-                        </child>
-                        <child>
-                          <object class="GtkButton" id="button_next">
-                            <property name="label" translatable="yes">Find Next</property>
+                          <object class="GtkScrolledWindow" id="scrolledwindow_find">
                             <property name="visible">True</property>
-                            <property name="sensitive">False</property>
                             <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="image">image1</property>
-                            <property name="focus_on_click">False</property>
+                            <property name="hscrollbar_policy">never</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <placeholder/>
+                            </child>
                           </object>
                           <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="pack_type">end</property>
-                            <property name="position">2</property>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkButton" id="button_previous">
-                            <property name="label" translatable="yes">Find Previous</property>
+                          <object class="GtkHBox" id="hbox171">
                             <property name="visible">True</property>
-                            <property name="sensitive">False</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="image">image2</property>
-                            <property name="focus_on_click">False</property>
+                            <property name="can_focus">False</property>
+                            <property name="spacing">12</property>
+                            <child>
+                              <object class="GtkButton" id="button_close">
+                                <property name="label">gtk-close</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="use_stock">True</property>
+                                <property name="focus_on_click">False</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="pack_type">end</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkButton" id="button_previous">
+                                <property name="label" translatable="yes">Find Previous</property>
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="image">image2</property>
+                                <property name="focus_on_click">False</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="pack_type">end</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkButton" id="button_next">
+                                <property name="label" translatable="yes">Find Next</property>
+                                <property name="visible">True</property>
+                                <property name="sensitive">False</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="image">image1</property>
+                                <property name="focus_on_click">False</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="pack_type">end</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <placeholder/>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
                             <property name="fill">False</property>
-                            <property name="pack_type">end</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
-                        <child>
-                          <object class="GtkButton" id="button_close">
-                            <property name="label">gtk-close</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">True</property>
-                            <property name="use_stock">True</property>
-                            <property name="focus_on_click">False</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="pack_type">end</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
+                        <property name="resize">True</property>
+                        <property name="shrink">True</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="resize">True</property>
-                    <property name="shrink">True</property>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-          </object>
-        </child>
-        <child type="tab">
-          <object class="GtkLabel" id="label595">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes" comments="Tab Label">Search</property>
-          </object>
-          <packing>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkTable" id="table7">
-            <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <property name="n_rows">3</property>
-            <property name="n_columns">2</property>
-            <property name="column_spacing">6</property>
-            <property name="row_spacing">6</property>
-            <child>
-              <object class="GtkVBox" id="vbox_chats">
-                <property name="visible">True</property>
-                <property name="spacing">6</property>
                 <child>
                   <placeholder/>
                 </child>
-              </object>
-              <packing>
-                <property name="x_options">GTK_FILL</property>
-                <property name="y_options">GTK_FILL</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow_chats">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="shadow_type">in</property>
                 <child>
                   <placeholder/>
                 </child>
               </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label595">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" comments="Tab Label">Search</property>
+              </object>
               <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
+                <property name="tab_fill">False</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox191">
+              <object class="GtkTable" id="table7">
                 <property name="visible">True</property>
-                <property name="spacing">6</property>
+                <property name="can_focus">False</property>
+                <property name="border_width">12</property>
+                <property name="n_rows">3</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">6</property>
+                <property name="row_spacing">6</property>
                 <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow13">
-                    <property name="width_request">150</property>
+                  <object class="GtkHBox" id="hbox_chats">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <property name="shadow_type">in</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <object class="GtkTreeView" id="treeview_chats">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                      </object>
+                      <placeholder/>
                     </child>
                   </object>
                   <packing>
-                    <property name="position">0</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options">GTK_FILL</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkCalendar" id="calendar_chats">
+                  <object class="GtkScrolledWindow" id="scrolledwindow_chats">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
                   </packing>
                 </child>
-              </object>
-              <packing>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
-                <property name="x_options">GTK_FILL</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkHBox" id="hbox143">
-                <property name="visible">True</property>
-                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkImage" id="image247">
+                  <object class="GtkVBox" id="vbox191">
                     <property name="visible">True</property>
-                    <property name="stock">gtk-find</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow13">
+                        <property name="width_request">150</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">never</property>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTreeView" id="treeview_chats">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="headers_visible">False</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCalendar" id="calendar_chats">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options">GTK_FILL</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkEntry" id="entry_chats">
+                  <object class="GtkHBox" id="hbox143">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="activates_default">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkImage" id="image247">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="stock">gtk-find</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_chats">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="activates_default">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
-                    <property name="position">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options">GTK_FILL</property>
                   </packing>
                 </child>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-                <property name="x_options">GTK_FILL</property>
-                <property name="y_options">GTK_FILL</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkHBox" id="hbox2">
-                <property name="visible">True</property>
-                <property name="spacing">12</property>
-                <child>
-                  <placeholder/>
-                </child>
                 <child>
-                  <object class="GtkButton" id="button_close2">
-                    <property name="label">gtk-close</property>
+                  <object class="GtkHBox" id="hbox2">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_stock">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="button_close2">
+                        <property name="label">gtk-close</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="use_stock">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="pack_type">end</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="pack_type">end</property>
-                    <property name="position">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                    <property name="y_options"></property>
                   </packing>
                 </child>
+                <child>
+                  <placeholder/>
+                </child>
               </object>
               <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-                <property name="top_attach">2</property>
-                <property name="bottom_attach">3</property>
-                <property name="y_options"></property>
+                <property name="position">1</property>
               </packing>
             </child>
-            <child>
-              <placeholder/>
+            <child type="tab">
+              <object class="GtkLabel" id="label596">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes" comments="Tab Label">Conversations</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
             </child>
           </object>
           <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
         </child>
-        <child type="tab">
-          <object class="GtkLabel" id="label596">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes" comments="Tab Label">Conversations</property>
-          </object>
-          <packing>
-            <property name="position">1</property>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
       </object>
     </child>
   </object>
-  <object class="GtkImage" id="image1">
-    <property name="visible">True</property>
-    <property name="stock">gtk-go-forward</property>
-  </object>
-  <object class="GtkImage" id="image2">
-    <property name="visible">True</property>
-    <property name="stock">gtk-go-back</property>
-  </object>
 </interface>


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