[ekiga] CallHistoryBookViewGtk: Fixed infinite loop when call is cleared.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga] CallHistoryBookViewGtk: Fixed infinite loop when call is cleared.
- Date: Sat, 27 Dec 2014 11:11:08 +0000 (UTC)
commit 7efde8e5c1e5e3405ec04e862f732d6747fbd352
Author: Damien Sandras <dsandras seconix com>
Date: Sat Dec 27 12:08:30 2014 +0100
CallHistoryBookViewGtk: Fixed infinite loop when call is cleared.
The code was optimized to react differently when a call is added to the
history and when the entirer history is reset. Formerly, the entire call
history was cleared then rebuilt when a new call was added. This was not
efficient.
.../gui/gtk-frontend/call-history-view-gtk.cpp | 99 +++++++++++++-------
1 files changed, 66 insertions(+), 33 deletions(-)
---
diff --git a/lib/engine/gui/gtk-frontend/call-history-view-gtk.cpp
b/lib/engine/gui/gtk-frontend/call-history-view-gtk.cpp
index ecea07e..0431ba7 100644
--- a/lib/engine/gui/gtk-frontend/call-history-view-gtk.cpp
+++ b/lib/engine/gui/gtk-frontend/call-history-view-gtk.cpp
@@ -45,6 +45,7 @@
#include "menu-builder-gtk.h"
#include "gm-cell-renderer-bitext.h"
#include "gactor-menu.h"
+#include "scoped-connections.h"
struct null_deleter
@@ -67,9 +68,10 @@ struct _CallHistoryViewGtkPrivate
Ekiga::GActorMenuPtr contact_menu;
GtkTreeView* tree;
- boost::signals2::scoped_connection connection;
+ Ekiga::scoped_connections conns;
};
+
/* this is what we put in the view */
enum {
COLUMN_CONTACT,
@@ -150,6 +152,34 @@ on_contact_added (Ekiga::ContactPtr contact,
-1);
}
+
+static void
+on_selection_changed (G_GNUC_UNUSED GtkTreeSelection* selection,
+ gpointer data)
+{
+ CallHistoryViewGtk* self = NULL;
+ History::Contact *contact = NULL;
+
+ self = CALL_HISTORY_VIEW_GTK (data);
+
+ /* Reset old data. This also ensures GIO actions are
+ * properly removed before adding new ones.
+ */
+ self->priv->contact_menu.reset ();
+
+ /* Set or reset ContactActor data */
+ call_history_view_gtk_get_selected (self, &contact);
+
+ if (contact != NULL) {
+ self->priv->contact_menu = Ekiga::GActorMenuPtr (new Ekiga::GActorMenu (*contact));
+ g_signal_emit (self, signals[ACTIONS_CHANGED_SIGNAL], 0,
+ self->priv->contact_menu->get_model (boost::assign::list_of (self->priv->menu)));
+ }
+ else
+ g_signal_emit (self, signals[ACTIONS_CHANGED_SIGNAL], 0, NULL);
+}
+
+
static bool
on_visit_contacts (Ekiga::ContactPtr contact,
GtkListStore *store)
@@ -158,15 +188,42 @@ on_visit_contacts (Ekiga::ContactPtr contact,
return true;
}
+
static void
-on_book_updated (CallHistoryViewGtk* self)
+on_book_contact_added (Ekiga::ContactPtr contact,
+ CallHistoryViewGtk* self)
{
- GtkTreeModel* store = gtk_tree_view_get_model (self->priv->tree);
+ GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (self->priv->tree));
- gtk_list_store_clear (GTK_LIST_STORE (store));
- self->priv->book->visit_contacts (boost::bind (&on_visit_contacts, _1, GTK_LIST_STORE (store)));
+ on_contact_added (contact, store);
}
+
+static void
+on_book_cleared (CallHistoryViewGtk* data)
+{
+ GtkListStore *store = NULL;
+ GtkTreeSelection *selection = NULL;
+
+ g_return_if_fail (IS_CALL_HISTORY_VIEW_GTK (data));
+ CallHistoryViewGtk *self = CALL_HISTORY_VIEW_GTK (data);
+
+ store = GTK_LIST_STORE (gtk_tree_view_get_model (self->priv->tree));
+ selection = gtk_tree_view_get_selection (self->priv->tree);
+
+ /* Reset old data. This also ensures GIO actions are
+ * properly removed before adding new ones.
+ */
+ self->priv->contact_menu.reset ();
+
+ if (selection)
+ g_signal_handlers_block_by_func (selection, (gpointer) on_selection_changed, self);
+ gtk_list_store_clear (store);
+ if (selection)
+ g_signal_handlers_unblock_by_func (selection, (gpointer) on_selection_changed, self);
+}
+
+
/* react to user clicks */
static gint
on_clicked (G_GNUC_UNUSED GtkWidget *tree,
@@ -187,31 +244,6 @@ on_clicked (G_GNUC_UNUSED GtkWidget *tree,
return TRUE;
}
-static void
-on_selection_changed (G_GNUC_UNUSED GtkTreeSelection* selection,
- gpointer data)
-{
- CallHistoryViewGtk* self = NULL;
- History::Contact *contact = NULL;
-
- self = CALL_HISTORY_VIEW_GTK (data);
-
- /* Reset old data. This also ensures GIO actions are
- * properly removed before adding new ones.
- */
- self->priv->contact_menu.reset ();
-
- /* Set or reset ContactActor data */
- call_history_view_gtk_get_selected (self, &contact);
-
- if (contact != NULL) {
- self->priv->contact_menu = Ekiga::GActorMenuPtr (new Ekiga::GActorMenu (*contact));
- g_signal_emit (self, signals[ACTIONS_CHANGED_SIGNAL], 0,
- self->priv->contact_menu->get_model (boost::assign::list_of (self->priv->menu)));
- }
- else
- g_signal_emit (self, signals[ACTIONS_CHANGED_SIGNAL], 0, NULL);
-}
static void
on_map_cb (G_GNUC_UNUSED GtkWidget *widget,
@@ -336,11 +368,12 @@ call_history_view_gtk_new (boost::shared_ptr<History::Book> book,
g_signal_connect (GTK_WIDGET (self), "map",
G_CALLBACK (on_map_cb), self);
- /* connect to the signal */
- self->priv->connection = book->updated.connect (boost::bind (&on_book_updated, self));
+ /* connect to the signals */
+ self->priv->conns.add (book->contact_added.connect (boost::bind (&on_book_contact_added, _1, self)));
+ self->priv->conns.add (book->cleared.connect (boost::bind (&on_book_cleared, self)));
/* initial populate */
- on_book_updated(self);
+ self->priv->book->visit_contacts (boost::bind (&on_visit_contacts, _1, GTK_LIST_STORE (store)));
/* register book actions */
self->priv->menu = Ekiga::GActorMenuPtr (new Ekiga::GActorMenu (*book));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]