diff options
Diffstat (limited to 'libempathy-gtk')
28 files changed, 923 insertions, 389 deletions
diff --git a/libempathy-gtk/empathy-account-chooser.c b/libempathy-gtk/empathy-account-chooser.c index 8c402c07a..5d11e8e1e 100644 --- a/libempathy-gtk/empathy-account-chooser.c +++ b/libempathy-gtk/empathy-account-chooser.c @@ -37,6 +37,23 @@ #include "empathy-ui-utils.h" #include "empathy-account-chooser.h" +/** + * SECTION:empathy-account-chooser + * @title:EmpathyAccountChooser + * @short_description: A widget used to choose from a list of accounts + * @include: libempathy-gtk/empathy-account-chooser.h + * + * #EmpathyAccountChooser is a widget which extends #GtkComboBox to provide + * a chooser of available accounts. + */ + +/** + * EmpathyAccountChooser: + * @parent: parent object + * + * Widget which extends #GtkComboBox to provide a chooser of available accounts. + */ + #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountChooser) typedef struct { EmpathyAccountManager *manager; @@ -112,6 +129,11 @@ empathy_account_chooser_class_init (EmpathyAccountChooserClass *klass) object_class->get_property = account_chooser_get_property; object_class->set_property = account_chooser_set_property; + /** + * EmpathyAccountChooser:has-all-option: + * + * Have an additional option in the list to mean all accounts. + */ g_object_class_install_property (object_class, PROP_HAS_ALL_OPTION, g_param_spec_boolean ("has-all-option", @@ -209,6 +231,13 @@ account_chooser_set_property (GObject *object, }; } +/** + * empathy_account_chooser_new: + * + * Creates a new #EmpathyAccountChooser. + * + * Return value: A new #EmpathyAccountChooser + */ GtkWidget * empathy_account_chooser_new (void) { @@ -219,8 +248,18 @@ empathy_account_chooser_new (void) return chooser; } +/** + * empathy_account_chooser_dup_account: + * @chooser: an #EmpathyAccountChooser + * + * Returns the account which is currently selected in the chooser or %NULL + * if there is no account selected. The #McAccount returned should be + * unrefed with g_object_unref() when finished with. + * + * Return value: a new ref to the #McAccount currently selected, or %NULL. + */ McAccount * -empathy_account_chooser_get_account (EmpathyAccountChooser *chooser) +empathy_account_chooser_dup_account (EmpathyAccountChooser *chooser) { EmpathyAccountChooserPriv *priv; McAccount *account; @@ -241,6 +280,44 @@ empathy_account_chooser_get_account (EmpathyAccountChooser *chooser) return account; } +/** + * empathy_account_chooser_get_connection: + * @chooser: an #EmpathyAccountChooser + * + * Returns a borrowed reference to the #TpConnection associated with the + * account currently selected. The caller must reference the returned object with + * g_object_ref() if it will be kept + * + * Return value: a borrowed reference to the #TpConnection associated with the + * account curently selected. + */ +TpConnection * +empathy_account_chooser_get_connection (EmpathyAccountChooser *chooser) +{ + EmpathyAccountChooserPriv *priv; + McAccount *account; + TpConnection *connection; + + g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser), NULL); + + priv = GET_PRIV (chooser); + + account = empathy_account_chooser_dup_account (chooser); + connection = empathy_account_manager_get_connection (priv->manager, account); + g_object_unref (account); + + return connection; +} + +/** + * empathy_account_chooser_set_account: + * @chooser: an #EmpathyAccountChooser + * @account: an #McAccount + * + * Sets the currently selected account to @account, if it exists in the list. + * + * Return value: whether the chooser was set to @account. + */ gboolean empathy_account_chooser_set_account (EmpathyAccountChooser *chooser, McAccount *account) @@ -266,6 +343,16 @@ empathy_account_chooser_set_account (EmpathyAccountChooser *chooser, return data.set; } +/** + * empathy_account_chooser_get_has_all_option: + * @chooser: an #EmpathyAccountChooser + * + * Returns whether @chooser has the #EmpathyAccountChooser:has-all-option property + * set to true. + * + * Return value: whether @chooser has the #EmpathyAccountChooser:has-all-option property + * enabled. + */ gboolean empathy_account_chooser_get_has_all_option (EmpathyAccountChooser *chooser) { @@ -278,6 +365,13 @@ empathy_account_chooser_get_has_all_option (EmpathyAccountChooser *chooser) return priv->has_all_option; } +/** + * empathy_account_chooser_set_has_all_option: + * @chooser: an #EmpathyAccountChooser + * @has_all_option: a new value for the #EmpathyAccountChooser:has-all-option property + * + * Sets the #EmpathyAccountChooser:has-all-option property. + */ void empathy_account_chooser_set_has_all_option (EmpathyAccountChooser *chooser, gboolean has_all_option) @@ -618,6 +712,15 @@ account_chooser_filter_foreach (GtkTreeModel *model, return FALSE; } +/** + * empathy_account_chooser_set_filter: + * @chooser: an #EmpathyAccountChooser + * @filter: a filter + * @user_data: data to pass to @filter, or %NULL + * + * Sets a filter on the @chooser so only accounts that are %TRUE in the eyes + * of the filter are visible in the @chooser. + */ void empathy_account_chooser_set_filter (EmpathyAccountChooser *chooser, EmpathyAccountChooserFilterFunc filter, @@ -639,6 +742,27 @@ empathy_account_chooser_set_filter (EmpathyAccountChooser *chooser, gtk_tree_model_foreach (model, account_chooser_filter_foreach, chooser); } +/** + * EmpathyAccountChooserFilterFunc: + * @account: an #McAccount + * @user_data: user data, or %NULL + * + * A function which decides whether the account indicated by @account + * is visible. + * + * Return value: whether the account indicated by @account is visible. + */ + +/** + * empathy_account_chooser_filter_is_connected: + * @account: an #McAccount + * @user_data: user data or %NULL + * + * A useful #EmpathyAccountChooserFilterFunc that one could pass into + * empathy_account_chooser_set_filter() and only show connected accounts. + * + * Return value: Whether @account is connected + */ gboolean empathy_account_chooser_filter_is_connected (McAccount *account, gpointer user_data) diff --git a/libempathy-gtk/empathy-account-chooser.h b/libempathy-gtk/empathy-account-chooser.h index c15923bc3..98d568bcc 100644 --- a/libempathy-gtk/empathy-account-chooser.h +++ b/libempathy-gtk/empathy-account-chooser.h @@ -47,6 +47,8 @@ typedef struct _EmpathyAccountChooserClass EmpathyAccountChooserClass; struct _EmpathyAccountChooser { GtkComboBox parent; + + /*<private>*/ gpointer priv; }; @@ -56,7 +58,8 @@ struct _EmpathyAccountChooserClass { GType empathy_account_chooser_get_type (void) G_GNUC_CONST; GtkWidget * empathy_account_chooser_new (void); -McAccount * empathy_account_chooser_get_account (EmpathyAccountChooser *chooser); +McAccount * empathy_account_chooser_dup_account (EmpathyAccountChooser *chooser); +TpConnection * empathy_account_chooser_get_connection (EmpathyAccountChooser *chooser); gboolean empathy_account_chooser_set_account (EmpathyAccountChooser *chooser, McAccount *account); gboolean empathy_account_chooser_get_has_all_option (EmpathyAccountChooser *chooser); diff --git a/libempathy-gtk/empathy-account-widget-irc.c b/libempathy-gtk/empathy-account-widget-irc.c index 3af842415..cc86a5aaa 100644 --- a/libempathy-gtk/empathy-account-widget-irc.c +++ b/libempathy-gtk/empathy-account-widget-irc.c @@ -50,9 +50,6 @@ typedef struct { GtkWidget *vbox_settings; GtkWidget *combobox_network; - GtkWidget *button_add_network; - GtkWidget *button_network; - GtkWidget *button_remove; } EmpathyAccountWidgetIrc; enum { @@ -462,9 +459,6 @@ empathy_account_widget_irc_new (McAccount *account) gui = empathy_builder_get_file (filename, "vbox_irc_settings", &settings->vbox_settings, "combobox_network", &settings->combobox_network, - "button_network", &settings->button_network, - "button_add_network", &settings->button_add_network, - "button_remove", &settings->button_remove, NULL); g_free (filename); @@ -501,7 +495,7 @@ empathy_account_widget_irc_new (McAccount *account) "vbox_irc_settings", "destroy", account_widget_irc_destroy_cb, "button_network", "clicked", account_widget_irc_button_edit_network_clicked_cb, "button_add_network", "clicked", account_widget_irc_button_add_network_clicked_cb, - "button_remove", "clicked", account_widget_irc_button_remove_clicked_cb, + "button_remove_network", "clicked", account_widget_irc_button_remove_clicked_cb, "combobox_network", "changed", account_widget_irc_combobox_network_changed_cb, NULL); diff --git a/libempathy-gtk/empathy-account-widget-irc.ui b/libempathy-gtk/empathy-account-widget-irc.ui index f499866eb..76c67f711 100644 --- a/libempathy-gtk/empathy-account-widget-irc.ui +++ b/libempathy-gtk/empathy-account-widget-irc.ui @@ -3,7 +3,6 @@ <requires lib="gtk+" version="2.16"/> <!-- interface-naming-policy toplevel-contextual --> <object class="GtkDialog" id="irc_network_dialog"> - <property name="visible">True</property> <property name="border_width">5</property> <property name="title" translatable="yes">Network</property> <property name="window_position">center-on-parent</property> @@ -418,7 +417,7 @@ </packing> </child> <child> - <object class="GtkButton" id="button_remove"> + <object class="GtkButton" id="button_remove_network"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -444,7 +443,7 @@ </packing> </child> <child> - <object class="GtkLabel" id="label_network"> + <object class="GtkLabel" id="label_network2"> <property name="visible">True</property> <property name="xalign">0</property> <property name="label" translatable="yes">Network:</property> diff --git a/libempathy-gtk/empathy-avatar-chooser.c b/libempathy-gtk/empathy-avatar-chooser.c index 04a5ed63e..c86b85d25 100644 --- a/libempathy-gtk/empathy-avatar-chooser.c +++ b/libempathy-gtk/empathy-avatar-chooser.c @@ -30,7 +30,7 @@ #include <gio/gio.h> #include <libempathy/empathy-utils.h> -#include <libempathy/empathy-contact-factory.h> +#include <libempathy/empathy-tp-contact-factory.h> #include "empathy-avatar-chooser.h" #include "empathy-conf.h" @@ -39,15 +39,31 @@ #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include <libempathy/empathy-debug.h> +/** + * SECTION:empathy-avatar-chooser + * @title: EmpathyAvatarChooser + * @short_description: A widget used to change avatar + * @include: libempathy-gtk/empathy-avatar-chooser.h + * + * #EmpathyAvatarChooser is a widget which extends #GtkButton to + * provide a way of changing avatar. + */ + +/** + * EmpathyAvatarChooser: + * @parent: parent object + * + * Widget which extends #GtkButton to provide a way of changing avatar. + */ + #define AVATAR_SIZE_SAVE 96 #define AVATAR_SIZE_VIEW 64 #define DEFAULT_DIR DATADIR"/pixmaps/faces" #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAvatarChooser) typedef struct { - EmpathyContactFactory *contact_factory; - McAccount *account; - EmpathyTpContactFactory *tp_contact_factory; + EmpathyTpContactFactory *factory; + TpConnection *connection; GtkFileChooser *chooser_dialog; gulong ready_handler_id; @@ -56,8 +72,8 @@ typedef struct { } EmpathyAvatarChooserPriv; static void avatar_chooser_finalize (GObject *object); -static void avatar_chooser_set_account (EmpathyAvatarChooser *self, - McAccount *account); +static void avatar_chooser_set_connection (EmpathyAvatarChooser *self, + TpConnection *connection); static void avatar_chooser_set_image (EmpathyAvatarChooser *chooser, EmpathyAvatar *avatar, GdkPixbuf *pixbuf, @@ -96,7 +112,7 @@ enum { enum { PROP_0, - PROP_ACCOUNT + PROP_CONNECTION }; static guint signals [LAST_SIGNAL]; @@ -125,8 +141,8 @@ avatar_chooser_get_property (GObject *object, EmpathyAvatarChooserPriv *priv = GET_PRIV (object); switch (param_id) { - case PROP_ACCOUNT: - g_value_set_object (value, priv->account); + case PROP_CONNECTION: + g_value_set_object (value, priv->connection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -143,8 +159,8 @@ avatar_chooser_set_property (GObject *object, EmpathyAvatarChooser *self = EMPATHY_AVATAR_CHOOSER (object); switch (param_id) { - case PROP_ACCOUNT: - avatar_chooser_set_account (self, g_value_get_object (value)); + case PROP_CONNECTION: + avatar_chooser_set_connection (self, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -162,6 +178,13 @@ empathy_avatar_chooser_class_init (EmpathyAvatarChooserClass *klass) object_class->get_property = avatar_chooser_get_property; object_class->set_property = avatar_chooser_set_property; + /** + * EmpathyAvatarChooser::changed: + * @chooser: an #EmpathyAvatarChooser + * + * Emitted when the chosen avatar has changed. + * + */ signals[CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (klass), @@ -171,15 +194,21 @@ empathy_avatar_chooser_class_init (EmpathyAvatarChooserClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - param_spec = g_param_spec_object ("account", - "McAccount", - "McAccount whose avatar should be " + /** + * EmpathyAvatarChooser:connection: + * + * The #TpConnection whose avatar should be shown and modified by + * the #EmpathyAvatarChooser instance. + */ + param_spec = g_param_spec_object ("connection", + "TpConnection", + "TpConnection whose avatar should be " "shown and modified by this widget", - MC_TYPE_ACCOUNT, + TP_TYPE_CONNECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, - PROP_ACCOUNT, + PROP_CONNECTION, param_spec); g_type_class_add_private (object_class, sizeof (EmpathyAvatarChooserPriv)); @@ -214,8 +243,6 @@ empathy_avatar_chooser_init (EmpathyAvatarChooser *chooser) G_CALLBACK (avatar_chooser_clicked_cb), chooser); - priv->contact_factory = empathy_contact_factory_dup_singleton (); - empathy_avatar_chooser_set (chooser, NULL); } @@ -226,11 +253,9 @@ avatar_chooser_finalize (GObject *object) priv = GET_PRIV (object); - avatar_chooser_set_account (EMPATHY_AVATAR_CHOOSER (object), NULL); - g_assert (priv->account == NULL); - g_assert (priv->tp_contact_factory == NULL); - - g_object_unref (priv->contact_factory); + avatar_chooser_set_connection (EMPATHY_AVATAR_CHOOSER (object), NULL); + g_assert (priv->connection == NULL); + g_assert (priv->factory == NULL); if (priv->avatar != NULL) { empathy_avatar_unref (priv->avatar); @@ -240,51 +265,22 @@ avatar_chooser_finalize (GObject *object) } static void -avatar_chooser_tp_cf_ready_cb (EmpathyTpContactFactory *tp_cf, - GParamSpec *unused, - EmpathyAvatarChooser *self) +avatar_chooser_set_connection (EmpathyAvatarChooser *self, + TpConnection *connection) { EmpathyAvatarChooserPriv *priv = GET_PRIV (self); - gboolean ready; - - /* sanity check that we're listening on the right ETpCF */ - g_assert (priv->tp_contact_factory == tp_cf); - - ready = empathy_tp_contact_factory_is_ready (tp_cf); - gtk_widget_set_sensitive (GTK_WIDGET (self), ready); -} - -static void -avatar_chooser_set_account (EmpathyAvatarChooser *self, - McAccount *account) -{ - EmpathyAvatarChooserPriv *priv = GET_PRIV (self); - - if (priv->account != NULL) { - g_object_unref (priv->account); - priv->account = NULL; - g_assert (priv->tp_contact_factory != NULL); + if (priv->connection != NULL) { + g_object_unref (priv->connection); + priv->connection = NULL; - g_signal_handler_disconnect (priv->tp_contact_factory, - priv->ready_handler_id); - priv->ready_handler_id = 0; - - g_object_unref (priv->tp_contact_factory); - priv->tp_contact_factory = NULL; + g_object_unref (priv->factory); + priv->factory = NULL; } - if (account != NULL) { - priv->account = g_object_ref (account); - priv->tp_contact_factory = g_object_ref ( - empathy_contact_factory_get_tp_factory ( - priv->contact_factory, priv->account)); - - priv->ready_handler_id = g_signal_connect ( - priv->tp_contact_factory, "notify::ready", - G_CALLBACK (avatar_chooser_tp_cf_ready_cb), self); - avatar_chooser_tp_cf_ready_cb (priv->tp_contact_factory, NULL, - self); + if (connection != NULL) { + priv->connection = g_object_ref (connection); + priv->factory = empathy_tp_contact_factory_dup_singleton (connection); } } @@ -412,7 +408,6 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser, EmpathyAvatar *avatar) { EmpathyAvatarChooserPriv *priv = GET_PRIV (chooser); - EmpathyTpContactFactory *tp_cf = priv->tp_contact_factory; guint max_width = 0, max_height = 0, max_size = 0; gchar **mime_types = NULL; gboolean needs_conversion = FALSE; @@ -424,15 +419,7 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser, gchar *converted_image_data = NULL; gsize converted_image_size = 0; - /* This should only be called if the user is setting a new avatar, - * which should only be allowed once the avatar requirements have been - * discovered. - */ - g_return_val_if_fail (tp_cf != NULL, NULL); - g_return_val_if_fail (empathy_tp_contact_factory_is_ready (tp_cf), - NULL); - - g_object_get (tp_cf, + g_object_get (priv->factory, "avatar-mime-types", &mime_types, /* Needs g_strfreev-ing */ "avatar-max-width", &max_width, "avatar-max-height", &max_height, @@ -529,6 +516,7 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser, &converted_image_size, new_format_name, &error, NULL); + g_object_unref (pixbuf_scaled); if (!saved) { g_free (new_format_name); @@ -884,6 +872,8 @@ avatar_chooser_update_preview_cb (GtkFileChooser *file_chooser, "gtk-dialog-question", GTK_ICON_SIZE_DIALOG); } + + g_free (filename); } gtk_file_chooser_set_preview_widget_active (file_chooser, TRUE); @@ -898,16 +888,6 @@ avatar_chooser_response_cb (GtkWidget *widget, priv->chooser_dialog = NULL; - if (response == GTK_RESPONSE_CANCEL) { - goto out; - } - - /* Check if we went non-ready since displaying the dialog. */ - if (!empathy_tp_contact_factory_is_ready (priv->tp_contact_factory)) { - DEBUG ("Can't set avatar when contact factory isn't ready."); - goto out; - } - if (response == GTK_RESPONSE_OK) { gchar *filename; gchar *path; @@ -929,7 +909,6 @@ avatar_chooser_response_cb (GtkWidget *widget, avatar_chooser_clear_image (chooser); } -out: gtk_widget_destroy (widget); } @@ -1034,12 +1013,26 @@ avatar_chooser_clicked_cb (GtkWidget *button, g_free (saved_dir); } +/** + * empathy_avatar_chooser_new: + * + * Creates a new #EmpathyAvatarChooser. + * + * Return value: a new #EmpathyAvatarChooser + */ GtkWidget * empathy_avatar_chooser_new () { return g_object_new (EMPATHY_TYPE_AVATAR_CHOOSER, NULL); } +/** + * empathy_avatar_chooser_set: + * @chooser: an #EmpathyAvatarChooser + * @avatar: a new #EmpathyAvatar + * + * Sets the @chooser to display the avatar indicated by @avatar. + */ void empathy_avatar_chooser_set (EmpathyAvatarChooser *chooser, EmpathyAvatar *avatar) @@ -1053,6 +1046,15 @@ empathy_avatar_chooser_set (EmpathyAvatarChooser *chooser, } } +/** + * empathy_avatar_chooser_get_image_data: + * @chooser: an #EmpathyAvatarChooser + * @data: avatar bytes + * @data_size: size of @data + * @mime_type: avatar mime-type + * + * Gets image data about the currently selected avatar. + */ void empathy_avatar_chooser_get_image_data (EmpathyAvatarChooser *chooser, const gchar **data, diff --git a/libempathy-gtk/empathy-avatar-chooser.h b/libempathy-gtk/empathy-avatar-chooser.h index bdc5b40ae..564c1f37d 100644 --- a/libempathy-gtk/empathy-avatar-chooser.h +++ b/libempathy-gtk/empathy-avatar-chooser.h @@ -41,6 +41,8 @@ typedef struct _EmpathyAvatarChooserClass EmpathyAvatarChooserClass; struct _EmpathyAvatarChooser { GtkButton parent; + + /*<private>*/ gpointer priv; }; diff --git a/libempathy-gtk/empathy-avatar-image.c b/libempathy-gtk/empathy-avatar-image.c index 51f30bdd5..e5513231b 100644 --- a/libempathy-gtk/empathy-avatar-image.c +++ b/libempathy-gtk/empathy-avatar-image.c @@ -33,6 +33,22 @@ #include "empathy-avatar-image.h" #include "empathy-ui-utils.h" +/** + * SECTION:empathy-avatar-image + * @title: EmpathyAvatarImage + * @short_description: A widget to display an avatar + * @include: libempathy-gtk/empathy-avatar-image.h + * + * #EmpathyAvatarImage is a widget which displays an avatar. + */ + +/** + * EmpathyAvatarImage: + * @parent: parent object + * + * Widget which displays an avatar. + */ + #define MAX_SMALL 64 #define MAX_LARGE 400 @@ -251,6 +267,13 @@ avatar_image_button_release_event (GtkWidget *widget, GdkEventButton *event) return TRUE; } +/** + * empathy_avatar_image_new: + * + * Creates a new #EmpathyAvatarImage. + * + * Return value: a new #EmpathyAvatarImage + */ GtkWidget * empathy_avatar_image_new (void) { @@ -261,6 +284,13 @@ empathy_avatar_image_new (void) return GTK_WIDGET (avatar_image); } +/** + * empathy_avatar_image_set: + * @avatar_image: an #EmpathyAvatarImage + * @avatar: the #EmpathyAvatar to set @avatar_image to + * + * Sets @avatar_image to display the avatar indicated by @avatar. + */ void empathy_avatar_image_set (EmpathyAvatarImage *avatar_image, EmpathyAvatar *avatar) diff --git a/libempathy-gtk/empathy-avatar-image.h b/libempathy-gtk/empathy-avatar-image.h index d6a6cd0b0..8969c1227 100644 --- a/libempathy-gtk/empathy-avatar-image.h +++ b/libempathy-gtk/empathy-avatar-image.h @@ -42,6 +42,8 @@ typedef struct _EmpathyAvatarImageClass EmpathyAvatarImageClass; struct _EmpathyAvatarImage { GtkEventBox parent; + + /*<private>*/ gpointer priv; }; diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 7d9390274..985eaa4cf 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -65,7 +65,6 @@ #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChat) typedef struct { EmpathyTpChat *tp_chat; - gulong tp_chat_destroy_handler; McAccount *account; gchar *id; gchar *name; @@ -190,17 +189,15 @@ chat_connect_channel_reconnected (EmpathyDispatchOperation *dispatch, } static void -chat_connection_changed_cb (EmpathyAccountManager *manager, - McAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyChat *chat) +chat_new_connection_cb (EmpathyAccountManager *manager, + TpConnection *connection, + EmpathyChat *chat) { EmpathyChatPriv *priv = GET_PRIV (chat); + McAccount *account; - if (current == TP_CONNECTION_STATUS_CONNECTED && !priv->tp_chat && - empathy_account_equal (account, priv->account) && + account = empathy_account_manager_get_account (manager, connection); + if (!priv->tp_chat && empathy_account_equal (account, priv->account) && priv->handle_type != TP_HANDLE_TYPE_NONE && !EMP_STR_EMPTY (priv->id)) { @@ -208,12 +205,14 @@ chat_connection_changed_cb (EmpathyAccountManager *manager, switch (priv->handle_type) { case TP_HANDLE_TYPE_CONTACT: - empathy_dispatcher_chat_with_contact_id (account, priv->id, + empathy_dispatcher_chat_with_contact_id ( + connection, priv->id, chat_connect_channel_reconnected, chat); break; case TP_HANDLE_TYPE_ROOM: - empathy_dispatcher_join_muc (account, priv->id, + empathy_dispatcher_join_muc (connection, + priv->id, chat_connect_channel_reconnected, chat); break; @@ -1139,10 +1138,6 @@ chat_members_changed_cb (EmpathyTpChat *tp_chat, if (priv->block_events_timeout_id == 0) { gchar *str; - empathy_contact_run_until_ready (contact, - EMPATHY_CONTACT_READY_NAME, - NULL); - if (is_member) { str = g_strdup_printf (_("%s has joined the room"), empathy_contact_get_name (contact)); @@ -1434,13 +1429,26 @@ chat_finalize (GObject *object) chat_composing_remove_timeout (chat); g_signal_handlers_disconnect_by_func (priv->account_manager, - chat_connection_changed_cb, object); + chat_new_connection_cb, object); g_object_unref (priv->account_manager); g_object_unref (priv->log_manager); if (priv->tp_chat) { - g_signal_handler_disconnect (priv->tp_chat, priv->tp_chat_destroy_handler); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_destroy_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_message_received_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_send_error_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_state_changed_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_property_changed_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_members_changed_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_remote_contact_changed_cb, chat); empathy_tp_chat_close (priv->tp_chat); g_object_unref (priv->tp_chat); } @@ -1578,8 +1586,8 @@ empathy_chat_init (EmpathyChat *chat) priv->account_manager = empathy_account_manager_dup_singleton (); g_signal_connect (priv->account_manager, - "account-connection-changed", - G_CALLBACK (chat_connection_changed_cb), + "new-connection", + G_CALLBACK (chat_new_connection_cb), chat); /* Block events for some time to avoid having "has come online" or @@ -1613,6 +1621,7 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, EmpathyTpChat *tp_chat) { EmpathyChatPriv *priv = GET_PRIV (chat); + TpConnection *connection; g_return_if_fail (EMPATHY_IS_CHAT (chat)); g_return_if_fail (EMPATHY_IS_TP_CHAT (tp_chat)); @@ -1627,8 +1636,14 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, } priv->tp_chat = g_object_ref (tp_chat); - priv->account = g_object_ref (empathy_tp_chat_get_account (tp_chat)); + connection = empathy_tp_chat_get_connection (priv->tp_chat); + priv->account = empathy_account_manager_get_account (priv->account_manager, + connection); + g_object_ref (priv->account); + g_signal_connect (tp_chat, "destroy", + G_CALLBACK (chat_destroy_cb), + chat); g_signal_connect (tp_chat, "message-received", G_CALLBACK (chat_message_received_cb), chat); @@ -1647,10 +1662,6 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect_swapped (tp_chat, "notify::remote-contact", G_CALLBACK (chat_remote_contact_changed_cb), chat); - priv->tp_chat_destroy_handler = - g_signal_connect (tp_chat, "destroy", - G_CALLBACK (chat_destroy_cb), - chat); chat_remote_contact_changed_cb (chat); @@ -1730,20 +1741,6 @@ empathy_chat_get_remote_contact (EmpathyChat *chat) return priv->remote_contact; } -guint -empathy_chat_get_members_count (EmpathyChat *chat) -{ - EmpathyChatPriv *priv = GET_PRIV (chat); - - g_return_val_if_fail (EMPATHY_IS_CHAT (chat), 0); - - if (priv->tp_chat) { - return empathy_tp_chat_get_members_count (priv->tp_chat); - } - - return 0; -} - GtkWidget * empathy_chat_get_contact_menu (EmpathyChat *chat) { diff --git a/libempathy-gtk/empathy-chat.h b/libempathy-gtk/empathy-chat.h index 6b7fcf26e..f61ce4154 100644 --- a/libempathy-gtk/empathy-chat.h +++ b/libempathy-gtk/empathy-chat.h @@ -71,7 +71,6 @@ const gchar * empathy_chat_get_id (EmpathyChat *chat); const gchar * empathy_chat_get_name (EmpathyChat *chat); const gchar * empathy_chat_get_subject (EmpathyChat *chat); EmpathyContact * empathy_chat_get_remote_contact (EmpathyChat *chat); -guint empathy_chat_get_members_count (EmpathyChat *chat); GtkWidget * empathy_chat_get_contact_menu (EmpathyChat *chat); void empathy_chat_clear (EmpathyChat *chat); void empathy_chat_scroll_down (EmpathyChat *chat); diff --git a/libempathy-gtk/empathy-contact-dialogs.c b/libempathy-gtk/empathy-contact-dialogs.c index 72b5b28b3..056ec2d85 100644 --- a/libempathy-gtk/empathy-contact-dialogs.c +++ b/libempathy-gtk/empathy-contact-dialogs.c @@ -30,6 +30,7 @@ #include <libmissioncontrol/mission-control.h> #include <libempathy/empathy-contact-manager.h> +#include <libempathy/empathy-account-manager.h> #include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-utils.h> @@ -39,9 +40,10 @@ static GList *subscription_dialogs = NULL; static GList *information_dialogs = NULL; +static GList *edit_dialogs = NULL; +static GtkWidget *personal_dialog = NULL; static GtkWidget *new_contact_dialog = NULL; - static gint contact_dialogs_find (GtkDialog *dialog, EmpathyContact *contact) @@ -114,6 +116,7 @@ empathy_subscription_dialog_show (EmpathyContact *contact, g_free (filename); g_object_unref (gui); + /* Contact info widget */ contact_widget = empathy_contact_widget_new (contact, EMPATHY_CONTACT_WIDGET_EDIT_ALIAS | EMPATHY_CONTACT_WIDGET_EDIT_GROUPS); @@ -123,7 +126,6 @@ empathy_subscription_dialog_show (EmpathyContact *contact, 0); gtk_widget_show (contact_widget); - g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget); subscription_dialogs = g_list_prepend (subscription_dialogs, dialog); @@ -143,25 +145,22 @@ empathy_subscription_dialog_show (EmpathyContact *contact, */ static void -contact_information_response_cb (GtkDialog *dialog, - gint response, - GtkWidget *contact_widget) +contact_dialogs_response_cb (GtkDialog *dialog, + gint response, + GList **dialogs) { - information_dialogs = g_list_remove (information_dialogs, dialog); + *dialogs = g_list_remove (*dialogs, dialog); gtk_widget_destroy (GTK_WIDGET (dialog)); } void empathy_contact_information_dialog_show (EmpathyContact *contact, - GtkWindow *parent, - gboolean edit, - gboolean is_user) + GtkWindow *parent) { - GtkWidget *dialog; - GtkWidget *button; - GtkWidget *contact_widget; - GList *l; - EmpathyContactWidgetFlags flags = 0; + GtkWidget *dialog; + GtkWidget *button; + GtkWidget *contact_widget; + GList *l; g_return_if_fail (EMPATHY_IS_CONTACT (contact)); @@ -177,15 +176,7 @@ empathy_contact_information_dialog_show (EmpathyContact *contact, dialog = gtk_dialog_new (); gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - if (is_user) { - gtk_window_set_title (GTK_WINDOW (dialog), _("Personal Information")); - } - else if (edit) { - gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information")); - } - else { - gtk_window_set_title (GTK_WINDOW (dialog), _("Contact Information")); - } + gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information")); /* Close button */ button = gtk_button_new_with_label (GTK_STOCK_CLOSE); @@ -198,34 +189,79 @@ empathy_contact_information_dialog_show (EmpathyContact *contact, gtk_widget_show (button); /* Contact info widget */ - if (edit) { - flags |= EMPATHY_CONTACT_WIDGET_EDIT_ALIAS; - } - if (is_user) { - flags |= EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT; - flags |= EMPATHY_CONTACT_WIDGET_EDIT_AVATAR; + contact_widget = empathy_contact_widget_new (contact, + EMPATHY_CONTACT_WIDGET_EDIT_NONE); + gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + contact_widget, + TRUE, TRUE, 0); + gtk_widget_show (contact_widget); + + g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget); + information_dialogs = g_list_prepend (information_dialogs, dialog); + + g_signal_connect (dialog, "response", + G_CALLBACK (contact_dialogs_response_cb), + &information_dialogs); + + if (parent) { + gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); } - if (!is_user && edit) { - flags |= EMPATHY_CONTACT_WIDGET_EDIT_GROUPS; + + gtk_widget_show (dialog); +} + +void +empathy_contact_edit_dialog_show (EmpathyContact *contact, + GtkWindow *parent) +{ + GtkWidget *dialog; + GtkWidget *button; + GtkWidget *contact_widget; + GList *l; + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + l = g_list_find_custom (edit_dialogs, + contact, + (GCompareFunc) contact_dialogs_find); + if (l) { + gtk_window_present (GTK_WINDOW (l->data)); + return; } - contact_widget = empathy_contact_widget_new (contact, flags); + + /* Create dialog */ + dialog = gtk_dialog_new (); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information")); + + /* Close button */ + button = gtk_button_new_with_label (GTK_STOCK_CLOSE); + gtk_button_set_use_stock (GTK_BUTTON (button), TRUE); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), + button, + GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_window_set_default (GTK_WINDOW (dialog), button); + gtk_widget_show (button); + + /* Contact info widget */ + contact_widget = empathy_contact_widget_new (contact, + EMPATHY_CONTACT_WIDGET_EDIT_ALIAS | + EMPATHY_CONTACT_WIDGET_EDIT_GROUPS); gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), contact_widget, TRUE, TRUE, 0); - if (flags & EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT) { - empathy_contact_widget_set_account_filter (contact_widget, - empathy_account_chooser_filter_is_connected, - NULL); - } gtk_widget_show (contact_widget); g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget); - information_dialogs = g_list_prepend (information_dialogs, dialog); + edit_dialogs = g_list_prepend (edit_dialogs, dialog); g_signal_connect (dialog, "response", - G_CALLBACK (contact_information_response_cb), - contact_widget); + G_CALLBACK (contact_dialogs_response_cb), + &edit_dialogs); if (parent) { gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); @@ -234,6 +270,58 @@ empathy_contact_information_dialog_show (EmpathyContact *contact, gtk_widget_show (dialog); } +void +empathy_contact_personal_dialog_show (GtkWindow *parent) +{ + GtkWidget *button; + GtkWidget *contact_widget; + + if (personal_dialog) { + gtk_window_present (GTK_WINDOW (personal_dialog)); + return; + } + + /* Create dialog */ + personal_dialog = gtk_dialog_new (); + gtk_dialog_set_has_separator (GTK_DIALOG (personal_dialog), FALSE); + gtk_window_set_resizable (GTK_WINDOW (personal_dialog), FALSE); + gtk_window_set_title (GTK_WINDOW (personal_dialog), _("Personal Information")); + + /* Close button */ + button = gtk_button_new_with_label (GTK_STOCK_CLOSE); + gtk_button_set_use_stock (GTK_BUTTON (button), TRUE); + gtk_dialog_add_action_widget (GTK_DIALOG (personal_dialog), + button, + GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_window_set_default (GTK_WINDOW (personal_dialog), button); + gtk_widget_show (button); + + /* Contact info widget */ + contact_widget = empathy_contact_widget_new (NULL, + EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT | + EMPATHY_CONTACT_WIDGET_EDIT_ALIAS | + EMPATHY_CONTACT_WIDGET_EDIT_AVATAR); + gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (personal_dialog)->vbox), + contact_widget, + TRUE, TRUE, 0); + empathy_contact_widget_set_account_filter (contact_widget, + empathy_account_chooser_filter_is_connected, NULL); + gtk_widget_show (contact_widget); + + g_signal_connect (personal_dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + g_object_add_weak_pointer (G_OBJECT (personal_dialog), + (gpointer) &personal_dialog); + + if (parent) { + gtk_window_set_transient_for (GTK_WINDOW (personal_dialog), parent); + } + + gtk_widget_show (personal_dialog); +} + /* * New contact dialog */ @@ -242,12 +330,23 @@ static gboolean can_add_contact_to_account (McAccount *account, gpointer user_data) { - EmpathyContactManager *mgr; + EmpathyAccountManager *account_manager; + EmpathyContactManager *contact_manager; + TpConnection *connection; gboolean result; - mgr = empathy_contact_manager_dup_singleton (); - result = empathy_contact_manager_can_add (mgr, account); - g_object_unref (mgr); + account_manager = empathy_account_manager_dup_singleton (); + connection = empathy_account_manager_get_connection (account_manager, + account); + if (!connection) { + g_object_unref (account_manager); + return FALSE; + } + + contact_manager = empathy_contact_manager_dup_singleton (); + result = empathy_contact_manager_can_add (contact_manager, connection); + g_object_unref (contact_manager); + g_object_unref (account_manager); return result; } diff --git a/libempathy-gtk/empathy-contact-dialogs.h b/libempathy-gtk/empathy-contact-dialogs.h index e375f959c..c714c6b96 100644 --- a/libempathy-gtk/empathy-contact-dialogs.h +++ b/libempathy-gtk/empathy-contact-dialogs.h @@ -29,12 +29,13 @@ G_BEGIN_DECLS void empathy_subscription_dialog_show (EmpathyContact *contact, - GtkWindow *parent); + GtkWindow *parent); void empathy_contact_information_dialog_show (EmpathyContact *contact, - GtkWindow *parent, - gboolean edit, - gboolean is_user); -void empathy_new_contact_dialog_show (GtkWindow *parent); + GtkWindow *parent); +void empathy_contact_edit_dialog_show (EmpathyContact *contact, + GtkWindow *parent); +void empathy_contact_personal_dialog_show (GtkWindow *parent); +void empathy_new_contact_dialog_show (GtkWindow *parent); G_END_DECLS diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c index 3fdc7b327..ca224f526 100644 --- a/libempathy-gtk/empathy-contact-list-view.c +++ b/libempathy-gtk/empathy-contact-list-view.c @@ -31,10 +31,12 @@ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> +#include <telepathy-glib/util.h> #include <libmissioncontrol/mc-account.h> +#include <libempathy/empathy-account-manager.h> #include <libempathy/empathy-call-factory.h> -#include <libempathy/empathy-contact-factory.h> +#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-contact-groups.h> #include <libempathy/empathy-dispatcher.h> @@ -122,8 +124,8 @@ contact_list_view_tooltip_destroy_cb (GtkWidget *widget, if (priv->tooltip_widget) { DEBUG ("Tooltip destroyed"); + g_object_unref (priv->tooltip_widget); priv->tooltip_widget = NULL; - g_object_unref (widget); } } @@ -188,8 +190,52 @@ OUT: return ret; } +typedef struct { + gchar *new_group; + gchar *old_group; + GdkDragAction action; +} DndGetContactData; + +static void +contact_list_view_dnd_get_contact_free (DndGetContactData *data) +{ + g_free (data->new_group); + g_free (data->old_group); + g_slice_free (DndGetContactData, data); +} + static void -contact_list_view_drag_data_received (GtkWidget *widget, +contact_list_view_drag_got_contact (EmpathyTpContactFactory *factory, + EmpathyContact *contact, + const GError *error, + gpointer user_data, + GObject *view) +{ + EmpathyContactListViewPriv *priv = GET_PRIV (view); + DndGetContactData *data = user_data; + EmpathyContactList *list; + + if (error != NULL) { + DEBUG ("Error: %s", error->message); + return; + } + + DEBUG ("contact %s (%d) dragged from '%s' to '%s'", + empathy_contact_get_id (contact), + empathy_contact_get_handle (contact), + data->old_group, data->new_group); + + list = empathy_contact_list_store_get_list_iface (priv->store); + if (data->new_group) { + empathy_contact_list_add_to_group (list, contact, data->new_group); + } + if (data->old_group && data->action == GDK_ACTION_MOVE) { + empathy_contact_list_remove_from_group (list, contact, data->old_group); + } +} + +static void +contact_list_view_drag_data_received (GtkWidget *view, GdkDragContext *context, gint x, gint y, @@ -198,88 +244,102 @@ contact_list_view_drag_data_received (GtkWidget *widget, guint time) { EmpathyContactListViewPriv *priv; - EmpathyContactList *list; - EmpathyContactFactory *factory; + EmpathyAccountManager *account_manager; + EmpathyTpContactFactory *factory = NULL; McAccount *account; GtkTreeModel *model; - GtkTreePath *path; GtkTreeViewDropPosition position; - EmpathyContact *contact = NULL; + GtkTreePath *path; const gchar *id; - gchar **strv; + gchar **strv = NULL; + const gchar *account_id; + const gchar *contact_id; gchar *new_group = NULL; gchar *old_group = NULL; + DndGetContactData *data; gboolean is_row; + gboolean success = TRUE; - priv = GET_PRIV (widget); - - id = (const gchar*) selection->data; - DEBUG ("Received %s%s drag & drop contact from roster with id:'%s'", - context->action == GDK_ACTION_MOVE ? "move" : "", - context->action == GDK_ACTION_COPY ? "copy" : "", - id); + priv = GET_PRIV (view); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (view)); - strv = g_strsplit (id, "/", 2); - factory = empathy_contact_factory_dup_singleton (); - account = mc_account_lookup (strv[0]); - if (account) { - contact = empathy_contact_factory_get_from_id (factory, - account, - strv[1]); - g_object_unref (account); - } - g_object_unref (factory); - g_strfreev (strv); + /* Get destination group information. */ + is_row = gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), + x, + y, + &path, + &position); - if (!contact) { - DEBUG ("No contact found associated with drag & drop"); - return; + if (is_row) { + new_group = empathy_contact_list_store_get_parent_group (model, + path, NULL); + gtk_tree_path_free (path); } - empathy_contact_run_until_ready (contact, - EMPATHY_CONTACT_READY_HANDLE, - NULL); - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); - /* Get source group information. */ if (priv->drag_row) { path = gtk_tree_row_reference_get_path (priv->drag_row); if (path) { - old_group = empathy_contact_list_store_get_parent_group (model, path, NULL); + old_group = empathy_contact_list_store_get_parent_group ( + model, path, NULL); gtk_tree_path_free (path); } } - /* Get destination group information. */ - is_row = gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget), - x, - y, - &path, - &position); - - if (is_row) { - new_group = empathy_contact_list_store_get_parent_group (model, path, NULL); - gtk_tree_path_free (path); + if (!tp_strdiff (old_group, new_group)) { + g_free (new_group); + g_free (old_group); + goto OUT; } - DEBUG ("contact %s (%d) dragged from '%s' to '%s'", - empathy_contact_get_id (contact), - empathy_contact_get_handle (contact), - old_group, new_group); + id = (const gchar*) selection->data; + DEBUG ("Received %s%s drag & drop contact from roster with id:'%s'", + context->action == GDK_ACTION_MOVE ? "move" : "", + context->action == GDK_ACTION_COPY ? "copy" : "", + id); - list = empathy_contact_list_store_get_list_iface (priv->store); - if (new_group) { - empathy_contact_list_add_to_group (list, contact, new_group); + strv = g_strsplit (id, "/", 2); + account_id = strv[0]; + contact_id = strv[1]; + account = mc_account_lookup (account_id); + if (account) { + TpConnection *connection; + + /* FIXME: We assume we have already an account manager */ + account_manager = empathy_account_manager_dup_singleton (); + connection = empathy_account_manager_get_connection (account_manager, + account); + if (connection) { + factory = empathy_tp_contact_factory_dup_singleton (connection); + } + g_object_unref (account_manager); } - if (old_group && context->action == GDK_ACTION_MOVE) { - empathy_contact_list_remove_from_group (list, contact, old_group); + + if (!factory) { + DEBUG ("Failed to get factory for account '%s'", account_id); + success = FALSE; + g_free (new_group); + g_free (old_group); + goto OUT; } - g_free (old_group); - g_free (new_group); + data = g_slice_new0 (DndGetContactData); + data->new_group = new_group; + data->old_group = old_group; + data->action = context->action; - gtk_drag_finish (context, TRUE, FALSE, GDK_CURRENT_TIME); + /* FIXME: We should probably wait for the cb before calling + * gtk_drag_finish */ + empathy_tp_contact_factory_get_from_id (factory, contact_id, + contact_list_view_drag_got_contact, + data, (GDestroyNotify) contact_list_view_dnd_get_contact_free, + G_OBJECT (view)); + + g_object_unref (factory); + +OUT: + g_strfreev (strv); + gtk_drag_finish (context, success, FALSE, GDK_CURRENT_TIME); } static gboolean @@ -414,7 +474,7 @@ contact_list_view_drag_data_get (GtkWidget *widget, gtk_tree_path_free (src_path); - contact = empathy_contact_list_view_get_selected (EMPATHY_CONTACT_LIST_VIEW (widget)); + contact = empathy_contact_list_view_dup_selected (EMPATHY_CONTACT_LIST_VIEW (widget)); if (!contact) { return; } @@ -1158,7 +1218,7 @@ empathy_contact_list_view_new (EmpathyContactListStore *store, } EmpathyContact * -empathy_contact_list_view_get_selected (EmpathyContactListView *view) +empathy_contact_list_view_dup_selected (EmpathyContactListView *view) { EmpathyContactListViewPriv *priv; GtkTreeSelection *selection; @@ -1324,7 +1384,7 @@ contact_list_view_remove_activate_cb (GtkMenuItem *menuitem, EmpathyContactListViewPriv *priv = GET_PRIV (view); EmpathyContact *contact; - contact = empathy_contact_list_view_get_selected (view); + contact = empathy_contact_list_view_dup_selected (view); if (contact) { gchar *text; @@ -1357,7 +1417,7 @@ empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view) g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL); - contact = empathy_contact_list_view_get_selected (view); + contact = empathy_contact_list_view_dup_selected (view); if (!contact) { return NULL; } diff --git a/libempathy-gtk/empathy-contact-list-view.h b/libempathy-gtk/empathy-contact-list-view.h index 82990d64f..bb6766c4a 100644 --- a/libempathy-gtk/empathy-contact-list-view.h +++ b/libempathy-gtk/empathy-contact-list-view.h @@ -70,7 +70,7 @@ GType empathy_contact_list_view_get_type (void) G EmpathyContactListView * empathy_contact_list_view_new (EmpathyContactListStore *store, EmpathyContactListFeatureFlags list_features, EmpathyContactFeatureFlags contact_features); -EmpathyContact * empathy_contact_list_view_get_selected (EmpathyContactListView *view); +EmpathyContact * empathy_contact_list_view_dup_selected (EmpathyContactListView *view); gchar * empathy_contact_list_view_get_selected_group (EmpathyContactListView *view); GtkWidget * empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view); GtkWidget * empathy_contact_list_view_get_group_menu (EmpathyContactListView *view); diff --git a/libempathy-gtk/empathy-contact-menu.c b/libempathy-gtk/empathy-contact-menu.c index f311b1290..a3cf1da26 100644 --- a/libempathy-gtk/empathy-contact-menu.c +++ b/libempathy-gtk/empathy-contact-menu.c @@ -158,7 +158,7 @@ empathy_contact_call_menu_item_new (EmpathyContact *contact) g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); - item = gtk_image_menu_item_new_with_mnemonic (_("_Call")); + item = gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Call")); image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); @@ -236,7 +236,7 @@ empathy_contact_file_transfer_menu_item_new (EmpathyContact *contact) static void contact_info_menu_item_activate_cb (EmpathyContact *contact) { - empathy_contact_information_dialog_show (contact, NULL, FALSE, FALSE); + empathy_contact_information_dialog_show (contact, NULL); } GtkWidget * @@ -263,7 +263,7 @@ empathy_contact_info_menu_item_new (EmpathyContact *contact) static void contact_edit_menu_item_activate_cb (EmpathyContact *contact) { - empathy_contact_information_dialog_show (contact, NULL, TRUE, FALSE); + empathy_contact_edit_dialog_show (contact, NULL); } GtkWidget * @@ -360,9 +360,7 @@ empathy_contact_invite_menu_item_new (EmpathyContact *contact) GtkWidget *room_item; EmpathyChatroomManager *mgr; GList *rooms, *l; - GtkWidget *submenu; - GtkMenuShell *submenu_shell; - gboolean have_rooms = FALSE; + GtkWidget *submenu = NULL; g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); @@ -375,27 +373,23 @@ empathy_contact_invite_menu_item_new (EmpathyContact *contact) rooms = empathy_chatroom_manager_get_chatrooms (mgr, empathy_contact_get_account (contact)); - /* create rooms sub menu */ - submenu = gtk_menu_new (); - submenu_shell = GTK_MENU_SHELL (submenu); - for (l = rooms; l != NULL; l = g_list_next (l)) { EmpathyChatroom *chatroom = l->data; if (empathy_chatroom_get_tp_chat (chatroom) != NULL) { - have_rooms = TRUE; + if (G_UNLIKELY (submenu == NULL)) + submenu = gtk_menu_new (); room_item = create_room_sub_menu (contact, chatroom); - gtk_menu_shell_append (submenu_shell, room_item); + gtk_menu_shell_append ((GtkMenuShell*)submenu, room_item); gtk_widget_show (room_item); } } - if (have_rooms) { + if (submenu) { gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); } else { gtk_widget_set_sensitive (item, FALSE); - gtk_widget_destroy (submenu); } gtk_widget_show (image); diff --git a/libempathy-gtk/empathy-contact-selector.c b/libempathy-gtk/empathy-contact-selector.c index 539629a23..f4a302c5b 100644 --- a/libempathy-gtk/empathy-contact-selector.c +++ b/libempathy-gtk/empathy-contact-selector.c @@ -31,6 +31,23 @@ #include "empathy-contact-selector.h" +/** + * SECTION:empathy-contact-selector + * @title:EmpathyContactSelector + * @short_description: A widget used to choose from a list of contacts. + * @include: libempathy-gtk/empathy-contact-selector.h + * + * #EmpathyContactSelector is a widget which extends #GtkComboBox to provide + * a chooser of available contacts. + */ + +/** + * EmpathyContactSelector: + * @parent: parent object + * + * Widget which extends #GtkComboBox to provide a chooser of available contacts. + */ + G_DEFINE_TYPE (EmpathyContactSelector, empathy_contact_selector, GTK_TYPE_COMBO_BOX) @@ -320,14 +337,27 @@ empathy_contact_selector_class_init (EmpathyContactSelectorClass *klass) object_class->get_property = contact_selector_get_property; g_type_class_add_private (klass, sizeof (EmpathyContactSelectorPriv)); + /** + * EmpathyContactSelector:contact-list: + * + * An #EmpathyContactList containing the contacts for the + * #EmpathyContactSelector. + */ g_object_class_install_property (object_class, PROP_CONTACT_LIST, g_param_spec_object ("contact-list", "contact list", "contact list", EMPATHY_TYPE_CONTACT_LIST, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); } -/* public methods */ - +/** + * empathy_contact_selector_new: + * @contact_list: an #EmpathyContactList containing the contacts to list in + * the contact selector + * + * Creates a new #EmpathyContactSelector. + * + * Return value: A new #EmpathyContactSelector + */ GtkWidget * empathy_contact_selector_new (EmpathyContactList *contact_list) { @@ -337,6 +367,16 @@ empathy_contact_selector_new (EmpathyContactList *contact_list) "contact-list", contact_list, NULL)); } +/** + * empathy_contact_selector_dup_selected: + * @selector: An #EmpathyContactSelector + * + * Returns a new reference to the contact which is currently selected in + * @selector, or %NULL if there is no contact selected. The returned contact + * should be unrefed with g_object_unref() when finished with. + * + * Return value: A new reference to the contact currently selected, or %NULL + */ EmpathyContact * empathy_contact_selector_dup_selected (EmpathyContactSelector *selector) { @@ -390,6 +430,19 @@ contact_selector_filter_visible_func (GtkTreeModel *model, return visible; } +/** + * empathy_contact_selector_set_visible: + * @selector: an #EmpathyContactSelector + * @func: an #EmpathyContactSelectorFilterFunc to filter the contacts + * @user_data: data to pass to @func or %NULL + * + * Sets a filter on the @selector so only contacts that return %TRUE + * when passed into @func are visible. + * + * A typical usage for this function would be to only show contacts that + * can send or receive files. In this case, one could use the + * empathy_contact_can_send_files() function + */ void empathy_contact_selector_set_visible (EmpathyContactSelector *selector, EmpathyContactSelectorFilterFunc func, @@ -407,3 +460,14 @@ empathy_contact_selector_set_visible (EmpathyContactSelector *selector, gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->model)); } + +/** + * EmpathyContactSelectorFilterFunc: + * @contact: an #EmpathyContact + * @user_data: user data or %NULL + * + * A function which decides whether the contact indicated by @contact + * is visible. + * + * Return value: whether @contact is visible + */ diff --git a/libempathy-gtk/empathy-contact-selector.h b/libempathy-gtk/empathy-contact-selector.h index f7af92f2c..205b9e411 100644 --- a/libempathy-gtk/empathy-contact-selector.h +++ b/libempathy-gtk/empathy-contact-selector.h @@ -49,6 +49,8 @@ typedef struct _EmpathyContactSelectorClass EmpathyContactSelectorClass; struct _EmpathyContactSelector { GtkComboBox parent; + + /*<private>*/ gpointer priv; }; diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c index 0b2fb82b8..c78aafeaa 100644 --- a/libempathy-gtk/empathy-contact-widget.c +++ b/libempathy-gtk/empathy-contact-widget.c @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * Copyright (C) 2007-2008 Collabora Ltd. + * Copyright (C) 2007-2009 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,7 +30,7 @@ #include <libmissioncontrol/mc-account.h> #include <telepathy-glib/util.h> -#include <libempathy/empathy-contact-factory.h> +#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-contact-manager.h> #include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-utils.h> @@ -44,16 +44,34 @@ #define DEBUG_FLAG EMPATHY_DEBUG_CONTACT #include <libempathy/empathy-debug.h> +/** + * SECTION:empathy-contact-widget + * @title:EmpathyContactWidget + * @short_description: A widget used to display and edit details about a contact + * @include: libempathy-empathy-contact-widget.h + * + * #EmpathyContactWidget is a widget which displays appropriate widgets + * with details about a contact, also allowing changing these details, + * if desired. + */ + +/** + * EmpathyContactWidget: + * @parent: parent object + * + * Widget which displays appropriate widgets with details about a contact, + * also allowing changing these details, if desired. + */ + /* Delay before updating the widget when the id entry changed (seconds) */ #define ID_CHANGED_TIMEOUT 1 typedef struct { - EmpathyContactFactory *factory; + EmpathyTpContactFactory *factory; EmpathyContactManager *manager; EmpathyContact *contact; EmpathyContactWidgetFlags flags; - GtkCellRenderer *renderer; guint widget_id_timeout; GtkWidget *vbox_contact_widget; @@ -107,8 +125,6 @@ static void contact_widget_contact_update (EmpathyContactWidget *information); static void contact_widget_change_contact (EmpathyContactWidget *information); static void contact_widget_avatar_changed_cb (EmpathyAvatarChooser *chooser, EmpathyContactWidget *information); -static void contact_widget_account_changed_cb (GtkComboBox *widget, - EmpathyContactWidget *information); static gboolean contact_widget_id_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, EmpathyContactWidget *information); static gboolean contact_widget_entry_alias_focus_event_cb ( @@ -154,6 +170,15 @@ enum COL_COUNT }; +/** + * empathy_contact_widget_new: + * @contact: an #EmpathyContact + * @flags: #EmpathyContactWidgetFlags for the new contact widget + * + * Creates a new #EmpathyContactWidget. + * + * Return value: a new #EmpathyContactWidget + */ GtkWidget * empathy_contact_widget_new (EmpathyContact *contact, EmpathyContactWidgetFlags flags) @@ -162,9 +187,10 @@ empathy_contact_widget_new (EmpathyContact *contact, GtkBuilder *gui; gchar *filename; + g_return_val_if_fail (contact == NULL || EMPATHY_IS_CONTACT (contact), NULL); + information = g_slice_new0 (EmpathyContactWidget); information->flags = flags; - information->factory = empathy_contact_factory_dup_singleton (); filename = empathy_file_lookup ("empathy-contact-widget.ui", "libempathy-gtk"); @@ -207,12 +233,21 @@ empathy_contact_widget_new (EmpathyContact *contact, contact_widget_details_setup (information); contact_widget_client_setup (information); - contact_widget_set_contact (information, contact); + if (contact != NULL) + contact_widget_set_contact (information, contact); return empathy_builder_unref_and_keep_widget (gui, information->vbox_contact_widget); } +/** + * empathy_contact_widget_get_contact: + * @widget: an #EmpathyContactWidget + * + * Get the #EmpathyContact related with the #EmpathyContactWidget @widget. + * + * Returns: the #EmpathyContact associated with @widget + */ EmpathyContact * empathy_contact_widget_get_contact (GtkWidget *widget) { @@ -227,6 +262,13 @@ empathy_contact_widget_get_contact (GtkWidget *widget) return information->contact; } +/** + * empathy_contact_widget_set_contact: + * @widget: an #EmpathyContactWidget + * @contact: a different #EmpathyContact + * + * Change the #EmpathyContact related with the #EmpathyContactWidget @widget. + */ void empathy_contact_widget_set_contact (GtkWidget *widget, EmpathyContact *contact) @@ -243,6 +285,15 @@ empathy_contact_widget_set_contact (GtkWidget *widget, contact_widget_set_contact (information, contact); } +/** + * empathy_contact_widget_set_account_filter: + * @widget: an #EmpathyContactWidget + * @filter: a #EmpathyAccountChooserFilterFunc + * @user_data: user data to pass to @filter, or %NULL + * + * Set a filter on the #EmpathyAccountChooser included in the + * #EmpathyContactWidget. + */ void empathy_contact_widget_set_account_filter ( GtkWidget *widget, @@ -273,10 +324,6 @@ contact_widget_destroy_cb (GtkWidget *widget, { g_source_remove (information->widget_id_timeout); } - if (information->factory) - { - g_object_unref (information->factory); - } if (information->manager) { g_object_unref (information->manager); @@ -300,7 +347,9 @@ contact_widget_remove_contact (EmpathyContactWidget *information) contact_widget_groups_notify_cb, information); g_object_unref (information->contact); + g_object_unref (information->factory); information->contact = NULL; + information->factory = NULL; } } @@ -313,7 +362,13 @@ contact_widget_set_contact (EmpathyContactWidget *information, contact_widget_remove_contact (information); if (contact) + { + TpConnection *connection; + + connection = empathy_contact_get_connection (contact); information->contact = g_object_ref (contact); + information->factory = empathy_tp_contact_factory_dup_singleton (connection); + } /* Update information for widgets */ contact_widget_contact_update (information); @@ -492,10 +547,10 @@ static void update_avatar_chooser_account_cb (EmpathyAccountChooser *account_chooser, EmpathyAvatarChooser *avatar_chooser) { - McAccount *account; + TpConnection *connection; - account = empathy_account_chooser_get_account (account_chooser); - g_object_set (avatar_chooser, "account", account, NULL); + connection = empathy_account_chooser_get_connection (account_chooser); + g_object_set (avatar_chooser, "connection", connection, NULL); } static void @@ -506,8 +561,9 @@ contact_widget_contact_setup (EmpathyContactWidget *information) { information->widget_account = empathy_account_chooser_new (); - g_signal_connect (information->widget_account, "changed", - G_CALLBACK (contact_widget_account_changed_cb), + contact_widget_change_contact (information); + g_signal_connect_swapped (information->widget_account, "changed", + G_CALLBACK (contact_widget_change_contact), information); } else @@ -637,12 +693,12 @@ contact_widget_contact_update (EmpathyContactWidget *information) if (account) { g_signal_handlers_block_by_func (information->widget_account, - contact_widget_account_changed_cb, + contact_widget_change_contact, information); empathy_account_chooser_set_account ( EMPATHY_ACCOUNT_CHOOSER (information->widget_account), account); g_signal_handlers_unblock_by_func (information->widget_account, - contact_widget_account_changed_cb, information); + contact_widget_change_contact, information); } } else @@ -684,83 +740,71 @@ contact_widget_contact_update (EmpathyContactWidget *information) } static void -contact_widget_change_contact_cb (EmpathyContact *contact, - const GError *error, - gpointer information, - GObject *weak_object) +contact_widget_got_contact_cb (EmpathyTpContactFactory *factory, + EmpathyContact *contact, + const GError *error, + gpointer user_data, + GObject *weak_object) { - if (error) - DEBUG ("Error: %s", error->message); - else - contact_widget_set_contact (information, contact); - g_object_unref (contact); + EmpathyContactWidget *information = user_data; + + if (error != NULL) + { + DEBUG ("Error: %s", error->message); + return; + } + + contact_widget_set_contact (information, contact); } static void contact_widget_change_contact (EmpathyContactWidget *information) { - EmpathyContact *contact; - McAccount *account; + EmpathyTpContactFactory *factory; + TpConnection *connection; - account = empathy_account_chooser_get_account ( + connection = empathy_account_chooser_get_connection ( EMPATHY_ACCOUNT_CHOOSER (information->widget_account)); - if (!account) + if (!connection) return; + factory = empathy_tp_contact_factory_dup_singleton (connection); if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ID) { const gchar *id; id = gtk_entry_get_text (GTK_ENTRY (information->widget_id)); - if (EMP_STR_EMPTY (id)) - return; - - contact = empathy_contact_factory_get_from_id (information->factory, - account, id); + if (!EMP_STR_EMPTY (id)) + { + empathy_tp_contact_factory_get_from_id (factory, id, + contact_widget_got_contact_cb, information, NULL, + G_OBJECT (information->vbox_contact_widget)); + } } else { - contact = empathy_contact_factory_get_user (information->factory, - account); - } - - if (contact) - { - /* Give the contact ref to the callback */ - empathy_contact_call_when_ready (contact, - EMPATHY_CONTACT_READY_HANDLE | - EMPATHY_CONTACT_READY_ID, - contact_widget_change_contact_cb, - information, NULL, + empathy_tp_contact_factory_get_from_handle (factory, + tp_connection_get_self_handle (connection), + contact_widget_got_contact_cb, information, NULL, G_OBJECT (information->vbox_contact_widget)); } + + g_object_unref (factory); } static void contact_widget_avatar_changed_cb (EmpathyAvatarChooser *chooser, EmpathyContactWidget *information) { - if (information->contact && empathy_contact_is_user (information->contact)) - { - McAccount *account; - const gchar *data; - gsize size; - const gchar *mime_type; - - account = empathy_contact_get_account (information->contact); - empathy_avatar_chooser_get_image_data ( - EMPATHY_AVATAR_CHOOSER (information->widget_avatar), - &data, &size, &mime_type); - empathy_contact_factory_set_avatar (information->factory, account, - data, size, mime_type); - } -} - -static void -contact_widget_account_changed_cb (GtkComboBox *widget, - EmpathyContactWidget *information) -{ - contact_widget_change_contact (information); + const gchar *data; + gsize size; + const gchar *mime_type; + + empathy_avatar_chooser_get_image_data ( + EMPATHY_AVATAR_CHOOSER (information->widget_avatar), + &data, &size, &mime_type); + empathy_tp_contact_factory_set_avatar (information->factory, + data, size, mime_type); } static gboolean @@ -782,7 +826,7 @@ contact_widget_entry_alias_focus_event_cb (GtkEditable *editable, const gchar *alias; alias = gtk_entry_get_text (GTK_ENTRY (editable)); - empathy_contact_factory_set_alias (information->factory, + empathy_tp_contact_factory_set_alias (information->factory, information->contact, alias); } @@ -924,11 +968,6 @@ contact_widget_model_populate_columns (EmpathyContactWidget *information) gtk_tree_view_column_set_sort_column_id (column, COL_NAME); gtk_tree_view_column_set_resizable (column,FALSE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); - - if (information->renderer) - g_object_unref (information->renderer); - - information->renderer = g_object_ref (renderer); } static void diff --git a/libempathy-gtk/empathy-contact-widget.h b/libempathy-gtk/empathy-contact-widget.h index 4ba75e17f..0da5580a3 100644 --- a/libempathy-gtk/empathy-contact-widget.h +++ b/libempathy-gtk/empathy-contact-widget.h @@ -29,6 +29,27 @@ G_BEGIN_DECLS +/** + * EmpathyContactWidgetFlags: + * @EMPATHY_CONTACT_WIDGET_EDIT_NONE: Don't show any widgets to edit any details + * of the contact. This should be the option for widgets that merely display + * information about a contact. + * @EMPATHY_CONTACT_WIDGET_EDIT_ALIAS: Show a #GtkEntry allowing changes to the + * contact's alias. + * @EMPATHY_CONTACT_WIDGET_EDIT_AVATAR: Show an #EmpathyAvatarChooser allowing + * changes to the contact's avatar. + * @EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT: Show an #EmpathyAccountChooser allowing + * changes to the contact's account. + * @EMPATHY_CONTACT_WIDGET_EDIT_ID: Show a #GtkEntry allowing changes to the + * contact's identifier. + * @EMPATHY_CONTACT_WIDGET_EDIT_GROUPS: Show a widget to change the groups the + * contact is in. + * @EMPATHY_CONTACT_WIDGET_FOR_TOOLTIP: Make widgets more designed for a tooltip. + * For example, make widgets not selectable. + * + * Flags used when creating an #EmpathyContactWidget to specify which features + * should be available. + */ typedef enum { EMPATHY_CONTACT_WIDGET_EDIT_NONE = 0, diff --git a/libempathy-gtk/empathy-irc-network-dialog.c b/libempathy-gtk/empathy-irc-network-dialog.c index 89ee5b284..8f7f47bda 100644 --- a/libempathy-gtk/empathy-irc-network-dialog.c +++ b/libempathy-gtk/empathy-irc-network-dialog.c @@ -572,6 +572,7 @@ empathy_irc_network_dialog_show (EmpathyIrcNetwork *network, gtk_window_set_modal (GTK_WINDOW (dialog->dialog), TRUE); irc_network_dialog_network_update_buttons (dialog); + gtk_widget_show_all (dialog->dialog); return dialog->dialog; } diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c index 2cec17783..13d9bcbd3 100644 --- a/libempathy-gtk/empathy-log-window.c +++ b/libempathy-gtk/empathy-log-window.c @@ -618,7 +618,7 @@ log_window_chats_populate (EmpathyLogWindow *window) GtkTreeIter iter; account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser_chats); - account = empathy_account_chooser_get_account (account_chooser); + account = empathy_account_chooser_dup_account (account_chooser); view = GTK_TREE_VIEW (window->treeview_chats); model = gtk_tree_view_get_model (view); diff --git a/libempathy-gtk/empathy-new-message-dialog.c b/libempathy-gtk/empathy-new-message-dialog.c index f6eb46a5f..3e6e3f11d 100644 --- a/libempathy-gtk/empathy-new-message-dialog.c +++ b/libempathy-gtk/empathy-new-message-dialog.c @@ -31,7 +31,7 @@ #include <libmissioncontrol/mission-control.h> #include <libempathy/empathy-call-factory.h> -#include <libempathy/empathy-contact-factory.h> +#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-contact-manager.h> #include <libempathy/empathy-dispatcher.h> #include <libempathy/empathy-utils.h> @@ -44,6 +44,16 @@ #include "empathy-new-message-dialog.h" #include "empathy-account-chooser.h" +/** + * SECTION:empathy-new-message-dialog + * @title: EmpathyNewMessageDialog + * @short_description: A dialog to show a new message + * @include: libempathy-gtk/empathy-new-message-dialog.h + * + * #EmpathyNewMessageDialog is a dialog which allows a text chat or + * call to be started with any contact on any enabled account. + */ + typedef struct { GtkWidget *dialog; GtkWidget *table_contact; @@ -65,48 +75,54 @@ new_message_dialog_account_changed_cb (GtkWidget *widget, EmpathyNewMessageDialog *dialog) { EmpathyAccountChooser *chooser; - McAccount *account; + TpConnection *connection; EmpathyTpContactList *contact_list; - GList *members, *l; + GList *members; GtkListStore *store; GtkEntryCompletion *completion; GtkTreeIter iter; gchar *tmpstr; - chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); - account = empathy_account_chooser_get_account (chooser); - contact_list = empathy_contact_manager_get_list (dialog->contact_manager, - account); - members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (contact_list)); + /* Remove completions */ completion = gtk_entry_get_completion (GTK_ENTRY (dialog->entry_id)); store = GTK_LIST_STORE (gtk_entry_completion_get_model (completion)); gtk_list_store_clear (store); - for (l = members; l; l = l->next) { - EmpathyContact *contact = l->data; + /* Get members of the new account */ + chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); + connection = empathy_account_chooser_get_connection (chooser); + if (!connection) { + return; + } + contact_list = empathy_contact_manager_get_list (dialog->contact_manager, + connection); + members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (contact_list)); + + /* Add members to the completion */ + while (members) { + EmpathyContact *contact = members->data; - if (!empathy_contact_is_online (contact)) { - continue; - } + if (empathy_contact_is_online (contact)) { + DEBUG ("Adding contact ID %s, Name %s", + empathy_contact_get_id (contact), + empathy_contact_get_name (contact)); - DEBUG ("Adding contact ID %s, Name %s", - empathy_contact_get_id (contact), - empathy_contact_get_name (contact)); + tmpstr = g_strdup_printf ("%s (%s)", + empathy_contact_get_name (contact), + empathy_contact_get_id (contact)); - tmpstr = g_strdup_printf ("%s (%s)", - empathy_contact_get_name (contact), - empathy_contact_get_id (contact)); + gtk_list_store_insert_with_values (store, &iter, -1, + COMPLETION_COL_TEXT, tmpstr, + COMPLETION_COL_ID, empathy_contact_get_id (contact), + COMPLETION_COL_NAME, empathy_contact_get_name (contact), + -1); - gtk_list_store_insert_with_values (store, &iter, -1, - COMPLETION_COL_TEXT, tmpstr, - COMPLETION_COL_ID, empathy_contact_get_id (contact), - COMPLETION_COL_NAME, empathy_contact_get_name (contact), - -1); + g_free (tmpstr); + } - g_free (tmpstr); + g_object_unref (contact); + members = g_list_delete_link (members, members); } - - g_object_unref (account); } static gboolean @@ -166,41 +182,51 @@ new_message_dialog_match_func (GtkEntryCompletion *completion, } static void +new_message_dialog_call_got_contact_cb (EmpathyTpContactFactory *factory, + EmpathyContact *contact, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + EmpathyCallFactory *call_factory; + + if (error != NULL) { + DEBUG ("Error: %s", error->message); + return; + } + + call_factory = empathy_call_factory_get(); + empathy_call_factory_new_call (call_factory, contact); +} + +static void new_message_dialog_response_cb (GtkWidget *widget, gint response, EmpathyNewMessageDialog *dialog) { - McAccount *account; + TpConnection *connection; const gchar *id; - account = empathy_account_chooser_get_account (EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser)); + connection = empathy_account_chooser_get_connection ( + EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser)); id = gtk_entry_get_text (GTK_ENTRY (dialog->entry_id)); - if (!account || EMP_STR_EMPTY (id)) { - if (account) { - g_object_unref (account); - } + if (!connection || EMP_STR_EMPTY (id)) { gtk_widget_destroy (widget); return; } if (response == 1) { - EmpathyContactFactory *factory; - EmpathyContact *contact; - EmpathyCallFactory *call_factory; - - factory = empathy_contact_factory_dup_singleton (); - contact = empathy_contact_factory_get_from_id (factory, account, id); + EmpathyTpContactFactory *factory; - call_factory = empathy_call_factory_get(); - empathy_call_factory_new_call (call_factory, contact); - - g_object_unref (contact); + factory = empathy_tp_contact_factory_dup_singleton (connection); + empathy_tp_contact_factory_get_from_id (factory, id, + new_message_dialog_call_got_contact_cb, + NULL, NULL, NULL); g_object_unref (factory); } else if (response == 2) { - empathy_dispatcher_chat_with_contact_id (account, id, NULL, NULL); + empathy_dispatcher_chat_with_contact_id (connection, id, NULL, NULL); } - g_object_unref (account); gtk_widget_destroy (widget); } @@ -226,6 +252,14 @@ new_message_dialog_destroy_cb (GtkWidget *widget, g_free (dialog); } +/** + * empathy_new_message_dialog_show: + * @parent: parent #GtkWindow of the dialog + * + * Create a new #EmpathyNewMessageDialog and show it. + * + * Return value: the new #EmpathyNewMessageDialog + */ GtkWidget * empathy_new_message_dialog_show (GtkWindow *parent) { diff --git a/libempathy-gtk/empathy-presence-chooser.c b/libempathy-gtk/empathy-presence-chooser.c index d97abea0c..f4a325b51 100644 --- a/libempathy-gtk/empathy-presence-chooser.c +++ b/libempathy-gtk/empathy-presence-chooser.c @@ -48,6 +48,23 @@ #include "empathy-presence-chooser.h" #include "empathy-status-preset-dialog.h" +/** + * SECTION:empathy-presence-chooser + * @title:EmpathyPresenceChooser + * @short_description: A widget used to change presence + * @include: libempathy-gtk/empathy-presence-chooser.h + * + * #EmpathyPresenceChooser is a widget which extends #GtkComboBoxEntry + * to change presence. + */ + +/** + * EmpathyAccountChooser: + * @parent: parent object + * + * Widget which extends #GtkComboBoxEntry to change presence. + */ + /* Flashing delay for icons (milliseconds). */ #define FLASH_TIMEOUT 500 @@ -782,6 +799,13 @@ presence_chooser_finalize (GObject *object) G_OBJECT_CLASS (empathy_presence_chooser_parent_class)->finalize (object); } +/** + * empathy_presence_chooser_new: + * + * Creates a new #EmpathyPresenceChooser widget. + * + * Return value: A new #EmpathyPresenceChooser widget + */ GtkWidget * empathy_presence_chooser_new (void) { @@ -939,6 +963,13 @@ presence_chooser_flash_stop (EmpathyPresenceChooser *chooser, empathy_icon_name_for_presence (state)); } +/** + * empathy_presence_chooser_create_menu: + * + * Creates a new #GtkMenu allowing users to change their presence from a menu. + * + * Return value: a new #GtkMenu for changing presence in a menu. + */ GtkWidget * empathy_presence_chooser_create_menu (void) { diff --git a/libempathy-gtk/empathy-presence-chooser.h b/libempathy-gtk/empathy-presence-chooser.h index 138e1dc7f..dab95f553 100644 --- a/libempathy-gtk/empathy-presence-chooser.h +++ b/libempathy-gtk/empathy-presence-chooser.h @@ -43,6 +43,8 @@ typedef struct _EmpathyPresenceChooserClass EmpathyPresenceChooserClass; struct _EmpathyPresenceChooser { GtkComboBoxEntry parent; + + /*<private>*/ gpointer priv; }; diff --git a/libempathy-gtk/empathy-profile-chooser.c b/libempathy-gtk/empathy-profile-chooser.c index fd68dd8b0..10eb3791a 100644 --- a/libempathy-gtk/empathy-profile-chooser.c +++ b/libempathy-gtk/empathy-profile-chooser.c @@ -30,6 +30,16 @@ #include "empathy-profile-chooser.h" #include "empathy-ui-utils.h" +/** + * SECTION:empathy-profile-chooser + * @title: EmpathyProfileChooser + * @short_description: A widget used to choose from a list of profiles + * @include: libempathy-gtk/empathy-account-chooser.h + * + * #EmpathyProfileChooser is a widget which provides a chooser of available + * profiles. + */ + enum { COL_ICON, COL_LABEL, @@ -37,8 +47,17 @@ enum { COL_COUNT }; +/** + * empathy_profile_chooser_dup_selected: + * @widget: an #EmpathyProfileChooser + * + * Returns a new reference to the selected #McProfile in @widget. The returned + * #McProfile should be unrefed with g_object_unref() when finished with. + * + * Return value: a new reference to the selected #McProfile + */ McProfile* -empathy_profile_chooser_get_selected (GtkWidget *widget) +empathy_profile_chooser_dup_selected (GtkWidget *widget) { GtkTreeModel *model; GtkTreeIter iter; @@ -54,6 +73,14 @@ empathy_profile_chooser_get_selected (GtkWidget *widget) return profile; } +/** + * empathy_profile_chooser_n_profiles: + * @widget: an #EmpathyProfileChooser + * + * Returns the number of profiles in @widget. + * + * Return value: the number of profiles in @widget + */ gint empathy_profile_chooser_n_profiles (GtkWidget *widget) { @@ -115,6 +142,13 @@ profile_chooser_sort_func (GtkTreeModel *model, return cmp; } +/** + * empathy_profile_chooser_new: + * + * Creates a new #EmpathyProfileChooser widget. + * + * Return value: a new #EmpathyProfileChooser widget + */ GtkWidget * empathy_profile_chooser_new (void) { diff --git a/libempathy-gtk/empathy-profile-chooser.h b/libempathy-gtk/empathy-profile-chooser.h index 8cdc33d67..74c761cc4 100644 --- a/libempathy-gtk/empathy-profile-chooser.h +++ b/libempathy-gtk/empathy-profile-chooser.h @@ -27,7 +27,7 @@ G_BEGIN_DECLS GtkWidget * empathy_profile_chooser_new (void); -McProfile * empathy_profile_chooser_get_selected (GtkWidget *widget); +McProfile * empathy_profile_chooser_dup_selected (GtkWidget *widget); gint empathy_profile_chooser_n_profiles (GtkWidget *widget); G_END_DECLS diff --git a/libempathy-gtk/empathy-theme-boxes.c b/libempathy-gtk/empathy-theme-boxes.c index 0561ecac0..5b435f1d5 100644 --- a/libempathy-gtk/empathy-theme-boxes.c +++ b/libempathy-gtk/empathy-theme-boxes.c @@ -208,9 +208,9 @@ theme_boxes_maybe_append_header (EmpathyThemeBoxes *theme, DEBUG ("Maybe add fancy header"); /* Only insert a header if the previously inserted block is not the same - * as this one. This catches all the different cases: + * as this one. */ - if (last_contact && empathy_contact_equal (last_contact, contact)) { + if (last_contact == contact) { return; } diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c index aa3492899..9a249e65b 100644 --- a/libempathy-gtk/empathy-ui-utils.c +++ b/libempathy-gtk/empathy-ui-utils.c @@ -102,7 +102,7 @@ builder_get_file_valist (const gchar *filename, gui = gtk_builder_new (); if (!gtk_builder_add_from_file (gui, filename, &error)) { - DEBUG ("Error: %s", error->message); + g_critical ("GtkBuilder Error: %s", error->message); g_clear_error (&error); g_object_unref (gui); return NULL; |