2 * Copyright (C) 2005-2007 Imendio AB
3 * Copyright (C) 2007-2008, 2010 Collabora Ltd.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301 USA
20 * Authors: Mikael Hallendal <micke@imendio.com>
21 * Martyn Russell <martyn@imendio.com>
22 * Xavier Claessens <xclaesse@gmail.com>
23 * Philip Withnall <philip.withnall@collabora.co.uk>
25 * Based off EmpathyContactListView.
32 #include <glib/gi18n-lib.h>
35 #include <telepathy-glib/util.h>
37 #include <folks/folks.h>
38 #include <folks/folks-telepathy.h>
40 #include <libempathy/empathy-individual-manager.h>
41 #include <libempathy/empathy-utils.h>
43 #include "empathy-persona-view.h"
44 #include "empathy-contact-widget.h"
45 #include "empathy-images.h"
46 #include "empathy-cell-renderer-text.h"
47 #include "empathy-cell-renderer-activatable.h"
48 #include "empathy-gtk-enum-types.h"
49 #include "empathy-gtk-marshal.h"
50 #include "empathy-ui-utils.h"
52 #define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
53 #include <libempathy/empathy-debug.h>
56 * SECTION:empathy-persona-view
57 * @title: EmpathyPersonaView
58 * @short_description: A tree view which displays personas from an individual
59 * @include: libempathy-gtk/empathy-persona-view.h
61 * #EmpathyPersonaView is a tree view widget which displays the personas from
62 * a given #EmpathyPersonaStore.
64 * It supports hiding offline personas and highlighting active personas. Active
65 * personas are those which have recently changed state (e.g. online, offline or
66 * from normal to a busy state).
69 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyPersonaView)
73 GtkTreeModelFilter
*filter
;
74 GtkWidget
*tooltip_widget
;
75 gboolean show_offline
;
76 EmpathyPersonaViewFeatureFlags features
;
77 } EmpathyPersonaViewPriv
;
89 DND_DRAG_TYPE_UNKNOWN
= -1,
90 DND_DRAG_TYPE_INDIVIDUAL_ID
= 0,
91 DND_DRAG_TYPE_PERSONA_ID
,
95 #define DRAG_TYPE(T,I) \
98 static const GtkTargetEntry drag_types_dest
[] = {
99 DRAG_TYPE ("text/individual-id", DND_DRAG_TYPE_INDIVIDUAL_ID
),
100 DRAG_TYPE ("text/plain", DND_DRAG_TYPE_STRING
),
101 DRAG_TYPE ("STRING", DND_DRAG_TYPE_STRING
),
104 static const GtkTargetEntry drag_types_source
[] = {
105 DRAG_TYPE ("text/persona-id", DND_DRAG_TYPE_PERSONA_ID
),
110 static GdkAtom drag_atoms_dest
[G_N_ELEMENTS (drag_types_dest
)];
114 DRAG_INDIVIDUAL_RECEIVED
,
118 static guint signals
[LAST_SIGNAL
];
120 G_DEFINE_TYPE (EmpathyPersonaView
, empathy_persona_view
, GTK_TYPE_TREE_VIEW
);
123 filter_visible_func (GtkTreeModel
*model
,
125 EmpathyPersonaView
*self
)
127 EmpathyPersonaViewPriv
*priv
= GET_PRIV (self
);
130 gtk_tree_model_get (model
, iter
,
131 EMPATHY_PERSONA_STORE_COL_IS_ONLINE
, &is_online
,
134 return (priv
->show_offline
|| is_online
);
138 set_model (EmpathyPersonaView
*self
,
141 EmpathyPersonaViewPriv
*priv
= GET_PRIV (self
);
143 tp_clear_object (&priv
->filter
);
145 priv
->filter
= GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model
,
147 gtk_tree_model_filter_set_visible_func (priv
->filter
,
148 (GtkTreeModelFilterVisibleFunc
) filter_visible_func
, self
, NULL
);
150 gtk_tree_view_set_model (GTK_TREE_VIEW (self
), GTK_TREE_MODEL (priv
->filter
));
154 tooltip_destroy_cb (GtkWidget
*widget
,
155 EmpathyPersonaView
*self
)
157 EmpathyPersonaViewPriv
*priv
= GET_PRIV (self
);
159 if (priv
->tooltip_widget
)
161 DEBUG ("Tooltip destroyed");
162 g_object_unref (priv
->tooltip_widget
);
163 priv
->tooltip_widget
= NULL
;
168 query_tooltip_cb (EmpathyPersonaView
*self
,
171 gboolean keyboard_mode
,
175 EmpathyPersonaViewPriv
*priv
= GET_PRIV (self
);
176 FolksPersona
*persona
;
177 EmpathyContact
*contact
;
181 static gint running
= 0;
182 gboolean ret
= FALSE
;
184 /* Avoid an infinite loop. See GNOME bug #574377 */
189 if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (self
), &x
, &y
,
190 keyboard_mode
, &model
, &path
, &iter
))
195 gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (self
), tooltip
, path
);
196 gtk_tree_path_free (path
);
198 gtk_tree_model_get (model
, &iter
,
199 EMPATHY_PERSONA_STORE_COL_PERSONA
, &persona
,
204 contact
= empathy_contact_dup_from_tp_contact (tpf_persona_get_contact (
205 TPF_PERSONA (persona
)));
207 if (priv
->tooltip_widget
== NULL
)
209 priv
->tooltip_widget
= empathy_contact_widget_new (contact
,
210 EMPATHY_CONTACT_WIDGET_FOR_TOOLTIP
|
211 EMPATHY_CONTACT_WIDGET_SHOW_LOCATION
);
212 gtk_container_set_border_width (GTK_CONTAINER (priv
->tooltip_widget
), 8);
213 g_object_ref (priv
->tooltip_widget
);
214 g_signal_connect (priv
->tooltip_widget
, "destroy",
215 (GCallback
) tooltip_destroy_cb
, self
);
216 gtk_widget_show (priv
->tooltip_widget
);
220 empathy_contact_widget_set_contact (priv
->tooltip_widget
, contact
);
223 gtk_tooltip_set_custom (tooltip
, priv
->tooltip_widget
);
226 g_object_unref (contact
);
227 g_object_unref (persona
);
236 cell_set_background (EmpathyPersonaView
*self
,
237 GtkCellRenderer
*cell
,
243 GtkStyleContext
*style
;
245 style
= gtk_widget_get_style_context (GTK_WIDGET (self
));
247 gtk_style_context_get_background_color (style
, GTK_STATE_FLAG_SELECTED
,
250 /* Here we take the current theme colour and add it to
251 * the colour for white and average the two. This
252 * gives a colour which is inline with the theme but
255 empathy_make_color_whiter (&color
);
257 g_object_set (cell
, "cell-background-rgba", &color
, NULL
);
261 g_object_set (cell
, "cell-background-rgba", NULL
, NULL
);
266 pixbuf_cell_data_func (GtkTreeViewColumn
*tree_column
,
267 GtkCellRenderer
*cell
,
270 EmpathyPersonaView
*self
)
275 gtk_tree_model_get (model
, iter
,
276 EMPATHY_PERSONA_STORE_COL_IS_ACTIVE
, &is_active
,
277 EMPATHY_PERSONA_STORE_COL_ICON_STATUS
, &pixbuf
,
280 g_object_set (cell
, "pixbuf", pixbuf
, NULL
);
281 tp_clear_object (&pixbuf
);
283 cell_set_background (self
, cell
, is_active
);
287 audio_call_cell_data_func (GtkTreeViewColumn
*tree_column
,
288 GtkCellRenderer
*cell
,
291 EmpathyPersonaView
*self
)
294 gboolean can_audio
, can_video
;
296 gtk_tree_model_get (model
, iter
,
297 EMPATHY_PERSONA_STORE_COL_IS_ACTIVE
, &is_active
,
298 EMPATHY_PERSONA_STORE_COL_CAN_AUDIO_CALL
, &can_audio
,
299 EMPATHY_PERSONA_STORE_COL_CAN_VIDEO_CALL
, &can_video
,
303 "visible", (can_audio
|| can_video
),
304 "icon-name", can_video
? EMPATHY_IMAGE_VIDEO_CALL
: EMPATHY_IMAGE_VOIP
,
307 cell_set_background (self
, cell
, is_active
);
311 avatar_cell_data_func (GtkTreeViewColumn
*tree_column
,
312 GtkCellRenderer
*cell
,
315 EmpathyPersonaView
*self
)
318 gboolean show_avatar
, is_active
;
320 gtk_tree_model_get (model
, iter
,
321 EMPATHY_PERSONA_STORE_COL_PIXBUF_AVATAR
, &pixbuf
,
322 EMPATHY_PERSONA_STORE_COL_PIXBUF_AVATAR_VISIBLE
, &show_avatar
,
323 EMPATHY_PERSONA_STORE_COL_IS_ACTIVE
, &is_active
,
327 "visible", show_avatar
,
331 tp_clear_object (&pixbuf
);
333 cell_set_background (self
, cell
, is_active
);
337 text_cell_data_func (GtkTreeViewColumn
*tree_column
,
338 GtkCellRenderer
*cell
,
341 EmpathyPersonaView
*self
)
345 gtk_tree_model_get (model
, iter
,
346 EMPATHY_PERSONA_STORE_COL_IS_ACTIVE
, &is_active
,
349 cell_set_background (self
, cell
, is_active
);
353 individual_drag_received (EmpathyPersonaView
*self
,
354 GdkDragContext
*context
,
355 GtkSelectionData
*selection
)
357 EmpathyIndividualManager
*manager
= NULL
;
358 FolksIndividual
*individual
;
359 const gchar
*individual_id
;
360 gboolean success
= FALSE
;
362 individual_id
= (const gchar
*) gtk_selection_data_get_data (selection
);
363 manager
= empathy_individual_manager_dup_singleton ();
364 individual
= empathy_individual_manager_lookup_member (manager
,
367 if (individual
== NULL
)
369 DEBUG ("Failed to find drag event individual with ID '%s'",
371 g_object_unref (manager
);
375 /* Emit a signal notifying of the drag. */
376 g_signal_emit (self
, signals
[DRAG_INDIVIDUAL_RECEIVED
], 0,
377 gdk_drag_context_get_selected_action (context
), individual
, &success
);
379 g_object_unref (manager
);
385 drag_data_received (GtkWidget
*widget
,
386 GdkDragContext
*context
,
389 GtkSelectionData
*selection
,
393 EmpathyPersonaView
*self
= EMPATHY_PERSONA_VIEW (widget
);
394 gboolean success
= TRUE
;
396 if (info
== DND_DRAG_TYPE_INDIVIDUAL_ID
|| info
== DND_DRAG_TYPE_STRING
)
397 success
= individual_drag_received (self
, context
, selection
);
399 gtk_drag_finish (context
, success
, FALSE
, GDK_CURRENT_TIME
);
403 drag_motion (GtkWidget
*widget
,
404 GdkDragContext
*context
,
409 EmpathyPersonaView
*self
= EMPATHY_PERSONA_VIEW (widget
);
412 DndDragType drag_type
= DND_DRAG_TYPE_UNKNOWN
;
414 target
= gtk_drag_dest_find_target (GTK_WIDGET (self
), context
, NULL
);
416 /* Determine the DndDragType of the data */
417 for (i
= 0; i
< G_N_ELEMENTS (drag_atoms_dest
); i
++)
419 if (target
== drag_atoms_dest
[i
])
421 drag_type
= drag_types_dest
[i
].info
;
426 if (drag_type
== DND_DRAG_TYPE_INDIVIDUAL_ID
)
430 /* FIXME: It doesn't make sense for us to highlight a specific row or
431 * position to drop an Individual in, so just highlight the entire
433 * Since I can't find a way to do this, just highlight the first possible
434 * position in the tree. */
435 gdk_drag_status (context
, gdk_drag_context_get_suggested_action (context
),
438 path
= gtk_tree_path_new_first ();
439 gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (self
), path
,
440 GTK_TREE_VIEW_DROP_BEFORE
);
441 gtk_tree_path_free (path
);
446 /* Unknown or unhandled drag target */
447 gdk_drag_status (context
, GDK_ACTION_DEFAULT
, time_
);
448 gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (self
), NULL
, 0);
454 drag_data_get (GtkWidget
*widget
,
455 GdkDragContext
*context
,
456 GtkSelectionData
*selection
,
460 EmpathyPersonaView
*self
= EMPATHY_PERSONA_VIEW (widget
);
461 FolksPersona
*persona
;
462 const gchar
*persona_uid
;
464 if (info
!= DND_DRAG_TYPE_PERSONA_ID
)
467 persona
= empathy_persona_view_dup_selected (self
);
471 persona_uid
= folks_persona_get_uid (persona
);
472 gtk_selection_data_set (selection
,
473 gdk_atom_intern ("text/persona-id", FALSE
), 8,
474 (guchar
*) persona_uid
, strlen (persona_uid
) + 1);
476 g_object_unref (persona
);
480 drag_drop (GtkWidget
*widget
,
481 GdkDragContext
*drag_context
,
490 set_features (EmpathyPersonaView
*self
,
491 EmpathyPersonaViewFeatureFlags features
)
493 EmpathyPersonaViewPriv
*priv
= GET_PRIV (self
);
495 priv
->features
= features
;
497 /* Setting reorderable is a hack that gets us row previews as drag icons
498 for free. We override all the drag handlers. It's tricky to get the
499 position of the drag icon right in drag_begin. GtkTreeView has special
500 voodoo for it, so we let it do the voodoo that he do (but only if dragging
502 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (self
),
503 (features
& EMPATHY_PERSONA_VIEW_FEATURE_PERSONA_DRAG
));
505 /* Update DnD source/dest */
506 if (features
& EMPATHY_PERSONA_VIEW_FEATURE_PERSONA_DRAG
)
508 gtk_drag_source_set (GTK_WIDGET (self
),
511 G_N_ELEMENTS (drag_types_source
),
512 GDK_ACTION_MOVE
| GDK_ACTION_COPY
);
516 gtk_drag_source_unset (GTK_WIDGET (self
));
519 if (features
& EMPATHY_PERSONA_VIEW_FEATURE_PERSONA_DROP
)
521 gtk_drag_dest_set (GTK_WIDGET (self
),
522 GTK_DEST_DEFAULT_ALL
,
524 G_N_ELEMENTS (drag_types_dest
), GDK_ACTION_MOVE
| GDK_ACTION_COPY
);
528 gtk_drag_dest_unset (GTK_WIDGET (self
));
531 g_object_notify (G_OBJECT (self
), "features");
535 empathy_persona_view_init (EmpathyPersonaView
*self
)
537 EmpathyPersonaViewPriv
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (self
,
538 EMPATHY_TYPE_PERSONA_VIEW
, EmpathyPersonaViewPriv
);
542 /* Connect to tree view signals rather than override. */
543 g_signal_connect (self
, "query-tooltip", (GCallback
) query_tooltip_cb
, NULL
);
547 constructed (GObject
*object
)
549 EmpathyPersonaView
*self
= EMPATHY_PERSONA_VIEW (object
);
550 GtkCellRenderer
*cell
;
551 GtkTreeViewColumn
*col
;
556 "headers-visible", FALSE
,
557 "show-expanders", FALSE
,
560 col
= gtk_tree_view_column_new ();
563 cell
= gtk_cell_renderer_pixbuf_new ();
564 gtk_tree_view_column_pack_start (col
, cell
, FALSE
);
565 gtk_tree_view_column_set_cell_data_func (col
, cell
,
566 (GtkTreeCellDataFunc
) pixbuf_cell_data_func
, self
, NULL
);
575 cell
= empathy_cell_renderer_text_new ();
576 gtk_tree_view_column_pack_start (col
, cell
, TRUE
);
577 gtk_tree_view_column_set_cell_data_func (col
, cell
,
578 (GtkTreeCellDataFunc
) text_cell_data_func
, self
, NULL
);
580 /* We (ab)use the name and status properties here to display display ID and
581 * account name, respectively. Harmless. */
582 gtk_tree_view_column_add_attribute (col
, cell
,
583 "name", EMPATHY_PERSONA_STORE_COL_DISPLAY_ID
);
584 gtk_tree_view_column_add_attribute (col
, cell
,
585 "text", EMPATHY_PERSONA_STORE_COL_DISPLAY_ID
);
586 gtk_tree_view_column_add_attribute (col
, cell
,
587 "presence-type", EMPATHY_PERSONA_STORE_COL_PRESENCE_TYPE
);
588 gtk_tree_view_column_add_attribute (col
, cell
,
589 "status", EMPATHY_PERSONA_STORE_COL_ACCOUNT_NAME
);
591 /* Audio Call Icon */
592 cell
= empathy_cell_renderer_activatable_new ();
593 gtk_tree_view_column_pack_start (col
, cell
, FALSE
);
594 gtk_tree_view_column_set_cell_data_func (col
, cell
,
595 (GtkTreeCellDataFunc
) audio_call_cell_data_func
, self
, NULL
);
602 cell
= gtk_cell_renderer_pixbuf_new ();
603 gtk_tree_view_column_pack_start (col
, cell
, FALSE
);
604 gtk_tree_view_column_set_cell_data_func (col
, cell
,
605 (GtkTreeCellDataFunc
) avatar_cell_data_func
, self
, NULL
);
615 /* Actually add the column now we have added all cell renderers */
616 gtk_tree_view_append_column (GTK_TREE_VIEW (self
), col
);
619 for (i
= 0; i
< G_N_ELEMENTS (drag_types_dest
); ++i
)
620 drag_atoms_dest
[i
] = gdk_atom_intern (drag_types_dest
[i
].target
, FALSE
);
624 get_property (GObject
*object
,
629 EmpathyPersonaViewPriv
*priv
= GET_PRIV (object
);
634 g_value_set_object (value
, priv
->filter
);
636 case PROP_SHOW_OFFLINE
:
637 g_value_set_boolean (value
, priv
->show_offline
);
640 g_value_set_flags (value
, priv
->features
);
643 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
649 set_property (GObject
*object
,
654 EmpathyPersonaView
*self
= EMPATHY_PERSONA_VIEW (object
);
659 set_model (self
, g_value_get_object (value
));
661 case PROP_SHOW_OFFLINE
:
662 empathy_persona_view_set_show_offline (self
,
663 g_value_get_boolean (value
));
666 set_features (self
, g_value_get_flags (value
));
669 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
675 dispose (GObject
*object
)
677 EmpathyPersonaView
*self
= EMPATHY_PERSONA_VIEW (object
);
678 EmpathyPersonaViewPriv
*priv
= GET_PRIV (self
);
680 tp_clear_object (&priv
->filter
);
682 if (priv
->tooltip_widget
)
683 gtk_widget_destroy (priv
->tooltip_widget
);
684 priv
->tooltip_widget
= NULL
;
686 G_OBJECT_CLASS (empathy_persona_view_parent_class
)->dispose (object
);
690 empathy_persona_view_class_init (EmpathyPersonaViewClass
*klass
)
692 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
693 GtkWidgetClass
*widget_class
= GTK_WIDGET_CLASS (klass
);
695 object_class
->constructed
= constructed
;
696 object_class
->dispose
= dispose
;
697 object_class
->get_property
= get_property
;
698 object_class
->set_property
= set_property
;
700 widget_class
->drag_data_received
= drag_data_received
;
701 widget_class
->drag_drop
= drag_drop
;
702 widget_class
->drag_data_get
= drag_data_get
;
703 widget_class
->drag_motion
= drag_motion
;
705 signals
[DRAG_INDIVIDUAL_RECEIVED
] =
706 g_signal_new ("drag-individual-received",
707 G_OBJECT_CLASS_TYPE (klass
),
709 G_STRUCT_OFFSET (EmpathyPersonaViewClass
, drag_individual_received
),
711 _empathy_gtk_marshal_BOOLEAN__UINT_OBJECT
,
712 G_TYPE_BOOLEAN
, 2, G_TYPE_UINT
, FOLKS_TYPE_INDIVIDUAL
);
714 /* We override the "model" property so that we can wrap it in a
715 * GtkTreeModelFilter for showing/hiding offline personas. */
716 g_object_class_override_property (object_class
, PROP_MODEL
, "model");
719 * EmpathyPersonaStore:show-offline:
721 * Whether to display offline personas.
723 g_object_class_install_property (object_class
, PROP_SHOW_OFFLINE
,
724 g_param_spec_boolean ("show-offline",
726 "Whether to display offline personas.",
728 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
));
731 * EmpathyPersonaStore:features:
733 * Features of the view, such as whether drag and drop is enabled.
735 g_object_class_install_property (object_class
, PROP_FEATURES
,
736 g_param_spec_flags ("features",
738 "Flags for all enabled features.",
739 EMPATHY_TYPE_PERSONA_VIEW_FEATURE_FLAGS
,
740 EMPATHY_PERSONA_VIEW_FEATURE_NONE
,
741 G_PARAM_CONSTRUCT_ONLY
| G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
));
743 g_type_class_add_private (object_class
, sizeof (EmpathyPersonaViewPriv
));
747 * empathy_persona_view_new:
748 * @store: an #EmpathyPersonaStore
749 * @features: a set of flags specifying the view's functionality, or
750 * %EMPATHY_PERSONA_VIEW_FEATURE_NONE
752 * Create a new #EmpathyPersonaView displaying the personas in
753 * #EmpathyPersonaStore.
755 * Return value: a new #EmpathyPersonaView
758 empathy_persona_view_new (EmpathyPersonaStore
*store
,
759 EmpathyPersonaViewFeatureFlags features
)
761 g_return_val_if_fail (EMPATHY_IS_PERSONA_STORE (store
), NULL
);
763 return g_object_new (EMPATHY_TYPE_PERSONA_VIEW
,
765 "features", features
,
770 * empathy_persona_view_dup_selected:
771 * @self: an #EmpathyPersonaView
773 * Return the #FolksPersona associated with the currently selected row. The
774 * persona is referenced before being returned. If no row is selected, %NULL is
777 * Return value: the currently selected #FolksPersona, or %NULL; unref with
781 empathy_persona_view_dup_selected (EmpathyPersonaView
*self
)
783 GtkTreeSelection
*selection
;
786 FolksPersona
*persona
;
788 g_return_val_if_fail (EMPATHY_IS_PERSONA_VIEW (self
), NULL
);
790 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (self
));
791 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
794 gtk_tree_model_get (model
, &iter
,
795 EMPATHY_PERSONA_STORE_COL_PERSONA
, &persona
,
802 * empathy_persona_view_get_show_offline:
803 * @self: an #EmpathyPersonaView
805 * Get the value of the #EmpathyPersonaView:show-offline property.
807 * Return value: %TRUE if offline personas are being shown, %FALSE otherwise
810 empathy_persona_view_get_show_offline (EmpathyPersonaView
*self
)
812 g_return_val_if_fail (EMPATHY_IS_PERSONA_VIEW (self
), FALSE
);
814 return GET_PRIV (self
)->show_offline
;
818 * empathy_persona_view_set_show_offline:
819 * @self: an #EmpathyPersonaView
820 * @show_offline: %TRUE to show personas which are offline, %FALSE otherwise
822 * Set the #EmpathyPersonaView:show-offline property to @show_offline.
825 empathy_persona_view_set_show_offline (EmpathyPersonaView
*self
,
826 gboolean show_offline
)
828 EmpathyPersonaViewPriv
*priv
;
830 g_return_if_fail (EMPATHY_IS_PERSONA_VIEW (self
));
832 priv
= GET_PRIV (self
);
833 priv
->show_offline
= show_offline
;
835 gtk_tree_model_filter_refilter (priv
->filter
);
837 g_object_notify (G_OBJECT (self
), "show-offline");