/* * Copyright (C) 2007 OpenedHand Ltd * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include "hito-contact-view.h" G_DEFINE_TYPE (HitoContactView, hito_contact_view, GTK_TYPE_TREE_VIEW); #define GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), HITO_TYPE_CONTACT_VIEW, HitoContactViewPrivate)) typedef struct { HitoContactStore *store; HitoContactModelFilter *filter; } HitoContactViewPrivate; enum { PROP_0, PROP_BASE_MODEL, PROP_FILTER, }; /* * Private methods. */ /* * Cell data function for the name column. */ static void name_data_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { EContact *contact = NULL; gtk_tree_model_get (model, iter, COLUMN_CONTACT, &contact, -1); if (!contact) return; /* Get the display name from the store, so that the display and sort names are in sync */ g_object_set (cell, "text", e_contact_get_const (contact, E_CONTACT_FULL_NAME), NULL); g_object_unref (contact); } /* * Custom function for interactive searches. */ static gboolean search_equal_func (GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) { EContact *contact = NULL; const char *name; gboolean found; gtk_tree_model_get (model, iter, COLUMN_CONTACT, &contact, -1); if (!contact) return FALSE; name = e_contact_get_const (contact, E_CONTACT_FULL_NAME); found = e_util_utf8_strstrcasedecomp (name, key) != NULL; g_object_unref (contact); /* GtkTreeView is insane */ return ! found; } /* * Object methods. */ static void hito_contact_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { /* TODO */ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void hito_contact_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { HitoContactViewPrivate *priv = GET_PRIVATE (object); switch (property_id) { case PROP_FILTER: if (priv->filter) { g_object_unref (priv->filter); } priv->filter = HITO_CONTACT_MODEL_FILTER (g_value_dup_object (value)); break; case PROP_BASE_MODEL: if (priv->store) { g_object_unref (priv->store); } priv->store = HITO_CONTACT_STORE (g_value_dup_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void hito_contact_view_dispose (GObject *object) { HitoContactViewPrivate *priv = GET_PRIVATE (object); if (priv->filter) { g_object_unref (priv->filter); priv->filter = NULL; } if (priv->store) { g_object_unref (priv->store); priv->store = NULL; } if (G_OBJECT_CLASS (hito_contact_view_parent_class)->dispose) G_OBJECT_CLASS (hito_contact_view_parent_class)->dispose (object); } static void hito_contact_view_finalize (GObject *object) { G_OBJECT_CLASS (hito_contact_view_parent_class)->finalize (object); } static void hito_contact_view_class_init (HitoContactViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (HitoContactViewPrivate)); object_class->get_property = hito_contact_view_get_property; object_class->set_property = hito_contact_view_set_property; object_class->dispose = hito_contact_view_dispose; object_class->finalize = hito_contact_view_finalize; g_object_class_install_property (object_class, PROP_BASE_MODEL, g_param_spec_object ("base-model", "Base model", NULL, HITO_TYPE_CONTACT_STORE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); g_object_class_install_property (object_class, PROP_FILTER, g_param_spec_object ("filter", "Filter", NULL, HITO_TYPE_CONTACT_MODEL_FILTER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); } static void hito_contact_view_init (HitoContactView *self) { GtkTreeView *treeview; GtkCellRenderer *renderer; GtkTreeViewColumn *column; treeview = GTK_TREE_VIEW (self); gtk_tree_view_set_rules_hint (treeview, TRUE); gtk_tree_view_set_headers_visible (treeview, FALSE); gtk_tree_view_set_enable_search (treeview, TRUE); gtk_tree_view_set_search_column (treeview, COLUMN_CONTACT); gtk_tree_view_set_search_equal_func (treeview, search_equal_func, NULL, NULL); /* Summary column */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, NULL); g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); gtk_tree_view_column_set_cell_data_func (column, renderer, name_data_func, treeview, NULL); gtk_tree_view_append_column (treeview, column); } /* * Public methods. */ GtkWidget * hito_contact_view_new (HitoContactStore *store, HitoContactModelFilter *filter) { return g_object_new (HITO_TYPE_CONTACT_VIEW, "model", filter ? (GtkTreeModel*)filter : (GtkTreeModel*)store, "base-model", store, "filter", filter, NULL); } #if 0 /** * hito_contact_view_get_selected_contact: * @view: A #HitoContactView. * * Return the currently selected #EContact, or #NULL if there is now row * selected. When finished with the #EContact, unref it with g_object_unref(). * * Returns: a #EContact with its reference count incremented, or #NULL. */ HitoContact * hito_contact_view_get_selected_contact (HitoContactView *view) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; EContact *contact = NULL; g_return_val_if_fail (HITO_IS_CONTACT_VIEW (view), NULL); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { return NULL; } gtk_tree_model_get (model, &iter, COLUMN_CONTACT, &contact, -1); return contact; } #endif gboolean hito_contact_view_get_selected_iter (HitoContactView *view, GtkTreeIter *iter) { GtkTreeSelection *selection; g_return_val_if_fail (HITO_IS_CONTACT_VIEW (view), FALSE); g_return_val_if_fail (iter, FALSE); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); return gtk_tree_selection_get_selected (selection, NULL, iter); }