[ekiga/ds-gtk-application] Book View: Ported to the new Actor framework and GTK3.
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga/ds-gtk-application] Book View: Ported to the new Actor framework and GTK3.
- Date: Sun, 30 Nov 2014 10:29:03 +0000 (UTC)
commit 94f9b0b885b7680ea54fdb606de42e879f696b66
Author: Damien Sandras <dsandras seconix com>
Date: Sun Nov 30 11:25:42 2014 +0100
Book View: Ported to the new Actor framework and GTK3.
lib/engine/gui/gtk-frontend/book-view-gtk.cpp | 432 ++++++++++++++++---------
lib/engine/gui/gtk-frontend/book-view-gtk.h | 16 +-
2 files changed, 287 insertions(+), 161 deletions(-)
---
diff --git a/lib/engine/gui/gtk-frontend/book-view-gtk.cpp b/lib/engine/gui/gtk-frontend/book-view-gtk.cpp
index 412e788..1d3c9bf 100644
--- a/lib/engine/gui/gtk-frontend/book-view-gtk.cpp
+++ b/lib/engine/gui/gtk-frontend/book-view-gtk.cpp
@@ -36,11 +36,15 @@
*/
#include <glib/gi18n.h>
+#include <boost/assign/ptr_list_of.hpp>
#include "book-view-gtk.h"
+#include "gm-info-bar.h"
+
#include "filterable.h"
+#include "gactor-menu.h"
#include "menu-builder-tools.h"
#include "menu-builder-gtk.h"
#include "scoped-connections.h"
@@ -55,9 +59,14 @@ struct _BookViewGtkPrivate
GtkTreeView *tree_view;
GtkWidget *vbox;
GtkWidget *entry;
- GtkWidget *statusbar;
+ GtkWidget *search_button;
+ GtkWidget *searchbar;
+ GtkWidget *info_bar;
GtkWidget *scrolled_window;
+ Ekiga::GActorMenuPtr book_menu;
+ Ekiga::GActorMenuPtr contact_menu;
+
Ekiga::BookPtr book;
Ekiga::scoped_connections connections;
};
@@ -71,6 +80,16 @@ enum {
COLUMN_NUMBER
};
+
+enum {
+ ACTIONS_CHANGED_SIGNAL,
+ LAST_SIGNAL
+};
+
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+
G_DEFINE_TYPE (BookViewGtk, book_view_gtk, GTK_TYPE_FRAME);
/*
@@ -115,12 +134,11 @@ static void on_contact_removed (Ekiga::ContactPtr contact,
gpointer data);
-/* DESCRIPTION : Called when the a contact selection has been changed.
- * BEHAVIOR : Emits the "updated" signal on the GObject passed as
- * second parameter..
- * PRE : The gpointer must point to a BookViewGtk GObject.
+/* DESCRIPTION : Called when the user selects a contact.
+ * BEHAVIOR : Rebuilds menus and emit the actions_changed signal.
+ * PRE : The gpointer must point to the BookViewGtk GObject.
*/
-static void on_selection_changed (GtkTreeSelection * /*selection*/,
+static void on_selection_changed (GtkTreeSelection *selection,
gpointer data);
@@ -129,17 +147,8 @@ static void on_selection_changed (GtkTreeSelection * /*selection*/,
* a refresh.
* PRE : A valid pointer to the BookViewGtk.
*/
-static void on_entry_activated_cb (GtkWidget *entry,
- gpointer data);
-
-
-/* DESCRIPTION : Called when the user clicks on the Find button.
- * BEHAVIOR : Activates the GtkEntry.
- * PRE : A valid pointer to the BookViewGtk containing
- * the GtkEntry to activate.
- */
-static void on_button_clicked_cb (GtkWidget *button,
- gpointer data);
+static void on_search_entry_activated_cb (GtkWidget *entry,
+ gpointer data);
/* DESCRIPTION : Called when the a contact is clicked.
@@ -151,6 +160,33 @@ static gint on_contact_clicked (GtkWidget *tree_view,
gpointer data);
+/* DESCRIPTION : Called when the BookViewGtk widget becomes visible.
+ * BEHAVIOR : Add its own search action (if it is filterable).
+ * Calls on_selection_changed to update actions.
+ * PRE : /
+ */
+static void on_map_cb (G_GNUC_UNUSED GtkWidget *widget,
+ gpointer data);
+
+
+/* DESCRIPTION : Called when the BookViewGtk widget becomes invisible.
+ * BEHAVIOR : Remove Actions. They will be mapped again when we
+ * are mapped again.
+ * PRE : /
+ */
+static void on_unmap_cb (G_GNUC_UNUSED GtkWidget *widget,
+ gpointer data);
+
+
+/* DESCRIPTION : Called when the user triggers the search action.
+ * BEHAVIOR : Toggle the search bar.
+ * PRE : /
+ */
+static void on_search_cb (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer data);
+
+
/* Static functions */
/* DESCRIPTION : /
@@ -182,6 +218,14 @@ book_view_gtk_remove_contact (BookViewGtk *self,
/* DESCRIPTION : /
+ * BEHAVIOR : Create and return the window GtkSearchBar.
+ * PRE : /
+ */
+static GtkWidget *
+book_view_build_searchbar (BookViewGtk *self);
+
+
+/* DESCRIPTION : /
* BEHAVIOR : Return TRUE and update the GtkTreeIter if we found
* the iter corresponding to the Contact in the BookViewGtk.
* PRE : /
@@ -192,6 +236,12 @@ book_view_gtk_find_iter_for_contact (BookViewGtk *view,
GtkTreeIter *iter);
+static GActionEntry win_entries[] =
+{
+ { "search", on_search_cb, NULL, NULL, NULL, 0 }
+};
+
+
/* Implementation of the callbacks */
static bool
@@ -235,12 +285,12 @@ on_updated (gpointer data)
std::string status = view->priv->book->get_status ();
- gtk_statusbar_pop (GTK_STATUSBAR (view->priv->statusbar), 0);
- gtk_statusbar_push (GTK_STATUSBAR (view->priv->statusbar), 0, status.c_str ());
+ gm_info_bar_push_message (GM_INFO_BAR (view->priv->info_bar),
+ GTK_MESSAGE_INFO,
+ status.c_str ());
boost::shared_ptr<Ekiga::Filterable> filtered =
boost::dynamic_pointer_cast<Ekiga::Filterable>(view->priv->book);
if (filtered) {
-
gtk_entry_set_text (GTK_ENTRY (view->priv->entry),
filtered->get_search_filter ().c_str ());
}
@@ -260,96 +310,124 @@ on_contact_removed (Ekiga::ContactPtr contact,
static void
-on_selection_changed (GtkTreeSelection * /*selection*/,
+on_selection_changed (GtkTreeSelection *selection,
gpointer data)
{
- g_signal_emit_by_name (data, "updated", NULL);
-}
+ BookViewGtk* self = NULL;
+ GtkTreeModel *model = NULL;
+ GtkTreeIter iter;
+ Ekiga::Contact *contact = NULL;
-static void
-on_entry_activated_cb (GtkWidget *entry,
- gpointer data)
-{
- const char *entry_text = gtk_entry_get_text (GTK_ENTRY (entry));
+ self = BOOK_VIEW_GTK (data);
+ model = gtk_tree_view_get_model (self->priv->tree_view);
- boost::shared_ptr<Ekiga::Filterable> filtered =
boost::dynamic_pointer_cast<Ekiga::Filterable>(BOOK_VIEW_GTK (data)->priv->book);
+ /* Reset old data. This also ensures GIO actions are
+ * properly removed before adding new ones.
+ */
+ if (self->priv->contact_menu)
+ self->priv->contact_menu.reset ();
- filtered->set_search_filter (entry_text);
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+
+ gtk_tree_model_get (model, &iter,
+ COLUMN_CONTACT_POINTER, &contact,
+ -1);
+
+ if (contact != NULL) {
+ self->priv->contact_menu = Ekiga::GActorMenuPtr (new Ekiga::GActorMenu (*contact,
+ contact->get_name ()));
+ g_signal_emit (self, signals[ACTIONS_CHANGED_SIGNAL], 0,
+ self->priv->contact_menu->get_model (boost::assign::list_of (self->priv->book_menu)));
+ }
+ }
+ else
+ g_signal_emit (self, signals[ACTIONS_CHANGED_SIGNAL], 0,
+ self->priv->book_menu->get_model ());
}
static void
-on_button_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
- gpointer data)
+on_search_entry_activated_cb (G_GNUC_UNUSED GtkWidget *entry,
+ gpointer data)
{
- g_return_if_fail (data != NULL);
+ g_return_if_fail (IS_BOOK_VIEW_GTK (data));
+ BookViewGtk *self = BOOK_VIEW_GTK (data);
- gtk_widget_activate (GTK_WIDGET (BOOK_VIEW_GTK (data)->priv->entry));
+ const char *entry_text = gtk_entry_get_text (GTK_ENTRY (self->priv->entry));
+ boost::shared_ptr<Ekiga::Filterable> filtered =
boost::dynamic_pointer_cast<Ekiga::Filterable>(BOOK_VIEW_GTK (data)->priv->book);
+ filtered->set_search_filter (entry_text);
}
static gint
-on_contact_clicked (GtkWidget *tree_view,
+on_contact_clicked (G_GNUC_UNUSED GtkWidget *tree_view,
GdkEventButton *event,
gpointer data)
{
- GtkTreePath *path = NULL;
- GtkTreeIter iter;
- GtkTreeModel *model = NULL;
+ g_return_val_if_fail (IS_BOOK_VIEW_GTK (data), FALSE);
+ BookViewGtk *self = BOOK_VIEW_GTK (data);
- if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view),
- (gint) event->x, (gint) event->y,
- &path, NULL, NULL, NULL)) {
+ if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
+ gtk_menu_popup (GTK_MENU (self->priv->contact_menu->get_menu ()),
+ NULL, NULL, NULL, NULL, event->button, event->time);
+ }
- model
- = gtk_tree_view_get_model (BOOK_VIEW_GTK (data)->priv->tree_view);
+ return TRUE;
+}
- if (gtk_tree_model_get_iter (model, &iter, path)) {
- Ekiga::Contact *contact = NULL;
- gtk_tree_model_get (model, &iter,
- COLUMN_CONTACT_POINTER, &contact,
- -1);
+static void
+on_map_cb (G_GNUC_UNUSED GtkWidget *widget,
+ gpointer data)
+{
+ GtkTreeSelection *selection = NULL;
- if (contact != NULL) {
+ g_return_if_fail (IS_BOOK_VIEW_GTK (data));
+ BookViewGtk *self = BOOK_VIEW_GTK (data);
- if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
+ g_action_map_remove_action (G_ACTION_MAP (g_application_get_default ()),
+ "search");
+ if (self->priv->searchbar)
+ g_action_map_add_action_entries (G_ACTION_MAP (g_application_get_default ()),
+ win_entries, G_N_ELEMENTS (win_entries),
+ self);
+ selection = gtk_tree_view_get_selection (self->priv->tree_view);
+ on_selection_changed (selection, self);
+}
- Ekiga::TemporaryMenuBuilder temp;
- MenuBuilderGtk builder;
- BOOK_VIEW_GTK (data)->priv->book->populate_menu (temp);
- contact->populate_menu (builder);
+static void
+on_unmap_cb (G_GNUC_UNUSED GtkWidget *widget,
+ gpointer data)
+{
+ g_return_if_fail (IS_BOOK_VIEW_GTK (data));
+ BookViewGtk *self = BOOK_VIEW_GTK (data);
- if (!temp.empty ()) {
+ g_action_map_remove_action (G_ACTION_MAP (g_application_get_default ()),
+ "search");
- builder.add_separator ();
- temp.populate_menu (builder);
- }
+ /* Reset old data. This also ensures GIO actions are
+ * properly removed when we are going out of scope.
+ */
+ if (self->priv->contact_menu)
+ self->priv->contact_menu.reset ();
+}
- if (!builder.empty ()) {
- gtk_widget_show_all (builder.menu);
- gtk_menu_popup (GTK_MENU (builder.menu), NULL, NULL,
- NULL, NULL, event->button, event->time);
- g_signal_connect (builder.menu, "hide",
- G_CALLBACK (g_object_unref),
- (gpointer) builder.menu);
- }
- g_object_ref_sink (G_OBJECT (builder.menu));
- } else if (event->type == GDK_2BUTTON_PRESS) {
- Ekiga::TriggerMenuBuilder builder;
+static void
+on_search_cb (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer data)
+{
+ g_return_if_fail (IS_BOOK_VIEW_GTK (data));
+ BookViewGtk *self = BOOK_VIEW_GTK (data);
- contact->populate_menu (builder);
- }
- }
- }
- gtk_tree_path_free (path);
- }
+ gboolean toggle = gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (self->priv->searchbar));
- return TRUE;
+ gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (self->priv->searchbar),
+ !toggle);
}
@@ -408,6 +486,47 @@ book_view_gtk_remove_contact (BookViewGtk *self,
}
+static GtkWidget *
+book_view_build_searchbar (BookViewGtk *self)
+{
+ GtkWidget *box = NULL;
+ GtkWidget *label = NULL;
+ GtkWidget *image = NULL;
+ GtkWidget *searchbar = NULL;
+
+ searchbar = gtk_search_bar_new ();
+ gtk_search_bar_set_show_close_button (GTK_SEARCH_BAR (searchbar), TRUE);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_container_add (GTK_CONTAINER (searchbar), box);
+ gtk_widget_show (box);
+
+ label = gtk_label_new_with_mnemonic (_("_Search Filter:"));
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+ gtk_widget_show (label);
+
+ self->priv->entry = gtk_search_entry_new ();
+ gtk_box_pack_start (GTK_BOX (box), self->priv->entry, TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->entry);
+
+ self->priv->search_button = gtk_button_new ();
+ image = gtk_image_new_from_icon_name ("view-refresh-symbolic", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (self->priv->search_button), image);
+ gtk_box_pack_start (GTK_BOX (box), self->priv->search_button, TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->search_button);
+
+ g_signal_connect (self->priv->entry, "activate",
+ G_CALLBACK (on_search_entry_activated_cb), self);
+ g_signal_connect (self->priv->search_button, "clicked",
+ G_CALLBACK (on_search_entry_activated_cb), self);
+
+ gtk_search_bar_connect_entry (GTK_SEARCH_BAR (searchbar), GTK_ENTRY (self->priv->entry));
+
+ return searchbar;
+}
+
+
+
static gboolean
book_view_gtk_find_iter_for_contact (BookViewGtk *view,
Ekiga::ContactPtr contact,
@@ -440,22 +559,13 @@ book_view_gtk_find_iter_for_contact (BookViewGtk *view,
static void
book_view_gtk_dispose (GObject *obj)
{
- BookViewGtk *view = NULL;
-
- view = BOOK_VIEW_GTK (obj);
-
- if (view->priv->tree_view) {
+ BookViewGtk *self = NULL;
- g_signal_handlers_disconnect_matched (gtk_tree_view_get_selection (view->priv->tree_view),
- (GSignalMatchType) G_SIGNAL_MATCH_DATA,
- 0, /* signal_id */
- (GQuark) 0, /* detail */
- NULL, /* closure */
- NULL, /* func */
- view); /* data */
- gtk_list_store_clear (GTK_LIST_STORE (gtk_tree_view_get_model (view->priv->tree_view)));
+ self = BOOK_VIEW_GTK (obj);
- view->priv->tree_view = NULL;
+ if (self->priv) {
+ delete self->priv;
+ self->priv = NULL;
}
G_OBJECT_CLASS (book_view_gtk_parent_class)->dispose (obj);
@@ -463,35 +573,26 @@ book_view_gtk_dispose (GObject *obj)
static void
-book_view_gtk_finalize (GObject *obj)
-{
- BookViewGtk *view = NULL;
-
- view = BOOK_VIEW_GTK (obj);
-
- delete view->priv;
-
- G_OBJECT_CLASS (book_view_gtk_parent_class)->finalize (obj);
-}
-
-static void
book_view_gtk_init (G_GNUC_UNUSED BookViewGtk* self)
{
/* can't do anything here... waiting for a core :-/ */
}
+
static void
book_view_gtk_class_init (BookViewGtkClass* klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = book_view_gtk_dispose;
- gobject_class->finalize = book_view_gtk_finalize;
- g_signal_new ("updated",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL);
+ signals[ACTIONS_CHANGED_SIGNAL] =
+ g_signal_new ("actions-changed",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (BookViewGtkClass, selection_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_MENU_MODEL);
}
@@ -499,76 +600,73 @@ book_view_gtk_class_init (BookViewGtkClass* klass)
GtkWidget *
book_view_gtk_new (Ekiga::BookPtr book)
{
- BookViewGtk *result = NULL;
-
- GtkWidget *label = NULL;
- GtkWidget *hbox = NULL;
- GtkWidget *button = NULL;
+ BookViewGtk *self = NULL;
GtkTreeSelection *selection = NULL;
GtkListStore *store = NULL;
GtkTreeViewColumn *column = NULL;
GtkCellRenderer *renderer = NULL;
- result = (BookViewGtk *) g_object_new (BOOK_VIEW_GTK_TYPE, NULL);
+ self = (BookViewGtk *) g_object_new (BOOK_VIEW_GTK_TYPE, NULL);
+
+ self->priv = new _BookViewGtkPrivate (book);
+ self->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_frame_set_shadow_type (GTK_FRAME (self), GTK_SHADOW_NONE);
+ gtk_widget_show (self->priv->vbox);
- result->priv = new _BookViewGtkPrivate (book);
- result->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_frame_set_shadow_type (GTK_FRAME (result), GTK_SHADOW_NONE);
+ /* populate book actions */
+ self->priv->book_menu = Ekiga::GActorMenuPtr (new Ekiga::GActorMenu (*book,
+ book->get_name ()));
/* The Search Box */
boost::shared_ptr<Ekiga::Filterable> filtered = boost::dynamic_pointer_cast<Ekiga::Filterable> (book);
-
+ self->priv->entry = NULL;
+ self->priv->search_button = NULL;
+ self->priv->searchbar = NULL;
if (filtered) {
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- result->priv->entry = gtk_entry_new ();
- button = gtk_button_new_from_stock (GTK_STOCK_FIND);
- label = gtk_label_new_with_mnemonic (_("_Search Filter:"));
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
- gtk_box_pack_start (GTK_BOX (hbox), result->priv->entry, TRUE, TRUE, 2);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 2);
- gtk_box_pack_start (GTK_BOX (result->priv->vbox), hbox, FALSE, FALSE, 0);
- g_signal_connect (result->priv->entry, "activate",
- G_CALLBACK (on_entry_activated_cb), result);
- g_signal_connect (button, "clicked",
- G_CALLBACK (on_button_clicked_cb), result);
- } else {
-
- result->priv->entry = NULL;
+ /* Search bar */
+ self->priv->searchbar = book_view_build_searchbar (self);
+ gtk_box_pack_start (GTK_BOX (self->priv->vbox),
+ self->priv->searchbar, FALSE, FALSE, 0);
+ gtk_widget_show (self->priv->searchbar);
}
+ /* The info bar */
+ self->priv->info_bar = gm_info_bar_new ();
+ gtk_box_pack_start (GTK_BOX (self->priv->vbox),
+ self->priv->info_bar, FALSE, FALSE, 0);
+
/* The List Store */
- result->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ self->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
- (result->priv->scrolled_window),
+ (self->priv->scrolled_window),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- result->priv->tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
- gtk_tree_view_set_headers_visible (result->priv->tree_view, FALSE);
- gtk_container_add (GTK_CONTAINER (result), GTK_WIDGET (result->priv->vbox));
- gtk_box_pack_start (GTK_BOX (result->priv->vbox),
- GTK_WIDGET (result->priv->scrolled_window), TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (result->priv->scrolled_window),
- GTK_WIDGET (result->priv->tree_view));
+ self->priv->tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
+ gtk_tree_view_set_headers_visible (self->priv->tree_view, FALSE);
+ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (self->priv->tree_view), FALSE);
+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->priv->vbox));
+ gtk_box_pack_start (GTK_BOX (self->priv->vbox),
+ GTK_WIDGET (self->priv->scrolled_window), TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (self->priv->scrolled_window),
+ GTK_WIDGET (self->priv->tree_view));
- selection = gtk_tree_view_get_selection (result->priv->tree_view);
+ selection = gtk_tree_view_get_selection (self->priv->tree_view);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
g_signal_connect (selection, "changed",
- G_CALLBACK (on_selection_changed), result);
+ G_CALLBACK (on_selection_changed), self);
- g_signal_connect (result->priv->tree_view, "event-after",
- G_CALLBACK (on_contact_clicked), result);
+ g_signal_connect (self->priv->tree_view, "event-after",
+ G_CALLBACK (on_contact_clicked), self);
store = gtk_list_store_new (COLUMN_NUMBER,
G_TYPE_POINTER,
GDK_TYPE_PIXBUF,
G_TYPE_STRING);
- gtk_tree_view_set_model (result->priv->tree_view, GTK_TREE_MODEL (store));
+ gtk_tree_view_set_model (self->priv->tree_view, GTK_TREE_MODEL (store));
g_object_unref (store);
- /* Name */
column = gtk_tree_view_column_new ();
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer, FALSE);
@@ -586,23 +684,37 @@ book_view_gtk_new (Ekiga::BookPtr book)
gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_resizable (column, true);
- gtk_tree_view_append_column (GTK_TREE_VIEW (result->priv->tree_view), column);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->tree_view), column);
- /* The status bar */
- result->priv->statusbar = gtk_statusbar_new ();
- gtk_box_pack_start (GTK_BOX (result->priv->vbox), result->priv->statusbar, FALSE, TRUE, 0);
+ gtk_widget_show_all (self->priv->scrolled_window);
/* connect to the signals */
- result->priv->connections.add (book->contact_added.connect (boost::bind (&on_contact_added, _1,
(gpointer)result)));
- result->priv->connections.add (book->contact_updated.connect (boost::bind (&on_contact_updated, _1,
(gpointer)result)));
- result->priv->connections.add (book->contact_removed.connect (boost::bind (&on_contact_removed, _1,
(gpointer)result)));
- result->priv->connections.add (book->updated.connect (boost::bind (&on_updated, (gpointer)result)));
-
+ self->priv->connections.add (book->contact_added.connect (boost::bind (&on_contact_added, _1,
(gpointer)self)));
+ self->priv->connections.add (book->contact_updated.connect (boost::bind (&on_contact_updated, _1,
(gpointer)self)));
+ self->priv->connections.add (book->contact_removed.connect (boost::bind (&on_contact_removed, _1,
(gpointer)self)));
+ self->priv->connections.add (book->updated.connect (boost::bind (&on_updated, (gpointer)self)));
/* populate */
- book->visit_contacts (boost::bind (&on_visit_contacts, _1, (gpointer)result));
+ book->visit_contacts (boost::bind (&on_visit_contacts, _1, (gpointer)self));
+
+ g_signal_connect (GTK_WIDGET (self), "map",
+ G_CALLBACK (on_map_cb), self);
+ g_signal_connect (GTK_WIDGET (self), "unmap",
+ G_CALLBACK (on_unmap_cb), self);
+
+ return GTK_WIDGET (self);
+}
+
+
+gboolean
+book_view_gtk_handle_event (BookViewGtk *self,
+ GdkEvent *event)
+{
+ if (self->priv->searchbar)
+ return gtk_search_bar_handle_event (GTK_SEARCH_BAR (self->priv->searchbar),
+ event);
- return (GtkWidget *) result;
+ return FALSE;
}
diff --git a/lib/engine/gui/gtk-frontend/book-view-gtk.h b/lib/engine/gui/gtk-frontend/book-view-gtk.h
index d3982f8..4fb6e82 100644
--- a/lib/engine/gui/gtk-frontend/book-view-gtk.h
+++ b/lib/engine/gui/gtk-frontend/book-view-gtk.h
@@ -45,10 +45,22 @@ typedef struct _BookViewGtk BookViewGtk;
typedef struct _BookViewGtkPrivate BookViewGtkPrivate;
typedef struct _BookViewGtkClass BookViewGtkClass;
-/* public api */
+/* Signals emitted by that widget :
+ *
+ * - "actions-changed", comes with nothing, and notifies when new
+ * actions are available (wrt the active selection). The GMenuModel
+ * signal callback argument details available actions.
+ *
+ * Reported Actions are Book and Contact Actions.
+ */
+
+/* Public API */
GtkWidget *book_view_gtk_new (Ekiga::BookPtr book);
+gboolean book_view_gtk_handle_event (BookViewGtk *self,
+ GdkEvent *event);
+
void book_view_gtk_populate_menu (BookViewGtk *, GtkWidget *);
/* GObject thingies */
@@ -63,6 +75,8 @@ struct _BookViewGtk
struct _BookViewGtkClass
{
GtkFrameClass parent;
+
+ void (*selection_changed) (BookViewGtk* self);
};
#define BOOK_VIEW_GTK_TYPE (book_view_gtk_get_type ())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]