From 73a749cafbd78b45494aa5eba645ef2fe9c4e21a Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Fri, 20 Jul 2007 15:26:30 +0000 Subject: [PATCH] Initial room list support. It does not works yet. 2007-07-20 Xavier Claessens * libempathy/Makefile.am: * libempathy/empathy-tp-roomlist.h: * libempathy/empathy-tp-roomlist.c: * libempathy-gtk/empathy-chatrooms-window.c: * libempathy-gtk/empathy-new-chatroom-dialog.c: Initial room list support. It does not works yet. * libempathy-gtk/empathy-account-widget-generic.c: Add support for all types of integer and float. Fixes bug #457740 (Jamey Hicks). * libempathy/empathy-tp-chat.c: * libempathy-gtk/empathy-chat.c: If there is an error sending a message, show an error message to the user. * libempathy-gtk/empathy-accounts-dialog.c: Fix a leak, profile should be unrefed after mc_account_get_profile. * libempathy/empathy-utils.c: * libempathy/empathy-utils.h: * libempathy/empathy-tp-chatroom.c: * libempathy/empathy-tp-group.h: * libempathy/empathy-tp-group.c: * src/empathy.c: Rename empathy_get_channel_id() to empathy_inspect_channel(). We now have empathy_inspect_handle(). * po/POTFILES.in: * libempathy/empathy-tp-contact-list.c: Set all contacts from salut protocol to the "Local Network" group. * libempathy/empathy-idle.c: Fix NetworkManager support. * libempathy/empathy-chatroom.h: Fix indentation. * libempathy-gtk/empathy-status-icon.c: * libempathy-gtk/empathy-ui-utils.c: * libempathy-gtk/empathy-ui-utils.h: - Iconify main window to the status icon like in rhythmbox. Fixes bug #458106 (Jaap A. Haitsma). - Rounded avatars. Fixes bug #457992 (Raphael Slinckx) * Makefile.am: Fix distcheck for gtkdoc (Vincent Untz) * data/empathy.desktop.in.in: Change application description (Jaap A. Haitsma). svn path=/trunk/; revision=190 --- ChangeLog | 47 +++ Makefile.am | 3 +- data/empathy.desktop.in.in | 2 +- .../empathy-account-widget-generic.c | 38 +- libempathy-gtk/empathy-accounts-dialog.c | 1 + libempathy-gtk/empathy-chat.c | 147 +++++--- libempathy-gtk/empathy-chatrooms-window.c | 1 - libempathy-gtk/empathy-new-chatroom-dialog.c | 338 ++++++++--------- libempathy-gtk/empathy-status-icon.c | 5 +- libempathy-gtk/empathy-ui-utils.c | 184 ++++++--- libempathy-gtk/empathy-ui-utils.h | 3 +- libempathy/Makefile.am | 2 + libempathy/empathy-chatroom.h | 24 +- libempathy/empathy-idle.c | 33 +- libempathy/empathy-tp-chat.c | 46 ++- libempathy/empathy-tp-chatroom.c | 10 +- libempathy/empathy-tp-contact-list.c | 26 +- libempathy/empathy-tp-group.c | 53 +-- libempathy/empathy-tp-group.h | 5 +- libempathy/empathy-tp-roomlist.c | 352 ++++++++++++++++++ libempathy/empathy-tp-roomlist.h | 59 +++ libempathy/empathy-utils.c | 25 +- libempathy/empathy-utils.h | 7 +- po/POTFILES.in | 1 + src/empathy.c | 2 +- 25 files changed, 1031 insertions(+), 383 deletions(-) create mode 100644 libempathy/empathy-tp-roomlist.c create mode 100644 libempathy/empathy-tp-roomlist.h diff --git a/ChangeLog b/ChangeLog index d6ccd569..85281f17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +2007-07-20 Xavier Claessens + + * libempathy/Makefile.am: + * libempathy/empathy-tp-roomlist.h: + * libempathy/empathy-tp-roomlist.c: + * libempathy-gtk/empathy-chatrooms-window.c: + * libempathy-gtk/empathy-new-chatroom-dialog.c: Initial room list + support. It does not works yet. + + * libempathy-gtk/empathy-account-widget-generic.c: Add support for all + types of integer and float. Fixes bug #457740 (Jamey Hicks). + + * libempathy/empathy-tp-chat.c: + * libempathy-gtk/empathy-chat.c: If there is an error sending a message, + show an error message to the user. + + * libempathy-gtk/empathy-accounts-dialog.c: Fix a leak, profile should + be unrefed after mc_account_get_profile. + + * libempathy/empathy-utils.c: + * libempathy/empathy-utils.h: + * libempathy/empathy-tp-chatroom.c: + * libempathy/empathy-tp-group.h: + * libempathy/empathy-tp-group.c: + * src/empathy.c: Rename empathy_get_channel_id() to + empathy_inspect_channel(). We now have empathy_inspect_handle(). + + * po/POTFILES.in: + * libempathy/empathy-tp-contact-list.c: Set all contacts from salut + protocol to the "Local Network" group. + + * libempathy/empathy-idle.c: Fix NetworkManager support. + + * libempathy/empathy-chatroom.h: Fix indentation. + + * libempathy-gtk/empathy-status-icon.c: + * libempathy-gtk/empathy-ui-utils.c: + * libempathy-gtk/empathy-ui-utils.h: + - Iconify main window to the status icon like in rhythmbox. + Fixes bug #458106 (Jaap A. Haitsma). + - Rounded avatars. Fixes bug #457992 (Raphael Slinckx) + + * Makefile.am: Fix distcheck for gtkdoc (Vincent Untz) + + * data/empathy.desktop.in.in: Change application description + (Jaap A. Haitsma). + 2007-07-14 Xavier Claessens * libempathy-gtk/empathy-contact-list-store.c: Show avatars by default. diff --git a/Makefile.am b/Makefile.am index ebbbf346..9e4c06f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,8 @@ SUBDIRS = po data libempathy libempathy-gtk src doc DISTCHECK_CONFIGURE_FLAGS = \ - --disable-scrollkeeper + --disable-scrollkeeper \ + --enable-gtk-doc INTLTOOL = \ intltool-extract.in \ diff --git a/data/empathy.desktop.in.in b/data/empathy.desktop.in.in index abf48ce1..9ccc34a4 100644 --- a/data/empathy.desktop.in.in +++ b/data/empathy.desktop.in.in @@ -2,7 +2,7 @@ Version=1.0 Encoding=UTF-8 _Name=Empathy Instant Messenger -_Comment=Instant Messenger +_Comment=Send and receive instant messages Exec=empathy --no-connect Icon=empathy StartupNotify=false diff --git a/libempathy-gtk/empathy-account-widget-generic.c b/libempathy-gtk/empathy-account-widget-generic.c index 1ba38f7f..c97b6561 100644 --- a/libempathy-gtk/empathy-account-widget-generic.c +++ b/libempathy-gtk/empathy-account-widget-generic.c @@ -32,9 +32,12 @@ #include #include -#include +#include #include "empathy-account-widget-generic.h" +#include "empathy-ui-utils.h" + +#define DEBUG_DOMAIN "AccountWidgetGeneric" typedef struct { McAccount *account; @@ -178,10 +181,30 @@ account_widget_generic_setup_foreach (McProtocolParam *param, GTK_FILL | GTK_EXPAND, 0, 0, 0); } - else if (param->signature[0] == 'q' || - param->signature[0] == 'n') { - gchar *str = NULL; - gint value = 0; + /* int types: ynqiuxt. double type is 'd' */ + else if (param->signature[0] == 'y' || + param->signature[0] == 'n' || + param->signature[0] == 'q' || + param->signature[0] == 'i' || + param->signature[0] == 'u' || + param->signature[0] == 'x' || + param->signature[0] == 't' || + param->signature[0] == 'd') { + gchar *str = NULL; + gint value = 0; + gdouble minint = 0; + gdouble maxint = 0; + gdouble step = 1; + switch (param->signature[0]) { + case 'y': minint = G_MININT8; maxint = G_MAXINT8; break; + case 'n': minint = G_MININT16; maxint = G_MAXINT16; break; + case 'q': minint = 0; maxint = G_MAXUINT16; break; + case 'i': minint = G_MININT32; maxint = G_MAXINT32; break; + case 'u': minint = 0; maxint = G_MAXUINT32; break; + case 'x': minint = G_MININT64; maxint = G_MAXINT64; break; + case 't': minint = 0; maxint = G_MAXUINT64; break; + case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break; + } str = g_strdup_printf (_("%s:"), param_name_formatted); widget = gtk_label_new (str); @@ -195,7 +218,7 @@ account_widget_generic_setup_foreach (McProtocolParam *param, GTK_FILL, 0, 0, 0); - widget = gtk_spin_button_new_with_range (0, G_MAXINT, 1); + widget = gtk_spin_button_new_with_range (minint, maxint, step); mc_account_get_param_int (settings->account, param->name, &value); @@ -233,6 +256,9 @@ account_widget_generic_setup_foreach (McProtocolParam *param, GTK_FILL | GTK_EXPAND, 0, 0, 0); } else { + empathy_debug (DEBUG_DOMAIN, + "Unknown signature for param %s: %s\n", + param_name_formatted, param->signature); g_assert_not_reached (); } diff --git a/libempathy-gtk/empathy-accounts-dialog.c b/libempathy-gtk/empathy-accounts-dialog.c index 8f6a281e..cc88b73a 100644 --- a/libempathy-gtk/empathy-accounts-dialog.c +++ b/libempathy-gtk/empathy-accounts-dialog.c @@ -284,6 +284,7 @@ accounts_dialog_update_account (EmpathyAccountsDialog *dialog, profile = mc_account_get_profile (account); config_ui = mc_profile_get_configuration_ui (profile); + g_object_unref (profile); if (strcmp (config_ui, "jabber") == 0) { dialog->settings_widget = diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 8f6ca370..304e8d44 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -94,56 +94,60 @@ typedef struct { GtkTextIter end; } EmpathyChatSpell; -static void empathy_chat_class_init (EmpathyChatClass *klass); -static void empathy_chat_init (EmpathyChat *chat); -static void chat_finalize (GObject *object); -static void chat_destroy_cb (EmpathyTpChat *tp_chat, - EmpathyChat *chat); -static void chat_send (EmpathyChat *chat, - const gchar *msg); -static void chat_input_text_view_send (EmpathyChat *chat); -static void chat_message_received_cb (EmpathyTpChat *tp_chat, - EmpathyMessage *message, - EmpathyChat *chat); -void chat_sent_message_add (EmpathyChat *chat, - const gchar *str); -const gchar * chat_sent_message_get_next (EmpathyChat *chat); -const gchar * chat_sent_message_get_last (EmpathyChat *chat); -static gboolean chat_input_key_press_event_cb (GtkWidget *widget, - GdkEventKey *event, - EmpathyChat *chat); -static void chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer, - EmpathyChat *chat); -static gboolean chat_text_view_focus_in_event_cb (GtkWidget *widget, - GdkEvent *event, - EmpathyChat *chat); -static void chat_text_view_scroll_hide_cb (GtkWidget *widget, - EmpathyChat *chat); -static void chat_text_view_size_allocate_cb (GtkWidget *widget, - GtkAllocation *allocation, - EmpathyChat *chat); -static void chat_text_view_realize_cb (GtkWidget *widget, - EmpathyChat *chat); -static void chat_text_populate_popup_cb (GtkTextView *view, - GtkMenu *menu, - EmpathyChat *chat); -static void chat_text_check_word_spelling_cb (GtkMenuItem *menuitem, - EmpathyChatSpell *chat_spell); -static EmpathyChatSpell *chat_spell_new (EmpathyChat *chat, - const gchar *word, - GtkTextIter start, - GtkTextIter end); -static void chat_spell_free (EmpathyChatSpell *chat_spell); -static void chat_composing_start (EmpathyChat *chat); -static void chat_composing_stop (EmpathyChat *chat); -static void chat_composing_remove_timeout (EmpathyChat *chat); -static gboolean chat_composing_stop_timeout_cb (EmpathyChat *chat); -static void chat_state_changed_cb (EmpathyTpChat *tp_chat, - EmpathyContact *contact, - TelepathyChannelChatState state, - EmpathyChat *chat); -static void chat_add_logs (EmpathyChat *chat); -static gboolean chat_scroll_down_idle_func (EmpathyChat *chat); +static void empathy_chat_class_init (EmpathyChatClass *klass); +static void empathy_chat_init (EmpathyChat *chat); +static void chat_finalize (GObject *object); +static void chat_destroy_cb (EmpathyTpChat *tp_chat, + EmpathyChat *chat); +static void chat_send (EmpathyChat *chat, + const gchar *msg); +static void chat_input_text_view_send (EmpathyChat *chat); +static void chat_message_received_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + EmpathyChat *chat); +static void chat_send_error_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + TelepathyChannelTextSendError error_code, + EmpathyChat *chat); +void chat_sent_message_add (EmpathyChat *chat, + const gchar *str); +const gchar * chat_sent_message_get_next (EmpathyChat *chat); +const gchar * chat_sent_message_get_last (EmpathyChat *chat); +static gboolean chat_input_key_press_event_cb (GtkWidget *widget, + GdkEventKey *event, + EmpathyChat *chat); +static void chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer, + EmpathyChat *chat); +static gboolean chat_text_view_focus_in_event_cb (GtkWidget *widget, + GdkEvent *event, + EmpathyChat *chat); +static void chat_text_view_scroll_hide_cb (GtkWidget *widget, + EmpathyChat *chat); +static void chat_text_view_size_allocate_cb (GtkWidget *widget, + GtkAllocation *allocation, + EmpathyChat *chat); +static void chat_text_view_realize_cb (GtkWidget *widget, + EmpathyChat *chat); +static void chat_text_populate_popup_cb (GtkTextView *view, + GtkMenu *menu, + EmpathyChat *chat); +static void chat_text_check_word_spelling_cb (GtkMenuItem *menuitem, + EmpathyChatSpell *chat_spell); +static EmpathyChatSpell *chat_spell_new (EmpathyChat *chat, + const gchar *word, + GtkTextIter start, + GtkTextIter end); +static void chat_spell_free (EmpathyChatSpell *chat_spell); +static void chat_composing_start (EmpathyChat *chat); +static void chat_composing_stop (EmpathyChat *chat); +static void chat_composing_remove_timeout (EmpathyChat *chat); +static gboolean chat_composing_stop_timeout_cb (EmpathyChat *chat); +static void chat_state_changed_cb (EmpathyTpChat *tp_chat, + EmpathyContact *contact, + TelepathyChannelChatState state, + EmpathyChat *chat); +static void chat_add_logs (EmpathyChat *chat); +static gboolean chat_scroll_down_idle_func (EmpathyChat *chat); enum { COMPOSING, @@ -424,6 +428,43 @@ chat_message_received_cb (EmpathyTpChat *tp_chat, g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, FALSE); } +static void +chat_send_error_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + TelepathyChannelTextSendError error_code, + EmpathyChat *chat) +{ + const gchar *error; + gchar *str; + + switch (error_code) { + case TP_CHANNEL_TEXT_SEND_ERROR_OFFLINE: + error = _("offline"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_INVALID_CONTACT: + error = _("invalid contact"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_PERMISSION_DENIED: + error = _("permission denied"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_TOO_LONG: + error = _("too long message"); + break; + case TP_CHANNEL_TEXT_SEND_ERROR_NOT_IMPLEMENTED: + error = _("not implemented"); + break; + default: + error = _("unknown"); + break; + } + + str = g_strdup_printf (_("Error sending message '%s': %s"), + empathy_message_get_body (message), + error); + empathy_chat_view_append_event (chat->view, str); + g_free (str); +} + void chat_sent_message_add (EmpathyChat *chat, const gchar *str) @@ -1307,6 +1348,9 @@ empathy_chat_set_tp_chat (EmpathyChat *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_destroy_cb, chat); @@ -1326,6 +1370,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect (tp_chat, "message-received", G_CALLBACK (chat_message_received_cb), chat); + g_signal_connect (tp_chat, "send-error", + G_CALLBACK (chat_send_error_cb), + chat); g_signal_connect (tp_chat, "chat-state-changed", G_CALLBACK (chat_state_changed_cb), chat); diff --git a/libempathy-gtk/empathy-chatrooms-window.c b/libempathy-gtk/empathy-chatrooms-window.c index c049e366..390fff42 100644 --- a/libempathy-gtk/empathy-chatrooms-window.c +++ b/libempathy-gtk/empathy-chatrooms-window.c @@ -38,7 +38,6 @@ #include "empathy-account-chooser.h" #include "empathy-chatrooms-window.h" -//#include "empathy-edit-chatroom-dialog.h" #include "empathy-new-chatroom-dialog.h" #include "empathy-ui-utils.h" diff --git a/libempathy-gtk/empathy-new-chatroom-dialog.c b/libempathy-gtk/empathy-new-chatroom-dialog.c index 5df2a1f4..6194fb29 100644 --- a/libempathy-gtk/empathy-new-chatroom-dialog.c +++ b/libempathy-gtk/empathy-new-chatroom-dialog.c @@ -36,6 +36,8 @@ #include #include +#include +#include #include #include @@ -47,45 +49,33 @@ #define DEBUG_DOMAIN "NewChatroomDialog" typedef struct { - GtkWidget *window; - - GtkWidget *vbox_widgets; - GtkWidget *table_info; - - GtkWidget *label_account; - GtkWidget *account_chooser; - - GtkWidget *label_server; - GtkWidget *entry_server; - GtkWidget *togglebutton_refresh; - - GtkWidget *label_room; - GtkWidget *entry_room; - - GtkWidget *vbox_browse; - GtkWidget *image_status; - GtkWidget *label_status; - GtkWidget *hbox_status; - GtkWidget *throbber; - GtkWidget *treeview; - GtkTreeModel *model; - GtkTreeModel *filter; - - GtkWidget *button_join; - GtkWidget *button_close; + EmpathyTpRoomlist *room_list; + + GtkWidget *window; + GtkWidget *vbox_widgets; + GtkWidget *table_info; + GtkWidget *label_account; + GtkWidget *account_chooser; + GtkWidget *label_server; + GtkWidget *entry_server; + GtkWidget *togglebutton_refresh; + GtkWidget *label_room; + GtkWidget *entry_room; + GtkWidget *vbox_browse; + GtkWidget *image_status; + GtkWidget *label_status; + GtkWidget *hbox_status; + GtkWidget *throbber; + GtkWidget *treeview; + GtkTreeModel *model; + GtkWidget *button_join; + GtkWidget *button_close; } EmpathyNewChatroomDialog; -typedef struct { - guint handle; - gchar *channel_type; - gchar *name; - gchar *id; -} EmpathyRoomListItem; - enum { COL_IMAGE, COL_NAME, - COL_POINTER, + COL_ROOM, COL_COUNT }; @@ -97,25 +87,20 @@ static void new_chatroom_dialog_destroy_cb (GtkWidget static void new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog); static void new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog); static void new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, +static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_add (EmpathyNewChatroomDialog *dialog, - EmpathyRoomListItem *item); -static void new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog); -static GList * new_chatroom_dialog_model_get_selected (EmpathyNewChatroomDialog *dialog); -static gboolean new_chatroom_dialog_model_filter_func (GtkTreeModel *model, - GtkTreeIter *iter, +static void new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, +static void new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, + EmpathyChatroom *chatroom, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, +static void new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, + gboolean listing, EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model, +static void new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog); +static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, + GtkTreeViewColumn *column, EmpathyNewChatroomDialog *dialog); static void new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, EmpathyNewChatroomDialog *dialog); @@ -187,16 +172,8 @@ empathy_new_chatroom_dialog_show (GtkWindow *parent) g_object_unref (size_group); - /* Account chooser for custom */ - dialog->account_chooser = empathy_account_chooser_new (); - gtk_table_attach_defaults (GTK_TABLE (dialog->table_info), - dialog->account_chooser, - 1, 3, 0, 1); - gtk_widget_show (dialog->account_chooser); - - g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed", - G_CALLBACK (new_chatroom_dialog_account_changed_cb), - dialog); + /* Set up chatrooms treeview */ + new_chatroom_dialog_model_setup (dialog); /* Add throbber */ dialog->throbber = ephy_spinner_new (); @@ -206,11 +183,18 @@ empathy_new_chatroom_dialog_show (GtkWindow *parent) gtk_box_pack_start (GTK_BOX (dialog->hbox_status), dialog->throbber, FALSE, FALSE, 0); - /* Set up chatrooms treeview */ - new_chatroom_dialog_model_setup (dialog); + /* Account chooser for custom */ + dialog->account_chooser = empathy_account_chooser_new (); + gtk_table_attach_defaults (GTK_TABLE (dialog->table_info), + dialog->account_chooser, + 1, 3, 0, 1); + gtk_widget_show (dialog->account_chooser); - /* Set things up according to the account type */ - new_chatroom_dialog_update_widgets (dialog); + g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed", + G_CALLBACK (new_chatroom_dialog_account_changed_cb), + dialog); + new_chatroom_dialog_account_changed_cb (GTK_COMBO_BOX (dialog->account_chooser), + dialog); if (parent) { gtk_window_set_transient_for (GTK_WINDOW (dialog->window), @@ -236,8 +220,10 @@ static void new_chatroom_dialog_destroy_cb (GtkWidget *widget, EmpathyNewChatroomDialog *dialog) { + if (dialog->room_list) { + g_object_unref (dialog->room_list); + } g_object_unref (dialog->model); - g_object_unref (dialog->filter); g_free (dialog); } @@ -260,36 +246,19 @@ new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog) store = gtk_list_store_new (COL_COUNT, G_TYPE_STRING, /* Image */ G_TYPE_STRING, /* Text */ - G_TYPE_POINTER); /* infos */ + G_TYPE_STRING); /* Room */ dialog->model = GTK_TREE_MODEL (store); - - /* Filter */ - dialog->filter = gtk_tree_model_filter_new (dialog->model, NULL); - - gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (dialog->filter), - (GtkTreeModelFilterVisibleFunc) - new_chatroom_dialog_model_filter_func, - dialog, - NULL); - - gtk_tree_view_set_model (view, dialog->filter); - - g_signal_connect (dialog->filter, "row-inserted", - G_CALLBACK (new_chatroom_dialog_model_row_inserted_cb), - dialog); - g_signal_connect (dialog->filter, "row-deleted", - G_CALLBACK (new_chatroom_dialog_model_row_deleted_cb), - dialog); + gtk_tree_view_set_model (view, dialog->model); /* Selection */ selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COL_NAME, GTK_SORT_ASCENDING); g_signal_connect (selection, "changed", - G_CALLBACK (new_chatroom_dialog_model_selection_changed), dialog); + G_CALLBACK (new_chatroom_dialog_model_selection_changed), + dialog); /* Columns */ new_chatroom_dialog_model_add_columns (dialog); @@ -373,105 +342,105 @@ static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, EmpathyNewChatroomDialog *dialog) { + EmpathyAccountChooser *account_chooser; + McAccount *account; + gboolean listing = FALSE; + + if (dialog->room_list) { + g_object_unref (dialog->room_list); + } + + ephy_spinner_stop (EPHY_SPINNER (dialog->throbber)); + new_chatroom_dialog_model_clear (dialog); + + account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); + account = empathy_account_chooser_get_account (account_chooser); + dialog->room_list = empathy_tp_roomlist_new (account); + + if (dialog->room_list) { + g_signal_connect (dialog->room_list, "destroy", + G_CALLBACK (new_chatroom_dialog_roomlist_destroy_cb), + dialog); + g_signal_connect (dialog->room_list, "new-room", + G_CALLBACK (new_chatroom_dialog_new_room_cb), + dialog); + g_signal_connect (dialog->room_list, "listing", + G_CALLBACK (new_chatroom_dialog_listing_cb), + dialog); + + listing = empathy_tp_roomlist_is_listing (dialog->room_list); + if (listing) { + ephy_spinner_start (EPHY_SPINNER (dialog->throbber)); + } + } + new_chatroom_dialog_update_widgets (dialog); } static void -new_chatroom_dialog_model_add (EmpathyNewChatroomDialog *dialog, - EmpathyRoomListItem *item) +new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, + EmpathyNewChatroomDialog *dialog) +{ + g_object_unref (dialog->room_list); + dialog->room_list = NULL; +} + +static void +new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, + EmpathyChatroom *chatroom, + EmpathyNewChatroomDialog *dialog) { GtkTreeView *view; GtkTreeSelection *selection; GtkListStore *store; GtkTreeIter iter; + empathy_debug (DEBUG_DOMAIN, "New chatroom listed: %s (%s)", + empathy_chatroom_get_name (chatroom), + empathy_chatroom_get_room (chatroom)); + /* Add to model */ view = GTK_TREE_VIEW (dialog->treeview); selection = gtk_tree_view_get_selection (view); store = GTK_LIST_STORE (dialog->model); gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COL_NAME, item->name, - COL_POINTER, item, + COL_NAME, empathy_chatroom_get_name (chatroom), + COL_ROOM, empathy_chatroom_get_room (chatroom), -1); } static void -new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog) -{ - GtkListStore *store; - - store = GTK_LIST_STORE (dialog->model); - gtk_list_store_clear (store); -} - -static GList * -new_chatroom_dialog_model_get_selected (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, + gboolean listing, + EmpathyNewChatroomDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GList *rows, *l; - GList *chatrooms = NULL; - - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - - rows = gtk_tree_selection_get_selected_rows (selection, NULL); - for (l = rows; l; l = l->next) { - GtkTreeIter iter; - EmpathyRoomListItem *chatroom; - - if (!gtk_tree_model_get_iter (model, &iter, l->data)) { - continue; - } - - gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1); - chatrooms = g_list_append (chatrooms, chatroom); + /* Update the throbber */ + if (listing) { + ephy_spinner_start (EPHY_SPINNER (dialog->throbber)); + } else { + ephy_spinner_stop (EPHY_SPINNER (dialog->throbber)); } - g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); - g_list_free (rows); - - return chatrooms; + /* Update the refresh toggle button */ + g_signal_handlers_block_by_func (dialog->togglebutton_refresh, + new_chatroom_dialog_togglebutton_refresh_toggled_cb, + dialog); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->togglebutton_refresh), + listing); + g_signal_handlers_unblock_by_func (dialog->togglebutton_refresh, + new_chatroom_dialog_togglebutton_refresh_toggled_cb, + dialog); } -static gboolean -new_chatroom_dialog_model_filter_func (GtkTreeModel *model, - GtkTreeIter *iter, - EmpathyNewChatroomDialog *dialog) +static void +new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog) { - EmpathyRoomListItem *chatroom; - const gchar *text; - gchar *room_nocase; - gchar *text_nocase; - gboolean found = FALSE; - - gtk_tree_model_get (model, iter, COL_POINTER, &chatroom, -1); - - if (!chatroom) { - return TRUE; - } - - text = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - - /* Casefold */ - room_nocase = g_utf8_casefold (chatroom->id, -1); - text_nocase = g_utf8_casefold (text, -1); - - /* Compare */ - if (g_utf8_strlen (text_nocase, -1) < 1 || - strstr (room_nocase, text_nocase)) { - found = TRUE; - } - - g_free (room_nocase); - g_free (text_nocase); + GtkListStore *store; - return found; + store = GTK_LIST_STORE (dialog->model); + gtk_list_store_clear (store); } static void @@ -484,24 +453,30 @@ new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, } static void -new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - EmpathyNewChatroomDialog *dialog) -{ -} +new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, + EmpathyNewChatroomDialog *dialog) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gchar *room = NULL; + gchar *server = NULL; -static void -new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model, - GtkTreePath *path, - EmpathyNewChatroomDialog *dialog) -{ -} + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { + return; + } -static void -new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyNewChatroomDialog *dialog) -{ + gtk_tree_model_get (model, &iter, COL_ROOM, &room, -1); + server = strstr (room, "@"); + if (server) { + *server = '\0'; + server++; + } + + gtk_entry_set_text (GTK_ENTRY (dialog->entry_server), server ? server : ""); + gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), room ? room : ""); + + g_free (server); + g_free (room); } static void @@ -510,20 +485,10 @@ new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog) McAccount *account; EmpathyAccountChooser *account_chooser; MissionControl *mc; - GList *chatrooms, *l; const gchar *room; const gchar *server = NULL; gchar *room_name = NULL; - chatrooms = new_chatroom_dialog_model_get_selected (dialog); - if (chatrooms) { - for (l = chatrooms; l; l = l->next) { - /* Join it */ - } - g_list_free (chatrooms); - return; - } - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); server = gtk_entry_get_text (GTK_ENTRY (dialog->entry_server)); @@ -557,23 +522,26 @@ new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, const gchar *room; room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (dialog->filter)); gtk_widget_set_sensitive (dialog->button_join, !G_STR_EMPTY (room)); + /* FIXME: Select the room in the list */ } } static void new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *dialog) { - if (0) { - new_chatroom_dialog_model_clear (dialog); - new_chatroom_dialog_model_add (dialog, NULL); + new_chatroom_dialog_model_clear (dialog); + if (dialog->room_list) { + empathy_tp_roomlist_start (dialog->room_list); } } static void new_chatroom_dialog_browse_stop (EmpathyNewChatroomDialog *dialog) { + if (dialog->room_list) { + empathy_tp_roomlist_stop (dialog->room_list); + } } static void diff --git a/libempathy-gtk/empathy-status-icon.c b/libempathy-gtk/empathy-status-icon.c index 3e56f09e..6cd0f5f9 100644 --- a/libempathy-gtk/empathy-status-icon.c +++ b/libempathy-gtk/empathy-status-icon.c @@ -390,7 +390,7 @@ status_icon_toggle_visibility (EmpathyStatusIcon *icon) visible = empathy_window_get_is_visible (GTK_WINDOW (priv->window)); if (visible) { - gtk_widget_hide (GTK_WIDGET (priv->window)); + empathy_window_iconify (priv->window, priv->icon); empathy_conf_set_bool (empathy_conf_get (), EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, TRUE); } else { @@ -420,6 +420,9 @@ status_icon_activate_cb (GtkStatusIcon *status_icon, priv = GET_PRIV (icon); + empathy_debug (DEBUG_DOMAIN, "Activated: %s", + priv->events ? "event" : "toggle"); + if (priv->events) { status_icon_event_remove (icon, priv->events->data); } else { diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c index 1331f3fb..5a6ba873 100644 --- a/libempathy-gtk/empathy-ui-utils.c +++ b/libempathy-gtk/empathy-ui-utils.c @@ -29,7 +29,8 @@ */ #include - +#include +#include #include #include #include @@ -395,41 +396,6 @@ empathy_icon_name_for_contact (EmpathyContact *contact) return EMPATHY_IMAGE_OFFLINE; } -GdkPixbuf * -empathy_pixbuf_avatar_from_contact (EmpathyContact *contact) -{ - GdkPixbuf *pixbuf; - GdkPixbufLoader *loader; - EmpathyAvatar *avatar; - GError *error = NULL; - - g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); - - avatar = empathy_contact_get_avatar (contact); - if (!avatar) { - return NULL; - } - - loader = gdk_pixbuf_loader_new (); - - if (!gdk_pixbuf_loader_write (loader, avatar->data, avatar->len, &error)) { - g_warning ("Couldn't write avatar image:%p with " - "length:%" G_GSIZE_FORMAT " to pixbuf loader: %s", - avatar->data, avatar->len, error->message); - g_error_free (error); - return NULL; - } - - gdk_pixbuf_loader_close (loader, NULL); - - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - - g_object_ref (pixbuf); - g_object_unref (loader); - - return pixbuf; -} - static void pixbuf_from_avatar_size_prepared_cb (GdkPixbufLoader *loader, int width, @@ -471,6 +437,86 @@ pixbuf_from_avatar_size_prepared_cb (GdkPixbufLoader *loader, gdk_pixbuf_loader_set_size (loader, width, height); } +static void +empathy_avatar_pixbuf_roundify (GdkPixbuf *pixbuf) +{ + gint width, height, rowstride; + guchar *pixels; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + if (width < 6 || height < 6) { + return; + } + + /* Top left */ + pixels[3] = 0; + pixels[7] = 0x80; + pixels[11] = 0xC0; + pixels[rowstride + 3] = 0x80; + pixels[rowstride * 2 + 3] = 0xC0; + + /* Top right */ + pixels[width * 4 - 1] = 0; + pixels[width * 4 - 5] = 0x80; + pixels[width * 4 - 9] = 0xC0; + pixels[rowstride + (width * 4) - 1] = 0x80; + pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0; + + /* Bottom left */ + pixels[(height - 1) * rowstride + 3] = 0; + pixels[(height - 1) * rowstride + 7] = 0x80; + pixels[(height - 1) * rowstride + 11] = 0xC0; + pixels[(height - 2) * rowstride + 3] = 0x80; + pixels[(height - 3) * rowstride + 3] = 0xC0; + + /* Bottom right */ + pixels[height * rowstride - 1] = 0; + pixels[(height - 1) * rowstride - 1] = 0x80; + pixels[(height - 2) * rowstride - 1] = 0xC0; + pixels[height * rowstride - 5] = 0x80; + pixels[height * rowstride - 9] = 0xC0; +} + +static gboolean +empathy_gdk_pixbuf_is_opaque (GdkPixbuf *pixbuf) +{ + gint width, height, rowstride, i; + guchar *pixels; + guchar *row; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + row = pixels; + for (i = 3; i < rowstride; i+=4) { + if (row[i] < 0xfe) { + return FALSE; + } + } + + for (i = 1; i < height - 1; i++) { + row = pixels + (i*rowstride); + if (row[3] < 0xfe || row[rowstride-1] < 0xfe) { + return FALSE; + } + } + + row = pixels + ((height-1) * rowstride); + for (i = 3; i < rowstride; i+=4) { + if (row[i] < 0xfe) { + return FALSE; + } + } + + return TRUE; +} + GdkPixbuf * empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar, gint width, @@ -506,8 +552,26 @@ empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar, gdk_pixbuf_loader_close (loader, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (!gdk_pixbuf_get_has_alpha (pixbuf)) { + GdkPixbuf *rounded_pixbuf; + + rounded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + gdk_pixbuf_copy_area (pixbuf, 0, 0, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + rounded_pixbuf, + 0, 0); + pixbuf = rounded_pixbuf; + } else { + g_object_ref (pixbuf); + } + + if (empathy_gdk_pixbuf_is_opaque (pixbuf)) { + empathy_avatar_pixbuf_roundify (pixbuf); + } - g_object_ref (pixbuf); g_object_unref (loader); return pixbuf; @@ -526,6 +590,7 @@ empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact, return empathy_pixbuf_from_avatar_scaled (avatar, width, height); } + /* Stolen from GtkSourceView, hence the weird intendation. Please keep it like * that to make it easier to apply changes from the original code. */ @@ -1206,15 +1271,39 @@ window_get_is_on_current_workspace (GtkWindow *window) gboolean empathy_window_get_is_visible (GtkWindow *window) { - gboolean visible; + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); - g_return_val_if_fail (window != NULL, FALSE); + return GTK_WIDGET_VISIBLE (GTK_WIDGET (window)) && + window_get_is_on_current_workspace (window); +} - g_object_get (window, - "visible", &visible, - NULL); +void +empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon) +{ + GdkRectangle icon_location; + gulong data[4]; + Display *dpy; + GdkWindow *gdk_window; + + gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL); + gdk_window = GTK_WIDGET (window)->window; + dpy = gdk_x11_drawable_get_xdisplay (gdk_window); + + data[0] = icon_location.x; + data[1] = icon_location.y; + data[2] = icon_location.width; + data[3] = icon_location.height; + + XChangeProperty (dpy, + GDK_WINDOW_XID (gdk_window), + gdk_x11_get_xatom_by_name_for_display (gdk_drawable_get_display (gdk_window), + "_NET_WM_ICON_GEOMETRY"), + XA_CARDINAL, 32, PropModeReplace, + (guchar *)&data, 4); + + gtk_window_set_skip_taskbar_hint (window, TRUE); + gtk_window_iconify (window); - return visible && window_get_is_on_current_workspace (window); } /* Takes care of moving the window to the current workspace. */ @@ -1222,7 +1311,6 @@ void empathy_window_present (GtkWindow *window, gboolean steal_focus) { - gboolean visible; gboolean on_current; guint32 timestamp; @@ -1232,17 +1320,15 @@ empathy_window_present (GtkWindow *window, * workspace. */ - g_object_get (window, - "visible", &visible, - NULL); - on_current = window_get_is_on_current_workspace (window); - if (visible && !on_current) { + if ( GTK_WIDGET_VISIBLE (GTK_WIDGET (window)) && !on_current) { /* Hide it so present brings it to the current workspace. */ gtk_widget_hide (GTK_WIDGET (window)); } + gtk_window_set_skip_taskbar_hint (window, FALSE); + timestamp = gtk_get_current_event_time (); if (steal_focus && timestamp != GDK_CURRENT_TIME) { gtk_window_present_with_time (window, timestamp); diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h index 070f9e2b..a513a30b 100644 --- a/libempathy-gtk/empathy-ui-utils.h +++ b/libempathy-gtk/empathy-ui-utils.h @@ -78,7 +78,6 @@ const gchar * empathy_icon_name_for_contact (EmpathyContact GdkPixbuf * empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar, gint width, gint height); -GdkPixbuf * empathy_pixbuf_avatar_from_contact (EmpathyContact *contact); GdkPixbuf * empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact, gint width, gint height); @@ -98,6 +97,8 @@ gboolean empathy_text_iter_backward_search (const GtkTextIter *iter, gboolean empathy_window_get_is_visible (GtkWindow *window); void empathy_window_present (GtkWindow *window, gboolean steal_focus); +void empathy_window_iconify (GtkWindow *window, + GtkStatusIcon *status_icon); GtkWindow *empathy_get_toplevel_window (GtkWidget *widget); void empathy_url_show (const char *url); void empathy_toggle_button_set_state_quietly (GtkWidget *widget, diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index 3f73265c..9fbb7fe0 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -30,6 +30,7 @@ libempathy_la_SOURCES = \ empathy-tp-contact-list.c \ empathy-tp-chat.c \ empathy-tp-chatroom.c \ + empathy-tp-roomlist.c \ empathy-chandler.c \ empathy-filter.c \ empathy-idle.c \ @@ -57,6 +58,7 @@ libempathy_HEADERS = \ empathy-tp-contact-list.h \ empathy-tp-chat.h \ empathy-tp-chatroom.h \ + empathy-tp-roomlist.h \ empathy-chandler.h \ empathy-filter.h \ empathy-idle.h \ diff --git a/libempathy/empathy-chatroom.h b/libempathy/empathy-chatroom.h index 20f98ecc..39dff36d 100644 --- a/libempathy/empathy-chatroom.h +++ b/libempathy/empathy-chatroom.h @@ -50,27 +50,27 @@ struct _EmpathyChatroomClass { GObjectClass parent_class; }; -GType empathy_chatroom_get_type (void) G_GNUC_CONST; -EmpathyChatroom *empathy_chatroom_new (McAccount *account, - const gchar *room); +GType empathy_chatroom_get_type (void) G_GNUC_CONST; +EmpathyChatroom *empathy_chatroom_new (McAccount *account, + const gchar *room); EmpathyChatroom *empathy_chatroom_new_full (McAccount *account, - const gchar *room, - const gchar *name, - gboolean auto_connect); + const gchar *room, + const gchar *name, + gboolean auto_connect); McAccount * empathy_chatroom_get_account (EmpathyChatroom *chatroom); void empathy_chatroom_set_account (EmpathyChatroom *chatroom, - McAccount *account); + McAccount *account); const gchar * empathy_chatroom_get_room (EmpathyChatroom *chatroom); void empathy_chatroom_set_room (EmpathyChatroom *chatroom, - const gchar *room); + const gchar *room); const gchar * empathy_chatroom_get_name (EmpathyChatroom *chatroom); void empathy_chatroom_set_name (EmpathyChatroom *chatroom, - const gchar *name); + const gchar *name); gboolean empathy_chatroom_get_auto_connect (EmpathyChatroom *chatroom); void empathy_chatroom_set_auto_connect (EmpathyChatroom *chatroom, - gboolean auto_connect); -gboolean empathy_chatroom_equal (gconstpointer v1, - gconstpointer v2); + gboolean auto_connect); +gboolean empathy_chatroom_equal (gconstpointer v1, + gconstpointer v2); G_BEGIN_DECLS diff --git a/libempathy/empathy-idle.c b/libempathy/empathy-idle.c index 5b04d363..923b499b 100644 --- a/libempathy/empathy-idle.c +++ b/libempathy/empathy-idle.c @@ -42,7 +42,7 @@ #define EXT_AWAY_TIME (30*60) typedef enum { - NM_STATE_UNKNOWN = 0, + NM_STATE_UNKNOWN, NM_STATE_ASLEEP, NM_STATE_CONNECTING, NM_STATE_CONNECTED, @@ -180,16 +180,31 @@ empathy_idle_init (EmpathyIdle *idle) "org.freedesktop.NetworkManager"); } if (priv->nm_proxy) { + guint nm_status; + dbus_g_proxy_add_signal (priv->nm_proxy, "StateChange", G_TYPE_UINT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->nm_proxy, "StateChange", G_CALLBACK (idle_nm_state_change_cb), idle, NULL); + dbus_g_proxy_call (priv->nm_proxy, "state", + &error, + G_TYPE_INVALID, + G_TYPE_UINT, &nm_status, + G_TYPE_INVALID); + priv->nm_connected = (nm_status == NM_STATE_CONNECTED); + + empathy_debug (DEBUG_DOMAIN, "NetworkManager connected: %s", + priv->nm_connected ? "Yes" : "No"); + + if (!priv->nm_connected) { + priv->saved_state = priv->state; + priv->saved_status = g_strdup (priv->status); + } } else { empathy_debug (DEBUG_DOMAIN, "Failed to get nm proxy"); + priv->nm_connected = TRUE; } - /* FIXME: get value */ - priv->nm_connected = TRUE; } static void @@ -363,7 +378,13 @@ empathy_idle_set_presence (EmpathyIdle *idle, priv = GET_PRIV (idle); + empathy_debug (DEBUG_DOMAIN, "Changing presence to %s (%d)", + status, state); + if (!priv->nm_connected) { + empathy_debug (DEBUG_DOMAIN, + "NM not connected, saving requested presence"); + g_free (priv->saved_status); priv->saved_state = state; priv->saved_status = g_strdup (status); @@ -475,8 +496,7 @@ idle_nm_state_change_cb (DBusGProxy *proxy, empathy_debug (DEBUG_DOMAIN, "New network state (%d)", state); - if (state != NM_STATE_CONNECTED && - priv->state > MC_PRESENCE_OFFLINE) { + if (state != NM_STATE_CONNECTED && priv->nm_connected) { /* We are no more connected */ idle_ext_away_stop (idle); g_free (priv->saved_status); @@ -486,8 +506,7 @@ idle_nm_state_change_cb (DBusGProxy *proxy, empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE); priv->nm_connected = FALSE; } - else if (priv->state <= MC_PRESENCE_OFFLINE && - state == NM_STATE_CONNECTED) { + else if (state == NM_STATE_CONNECTED && !priv->nm_connected) { /* We are now connected */ priv->nm_connected = TRUE; empathy_idle_set_presence (idle, diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index e52b4a08..691d7a2f 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -88,6 +88,12 @@ static void tp_chat_sent_cb (DBusGProxy guint message_type, gchar *message_body, EmpathyTpChat *chat); +static void tp_chat_send_error_cb (DBusGProxy *text_iface, + guint error_code, + guint timestamp, + guint message_type, + gchar *message_body, + EmpathyTpChat *chat); static void tp_chat_state_changed_cb (DBusGProxy *chat_state_iface, guint handle, TelepathyChannelChatState state, @@ -127,6 +133,7 @@ enum { enum { MESSAGE_RECEIVED, + SEND_ERROR, CHAT_STATE_CHANGED, DESTROY, LAST_SIGNAL @@ -291,6 +298,16 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) G_TYPE_NONE, 1, EMPATHY_TYPE_MESSAGE); + signals[SEND_ERROR] = + g_signal_new ("send-error", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + empathy_marshal_VOID__OBJECT_UINT, + G_TYPE_NONE, + 2, EMPATHY_TYPE_MESSAGE, G_TYPE_UINT); + signals[CHAT_STATE_CHANGED] = g_signal_new ("chat-state-changed", G_TYPE_FROM_CLASS (klass), @@ -399,6 +416,9 @@ tp_chat_constructor (GType type, dbus_g_proxy_connect_signal (priv->text_iface, "Sent", G_CALLBACK (tp_chat_sent_cb), chat, NULL); + dbus_g_proxy_connect_signal (priv->text_iface, "SendError", + G_CALLBACK (tp_chat_send_error_cb), + chat, NULL); if (priv->chat_state_iface != NULL) { dbus_g_proxy_connect_signal (priv->chat_state_iface, @@ -733,7 +753,7 @@ empathy_tp_chat_get_id (EmpathyTpChat *chat) return priv->id; } - priv->id = empathy_get_channel_id (priv->account, priv->tp_chan); + priv->id = empathy_inspect_channel (priv->account, priv->tp_chan); return priv->id; } @@ -770,7 +790,6 @@ tp_chat_closed_cb (TpChan *text_chan, tp_chat_destroy_cb, chat); tp_chat_destroy_cb (text_chan, chat); - } static void @@ -831,6 +850,29 @@ tp_chat_sent_cb (DBusGProxy *text_iface, g_object_unref (message); } +static void +tp_chat_send_error_cb (DBusGProxy *text_iface, + guint error_code, + guint timestamp, + guint message_type, + gchar *message_body, + EmpathyTpChat *chat) +{ + EmpathyMessage *message; + + empathy_debug (DEBUG_DOMAIN, "Message sent error: %s (%d)", + message_body, error_code); + + message = tp_chat_build_message (chat, + message_type, + timestamp, + 0, + message_body); + + g_signal_emit (chat, signals[SEND_ERROR], 0, message, error_code); + g_object_unref (message); +} + static void tp_chat_state_changed_cb (DBusGProxy *chat_state_iface, guint handle, diff --git a/libempathy/empathy-tp-chatroom.c b/libempathy/empathy-tp-chatroom.c index fe8e7f8e..32716865 100644 --- a/libempathy/empathy-tp-chatroom.c +++ b/libempathy/empathy-tp-chatroom.c @@ -22,8 +22,6 @@ #include -#include - #include "empathy-tp-chatroom.h" #include "empathy-tp-contact-list.h" #include "empathy-contact-list.h" @@ -130,8 +128,6 @@ empathy_tp_chatroom_new (McAccount *account, { EmpathyTpChatroomPriv *priv; EmpathyTpChatroom *chatroom; - TpConn *tp_conn; - MissionControl *mc; GList *members, *l; guint self_handle; @@ -145,11 +141,9 @@ empathy_tp_chatroom_new (McAccount *account, priv = GET_PRIV (chatroom); - mc = empathy_mission_control_new (); - tp_conn = mission_control_get_connection (mc, account, NULL); priv->manager = empathy_contact_manager_new (); priv->list = empathy_contact_manager_get_list (priv->manager, account); - priv->group = empathy_tp_group_new (tp_chan, tp_conn); + priv->group = empathy_tp_group_new (account, tp_chan); g_signal_connect (priv->group, "members-added", G_CALLBACK (tp_chatroom_members_added_cb), @@ -181,8 +175,6 @@ empathy_tp_chatroom_new (McAccount *account, } empathy_tp_group_info_list_free (members); - g_object_unref (mc); - g_object_unref (tp_conn); return chatroom; } diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c index 4dedb4fe..8ecf564e 100644 --- a/libempathy/empathy-tp-contact-list.c +++ b/libempathy/empathy-tp-contact-list.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -51,6 +52,7 @@ struct _EmpathyTpContactListPriv { MissionControl *mc; EmpathyContact *user_contact; gboolean setup; + const gchar *protocol_group; EmpathyTpGroup *publish; EmpathyTpGroup *subscribe; @@ -322,6 +324,8 @@ empathy_tp_contact_list_new (McAccount *account) EmpathyTpContactListPriv *priv; EmpathyTpContactList *list; MissionControl *mc; + McProfile *profile; + const gchar *protocol_name; guint handle; GError *error = NULL; @@ -341,6 +345,16 @@ empathy_tp_contact_list_new (McAccount *account) priv->account = g_object_ref (account); priv->mc = mc; + /* Check for protocols that does not support contact groups. We can + * put all contacts into a special group in that case. + * FIXME: Default group should be an information in the profile */ + profile = mc_account_get_profile (account); + protocol_name = mc_profile_get_protocol_name (profile); + if (strcmp (protocol_name, "salut") == 0) { + priv->protocol_group = _("Local Network"); + } + g_object_unref (profile); + g_signal_connect (priv->tp_conn, "destroy", G_CALLBACK (tp_contact_list_destroy_cb), list); @@ -704,7 +718,7 @@ empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list, /* Create contact objects */ for (i = 0, id = handles_names; *id && i < new_handles->len; id++, i++) { EmpathyContact *contact; - guint handle; + guint handle; handle = g_array_index (new_handles, guint, i); contact = g_object_new (EMPATHY_TYPE_CONTACT, @@ -713,6 +727,10 @@ empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list, "handle", handle, NULL); + if (priv->protocol_group) { + empathy_contact_add_group (contact, priv->protocol_group); + } + if (!priv->presence_iface) { EmpathyPresence *presence; @@ -960,7 +978,7 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy, if (handle_type == TP_HANDLE_TYPE_LIST) { TpContactListType list_type; - group = empathy_tp_group_new (new_chan, priv->tp_conn); + group = empathy_tp_group_new (priv->account, new_chan); list_type = tp_contact_list_get_type (list, group); if (list_type == TP_CONTACT_LIST_TYPE_UNKNOWN) { @@ -1058,7 +1076,7 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy, return; } - group = empathy_tp_group_new (new_chan, priv->tp_conn); + group = empathy_tp_group_new (priv->account, new_chan); empathy_debug (DEBUG_DOMAIN, "New server-side group channel: %s", empathy_tp_group_get_name (group)); @@ -1472,7 +1490,7 @@ tp_contact_list_get_group (EmpathyTpContactList *list, list, NULL); - group = empathy_tp_group_new (group_channel, priv->tp_conn); + group = empathy_tp_group_new (priv->account, group_channel); g_hash_table_insert (priv->groups, group_object_path, group); g_signal_connect (group, "members-added", G_CALLBACK (tp_contact_list_group_members_added_cb), diff --git a/libempathy/empathy-tp-group.c b/libempathy/empathy-tp-group.c index 65e52f09..b86a00e2 100644 --- a/libempathy/empathy-tp-group.c +++ b/libempathy/empathy-tp-group.c @@ -28,6 +28,7 @@ #include "empathy-debug.h" #include "empathy-tp-group.h" +#include "empathy-utils.h" #include "empathy-marshal.h" #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ @@ -36,8 +37,8 @@ #define DEBUG_DOMAIN "TpGroup" struct _EmpathyTpGroupPriv { + McAccount *account; DBusGProxy *group_iface; - TpConn *tp_conn; TpChan *tp_chan; gchar *group_name; }; @@ -141,8 +142,8 @@ tp_group_finalize (GObject *object) g_object_unref (priv->group_iface); } - if (priv->tp_conn) { - g_object_unref (priv->tp_conn); + if (priv->account) { + g_object_unref (priv->account); } if (priv->tp_chan) { @@ -155,15 +156,15 @@ tp_group_finalize (GObject *object) } EmpathyTpGroup * -empathy_tp_group_new (TpChan *tp_chan, - TpConn *tp_conn) +empathy_tp_group_new (McAccount *account, + TpChan *tp_chan) { EmpathyTpGroup *group; EmpathyTpGroupPriv *priv; DBusGProxy *group_iface; g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); - g_return_val_if_fail (TELEPATHY_IS_CONN (tp_conn), NULL); + g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); group_iface = tp_chan_get_interface (tp_chan, TELEPATHY_CHAN_IFACE_GROUP_QUARK); @@ -172,7 +173,7 @@ empathy_tp_group_new (TpChan *tp_chan, group = g_object_new (EMPATHY_TYPE_TP_GROUP, NULL); priv = GET_PRIV (group); - priv->tp_conn = g_object_ref (tp_conn); + priv->account = g_object_ref (account); priv->tp_chan = g_object_ref (tp_chan); priv->group_iface = g_object_ref (group_iface); @@ -393,11 +394,9 @@ tp_group_destroy_cb (DBusGProxy *proxy, priv = GET_PRIV (group); g_object_unref (priv->group_iface); - g_object_unref (priv->tp_conn); g_object_unref (priv->tp_chan); priv->group_iface = NULL; priv->tp_chan = NULL; - priv->tp_conn = NULL; } static void @@ -437,12 +436,6 @@ tp_group_members_changed_cb (DBusGProxy *group_iface, const gchar * empathy_tp_group_get_name (EmpathyTpGroup *group) { - TelepathyHandleType handle_type; - guint channel_handle; - GArray *group_handles; - gchar **group_names; - GError *error = NULL; - EmpathyTpGroupPriv *priv; g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL); @@ -454,35 +447,7 @@ empathy_tp_group_get_name (EmpathyTpGroup *group) return priv->group_name; } - if (!tp_chan_get_handle (DBUS_G_PROXY (priv->tp_chan), - &handle_type, - &channel_handle, - &error)) { - empathy_debug (DEBUG_DOMAIN, - "Couldn't retreive channel handle for group: %s", - error ? error->message : "No error given"); - g_clear_error (&error); - return NULL; - } - - group_handles = g_array_new (FALSE, FALSE, sizeof (guint)); - g_array_append_val (group_handles, channel_handle); - if (!tp_conn_inspect_handles (DBUS_G_PROXY (priv->tp_conn), - handle_type, - group_handles, - &group_names, - &error)) { - empathy_debug (DEBUG_DOMAIN, - "Couldn't get group name: %s", - error ? error->message : "No error given"); - g_clear_error (&error); - g_array_free (group_handles, TRUE); - return NULL; - } - - priv->group_name = *group_names; - g_array_free (group_handles, TRUE); - g_free (group_names); + priv->group_name = empathy_inspect_channel (priv->account, priv->tp_chan); return priv->group_name; } diff --git a/libempathy/empathy-tp-group.h b/libempathy/empathy-tp-group.h index 2381ea10..5ea7bfc7 100644 --- a/libempathy/empathy-tp-group.h +++ b/libempathy/empathy-tp-group.h @@ -24,6 +24,7 @@ #include #include +#include G_BEGIN_DECLS @@ -54,8 +55,8 @@ typedef struct { } EmpathyTpGroupInfo; GType empathy_tp_group_get_type (void) G_GNUC_CONST; -EmpathyTpGroup * empathy_tp_group_new (TpChan *tp_chan, - TpConn *tp_conn); +EmpathyTpGroup * empathy_tp_group_new (McAccount *account, + TpChan *tp_chan); void empathy_tp_group_add_members (EmpathyTpGroup *group, GArray *handles, const gchar *message); diff --git a/libempathy/empathy-tp-roomlist.c b/libempathy/empathy-tp-roomlist.c new file mode 100644 index 00000000..a91d1ba0 --- /dev/null +++ b/libempathy/empathy-tp-roomlist.c @@ -0,0 +1,352 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2007 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Xavier Claessens + */ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include "empathy-tp-roomlist.h" +#include "empathy-chatroom.h" +#include "empathy-utils.h" +#include "empathy-debug.h" + +#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistPriv)) + +#define DEBUG_DOMAIN "TpRoomlist" + +struct _EmpathyTpRoomlistPriv { + McAccount *account; + TpChan *tp_chan; + DBusGProxy *roomlist_iface; +}; + +static void empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass); +static void empathy_tp_roomlist_init (EmpathyTpRoomlist *chat); +static void tp_roomlist_finalize (GObject *object); +static void tp_roomlist_destroy_cb (TpChan *tp_chan, + EmpathyTpRoomlist *list); +static void tp_roomlist_closed_cb (TpChan *tp_chan, + EmpathyTpRoomlist *list); +static void tp_roomlist_listing_cb (DBusGProxy *roomlist_iface, + gboolean listing, + EmpathyTpRoomlist *list); +static void tp_roomlist_got_rooms_cb (DBusGProxy *roomlist_iface, + GPtrArray *room_list, + EmpathyTpRoomlist *list); + +enum { + NEW_ROOM, + LISTING, + DESTROY, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +G_DEFINE_TYPE (EmpathyTpRoomlist, empathy_tp_roomlist, G_TYPE_OBJECT); + +static void +empathy_tp_roomlist_class_init (EmpathyTpRoomlistClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = tp_roomlist_finalize; + + signals[NEW_ROOM] = + g_signal_new ("new-room", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, EMPATHY_TYPE_CHATROOM); + + signals[LISTING] = + g_signal_new ("listing", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, + 1, G_TYPE_BOOLEAN); + + signals[DESTROY] = + g_signal_new ("destroy", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_type_class_add_private (object_class, sizeof (EmpathyTpRoomlistPriv)); +} + +static void +empathy_tp_roomlist_init (EmpathyTpRoomlist *list) +{ +} + +static void +tp_roomlist_finalize (GObject *object) +{ + EmpathyTpRoomlistPriv *priv; + GError *error = NULL; + + priv = GET_PRIV (object); + + if (priv->tp_chan) { + g_signal_handlers_disconnect_by_func (priv->tp_chan, + tp_roomlist_destroy_cb, + object); + + empathy_debug (DEBUG_DOMAIN, "Closing channel..."); + if (!tp_chan_close (DBUS_G_PROXY (priv->tp_chan), &error)) { + empathy_debug (DEBUG_DOMAIN, + "Error closing roomlist channel: %s", + error ? error->message : "No error given"); + g_clear_error (&error); + } + g_object_unref (priv->tp_chan); + } + + if (priv->account) { + g_object_unref (priv->account); + } + + G_OBJECT_CLASS (empathy_tp_roomlist_parent_class)->finalize (object); +} + +EmpathyTpRoomlist * +empathy_tp_roomlist_new (McAccount *account) +{ + EmpathyTpRoomlist *list; + EmpathyTpRoomlistPriv *priv; + TpConn *tp_conn; + MissionControl *mc; + const gchar *bus_name; + + g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); + + list = g_object_new (EMPATHY_TYPE_TP_ROOMLIST, NULL); + priv = GET_PRIV (list); + + mc = empathy_mission_control_new (); + tp_conn = mission_control_get_connection (mc, account, NULL); + g_object_unref (mc); + + bus_name = dbus_g_proxy_get_bus_name (DBUS_G_PROXY (tp_conn)); + priv->tp_chan = tp_conn_new_channel (tp_get_bus (), + tp_conn, + bus_name, + TP_IFACE_CHANNEL_TYPE_ROOM_LIST, + TP_HANDLE_TYPE_NONE, + 0, + TRUE); + g_object_unref (tp_conn); + + if (!priv->tp_chan) { + empathy_debug (DEBUG_DOMAIN, "Failed to get roomlist channel"); + g_object_unref (list); + return NULL; + } + + priv->account = g_object_ref (account); + priv->roomlist_iface = tp_chan_get_interface (priv->tp_chan, + TELEPATHY_CHAN_IFACE_ROOMLIST_QUARK); + + g_signal_connect (priv->tp_chan, "destroy", + G_CALLBACK (tp_roomlist_destroy_cb), + list); + dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->tp_chan), "Closed", + G_CALLBACK (tp_roomlist_closed_cb), + list, NULL); + dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->roomlist_iface), "ListingRooms", + G_CALLBACK (tp_roomlist_listing_cb), + list, NULL); + dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->roomlist_iface), "GotRooms", + G_CALLBACK (tp_roomlist_got_rooms_cb), + list, NULL); + + return list; +} + +gboolean +empathy_tp_roomlist_is_listing (EmpathyTpRoomlist *list) +{ + EmpathyTpRoomlistPriv *priv; + GError *error = NULL; + gboolean listing = FALSE; + + g_return_val_if_fail (EMPATHY_IS_TP_ROOMLIST (list), FALSE); + + priv = GET_PRIV (list); + + if (!tp_chan_type_room_list_get_listing_rooms (priv->roomlist_iface, + &listing, + &error)) { + empathy_debug (DEBUG_DOMAIN, + "Error GetListingRooms: %s", + error ? error->message : "No error given"); + g_clear_error (&error); + return FALSE; + } + + return listing; +} + +void +empathy_tp_roomlist_start (EmpathyTpRoomlist *list) +{ + EmpathyTpRoomlistPriv *priv; + GError *error = NULL; + + g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list)); + + priv = GET_PRIV (list); + + if (!tp_chan_type_room_list_list_rooms (priv->roomlist_iface, &error)) { + empathy_debug (DEBUG_DOMAIN, + "Error ListRooms: %s", + error ? error->message : "No error given"); + g_clear_error (&error); + } +} + +void +empathy_tp_roomlist_stop (EmpathyTpRoomlist *list) +{ + EmpathyTpRoomlistPriv *priv; + GError *error = NULL; + + g_return_if_fail (EMPATHY_IS_TP_ROOMLIST (list)); + + priv = GET_PRIV (list); + + if (!tp_chan_type_room_list_stop_listing (priv->roomlist_iface, &error)) { + empathy_debug (DEBUG_DOMAIN, + "Error StopListing: %s", + error ? error->message : "No error given"); + g_clear_error (&error); + } +} + +static void +tp_roomlist_destroy_cb (TpChan *tp_chan, + EmpathyTpRoomlist *list) +{ + EmpathyTpRoomlistPriv *priv; + + priv = GET_PRIV (list); + + empathy_debug (DEBUG_DOMAIN, "Channel Closed or CM crashed"); + + tp_roomlist_listing_cb (priv->roomlist_iface, FALSE, list); + + g_object_unref (priv->tp_chan); + priv->tp_chan = NULL; + priv->roomlist_iface = NULL; + + g_signal_emit (list, signals[DESTROY], 0); +} + +static void +tp_roomlist_closed_cb (TpChan *tp_chan, + EmpathyTpRoomlist *list) +{ + EmpathyTpRoomlistPriv *priv; + + priv = GET_PRIV (list); + + /* The channel is closed, do just like if the proxy was destroyed */ + g_signal_handlers_disconnect_by_func (priv->tp_chan, + tp_roomlist_destroy_cb, + list); + tp_roomlist_destroy_cb (priv->tp_chan, list); +} + +static void +tp_roomlist_listing_cb (DBusGProxy *roomlist_iface, + gboolean listing, + EmpathyTpRoomlist *list) +{ + empathy_debug (DEBUG_DOMAIN, "Listing: %s", listing ? "Yes" : "No"); + g_signal_emit (list, signals[LISTING], 0, listing); +} + +static void +tp_roomlist_got_rooms_cb (DBusGProxy *roomlist_iface, + GPtrArray *room_list, + EmpathyTpRoomlist *list) +{ + EmpathyTpRoomlistPriv *priv; + guint i; + + priv = GET_PRIV (list); + + g_print ("Got negsghgfdhgfdhgfdw room !!!"); + + for (i = 0; i < room_list->len; i++) { + EmpathyChatroom *chatroom; + gchar *room_id; + const gchar *room_name; + GValueArray *room_struct; + guint handle; + const gchar *channel_type; + GHashTable *info; + + /* Get information */ + room_struct = g_ptr_array_index (room_list, i); + handle = g_value_get_uint (g_value_array_get_nth (room_struct, 0)); + channel_type = g_value_get_string (g_value_array_get_nth (room_struct, 1)); + info = g_value_get_boxed (g_value_array_get_nth (room_struct, 0)); + + g_print ("Got new room !!!"); + + /* Create the chatroom */ + room_name = g_hash_table_lookup (info, "name"); + room_id = empathy_inspect_handle (priv->account, + handle, + TP_HANDLE_TYPE_ROOM); + chatroom = empathy_chatroom_new_full (priv->account, + room_id, + room_name, + FALSE); + + /* Tells the world */ + g_signal_emit (list, signals[NEW_ROOM], 0, chatroom); + + g_object_unref (chatroom); + } +} + diff --git a/libempathy/empathy-tp-roomlist.h b/libempathy/empathy-tp-roomlist.h new file mode 100644 index 00000000..4faa6d9c --- /dev/null +++ b/libempathy/empathy-tp-roomlist.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2007 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Xavier Claessens + */ + +#ifndef __EMPATHY_TP_ROOMLIST_H__ +#define __EMPATHY_TP_ROOMLIST_H__ + +#include + +#include + +G_BEGIN_DECLS + +#define EMPATHY_TYPE_TP_ROOMLIST (empathy_tp_roomlist_get_type ()) +#define EMPATHY_TP_ROOMLIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlist)) +#define EMPATHY_TP_ROOMLIST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistClass)) +#define EMPATHY_IS_TP_ROOMLIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_TP_ROOMLIST)) +#define EMPATHY_IS_TP_ROOMLIST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_TP_ROOMLIST)) +#define EMPATHY_TP_ROOMLIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_TP_ROOMLIST, EmpathyTpRoomlistClass)) + +typedef struct _EmpathyTpRoomlist EmpathyTpRoomlist; +typedef struct _EmpathyTpRoomlistClass EmpathyTpRoomlistClass; +typedef struct _EmpathyTpRoomlistPriv EmpathyTpRoomlistPriv; + +struct _EmpathyTpRoomlist { + GObject parent; +}; + +struct _EmpathyTpRoomlistClass { + GObjectClass parent_class; +}; + +GType empathy_tp_roomlist_get_type (void) G_GNUC_CONST; +EmpathyTpRoomlist *empathy_tp_roomlist_new (McAccount *account); +gboolean empathy_tp_roomlist_is_listing (EmpathyTpRoomlist *list); +void empathy_tp_roomlist_start (EmpathyTpRoomlist *list); +void empathy_tp_roomlist_stop (EmpathyTpRoomlist *list); + +G_END_DECLS + +#endif /* __EMPATHY_TP_ROOMLIST_H__ */ diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c index 74a6bc07..2bb17197 100644 --- a/libempathy/empathy-utils.c +++ b/libempathy/empathy-utils.c @@ -446,8 +446,21 @@ empathy_mission_control_new (void) } gchar * -empathy_get_channel_id (McAccount *account, - TpChan *tp_chan) +empathy_inspect_channel (McAccount *account, + TpChan *tp_chan) +{ + g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); + g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); + + return empathy_inspect_handle (account, + tp_chan->handle, + tp_chan->handle_type); +} + +gchar * +empathy_inspect_handle (McAccount *account, + guint handle, + guint handle_type) { MissionControl *mc; TpConn *tp_conn; @@ -457,7 +470,8 @@ empathy_get_channel_id (McAccount *account, GError *error; g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); - g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); + g_return_val_if_fail (handle != 0, NULL); + g_return_val_if_fail (handle_type != 0, NULL); mc = empathy_mission_control_new (); tp_conn = mission_control_get_connection (mc, account, NULL); @@ -469,9 +483,9 @@ empathy_get_channel_id (McAccount *account, /* Get the handle's name */ handles = g_array_new (FALSE, FALSE, sizeof (guint)); - g_array_append_val (handles, tp_chan->handle); + g_array_append_val (handles, handle); if (!tp_conn_inspect_handles (DBUS_G_PROXY (tp_conn), - tp_chan->handle_type, + handle_type, handles, &names, &error)) { @@ -493,3 +507,4 @@ empathy_get_channel_id (McAccount *account, return name; } + diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h index 17be9ed3..da56174b 100644 --- a/libempathy/empathy-utils.h +++ b/libempathy/empathy-utils.h @@ -92,8 +92,11 @@ guint empathy_account_hash (gconstpointer key); gboolean empathy_account_equal (gconstpointer a, gconstpointer b); MissionControl *empathy_mission_control_new (void); -gchar * empathy_get_channel_id (McAccount *account, - TpChan *tp_chan); +gchar * empathy_inspect_handle (McAccount *account, + guint handle, + guint handle_type); +gchar * empathy_inspect_channel (McAccount *account, + TpChan *tp_chan); G_END_DECLS diff --git a/po/POTFILES.in b/po/POTFILES.in index 419b4f8c..d838f6b1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -9,6 +9,7 @@ data/empathy.schemas.in libempathy/empathy-idle.c libempathy/empathy-contact.c libempathy/empathy-presence.c +libempathy/empathy-tp-contact-list.c libempathy-gtk/empathy-about-dialog.c libempathy-gtk/empathy-account-chooser.c diff --git a/src/empathy.c b/src/empathy.c index 9a764cef..c4ca5530 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -108,7 +108,7 @@ new_channel_cb (EmpathyChandler *chandler, gchar *id; account = mission_control_get_account_for_connection (mc, tp_conn, NULL); - id = empathy_get_channel_id (account, tp_chan); + id = empathy_inspect_channel (account, tp_chan); chat = empathy_chat_window_find_chat (account, id); g_free (id); -- 2.39.2