Initial room list support. It does not works yet.
authorXavier Claessens <xclaesse@gmail.com>
Fri, 20 Jul 2007 15:26:30 +0000 (15:26 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Fri, 20 Jul 2007 15:26:30 +0000 (15:26 +0000)
2007-07-20 Xavier Claessens  <xclaesse@gmail.com>

* 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

25 files changed:
ChangeLog
Makefile.am
data/empathy.desktop.in.in
libempathy-gtk/empathy-account-widget-generic.c
libempathy-gtk/empathy-accounts-dialog.c
libempathy-gtk/empathy-chat.c
libempathy-gtk/empathy-chatrooms-window.c
libempathy-gtk/empathy-new-chatroom-dialog.c
libempathy-gtk/empathy-status-icon.c
libempathy-gtk/empathy-ui-utils.c
libempathy-gtk/empathy-ui-utils.h
libempathy/Makefile.am
libempathy/empathy-chatroom.h
libempathy/empathy-idle.c
libempathy/empathy-tp-chat.c
libempathy/empathy-tp-chatroom.c
libempathy/empathy-tp-contact-list.c
libempathy/empathy-tp-group.c
libempathy/empathy-tp-group.h
libempathy/empathy-tp-roomlist.c [new file with mode: 0644]
libempathy/empathy-tp-roomlist.h [new file with mode: 0644]
libempathy/empathy-utils.c
libempathy/empathy-utils.h
po/POTFILES.in
src/empathy.c

index d6ccd5690f329f925adb5b448ae442bad7d1ec0a..85281f17770fa61a91609f98a531594932e49691 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2007-07-20 Xavier Claessens  <xclaesse@gmail.com>
+
+       * 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  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-list-store.c: Show avatars by default.
index ebbbf346d5fe22e434231b49f70f06da3a40d31c..9e4c06f3adbc98058a3af1e825890d83428bd739 100644 (file)
@@ -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     \
index abf48ce11476cdc46da30c2d2b424b72ce0ac046..9ccc34a436bd017444b5d2c68979a6611a0c9983 100644 (file)
@@ -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
index 1ba38f7fb4895e53aa981490cda33d853c5c73e9..c97b6561ead0b0d67916b15d400addb939237a38 100644 (file)
 #include <libmissioncontrol/mc-account.h>
 #include <libmissioncontrol/mc-protocol.h>
 
-#include <libempathy-gtk/empathy-ui-utils.h>
+#include <libempathy/empathy-debug.h>
 
 #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 ();
        }
 
index 8f6a281e89ff16127f2ee7d4bf382701db179f6d..cc88b73a7f9b7a184bc820b6d633917dae833237 100644 (file)
@@ -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 = 
index 8f6ca3705d189aa00659df23f6a3f5aa5bb8943d..304e8d447111f54c3ca1df6b77b388e1c52697eb 100644 (file)
@@ -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);
index c049e366f6e185b2fef2baa1dde1f954c10a423e..390fff42e675522dbc698c3c370fe872e2fef247 100644 (file)
@@ -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"
 
index 5df2a1f443842b5e5eeab1b44b80ed2002fca549..6194fb2946649b74d54489e330d0a3f66bfd5885 100644 (file)
@@ -36,6 +36,8 @@
 #include <libmissioncontrol/mc-account.h>
 #include <libmissioncontrol/mc-profile.h>
 
+#include <libempathy/empathy-tp-roomlist.h>
+#include <libempathy/empathy-chatroom.h>
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-debug.h>
 
 #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
index 3e56f09efe17916ee3dd653de2697878b7cd415c..6cd0f5f90cf0ca63589396ad3d1b27008dfca507 100644 (file)
@@ -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 {
index 1331f3fb9171c458b160ab4010d2ea4c311eb6cb..5a6ba8733fc4ba8a5e45f7099400b5c94fcd2873 100644 (file)
@@ -29,7 +29,8 @@
  */
 
 #include <string.h>
-
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
@@ -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);
index 070f9e2b2239d87bd2145ce57bf0bd9fd2ef5daa..a513a30bfa5ce3cca346f735d6bd3cc35e2f14f7 100644 (file)
@@ -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,
index 3f73265cf2377686a189a61fd5f804957f03693f..9fbb7fe0b13e62860815f58f9c52ce2c2b00a775 100644 (file)
@@ -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                          \
index 20f98ecc6b25bafb7f4f5bf013a41181054bb6a8..39dff36db7440aca486ab888307f751e6e97e73e 100644 (file)
@@ -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
index 5b04d363f913a279fa2c6de7812a8f6927ade108..923b499beefec1bd9c575cc77ea1767fa3ac1b5a 100644 (file)
@@ -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,
index e52b4a0869b801afdd7ae2c81096dce7cfc7f920..691d7a2f14c7dfab6447abd21661fd8616c25be5 100644 (file)
@@ -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,
index fe8e7f8e75b294ddbacd1416c4f14cda927a2737..32716865d046ea67d5cf5967332f2d9b07ee7e31 100644 (file)
@@ -22,8 +22,6 @@
 
 #include <config.h>
 
-#include <libmissioncontrol/mission-control.h>
-
 #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;
 }
index 4dedb4fef956b2635c89c0151d8d2f5f81db8bad..8ecf564e3daeb69af841e031ce5c4c91904d8bdb 100644 (file)
@@ -24,6 +24,7 @@
 #include <config.h>
 
 #include <string.h>
+#include <glib/gi18n.h>
 
 #include <libtelepathy/tp-helpers.h>
 #include <libtelepathy/tp-conn.h>
@@ -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),
index 65e52f091a4f6da0e226ff639e2c3ae7e52768ad..b86a00e28139a56cd989738a21f200acc249a3b1 100644 (file)
@@ -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;
 }
index 2381ea10e33e60bb62a9652410df5a0e576cb729..5ea7bfc710f092ba1daf2fa89eef0c93f995c621 100644 (file)
@@ -24,6 +24,7 @@
 #include <glib.h>
 
 #include <libtelepathy/tp-chan.h>
+#include <libmissioncontrol/mc-account.h>
 
 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 (file)
index 0000000..a91d1ba
--- /dev/null
@@ -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 <xclaesse@gmail.com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <libtelepathy/tp-chan-type-room-list-gen.h>
+#include <libtelepathy/tp-helpers.h>
+#include <libtelepathy/tp-conn.h>
+#include <libtelepathy/tp-chan.h>
+
+#include <libmissioncontrol/mission-control.h>
+
+#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 (file)
index 0000000..4faa6d9
--- /dev/null
@@ -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 <xclaesse@gmail.com>
+ */
+
+#ifndef __EMPATHY_TP_ROOMLIST_H__
+#define __EMPATHY_TP_ROOMLIST_H__
+
+#include <glib.h>
+
+#include <libmissioncontrol/mc-account.h>
+
+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__ */
index 74a6bc076a80aa7b0df538bfe174f801a7097941..2bb1719762f12f79a3b309d0c22d99c3a714ab0a 100644 (file)
@@ -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;
 }
 
+
index 17be9ed3ca2ec29ed0dbd03eea42dd7a525e3c38..da56174bd9ff5d41cce5b5fd519cee3be9b5d048 100644 (file)
@@ -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
 
index 419b4f8c7a179935b4fd7f127f4f4c77022ecedd..d838f6b1fffe9604410558a6a2ede17084a08dd2 100644 (file)
@@ -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
index 9a764cef33f0aaab5f5c93afc598e788afd1dd3a..c4ca55309f28e538f462914c591aac86d83c1380 100644 (file)
@@ -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);