aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk/empathy-contact-list-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy-gtk/empathy-contact-list-view.c')
-rw-r--r--libempathy-gtk/empathy-contact-list-view.c129
1 files changed, 123 insertions, 6 deletions
diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index e8fddf0ac..8e8342275 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -157,6 +157,11 @@ contact_list_view_query_tooltip_cb (EmpathyContactListView *view,
}
running++;
+ /* Don't show the tooltip if there's already a popup menu */
+ if (gtk_menu_get_for_attach_widget (GTK_WIDGET (view)) != NULL) {
+ goto OUT;
+ }
+
if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (view), &x, &y,
keyboard_mode,
&model, &path, &iter)) {
@@ -235,6 +240,21 @@ contact_list_view_drag_got_contact (EmpathyTpContactFactory *factory,
data->old_group, data->new_group);
list = empathy_contact_list_store_get_list_iface (priv->store);
+
+ if (!tp_strdiff (data->new_group, EMPATHY_CONTACT_LIST_STORE_FAVORITE)) {
+ /* Mark contact as favourite */
+ empathy_contact_list_add_to_favourites (list, contact);
+ return;
+ }
+
+ if (!tp_strdiff (data->old_group, EMPATHY_CONTACT_LIST_STORE_FAVORITE)) {
+ /* Remove contact as favourite */
+ empathy_contact_list_remove_from_favourites (list, contact);
+ /* Don't try to remove it */
+ g_free (data->old_group);
+ data->old_group = NULL;
+ }
+
if (data->new_group) {
empathy_contact_list_add_to_group (list, contact, data->new_group);
}
@@ -244,6 +264,27 @@ contact_list_view_drag_got_contact (EmpathyTpContactFactory *factory,
}
static gboolean
+group_can_be_modified (const gchar *name,
+ gboolean is_fake_group,
+ gboolean adding)
+{
+ /* Real groups can always be modified */
+ if (!is_fake_group)
+ return TRUE;
+
+ /* The favorite fake group can be modified so users can
+ * add/remove favorites using DnD */
+ if (!tp_strdiff (name, EMPATHY_CONTACT_LIST_STORE_FAVORITE))
+ return TRUE;
+
+ /* We can remove contacts from the 'ungrouped' fake group */
+ if (!adding && !tp_strdiff (name, EMPATHY_CONTACT_LIST_STORE_UNGROUPED))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean
contact_list_view_contact_drag_received (GtkWidget *view,
GdkDragContext *context,
GtkTreeModel *model,
@@ -263,23 +304,30 @@ contact_list_view_contact_drag_received (GtkWidget *view,
gchar *new_group = NULL;
gchar *old_group = NULL;
gboolean success = TRUE;
+ gboolean new_group_is_fake, old_group_is_fake = TRUE;
priv = GET_PRIV (view);
sel_data = (const gchar *) gtk_selection_data_get_data (selection);
new_group = empathy_contact_list_store_get_parent_group (model,
- path, NULL);
+ path, NULL, &new_group_is_fake);
+
+ if (!group_can_be_modified (new_group, new_group_is_fake, TRUE))
+ return FALSE;
/* Get source group information. */
if (priv->drag_row) {
source_path = gtk_tree_row_reference_get_path (priv->drag_row);
if (source_path) {
old_group = empathy_contact_list_store_get_parent_group (
- model, source_path, NULL);
+ model, source_path, NULL, &old_group_is_fake);
gtk_tree_path_free (source_path);
}
}
+ if (!group_can_be_modified (old_group, old_group_is_fake, FALSE))
+ return FALSE;
+
if (!tp_strdiff (old_group, new_group)) {
g_free (new_group);
g_free (old_group);
@@ -681,6 +729,10 @@ contact_list_view_popup_menu_idle_cb (gpointer user_data)
}
if (menu) {
+ g_signal_connect (menu, "deactivate",
+ G_CALLBACK (gtk_menu_detach), NULL);
+ gtk_menu_attach_to_widget (GTK_MENU (menu),
+ GTK_WIDGET (data->view), NULL);
gtk_widget_show (menu);
gtk_menu_popup (GTK_MENU (menu),
NULL, NULL, NULL, NULL,
@@ -796,6 +848,10 @@ contact_list_view_call_activated_cb (
gtk_menu_shell_append (shell, item);
gtk_widget_show (item);
+ g_signal_connect (menu, "deactivate",
+ G_CALLBACK (gtk_menu_detach), NULL);
+ gtk_menu_attach_to_widget (GTK_MENU (menu),
+ GTK_WIDGET (view), NULL);
gtk_widget_show (menu);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
event->button, event->time);
@@ -868,6 +924,43 @@ contact_list_view_pixbuf_cell_data_func (GtkTreeViewColumn *tree_column,
}
static void
+contact_list_view_group_icon_cell_data_func (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EmpathyContactListView *view)
+{
+ GdkPixbuf *pixbuf = NULL;
+ gboolean is_group;
+ gchar *name;
+
+ gtk_tree_model_get (model, iter,
+ EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, &is_group,
+ EMPATHY_CONTACT_LIST_STORE_COL_NAME, &name,
+ -1);
+
+ if (!is_group)
+ goto out;
+
+ if (tp_strdiff (name, EMPATHY_CONTACT_LIST_STORE_FAVORITE))
+ goto out;
+
+ pixbuf = empathy_pixbuf_from_icon_name ("emblem-favorite",
+ GTK_ICON_SIZE_MENU);
+
+out:
+ g_object_set (cell,
+ "visible", pixbuf != NULL,
+ "pixbuf", pixbuf,
+ NULL);
+
+ if (pixbuf != NULL)
+ g_object_unref (pixbuf);
+
+ g_free (name);
+}
+
+static void
contact_list_view_audio_call_cell_data_func (
GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
@@ -1104,6 +1197,22 @@ contact_list_view_setup (EmpathyContactListView *view)
"visible", FALSE,
NULL);
+ /* Group icon */
+ cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (col, cell, FALSE);
+ gtk_tree_view_column_set_cell_data_func (
+ col, cell,
+ (GtkTreeCellDataFunc) contact_list_view_group_icon_cell_data_func,
+ view, NULL);
+
+ g_object_set (cell,
+ "xpad", 0,
+ "ypad", 0,
+ "visible", FALSE,
+ "width", 16,
+ "height", 16,
+ NULL);
+
/* Name */
cell = empathy_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (col, cell, TRUE);
@@ -1446,7 +1555,8 @@ empathy_contact_list_view_get_flags (EmpathyContactListView *view)
}
gchar *
-empathy_contact_list_view_get_selected_group (EmpathyContactListView *view)
+empathy_contact_list_view_get_selected_group (EmpathyContactListView *view,
+ gboolean *is_fake_group)
{
EmpathyContactListViewPriv *priv;
GtkTreeSelection *selection;
@@ -1454,6 +1564,7 @@ empathy_contact_list_view_get_selected_group (EmpathyContactListView *view)
GtkTreeModel *model;
gboolean is_group;
gchar *name;
+ gboolean fake;
g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
@@ -1467,6 +1578,7 @@ empathy_contact_list_view_get_selected_group (EmpathyContactListView *view)
gtk_tree_model_get (model, &iter,
EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, &is_group,
EMPATHY_CONTACT_LIST_STORE_COL_NAME, &name,
+ EMPATHY_CONTACT_LIST_STORE_COL_IS_FAKE_GROUP, &fake,
-1);
if (!is_group) {
@@ -1474,6 +1586,9 @@ empathy_contact_list_view_get_selected_group (EmpathyContactListView *view)
return NULL;
}
+ if (is_fake_group != NULL)
+ *is_fake_group = fake;
+
return name;
}
@@ -1510,7 +1625,7 @@ contact_list_view_group_remove_activate_cb (GtkMenuItem *menuitem,
EmpathyContactListViewPriv *priv = GET_PRIV (view);
gchar *group;
- group = empathy_contact_list_view_get_selected_group (view);
+ group = empathy_contact_list_view_get_selected_group (view, NULL);
if (group) {
gchar *text;
GtkWindow *parent;
@@ -1538,6 +1653,7 @@ empathy_contact_list_view_get_group_menu (EmpathyContactListView *view)
GtkWidget *menu;
GtkWidget *item;
GtkWidget *image;
+ gboolean is_fake_group;
g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
@@ -1546,8 +1662,9 @@ empathy_contact_list_view_get_group_menu (EmpathyContactListView *view)
return NULL;
}
- group = empathy_contact_list_view_get_selected_group (view);
- if (!group) {
+ group = empathy_contact_list_view_get_selected_group (view, &is_fake_group);
+ if (!group || is_fake_group) {
+ /* We can't alter fake groups */
return NULL;
}