]> git.0d.be Git - empathy.git/commitdiff
Completely reworked ContactList API. Fixes bug #471611, bug #467280, bug #459540...
authorXavier Claessens <xclaesse@src.gnome.org>
Thu, 30 Aug 2007 16:49:52 +0000 (16:49 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Thu, 30 Aug 2007 16:49:52 +0000 (16:49 +0000)
svn path=/trunk/; revision=280

49 files changed:
ChangeLog
configure.ac
doc/libempathy-gtk/tmpl/empathy-contact-list-store.sgml
doc/libempathy-gtk/tmpl/empathy-contact-list-view.sgml
doc/libempathy-gtk/tmpl/empathy-images.sgml
doc/libempathy-gtk/tmpl/empathy-preferences.sgml
doc/libempathy/libempathy.types
doc/libempathy/tmpl/empathy-avatar.sgml
doc/libempathy/tmpl/empathy-contact-list.sgml
doc/libempathy/tmpl/empathy-contact-manager.sgml
doc/libempathy/tmpl/empathy-contact.sgml
doc/libempathy/tmpl/empathy-tp-contact-list.sgml
doc/libempathy/tmpl/empathy-tp-group.sgml
libempathy-gtk/empathy-chat-window.c
libempathy-gtk/empathy-contact-dialogs.c
libempathy-gtk/empathy-contact-list-store.c
libempathy-gtk/empathy-contact-list-store.h
libempathy-gtk/empathy-contact-list-view.c
libempathy-gtk/empathy-contact-list-view.h
libempathy-gtk/empathy-contact-widget.c
libempathy-gtk/empathy-group-chat.c
libempathy-gtk/empathy-images.h
libempathy-gtk/empathy-main-window.c
libempathy-gtk/empathy-private-chat.c
libempathy-gtk/empathy-status-icon.c
libempathy-gtk/empathy-ui-utils.c
libempathy/Makefile.am
libempathy/empathy-avatar.c
libempathy/empathy-avatar.h
libempathy/empathy-contact-factory.c [new file with mode: 0644]
libempathy/empathy-contact-factory.h [new file with mode: 0644]
libempathy/empathy-contact-list.c
libempathy/empathy-contact-list.h
libempathy/empathy-contact-manager.c
libempathy/empathy-contact-manager.h
libempathy/empathy-contact.c
libempathy/empathy-contact.h
libempathy/empathy-log-manager.c
libempathy/empathy-marshal.list
libempathy/empathy-tp-chat.c
libempathy/empathy-tp-chatroom.c
libempathy/empathy-tp-contact-list.c
libempathy/empathy-tp-contact-list.h
libempathy/empathy-tp-group.c
libempathy/empathy-tp-group.h
python/README [new file with mode: 0644]
python/pyempathy/pyempathy.defs
python/pyempathy/pyempathy.override
python/pyempathygtk/pyempathygtk.defs

index fdb0c4d9a4f292a624fa392453c4c4bc0827f7aa..976db9ebabea051ba0ce0a357aa8c3150985ddfe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,23 +1,69 @@
-2007-08-24 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-30  Xavier Claessens  <xclaesse@gmail.com>
+
+       * python/pyempathy/pyempathy.defs:
+       * python/pyempathy/pyempathy.override:
+       * python/pyempathygtk/pyempathygtk.defs: Updated for new API.
+       * python/README: Explain how to update python binding.
+
+       * libempathy-gtk/empathy-images.h:
+       * libempathy-gtk/empathy-private-chat.c:
+       * libempathy-gtk/empathy-main-window.c:
+       * libempathy-gtk/empathy-status-icon.c:
+       * libempathy-gtk/empathy-group-chat.c:
+       * libempathy-gtk/empathy-ui-utils.c:
+       * libempathy-gtk/empathy-contact-dialogs.c:
+       * libempathy-gtk/empathy-contact-list-view.c:
+       * libempathy-gtk/empathy-contact-list-view.h:
+       * libempathy-gtk/empathy-contact-widget.c:
+       * libempathy-gtk/empathy-contact-list-store.c:
+       * libempathy-gtk/empathy-contact-list-store.h:
+       * libempathy-gtk/empathy-chat-window.c: Updated to use new libempathy
+       API.
+
+       * libempathy/empathy-log-manager.c:
+       * libempathy/empathy-contact.c:
+       * libempathy/empathy-contact.h:
+       * libempathy/empathy-tp-chat.c:
+       * libempathy/empathy-contact-manager.c:
+       * libempathy/empathy-contact-manager.h:
+       * libempathy/empathy-avatar.c:
+       * libempathy/empathy-avatar.h:
+       * libempathy/empathy-tp-contact-list.c:
+       * libempathy/empathy-tp-contact-list.h:
+       * libempathy/empathy-tp-chatroom.c:
+       * libempathy/empathy-contact-factory.c:
+       * libempathy/empathy-contact-factory.h:
+       * libempathy/empathy-contact-list.c:
+       * libempathy/empathy-contact-list.h:
+       * libempathy/empathy-tp-group.c:
+       * libempathy/empathy-marshal.list:
+       * libempathy/empathy-tp-group.h:
+       * libempathy/Makefile.am:
+       * configure.ac: Completely reworked ContactList API. Fixes bug #471611,
+       bug #467280, bug #459540 and bug #462907.
+
+       * doc/*: Updated.
+
+2007-08-24  Xavier Claessens  <xclaesse@gmail.com>
 
        * python/pyempathy/Makefile.am:
        * python/pyempathygtk/Makefile.am:
        * configure.ac: Make use of AM_PATH_PYTHON to get python variables.
        Fixes bug #470642 (Daniel Gryniewicz).
 
 
        * python/pyempathy/Makefile.am:
        * python/pyempathygtk/Makefile.am:
        * configure.ac: Make use of AM_PATH_PYTHON to get python variables.
        Fixes bug #470642 (Daniel Gryniewicz).
 
-2007-08-24 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-24  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump version to 0.13.
        * NEWS: Last NEWS entry is for version 0.12 and not 0.11.
 
 
        * configure.ac: Bump version to 0.13.
        * NEWS: Last NEWS entry is for version 0.12 and not 0.11.
 
-2007-08-24 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-24  Xavier Claessens  <xclaesse@gmail.com>
 
         * configure.ac:
         * doc/libempathy-gtk/tmpl/empathy-preferences.sgml:
         * NEWS:
         * po/POTFILES.in: Updated.
 
 
         * configure.ac:
         * doc/libempathy-gtk/tmpl/empathy-preferences.sgml:
         * NEWS:
         * po/POTFILES.in: Updated.
 
-2007-08-24 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-24  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        * libempathy-gtk/empathy-contact-widget.c:
 
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        * libempathy-gtk/empathy-contact-widget.c:
        * data/salut.profile: Salut's protocol name is going to change to
        local-xmpp. Fixes bug #469638 (Sjoerd Simons)
 
        * data/salut.profile: Salut's protocol name is going to change to
        local-xmpp. Fixes bug #469638 (Sjoerd Simons)
 
-2007-08-24 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-24  Xavier Claessens  <xclaesse@gmail.com>
 
        * src/empathy.c: Check if there is already a Salut account before
        creating a new one and add more debug messages.
 
 
        * src/empathy.c: Check if there is already a Salut account before
        creating a new one and add more debug messages.
 
-2007-08-24 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-24  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac:
        * data/22x22/Makefile.am:
 
        * configure.ac:
        * data/22x22/Makefile.am:
@@ -52,7 +98,7 @@
        * data/Makefile.am: Change jabber icon. Fixes bug #466377
        (Björn Martensen).
 
        * data/Makefile.am: Change jabber icon. Fixes bug #466377
        (Björn Martensen).
 
-2007-08-23 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-23  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-salut.glade:
        * libempathy-gtk/empathy-account-widget-salut.c:
 
        * libempathy-gtk/empathy-account-widget-salut.glade:
        * libempathy-gtk/empathy-account-widget-salut.c:
        salut CM installed using gnome-about-me information. Fixes bug #447467
        (Cosimo Cecchi, Xavier Claessens).
 
        salut CM installed using gnome-about-me information. Fixes bug #447467
        (Cosimo Cecchi, Xavier Claessens).
 
-2007-08-19 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-19  Xavier Claessens  <xclaesse@gmail.com>
 
        * python/pyempathy/Makefile.am:
        * python/pyempathy/pyempathy.override:
        * python/pyempathygtk/Makefile.am: Fix build system, make distcheck now
        works.
 
 
        * python/pyempathy/Makefile.am:
        * python/pyempathy/pyempathy.override:
        * python/pyempathygtk/Makefile.am: Fix build system, make distcheck now
        works.
 
-2007-08-19 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-19  Xavier Claessens  <xclaesse@gmail.com>
 
        * python/pyempathy/pyempathy.defs:
        * python/pyempathy/pyempathymodule.c:
 
        * python/pyempathy/pyempathy.defs:
        * python/pyempathy/pyempathymodule.c:
        * configure.ac:
        * Makefile.am: Add python binding. Fixes bug #457660 (Michael Sheldon).
 
        * configure.ac:
        * Makefile.am: Add python binding. Fixes bug #457660 (Michael Sheldon).
 
-2007-08-19 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-19  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-main-window.glade: Edit menu should be second
        from the left. Fixes bug #467827 (Cosimo Cecchi).
 
 
        * libempathy-gtk/empathy-main-window.glade: Edit menu should be second
        from the left. Fixes bug #467827 (Cosimo Cecchi).
 
-2007-08-13 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-13  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-group-chat.c: Only update the topic of it has
        really be changed, avoid diplaying many times "Topic set to:" message.
 
        * libempathy-gtk/empathy-group-chat.c: Only update the topic of it has
        really be changed, avoid diplaying many times "Topic set to:" message.
        if we already logged them last time we joined that room. Previous
        workaround prevented Empathy to log offline messages.
 
        if we already logged them last time we joined that room. Previous
        workaround prevented Empathy to log offline messages.
 
-2007-08-12 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-12  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump version to 0.12.
 
 
        * configure.ac: Bump version to 0.12.
 
-2007-08-12 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-12  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Update libtool version.
 
 
        * configure.ac: Update libtool version.
 
        * doc/libempathy-gtk/tmpl/empathy-status-presets.sgml:
        * NEWS: Updated.
 
        * doc/libempathy-gtk/tmpl/empathy-status-presets.sgml:
        * NEWS: Updated.
 
-2007-08-12 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-12  Xavier Claessens  <xclaesse@gmail.com>
 
        * data/irc.profile: Removed spaces in the SupportedPresences key to
        workaround a MC warning SF bug 1772539.
 
 
        * data/irc.profile: Removed spaces in the SupportedPresences key to
        workaround a MC warning SF bug 1772539.
 
-2007-08-11 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-11  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-accounts-dialog.c: Make "Add account" button
        insensitive when we are creating one. Fixes bug #459170
        (Jaap A. Haitsma).
 
 
        * libempathy-gtk/empathy-accounts-dialog.c: Make "Add account" button
        insensitive when we are creating one. Fixes bug #459170
        (Jaap A. Haitsma).
 
-2007-08-11 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-11  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-tp-contact-list.c: s/Local Network/People nearby/
        (Sjoerd Simons)
 
 
        * libempathy/empathy-tp-contact-list.c: s/Local Network/People nearby/
        (Sjoerd Simons)
 
-2007-08-10 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-10  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-accounts-dialog.c: Unselect accounts when
        clicking on "add" button. Fixes bug #459173 (Cosimo Cecchi).
 
 
        * libempathy-gtk/empathy-accounts-dialog.c: Unselect accounts when
        clicking on "add" button. Fixes bug #459173 (Cosimo Cecchi).
 
-2007-08-10 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-10  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-presence-chooser.glade: add some spacing in
        "Custom message" dialog. Fixes bug #465360 (Frederic Peters).
 
 
        * libempathy-gtk/empathy-presence-chooser.glade: add some spacing in
        "Custom message" dialog. Fixes bug #465360 (Frederic Peters).
 
-2007-08-10 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-10  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-images.h:
        * libempathy-gtk/empathy-presence-chooser.c:
 
        * libempathy-gtk/empathy-images.h:
        * libempathy-gtk/empathy-presence-chooser.c:
        * data/irc.profile:
        * data/msn.profile: Updated to use SupportedPresences field.
 
        * data/irc.profile:
        * data/msn.profile: Updated to use SupportedPresences field.
 
-2007-08-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-presence-chooser.glade:
        * libempathy-gtk/empathy-presence-chooser.c:
 
        * libempathy-gtk/empathy-presence-chooser.glade:
        * libempathy-gtk/empathy-presence-chooser.c:
        messages. Make easier to add other states to the list if needed.
        Fixes bug #460678.
 
        messages. Make easier to add other states to the list if needed.
        Fixes bug #460678.
 
-2007-08-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-presence.c:
        * libempathy/empathy-idle.c:
        * configure.ac: Remove workaround for mc-enum-types.h not being
        installed by MC and bump MC minimal version to 4.33.
 
 
        * libempathy/empathy-presence.c:
        * libempathy/empathy-idle.c:
        * configure.ac: Remove workaround for mc-enum-types.h not being
        installed by MC and bump MC minimal version to 4.33.
 
-2007-08-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-preferences.c:
        * libempathy-gtk/empathy-preferences.glade: Useless spell checker
        option. Fixes bug #459164 (Cosimo Cecchi).
 
 
        * libempathy-gtk/empathy-preferences.c:
        * libempathy-gtk/empathy-preferences.glade: Useless spell checker
        option. Fixes bug #459164 (Cosimo Cecchi).
 
-2007-08-08 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-08  Xavier Claessens  <xclaesse@gmail.com>
 
        * autogen.sh: Requier automake 1.9. Fixes bug #464822 (Cosimo Cecchi).
 
 
        * autogen.sh: Requier automake 1.9. Fixes bug #464822 (Cosimo Cecchi).
 
-2007-08-08 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-08  Xavier Claessens  <xclaesse@gmail.com>
 
        * MAINTAINERS: Updated the MAINTAINERS file to match new syntax.
 
 
        * MAINTAINERS: Updated the MAINTAINERS file to match new syntax.
 
        empathy_contact_list_store_sort_get_type() as it's now auto-generated
        by glib-mkenums.
 
        empathy_contact_list_store_sort_get_type() as it's now auto-generated
        by glib-mkenums.
 
-2007-08-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-main-window.glade: Change main window's title
        to "Contact list".
 
 
        * libempathy-gtk/empathy-main-window.glade: Change main window's title
        to "Contact list".
 
-2007-08-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-tp-chat.c: Don't forget to reverse the glist of
        pending messages.
 
        * libempathy/empathy-tp-chat.c: Don't forget to reverse the glist of
        pending messages.
        * libempathy/empathy-tp-roomlist.c: Fix wrong room list names when
        listing them.
 
        * libempathy/empathy-tp-roomlist.c: Fix wrong room list names when
        listing them.
 
-2007-08-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-msn.glade:
        * libempathy-gtk/empathy-account-widget-msn.c: Add an Advanced section
 
        * libempathy-gtk/empathy-account-widget-msn.glade:
        * libempathy-gtk/empathy-account-widget-msn.c: Add an Advanced section
 
        * README: Use ./autogen.sh instead of gnome-autogen.sh.
 
 
        * README: Use ./autogen.sh instead of gnome-autogen.sh.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-accounts-dialog.glade:
        * libempathy-gtk/empathy-accounts-dialog.c: Click on the treeview to
        edit the name of an account. Fixes bug #459166.
 
 
        * libempathy-gtk/empathy-accounts-dialog.glade:
        * libempathy-gtk/empathy-accounts-dialog.c: Click on the treeview to
        edit the name of an account. Fixes bug #459166.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-jabber.c: Do not try to guess
        the Jabber server from the jid, gabble does that for us.
 
 
        * libempathy-gtk/empathy-account-widget-jabber.c: Do not try to guess
        the Jabber server from the jid, gabble does that for us.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * doc/libempathy-gtk/tmpl/empathy-account-chooser.sgml:
        * doc/libempathy-gtk/tmpl/empathy-ui-utils.sgml:
 
        * doc/libempathy-gtk/tmpl/empathy-account-chooser.sgml:
        * doc/libempathy-gtk/tmpl/empathy-ui-utils.sgml:
        * doc/libempathy/tmpl/empathy-message.sgml:
        * doc/libempathy/tmpl/empathy-utils.sgml: Update doc.
 
        * doc/libempathy/tmpl/empathy-message.sgml:
        * doc/libempathy/tmpl/empathy-utils.sgml: Update doc.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-profile-chooser.c: Do not list profiles that
        don't have the corresponding CM installed when creating a new account.
        This is a workaround for MC bug: SF #1688779.
 
 
        * libempathy-gtk/empathy-profile-chooser.c: Do not list profiles that
        don't have the corresponding CM installed when creating a new account.
        This is a workaround for MC bug: SF #1688779.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-generic.c: Remove size_group.
        Fixes bug #462792.
 
 
        * libempathy-gtk/empathy-account-widget-generic.c: Remove size_group.
        Fixes bug #462792.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-accounts-dialog.c:
        * libempathy/empathy-utils.c:
 
        * libempathy-gtk/empathy-accounts-dialog.c:
        * libempathy/empathy-utils.c:
        telepathy-glib. It check if strings are != NULL before using strcmp.
        Using that API to fix bug #461886. Should be used in more places.
 
        telepathy-glib. It check if strings are != NULL before using strcmp.
        Using that API to fix bug #461886. Should be used in more places.
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c: Click on the tray icon shows the
        window if it's not active and hide if it is. Fixes bug #462057
        (Olivier Valentin).
 
 
        * libempathy-gtk/empathy-status-icon.c: Click on the tray icon shows the
        window if it's not active and hide if it is. Fixes bug #462057
        (Olivier Valentin).
 
-2007-08-02 Xavier Claessens  <xclaesse@gmail.com>
+2007-08-02  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-group-chat.c: don't display
        "Topic set to: (null)". Fixes bug #460205 (Michael Scherer).
 
 
        * libempathy-gtk/empathy-group-chat.c: don't display
        "Topic set to: (null)". Fixes bug #460205 (Michael Scherer).
 
-2007-07-30 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-30  Xavier Claessens  <xclaesse@gmail.com>
 
        * autogen.sh: Added back, it calls gnome-autogen.sh.
 
 
        * autogen.sh: Added back, it calls gnome-autogen.sh.
 
-2007-07-29 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-29  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-profile-chooser.c:
        * libempathy/empathy-message.c: Add missing include string.h.
 
 
        * libempathy-gtk/empathy-profile-chooser.c:
        * libempathy/empathy-message.c: Add missing include string.h.
 
-2007-07-29 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-29  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump version to 0.11.
 
 
        * configure.ac: Bump version to 0.11.
 
-2007-07-29 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-29  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-generic.c:
        * libempathy-gtk/empathy-account-widget-generic.h: Align param names
 
        * libempathy-gtk/empathy-account-widget-generic.c:
        * libempathy-gtk/empathy-account-widget-generic.h: Align param names
 
        * configure.ac: Set Collabora Ltd. in the Copyright.
 
 
        * configure.ac: Set Collabora Ltd. in the Copyright.
 
-2007-07-28 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-28  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-profile-chooser.c: Makes easier to change to
        profile order.
 
 
        * libempathy-gtk/empathy-profile-chooser.c: Makes easier to change to
        profile order.
 
-2007-07-28 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-28  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-jabber.c: Try to guess the
        server from the jid only if we are using the jabber profile. When we
        guessed a server don't forget to set the "server" McAccount param,
        setting the entry's text is not enough.
 
 
        * libempathy-gtk/empathy-account-widget-jabber.c: Try to guess the
        server from the jid only if we are using the jabber profile. When we
        guessed a server don't forget to set the "server" McAccount param,
        setting the entry's text is not enough.
 
-2007-07-28 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-28  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-profile-chooser.c: Improve the sort function
        a bit to have Jabber before GTalk.
 
 
        * libempathy-gtk/empathy-profile-chooser.c: Improve the sort function
        a bit to have Jabber before GTalk.
 
-2007-07-28 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-28  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-accounts-dialog.glade:
        * libempathy-gtk/empathy-accounts-dialog.c: Update the Enable/Disable
        button even if there is no account selected. Set it insensitive if no
        account is selected. Fixes bug #459012.
 
 
        * libempathy-gtk/empathy-accounts-dialog.glade:
        * libempathy-gtk/empathy-accounts-dialog.c: Update the Enable/Disable
        button even if there is no account selected. Set it insensitive if no
        account is selected. Fixes bug #459012.
 
-2007-07-27 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-27  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-profile-chooser.c: Sort profiles to have
        free protocols first. Fixes bug #460605.
 
 
        * libempathy-gtk/empathy-profile-chooser.c: Sort profiles to have
        free protocols first. Fixes bug #460605.
 
-2007-07-27 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-27  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-message.c:
        * libempathy/empathy-message.h:
 
        * libempathy/empathy-message.c:
        * libempathy/empathy-message.h:
 
        * doc/*: Updated.
 
 
        * doc/*: Updated.
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * po/POTFILES.in: Add missing file
        libempathy-gtk/empathy-account-widget-msn.glade.
 
 
        * po/POTFILES.in: Add missing file
        libempathy-gtk/empathy-account-widget-msn.glade.
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-jabber.glade:
        * libempathy-gtk/empathy-account-widget-jabber.c: Hide
        "advanced options" for jabber in a GtkExpander. Fixes bug #459168
        (Guillaume Desmottes).
 
 
        * libempathy-gtk/empathy-account-widget-jabber.glade:
        * libempathy-gtk/empathy-account-widget-jabber.c: Hide
        "advanced options" for jabber in a GtkExpander. Fixes bug #459168
        (Guillaume Desmottes).
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        * libempathy/empathy-tp-roomlist.c: Fix Room listing. Fixes bug #460416
        (Sjoerd Simons).
 
 
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        * libempathy/empathy-tp-roomlist.c: Fix Room listing. Fixes bug #460416
        (Sjoerd Simons).
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/Makefile.am:
        * libempathy/Makefile.am:
        * configure.ac: Use libtool -version-info. Fixes bug #460579
        (Laurent Bigonville).
 
 
        * libempathy-gtk/Makefile.am:
        * libempathy/Makefile.am:
        * configure.ac: Use libtool -version-info. Fixes bug #460579
        (Laurent Bigonville).
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * README:
        * autogen.sh: Remove the autogen.sh script and use gnome-autogen.sh
        instead. Fixes bug #460590.
 
 
        * README:
        * autogen.sh: Remove the autogen.sh script and use gnome-autogen.sh
        instead. Fixes bug #460590.
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-chooser.c:
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
 
        * libempathy-gtk/empathy-account-chooser.c:
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        a bit EmpathyContactWidget. Fixes bug #459100
        (Guillaume Desmottes, Xavier Claessens).
 
        a bit EmpathyContactWidget. Fixes bug #459100
        (Guillaume Desmottes, Xavier Claessens).
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-accounts-dialog.c: add contact frame is not
        hidden after cancelling. Fixes bug #458997 (Frederic Peters).
 
 
        * libempathy-gtk/empathy-accounts-dialog.c: add contact frame is not
        hidden after cancelling. Fixes bug #458997 (Frederic Peters).
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-idle.c: Fix problems when NM is not running. Fixes
        bug #460419.
 
        * doc/*: Updated documentation.
 
 
        * libempathy/empathy-idle.c: Fix problems when NM is not running. Fixes
        bug #460419.
 
        * doc/*: Updated documentation.
 
-2007-07-26 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-26  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump version to 0.10
 
 
        * configure.ac: Bump version to 0.10
 
-2007-07-25 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-25  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-filter.c: Adding more debug output.
 
 
        * libempathy/empathy-filter.c: Adding more debug output.
 
-2007-07-25 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-25  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-tp-contact-list.c: Add a check to be sure the
        new channel is valid in the NewChannel cb. Fixes bug #451564.
 
 
        * libempathy/empathy-tp-contact-list.c: Add a check to be sure the
        new channel is valid in the NewChannel cb. Fixes bug #451564.
 
-2007-07-20 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-20  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/Makefile.am:
        * libempathy/empathy-tp-roomlist.h:
 
        * libempathy/Makefile.am:
        * libempathy/empathy-tp-roomlist.h:
        * data/empathy.desktop.in.in: Change application description
        (Jaap A. Haitsma).
 
        * data/empathy.desktop.in.in: Change application description
        (Jaap A. Haitsma).
 
-2007-07-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-list-store.c: Show avatars by default.
 
 
        * libempathy-gtk/empathy-contact-list-store.c: Show avatars by default.
 
-2007-07-13 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-13  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c: If there is no pending msg
        when a text channel should be filtered wait for the first message
        instead of not dispatching the channel which may cause messages to be
        lost.
 
 
        * libempathy-gtk/empathy-status-icon.c: If there is no pending msg
        when a text channel should be filtered wait for the first message
        instead of not dispatching the channel which may cause messages to be
        lost.
 
-2007-07-13 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-13  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-tp-contact-list.c: Fix avatar request queue.
 
 
        * libempathy/empathy-tp-contact-list.c: Fix avatar request queue.
 
-2007-07-13 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-13  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        * libempathy-gtk/empathy-new-chatroom-dialog.glade: Remove unused
 
        * libempathy-gtk/empathy-new-chatroom-dialog.c:
        * libempathy-gtk/empathy-new-chatroom-dialog.glade: Remove unused
        * libempathy/empathy-tp-contact-list.c: Add more debug msg for avatar
        handling.
 
        * libempathy/empathy-tp-contact-list.c: Add more debug msg for avatar
        handling.
 
-2007-07-12 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-12  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/Makefile.am: Fix missing header for
        EmpathyAccountWidgetMSN.
 
        * libempathy-gtk/Makefile.am: Fix missing header for
        EmpathyAccountWidgetMSN.
 
        * autogen.sh: run gtkdocize if needed.
 
 
        * autogen.sh: run gtkdocize if needed.
 
-2007-07-12 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-12  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac:
        * doc/*:
        * Makefile.am: Adding initial API documentation using gtk-doc.
 
 
        * configure.ac:
        * doc/*:
        * Makefile.am: Adding initial API documentation using gtk-doc.
 
-2007-07-12 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-12  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-tp-contact-list.c: Auto-accept to publish presence
        to contacts that are in our subscribe list. When accepting a pending
        contact add it to publish and subscribe list.
 
 
        * libempathy/empathy-tp-contact-list.c: Auto-accept to publish presence
        to contacts that are in our subscribe list. When accepting a pending
        contact add it to publish and subscribe list.
 
-2007-07-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * src/empathy.c:
        * libempathy/empathy-debug.c:
        * libempathy/empathy-debug.h: Add EMPATHY_LOGFILE env variable. Fixes
        bug #455240 (Guillaume Desmottes).
 
 
        * src/empathy.c:
        * libempathy/empathy-debug.c:
        * libempathy/empathy-debug.h: Add EMPATHY_LOGFILE env variable. Fixes
        bug #455240 (Guillaume Desmottes).
 
-2007-07-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-msn.glade:
        * libempathy-gtk/empathy-account-widget-msn.c:
 
        * libempathy-gtk/empathy-account-widget-msn.glade:
        * libempathy-gtk/empathy-account-widget-msn.c:
        * libempathy/empathy-log-manager.h: Add needed API to show chat logs in
        Tracker. Fixes bug #452536.
 
        * libempathy/empathy-log-manager.h: Add needed API to show chat logs in
        Tracker. Fixes bug #452536.
 
-2007-07-07 Xavier Claessens  <xclaesse@gmail.com>
+2007-07-07  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-generic.c: Workaround to fix a 
        commonly reported crash. Fixes bug #454277
        * libempathy/empathy-tp-group.c: Add a missing check.
 
 
        * libempathy-gtk/empathy-account-widget-generic.c: Workaround to fix a 
        commonly reported crash. Fixes bug #454277
        * libempathy/empathy-tp-group.c: Add a missing check.
 
-2007-06-30 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-30  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump MC version required to 4.27.
        * TODO: Updated.
 
 
        * configure.ac: Bump MC version required to 4.27.
        * TODO: Updated.
 
-2007-06-30 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-30  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-account-widget-generic.c: Fix a leaked ref.
 
 
        * libempathy-gtk/empathy-account-widget-generic.c: Fix a leaked ref.
 
        status icon flash when there we receive a new message. Dispatch the
        channel only when we get a message and the user click on the icon.
 
        status icon flash when there we receive a new message. Dispatch the
        channel only when we get a message and the user click on the icon.
 
-2007-06-22 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-22  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/libempathy-gtk.pc.in:
        * libempathy-gtk/Makefile.am:
 
        * libempathy-gtk/libempathy-gtk.pc.in:
        * libempathy-gtk/Makefile.am:
        * configure.ac: Install libempathy and libempathy-gtk and make their
        API public.
 
        * configure.ac: Install libempathy and libempathy-gtk and make their
        API public.
 
-2007-06-22 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-22  Xavier Claessens  <xclaesse@gmail.com>
 
        * po/POTFILES.in: s/gossip/empathy/
 
 
        * po/POTFILES.in: s/gossip/empathy/
 
-2007-06-22 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-22  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/*.[ch]:
        * libempathy-gtk/*.[ch]:
 
        * libempathy/*.[ch]:
        * libempathy-gtk/*.[ch]:
        change namespace of all gossip_*() functions to empathy_*().
        Fixes bug #444490 (Mario Danic, Xavier Claessens).
 
        change namespace of all gossip_*() functions to empathy_*().
        Fixes bug #444490 (Mario Danic, Xavier Claessens).
 
-2007-06-21 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-21  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump version to 0.9
 
 
        * configure.ac: Bump version to 0.9
 
-2007-06-21 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-21  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/empathy-tp-contact-list.c: Fix typo causing warnings.
 
 
        * libempathy/empathy-tp-contact-list.c: Fix typo causing warnings.
 
-2007-06-21 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-21  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-dialogs.c:
        * libempathy-gtk/gossip-contact-list-store.c:
 
        * libempathy-gtk/empathy-contact-dialogs.c:
        * libempathy-gtk/gossip-contact-list-store.c:
        only add/remove from subscribe list. Accept/Reject a contact in
        local-pending of publish list is done using _process_pending().
 
        only add/remove from subscribe list. Accept/Reject a contact in
        local-pending of publish list is done using _process_pending().
 
-2007-06-15 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-15  Xavier Claessens  <xclaesse@gmail.com>
 
        * src/empathy.c:
        * libempathy/empathy-idle.c: Adding NetworkManager support.
 
 
        * src/empathy.c:
        * libempathy/empathy-idle.c: Adding NetworkManager support.
 
-2007-06-15 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-15  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c:
        * libempathy-gtk/gossip-presence-chooser.c:
 
        * libempathy-gtk/empathy-status-icon.c:
        * libempathy-gtk/gossip-presence-chooser.c:
        * libempathy/empathy-idle.h: Prepare for slack time when coming back
        from auto away. Not yet fully implemented.
 
        * libempathy/empathy-idle.h: Prepare for slack time when coming back
        from auto away. Not yet fully implemented.
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-images.h:
        * libempathy-gtk/gossip-chat.c: Use gtk-info for contact informaiton.
 
        * libempathy-gtk/empathy-images.h:
        * libempathy-gtk/gossip-chat.c: Use gtk-info for contact informaiton.
        * data/scalable/Makefile.am:
        * data/salut.profile: Add salut icon. Fixes bug #447659 (Michael Monreal).
 
        * data/scalable/Makefile.am:
        * data/salut.profile: Add salut icon. Fixes bug #447659 (Michael Monreal).
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-contact-list-view.c: Show logs when right
        click on a contact in the roster.
 
 
        * libempathy-gtk/gossip-contact-list-view.c: Show logs when right
        click on a contact in the roster.
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * src/org.gnome.Empathy.Chat.service.in:
        * src/empathy-accounts.c:
 
        * src/org.gnome.Empathy.Chat.service.in:
        * src/empathy-accounts.c:
        debugging more difficult when emmpathy-chat crashes. It's also more
        optimised like that since contact objects can be shared.
 
        debugging more difficult when emmpathy-chat crashes. It's also more
        optimised like that since contact objects can be shared.
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-chat-window.c: Disconnect signals from
        chatroom_manager. Fixes bug #447178.
 
 
        * libempathy-gtk/gossip-chat-window.c: Disconnect signals from
        chatroom_manager. Fixes bug #447178.
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * po/POTFILES.in:
        * po/POTFILES.skip: Get strings in empathy.desktop.in.in and skip
        empathy.desktop.in. Fixes bug #446161.
 
 
        * po/POTFILES.in:
        * po/POTFILES.skip: Get strings in empathy.desktop.in.in and skip
        empathy.desktop.in. Fixes bug #446161.
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * po/POTFILES.in: Adding missing files.
 
 
        * po/POTFILES.in: Adding missing files.
 
-2007-06-14 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-14  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-log-window.c:
        * libempathy-gtk/gossip-chat-window.c:
 
        * libempathy-gtk/gossip-log-window.c:
        * libempathy-gtk/gossip-chat-window.c:
        chat if there is no messages to put in. Show logs and information for
        the contact we are speaking with in the chat window menu.
 
        chat if there is no messages to put in. Show logs and information for
        the contact we are speaking with in the chat window menu.
 
-2007-06-13 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-13  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/Makefile.am:
        * libempathy-gtk/gossip-log-window.glade:
 
        * libempathy-gtk/Makefile.am:
        * libempathy-gtk/gossip-log-window.glade:
        * libempathy/gossip-message.c: Add a "receiver" property like that we
        have our self contact for nick highlight.
 
        * libempathy/gossip-message.c: Add a "receiver" property like that we
        have our self contact for nick highlight.
 
-2007-06-10 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-10  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-spell-dialog.glade:
        * libempathy-gtk/gossip-spell-dialog.c:
 
        * libempathy-gtk/gossip-spell-dialog.glade:
        * libempathy-gtk/gossip-spell-dialog.c:
        * libempathy-gtk/gossip-spell.c:
        * libempathy/gossip-conf.c: Remove useless debug messages.
 
        * libempathy-gtk/gossip-spell.c:
        * libempathy/gossip-conf.c: Remove useless debug messages.
 
-2007-06-10 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-10  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-chat-view.c: Smooth scrolling.
        Fixes bug #445859 (Raphael Slinckx).
 
 
        * libempathy-gtk/gossip-chat-view.c: Smooth scrolling.
        Fixes bug #445859 (Raphael Slinckx).
 
-2007-06-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/gossip-contact.c: Emit notify signal only if the property
        value effectively changed.
 
 
        * libempathy/gossip-contact.c: Emit notify signal only if the property
        value effectively changed.
 
-2007-06-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-contact-list-view.c: Fix warning for DnD.
        patch imported from gossip.
 
 
        * libempathy-gtk/gossip-contact-list-view.c: Fix warning for DnD.
        patch imported from gossip.
 
-2007-06-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * configure.ac: Bump version to 0.8
 
 
        * configure.ac: Bump version to 0.8
 
        * data/msn.profile: Add VCardField and VCardDefault to profiles for
        eds-sync support.
 
        * data/msn.profile: Add VCardField and VCardDefault to profiles for
        eds-sync support.
 
-2007-06-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-widget.c: Fix a warning.
 
 
        * libempathy-gtk/empathy-contact-widget.c: Fix a warning.
 
-2007-06-09 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-09  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-main-window.c:
        * libempathy-gtk/empathy-contact-widget.glade:
 
        * libempathy-gtk/empathy-main-window.c:
        * libempathy-gtk/empathy-contact-widget.glade:
 
        * libempathy/empathy-tp-contact-list.c: Fix a refcount bug.
 
 
        * libempathy/empathy-tp-contact-list.c: Fix a refcount bug.
 
-2007-06-08 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-08  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/gossip-chatroom-manager.c: Checks if the chatroom has
        an account and a room. Fixes bug #444135.
 
 
        * libempathy/gossip-chatroom-manager.c: Checks if the chatroom has
        an account and a room. Fixes bug #444135.
 
-2007-06-08 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-08  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-dialogs.c:
        * libempathy-gtk/empathy-contact-widget.c:
 
        * libempathy-gtk/empathy-contact-dialogs.c:
        * libempathy-gtk/empathy-contact-widget.c:
        gossip_contact_add/remove_group(). This fixes leaks when a contact is
        added/removed from a group.
 
        gossip_contact_add/remove_group(). This fixes leaks when a contact is
        added/removed from a group.
 
-2007-06-08 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-08  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-chat.c: Fix build on 64bits arch.
        Fixes bug #444680 (Matej Cepl).
 
 
        * libempathy-gtk/gossip-chat.c: Fix build on 64bits arch.
        Fixes bug #444680 (Matej Cepl).
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-dialogs.glade:
        * libempathy-gtk/empathy-contact-dialogs.c: Fix response and action
        buttons.
 
 
        * libempathy-gtk/empathy-contact-dialogs.glade:
        * libempathy-gtk/empathy-contact-dialogs.c: Fix response and action
        buttons.
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-dialogs.glade:
        * libempathy-gtk/empathy-contact-widget.glade:
 
        * libempathy-gtk/empathy-contact-dialogs.glade:
        * libempathy-gtk/empathy-contact-widget.glade:
        * libempathy-gtk/empathy-subscription-dialog.h: Implement editing and
        viewing contact information with right click on the roster.
 
        * libempathy-gtk/empathy-subscription-dialog.h: Implement editing and
        viewing contact information with right click on the roster.
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-contact-widget.glade:
        * libempathy-gtk/empathy-contact-widget.c:
 
        * libempathy-gtk/empathy-contact-widget.glade:
        * libempathy-gtk/empathy-contact-widget.c:
        * libempathy-gtk/empathy-subscription-dialog.c: EmpatchContactWidget
        has 2 modes: editable or not.
 
        * libempathy-gtk/empathy-subscription-dialog.c: EmpatchContactWidget
        has 2 modes: editable or not.
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * po/POTFILES.in: Updated with new files.
 
 
        * po/POTFILES.in: Updated with new files.
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c:
        * libempathy-gtk/empathy-subscription-dialog.glade:
 
        * libempathy-gtk/empathy-status-icon.c:
        * libempathy-gtk/empathy-subscription-dialog.glade:
        dialog appears when clicking on the status icon when it blinks. You
        can also remove contacts when right-click on it in the roster.
 
        dialog appears when clicking on the status icon when it blinks. You
        can also remove contacts when right-click on it in the roster.
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c:
        * libempathy-gtk/empathy-contact-widget.glade:
 
        * libempathy-gtk/empathy-status-icon.c:
        * libempathy-gtk/empathy-contact-widget.glade:
        gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE)
        when there is no presence.
 
        gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE)
        when there is no presence.
 
-2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-06  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c: Add support for blinking when
        there is an event. Make use of EmpathyIdle for presence handling. Add
 
        * libempathy-gtk/empathy-status-icon.c: Add support for blinking when
        there is an event. Make use of EmpathyIdle for presence handling. Add
 
        * TODO: Updated.
 
 
        * TODO: Updated.
 
-2007-06-03 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-03  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-accounts-dialog.glade: Set use_stock for
        button_connect to False, to avoid a crasher when opening the accounts
 
        * libempathy-gtk/gossip-accounts-dialog.glade: Set use_stock for
        button_connect to False, to avoid a crasher when opening the accounts
        * libempathy-gtk/gossip-chat.c: Do not add backlog for chatrooms and
        do not log backlog from jabber server.
 
        * libempathy-gtk/gossip-chat.c: Do not add backlog for chatrooms and
        do not log backlog from jabber server.
 
-2007-06-03 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-03  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-ui-utils.c
        * libempathy-gtk/gossip-accounts-dialog.c
 
        * libempathy-gtk/gossip-ui-utils.c
        * libempathy-gtk/gossip-accounts-dialog.c
        * libempathy/gossip-paths.h: Remove unused code and append DATADIR to
        dirs where GTK should search icons.
 
        * libempathy/gossip-paths.h: Remove unused code and append DATADIR to
        dirs where GTK should search icons.
 
-2007-06-03 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-03  Xavier Claessens  <xclaesse@gmail.com>
 
        * po/POTFILES.in:
        * po/POTFILES.skip: Add missing files that have strings for translation.
        Skip empathy-desktop.in.in. (Olivier Crete)
 
 
        * po/POTFILES.in:
        * po/POTFILES.skip: Add missing files that have strings for translation.
        Skip empathy-desktop.in.in. (Olivier Crete)
 
-2007-06-03 Xavier Claessens  <xclaesse@gmail.com>
+2007-06-03  Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/gossip-group-chat.c:
        * libempathy-gtk/gossip-private-chat.c:
 
        * libempathy-gtk/gossip-group-chat.c:
        * libempathy-gtk/gossip-private-chat.c:
index c31afd82c1a114162e51ac2886b1052ec76ede90..49a09b7b83bcde882830a58673a3b346b15eb542 100644 (file)
@@ -155,62 +155,58 @@ AC_ARG_ENABLE(python,
                              [build python bindings to libempathy and libempathy-gtk]), ,
                              enable_python=auto)
 
                              [build python bindings to libempathy and libempathy-gtk]), ,
                              enable_python=auto)
 
-PKG_CHECK_MODULES(PYTHON_BINDING,
-[
-   pygtk-2.0,
-   glib-2.0 >= $GLIB_REQUIRED
-   gobject-2.0
-   gconf-2.0 >= $GCONF_REQUIRED
-   libxml-2.0
-   gnome-vfs-2.0
-   libtelepathy >= $TELEPATHY_REQUIRED
-   libmissioncontrol >= $MISSION_CONTROL_REQUIRED
-   gtk+-2.0 >= $GTK_REQUIRED
-   libglade-2.0 >= $LIBGLADE_REQUIRED
-   libgnomeui-2.0
-], have_python="yes", have_python="no")
-
-if test "x$have_python" = "xno"; then
-       if test "x$enable_python" = "xyes"; then
-               AC_MSG_ERROR([Could not find python dependencies])
-       fi
-       enable_python="no (missing dependencies)"
+if test "x$enable_python" != "xno"; then
+   AM_PATH_PYTHON
+   if test -z "$PYTHON" ; then
+      have_python="no"
+   else
+      PKG_CHECK_MODULES(PYTHON_BINDING,
+      [
+         pygtk-2.0,
+         glib-2.0 >= $GLIB_REQUIRED
+         gobject-2.0
+         gconf-2.0 >= $GCONF_REQUIRED
+         libxml-2.0
+         gnome-vfs-2.0
+         libtelepathy >= $TELEPATHY_REQUIRED
+         libmissioncontrol >= $MISSION_CONTROL_REQUIRED
+         gtk+-2.0 >= $GTK_REQUIRED
+         libglade-2.0 >= $LIBGLADE_REQUIRED
+         libgnomeui-2.0
+      ], have_python="yes", have_python="no")
+   fi
 else
 else
-       if test "x$enable_python" != "xno"; then
-               AM_PATH_PYTHON
-               if test -z "$PYTHON" ; then
-                       enable_python="no"
-               else
-                       enable_python="yes"
-               fi
-       else
-               enable_python="no (disabled)"
-       fi
+   have_python=no
+fi
+
+if test "x$enable_python" = "xyes" -a "x$have_python" != "xyes"; then
+   AC_MSG_ERROR([Couldn't find python.])
 fi
 fi
-AM_CONDITIONAL(HAVE_PYTHON, test x$enable_python = xyes)
+
+AM_CONDITIONAL(HAVE_PYTHON, test "x$have_python" = "xyes")
 
 dnl -----------------------------------------------------------
 
 AC_OUTPUT([
 
 dnl -----------------------------------------------------------
 
 AC_OUTPUT([
-  Makefile
-  data/Makefile
-  data/empathy.desktop.in
-  data/16x16/Makefile
-  data/22x22/Makefile
-  data/24x24/Makefile
-  data/32x32/Makefile
-  data/48x48/Makefile
-  data/scalable/Makefile
-  po/Makefile.in
-  libempathy/Makefile
-  libempathy/libempathy.pc
-  libempathy-gtk/Makefile
-  libempathy-gtk/libempathy-gtk.pc
-  src/Makefile
-  doc/Makefile
-  doc/libempathy/Makefile
-  doc/libempathy-gtk/Makefile
-  python/Makefile
-  python/pyempathy/Makefile
-  python/pyempathygtk/Makefile
+   Makefile
+   data/Makefile
+   data/empathy.desktop.in
+   data/16x16/Makefile
+   data/22x22/Makefile
+   data/24x24/Makefile
+   data/32x32/Makefile
+   data/48x48/Makefile
+   data/scalable/Makefile
+   po/Makefile.in
+   libempathy/Makefile
+   libempathy/libempathy.pc
+   libempathy-gtk/Makefile
+   libempathy-gtk/libempathy-gtk.pc
+   src/Makefile
+   doc/Makefile
+   doc/libempathy/Makefile
+   doc/libempathy-gtk/Makefile
+   python/Makefile
+   python/pyempathy/Makefile
+   python/pyempathygtk/Makefile
 ])
 ])
index a4430da4971dc6ee9f643785f1d8b6f4c28864dc..cc74feef8e7809241e0947b6601588b0c672449d 100644 (file)
@@ -173,22 +173,3 @@ EmpathyContactListStore
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_contact_list_store_set_contact_groups_func ##### -->
-<para>
-
-</para>
-
-@store: 
-@func: 
-@user_data: 
-
-
-<!-- ##### FUNCTION empathy_contact_list_store_update_contact_groups ##### -->
-<para>
-
-</para>
-
-@store: 
-@contact: 
-
-
index ad7a1ff71d110a009f78c8ffe5ff95ad96bd17df..188033ebf619a5a4f2af9c006295fac3298c3b29 100644 (file)
@@ -39,23 +39,6 @@ EmpathyContactListView
 @arg2: 
 @arg3: 
 
 @arg2: 
 @arg3: 
 
-<!-- ##### ARG EmpathyContactListView:filter ##### -->
-<para>
-
-</para>
-
-<!-- ##### USER_FUNCTION EmpathyContactListViewDragReceivedFunc ##### -->
-<para>
-
-</para>
-
-@contact: 
-@action: 
-@old_group: 
-@new_group: 
-@user_data: 
-
-
 <!-- ##### FUNCTION empathy_contact_list_view_new ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_list_view_new ##### -->
 <para>
 
@@ -102,22 +85,3 @@ EmpathyContactListView
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_contact_list_view_set_filter ##### -->
-<para>
-
-</para>
-
-@view: 
-@filter: 
-
-
-<!-- ##### FUNCTION empathy_contact_list_view_set_drag_received_func ##### -->
-<para>
-
-</para>
-
-@view: 
-@func: 
-@user_data: 
-
-
index c55b21f1c85f7c0115a47b6edec10e9cf3ee308f..5b8c6541c5b262dd0314b81fb77190fd0ca71ca0 100644 (file)
@@ -59,13 +59,6 @@ empathy-images
 
 
 
 
 
 
-<!-- ##### MACRO EMPATHY_IMAGE_PENDING ##### -->
-<para>
-
-</para>
-
-
-
 <!-- ##### MACRO EMPATHY_IMAGE_MESSAGE ##### -->
 <para>
 
 <!-- ##### MACRO EMPATHY_IMAGE_MESSAGE ##### -->
 <para>
 
index d97f5b57b732cc9c077fae935406da47a1eeea04..0b7a7d27abb36058566e1c52a9833b68b6a307f3 100644 (file)
@@ -143,13 +143,6 @@ empathy-preferences
 
 
 
 
 
 
-<!-- ##### MACRO EMPATHY_PREFS_SALUT_ACCOUNT_CREATED ##### -->
-<para>
-
-</para>
-
-
-
 <!-- ##### FUNCTION empathy_preferences_show ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_preferences_show ##### -->
 <para>
 
index 0211e40b11748342a83279b5cab77137ac37e61f..15955d12b07c5659015dcf92a4cf96ec3ccc0940 100644 (file)
@@ -16,7 +16,7 @@
 #include <libempathy/empathy-message.h>
 #include <libempathy/empathy-tp-chatroom.h>
 
 #include <libempathy/empathy-message.h>
 #include <libempathy/empathy-tp-chatroom.h>
 
-empathy_avatar_get_gtype
+empathy_avatar_get_type
 empathy_chatroom_manager_get_type
 empathy_contact_manager_get_type
 empathy_idle_get_type
 empathy_chatroom_manager_get_type
 empathy_contact_manager_get_type
 empathy_idle_get_type
@@ -26,7 +26,7 @@ empathy_conf_get_type
 empathy_log_manager_get_type
 empathy_tp_group_get_type
 empathy_chandler_get_type
 empathy_log_manager_get_type
 empathy_tp_group_get_type
 empathy_chandler_get_type
-empathy_contact_get_gtype
+empathy_contact_get_type
 empathy_tp_chat_get_type
 empathy_chatroom_get_type
 empathy_contact_list_get_type
 empathy_tp_chat_get_type
 empathy_chatroom_get_type
 empathy_contact_list_get_type
index 44035517e0f1bbfc7685edcb87afa1dacefcf1e4..3f71285c866f67d754a10066559c4f0c59d9fdfe 100644 (file)
@@ -34,14 +34,6 @@ empathy-avatar
 @format: 
 @refcount: 
 
 @format: 
 @refcount: 
 
-<!-- ##### FUNCTION empathy_avatar_get_gtype ##### -->
-<para>
-
-</para>
-
-@Returns: 
-
-
 <!-- ##### FUNCTION empathy_avatar_new ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_avatar_new ##### -->
 <para>
 
index 1a2839fc761857643f03ba8154cec74c36c4cac3..a84646a8ea3bc083635af76b03c160d00ceb3f0d 100644 (file)
@@ -23,23 +23,29 @@ empathy-contact-list
 </para>
 
 
 </para>
 
 
-<!-- ##### SIGNAL EmpathyContactList::contact-added ##### -->
+<!-- ##### SIGNAL EmpathyContactList::groups-changed ##### -->
 <para>
 
 </para>
 
 @empathycontactlist: the object which received the signal.
 @arg1: 
 <para>
 
 </para>
 
 @empathycontactlist: the object which received the signal.
 @arg1: 
+@arg2: 
+@arg3: 
 
 
-<!-- ##### SIGNAL EmpathyContactList::contact-removed ##### -->
+<!-- ##### SIGNAL EmpathyContactList::members-changed ##### -->
 <para>
 
 </para>
 
 @empathycontactlist: the object which received the signal.
 @arg1: 
 <para>
 
 </para>
 
 @empathycontactlist: the object which received the signal.
 @arg1: 
+@arg2: 
+@arg3: 
+@arg4: 
+@arg5: 
 
 
-<!-- ##### SIGNAL EmpathyContactList::local-pending ##### -->
+<!-- ##### SIGNAL EmpathyContactList::pendings-changed ##### -->
 <para>
 
 </para>
 <para>
 
 </para>
@@ -47,6 +53,9 @@ empathy-contact-list
 @empathycontactlist: the object which received the signal.
 @arg1: 
 @arg2: 
 @empathycontactlist: the object which received the signal.
 @arg1: 
 @arg2: 
+@arg3: 
+@arg4: 
+@arg5: 
 
 <!-- ##### STRUCT EmpathyContactListIface ##### -->
 <para>
 
 <!-- ##### STRUCT EmpathyContactListIface ##### -->
 <para>
@@ -54,57 +63,15 @@ empathy-contact-list
 </para>
 
 @base_iface: 
 </para>
 
 @base_iface: 
-@setup: 
-@find: 
 @add: 
 @remove: 
 @get_members: 
 @add: 
 @remove: 
 @get_members: 
-@get_local_pending: 
-@process_pending: 
-
-<!-- ##### STRUCT EmpathyContactListInfo ##### -->
-<para>
-
-</para>
-
-@contact: 
-@message: 
-
-<!-- ##### FUNCTION empathy_contact_list_info_new ##### -->
-<para>
-
-</para>
-
-@contact: 
-@message: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_contact_list_info_free ##### -->
-<para>
-
-</para>
-
-@info: 
-
-
-<!-- ##### FUNCTION empathy_contact_list_setup ##### -->
-<para>
-
-</para>
-
-@list: 
-
-
-<!-- ##### FUNCTION empathy_contact_list_find ##### -->
-<para>
-
-</para>
-
-@list: 
-@id: 
-@Returns: 
-
+@get_pendings: 
+@get_all_groups: 
+@get_groups: 
+@add_to_group: 
+@remove_from_group: 
+@rename_group: 
 
 <!-- ##### FUNCTION empathy_contact_list_add ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_list_add ##### -->
 <para>
@@ -135,22 +102,3 @@ empathy-contact-list
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_contact_list_get_local_pending ##### -->
-<para>
-
-</para>
-
-@list: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_contact_list_process_pending ##### -->
-<para>
-
-</para>
-
-@list: 
-@contact: 
-@accept: 
-
-
index 0defe4840fbc5159017eaec64fd25613d5cf088e..fe25eb7eb970c4c80f9959dde96ffe1aa0bba05d 100644 (file)
@@ -47,43 +47,3 @@ EmpathyContactManager
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_contact_manager_get_user ##### -->
-<para>
-
-</para>
-
-@manager: 
-@account: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_contact_manager_create ##### -->
-<para>
-
-</para>
-
-@manager: 
-@account: 
-@id: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_contact_manager_rename_group ##### -->
-<para>
-
-</para>
-
-@manager: 
-@old_group: 
-@new_group: 
-
-
-<!-- ##### FUNCTION empathy_contact_manager_get_groups ##### -->
-<para>
-
-</para>
-
-@manager: 
-@Returns: 
-
-
index 1ab2321afc3c22c3f13055940d53a280a4b985e2..861151fb6e920600419385ef8e5cf5e9f249982e 100644 (file)
@@ -33,11 +33,6 @@ EmpathyContact
 
 </para>
 
 
 </para>
 
-<!-- ##### ARG EmpathyContact:groups ##### -->
-<para>
-
-</para>
-
 <!-- ##### ARG EmpathyContact:handle ##### -->
 <para>
 
 <!-- ##### ARG EmpathyContact:handle ##### -->
 <para>
 
@@ -63,29 +58,6 @@ EmpathyContact
 
 </para>
 
 
 </para>
 
-<!-- ##### ARG EmpathyContact:subscription ##### -->
-<para>
-
-</para>
-
-<!-- ##### ENUM EmpathySubscription ##### -->
-<para>
-
-</para>
-
-@EMPATHY_SUBSCRIPTION_NONE: 
-@EMPATHY_SUBSCRIPTION_TO: 
-@EMPATHY_SUBSCRIPTION_FROM: 
-@EMPATHY_SUBSCRIPTION_BOTH: 
-
-<!-- ##### FUNCTION empathy_contact_get_gtype ##### -->
-<para>
-
-</para>
-
-@Returns: 
-
-
 <!-- ##### FUNCTION empathy_contact_new ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_new ##### -->
 <para>
 
@@ -151,24 +123,6 @@ EmpathyContact
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_contact_get_groups ##### -->
-<para>
-
-</para>
-
-@contact: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_contact_get_subscription ##### -->
-<para>
-
-</para>
-
-@contact: 
-@Returns: 
-
-
 <!-- ##### FUNCTION empathy_contact_get_handle ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_get_handle ##### -->
 <para>
 
@@ -232,24 +186,6 @@ EmpathyContact
 @presence: 
 
 
 @presence: 
 
 
-<!-- ##### FUNCTION empathy_contact_set_groups ##### -->
-<para>
-
-</para>
-
-@contact: 
-@categories: 
-
-
-<!-- ##### FUNCTION empathy_contact_set_subscription ##### -->
-<para>
-
-</para>
-
-@contact: 
-@subscription: 
-
-
 <!-- ##### FUNCTION empathy_contact_set_handle ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_set_handle ##### -->
 <para>
 
@@ -268,24 +204,6 @@ EmpathyContact
 @is_user: 
 
 
 @is_user: 
 
 
-<!-- ##### FUNCTION empathy_contact_add_group ##### -->
-<para>
-
-</para>
-
-@contact: 
-@group: 
-
-
-<!-- ##### FUNCTION empathy_contact_remove_group ##### -->
-<para>
-
-</para>
-
-@contact: 
-@group: 
-
-
 <!-- ##### FUNCTION empathy_contact_is_online ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_is_online ##### -->
 <para>
 
@@ -295,16 +213,6 @@ EmpathyContact
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_contact_is_in_group ##### -->
-<para>
-
-</para>
-
-@contact: 
-@group: 
-@Returns: 
-
-
 <!-- ##### FUNCTION empathy_contact_get_status ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_contact_get_status ##### -->
 <para>
 
index 3420151dbbbe4fe09049ffca0f2e5e1c1acc0f02..a3ff09ef1dafeb596d460ba51d1d64420e38ef6b 100644 (file)
@@ -54,61 +54,3 @@ EmpathyTpContactList
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_tp_contact_list_get_user ##### -->
-<para>
-
-</para>
-
-@list: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_tp_contact_list_get_from_id ##### -->
-<para>
-
-</para>
-
-@list: 
-@id: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_tp_contact_list_get_from_handle ##### -->
-<para>
-
-</para>
-
-@list: 
-@handle: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_tp_contact_list_get_from_handles ##### -->
-<para>
-
-</para>
-
-@list: 
-@handles: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_tp_contact_list_rename_group ##### -->
-<para>
-
-</para>
-
-@list: 
-@old_group: 
-@new_group: 
-
-
-<!-- ##### FUNCTION empathy_tp_contact_list_get_groups ##### -->
-<para>
-
-</para>
-
-@list: 
-@Returns: 
-
-
index 988b5d8f6b54a6c79a2959f53a820ae926b9bbd7..6ea6206e4193311f4a80755b42f939819a378a5d 100644 (file)
@@ -29,6 +29,13 @@ EmpathyTpGroup
 </para>
 
 
 </para>
 
 
+<!-- ##### SIGNAL EmpathyTpGroup::destroy ##### -->
+<para>
+
+</para>
+
+@empathytpgroup: the object which received the signal.
+
 <!-- ##### SIGNAL EmpathyTpGroup::local-pending ##### -->
 <para>
 
 <!-- ##### SIGNAL EmpathyTpGroup::local-pending ##### -->
 <para>
 
@@ -40,7 +47,7 @@ EmpathyTpGroup
 @arg3: 
 @arg4: 
 
 @arg3: 
 @arg4: 
 
-<!-- ##### SIGNAL EmpathyTpGroup::members-added ##### -->
+<!-- ##### SIGNAL EmpathyTpGroup::member-added ##### -->
 <para>
 
 </para>
 <para>
 
 </para>
@@ -51,7 +58,7 @@ EmpathyTpGroup
 @arg3: 
 @arg4: 
 
 @arg3: 
 @arg4: 
 
-<!-- ##### SIGNAL EmpathyTpGroup::members-removed ##### -->
+<!-- ##### SIGNAL EmpathyTpGroup::member-removed ##### -->
 <para>
 
 </para>
 <para>
 
 </para>
@@ -73,16 +80,6 @@ EmpathyTpGroup
 @arg3: 
 @arg4: 
 
 @arg3: 
 @arg4: 
 
-<!-- ##### STRUCT EmpathyTpGroupInfo ##### -->
-<para>
-
-</para>
-
-@member: 
-@actor: 
-@reason: 
-@message: 
-
 <!-- ##### FUNCTION empathy_tp_group_new ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_tp_group_new ##### -->
 <para>
 
@@ -99,7 +96,7 @@ EmpathyTpGroup
 </para>
 
 @group: 
 </para>
 
 @group: 
-@handles: 
+@contacts: 
 @message: 
 
 
 @message: 
 
 
@@ -109,7 +106,7 @@ EmpathyTpGroup
 </para>
 
 @group: 
 </para>
 
 @group: 
-@handle
+@contact
 @message: 
 
 
 @message: 
 
 
@@ -119,7 +116,7 @@ EmpathyTpGroup
 </para>
 
 @group: 
 </para>
 
 @group: 
-@handle
+@contacts
 @message: 
 
 
 @message: 
 
 
@@ -129,7 +126,7 @@ EmpathyTpGroup
 </para>
 
 @group: 
 </para>
 
 @group: 
-@handle
+@contact
 @message: 
 
 
 @message: 
 
 
@@ -142,34 +139,6 @@ EmpathyTpGroup
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_tp_group_get_all_members ##### -->
-<para>
-
-</para>
-
-@group: 
-@members: 
-@local_pending: 
-@remote_pending: 
-
-
-<!-- ##### FUNCTION empathy_tp_group_get_local_pending_members_with_info ##### -->
-<para>
-
-</para>
-
-@group: 
-@Returns: 
-
-
-<!-- ##### FUNCTION empathy_tp_group_info_list_free ##### -->
-<para>
-
-</para>
-
-@infos: 
-
-
 <!-- ##### FUNCTION empathy_tp_group_get_name ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_tp_group_get_name ##### -->
 <para>
 
@@ -179,15 +148,6 @@ EmpathyTpGroup
 @Returns: 
 
 
 @Returns: 
 
 
-<!-- ##### FUNCTION empathy_tp_group_get_self_handle ##### -->
-<para>
-
-</para>
-
-@group: 
-@Returns: 
-
-
 <!-- ##### FUNCTION empathy_tp_group_get_object_path ##### -->
 <para>
 
 <!-- ##### FUNCTION empathy_tp_group_get_object_path ##### -->
 <para>
 
@@ -203,7 +163,7 @@ EmpathyTpGroup
 </para>
 
 @group: 
 </para>
 
 @group: 
-@handle
+@contact
 @Returns: 
 
 
 @Returns: 
 
 
index 7d48abf8ade5e55a253d6d8a0b43638747644d7e..c1df38b1503b192799e2970bb03481d57aeb3170 100644 (file)
@@ -34,7 +34,7 @@
 #include <glade/glade.h>
 #include <glib/gi18n.h>
 
 #include <glade/glade.h>
 #include <glib/gi18n.h>
 
-#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-contact-factory.h>
 #include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-log-manager.h>
 #include <libempathy/empathy-chatroom-manager.h>
 #include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-log-manager.h>
 #include <libempathy/empathy-chatroom-manager.h>
@@ -823,17 +823,20 @@ chat_window_update_menu (EmpathyChatWindow *window)
                                                   window);
        } else {
                EmpathyPrivateChat  *chat;
                                                   window);
        } else {
                EmpathyPrivateChat  *chat;
-               EmpathySubscription  subscription;
                EmpathyContact      *contact;
                EmpathyContact      *contact;
+               EmpathyPresence     *presence;
 
                chat = EMPATHY_PRIVATE_CHAT (priv->current_chat);
 
                /* Show / Hide widgets */
                gtk_widget_hide (priv->menu_room);
 
 
                chat = EMPATHY_PRIVATE_CHAT (priv->current_chat);
 
                /* Show / Hide widgets */
                gtk_widget_hide (priv->menu_room);
 
+               /* presence==NULL means this contact refuses to send us his
+                * presence. By adding the contact we ask the contact to accept
+                * to send his presence. */
                contact = empathy_private_chat_get_contact (chat);
                contact = empathy_private_chat_get_contact (chat);
-               subscription = empathy_contact_get_subscription (contact);
-               if (!(subscription & EMPATHY_SUBSCRIPTION_FROM)) {
+               presence = empathy_contact_get_presence (contact);
+               if (!presence) {
                        gtk_widget_show (priv->menu_conv_add_contact);
                } else {
                        gtk_widget_hide (priv->menu_conv_add_contact);
                        gtk_widget_show (priv->menu_conv_add_contact);
                } else {
                        gtk_widget_hide (priv->menu_conv_add_contact);
@@ -1583,12 +1586,13 @@ chat_window_drag_data_received (GtkWidget        *widget,
 {
        /* FIXME: DnD of contact do not seems to work... */
        if (info == DND_DRAG_TYPE_CONTACT_ID) {
 {
        /* FIXME: DnD of contact do not seems to work... */
        if (info == DND_DRAG_TYPE_CONTACT_ID) {
-               EmpathyContactManager *manager;
-               EmpathyContact         *contact;
-               EmpathyChat            *chat;
-               EmpathyChatWindow      *old_window;
+               EmpathyContactFactory *factory;
+               EmpathyContact        *contact = NULL;
+               EmpathyChat           *chat;
+               EmpathyChatWindow     *old_window;
                McAccount             *account;
                const gchar           *id = NULL;
                McAccount             *account;
                const gchar           *id = NULL;
+               gchar                **strv;
 
                if (selection) {
                        id = (const gchar*) selection->data;
 
                if (selection) {
                        id = (const gchar*) selection->data;
@@ -1596,9 +1600,18 @@ chat_window_drag_data_received (GtkWidget        *widget,
 
                empathy_debug (DEBUG_DOMAIN, "DND contact from roster with id:'%s'", id);
                
 
                empathy_debug (DEBUG_DOMAIN, "DND contact from roster with id:'%s'", id);
                
-               manager = empathy_contact_manager_new ();
-               contact = empathy_contact_list_find (EMPATHY_CONTACT_LIST (manager), id);
-               g_object_unref (manager);
+               strv = g_strsplit (id, "/", 2);
+               factory = empathy_contact_factory_new ();
+               account = mc_account_lookup (strv[0]);
+               if (account) {
+                       contact = empathy_contact_factory_get_from_id (factory,
+                                                                      account,
+                                                                      strv[1]);
+                       g_object_unref (account);
+               }
+               g_object_unref (factory);
+               g_object_unref (account);
+               g_strfreev (strv);
 
                if (!contact) {
                        empathy_debug (DEBUG_DOMAIN, "DND contact from roster not found");
 
                if (!contact) {
                        empathy_debug (DEBUG_DOMAIN, "DND contact from roster not found");
index 437e255fa80d0d01c236579216692082f6b0faae..553f85bcc4241ea7ca7f7d6e66504478a4943f1e 100644 (file)
@@ -42,7 +42,7 @@ static GtkWidget *new_contact_dialog = NULL;
 
 
 static gint
 
 
 static gint
-contact_dialogs_find (GtkDialog     *dialog,
+contact_dialogs_find (GtkDialog      *dialog,
                      EmpathyContact *contact)
 {
        GtkWidget     *contact_widget;
                      EmpathyContact *contact)
 {
        GtkWidget     *contact_widget;
@@ -64,18 +64,18 @@ subscription_dialog_response_cb (GtkDialog *dialog,
                                 GtkWidget *contact_widget)
 {
        EmpathyContactManager *manager;
                                 GtkWidget *contact_widget)
 {
        EmpathyContactManager *manager;
-       EmpathyContact         *contact;
+       EmpathyContact        *contact;
 
        manager = empathy_contact_manager_new ();
        contact = empathy_contact_widget_get_contact (contact_widget);
 
        if (response == GTK_RESPONSE_YES) {
 
        manager = empathy_contact_manager_new ();
        contact = empathy_contact_widget_get_contact (contact_widget);
 
        if (response == GTK_RESPONSE_YES) {
-               empathy_contact_list_process_pending (EMPATHY_CONTACT_LIST (manager),
-                                                     contact, TRUE);
+               empathy_contact_list_add (EMPATHY_CONTACT_LIST (manager),
+                                         contact, "");
        }
        else if (response == GTK_RESPONSE_NO) {
        }
        else if (response == GTK_RESPONSE_NO) {
-               empathy_contact_list_process_pending (EMPATHY_CONTACT_LIST (manager),
-                                                     contact, FALSE);
+               empathy_contact_list_remove (EMPATHY_CONTACT_LIST (manager),
+                                            contact, "");
        }
 
        subscription_dialogs = g_list_remove (subscription_dialogs, dialog);
        }
 
        subscription_dialogs = g_list_remove (subscription_dialogs, dialog);
index ac2fa62cd3e70e4e60bd2275171df5b048602282..9cf03bfe853508ae51c9bf3d6d9bb5b4fb5d4259 100644 (file)
@@ -57,10 +57,10 @@ struct _EmpathyContactListStorePriv {
        gboolean                    show_avatars;
        gboolean                    is_compact;
        gboolean                    show_active;
        gboolean                    show_avatars;
        gboolean                    is_compact;
        gboolean                    show_active;
-       EmpathyContactListStoreSort  sort_criterium;
+       EmpathyContactListStoreSort sort_criterium;
        guint                       inhibit_active;
 
        guint                       inhibit_active;
 
-       EmpathyContactGroupsFunc     get_contact_groups;
+       EmpathyContactGroupsFunc    get_contact_groups;
        gpointer                    get_contact_groups_data;
 };
 
        gpointer                    get_contact_groups_data;
 };
 
@@ -84,71 +84,74 @@ typedef struct {
 
 static void             empathy_contact_list_store_class_init         (EmpathyContactListStoreClass *klass);
 static void             empathy_contact_list_store_init               (EmpathyContactListStore      *list);
 
 static void             empathy_contact_list_store_class_init         (EmpathyContactListStoreClass *klass);
 static void             empathy_contact_list_store_init               (EmpathyContactListStore      *list);
-static void             contact_list_store_finalize                  (GObject                     *object);
-static void             contact_list_store_get_property              (GObject                     *object,
-                                                                     guint                        param_id,
-                                                                     GValue                      *value,
-                                                                     GParamSpec                  *pspec);
-static void             contact_list_store_set_property              (GObject                     *object,
-                                                                     guint                        param_id,
-                                                                     const GValue                *value,
-                                                                     GParamSpec                  *pspec);
-static void             contact_list_store_setup                     (EmpathyContactListStore      *store);
-static gboolean         contact_list_store_inibit_active_cb          (EmpathyContactListStore      *store);
-static void             contact_list_store_contact_added_cb          (EmpathyContactList          *list_iface,
-                                                                     EmpathyContact               *contact,
-                                                                     EmpathyContactListStore      *store);
-static void             contact_list_store_add_contact               (EmpathyContactListStore      *store,
-                                                                     EmpathyContact               *contact);
-static void             contact_list_store_contact_removed_cb        (EmpathyContactList          *list_iface,
-                                                                     EmpathyContact               *contact,
-                                                                     EmpathyContactListStore      *store);
-static void             contact_list_store_remove_contact            (EmpathyContactListStore      *store,
-                                                                     EmpathyContact               *contact);
-static void             contact_list_store_contact_update            (EmpathyContactListStore      *store,
-                                                                     EmpathyContact               *contact);
-static void             contact_list_store_contact_groups_updated_cb (EmpathyContact               *contact,
-                                                                     GParamSpec                  *param,
-                                                                     EmpathyContactListStore      *store);
-static void             contact_list_store_contact_updated_cb        (EmpathyContact               *contact,
-                                                                     GParamSpec                  *param,
-                                                                     EmpathyContactListStore      *store);
-static void             contact_list_store_contact_set_active        (EmpathyContactListStore      *store,
-                                                                     EmpathyContact               *contact,
-                                                                     gboolean                     active,
-                                                                     gboolean                     set_changed);
-static ShowActiveData * contact_list_store_contact_active_new        (EmpathyContactListStore      *store,
-                                                                     EmpathyContact               *contact,
-                                                                     gboolean                     remove);
-static void             contact_list_store_contact_active_free       (ShowActiveData              *data);
-static gboolean         contact_list_store_contact_active_cb         (ShowActiveData              *data);
-static gboolean         contact_list_store_get_group_foreach         (GtkTreeModel                *model,
-                                                                     GtkTreePath                 *path,
-                                                                     GtkTreeIter                 *iter,
-                                                                     FindGroup                   *fg);
-static void             contact_list_store_get_group                 (EmpathyContactListStore      *store,
-                                                                     const gchar                 *name,
-                                                                     GtkTreeIter                 *iter_group_to_set,
-                                                                     GtkTreeIter                 *iter_separator_to_set,
-                                                                     gboolean                    *created);
-static gint             contact_list_store_state_sort_func           (GtkTreeModel                *model,
-                                                                     GtkTreeIter                 *iter_a,
-                                                                     GtkTreeIter                 *iter_b,
-                                                                     gpointer                     user_data);
-static gint             contact_list_store_name_sort_func            (GtkTreeModel                *model,
-                                                                     GtkTreeIter                 *iter_a,
-                                                                     GtkTreeIter                 *iter_b,
-                                                                     gpointer                     user_data);
-static gboolean         contact_list_store_find_contact_foreach      (GtkTreeModel                *model,
-                                                                     GtkTreePath                 *path,
-                                                                     GtkTreeIter                 *iter,
-                                                                     FindContact                 *fc);
-static GList *          contact_list_store_find_contact              (EmpathyContactListStore      *store,
-                                                                     EmpathyContact               *contact);
-static gboolean         contact_list_store_update_list_mode_foreach  (GtkTreeModel                *model,
-                                                                     GtkTreePath                 *path,
-                                                                     GtkTreeIter                 *iter,
-                                                                     EmpathyContactListStore      *store);
+static void             contact_list_store_finalize                  (GObject                       *object);
+static void             contact_list_store_get_property              (GObject                       *object,
+                                                                     guint                          param_id,
+                                                                     GValue                        *value,
+                                                                     GParamSpec                    *pspec);
+static void             contact_list_store_set_property              (GObject                       *object,
+                                                                     guint                          param_id,
+                                                                     const GValue                  *value,
+                                                                     GParamSpec                    *pspec);
+static void             contact_list_store_setup                     (EmpathyContactListStore       *store);
+static gboolean         contact_list_store_inibit_active_cb          (EmpathyContactListStore       *store);
+static void             contact_list_store_members_changed_cb        (EmpathyContactList            *list_iface,
+                                                                     EmpathyContact                *contact,
+                                                                     EmpathyContact                *actor,
+                                                                     guint                          reason,
+                                                                     gchar                         *message,
+                                                                     gboolean                       is_member,
+                                                                     EmpathyContactListStore       *store);
+static void             contact_list_store_groups_changed_cb         (EmpathyContactList            *list_iface,
+                                                                     EmpathyContact                *contact,
+                                                                     gchar                         *group,
+                                                                     gboolean                       is_member,
+                                                                     EmpathyContactListStore       *store);
+static void             contact_list_store_add_contact               (EmpathyContactListStore       *store,
+                                                                     EmpathyContact                *contact);
+static void             contact_list_store_remove_contact            (EmpathyContactListStore       *store,
+                                                                     EmpathyContact                *contact);
+static void             contact_list_store_contact_update            (EmpathyContactListStore       *store,
+                                                                     EmpathyContact                *contact);
+static void             contact_list_store_contact_updated_cb        (EmpathyContact                *contact,
+                                                                     GParamSpec                    *param,
+                                                                     EmpathyContactListStore       *store);
+static void             contact_list_store_contact_set_active        (EmpathyContactListStore       *store,
+                                                                     EmpathyContact                *contact,
+                                                                     gboolean                       active,
+                                                                     gboolean                       set_changed);
+static ShowActiveData * contact_list_store_contact_active_new        (EmpathyContactListStore       *store,
+                                                                     EmpathyContact                *contact,
+                                                                     gboolean                       remove);
+static void             contact_list_store_contact_active_free       (ShowActiveData                *data);
+static gboolean         contact_list_store_contact_active_cb         (ShowActiveData                *data);
+static gboolean         contact_list_store_get_group_foreach         (GtkTreeModel                  *model,
+                                                                     GtkTreePath                   *path,
+                                                                     GtkTreeIter                   *iter,
+                                                                     FindGroup                     *fg);
+static void             contact_list_store_get_group                 (EmpathyContactListStore       *store,
+                                                                     const gchar                   *name,
+                                                                     GtkTreeIter                   *iter_group_to_set,
+                                                                     GtkTreeIter                   *iter_separator_to_set,
+                                                                     gboolean                      *created);
+static gint             contact_list_store_state_sort_func           (GtkTreeModel                  *model,
+                                                                     GtkTreeIter                   *iter_a,
+                                                                     GtkTreeIter                   *iter_b,
+                                                                     gpointer                       user_data);
+static gint             contact_list_store_name_sort_func            (GtkTreeModel                  *model,
+                                                                     GtkTreeIter                   *iter_a,
+                                                                     GtkTreeIter                   *iter_b,
+                                                                     gpointer                       user_data);
+static gboolean         contact_list_store_find_contact_foreach      (GtkTreeModel                  *model,
+                                                                     GtkTreePath                   *path,
+                                                                     GtkTreeIter                   *iter,
+                                                                     FindContact                   *fc);
+static GList *          contact_list_store_find_contact              (EmpathyContactListStore       *store,
+                                                                     EmpathyContact                *contact);
+static gboolean         contact_list_store_update_list_mode_foreach  (GtkTreeModel                  *model,
+                                                                     GtkTreePath                   *path,
+                                                                     GtkTreeIter                   *iter,
+                                                                     EmpathyContactListStore       *store);
 
 enum {
        PROP_0,
 
 enum {
        PROP_0,
@@ -317,24 +320,23 @@ empathy_contact_list_store_new (EmpathyContactList *list_iface)
 
        /* Signal connection. */
        g_signal_connect (priv->list,
 
        /* Signal connection. */
        g_signal_connect (priv->list,
-                         "contact-added",
-                         G_CALLBACK (contact_list_store_contact_added_cb),
+                         "members-changed",
+                         G_CALLBACK (contact_list_store_members_changed_cb),
                          store);
        g_signal_connect (priv->list,
                          store);
        g_signal_connect (priv->list,
-                         "contact-removed",
-                         G_CALLBACK (contact_list_store_contact_removed_cb),
+                         "groups-changed",
+                         G_CALLBACK (contact_list_store_groups_changed_cb),
                          store);
 
        /* Add contacts already created. */
        contacts = empathy_contact_list_get_members (priv->list);
        for (l = contacts; l; l = l->next) {
                          store);
 
        /* Add contacts already created. */
        contacts = empathy_contact_list_get_members (priv->list);
        for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact;
+               contact_list_store_members_changed_cb (priv->list, l->data,
+                                                      NULL, 0, NULL,
+                                                      TRUE,
+                                                      store);
 
 
-               contact = l->data;
-
-               contact_list_store_contact_added_cb (priv->list, contact, store);
-
-               g_object_unref (contact);
+               g_object_unref (l->data);
        }
        g_list_free (contacts);
 
        }
        g_list_free (contacts);
 
@@ -385,13 +387,9 @@ empathy_contact_list_store_set_show_offline (EmpathyContactListStore *store,
 
        contacts = empathy_contact_list_get_members (priv->list);
        for (l = contacts; l; l = l->next) {
 
        contacts = empathy_contact_list_get_members (priv->list);
        for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact;
-
-               contact = EMPATHY_CONTACT (l->data);
-
-               contact_list_store_contact_update (store, contact);
+               contact_list_store_contact_update (store, l->data);
 
 
-               g_object_unref (contact);
+               g_object_unref (l->data);
        }
        g_list_free (contacts);
 
        }
        g_list_free (contacts);
 
@@ -611,80 +609,6 @@ empathy_contact_list_store_search_equal_func (GtkTreeModel *model,
        return ret;
 }
 
        return ret;
 }
 
-void
-empathy_contact_list_store_set_contact_groups_func (EmpathyContactListStore  *store,
-                                                  EmpathyContactGroupsFunc  func,
-                                                  gpointer                 user_data)
-{
-       EmpathyContactListStorePriv *priv;
-       GList                      *contacts, *l;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_LIST_STORE (store));
-
-       priv = GET_PRIV (store);
-
-       if (func) {
-               priv->get_contact_groups = func;
-               priv->get_contact_groups_data = user_data;
-       } else {
-               priv->get_contact_groups = NULL;
-               priv->get_contact_groups_data = NULL;
-       }
-
-       /* If we set a custom function to get contacts groups  we have to
-        * disconnect our default notify::groups signal and wait for the user
-        * to call himself empathy_contact_list_store_update_contact_groups ()
-        * when needed. If func is NULL we come back to default.
-        */
-       contacts = empathy_contact_list_get_members (priv->list);
-       for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact;
-
-               contact = l->data;
-
-               if (func) {
-                       g_signal_handlers_disconnect_by_func (contact, 
-                                                             G_CALLBACK (contact_list_store_contact_groups_updated_cb),
-                                                             store);
-               } else {
-                       g_signal_connect (contact, "notify::groups",
-                                         G_CALLBACK (contact_list_store_contact_groups_updated_cb),
-                                         store);
-               }
-
-               empathy_contact_list_store_update_contact_groups (store, contact);
-
-               g_object_unref (contact);
-       }
-       g_list_free (contacts);
-}
-
-void
-empathy_contact_list_store_update_contact_groups (EmpathyContactListStore *store,
-                                                EmpathyContact          *contact)
-{
-       EmpathyContactListStorePriv *priv;
-       gboolean                    show_active;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_LIST_STORE (store));
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-       priv = GET_PRIV (store);
-
-       empathy_debug (DEBUG_DOMAIN, "Contact:'%s' updating groups",
-                     empathy_contact_get_name (contact));
-
-       /* We do this to make sure the groups are correct, if not, we
-        * would have to check the groups already set up for each
-        * contact and then see what has been updated.
-        */
-       show_active = priv->show_active;
-       priv->show_active = FALSE;
-       contact_list_store_remove_contact (store, contact);
-       contact_list_store_add_contact (store, contact);
-       priv->show_active = show_active;
-}
-
 static void
 contact_list_store_setup (EmpathyContactListStore *store)
 {
 static void
 contact_list_store_setup (EmpathyContactListStore *store)
 {
@@ -733,37 +657,73 @@ contact_list_store_inibit_active_cb (EmpathyContactListStore *store)
 }
 
 static void
 }
 
 static void
-contact_list_store_contact_added_cb (EmpathyContactList     *list_iface,
-                                    EmpathyContact          *contact,
-                                    EmpathyContactListStore *store)
+contact_list_store_members_changed_cb (EmpathyContactList      *list_iface,
+                                      EmpathyContact          *contact,
+                                      EmpathyContact          *actor,
+                                      guint                    reason,
+                                      gchar                   *message,
+                                      gboolean                 is_member,
+                                      EmpathyContactListStore *store)
 {
        EmpathyContactListStorePriv *priv;
 
        priv = GET_PRIV (store);
 
        empathy_debug (DEBUG_DOMAIN, 
 {
        EmpathyContactListStorePriv *priv;
 
        priv = GET_PRIV (store);
 
        empathy_debug (DEBUG_DOMAIN, 
-                     "Contact:'%s' added",
-                     empathy_contact_get_name (contact));
-
-       if (!priv->get_contact_groups) {
-               g_signal_connect (contact, "notify::groups",
-                                 G_CALLBACK (contact_list_store_contact_groups_updated_cb),
+                     "Contact %s (%d) %s",
+                     empathy_contact_get_id (contact),
+                     empathy_contact_get_handle (contact),
+                     is_member ? "added" : "removed");
+
+       if (is_member) {
+               g_signal_connect (contact, "notify::presence",
+                                 G_CALLBACK (contact_list_store_contact_updated_cb),
+                                 store);
+               g_signal_connect (contact, "notify::name",
+                                 G_CALLBACK (contact_list_store_contact_updated_cb),
                                  store);
                                  store);
+               g_signal_connect (contact, "notify::avatar",
+                                 G_CALLBACK (contact_list_store_contact_updated_cb),
+                                 store);
+               g_signal_connect (contact, "notify::type",
+                                 G_CALLBACK (contact_list_store_contact_updated_cb),
+                                 store);
+
+               contact_list_store_add_contact (store, contact);
+       } else {
+               g_signal_handlers_disconnect_by_func (contact,
+                                                     G_CALLBACK (contact_list_store_contact_updated_cb),
+                                                     store);
+
+               contact_list_store_remove_contact (store, contact);
        }
        }
-       g_signal_connect (contact, "notify::presence",
-                         G_CALLBACK (contact_list_store_contact_updated_cb),
-                         store);
-       g_signal_connect (contact, "notify::name",
-                         G_CALLBACK (contact_list_store_contact_updated_cb),
-                         store);
-       g_signal_connect (contact, "notify::avatar",
-                         G_CALLBACK (contact_list_store_contact_updated_cb),
-                         store);
-       g_signal_connect (contact, "notify::type",
-                         G_CALLBACK (contact_list_store_contact_updated_cb),
-                         store);
+}
 
 
+static void
+contact_list_store_groups_changed_cb (EmpathyContactList      *list_iface,
+                                     EmpathyContact          *contact,
+                                     gchar                   *group,
+                                     gboolean                 is_member,
+                                     EmpathyContactListStore *store)
+{
+       EmpathyContactListStorePriv *priv;
+       gboolean                     show_active;
+
+       priv = GET_PRIV (store);
+
+       empathy_debug (DEBUG_DOMAIN, "Updating groups for contact %s (%d)",
+                     empathy_contact_get_id (contact),
+                     empathy_contact_get_handle (contact));
+
+       /* We do this to make sure the groups are correct, if not, we
+        * would have to check the groups already set up for each
+        * contact and then see what has been updated.
+        */
+       show_active = priv->show_active;
+       priv->show_active = FALSE;
+       contact_list_store_remove_contact (store, contact);
        contact_list_store_add_contact (store, contact);
        contact_list_store_add_contact (store, contact);
+       priv->show_active = show_active;
 }
 
 static void
 }
 
 static void
@@ -780,14 +740,9 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
                return;
        }
 
                return;
        }
 
-       /* If no groups just add it at the top level. */
-       if (priv->get_contact_groups) {
-               groups = priv->get_contact_groups (contact,
-                                                  priv->get_contact_groups_data);
-       } else {
-               groups = empathy_contact_get_groups (contact);
-       }
+       groups = empathy_contact_list_get_groups (priv->list, contact);
 
 
+       /* If no groups just add it at the top level. */
        if (!groups) {
                gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
                gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
        if (!groups) {
                gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
                gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
@@ -800,15 +755,9 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
 
        /* Else add to each group. */
        for (l = groups; l; l = l->next) {
 
        /* Else add to each group. */
        for (l = groups; l; l = l->next) {
-               GtkTreeIter  iter_group;
-               const gchar *name;
-
-               name = l->data;
-               if (!name) {
-                       continue;
-               }
+               GtkTreeIter iter_group;
 
 
-               contact_list_store_get_group (store, name, &iter_group, NULL, NULL);
+               contact_list_store_get_group (store, l->data, &iter_group, NULL, NULL);
 
                gtk_tree_store_insert_after (GTK_TREE_STORE (store), &iter,
                                             &iter_group, NULL);
 
                gtk_tree_store_insert_after (GTK_TREE_STORE (store), &iter,
                                             &iter_group, NULL);
@@ -818,28 +767,12 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
                                    COL_IS_GROUP, FALSE,
                                    COL_IS_SEPARATOR, FALSE,
                                    -1);
                                    COL_IS_GROUP, FALSE,
                                    COL_IS_SEPARATOR, FALSE,
                                    -1);
+               g_free (l->data);
        }
        }
+       g_list_free (groups);
 
        contact_list_store_contact_update (store, contact);
 
        contact_list_store_contact_update (store, contact);
-}
-
-static void
-contact_list_store_contact_removed_cb (EmpathyContactList     *list_iface,
-                                      EmpathyContact          *contact,
-                                      EmpathyContactListStore *store)
-{
-       empathy_debug (DEBUG_DOMAIN, "Contact:'%s' removed",
-                     empathy_contact_get_name (contact));
-
-       /* Disconnect signals */
-       g_signal_handlers_disconnect_by_func (contact, 
-                                             G_CALLBACK (contact_list_store_contact_groups_updated_cb),
-                                             store);
-       g_signal_handlers_disconnect_by_func (contact,
-                                             G_CALLBACK (contact_list_store_contact_updated_cb),
-                                             store);
 
 
-       contact_list_store_remove_contact (store, contact);
 }
 
 static void
 }
 
 static void
@@ -1028,17 +961,9 @@ contact_list_store_contact_update (EmpathyContactListStore *store,
        g_list_free (iters);
 }
 
        g_list_free (iters);
 }
 
-static void
-contact_list_store_contact_groups_updated_cb (EmpathyContact          *contact,
-                                             GParamSpec             *param,
-                                             EmpathyContactListStore *store)
-{
-       empathy_contact_list_store_update_contact_groups (store, contact);
-}
-
 static void
 contact_list_store_contact_updated_cb (EmpathyContact          *contact,
 static void
 contact_list_store_contact_updated_cb (EmpathyContact          *contact,
-                                      GParamSpec             *param,
+                                      GParamSpec              *param,
                                       EmpathyContactListStore *store)
 {
        empathy_debug (DEBUG_DOMAIN,
                                       EmpathyContactListStore *store)
 {
        empathy_debug (DEBUG_DOMAIN,
@@ -1180,10 +1105,10 @@ contact_list_store_get_group (EmpathyContactListStore *store,
                              gboolean               *created)
 {
        EmpathyContactListStorePriv *priv;
                              gboolean               *created)
 {
        EmpathyContactListStorePriv *priv;
-       GtkTreeModel               *model;
-       GtkTreeIter                 iter_group;
-       GtkTreeIter                 iter_separator;
-       FindGroup                   fg;
+       GtkTreeModel                *model;
+       GtkTreeIter                  iter_group;
+       GtkTreeIter                  iter_separator;
+       FindGroup                    fg;
 
        priv = GET_PRIV (store);
 
 
        priv = GET_PRIV (store);
 
index d7c9635f5bf2c51440a86bf739b2c1bd6d37a1e8..d096daafd1d8d313a032ff71ba161b38788123f4 100644 (file)
@@ -106,11 +106,6 @@ gboolean                   empathy_contact_list_store_search_equal_func  (GtkTre
                                                                         const gchar                *key,
                                                                         GtkTreeIter                *iter,
                                                                         gpointer                    search_data);
                                                                         const gchar                *key,
                                                                         GtkTreeIter                *iter,
                                                                         gpointer                    search_data);
-void                       empathy_contact_list_store_set_contact_groups_func (EmpathyContactListStore*store,
-                                                                        EmpathyContactGroupsFunc     func,
-                                                                        gpointer                    user_data);
-void                       empathy_contact_list_store_update_contact_groups (EmpathyContactListStore  *store,
-                                                                        EmpathyContact              *contact);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
index 2a5cf3406c107d24edea38045ccbda31e2094cef..5b3f0de08283ff09512fdd5b6b0adb013de86592 100644 (file)
@@ -34,7 +34,7 @@
 #include <libmissioncontrol/mc-account.h>
 #include <libmissioncontrol/mission-control.h>
 
 #include <libmissioncontrol/mc-account.h>
 #include <libmissioncontrol/mission-control.h>
 
-#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-contact-factory.h>
 #include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-log-manager.h>
 #include <libempathy/empathy-debug.h>
 #include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-log-manager.h>
 #include <libempathy/empathy-debug.h>
 
 struct _EmpathyContactListViewPriv {
        EmpathyContactListStore *store;
 
 struct _EmpathyContactListViewPriv {
        EmpathyContactListStore *store;
-       GtkUIManager           *ui;
-       GtkTreeRowReference    *drag_row;
-       GtkTreeModel           *filter;
-       gchar                  *filter_text;
-
-       EmpathyContactListViewDragReceivedFunc drag_received;
-       gpointer                              drag_received_data;
+       GtkUIManager            *ui;
+       GtkTreeRowReference     *drag_row;
 };
 
 typedef struct {
 };
 
 typedef struct {
@@ -103,11 +98,6 @@ static void        contact_list_view_row_has_child_toggled_cb  (GtkTreeModel
                                                                GtkTreePath                *path,
                                                                GtkTreeIter                *iter,
                                                                EmpathyContactListView      *view);
                                                                GtkTreePath                *path,
                                                                GtkTreeIter                *iter,
                                                                EmpathyContactListView      *view);
-static void        contact_list_view_contact_received          (EmpathyContactListView      *view,
-                                                               EmpathyContact              *contact,
-                                                               GdkDragAction               action,
-                                                               const gchar                *old_group,
-                                                               const gchar                *new_group);
 static void        contact_list_view_drag_data_received        (GtkWidget                  *widget,
                                                                GdkDragContext             *context,
                                                                gint                        x,
 static void        contact_list_view_drag_data_received        (GtkWidget                  *widget,
                                                                GdkDragContext             *context,
                                                                gint                        x,
@@ -173,14 +163,6 @@ static void        contact_list_view_row_expand_or_collapse_cb (EmpathyContactLi
                                                                GtkTreeIter                *iter,
                                                                GtkTreePath                *path,
                                                                gpointer                    user_data);
                                                                GtkTreeIter                *iter,
                                                                GtkTreePath                *path,
                                                                gpointer                    user_data);
-static gboolean    contact_list_view_filter_show_contact       (EmpathyContact              *contact,
-                                                               const gchar                *filter);
-static gboolean    contact_list_view_filter_show_group         (EmpathyContactListView      *view,
-                                                               const gchar                *group,
-                                                               const gchar                *filter);
-static gboolean    contact_list_view_filter_func               (GtkTreeModel               *model,
-                                                               GtkTreeIter                *iter,
-                                                               EmpathyContactListView      *view);
 static void        contact_list_view_action_cb                 (GtkAction                  *action,
                                                                EmpathyContactListView      *view);
 static void        contact_list_view_action_activated          (EmpathyContactListView      *view,
 static void        contact_list_view_action_cb                 (GtkAction                  *action,
                                                                EmpathyContactListView      *view);
 static void        contact_list_view_action_activated          (EmpathyContactListView      *view,
@@ -188,7 +170,6 @@ static void        contact_list_view_action_activated          (EmpathyContactLi
 
 enum {
        PROP_0,
 
 enum {
        PROP_0,
-       PROP_FILTER,
 };
 
 static const GtkActionEntry entries[] = {
 };
 
 static const GtkActionEntry entries[] = {
@@ -315,14 +296,6 @@ empathy_contact_list_view_class_init (EmpathyContactListViewClass *klass)
                              G_TYPE_NONE,
                              3, EMPATHY_TYPE_CONTACT, G_TYPE_STRING, G_TYPE_STRING);
 
                              G_TYPE_NONE,
                              3, EMPATHY_TYPE_CONTACT, G_TYPE_STRING, G_TYPE_STRING);
 
-       g_object_class_install_property (object_class,
-                                        PROP_FILTER,
-                                        g_param_spec_string ("filter",
-                                                             "Filter",
-                                                             "The text to use to filter the contact list",
-                                                             NULL,
-                                                             G_PARAM_READWRITE));
-
        g_type_class_add_private (object_class, sizeof (EmpathyContactListViewPriv));
 }
 
        g_type_class_add_private (object_class, sizeof (EmpathyContactListViewPriv));
 }
 
@@ -389,10 +362,6 @@ contact_list_view_finalize (GObject *object)
        if (priv->store) {
                g_object_unref (priv->store);
        }
        if (priv->store) {
                g_object_unref (priv->store);
        }
-       if (priv->filter) {
-               g_object_unref (priv->filter);
-       }
-       g_free (priv->filter_text);
 
        G_OBJECT_CLASS (empathy_contact_list_view_parent_class)->finalize (object);
 }
 
        G_OBJECT_CLASS (empathy_contact_list_view_parent_class)->finalize (object);
 }
@@ -408,9 +377,6 @@ contact_list_view_get_property (GObject    *object,
        priv = GET_PRIV (object);
 
        switch (param_id) {
        priv = GET_PRIV (object);
 
        switch (param_id) {
-       case PROP_FILTER:
-               g_value_set_string (value, priv->filter_text);
-               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
                break;
@@ -428,10 +394,6 @@ contact_list_view_set_property (GObject      *object,
        priv = GET_PRIV (object);
 
        switch (param_id) {
        priv = GET_PRIV (object);
 
        switch (param_id) {
-       case PROP_FILTER:
-               empathy_contact_list_view_set_filter (EMPATHY_CONTACT_LIST_VIEW (object),
-                                               g_value_get_string (value));
-               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
                break;
@@ -547,47 +509,6 @@ empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view,
                                                   can_show_log);
 }
 
                                                   can_show_log);
 }
 
-void
-empathy_contact_list_view_set_filter (EmpathyContactListView *view,
-                                    const gchar           *filter)
-{
-       EmpathyContactListViewPriv *priv;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view));
-
-       priv = GET_PRIV (view);
-
-       g_free (priv->filter_text);
-       if (filter) {
-               priv->filter_text = g_utf8_casefold (filter, -1);
-       } else {
-               priv->filter_text = NULL;
-       }
-
-       empathy_debug (DEBUG_DOMAIN, "Refiltering with filter:'%s' (case folded)", filter);
-       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
-}
-
-void
-empathy_contact_list_view_set_drag_received_func (EmpathyContactListView                 *view,
-                                                EmpathyContactListViewDragReceivedFunc  func,
-                                                gpointer                               user_data)
-{
-       EmpathyContactListViewPriv *priv;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view));
-
-       priv = GET_PRIV (view);
-
-       if (func) {
-               priv->drag_received = func;
-               priv->drag_received_data = user_data;
-       } else {
-               priv->drag_received = NULL;
-               priv->drag_received_data = NULL;
-       }
-}
-
 static void
 contact_list_view_setup (EmpathyContactListView *view)
 {
 static void
 contact_list_view_setup (EmpathyContactListView *view)
 {
@@ -598,21 +519,11 @@ contact_list_view_setup (EmpathyContactListView *view)
 
        priv = GET_PRIV (view);
 
 
        priv = GET_PRIV (view);
 
-       /* Create filter */
-       priv->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->store), NULL);
-
-       gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->filter),
-                                               (GtkTreeModelFilterVisibleFunc)
-                                               contact_list_view_filter_func,
-                                               view, NULL);
-       gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (view),
-                                            empathy_contact_list_store_search_equal_func,
-                                            view, NULL);
-       g_signal_connect (priv->filter, "row-has-child-toggled",
+       g_signal_connect (priv->store, "row-has-child-toggled",
                          G_CALLBACK (contact_list_view_row_has_child_toggled_cb),
                          view);
                          G_CALLBACK (contact_list_view_row_has_child_toggled_cb),
                          view);
-       gtk_tree_view_set_model (GTK_TREE_VIEW (view), priv->filter);
-
+       gtk_tree_view_set_model (GTK_TREE_VIEW (view),
+                                GTK_TREE_MODEL (priv->store));
 
        /* Setup view */
        g_object_set (view,
 
        /* Setup view */
        g_object_set (view,
@@ -697,13 +608,13 @@ contact_list_view_setup (EmpathyContactListView *view)
                             GDK_BUTTON1_MASK,
                             drag_types_source,
                             G_N_ELEMENTS (drag_types_source),
                             GDK_BUTTON1_MASK,
                             drag_types_source,
                             G_N_ELEMENTS (drag_types_source),
-                            GDK_ACTION_MOVE);
+                            GDK_ACTION_MOVE | GDK_ACTION_COPY);
 
        gtk_drag_dest_set (GTK_WIDGET (view),
                           GTK_DEST_DEFAULT_ALL,
                           drag_types_dest,
                           G_N_ELEMENTS (drag_types_dest),
 
        gtk_drag_dest_set (GTK_WIDGET (view),
                           GTK_DEST_DEFAULT_ALL,
                           drag_types_dest,
                           G_N_ELEMENTS (drag_types_dest),
-                          GDK_ACTION_MOVE | GDK_ACTION_LINK);
+                          GDK_ACTION_MOVE | GDK_ACTION_COPY);
 }
 
 static void
 }
 
 static void
@@ -746,46 +657,6 @@ contact_list_view_row_has_child_toggled_cb (GtkTreeModel          *model,
        g_free (name);
 }
 
        g_free (name);
 }
 
-static void
-contact_list_view_contact_received (EmpathyContactListView *view,
-                                   EmpathyContact         *contact,
-                                   GdkDragAction          action,
-                                   const gchar           *old_group,
-                                   const gchar           *new_group)
-{
-       EmpathyContactListViewPriv *priv;
-       GList                     *groups, *l;
-       GList                     *new_groups_list = NULL;
-
-       priv = GET_PRIV (view);
-
-       groups = empathy_contact_get_groups (contact);
-       for (l = groups; l; l = l->next) {
-               gchar *str;
-
-               str = l->data;
-
-               if (action == GDK_ACTION_MOVE &&
-                   old_group != NULL &&
-                   strcmp (str, old_group) == 0) {
-                       continue;
-               }
-
-               if (new_group && strcmp (str, new_group) == 0) {
-                       /* Otherwise we set it twice */
-                       continue;
-               }
-
-               new_groups_list = g_list_prepend (new_groups_list, g_strdup (str));
-       }
-
-       if (new_group) {
-               new_groups_list = g_list_prepend (new_groups_list, g_strdup (new_group));
-       }
-
-       empathy_contact_set_groups (contact, new_groups_list);
-}
-
 static void
 contact_list_view_drag_data_received (GtkWidget         *widget,
                                      GdkDragContext    *context,
 static void
 contact_list_view_drag_data_received (GtkWidget         *widget,
                                      GdkDragContext    *context,
@@ -796,15 +667,18 @@ contact_list_view_drag_data_received (GtkWidget         *widget,
                                      guint              time)
 {
        EmpathyContactListViewPriv *priv;
                                      guint              time)
 {
        EmpathyContactListViewPriv *priv;
-       EmpathyContactList        *list;
-       GtkTreeModel              *model;
-       GtkTreePath               *path;
-       GtkTreeViewDropPosition    position;
-       EmpathyContact             *contact;
-       const gchar               *id;
-       gchar                     *new_group = NULL;
-       gchar                     *old_group = NULL;
-       gboolean                   is_row;
+       EmpathyContactList         *list;
+       EmpathyContactFactory      *factory;
+       McAccount                  *account;
+       GtkTreeModel               *model;
+       GtkTreePath                *path;
+       GtkTreeViewDropPosition     position;
+       EmpathyContact             *contact = NULL;
+       const gchar                *id;
+       gchar                     **strv;
+       gchar                      *new_group = NULL;
+       gchar                      *old_group = NULL;
+       gboolean                    is_row;
 
        priv = GET_PRIV (widget);
 
 
        priv = GET_PRIV (widget);
 
@@ -814,9 +688,18 @@ contact_list_view_drag_data_received (GtkWidget         *widget,
                      context->action == GDK_ACTION_COPY ? "copy" : "",
                      id);
 
                      context->action == GDK_ACTION_COPY ? "copy" : "",
                      id);
 
-       /* FIXME: This is ambigous, an id can come from multiple accounts */
-       list = empathy_contact_list_store_get_list_iface (priv->store);
-       contact = empathy_contact_list_find (list, id);
+       strv = g_strsplit (id, "/", 2);
+       factory = empathy_contact_factory_new ();
+       account = mc_account_lookup (strv[0]);
+       if (account) {
+               contact = empathy_contact_factory_get_from_id (factory,
+                                                              account,
+                                                              strv[1]);
+               g_object_unref (account);
+       }
+       g_object_unref (factory);
+       g_object_unref (account);
+       g_strfreev (strv);
 
        if (!contact) {
                empathy_debug (DEBUG_DOMAIN, "No contact found associated with drag & drop");
 
        if (!contact) {
                empathy_debug (DEBUG_DOMAIN, "No contact found associated with drag & drop");
@@ -847,22 +730,17 @@ contact_list_view_drag_data_received (GtkWidget         *widget,
        }
 
        empathy_debug (DEBUG_DOMAIN,
        }
 
        empathy_debug (DEBUG_DOMAIN,
-                     "contact '%s' dragged from '%s' to '%s'",
-                     empathy_contact_get_name (contact),
+                     "contact %s (%d) dragged from '%s' to '%s'",
+                     empathy_contact_get_id (contact),
+                     empathy_contact_get_handle (contact),
                      old_group, new_group);
 
                      old_group, new_group);
 
-       if (priv->drag_received) {
-               priv->drag_received (contact,
-                                    context->action,
-                                    old_group,
-                                    new_group,
-                                    priv->drag_received_data);
-       } else {
-               contact_list_view_contact_received (EMPATHY_CONTACT_LIST_VIEW (widget),
-                                                   contact,
-                                                   context->action,
-                                                   old_group,
-                                                   new_group);
+       list = empathy_contact_list_store_get_list_iface (priv->store);
+       if (new_group) {
+               empathy_contact_list_add_to_group (list, contact, new_group);
+       }
+       if (old_group && context->action == GDK_ACTION_MOVE) {  
+               empathy_contact_list_remove_from_group (list, contact, old_group);
        }
 
        g_free (old_group);
        }
 
        g_free (old_group);
@@ -976,11 +854,15 @@ contact_list_view_drag_data_get (GtkWidget        *widget,
                                 guint             time)
 {
        EmpathyContactListViewPriv *priv;
                                 guint             time)
 {
        EmpathyContactListViewPriv *priv;
-       GtkTreePath               *src_path;
-       GtkTreeIter                iter;
-       GtkTreeModel              *model;
+       GtkTreePath                *src_path;
+       GtkTreeIter                 iter;
+       GtkTreeModel               *model;
        EmpathyContact             *contact;
        EmpathyContact             *contact;
-       const gchar               *id;
+       McAccount                  *account;
+       const gchar                *contact_id;
+       const gchar                *account_id;
+       gchar                      *str;
+       
 
        priv = GET_PRIV (widget);
 
 
        priv = GET_PRIV (widget);
 
@@ -1006,18 +888,20 @@ contact_list_view_drag_data_get (GtkWidget        *widget,
                return;
        }
 
                return;
        }
 
-       id = empathy_contact_get_id (contact);
+       account = empathy_contact_get_account (contact);
+       account_id = mc_account_get_unique_name (account);
+       contact_id = empathy_contact_get_id (contact);
        g_object_unref (contact);
        g_object_unref (contact);
+       str = g_strconcat (account_id, "/", contact_id, NULL);
 
        switch (info) {
        case DND_DRAG_TYPE_CONTACT_ID:
                gtk_selection_data_set (selection, drag_atoms_source[info], 8,
 
        switch (info) {
        case DND_DRAG_TYPE_CONTACT_ID:
                gtk_selection_data_set (selection, drag_atoms_source[info], 8,
-                                       (guchar*)id, strlen (id) + 1);
+                                       (guchar*)str, strlen (str) + 1);
                break;
                break;
-
-       default:
-               return;
        }
        }
+
+       g_free (str);
 }
 
 static void
 }
 
 static void
@@ -1329,124 +1213,6 @@ contact_list_view_row_expand_or_collapse_cb (EmpathyContactListView *view,
        g_free (name);
 }
 
        g_free (name);
 }
 
-static gboolean 
-contact_list_view_filter_show_contact (EmpathyContact *contact,
-                                      const gchar   *filter)
-{
-       gchar    *str;
-       gboolean  visible;
-
-       /* Check contact id */
-       str = g_utf8_casefold (empathy_contact_get_id (contact), -1);
-       visible = G_STR_EMPTY (str) || strstr (str, filter);
-       g_free (str);
-
-       if (visible) {
-               return TRUE;
-       }
-
-       /* Check contact name */
-       str = g_utf8_casefold (empathy_contact_get_name (contact), -1);
-       visible = G_STR_EMPTY (str) || strstr (str, filter);
-       g_free (str);
-       
-       return visible;
-}
-
-static gboolean
-contact_list_view_filter_show_group (EmpathyContactListView *view,
-                                    const gchar           *group,
-                                    const gchar           *filter)
-{
-       EmpathyContactListViewPriv *priv;
-       EmpathyContactList        *list;
-       GList                     *contacts, *l;
-       gchar                     *str;
-       gboolean                   show_group = FALSE;
-
-       priv = GET_PRIV (view);
-       
-       str = g_utf8_casefold (group, -1);
-       if (!str) {
-               return FALSE;
-       }
-
-       /* If the filter is the partially the group name, we show the
-        * whole group.
-        */
-       if (strstr (str, filter)) {
-               g_free (str);
-               return TRUE;
-       }
-
-       /* At this point, we need to check in advance if this
-        * group should be shown because a contact we want to
-        * show exists in it.
-        */
-       list = empathy_contact_list_store_get_list_iface (priv->store);
-       contacts = empathy_contact_list_get_members (list);
-       for (l = contacts; l && !show_group; l = l->next) {
-               if (!empathy_contact_is_in_group (l->data, group)) {
-                       g_object_unref (l->data);
-                       continue;
-               }
-
-               if (contact_list_view_filter_show_contact (l->data, filter)) {
-                       show_group = TRUE;
-               }
-               g_object_unref (l->data);
-       }
-       g_list_free (contacts);
-       g_free (str);
-
-       return show_group;
-}
-
-static gboolean
-contact_list_view_filter_func (GtkTreeModel          *model,
-                              GtkTreeIter           *iter,
-                              EmpathyContactListView *view)
-{
-       EmpathyContactListViewPriv *priv;
-       gboolean                   is_group;
-       gboolean                   is_separator;
-       gboolean                   visible = TRUE;
-
-       priv = GET_PRIV (view);
-
-       if (G_STR_EMPTY (priv->filter_text)) {
-               return TRUE;
-       }
-       
-       /* Check to see if iter matches any group names */
-       gtk_tree_model_get (model, iter,
-                           COL_IS_GROUP, &is_group,
-                           COL_IS_SEPARATOR, &is_separator,
-                           -1);
-
-       if (is_group) {
-               gchar *name;
-
-               gtk_tree_model_get (model, iter, COL_NAME, &name, -1);
-               visible &= contact_list_view_filter_show_group (view,
-                                                               name,
-                                                               priv->filter_text);
-               g_free (name);
-       } else if (is_separator) {
-               /* Do nothing here */
-       } else {
-               EmpathyContact *contact;
-
-               /* Check contact id */
-               gtk_tree_model_get (model, iter, COL_CONTACT, &contact, -1);
-               visible &= contact_list_view_filter_show_contact (contact, 
-                                                                 priv->filter_text);
-               g_object_unref (contact);
-       }
-
-       return visible;
-}
-
 static void
 contact_list_view_action_cb (GtkAction             *action,
                             EmpathyContactListView *view)
 static void
 contact_list_view_action_cb (GtkAction             *action,
                             EmpathyContactListView *view)
index 4d7cf1cb9ed956046224fcbb6d8a6e732f6d6197..b9de24357229cf6992c1df88f735f52eb20fc751 100644 (file)
@@ -53,24 +53,13 @@ struct _EmpathyContactListViewClass {
        GtkTreeViewClass       parent_class;
 };
 
        GtkTreeViewClass       parent_class;
 };
 
-typedef void           (*EmpathyContactListViewDragReceivedFunc)        (EmpathyContact *contact,
-                                                                       GdkDragAction  action,
-                                                                       const gchar   *old_group,
-                                                                       const gchar   *new_group,
-                                                                       gpointer       user_data);
-
-GType                  empathy_contact_list_view_get_type               (void) G_GNUC_CONST;
-EmpathyContactListView *empathy_contact_list_view_new                    (EmpathyContactListStore                *store);
-EmpathyContact *        empathy_contact_list_view_get_selected           (EmpathyContactListView                 *view);
-gchar *                empathy_contact_list_view_get_selected_group     (EmpathyContactListView                 *view);
-GtkWidget *            empathy_contact_list_view_get_contact_menu       (EmpathyContactListView                 *view,
-                                                                       EmpathyContact                         *contact);
-GtkWidget *            empathy_contact_list_view_get_group_menu         (EmpathyContactListView                 *view);
-void                   empathy_contact_list_view_set_filter             (EmpathyContactListView                 *view,
-                                                                       const gchar                           *filter);
-void                   empathy_contact_list_view_set_drag_received_func (EmpathyContactListView                 *view,
-                                                                       EmpathyContactListViewDragReceivedFunc  func,
-                                                                       gpointer                               user_data);
+GType                   empathy_contact_list_view_get_type           (void) G_GNUC_CONST;
+EmpathyContactListView *empathy_contact_list_view_new                (EmpathyContactListStore *store);
+EmpathyContact *        empathy_contact_list_view_get_selected       (EmpathyContactListView  *view);
+gchar *                 empathy_contact_list_view_get_selected_group (EmpathyContactListView  *view);
+GtkWidget *             empathy_contact_list_view_get_contact_menu   (EmpathyContactListView  *view,
+                                                                     EmpathyContact          *contact);
+GtkWidget *             empathy_contact_list_view_get_group_menu     (EmpathyContactListView  *view);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
index 5c8f6d3d881554fdbba6360d9882240ee3d3694a..b3081b13098d065668751d9d48ef1e20ee4e1e85 100644 (file)
@@ -31,7 +31,9 @@
 
 #include <libmissioncontrol/mc-account.h>
 
 
 #include <libmissioncontrol/mc-account.h>
 
+#include <libempathy/empathy-contact-factory.h>
 #include <libempathy/empathy-contact-manager.h>
 #include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-utils.h>
 
 #include "empathy-contact-widget.h"
 #include <libempathy/empathy-utils.h>
 
 #include "empathy-contact-widget.h"
 #define ID_CHANGED_TIMEOUT 500
 
 typedef struct {
 #define ID_CHANGED_TIMEOUT 500
 
 typedef struct {
-       EmpathyContact  *contact;
-       gboolean         is_user;
-       EmpathyContactWidgetType type;
-       GtkCellRenderer *renderer;
-       guint            widget_id_timeout;
+       EmpathyContactFactory    *factory;
+       EmpathyContactManager    *manager;
+       EmpathyContact           *contact;
+       gboolean                  is_user;
+       EmpathyContactWidgetType  type;
+       GtkCellRenderer          *renderer;
+       guint                     widget_id_timeout;
 
 
-       GtkWidget       *vbox_contact_widget;
+       GtkWidget                *vbox_contact_widget;
 
        /* Contact */
 
        /* Contact */
-       GtkWidget       *vbox_contact;
-       GtkWidget       *widget_avatar;
-       GtkWidget       *widget_account;
-       GtkWidget       *widget_id;
-       GtkWidget       *widget_alias;
-       GtkWidget       *label_alias;
-       GtkWidget       *entry_alias;
-       GtkWidget       *hbox_presence;
-       GtkWidget       *image_state;
-       GtkWidget       *label_status;
-       GtkWidget       *table_contact;
-       GtkWidget       *hbox_contact;
+       GtkWidget                *vbox_contact;
+       GtkWidget                *widget_avatar;
+       GtkWidget                *widget_account;
+       GtkWidget                *widget_id;
+       GtkWidget                *widget_alias;
+       GtkWidget                *label_alias;
+       GtkWidget                *entry_alias;
+       GtkWidget                *hbox_presence;
+       GtkWidget                *image_state;
+       GtkWidget                *label_status;
+       GtkWidget                *table_contact;
+       GtkWidget                *hbox_contact;
 
        /* Groups */
 
        /* Groups */
-       GtkWidget       *vbox_groups;
-       GtkWidget       *entry_group;
-       GtkWidget       *button_group;
-       GtkWidget       *treeview_groups;
+       GtkWidget                *vbox_groups;
+       GtkWidget                *entry_group;
+       GtkWidget                *button_group;
+       GtkWidget                *treeview_groups;
 
        /* Details */
 
        /* Details */
-       GtkWidget       *vbox_details;
-       GtkWidget       *table_details;
-       GtkWidget       *hbox_details_requested;
+       GtkWidget                *vbox_details;
+       GtkWidget                *table_details;
+       GtkWidget                *hbox_details_requested;
 
        /* Client */
 
        /* Client */
-       GtkWidget       *vbox_client;
-       GtkWidget       *table_client;
-       GtkWidget       *hbow_client_requested;
-
+       GtkWidget                *vbox_client;
+       GtkWidget                *table_client;
+       GtkWidget                *hbow_client_requested;
 } EmpathyContactWidget;
 
 typedef struct {
 } EmpathyContactWidget;
 
 typedef struct {
@@ -151,6 +154,7 @@ empathy_contact_widget_new (EmpathyContact           *contact,
 
        information = g_slice_new0 (EmpathyContactWidget);
        information->type = type;
 
        information = g_slice_new0 (EmpathyContactWidget);
        information->type = type;
+       information->factory = empathy_contact_factory_new ();
        if (contact) {
                information->is_user = empathy_contact_is_user (contact);
        } else {
        if (contact) {
                information->is_user = empathy_contact_is_user (contact);
        } else {
@@ -231,6 +235,12 @@ contact_widget_destroy_cb (GtkWidget            *widget,
        if (information->widget_id_timeout != 0) {
                g_source_remove (information->widget_id_timeout);
        }
        if (information->widget_id_timeout != 0) {
                g_source_remove (information->widget_id_timeout);
        }
+       if (information->factory) {
+               g_object_unref (information->factory);
+       }               
+       if (information->manager) {
+               g_object_unref (information->manager);
+       }               
 
        g_slice_free (EmpathyContactWidget, information);
 }
 
        g_slice_free (EmpathyContactWidget, information);
 }
@@ -467,17 +477,15 @@ contact_widget_update_contact (EmpathyContactWidget *information)
        id = gtk_entry_get_text (GTK_ENTRY (information->widget_id));
 
        if (account && !G_STR_EMPTY (id)) {
        id = gtk_entry_get_text (GTK_ENTRY (information->widget_id));
 
        if (account && !G_STR_EMPTY (id)) {
-               EmpathyContactManager *manager;
-               EmpathyContact         *contact;
+               EmpathyContact *contact;
 
 
-               manager = empathy_contact_manager_new ();
-               contact = empathy_contact_manager_create (manager, account, id);
+               contact = empathy_contact_factory_get_from_id (information->factory,
+                                                              account, id);
                contact_widget_set_contact (information, contact);
 
                if (contact) {
                        g_object_unref (contact);
                }
                contact_widget_set_contact (information, contact);
 
                if (contact) {
                        g_object_unref (contact);
                }
-               g_object_unref (manager);
        }
 
        return FALSE;
        }
 
        return FALSE;
@@ -508,7 +516,9 @@ contact_widget_entry_alias_focus_event_cb (GtkEditable          *editable,
                const gchar *name;
 
                name = gtk_entry_get_text (GTK_ENTRY (editable));
                const gchar *name;
 
                name = gtk_entry_get_text (GTK_ENTRY (editable));
-               empathy_contact_set_name (information->contact, name);
+               empathy_contact_factory_set_name (information->factory,
+                                                 information->contact,
+                                                 name);
        }
 
        return FALSE;
        }
 
        return FALSE;
@@ -559,6 +569,7 @@ static void
 contact_widget_groups_setup (EmpathyContactWidget *information)
 {
        if (information->type > CONTACT_WIDGET_TYPE_SHOW) {
 contact_widget_groups_setup (EmpathyContactWidget *information)
 {
        if (information->type > CONTACT_WIDGET_TYPE_SHOW) {
+               information->manager = empathy_contact_manager_new ();
                contact_widget_model_setup (information);
        }
 }
                contact_widget_model_setup (information);
        }
 }
@@ -657,21 +668,19 @@ contact_widget_model_populate_columns (EmpathyContactWidget *information)
 static void
 contact_widget_groups_populate_data (EmpathyContactWidget *information)
 {
 static void
 contact_widget_groups_populate_data (EmpathyContactWidget *information)
 {
-       EmpathyContactManager *manager;
-       GtkTreeView           *view;
-       GtkListStore          *store;
-       GtkTreeIter            iter;
-       GList                 *my_groups, *l;
-       GList                 *all_groups;
+       GtkTreeView  *view;
+       GtkListStore *store;
+       GtkTreeIter   iter;
+       GList        *my_groups, *l;
+       GList        *all_groups;
 
        view = GTK_TREE_VIEW (information->treeview_groups);
        store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
        gtk_list_store_clear (store);
 
 
        view = GTK_TREE_VIEW (information->treeview_groups);
        store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
        gtk_list_store_clear (store);
 
-       manager = empathy_contact_manager_new ();
-       all_groups = empathy_contact_manager_get_groups (manager);
-       my_groups = empathy_contact_get_groups (information->contact);
-       g_object_unref (manager);
+       all_groups = empathy_contact_list_get_all_groups (EMPATHY_CONTACT_LIST (information->manager));
+       my_groups = empathy_contact_list_get_groups (EMPATHY_CONTACT_LIST (information->manager),
+                                                    information->contact);
 
        for (l = all_groups; l; l = l->next) {
                const gchar *group_str;
 
        for (l = all_groups; l; l = l->next) {
                const gchar *group_str;
@@ -691,7 +700,10 @@ contact_widget_groups_populate_data (EmpathyContactWidget *information)
                                    -1);
        }
 
                                    -1);
        }
 
+       g_list_foreach (all_groups, (GFunc) g_free, NULL);
+       g_list_foreach (my_groups, (GFunc) g_free, NULL);
        g_list_free (all_groups);
        g_list_free (all_groups);
+       g_list_free (my_groups);
 }
 
 static void
 }
 
 static void
@@ -792,9 +804,13 @@ contact_widget_cell_toggled (GtkCellRendererToggle *cell,
 
        if (group) {
                if (enabled) {
 
        if (group) {
                if (enabled) {
-                       empathy_contact_remove_group (information->contact, group);
+                       empathy_contact_list_remove_from_group (EMPATHY_CONTACT_LIST (information->manager),
+                                                               information->contact,
+                                                               group);
                } else {
                } else {
-                       empathy_contact_add_group (information->contact, group);        
+                       empathy_contact_list_add_to_group (EMPATHY_CONTACT_LIST (information->manager),
+                                                          information->contact,
+                                                          group);
                }
 
                g_free (group);
                }
 
                g_free (group);
@@ -846,7 +862,9 @@ contact_widget_button_group_clicked_cb (GtkButton             *button,
                            COL_ENABLED, TRUE,
                            -1);
 
                            COL_ENABLED, TRUE,
                            -1);
 
-       empathy_contact_add_group (information->contact, group);
+       empathy_contact_list_add_to_group (EMPATHY_CONTACT_LIST (information->manager),
+                                          information->contact,
+                                          group);
 }
 
 static void
 }
 
 static void
index ca046a3d76848b4025ad2c0518188051c91f3157..48439302d30cd8725d044a5a9dbf5999e6cae1a3 100644 (file)
@@ -78,11 +78,12 @@ static void          group_chat_finalize                 (GObject           *obj
 static void          group_chat_create_ui                (EmpathyGroupChat  *chat);
 static void          group_chat_widget_destroy_cb        (GtkWidget         *widget,
                                                          EmpathyGroupChat  *chat);
 static void          group_chat_create_ui                (EmpathyGroupChat  *chat);
 static void          group_chat_widget_destroy_cb        (GtkWidget         *widget,
                                                          EmpathyGroupChat  *chat);
-static void          group_chat_contact_added_cb         (EmpathyTpChatroom *tp_chat,
-                                                         EmpathyContact    *contact,
-                                                         EmpathyGroupChat  *chat);
-static void          group_chat_contact_removed_cb       (EmpathyTpChatroom *tp_chat,
+static void          group_chat_members_changed_cb       (EmpathyTpChatroom *tp_chat,
                                                          EmpathyContact    *contact,
                                                          EmpathyContact    *contact,
+                                                         EmpathyContact    *actor,
+                                                         guint              reason,
+                                                         gchar             *message,
+                                                         gboolean           is_member,
                                                          EmpathyGroupChat  *chat);
 static void          group_chat_topic_entry_activate_cb  (GtkWidget         *entry,
                                                          GtkDialog         *dialog);
                                                          EmpathyGroupChat  *chat);
 static void          group_chat_topic_entry_activate_cb  (GtkWidget         *entry,
                                                          GtkDialog         *dialog);
@@ -348,33 +349,26 @@ group_chat_widget_destroy_cb (GtkWidget       *widget,
 }
 
 static void
 }
 
 static void
-group_chat_contact_added_cb (EmpathyTpChatroom *tp_chat,
-                            EmpathyContact     *contact,
-                            EmpathyGroupChat   *chat)
-{
-       EmpathyGroupChatPriv *priv;
-       gchar               *str;
-
-       priv = GET_PRIV (chat);
-
-       str = g_strdup_printf (_("%s has joined the room"),
-                              empathy_contact_get_name (contact));
-       empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, str);
-       g_free (str);
-}
-
-static void
-group_chat_contact_removed_cb (EmpathyTpChatroom *tp_chat,
+group_chat_members_changed_cb (EmpathyTpChatroom *tp_chat,
                               EmpathyContact     *contact,
                               EmpathyContact     *contact,
+                              EmpathyContact     *actor,
+                              guint               reason,
+                              gchar              *message,
+                              gboolean            is_member,
                               EmpathyGroupChat   *chat)
 {
        EmpathyGroupChatPriv *priv;
                               EmpathyGroupChat   *chat)
 {
        EmpathyGroupChatPriv *priv;
-       gchar               *str;
+       gchar                *str;
 
        priv = GET_PRIV (chat);
 
 
        priv = GET_PRIV (chat);
 
-       str = g_strdup_printf (_("%s has left the room"),
-                              empathy_contact_get_name (contact));
+       if (is_member) {
+               str = g_strdup_printf (_("%s has joined the room"),
+                                      empathy_contact_get_name (contact));
+       } else {
+               str = g_strdup_printf (_("%s has left the room"),
+                                      empathy_contact_get_name (contact));
+       }
        empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, str);
        g_free (str);
 }
        empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, str);
        g_free (str);
 }
@@ -540,11 +534,8 @@ group_chat_set_tp_chat (EmpathyChat    *chat,
        gtk_widget_show (GTK_WIDGET (priv->view));
 
        /* Connect signals */
        gtk_widget_show (GTK_WIDGET (priv->view));
 
        /* Connect signals */
-       g_signal_connect (priv->tp_chat, "contact-added",
-                         G_CALLBACK (group_chat_contact_added_cb),
-                         chat);
-       g_signal_connect (priv->tp_chat, "contact-removed",
-                         G_CALLBACK (group_chat_contact_removed_cb),
+       g_signal_connect (priv->tp_chat, "members-changed",
+                         G_CALLBACK (group_chat_members_changed_cb),
                          chat);
        g_signal_connect (priv->tp_chat, "notify::subject",
                          G_CALLBACK (group_chat_subject_notify_cb),
                          chat);
        g_signal_connect (priv->tp_chat, "notify::subject",
                          G_CALLBACK (group_chat_subject_notify_cb),
index 227ebe599ae723d46e16f28d184db8baa1187046..ad6d43b28656a9b14e2090ee772e99bd5bf4e37f 100644 (file)
@@ -31,7 +31,7 @@ G_BEGIN_DECLS
 #define EMPATHY_IMAGE_BUSY                "empathy-busy"
 #define EMPATHY_IMAGE_AWAY                "empathy-away"
 #define EMPATHY_IMAGE_EXT_AWAY            "empathy-extended-away"
 #define EMPATHY_IMAGE_BUSY                "empathy-busy"
 #define EMPATHY_IMAGE_AWAY                "empathy-away"
 #define EMPATHY_IMAGE_EXT_AWAY            "empathy-extended-away"
-#define EMPATHY_IMAGE_PENDING             "empathy-pending"
+#define EMPATHY_IMAGE_UNKNOWN             "empathy-pending"
 
 #define EMPATHY_IMAGE_MESSAGE             "empathy-message"
 #define EMPATHY_IMAGE_NEW_MESSAGE         "empathy-new-message"
 
 #define EMPATHY_IMAGE_MESSAGE             "empathy-message"
 #define EMPATHY_IMAGE_NEW_MESSAGE         "empathy-new-message"
index 13c578d890141339828ac16205a1fcec83c4cb23..4b89c4e67632d023cc635519c3e2413e730639a0 100644 (file)
@@ -288,7 +288,6 @@ empathy_main_window_show (void)
        empathy_status_presets_get_all ();
 
        list_iface = EMPATHY_CONTACT_LIST (empathy_contact_manager_new ());
        empathy_status_presets_get_all ();
 
        list_iface = EMPATHY_CONTACT_LIST (empathy_contact_manager_new ());
-       empathy_contact_list_setup (list_iface);
        window->list_store = empathy_contact_list_store_new (list_iface);
        window->list_view = empathy_contact_list_view_new (window->list_store);
        g_object_unref (list_iface);
        window->list_store = empathy_contact_list_store_new (list_iface);
        window->list_view = empathy_contact_list_view_new (window->list_store);
        g_object_unref (list_iface);
index 81f93c02147548f36dc08d5c568cc8239211e598..b187e98cdb2c1665813fc038dff06a196eb2c685 100644 (file)
@@ -36,7 +36,7 @@
 #include <libempathy/empathy-debug.h>
 #include <libempathy/empathy-tp-chat.h>
 #include <libempathy/empathy-tp-contact-list.h>
 #include <libempathy/empathy-debug.h>
 #include <libempathy/empathy-tp-chat.h>
 #include <libempathy/empathy-tp-contact-list.h>
-#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-contact-factory.h>
 
 #include "empathy-private-chat.h"
 #include "empathy-chat-view.h"
 
 #include "empathy-private-chat.h"
 #include "empathy-chat-view.h"
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_PRIVATE_CHAT, EmpathyPrivateChatPriv))
 
 struct _EmpathyPrivateChatPriv {   
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_PRIVATE_CHAT, EmpathyPrivateChatPriv))
 
 struct _EmpathyPrivateChatPriv {   
-       EmpathyContact *contact;
-       gchar          *name;
-       gboolean        is_online;
-       GtkWidget      *widget;
-       GtkWidget      *text_view_sw;
+       EmpathyContactFactory *factory;
+       EmpathyContact        *contact;
+       gchar                 *name;
+       gboolean               is_online;
+       GtkWidget             *widget;
+       GtkWidget             *text_view_sw;
 };
 
 static void           empathy_private_chat_class_init            (EmpathyPrivateChatClass *klass);
 };
 
 static void           empathy_private_chat_class_init            (EmpathyPrivateChatClass *klass);
@@ -125,7 +126,9 @@ private_chat_finalize (GObject *object)
        if (priv->contact) {
                g_object_unref (priv->contact);
        }
        if (priv->contact) {
                g_object_unref (priv->contact);
        }
-
+       if (priv->factory) {
+               g_object_unref (priv->factory);
+       }
        g_free (priv->name);
 
        G_OBJECT_CLASS (empathy_private_chat_parent_class)->finalize (object);
        g_free (priv->name);
 
        G_OBJECT_CLASS (empathy_private_chat_parent_class)->finalize (object);
@@ -327,27 +330,30 @@ EmpathyPrivateChat *
 empathy_private_chat_new (McAccount *account,
                          TpChan    *tp_chan)
 {
 empathy_private_chat_new (McAccount *account,
                          TpChan    *tp_chan)
 {
-       EmpathyPrivateChat    *chat;
-       EmpathyTpChat         *tp_chat;
-       EmpathyContactManager *manager;
-       EmpathyTpContactList  *list;
-       EmpathyContact        *contact;
+       EmpathyPrivateChat     *chat;
+       EmpathyPrivateChatPriv *priv;
+       EmpathyTpChat          *tp_chat;
+       EmpathyContactFactory  *factory;
+       EmpathyContact         *contact;
 
        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 (MC_IS_ACCOUNT (account), NULL);
        g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
 
-       manager = empathy_contact_manager_new ();
-       list = empathy_contact_manager_get_list (manager, account);
-       contact = empathy_tp_contact_list_get_from_handle (list, tp_chan->handle);
+       factory = empathy_contact_factory_new ();
+       contact = empathy_contact_factory_get_from_handle (factory,
+                                                          account,
+                                                          tp_chan->handle);
 
        chat = g_object_new (EMPATHY_TYPE_PRIVATE_CHAT, NULL);
 
        chat = g_object_new (EMPATHY_TYPE_PRIVATE_CHAT, NULL);
-       tp_chat = empathy_tp_chat_new (account, tp_chan);
+       priv = GET_PRIV (chat);
 
 
+       priv->factory = factory;
+       tp_chat = empathy_tp_chat_new (account, tp_chan);
        private_chat_setup (chat, contact, tp_chat);
 
        g_object_unref (tp_chat);
        g_object_unref (contact);
        private_chat_setup (chat, contact, tp_chat);
 
        g_object_unref (tp_chat);
        g_object_unref (contact);
-       g_object_unref (manager);
+       g_object_unref (factory);
 
        return chat;
 }
 
        return chat;
 }
index 1ec1a21a5a1655dd63375b7737b36bc7a5798c95..1fdc0095309fdfdcd9485d6a1145e74e0ca483f6 100644 (file)
@@ -117,9 +117,12 @@ static void       status_icon_quit_cb             (GtkWidget              *windo
                                                   EmpathyStatusIcon      *icon);
 static void       status_icon_show_hide_window_cb (GtkWidget              *widget,
                                                   EmpathyStatusIcon      *icon);
                                                   EmpathyStatusIcon      *icon);
 static void       status_icon_show_hide_window_cb (GtkWidget              *widget,
                                                   EmpathyStatusIcon      *icon);
-static void       status_icon_local_pending_cb    (EmpathyContactManager  *manager,
-                                                  EmpathyContact          *contact,
+static void       status_icon_pendings_changed_cb (EmpathyContactManager  *manager,
+                                                  EmpathyContact         *contact,
+                                                  EmpathyContact         *actor,
+                                                  guint                   reason,
                                                   gchar                  *message,
                                                   gchar                  *message,
+                                                  gboolean                is_pending,
                                                   EmpathyStatusIcon      *icon);
 static void       status_icon_event_subscribe_cb  (StatusIconEvent        *event);
 static void       status_icon_event_flash_state_cb (StatusIconEvent       *event);
                                                   EmpathyStatusIcon      *icon);
 static void       status_icon_event_subscribe_cb  (StatusIconEvent        *event);
 static void       status_icon_event_flash_state_cb (StatusIconEvent       *event);
@@ -148,7 +151,7 @@ static void
 empathy_status_icon_init (EmpathyStatusIcon *icon)
 {
        EmpathyStatusIconPriv *priv;
 empathy_status_icon_init (EmpathyStatusIcon *icon)
 {
        EmpathyStatusIconPriv *priv;
-       GList                 *pending, *l;
+       GList                 *pendings, *l;
 
        priv = GET_PRIV (icon);
 
 
        priv = GET_PRIV (icon);
 
@@ -177,21 +180,25 @@ empathy_status_icon_init (EmpathyStatusIcon *icon)
        g_signal_connect (priv->icon, "popup-menu",
                          G_CALLBACK (status_icon_popup_menu_cb),
                          icon);
        g_signal_connect (priv->icon, "popup-menu",
                          G_CALLBACK (status_icon_popup_menu_cb),
                          icon);
-       g_signal_connect (priv->manager, "local-pending",
-                         G_CALLBACK (status_icon_local_pending_cb),
+       g_signal_connect (priv->manager, "pendings-changed",
+                         G_CALLBACK (status_icon_pendings_changed_cb),
                          icon);
 
                          icon);
 
-       pending = empathy_contact_list_get_local_pending (EMPATHY_CONTACT_LIST (priv->manager));
-       for (l = pending; l; l = l->next) {
-               EmpathyContactListInfo *info;
+       pendings = empathy_contact_list_get_pendings (EMPATHY_CONTACT_LIST (priv->manager));
+       for (l = pendings; l; l = l->next) {
+               EmpathyPendingInfo *info;
 
                info = l->data;
 
                info = l->data;
-               status_icon_local_pending_cb (priv->manager,
-                                             info->contact,
-                                             info->message,
-                                             icon);
+               status_icon_pendings_changed_cb (priv->manager,
+                                                info->member,
+                                                info->actor,
+                                                0,
+                                                info->message,
+                                                TRUE,
+                                                icon);
+               empathy_pending_info_free (info);
        }
        }
-       g_list_free (pending);
+       g_list_free (pendings);
 }
 
 static void
 }
 
 static void
@@ -533,10 +540,13 @@ status_icon_show_hide_window_cb (GtkWidget         *widget,
 }
 
 static void
 }
 
 static void
-status_icon_local_pending_cb (EmpathyContactManager *manager,
-                             EmpathyContact         *contact,
-                             gchar                 *message,
-                             EmpathyStatusIcon     *icon)
+status_icon_pendings_changed_cb (EmpathyContactManager *manager,
+                                EmpathyContact        *contact,
+                                EmpathyContact        *actor,
+                                guint                  reason,
+                                gchar                 *message,
+                                gboolean               is_pending,
+                                EmpathyStatusIcon     *icon)
 {
        EmpathyStatusIconPriv *priv;
        StatusIconEvent       *event;
 {
        EmpathyStatusIconPriv *priv;
        StatusIconEvent       *event;
@@ -545,6 +555,11 @@ status_icon_local_pending_cb (EmpathyContactManager *manager,
 
        priv = GET_PRIV (icon);
 
 
        priv = GET_PRIV (icon);
 
+       if (!is_pending) {
+               /* FIXME: We should remove the event */
+               return;
+       }
+
        for (l = priv->events; l; l = l->next) {
                if (empathy_contact_equal (contact, ((StatusIconEvent*)l->data)->user_data)) {
                        return;
        for (l = priv->events; l; l = l->next) {
                if (empathy_contact_equal (contact, ((StatusIconEvent*)l->data)->user_data)) {
                        return;
index fb491cc5ef0da93a0e2672b4f37e4e67ebc7cc0d..aedacb08be5b45190b1041e54675962a8c988580 100644 (file)
@@ -378,8 +378,7 @@ empathy_icon_name_for_presence (EmpathyPresence *presence)
 const gchar *
 empathy_icon_name_for_contact (EmpathyContact *contact)
 {
 const gchar *
 empathy_icon_name_for_contact (EmpathyContact *contact)
 {
-       EmpathyPresence     *presence;
-       EmpathySubscription  subscription;
+       EmpathyPresence *presence;
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT (contact),
                              EMPATHY_IMAGE_OFFLINE);
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT (contact),
                              EMPATHY_IMAGE_OFFLINE);
@@ -389,12 +388,7 @@ empathy_icon_name_for_contact (EmpathyContact *contact)
                return empathy_icon_name_for_presence (presence);
        }
 
                return empathy_icon_name_for_presence (presence);
        }
 
-       subscription = empathy_contact_get_subscription (contact);
-       if (!(subscription & EMPATHY_SUBSCRIPTION_FROM)) {
-               return EMPATHY_IMAGE_PENDING;
-       }
-
-       return EMPATHY_IMAGE_OFFLINE;
+       return EMPATHY_IMAGE_UNKNOWN;
 }
 
 static void
 }
 
 static void
index 39dfa9b62af3bfc2f2bbbd16620d88eb6efb8019..c24a16f211d88188e51d2d9f124eefbc34854ddf 100644 (file)
@@ -17,7 +17,6 @@ lib_LTLIBRARIES = libempathy.la
 
 libempathy_la_SOURCES =                                        \
        empathy-conf.c                                  \
 
 libempathy_la_SOURCES =                                        \
        empathy-conf.c                                  \
-       empathy-contact.c                               \
        empathy-avatar.c                                \
        empathy-time.c                                  \
        empathy-presence.c                              \
        empathy-avatar.c                                \
        empathy-time.c                                  \
        empathy-presence.c                              \
@@ -26,8 +25,10 @@ libempathy_la_SOURCES =                                      \
        empathy-message.c                               \
        empathy-chatroom-manager.c                      \
        empathy-chatroom.c                              \
        empathy-message.c                               \
        empathy-chatroom-manager.c                      \
        empathy-chatroom.c                              \
+       empathy-contact.c                               \
        empathy-contact-list.c                          \
        empathy-contact-manager.c                       \
        empathy-contact-list.c                          \
        empathy-contact-manager.c                       \
+       empathy-contact-factory.c                       \
        empathy-tp-group.c                              \
        empathy-tp-contact-list.c                       \
        empathy-tp-chat.c                               \
        empathy-tp-group.c                              \
        empathy-tp-contact-list.c                       \
        empathy-tp-chat.c                               \
@@ -50,7 +51,6 @@ libempathy_la_LDFLAGS =               \
 
 libempathy_headers =                           \
        empathy-conf.h                          \
 
 libempathy_headers =                           \
        empathy-conf.h                          \
-       empathy-contact.h                       \
        empathy-avatar.h                        \
        empathy-time.h                          \
        empathy-presence.h                      \
        empathy-avatar.h                        \
        empathy-time.h                          \
        empathy-presence.h                      \
@@ -59,8 +59,10 @@ libempathy_headers =                         \
        empathy-message.h                       \
        empathy-chatroom-manager.h              \
        empathy-chatroom.h                      \
        empathy-message.h                       \
        empathy-chatroom-manager.h              \
        empathy-chatroom.h                      \
+       empathy-contact.h                       \
        empathy-contact-list.h                  \
        empathy-contact-manager.h               \
        empathy-contact-list.h                  \
        empathy-contact-manager.h               \
+       empathy-contact-factory.h               \
        empathy-tp-group.h                      \
        empathy-tp-contact-list.h               \
        empathy-tp-chat.h                       \
        empathy-tp-group.h                      \
        empathy-tp-contact-list.h               \
        empathy-tp-chat.h                       \
index e5a2a73a97aef06950c43ac15c525e9df7ea477d..425f23f5530c3a68ce1b25e683efc42453ac0f57 100644 (file)
@@ -28,7 +28,7 @@
 #define DEBUG_DOMAIN "Avatar"
 
 GType
 #define DEBUG_DOMAIN "Avatar"
 
 GType
-empathy_avatar_get_gtype (void)
+empathy_avatar_get_type (void)
 {
        static GType type_id = 0;
 
 {
        static GType type_id = 0;
 
index 73d69cf794a5fed23561dd787eae4063de3e69a1..6b28e8e7a6b700c881cad2764417632095d85e70 100644 (file)
@@ -25,7 +25,7 @@
 
 G_BEGIN_DECLS
 
 
 G_BEGIN_DECLS
 
-#define EMPATHY_TYPE_AVATAR (empathy_avatar_get_gtype ())
+#define EMPATHY_TYPE_AVATAR (empathy_avatar_get_type ())
 
 typedef struct _EmpathyAvatar EmpathyAvatar;
 
 
 typedef struct _EmpathyAvatar EmpathyAvatar;
 
@@ -36,7 +36,7 @@ struct _EmpathyAvatar {
        guint   refcount;
 };
 
        guint   refcount;
 };
 
-GType          empathy_avatar_get_gtype (void) G_GNUC_CONST;
+GType          empathy_avatar_get_type (void) G_GNUC_CONST;
 EmpathyAvatar * empathy_avatar_new       (guchar       *avatar,
                                        gsize         len,
                                        gchar        *format);
 EmpathyAvatar * empathy_avatar_new       (guchar       *avatar,
                                        gsize         len,
                                        gchar        *format);
diff --git a/libempathy/empathy-contact-factory.c b/libempathy/empathy-contact-factory.c
new file mode 100644 (file)
index 0000000..1c91a65
--- /dev/null
@@ -0,0 +1,1102 @@
+/* -*- 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-conn.h>
+#include <libtelepathy/tp-conn-iface-aliasing-gen.h>
+#include <libtelepathy/tp-conn-iface-presence-gen.h>
+#include <libtelepathy/tp-conn-iface-avatars-gen.h>
+#include <libmissioncontrol/mission-control.h>
+
+#include "empathy-contact-factory.h"
+#include "empathy-utils.h"
+#include "empathy-debug.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+                      EMPATHY_TYPE_CONTACT_FACTORY, EmpathyContactFactoryPriv))
+
+#define DEBUG_DOMAIN "ContactFactory"
+
+struct _EmpathyContactFactoryPriv {
+       MissionControl *mc;
+       GHashTable     *accounts;
+};
+
+typedef struct {
+       EmpathyContactFactory *factory;
+       McAccount             *account;
+       guint                  nb_pending_calls;
+
+       TpConn                *tp_conn;
+       DBusGProxy            *aliasing_iface;
+       DBusGProxy            *avatars_iface;
+       DBusGProxy            *presence_iface;
+
+       GList                 *contacts;
+       guint                  self_handle;
+} ContactFactoryAccountData;
+
+typedef struct {
+       ContactFactoryAccountData *account_data;
+       GList                     *contacts;
+} RequestHandlesData;
+
+typedef struct {
+       ContactFactoryAccountData *account_data;
+       guint                     *handles;
+} RequestAliasesData;
+
+typedef struct {
+       ContactFactoryAccountData *account_data;
+       EmpathyContact            *contact;
+} RequestAvatarData;
+
+static void empathy_contact_factory_class_init (EmpathyContactFactoryClass *klass);
+static void empathy_contact_factory_init       (EmpathyContactFactory      *factory);
+
+G_DEFINE_TYPE (EmpathyContactFactory, empathy_contact_factory, G_TYPE_OBJECT);
+
+static gint
+contact_factory_find_by_handle (gconstpointer a,
+                               gconstpointer b)
+{
+       EmpathyContact *contact;
+       guint           handle; 
+
+       contact = EMPATHY_CONTACT (a);
+       handle = GPOINTER_TO_UINT (b);
+
+       return handle - empathy_contact_get_handle (contact);
+}
+
+static EmpathyContact *
+contact_factory_account_data_find_by_handle (ContactFactoryAccountData *account_data,
+                                            guint                      handle)
+{
+       GList *l;
+
+       l = g_list_find_custom (account_data->contacts,
+                               GUINT_TO_POINTER (handle),
+                               contact_factory_find_by_handle);
+
+       return l ? l->data : NULL;
+}
+
+static gint
+contact_factory_find_by_id (gconstpointer a,
+                           gconstpointer b)
+{
+       EmpathyContact *contact;
+       const gchar    *id = b;
+
+       contact = EMPATHY_CONTACT (a);
+
+       return strcmp (id, empathy_contact_get_id (contact));
+}
+
+static EmpathyContact *
+contact_factory_account_data_find_by_id (ContactFactoryAccountData *account_data,
+                                        const gchar               *id)
+{
+       GList *l;
+
+       l = g_list_find_custom (account_data->contacts,
+                               id,
+                               contact_factory_find_by_id);
+
+       return l ? l->data : NULL;
+}
+
+static void contact_factory_account_data_free (gpointer data);
+
+static void
+contact_factory_account_data_return_call (ContactFactoryAccountData *account_data)
+{
+       if (--account_data->nb_pending_calls == 0 &&
+           account_data->contacts == NULL) {
+               contact_factory_account_data_free (account_data);
+       }
+}
+
+static void
+contact_factory_presences_table_foreach (const gchar      *state_str,
+                                        GHashTable       *presences_table,
+                                        EmpathyPresence **presence)
+{
+       McPresence    state;
+       const GValue *message;
+
+       state = empathy_presence_state_from_str (state_str);
+       if (state == MC_PRESENCE_UNSET) {
+               return;
+       }
+
+       if (*presence) {
+               g_object_unref (*presence);
+               *presence = NULL;
+       }
+
+       *presence = empathy_presence_new ();
+       empathy_presence_set_state (*presence, state);
+
+       message = g_hash_table_lookup (presences_table, "message");
+       if (message != NULL) {
+               empathy_presence_set_status (*presence,
+                                            g_value_get_string (message));
+       }
+}
+
+static void
+contact_factory_parse_presence_foreach (guint                      handle,
+                                       GValueArray               *presence_struct,
+                                       ContactFactoryAccountData *account_data)
+{
+       GHashTable      *presences_table;
+       EmpathyContact  *contact;
+       EmpathyPresence *presence = NULL;
+
+       contact = contact_factory_account_data_find_by_handle (account_data,
+                                                              handle);
+       if (!contact) {
+               return;
+       }
+
+       presences_table = g_value_get_boxed (g_value_array_get_nth (presence_struct, 1));
+
+       g_hash_table_foreach (presences_table,
+                             (GHFunc) contact_factory_presences_table_foreach,
+                             &presence);
+
+       empathy_debug (DEBUG_DOMAIN, "Changing presence for contact %s (%d) to %s (%d)",
+                     empathy_contact_get_id (contact),
+                     handle,
+                     presence ? empathy_presence_get_status (presence) : "unset",
+                     presence ? empathy_presence_get_state (presence) : MC_PRESENCE_UNSET);
+
+       empathy_contact_set_presence (contact, presence);
+}
+
+static void
+contact_factory_get_presence_cb (DBusGProxy *proxy,
+                                GHashTable *handle_table,
+                                GError     *error,
+                                gpointer    user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
+                             error->message);
+               goto OUT;
+       }
+
+       g_hash_table_foreach (handle_table,
+                             (GHFunc) contact_factory_parse_presence_foreach,
+                             account_data);
+OUT:
+       contact_factory_account_data_return_call (account_data);
+}
+
+static void
+contact_factory_presence_update_cb (DBusGProxy                *proxy,
+                                   GHashTable                *handle_table,
+                                   ContactFactoryAccountData *account_data)
+{
+       g_hash_table_foreach (handle_table,
+                             (GHFunc) contact_factory_parse_presence_foreach,
+                             account_data);
+}
+
+static void
+contact_factory_set_aliases_cb (DBusGProxy *proxy,
+                               GError *error,
+                               gpointer user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Error setting alias: %s",
+                              error->message);
+       }
+
+       contact_factory_account_data_return_call (account_data);
+}
+
+static void
+contact_factory_request_aliases_cb (DBusGProxy  *proxy,
+                                   gchar      **contact_names,
+                                   GError      *error,
+                                   gpointer     user_data)
+{
+       RequestAliasesData  *data = user_data;
+       guint                i = 0;
+       gchar              **name;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
+                             error->message);
+               goto OUT;
+       }
+
+       for (name = contact_names; *name; name++) {
+               EmpathyContact *contact;
+
+               contact = contact_factory_account_data_find_by_handle (data->account_data,
+                                                                      data->handles[i]);
+               if (!contact) {
+                       continue;
+               }
+
+               empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (request cb)",
+                              empathy_contact_get_id (contact),
+                              data->handles[i], *name);
+
+               empathy_contact_set_name  (contact, *name);
+
+               i++;
+       }
+
+OUT:
+       contact_factory_account_data_return_call (data->account_data);
+       g_free (data->handles);
+       g_slice_free (RequestAliasesData, data);
+}
+
+static void
+contact_factory_aliases_changed_cb (DBusGProxy *proxy,
+                                   GPtrArray  *renamed_handlers,
+                                   gpointer    user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+       guint                     i;
+
+       for (i = 0; renamed_handlers->len > i; i++) {
+               guint           handle;
+               const gchar    *alias;
+               GValueArray    *renamed_struct;
+               EmpathyContact *contact;
+
+               renamed_struct = g_ptr_array_index (renamed_handlers, i);
+               handle = g_value_get_uint(g_value_array_get_nth (renamed_struct, 0));
+               alias = g_value_get_string(g_value_array_get_nth (renamed_struct, 1));
+               contact = contact_factory_account_data_find_by_handle (account_data, handle);
+
+               if (!contact) {
+                       /* We don't know this contact, skip */
+                       continue;
+               }
+
+               if (G_STR_EMPTY (alias)) {
+                       alias = NULL;
+               }
+
+               empathy_debug (DEBUG_DOMAIN, "Renaming contact %s (%d) to %s (changed cb)",
+                              empathy_contact_get_id (contact),
+                              handle, alias);
+
+               empathy_contact_set_name (contact, alias);
+       }
+}
+
+static void
+contact_factory_request_avatars_cb (DBusGProxy *proxy,
+                                   GError     *error,
+                                   gpointer    user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Error requesting avatars: %s",
+                              error->message);
+       }
+
+       contact_factory_account_data_return_call (account_data);
+}
+
+static void
+contact_factory_request_avatar_cb (DBusGProxy *proxy,
+                                  GArray     *avatar_data,
+                                  gchar      *mime_type,
+                                  GError     *error,
+                                  gpointer    user_data)
+{
+       RequestAvatarData *data = user_data;
+       EmpathyAvatar     *avatar;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Error requesting avatar: %s",
+                              error->message);
+               goto OUT;
+       }
+
+       empathy_debug (DEBUG_DOMAIN, "Avatar received for %s (%d)",
+                      empathy_contact_get_id (data->contact),
+                      empathy_contact_get_handle (data->contact));
+
+       avatar = empathy_avatar_new (avatar_data->data,
+                                    avatar_data->len,
+                                    mime_type);
+       empathy_contact_set_avatar (data->contact, avatar);
+       empathy_avatar_unref (avatar);
+
+OUT:
+       g_object_unref (data->contact);
+       contact_factory_account_data_return_call (data->account_data);
+       g_slice_free (RequestAvatarData, data);
+}
+
+static void
+contact_factory_avatar_updated_cb (DBusGProxy *proxy,
+                                  guint       handle,
+                                  gchar      *new_token,
+                                  gpointer    user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+       RequestAvatarData         *data;
+       EmpathyContact            *contact;
+
+       contact = contact_factory_account_data_find_by_handle (account_data,
+                                                              handle);
+       if (!contact) {
+               return;
+       }
+
+       account_data->nb_pending_calls++;
+       data = g_slice_new0 (RequestAvatarData);
+       data->account_data = account_data;
+       data->contact = g_object_ref (contact);
+       tp_conn_iface_avatars_request_avatar_async (account_data->avatars_iface,
+                                                   handle,
+                                                   contact_factory_request_avatar_cb,
+                                                   data);
+}
+
+static void
+contact_factory_avatar_retrieved_cb (DBusGProxy *proxy,
+                                    guint       handle,
+                                    gchar      *token,
+                                    GArray     *avatar_data,
+                                    gchar      *mime_type,
+                                    gpointer    user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+       EmpathyContact            *contact;
+       EmpathyAvatar             *avatar;
+
+       contact = contact_factory_account_data_find_by_handle (account_data,
+                                                              handle);
+       if (!contact) {
+               return;
+       }
+
+       avatar = empathy_avatar_new (avatar_data->data,
+                                    avatar_data->len,
+                                    mime_type);
+       empathy_contact_set_avatar (contact, avatar);
+       empathy_avatar_unref (avatar);
+}
+
+static void
+contact_factory_request_everything (ContactFactoryAccountData *account_data,
+                                   GArray                    *handles)
+{
+       if (account_data->presence_iface) {
+               account_data->nb_pending_calls++;
+               tp_conn_iface_presence_get_presence_async (account_data->presence_iface,
+                                                          handles,
+                                                          contact_factory_get_presence_cb,
+                                                          account_data);
+       }
+
+       if (account_data->aliasing_iface) {
+               RequestAliasesData *data;
+
+               account_data->nb_pending_calls++;
+               data = g_slice_new (RequestAliasesData);
+               data->account_data = account_data;
+               data->handles = g_memdup (handles->data, handles->len * sizeof (guint));
+
+               tp_conn_iface_aliasing_request_aliases_async (account_data->aliasing_iface,
+                                                             handles,
+                                                             contact_factory_request_aliases_cb,
+                                                             data);
+       }
+
+       if (account_data->avatars_iface) {
+               account_data->nb_pending_calls++;
+               tp_conn_iface_avatars_request_avatars_async (account_data->avatars_iface,
+                                                            handles,
+                                                            contact_factory_request_avatars_cb,
+                                                            account_data);
+       }
+}
+
+static void
+contact_factory_request_handles_cb (DBusGProxy *proxy,
+                                   GArray     *handles,
+                                   GError     *error,
+                                   gpointer    user_data)
+{
+       RequestHandlesData *data = user_data;
+       GList              *l;
+       guint               i = 0;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Failed to request handles: %s",
+                              error->message);
+               goto OUT;
+       }
+
+       for (l = data->contacts; l; l = l->next) {
+               guint handle;
+
+               handle = g_array_index (handles, guint, i);
+               empathy_contact_set_handle (l->data, handle);
+               if (handle == data->account_data->self_handle) {
+                       empathy_contact_set_is_user (l->data, TRUE);
+               }
+
+               i++;
+       }
+
+       contact_factory_request_everything (data->account_data, handles);
+
+OUT:
+       g_list_foreach (data->contacts, (GFunc) g_object_unref, NULL);
+       g_list_free (data->contacts);
+       contact_factory_account_data_return_call (data->account_data);
+       g_slice_free (RequestHandlesData, data);
+}
+
+static void
+contact_factory_disconnect_contact_foreach (gpointer data,
+                                           gpointer user_data)
+{
+       EmpathyContact *contact = data;
+       
+       empathy_contact_set_presence (contact, NULL);
+       empathy_contact_set_handle (contact, 0);
+}
+
+static void
+contact_factory_destroy_cb (TpConn                    *tp_conn,
+                           ContactFactoryAccountData *account_data)
+{
+       empathy_debug (DEBUG_DOMAIN, "Account disconnected or CM crashed");
+
+       g_object_unref (account_data->tp_conn);
+       account_data->tp_conn = NULL;
+       account_data->aliasing_iface = NULL;
+       account_data->avatars_iface = NULL;
+       account_data->presence_iface = NULL;
+
+       g_list_foreach (account_data->contacts,
+                       contact_factory_disconnect_contact_foreach,
+                       account_data);
+}
+
+static void
+contact_factory_account_data_disconnect (ContactFactoryAccountData *account_data)
+{
+       if (account_data->aliasing_iface) {
+               dbus_g_proxy_disconnect_signal (account_data->aliasing_iface,
+                                               "AliasesChanged",
+                                               G_CALLBACK (contact_factory_aliases_changed_cb),
+                                               account_data);
+       }
+       if (account_data->avatars_iface) {
+               dbus_g_proxy_disconnect_signal (account_data->avatars_iface,
+                                               "AvatarUpdated",
+                                               G_CALLBACK (contact_factory_avatar_updated_cb),
+                                               account_data);
+               dbus_g_proxy_disconnect_signal (account_data->avatars_iface,
+                                               "AvatarRetrieved",
+                                               G_CALLBACK (contact_factory_avatar_retrieved_cb),
+                                               account_data);
+       }
+       if (account_data->presence_iface) {
+               dbus_g_proxy_disconnect_signal (account_data->presence_iface,
+                                               "PresenceUpdate",
+                                               G_CALLBACK (contact_factory_presence_update_cb),
+                                               account_data);
+       }
+       if (account_data->tp_conn) {
+               g_signal_handlers_disconnect_by_func (account_data->tp_conn,
+                                                     contact_factory_destroy_cb,
+                                                     account_data);
+       }
+}
+
+static void
+contact_factory_account_data_update (ContactFactoryAccountData *account_data)
+{
+       EmpathyContactFactory     *factory = account_data->factory;
+       EmpathyContactFactoryPriv *priv = GET_PRIV (factory);
+       McAccount                 *account = account_data->account;
+       TpConn                    *tp_conn = NULL;
+       RequestHandlesData        *data;
+       const gchar              **contact_ids;
+       guint                      i;
+       GList                     *l;
+       GError                    *error;
+
+       if (account_data->account) {
+               guint status;
+
+               /* status == 0 means the status is CONNECTED */
+               status = mission_control_get_connection_status (priv->mc,
+                                                               account, NULL);
+               if (status == 0) {
+                       tp_conn = mission_control_get_connection (priv->mc,
+                                                                 account, NULL);
+               }
+       }
+
+       if (!tp_conn) {
+               /* We are not connected anymore, remove the old connection */
+               contact_factory_account_data_disconnect (account_data);
+               if (account_data->tp_conn) {
+                       contact_factory_destroy_cb (account_data->tp_conn,
+                                                   account_data);
+               }
+               return;
+       }
+       else if (account_data->tp_conn) {
+               /* We were connected and we still are connected, nothing
+                * changed so nothing to do. */
+               g_object_unref (tp_conn);
+               return;
+       }
+
+       /* We got a new connection */
+       account_data->tp_conn = tp_conn;
+       account_data->aliasing_iface = tp_conn_get_interface (tp_conn,
+                                                             TELEPATHY_CONN_IFACE_ALIASING_QUARK);
+       account_data->avatars_iface = tp_conn_get_interface (tp_conn,
+                                                            TELEPATHY_CONN_IFACE_AVATARS_QUARK);
+       account_data->presence_iface = tp_conn_get_interface (tp_conn,
+                                                             TELEPATHY_CONN_IFACE_PRESENCE_QUARK);
+
+       /* Connect signals */
+       if (account_data->aliasing_iface) {
+               dbus_g_proxy_connect_signal (account_data->aliasing_iface,
+                                            "AliasesChanged",
+                                            G_CALLBACK (contact_factory_aliases_changed_cb),
+                                            account_data, NULL);
+       }
+       if (account_data->avatars_iface) {
+               dbus_g_proxy_connect_signal (account_data->avatars_iface,
+                                            "AvatarUpdated",
+                                            G_CALLBACK (contact_factory_avatar_updated_cb),
+                                            account_data, NULL);
+               dbus_g_proxy_connect_signal (account_data->avatars_iface,
+                                            "AvatarRetrieved",
+                                            G_CALLBACK (contact_factory_avatar_retrieved_cb),
+                                            account_data, NULL);
+       }
+       if (account_data->presence_iface) {
+               dbus_g_proxy_connect_signal (account_data->presence_iface,
+                                            "PresenceUpdate",
+                                            G_CALLBACK (contact_factory_presence_update_cb),
+                                            account_data, NULL);
+       }
+       g_signal_connect (tp_conn, "destroy",
+                         G_CALLBACK (contact_factory_destroy_cb),
+                         account_data);
+
+       /* Get our own handle */
+       if (!tp_conn_get_self_handle (DBUS_G_PROXY (account_data->tp_conn),
+                                     &account_data->self_handle,
+                                     &error)) {
+               empathy_debug (DEBUG_DOMAIN, "GetSelfHandle Error: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+       }
+
+       /* Request new handles for all contacts */
+       if (account_data->contacts) {
+               data = g_slice_new (RequestHandlesData);
+               data->account_data = account_data;
+               data->contacts = g_list_copy (account_data->contacts);
+               g_list_foreach (data->contacts, (GFunc) g_object_ref, NULL);
+
+               i = g_list_length (data->contacts);
+               contact_ids = g_new0 (const gchar*, i + 1);
+               i = 0;
+               for (l = data->contacts; l; l = l->next) {
+                       contact_ids[i] = empathy_contact_get_id (l->data);
+                       i++;
+               }
+
+               account_data->nb_pending_calls++;
+               tp_conn_request_handles_async (DBUS_G_PROXY (account_data->tp_conn),
+                                              TP_HANDLE_TYPE_CONTACT,
+                                              contact_ids,
+                                              contact_factory_request_handles_cb,
+                                              data);
+               g_free (contact_ids);
+       }
+}
+
+static void
+contact_factory_weak_notify (gpointer data,
+                            GObject *where_the_object_was)
+{
+       ContactFactoryAccountData *account_data = data;
+
+       empathy_debug (DEBUG_DOMAIN, "Remove finalized contact %p",
+                      where_the_object_was);
+
+       account_data->contacts = g_list_remove (account_data->contacts,
+                                               where_the_object_was);
+       if (!account_data->contacts) {
+               EmpathyContactFactoryPriv *priv;
+
+               priv = GET_PRIV (account_data->factory);
+
+               g_hash_table_remove (priv->accounts, account_data->account);
+       }
+}
+
+static void
+contact_factory_remove_foreach (gpointer data,
+                               gpointer user_data)
+{
+       ContactFactoryAccountData *account_data = user_data;
+       EmpathyContact            *contact = data;
+
+       g_object_weak_unref (G_OBJECT (contact),
+                            contact_factory_weak_notify,
+                            account_data);
+}
+
+static ContactFactoryAccountData *
+contact_factory_account_data_new (EmpathyContactFactory *factory,
+                                 McAccount             *account)
+{
+       ContactFactoryAccountData *account_data;
+
+       account_data = g_slice_new0 (ContactFactoryAccountData);
+       account_data->factory = factory;
+       account_data->account = g_object_ref (account);
+
+       contact_factory_account_data_update (account_data);
+
+       return account_data;
+}
+
+static void
+contact_factory_account_data_free (gpointer data)
+{
+       ContactFactoryAccountData *account_data = data;
+
+       contact_factory_account_data_disconnect (account_data);
+
+       if (account_data->contacts) {
+               g_list_foreach (account_data->contacts,
+                               contact_factory_remove_foreach,
+                               account_data);
+               g_list_free (account_data->contacts);
+               account_data->contacts = NULL;
+       }
+
+       if (account_data->account) {
+               g_object_unref (account_data->account);
+               account_data->account = NULL;
+       }
+
+       if (account_data->tp_conn) {
+               g_object_unref (account_data->tp_conn);
+               account_data->tp_conn = NULL;
+               account_data->aliasing_iface = NULL;
+               account_data->avatars_iface = NULL;
+               account_data->presence_iface = NULL;
+       }
+
+       /* Keep the struct alive if we have calls in flight, it will be
+        * destroyed once all calls returned. */
+       if (account_data->nb_pending_calls == 0) {
+               g_slice_free (ContactFactoryAccountData, account_data);
+       }
+}
+
+static void
+contact_factory_status_changed_cb (MissionControl                  *mc,
+                                  TelepathyConnectionStatus        status,
+                                  McPresence                       presence,
+                                  TelepathyConnectionStatusReason  reason,
+                                  const gchar                     *unique_name,
+                                  EmpathyContactFactory           *factory)
+{
+       EmpathyContactFactoryPriv *priv = GET_PRIV (factory);
+       ContactFactoryAccountData *account_data;
+       McAccount                 *account;
+
+       account = mc_account_lookup (unique_name);
+       account_data = g_hash_table_lookup (priv->accounts, account);
+       if (account_data) {
+               contact_factory_account_data_update (account_data);
+       }
+       g_object_unref (account);
+}
+
+static ContactFactoryAccountData *
+contact_factory_account_data_get (EmpathyContactFactory *factory,
+                                 McAccount             *account)
+{
+       EmpathyContactFactoryPriv *priv = GET_PRIV (factory);
+       ContactFactoryAccountData *account_data;
+
+       account_data = g_hash_table_lookup (priv->accounts, account);
+       if (!account_data) {
+               account_data = contact_factory_account_data_new (factory, account);
+               g_hash_table_insert (priv->accounts,
+                                    g_object_ref (account),
+                                    account_data);
+       }
+
+       return account_data;
+}
+
+static void
+contact_factory_account_data_add_contact (ContactFactoryAccountData *account_data,
+                                         EmpathyContact            *contact)
+{
+       g_object_weak_ref (G_OBJECT (contact),
+                          contact_factory_weak_notify,
+                          account_data);
+       account_data->contacts = g_list_prepend (account_data->contacts, contact);
+
+       if (!account_data->presence_iface) {
+               EmpathyPresence *presence;
+
+               /* We have no presence iface, set default presence
+                * to available */
+               presence = empathy_presence_new_full (MC_PRESENCE_AVAILABLE,
+                                                    NULL);
+
+               empathy_contact_set_presence (contact, presence);
+               g_object_unref (presence);
+       }
+
+       empathy_debug (DEBUG_DOMAIN, "Contact added: %s (%d)",
+                      empathy_contact_get_id (contact),
+                      empathy_contact_get_handle (contact));
+}
+
+static void
+contact_factory_hold_handles_cb (DBusGProxy *proxy,
+                                GError     *error,
+                                gpointer    userdata)
+{
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Failed to hold handles: %s",
+                              error->message);
+       }
+}
+
+EmpathyContact *
+empathy_contact_factory_get_user (EmpathyContactFactory *factory,
+                                 McAccount             *account)
+{
+       ContactFactoryAccountData *account_data;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
+       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+
+       account_data = contact_factory_account_data_get (factory, account);
+
+       return empathy_contact_factory_get_from_handle (factory, account,
+                                                       account_data->self_handle);
+}
+
+EmpathyContact *
+empathy_contact_factory_get_from_id (EmpathyContactFactory *factory,
+                                    McAccount             *account,
+                                    const gchar           *id)
+{
+       ContactFactoryAccountData *account_data;
+       EmpathyContact            *contact;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
+       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+       g_return_val_if_fail (id != NULL, NULL);
+
+       /* Check if the contact already exists */
+       account_data = contact_factory_account_data_get (factory, account);
+       contact = contact_factory_account_data_find_by_id (account_data, id);
+       if (contact) {
+               return g_object_ref (contact);
+       }
+
+       /* Create new contact */
+       contact = g_object_new (EMPATHY_TYPE_CONTACT,
+                               "account", account,
+                               "id", id,
+                               NULL);
+       contact_factory_account_data_add_contact (account_data, contact);
+
+       /* If the account is connected, request contact's handle */
+       if (account_data->tp_conn) {
+               RequestHandlesData *data;
+               const gchar        *contact_ids[] = {id, NULL};
+               
+               account_data->nb_pending_calls++;
+               data = g_slice_new (RequestHandlesData);
+               data->account_data = account_data;
+               data->contacts = g_list_prepend (NULL, g_object_ref (contact));
+               tp_conn_request_handles_async (DBUS_G_PROXY (account_data->tp_conn),
+                                              TP_HANDLE_TYPE_CONTACT,
+                                              contact_ids,
+                                              contact_factory_request_handles_cb,
+                                              data);
+       }
+
+       return contact;
+}
+
+EmpathyContact *
+empathy_contact_factory_get_from_handle (EmpathyContactFactory *factory,
+                                        McAccount             *account,
+                                        guint                  handle)
+{
+       EmpathyContact *contact;
+       GArray         *handles;
+       GList          *contacts;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
+       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+
+       handles = g_array_new (FALSE, FALSE, sizeof (guint));
+       g_array_append_val (handles, handle);
+
+       contacts = empathy_contact_factory_get_from_handles (factory, account, handles);
+       g_array_free (handles, TRUE);
+
+       contact = contacts ? contacts->data : NULL;
+       g_list_free (contacts);
+
+       return contact;
+}
+
+GList *
+empathy_contact_factory_get_from_handles (EmpathyContactFactory *factory,
+                                         McAccount             *account,
+                                         GArray                *handles)
+{
+       ContactFactoryAccountData *account_data;
+       GList                     *contacts = NULL;
+       GArray                    *new_handles;
+       gchar                    **handles_names;
+       guint                      i;
+       GError                    *error = NULL;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory), NULL);
+       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+       g_return_val_if_fail (handles != NULL, NULL);
+
+       /* Search all contacts we already have */
+       account_data = contact_factory_account_data_get (factory, account);
+       new_handles = g_array_new (FALSE, FALSE, sizeof (guint));
+       for (i = 0; i < handles->len; i++) {
+               EmpathyContact *contact;
+               guint           handle;
+
+               handle = g_array_index (handles, guint, i);
+               if (handle == 0) {
+                       continue;
+               }
+
+               contact = contact_factory_account_data_find_by_handle (account_data, handle);
+               if (contact) {
+                       contacts = g_list_prepend (contacts, g_object_ref (contact));
+               } else {
+                       g_array_append_val (new_handles, handle);
+               }
+       }
+
+       if (new_handles->len == 0) {
+               g_array_free (new_handles, TRUE);
+               return contacts;
+       }
+
+       /* Get the IDs of all new handles */
+       if (!tp_conn_inspect_handles (DBUS_G_PROXY (account_data->tp_conn),
+                                     TP_HANDLE_TYPE_CONTACT,
+                                     new_handles,
+                                     &handles_names,
+                                     &error)) {
+               empathy_debug (DEBUG_DOMAIN, 
+                             "Couldn't inspect contact: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+               g_array_free (new_handles, TRUE);
+               return contacts;
+       }
+
+       /* Create new contacts */
+       for (i = 0; i < new_handles->len; i++) {
+               EmpathyContact *contact;
+               gchar          *id;
+               guint           handle;
+               gboolean        is_user;
+
+               id = handles_names[i];
+               handle = g_array_index (new_handles, guint, i);
+
+               is_user = (handle == account_data->self_handle);
+               contact = g_object_new (EMPATHY_TYPE_CONTACT,
+                                       "account", account,
+                                       "handle", handle,
+                                       "id", id,
+                                       "is-user", is_user,
+                                       NULL);
+               contact_factory_account_data_add_contact (account_data,
+                                                         contact);
+               contacts = g_list_prepend (contacts, contact);
+               g_free (id);
+       }
+       g_free (handles_names);
+
+       /* Hold all new handles. */
+       tp_conn_hold_handles_async (DBUS_G_PROXY (account_data->tp_conn),
+                                   TP_HANDLE_TYPE_CONTACT,
+                                   new_handles,
+                                   contact_factory_hold_handles_cb,
+                                   NULL);
+
+       contact_factory_request_everything (account_data, new_handles);
+
+       g_array_free (new_handles, TRUE);
+
+       return contacts;
+}
+
+void
+empathy_contact_factory_set_name (EmpathyContactFactory *factory,
+                                 EmpathyContact        *contact,
+                                 const gchar           *name)
+{
+       ContactFactoryAccountData *account_data;
+       McAccount                 *account;
+       GHashTable                *new_alias;
+       guint                      handle;
+
+       g_return_if_fail (EMPATHY_IS_CONTACT_FACTORY (factory));
+       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+
+       account = empathy_contact_get_account (contact);
+       account_data = contact_factory_account_data_get (factory, account);
+
+       if (!account_data->aliasing_iface) {
+               return;
+       }
+
+       handle = empathy_contact_get_handle (contact);
+
+       empathy_debug (DEBUG_DOMAIN, "Setting alias for contact %s (%d) to %s",
+                      empathy_contact_get_id (contact),
+                      handle, name);
+
+       new_alias = g_hash_table_new_full (g_direct_hash,
+                                          g_direct_equal,
+                                          NULL,
+                                          g_free);
+
+       g_hash_table_insert (new_alias,
+                            GUINT_TO_POINTER (handle),
+                            g_strdup (name));
+
+       account_data->nb_pending_calls++;
+       tp_conn_iface_aliasing_set_aliases_async (account_data->aliasing_iface,
+                                                 new_alias,
+                                                 contact_factory_set_aliases_cb,
+                                                 account_data);
+
+       g_hash_table_destroy (new_alias);
+}
+
+static void
+contact_factory_finalize (GObject *object)
+{
+       EmpathyContactFactoryPriv *priv;
+
+       priv = GET_PRIV (object);
+
+       dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
+                                       "AccountStatusChanged",
+                                       G_CALLBACK (contact_factory_status_changed_cb),
+                                       object);
+
+       g_hash_table_destroy (priv->accounts);
+       g_object_unref (priv->mc);
+
+       G_OBJECT_CLASS (empathy_contact_factory_parent_class)->finalize (object);
+}
+
+static void
+empathy_contact_factory_class_init (EmpathyContactFactoryClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = contact_factory_finalize;
+
+       g_type_class_add_private (object_class, sizeof (EmpathyContactFactoryPriv));
+}
+
+static void
+empathy_contact_factory_init (EmpathyContactFactory *factory)
+{
+       EmpathyContactFactoryPriv *priv;
+
+       priv = GET_PRIV (factory);
+
+       priv->mc = empathy_mission_control_new ();
+       priv->accounts = g_hash_table_new_full (empathy_account_hash,
+                                               empathy_account_equal,
+                                               g_object_unref,
+                                               contact_factory_account_data_free);
+
+       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
+                                    "AccountStatusChanged",
+                                    G_CALLBACK (contact_factory_status_changed_cb),
+                                    factory, NULL);
+}
+
+EmpathyContactFactory *
+empathy_contact_factory_new (void)
+{
+       static EmpathyContactFactory *factory = NULL;
+
+       if (!factory) {
+               factory = g_object_new (EMPATHY_TYPE_CONTACT_FACTORY, NULL);
+               g_object_add_weak_pointer (G_OBJECT (factory), (gpointer) &factory);
+       } else {
+               g_object_ref (factory);
+       }
+
+       return factory;
+}
+
diff --git a/libempathy/empathy-contact-factory.h b/libempathy/empathy-contact-factory.h
new file mode 100644 (file)
index 0000000..1379371
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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_CONTACT_FACTORY_H__
+#define __EMPATHY_CONTACT_FACTORY_H__
+
+#include <glib.h>
+
+#include <libmissioncontrol/mc-account.h>
+
+#include "empathy-contact.h"
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_CONTACT_FACTORY         (empathy_contact_factory_get_type ())
+#define EMPATHY_CONTACT_FACTORY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CONTACT_FACTORY, EmpathyContactFactory))
+#define EMPATHY_CONTACT_FACTORY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_CONTACT_FACTORY, EmpathyContactFactoryClass))
+#define EMPATHY_IS_CONTACT_FACTORY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CONTACT_FACTORY))
+#define EMPATHY_IS_CONTACT_FACTORY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_CONTACT_FACTORY))
+#define EMPATHY_CONTACT_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_CONTACT_FACTORY, EmpathyContactFactoryClass))
+
+typedef struct _EmpathyContactFactory      EmpathyContactFactory;
+typedef struct _EmpathyContactFactoryClass EmpathyContactFactoryClass;
+typedef struct _EmpathyContactFactoryPriv  EmpathyContactFactoryPriv;
+
+struct _EmpathyContactFactory {
+       GObject parent;
+};
+
+struct _EmpathyContactFactoryClass {
+       GObjectClass parent_class;
+};
+
+GType                  empathy_contact_factory_get_type         (void) G_GNUC_CONST;
+EmpathyContactFactory *empathy_contact_factory_new              (void);
+EmpathyContact *       empathy_contact_factory_get_user         (EmpathyContactFactory *factory,
+                                                                McAccount             *account);
+EmpathyContact *       empathy_contact_factory_get_from_id      (EmpathyContactFactory *factory,
+                                                                McAccount             *account,
+                                                                const gchar           *id);
+EmpathyContact *       empathy_contact_factory_get_from_handle  (EmpathyContactFactory *factory,
+                                                                McAccount             *account,
+                                                                guint                  handle);
+GList *                empathy_contact_factory_get_from_handles (EmpathyContactFactory *factory,
+                                                                McAccount             *account,
+                                                                GArray                *handles);
+void                   empathy_contact_factory_set_name         (EmpathyContactFactory *factory,
+                                                                EmpathyContact        *contact,
+                                                                const gchar           *name);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_CONTACT_FACTORY_H__ */
index cc388d7ec4f145a099d027ff2bfe19db48b9e292..80308314eb129a203105860fb60f3426762db3ea 100644 (file)
@@ -53,149 +53,154 @@ contact_list_base_init (gpointer klass)
        static gboolean initialized = FALSE;
 
        if (!initialized) {
        static gboolean initialized = FALSE;
 
        if (!initialized) {
-               g_signal_new ("contact-added",
+               g_signal_new ("members-changed",
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             g_cclosure_marshal_VOID__OBJECT,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING_BOOLEAN,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             1, EMPATHY_TYPE_CONTACT);
+                             5, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT,
+                             G_TYPE_UINT, G_TYPE_STRING, G_TYPE_BOOLEAN);
 
 
-               g_signal_new ("contact-removed",
+               g_signal_new ("pendings-changed",
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             g_cclosure_marshal_VOID__OBJECT,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING_BOOLEAN,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             1, EMPATHY_TYPE_CONTACT);
+                             5, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT,
+                             G_TYPE_UINT, G_TYPE_STRING, G_TYPE_BOOLEAN);
 
 
-               g_signal_new ("local-pending",
+               g_signal_new ("groups-changed",
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__OBJECT_STRING,
+                             empathy_marshal_VOID__OBJECT_STRING_BOOLEAN,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             2, EMPATHY_TYPE_CONTACT, G_TYPE_STRING);
+                             3, EMPATHY_TYPE_CONTACT, G_TYPE_STRING, G_TYPE_BOOLEAN);
 
                initialized = TRUE;
        }
 }
 
 
                initialized = TRUE;
        }
 }
 
-EmpathyContactListInfo *
-empathy_contact_list_info_new (EmpathyContact *contact,
-                              const gchar   *message)
-{
-       EmpathyContactListInfo *info;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
-
-       info = g_slice_new0 (EmpathyContactListInfo);
-       info->contact = g_object_ref (contact);
-       info->message = g_strdup (message);
-
-       return info;
-}                             
-
 void
 void
-empathy_contact_list_info_free (EmpathyContactListInfo *info)
+empathy_contact_list_add (EmpathyContactList *list,
+                         EmpathyContact     *contact,
+                         const gchar        *message)
 {
 {
-       if (!info) {
-               return;
-       }
+       g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
 
-       if (info->contact) {
-               g_object_unref (info->contact);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->add) {
+               EMPATHY_CONTACT_LIST_GET_IFACE (list)->add (list, contact, message);
        }
        }
-       g_free (info->message);
-
-       g_slice_free (EmpathyContactListInfo, info);
 }
 
 void
 }
 
 void
-empathy_contact_list_setup (EmpathyContactList *list)
+empathy_contact_list_remove (EmpathyContactList *list,
+                            EmpathyContact     *contact,
+                            const gchar        *message)
 {
        g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
 {
        g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->setup) {
-               EMPATHY_CONTACT_LIST_GET_IFACE (list)->setup (list);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->remove) {
+               EMPATHY_CONTACT_LIST_GET_IFACE (list)->remove (list, contact, message);
        }
 }
 
        }
 }
 
-EmpathyContact *
-empathy_contact_list_find (EmpathyContactList *list,
-                          const gchar        *id)
+GList *
+empathy_contact_list_get_members (EmpathyContactList *list)
 {
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
 
 {
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->find) {
-               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->find (list, id);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_members) {
+               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_members (list);
        }
 
        return NULL;
 }
 
        }
 
        return NULL;
 }
 
-void
-empathy_contact_list_add (EmpathyContactList *list,
-                         EmpathyContact      *contact,
-                         const gchar        *message)
+GList *
+empathy_contact_list_get_pendings (EmpathyContactList *list)
 {
 {
-       g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
 
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->add) {
-               EMPATHY_CONTACT_LIST_GET_IFACE (list)->add (list, contact, message);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_pendings) {
+               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_pendings (list);
        }
        }
+
+       return NULL;
 }
 
 }
 
-void
-empathy_contact_list_remove (EmpathyContactList *list,
-                            EmpathyContact      *contact,
-                            const gchar        *message)
+GList *
+empathy_contact_list_get_all_groups (EmpathyContactList *list)
 {
 {
-       g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
 
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->remove) {
-               EMPATHY_CONTACT_LIST_GET_IFACE (list)->remove (list, contact, message);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_all_groups) {
+               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_all_groups (list);
        }
        }
+
+       return NULL;
 }
 
 GList *
 }
 
 GList *
-empathy_contact_list_get_members (EmpathyContactList *list)
+empathy_contact_list_get_groups (EmpathyContactList *list,
+                                EmpathyContact     *contact)
 {
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
 {
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
 
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_members) {
-               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_members (list);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_groups) {
+               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_groups (list, contact);
        }
 
        return NULL;
 }
 
        }
 
        return NULL;
 }
 
-GList *
-empathy_contact_list_get_local_pending (EmpathyContactList *list)
+void
+empathy_contact_list_add_to_group (EmpathyContactList *list,
+                                  EmpathyContact     *contact,
+                                  const gchar        *group)
 {
 {
-       g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (list), NULL);
+       g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+       g_return_if_fail (group != NULL);
 
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_local_pending) {
-               return EMPATHY_CONTACT_LIST_GET_IFACE (list)->get_local_pending (list);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->add_to_group) {
+               EMPATHY_CONTACT_LIST_GET_IFACE (list)->add_to_group (list, contact, group);
        }
        }
+}
 
 
-       return NULL;
+void
+empathy_contact_list_remove_from_group (EmpathyContactList *list,
+                                       EmpathyContact     *contact,
+                                       const gchar        *group)
+{
+       g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+       g_return_if_fail (group != NULL);
+
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->remove_from_group) {
+               EMPATHY_CONTACT_LIST_GET_IFACE (list)->remove_from_group (list, contact, group);
+       }
 }
 
 void
 }
 
 void
-empathy_contact_list_process_pending (EmpathyContactList *list,
-                                     EmpathyContact      *contact,
-                                     gboolean            accept)
+empathy_contact_list_rename_group (EmpathyContactList *list,
+                                  const gchar        *old_group,
+                                  const gchar        *new_group)
 {
        g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
 {
        g_return_if_fail (EMPATHY_IS_CONTACT_LIST (list));
+       g_return_if_fail (old_group != NULL);
+       g_return_if_fail (new_group != NULL);
 
 
-       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->process_pending) {
-               EMPATHY_CONTACT_LIST_GET_IFACE (list)->process_pending (list,
-                                                                       contact,
-                                                                       accept);
+       if (EMPATHY_CONTACT_LIST_GET_IFACE (list)->rename_group) {
+               EMPATHY_CONTACT_LIST_GET_IFACE (list)->rename_group (list, old_group, new_group);
        }
 }
 
        }
 }
 
index 959f5c51faecfd2546b94d311e0e554f9b0087e1..4b027f083e0903ad9e3fb9b72b8a3a56dd314255 100644 (file)
@@ -26,6 +26,7 @@
 #include <glib-object.h>
 
 #include "empathy-contact.h"
 #include <glib-object.h>
 
 #include "empathy-contact.h"
+#include "empathy-tp-group.h"
 
 G_BEGIN_DECLS
 
 
 G_BEGIN_DECLS
 
@@ -37,49 +38,53 @@ G_BEGIN_DECLS
 typedef struct _EmpathyContactList      EmpathyContactList;
 typedef struct _EmpathyContactListIface EmpathyContactListIface;
 
 typedef struct _EmpathyContactList      EmpathyContactList;
 typedef struct _EmpathyContactListIface EmpathyContactListIface;
 
-typedef struct {
-       EmpathyContact *contact;
-       gchar         *message;
-} EmpathyContactListInfo;
-
 struct _EmpathyContactListIface {
        GTypeInterface   base_iface;
 
        /* VTabled */
 struct _EmpathyContactListIface {
        GTypeInterface   base_iface;
 
        /* VTabled */
-       void            (*setup)             (EmpathyContactList *list);
-       EmpathyContact * (*find)              (EmpathyContactList *list,
-                                             const gchar        *id);
-       void            (*add)               (EmpathyContactList *list,
-                                             EmpathyContact      *contact,
-                                             const gchar        *message);
-       void            (*remove)            (EmpathyContactList *list,
-                                             EmpathyContact      *contact,
-                                             const gchar        *message);
-       GList *         (*get_members)       (EmpathyContactList *list);
-       GList *         (*get_local_pending) (EmpathyContactList *list);
-       void            (*process_pending)   (EmpathyContactList *list,
-                                             EmpathyContact      *contact,
-                                             gboolean            accept);
+       void             (*add)               (EmpathyContactList *list,
+                                              EmpathyContact     *contact,
+                                              const gchar        *message);
+       void             (*remove)            (EmpathyContactList *list,
+                                              EmpathyContact     *contact,
+                                              const gchar        *message);
+       GList *          (*get_members)       (EmpathyContactList *list);
+       GList *          (*get_pendings)      (EmpathyContactList *list);
+       GList *          (*get_all_groups)    (EmpathyContactList *list);
+       GList *          (*get_groups)        (EmpathyContactList *list,
+                                              EmpathyContact     *contact);
+       void             (*add_to_group)      (EmpathyContactList *list,
+                                              EmpathyContact     *contact,
+                                              const gchar        *group);
+       void             (*remove_from_group) (EmpathyContactList *list,
+                                              EmpathyContact     *contact,
+                                              const gchar        *group);
+       void             (*rename_group)      (EmpathyContactList *list,
+                                              const gchar        *old_group,
+                                              const gchar        *new_group);
 };
 
 };
 
-GType                   empathy_contact_list_get_type          (void) G_GNUC_CONST;
-EmpathyContactListInfo *empathy_contact_list_info_new          (EmpathyContact          *contact,
-                                                               const gchar            *message);
-void                    empathy_contact_list_info_free         (EmpathyContactListInfo *info);
-void                    empathy_contact_list_setup             (EmpathyContactList     *list);
-EmpathyContact *         empathy_contact_list_find              (EmpathyContactList     *list,
-                                                               const gchar            *id);
-void                    empathy_contact_list_add               (EmpathyContactList     *list,
-                                                               EmpathyContact          *contact,
-                                                               const gchar            *message);
-void                    empathy_contact_list_remove            (EmpathyContactList     *list,
-                                                               EmpathyContact          *contact,
-                                                               const gchar            *message);
-GList *                 empathy_contact_list_get_members       (EmpathyContactList     *list);
-GList *                 empathy_contact_list_get_local_pending (EmpathyContactList     *list);
-void                    empathy_contact_list_process_pending   (EmpathyContactList     *list,
-                                                               EmpathyContact          *contact,
-                                                               gboolean                accept);
+GType    empathy_contact_list_get_type          (void) G_GNUC_CONST;
+void     empathy_contact_list_add               (EmpathyContactList *list,
+                                                EmpathyContact     *contact,
+                                                const gchar        *message);
+void     empathy_contact_list_remove            (EmpathyContactList *list,
+                                                EmpathyContact     *contact,
+                                                const gchar        *message);
+GList *  empathy_contact_list_get_members       (EmpathyContactList *list);
+GList *  empathy_contact_list_get_pendings      (EmpathyContactList *list);
+GList *  empathy_contact_list_get_all_groups    (EmpathyContactList *list);
+GList *  empathy_contact_list_get_groups        (EmpathyContactList *list,
+                                                EmpathyContact     *contact);
+void     empathy_contact_list_add_to_group      (EmpathyContactList *list,
+                                                EmpathyContact     *contact,
+                                                const gchar        *group);
+void     empathy_contact_list_remove_from_group (EmpathyContactList *list,
+                                                EmpathyContact     *contact,
+                                                const gchar        *group);
+void     empathy_contact_list_rename_group      (EmpathyContactList *list,
+                                                const gchar        *old_group,
+                                                const gchar        *new_group);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
index cc00108c856a2e2dc38745d7ce3789f357f31587..575814fab8218dc4c8df4f00a8fa6385ead136b8 100644 (file)
 struct _EmpathyContactManagerPriv {
        GHashTable     *lists;
        MissionControl *mc;
 struct _EmpathyContactManagerPriv {
        GHashTable     *lists;
        MissionControl *mc;
-       gboolean        setup;
 };
 
 };
 
-typedef struct {
-       const gchar *old_group;
-       const gchar *new_group;
-} ContactManagerRenameGroupData;
-
-typedef struct {
-       EmpathyContact *contact;
-       const gchar   *id;
-} ContactManagerFindData;
-
-static void           empathy_contact_manager_class_init   (EmpathyContactManagerClass      *klass);
-static void           contact_manager_iface_init           (EmpathyContactListIface         *iface);
-static void           empathy_contact_manager_init         (EmpathyContactManager           *manager);
-static void           contact_manager_finalize             (GObject                         *object);
-static void           contact_manager_setup                (EmpathyContactList              *manager);
-static EmpathyContact *contact_manager_find                 (EmpathyContactList              *manager,
-                                                           const gchar                     *id);
-static void           contact_manager_add                  (EmpathyContactList              *manager,
-                                                           EmpathyContact                   *contact,
-                                                           const gchar                     *message);
-static void           contact_manager_remove               (EmpathyContactList              *manager,
-                                                           EmpathyContact                   *contact,
-                                                           const gchar                     *message);
-static GList *        contact_manager_get_members          (EmpathyContactList              *manager);
-static GList *        contact_manager_get_local_pending    (EmpathyContactList              *manager);
-static void           contact_manager_process_pending      (EmpathyContactList              *manager,
-                                                           EmpathyContact                   *contact,
-                                                           gboolean                         accept);
-static void           contact_manager_setup_foreach        (McAccount                       *account,
-                                                           EmpathyTpContactList            *list,
-                                                           EmpathyContactManager           *manager);
-static gboolean       contact_manager_find_foreach         (McAccount                       *account,
-                                                           EmpathyTpContactList            *list,
-                                                           ContactManagerFindData          *data);
-static void           contact_manager_add_account          (EmpathyContactManager           *manager,
-                                                           McAccount                       *account);
-static void           contact_manager_added_cb             (EmpathyTpContactList            *list,
-                                                           EmpathyContact                   *contact,
-                                                           EmpathyContactManager           *manager);
-static void           contact_manager_removed_cb           (EmpathyTpContactList            *list,
-                                                           EmpathyContact                   *contact,
-                                                           EmpathyContactManager           *manager);
-static void           contact_manager_local_pending_cb     (EmpathyTpContactList            *list,
-                                                           EmpathyContact                   *contact,
-                                                           const gchar                     *message,
-                                                           EmpathyContactManager           *manager);
-static void           contact_manager_destroy_cb           (EmpathyTpContactList            *list,
-                                                           EmpathyContactManager           *manager);
-static void           contact_manager_rename_group_foreach (McAccount                       *account,
-                                                           EmpathyTpContactList            *list,
-                                                           ContactManagerRenameGroupData   *data);
-static void           contact_manager_get_groups_foreach   (McAccount                       *account,
-                                                           EmpathyTpContactList            *list,
-                                                           GList                          **all_groups);
-static void           contact_manager_get_members_foreach  (McAccount                       *account,
-                                                           EmpathyTpContactList            *list,
-                                                           GList                          **contacts);
-static void           contact_manager_get_local_pending_foreach (McAccount                  *account,
-                                                           EmpathyTpContactList            *list,
-                                                           GList                          **contacts);
-static void           contact_manager_status_changed_cb    (MissionControl                  *mc,
-                                                           TelepathyConnectionStatus        status,
-                                                           McPresence                       presence,
-                                                           TelepathyConnectionStatusReason  reason,
-                                                           const gchar                     *unique_name,
-                                                           EmpathyContactManager           *manager);
+static void empathy_contact_manager_class_init (EmpathyContactManagerClass *klass);
+static void empathy_contact_manager_init       (EmpathyContactManager      *manager);
+static void contact_manager_iface_init         (EmpathyContactListIface    *iface);
 
 G_DEFINE_TYPE_WITH_CODE (EmpathyContactManager, empathy_contact_manager, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
                                                contact_manager_iface_init));
 
 static void
 
 G_DEFINE_TYPE_WITH_CODE (EmpathyContactManager, empathy_contact_manager, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
                                                contact_manager_iface_init));
 
 static void
-empathy_contact_manager_class_init (EmpathyContactManagerClass *klass)
+contact_manager_members_changed_cb (EmpathyTpContactList  *list,
+                                   EmpathyContact        *contact,
+                                   EmpathyContact        *actor,
+                                   guint                  reason,
+                                   gchar                 *message,
+                                   gboolean               is_member,
+                                   EmpathyContactManager *manager)
 {
 {
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       g_signal_emit_by_name (manager, "members-changed",
+                              contact, actor, reason, message, is_member);
+}
 
 
-       object_class->finalize = contact_manager_finalize;
+static void
+contact_manager_pendings_changed_cb (EmpathyTpContactList  *list,
+                                    EmpathyContact        *contact,
+                                    EmpathyContact        *actor,
+                                    guint                  reason,
+                                    gchar                 *message,
+                                    gboolean               is_pending,
+                                    EmpathyContactManager *manager)
+{
+       g_signal_emit_by_name (manager, "pendings-changed",
+                              contact, actor, reason, message, is_pending);
+}
 
 
-       g_type_class_add_private (object_class, sizeof (EmpathyContactManagerPriv));
+static void
+contact_manager_groups_changed_cb (EmpathyTpContactList  *list,
+                                  EmpathyContact        *contact,
+                                  gchar                 *group,
+                                  gboolean               is_member,
+                                  EmpathyContactManager *manager)
+{
+       g_signal_emit_by_name (manager, "groups-changed",
+                              contact, group, is_member);
 }
 
 }
 
+static void contact_manager_destroy_cb (EmpathyTpContactList  *list,
+                                       EmpathyContactManager *manager);
+
 static void
 static void
-contact_manager_iface_init (EmpathyContactListIface *iface)
+contact_manager_disconnect_foreach (gpointer key,
+                                   gpointer value,
+                                   gpointer user_data)
 {
 {
-       iface->setup             = contact_manager_setup;
-       iface->find              = contact_manager_find;
-       iface->add               = contact_manager_add;
-       iface->remove            = contact_manager_remove;
-       iface->get_members       = contact_manager_get_members;
-       iface->get_local_pending = contact_manager_get_local_pending;
-       iface->process_pending   = contact_manager_process_pending;
+       EmpathyTpContactList  *list = value;
+       EmpathyContactManager *manager = user_data;
+
+       /* Disconnect signals from the list */
+       g_signal_handlers_disconnect_by_func (list,
+                                             contact_manager_members_changed_cb,
+                                             manager);
+       g_signal_handlers_disconnect_by_func (list,
+                                             contact_manager_pendings_changed_cb,
+                                             manager);
+       g_signal_handlers_disconnect_by_func (list,
+                                             contact_manager_groups_changed_cb,
+                                             manager);
+       g_signal_handlers_disconnect_by_func (list,
+                                             contact_manager_destroy_cb,
+                                             manager);
+}
+
+static void
+contact_manager_destroy_cb (EmpathyTpContactList  *list,
+                           EmpathyContactManager *manager)
+{
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       McAccount                 *account;
+
+       account = empathy_tp_contact_list_get_account (list);
+
+       empathy_debug (DEBUG_DOMAIN, "Removing account: %s",
+                      mc_account_get_display_name (account));
+
+       contact_manager_disconnect_foreach (account, list, manager);
+       g_hash_table_remove (priv->lists, account);
+}
+
+static void
+contact_manager_add_account (EmpathyContactManager *manager,
+                            McAccount             *account)
+{
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       EmpathyTpContactList      *list;
+
+       if (g_hash_table_lookup (priv->lists, account)) {
+               return;
+       }
+
+       empathy_debug (DEBUG_DOMAIN, "Adding new account: %s",
+                      mc_account_get_display_name (account));
+
+       list = empathy_tp_contact_list_new (account);
+       if (!list) {
+               return;
+       }
+
+       g_hash_table_insert (priv->lists, g_object_ref (account), list);
+
+       /* Connect signals */
+       g_signal_connect (list, "members-changed",
+                         G_CALLBACK (contact_manager_members_changed_cb),
+                         manager);
+       g_signal_connect (list, "pendings-changed",
+                         G_CALLBACK (contact_manager_pendings_changed_cb),
+                         manager);
+       g_signal_connect (list, "groups-changed",
+                         G_CALLBACK (contact_manager_groups_changed_cb),
+                         manager);
+       g_signal_connect (list, "destroy",
+                         G_CALLBACK (contact_manager_destroy_cb),
+                         manager);
+}
+
+static void
+contact_manager_status_changed_cb (MissionControl                  *mc,
+                                  TelepathyConnectionStatus        status,
+                                  McPresence                       presence,
+                                  TelepathyConnectionStatusReason  reason,
+                                  const gchar                     *unique_name,
+                                  EmpathyContactManager           *manager)
+{
+       McAccount *account;
+
+       if (status != TP_CONN_STATUS_CONNECTED) {
+               /* We only care about newly connected accounts */
+               return;
+       }
+
+       account = mc_account_lookup (unique_name);
+       contact_manager_add_account (manager, account);
+       g_object_unref (account);
+}
+
+static void
+contact_manager_finalize (GObject *object)
+{
+       EmpathyContactManagerPriv *priv = GET_PRIV (object);
+
+       g_hash_table_foreach (priv->lists,
+                             contact_manager_disconnect_foreach,
+                             object);
+       g_hash_table_destroy (priv->lists);
+       g_object_unref (priv->mc);
+}
+
+static void
+empathy_contact_manager_class_init (EmpathyContactManagerClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = contact_manager_finalize;
+
+       g_type_class_add_private (object_class, sizeof (EmpathyContactManagerPriv));
 }
 
 static void
 }
 
 static void
@@ -158,27 +229,12 @@ empathy_contact_manager_init (EmpathyContactManager *manager)
        /* Get ContactList for existing connections */
        accounts = mission_control_get_online_connections (priv->mc, NULL);
        for (l = accounts; l; l = l->next) {
        /* Get ContactList for existing connections */
        accounts = mission_control_get_online_connections (priv->mc, NULL);
        for (l = accounts; l; l = l->next) {
-               McAccount *account;
-
-               account = l->data;
-               contact_manager_add_account (manager, account);
-               
-               g_object_unref (account);
+               contact_manager_add_account (manager, l->data);
+               g_object_unref (l->data);
        }
        g_slist_free (accounts);
 }
 
        }
        g_slist_free (accounts);
 }
 
-static void
-contact_manager_finalize (GObject *object)
-{
-       EmpathyContactManagerPriv *priv;
-
-       priv = GET_PRIV (object);
-
-       g_hash_table_destroy (priv->lists);
-       g_object_unref (priv->mc);
-}
-
 EmpathyContactManager *
 empathy_contact_manager_new (void)
 {
 EmpathyContactManager *
 empathy_contact_manager_new (void)
 {
@@ -194,62 +250,28 @@ empathy_contact_manager_new (void)
        return manager;
 }
 
        return manager;
 }
 
-static void
-contact_manager_setup (EmpathyContactList *manager)
-{
-       EmpathyContactManagerPriv *priv;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
-
-       priv = GET_PRIV (manager);
-
-       if (priv->setup) {
-               /* Already done */
-               return;
-       }
-
-       g_hash_table_foreach (priv->lists,
-                             (GHFunc) contact_manager_setup_foreach,
-                             manager);
-
-       priv->setup = TRUE;
-}
-
-static EmpathyContact *
-contact_manager_find (EmpathyContactList *manager,
-                     const gchar        *id)
+EmpathyTpContactList *
+empathy_contact_manager_get_list (EmpathyContactManager *manager,
+                                 McAccount             *account)
 {
 {
-       EmpathyContactManagerPriv *priv;
-       ContactManagerFindData     data;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
-       g_return_val_if_fail (id != NULL, NULL);
-
-       priv = GET_PRIV (manager);
-
-       data.contact = NULL;
-       data.id = id;
-
-       g_hash_table_find (priv->lists,
-                          (GHRFunc) contact_manager_find_foreach,
-                          &data);
+       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
 
 
-       return data.contact;
+       return g_hash_table_lookup (priv->lists, account);
 }
 
 static void
 contact_manager_add (EmpathyContactList *manager,
 }
 
 static void
 contact_manager_add (EmpathyContactList *manager,
-                    EmpathyContact      *contact,
+                    EmpathyContact     *contact,
                     const gchar        *message)
 {
                     const gchar        *message)
 {
-       EmpathyContactManagerPriv *priv;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
        EmpathyContactList        *list;
        McAccount                 *account;
 
        g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
        EmpathyContactList        *list;
        McAccount                 *account;
 
        g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-       priv = GET_PRIV (manager);
 
        account = empathy_contact_get_account (contact);
        list = g_hash_table_lookup (priv->lists, account);
 
        account = empathy_contact_get_account (contact);
        list = g_hash_table_lookup (priv->lists, account);
@@ -264,14 +286,11 @@ contact_manager_remove (EmpathyContactList *manager,
                        EmpathyContact      *contact,
                        const gchar        *message)
 {
                        EmpathyContact      *contact,
                        const gchar        *message)
 {
-       EmpathyContactManagerPriv *priv;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
        EmpathyContactList        *list;
        McAccount                 *account;
 
        g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
        EmpathyContactList        *list;
        McAccount                 *account;
 
        g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-       priv = GET_PRIV (manager);
 
        account = empathy_contact_get_account (contact);
        list = g_hash_table_lookup (priv->lists, account);
 
        account = empathy_contact_get_account (contact);
        list = g_hash_table_lookup (priv->lists, account);
@@ -281,16 +300,25 @@ contact_manager_remove (EmpathyContactList *manager,
        }
 }
 
        }
 }
 
+static void
+contact_manager_get_members_foreach (McAccount             *account,
+                                    EmpathyTpContactList  *list,
+                                    GList                **contacts)
+{
+       GList *l;
+
+       l = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (list));
+       *contacts = g_list_concat (*contacts, l);
+}
+
 static GList *
 contact_manager_get_members (EmpathyContactList *manager)
 {
 static GList *
 contact_manager_get_members (EmpathyContactList *manager)
 {
-       EmpathyContactManagerPriv *priv;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
        GList                     *contacts = NULL;
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
 
        GList                     *contacts = NULL;
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
 
-       priv = GET_PRIV (manager);
-
        g_hash_table_foreach (priv->lists,
                              (GHFunc) contact_manager_get_members_foreach,
                              &contacts);
        g_hash_table_foreach (priv->lists,
                              (GHFunc) contact_manager_get_members_foreach,
                              &contacts);
@@ -298,337 +326,169 @@ contact_manager_get_members (EmpathyContactList *manager)
        return contacts;
 }
 
        return contacts;
 }
 
-static GList *
-contact_manager_get_local_pending (EmpathyContactList *manager)
-{
-       EmpathyContactManagerPriv *priv;
-       GList                     *pending = NULL;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
-
-       priv = GET_PRIV (manager);
-
-       g_hash_table_foreach (priv->lists,
-                             (GHFunc) contact_manager_get_local_pending_foreach,
-                             &pending);
-
-       return pending;
-}
-
 static void
 static void
-contact_manager_process_pending (EmpathyContactList *manager,
-                                EmpathyContact      *contact,
-                                gboolean            accept)
+contact_manager_get_pendings_foreach (McAccount             *account,
+                                     EmpathyTpContactList  *list,
+                                     GList                **contacts)
 {
 {
-       EmpathyContactManagerPriv *priv;
-       EmpathyContactList        *list;
-       McAccount                 *account;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-       priv = GET_PRIV (manager);
-
-       account = empathy_contact_get_account (contact);
-       list = g_hash_table_lookup (priv->lists, account);
-
-       if (list) {
-               empathy_contact_list_process_pending (list, contact, accept);
-       }
-}
-
-EmpathyTpContactList *
-empathy_contact_manager_get_list (EmpathyContactManager *manager,
-                                 McAccount             *account)
-{
-       EmpathyContactManagerPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
-       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
-
-       priv = GET_PRIV (manager);
+       GList *l;
 
 
-       return g_hash_table_lookup (priv->lists, account);
+       l = empathy_contact_list_get_pendings (EMPATHY_CONTACT_LIST (list));
+       *contacts = g_list_concat (*contacts, l);
 }
 
 }
 
-EmpathyContact *
-empathy_contact_manager_get_user (EmpathyContactManager *manager,
-                                 McAccount             *account)
+static GList *
+contact_manager_get_pendings (EmpathyContactList *manager)
 {
 {
-       EmpathyContactManagerPriv *priv;
-       EmpathyTpContactList        *list;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       GList                     *contacts = NULL;
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
-       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
-
-       priv = GET_PRIV (manager);
 
 
-       list = g_hash_table_lookup (priv->lists, account);
-       
-       if (!list) {
-               return NULL;
-       }
+       g_hash_table_foreach (priv->lists,
+                             (GHFunc) contact_manager_get_pendings_foreach,
+                             &contacts);
 
 
-       return empathy_tp_contact_list_get_user (list);
+       return contacts;
 }
 
 }
 
-EmpathyContact *
-empathy_contact_manager_create (EmpathyContactManager *manager,
-                               McAccount             *account,
-                               const gchar           *id)
+static void
+contact_manager_get_all_groups_foreach (McAccount             *account,
+                                       EmpathyTpContactList  *list,
+                                       GList                **all_groups)
 {
 {
-       EmpathyContactManagerPriv *priv;
-       EmpathyTpContactList      *list;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
-       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
-       g_return_val_if_fail (id != NULL, NULL);
-
-       priv = GET_PRIV (manager);
+       GList *groups, *l;
 
 
-       list = g_hash_table_lookup (priv->lists, account);
-       
-       if (!list) {
-               return NULL;
+       groups = empathy_contact_list_get_all_groups (EMPATHY_CONTACT_LIST (list));
+       for (l = groups; l; l = l->next) {
+               if (!g_list_find_custom (*all_groups,
+                                        l->data,
+                                        (GCompareFunc) strcmp)) {
+                       *all_groups = g_list_prepend (*all_groups, l->data);
+               } else {
+                       g_free (l->data);
+               }
        }
 
        }
 
-       return empathy_tp_contact_list_get_from_id (list, id);
-}
-
-void
-empathy_contact_manager_rename_group (EmpathyContactManager *manager,
-                                     const gchar           *old_group,
-                                     const gchar           *new_group)
-{
-       EmpathyContactManagerPriv   *priv;
-       ContactManagerRenameGroupData  data;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
-       g_return_if_fail (old_group != NULL);
-       g_return_if_fail (new_group != NULL);
-
-       priv = GET_PRIV (manager);
-
-       data.old_group = old_group;
-       data.new_group = new_group;
-
-       g_hash_table_foreach (priv->lists,
-                             (GHFunc) contact_manager_rename_group_foreach,
-                             &data);
+       g_list_free (groups);
 }
 
 }
 
-GList *
-empathy_contact_manager_get_groups (EmpathyContactManager *manager)
+static GList *
+contact_manager_get_all_groups (EmpathyContactList *manager)
 {
 {
-       EmpathyContactManagerPriv *priv;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
        GList                     *groups = NULL;
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
 
        GList                     *groups = NULL;
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
 
-       priv = GET_PRIV (manager);
-
        g_hash_table_foreach (priv->lists,
        g_hash_table_foreach (priv->lists,
-                             (GHFunc) contact_manager_get_groups_foreach,
+                             (GHFunc) contact_manager_get_all_groups_foreach,
                              &groups);
 
        return groups;
 }
 
                              &groups);
 
        return groups;
 }
 
-static void
-contact_manager_setup_foreach (McAccount             *account,
-                              EmpathyTpContactList  *list,
-                              EmpathyContactManager *manager)
+static GList *
+contact_manager_get_groups (EmpathyContactList *manager,
+                           EmpathyContact     *contact)
 {
 {
-       empathy_contact_list_setup (EMPATHY_CONTACT_LIST (list));
-}
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       EmpathyContactList        *list;
+       McAccount                 *account;
 
 
-static gboolean
-contact_manager_find_foreach (McAccount              *account,
-                             EmpathyTpContactList   *list,
-                              ContactManagerFindData *data)
-{
-       data->contact = empathy_contact_list_find (EMPATHY_CONTACT_LIST (list),
-                                                  data->id);
+       g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), NULL);
+
+       account = empathy_contact_get_account (contact);
+       list = g_hash_table_lookup (priv->lists, account);
 
 
-       if (data->contact) {
-               return TRUE;
+       if (list) {
+               return empathy_contact_list_get_groups (list, contact);
        }
 
        }
 
-       return FALSE;
+       return NULL;
 }
 
 static void
 }
 
 static void
-contact_manager_add_account (EmpathyContactManager *manager,
-                            McAccount             *account)
+contact_manager_add_to_group (EmpathyContactList *manager,
+                             EmpathyContact     *contact,
+                             const gchar        *group)
 {
 {
-       EmpathyContactManagerPriv *priv;
-       EmpathyTpContactList        *list;
-
-       priv = GET_PRIV (manager);
-
-       if (g_hash_table_lookup (priv->lists, account)) {
-               return;
-       }
-
-       empathy_debug (DEBUG_DOMAIN, "Adding new account: %s",
-                     mc_account_get_display_name (account));
-
-       list = empathy_tp_contact_list_new (account);
-       if (!list) {
-               return;
-       }
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       EmpathyContactList        *list;
+       McAccount                 *account;
 
 
-       g_hash_table_insert (priv->lists, g_object_ref (account), list);
+       g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
 
 
-       /* Connect signals */
-       g_signal_connect (list, "contact-added",
-                         G_CALLBACK (contact_manager_added_cb),
-                         manager);
-       g_signal_connect (list, "contact-removed",
-                         G_CALLBACK (contact_manager_removed_cb),
-                         manager);
-       g_signal_connect (list, "local-pending",
-                         G_CALLBACK (contact_manager_local_pending_cb),
-                         manager);
-       g_signal_connect (list, "destroy",
-                         G_CALLBACK (contact_manager_destroy_cb),
-                         manager);
+       account = empathy_contact_get_account (contact);
+       list = g_hash_table_lookup (priv->lists, account);
 
 
-       if (priv->setup) {
-               empathy_contact_list_setup (EMPATHY_CONTACT_LIST (list));
+       if (list) {
+               empathy_contact_list_add_to_group (list, contact, group);
        }
 }
 
 static void
        }
 }
 
 static void
-contact_manager_added_cb (EmpathyTpContactList  *list,
-                         EmpathyContact         *contact,
-                         EmpathyContactManager *manager)
+contact_manager_remove_from_group (EmpathyContactList *manager,
+                                  EmpathyContact     *contact,
+                                  const gchar        *group)
 {
 {
-       g_signal_emit_by_name (manager, "contact-added", contact);
-}
-
-static void
-contact_manager_removed_cb (EmpathyTpContactList  *list,
-                           EmpathyContact         *contact,
-                           EmpathyContactManager *manager)
-{
-       g_signal_emit_by_name (manager, "contact-removed", contact);
-}
-
-static void
-contact_manager_local_pending_cb (EmpathyTpContactList  *list,
-                                 EmpathyContact         *contact,
-                                 const gchar           *message,
-                                 EmpathyContactManager *manager)
-{
-       g_signal_emit_by_name (manager, "local-pending", contact, message);
-}
-
-static void
-contact_manager_destroy_cb (EmpathyTpContactList  *list,
-                           EmpathyContactManager *manager)
-{
-       EmpathyContactManagerPriv *priv;
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       EmpathyContactList        *list;
        McAccount                 *account;
 
        McAccount                 *account;
 
-       priv = GET_PRIV (manager);
-
-       account = empathy_tp_contact_list_get_account (list);
-
-       empathy_debug (DEBUG_DOMAIN, "Removing account: %s",
-                     mc_account_get_display_name (account));
+       g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
 
 
-       /* Disconnect signals from the list */
-       g_signal_handlers_disconnect_by_func (list,
-                                             contact_manager_added_cb,
-                                             manager);
-       g_signal_handlers_disconnect_by_func (list,
-                                             contact_manager_removed_cb,
-                                             manager);
-       g_signal_handlers_disconnect_by_func (list,
-                                             contact_manager_local_pending_cb,
-                                             manager);
-       g_signal_handlers_disconnect_by_func (list,
-                                             contact_manager_destroy_cb,
-                                             manager);
+       account = empathy_contact_get_account (contact);
+       list = g_hash_table_lookup (priv->lists, account);
 
 
-       g_hash_table_remove (priv->lists, account);
+       if (list) {
+               empathy_contact_list_remove_from_group (list, contact, group);
+       }
 }
 
 }
 
-static void
-contact_manager_rename_group_foreach (McAccount                     *account,
-                                     EmpathyTpContactList          *list,
-                                     ContactManagerRenameGroupData *data)
-{
-       empathy_tp_contact_list_rename_group (list,
-                                             data->old_group,
-                                             data->new_group);
-}
+typedef struct {
+       const gchar *old_group;
+       const gchar *new_group;
+} RenameGroupData;
 
 static void
 
 static void
-contact_manager_get_groups_foreach (McAccount             *account,
-                                   EmpathyTpContactList  *list,
-                                   GList                **all_groups)
+contact_manager_rename_group_foreach (McAccount            *account,
+                                     EmpathyTpContactList *list,
+                                     RenameGroupData      *data)
 {
 {
-       GList *groups, *l;
-
-       groups = empathy_tp_contact_list_get_groups (list);
-       for (l = groups; l; l = l->next) {
-               if (!g_list_find_custom (*all_groups,
-                                        l->data,
-                                        (GCompareFunc) strcmp)) {
-                       *all_groups = g_list_append (*all_groups,
-                                                    g_strdup (l->data));
-               }
-               g_free (l->data);
-       }
-
-       g_list_free (groups);
+       empathy_contact_list_rename_group (EMPATHY_CONTACT_LIST (list),
+                                          data->old_group,
+                                          data->new_group);
 }
 
 static void
 }
 
 static void
-contact_manager_get_members_foreach (McAccount             *account,
-                                    EmpathyTpContactList  *list,
-                                    GList                **contacts)
+contact_manager_rename_group (EmpathyContactList *manager,
+                             const gchar        *old_group,
+                             const gchar        *new_group)
 {
 {
-       GList *l;
-
-       l = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (list));
-       *contacts = g_list_concat (*contacts, l);
-}
+       EmpathyContactManagerPriv *priv = GET_PRIV (manager);
+       RenameGroupData            data;
 
 
-static void
-contact_manager_get_local_pending_foreach (McAccount             *account,
-                                          EmpathyTpContactList  *list,
-                                          GList                **contacts)
-{
-       GList *l;
+       g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
 
 
-       l = empathy_contact_list_get_local_pending (EMPATHY_CONTACT_LIST (list));
-       *contacts = g_list_concat (*contacts, l);
+       data.old_group = old_group;
+       data.new_group = new_group;
+       g_hash_table_foreach (priv->lists,
+                             (GHFunc) contact_manager_rename_group_foreach,
+                             &data);
 }
 
 static void
 }
 
 static void
-contact_manager_status_changed_cb (MissionControl                  *mc,
-                                  TelepathyConnectionStatus        status,
-                                  McPresence                       presence,
-                                  TelepathyConnectionStatusReason  reason,
-                                  const gchar                     *unique_name,
-                                  EmpathyContactManager           *manager)
+contact_manager_iface_init (EmpathyContactListIface *iface)
 {
 {
-       EmpathyContactManagerPriv *priv;
-       McAccount                 *account;
-
-       priv = GET_PRIV (manager);
-
-       if (status != TP_CONN_STATUS_CONNECTED) {
-               /* We only care about newly connected accounts */
-               return;
-       }
-
-       account = mc_account_lookup (unique_name);
-       contact_manager_add_account (manager, account);
-
-       g_object_unref (account);
+       iface->add               = contact_manager_add;
+       iface->remove            = contact_manager_remove;
+       iface->get_members       = contact_manager_get_members;
+       iface->get_pendings      = contact_manager_get_pendings;
+       iface->get_all_groups    = contact_manager_get_all_groups;
+       iface->get_groups        = contact_manager_get_groups;
+       iface->add_to_group      = contact_manager_add_to_group;
+       iface->remove_from_group = contact_manager_remove_from_group;
+       iface->rename_group      = contact_manager_rename_group;
 }
 
 }
 
index 768301ae72aad05fd202901acefcc395c6c9f3f0..41144cf43cfd2685425e2f4c7e05edc02380136a 100644 (file)
@@ -51,19 +51,10 @@ struct _EmpathyContactManagerClass {
        GObjectClass parent_class;
 };
 
        GObjectClass parent_class;
 };
 
-GType                  empathy_contact_manager_get_type     (void) G_GNUC_CONST;
-EmpathyContactManager *empathy_contact_manager_new          (void);
-EmpathyTpContactList * empathy_contact_manager_get_list     (EmpathyContactManager *manager,
-                                                            McAccount             *account);
-EmpathyContact *        empathy_contact_manager_get_user     (EmpathyContactManager *manager,
-                                                            McAccount             *account);
-EmpathyContact *        empathy_contact_manager_create       (EmpathyContactManager *manager,
-                                                            McAccount             *account,
-                                                            const gchar           *id);
-void                   empathy_contact_manager_rename_group (EmpathyContactManager *manager,
-                                                            const gchar           *old_group,
-                                                            const gchar           *new_group);
-GList *                empathy_contact_manager_get_groups   (EmpathyContactManager *manager);
+GType                  empathy_contact_manager_get_type (void) G_GNUC_CONST;
+EmpathyContactManager *empathy_contact_manager_new      (void);
+EmpathyTpContactList * empathy_contact_manager_get_list (EmpathyContactManager *manager,
+                                                        McAccount             *account);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
index d3935ad6c80d43d6da075fe64b0de0d799054288..505e190c0d92da363739ab2c5252ae0a85840752 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2004-2007 Imendio AB
+ * Copyright (C) 2004 Imendio AB
+ * 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
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -19,6 +20,7 @@
  *
  * Authors: Mikael Hallendal <micke@imendio.com>
  *          Martyn Russell <martyn@imendio.com>
  *
  * Authors: Mikael Hallendal <micke@imendio.com>
  *          Martyn Russell <martyn@imendio.com>
+ *          Xavier Claessens <xclaesse@gmail.com>
  */
 
 #include "config.h"
  */
 
 #include "config.h"
@@ -41,26 +43,26 @@ typedef struct _EmpathyContactPriv EmpathyContactPriv;
 struct _EmpathyContactPriv {
        gchar              *id;
        gchar              *name;
 struct _EmpathyContactPriv {
        gchar              *id;
        gchar              *name;
-       EmpathyAvatar       *avatar;
+       EmpathyAvatar      *avatar;
        McAccount          *account;
        McAccount          *account;
-       EmpathyPresence     *presence;
-       GList              *groups;
-       EmpathySubscription  subscription;
+       EmpathyPresence    *presence;
        guint               handle;
        gboolean            is_user;
 };
 
        guint               handle;
        gboolean            is_user;
 };
 
-static void contact_class_init    (EmpathyContactClass *class);
-static void contact_init          (EmpathyContact      *contact);
-static void contact_finalize      (GObject            *object);
-static void contact_get_property  (GObject            *object,
-                                  guint               param_id,
-                                  GValue             *value,
-                                  GParamSpec         *pspec);
-static void contact_set_property  (GObject            *object,
-                                  guint               param_id,
-                                  const GValue       *value,
-                                  GParamSpec         *pspec);
+static void empathy_contact_class_init (EmpathyContactClass *class);
+static void empathy_contact_init       (EmpathyContact      *contact);
+static void contact_finalize           (GObject             *object);
+static void contact_get_property       (GObject             *object,
+                                       guint                param_id,
+                                       GValue              *value,
+                                       GParamSpec          *pspec);
+static void contact_set_property       (GObject             *object,
+                                       guint                param_id,
+                                       const GValue        *value,
+                                       GParamSpec          *pspec);
+
+G_DEFINE_TYPE (EmpathyContact, empathy_contact, G_TYPE_OBJECT);
 
 enum {
        PROP_0,
 
 enum {
        PROP_0,
@@ -75,41 +77,12 @@ enum {
        PROP_IS_USER
 };
 
        PROP_IS_USER
 };
 
-static gpointer parent_class = NULL;
-
-GType
-empathy_contact_get_gtype (void)
-{
-       static GType type = 0;
-
-       if (!type) {
-               static const GTypeInfo info = {
-                       sizeof (EmpathyContactClass),
-                       NULL, /* base_init */
-                       NULL, /* base_finalize */
-                       (GClassInitFunc) contact_class_init,
-                       NULL, /* class_finalize */
-                       NULL, /* class_data */
-                       sizeof (EmpathyContact),
-                       0,    /* n_preallocs */
-                       (GInstanceInitFunc) contact_init
-               };
-
-               type = g_type_register_static (G_TYPE_OBJECT,
-                                              "EmpathyContact",
-                                              &info, 0);
-       }
-
-       return type;
-}
-
 static void
 static void
-contact_class_init (EmpathyContactClass *class)
+empathy_contact_class_init (EmpathyContactClass *class)
 {
        GObjectClass *object_class;
 
        object_class = G_OBJECT_CLASS (class);
 {
        GObjectClass *object_class;
 
        object_class = G_OBJECT_CLASS (class);
-       parent_class = g_type_class_peek_parent (class);
 
        object_class->finalize     = contact_finalize;
        object_class->get_property = contact_get_property;
 
        object_class->finalize     = contact_finalize;
        object_class->get_property = contact_get_property;
@@ -155,23 +128,6 @@ contact_class_init (EmpathyContactClass *class)
                                                              EMPATHY_TYPE_PRESENCE,
                                                              G_PARAM_READWRITE));
 
                                                              EMPATHY_TYPE_PRESENCE,
                                                              G_PARAM_READWRITE));
 
-       g_object_class_install_property (object_class,
-                                        PROP_GROUPS,
-                                        g_param_spec_pointer ("groups",
-                                                              "Contact groups",
-                                                              "Groups of contact",
-                                                              G_PARAM_READWRITE));
-
-       g_object_class_install_property (object_class,
-                                        PROP_SUBSCRIPTION,
-                                        g_param_spec_flags ("subscription",
-                                                            "Contact Subscription",
-                                                            "The subscription status of the contact",
-                                                            EMPATHY_TYPE_SUBSCRIPTION,
-                                                            EMPATHY_SUBSCRIPTION_NONE,
-                                                            G_PARAM_READWRITE));
-
-
        g_object_class_install_property (object_class,
                                         PROP_HANDLE,
                                         g_param_spec_uint ("handle",
        g_object_class_install_property (object_class,
                                         PROP_HANDLE,
                                         g_param_spec_uint ("handle",
@@ -193,7 +149,7 @@ contact_class_init (EmpathyContactClass *class)
 }
 
 static void
 }
 
 static void
-contact_init (EmpathyContact *contact)
+empathy_contact_init (EmpathyContact *contact)
 {
 }
 
 {
 }
 
@@ -217,16 +173,11 @@ contact_finalize (GObject *object)
                g_object_unref (priv->presence);
        }
 
                g_object_unref (priv->presence);
        }
 
-       if (priv->groups) {
-               g_list_foreach (priv->groups, (GFunc) g_free, NULL);
-               g_list_free (priv->groups);
-       }
-
        if (priv->account) {
                g_object_unref (priv->account);
        }
 
        if (priv->account) {
                g_object_unref (priv->account);
        }
 
-       (G_OBJECT_CLASS (parent_class)->finalize) (object);
+       G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
 }
 
 static void
 }
 
 static void
@@ -257,12 +208,6 @@ contact_get_property (GObject    *object,
        case PROP_PRESENCE:
                g_value_set_object (value, priv->presence);
                break;
        case PROP_PRESENCE:
                g_value_set_object (value, priv->presence);
                break;
-       case PROP_GROUPS:
-               g_value_set_pointer (value, priv->groups);
-               break;
-       case PROP_SUBSCRIPTION:
-               g_value_set_flags (value, priv->subscription);
-               break;
        case PROP_HANDLE:
                g_value_set_uint (value, priv->handle);
                break;
        case PROP_HANDLE:
                g_value_set_uint (value, priv->handle);
                break;
@@ -306,14 +251,6 @@ contact_set_property (GObject      *object,
                empathy_contact_set_presence (EMPATHY_CONTACT (object),
                                             EMPATHY_PRESENCE (g_value_get_object (value)));
                break;
                empathy_contact_set_presence (EMPATHY_CONTACT (object),
                                             EMPATHY_PRESENCE (g_value_get_object (value)));
                break;
-       case PROP_GROUPS:
-               empathy_contact_set_groups (EMPATHY_CONTACT (object),
-                                          g_value_get_pointer (value));
-               break;
-       case PROP_SUBSCRIPTION:
-               empathy_contact_set_subscription (EMPATHY_CONTACT (object),
-                                                 g_value_get_flags (value));
-               break;
        case PROP_HANDLE:
                empathy_contact_set_handle (EMPATHY_CONTACT (object),
                                           g_value_get_uint (value));
        case PROP_HANDLE:
                empathy_contact_set_handle (EMPATHY_CONTACT (object),
                                           g_value_get_uint (value));
@@ -338,8 +275,8 @@ empathy_contact_new (McAccount *account)
 
 EmpathyContact *
 empathy_contact_new_full (McAccount   *account,
 
 EmpathyContact *
 empathy_contact_new_full (McAccount   *account,
-                        const gchar *id,
-                        const gchar *name)
+                         const gchar *id,
+                         const gchar *name)
 {
        return g_object_new (EMPATHY_TYPE_CONTACT,
                             "account", account,
 {
        return g_object_new (EMPATHY_TYPE_CONTACT,
                             "account", account,
@@ -364,107 +301,6 @@ empathy_contact_get_id (EmpathyContact *contact)
        return "";
 }
 
        return "";
 }
 
-const gchar *
-empathy_contact_get_name (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
-
-       priv = GET_PRIV (contact);
-
-       if (G_STR_EMPTY (priv->name)) {
-               return empathy_contact_get_id (contact);
-       }
-
-       return priv->name;
-}
-
-EmpathyAvatar *
-empathy_contact_get_avatar (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
-
-       priv = GET_PRIV (contact);
-
-       return priv->avatar;
-}
-
-McAccount *
-empathy_contact_get_account (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
-
-       priv = GET_PRIV (contact);
-
-       return priv->account;
-}
-
-EmpathyPresence *
-empathy_contact_get_presence (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
-
-       priv = GET_PRIV (contact);
-
-       return priv->presence;
-}
-
-GList *
-empathy_contact_get_groups (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
-
-       priv = GET_PRIV (contact);
-
-       return priv->groups;
-}
-
-EmpathySubscription
-empathy_contact_get_subscription (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact),
-                             EMPATHY_SUBSCRIPTION_NONE);
-
-       priv = GET_PRIV (contact);
-
-       return priv->subscription;
-}
-
-guint
-empathy_contact_get_handle (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
-
-       priv = GET_PRIV (contact);
-
-       return priv->handle;
-}
-
-gboolean
-empathy_contact_is_user (EmpathyContact *contact)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
-
-       priv = GET_PRIV (contact);
-
-       return priv->is_user;
-}
-
 void
 empathy_contact_set_id (EmpathyContact *contact,
                       const gchar   *id)
 void
 empathy_contact_set_id (EmpathyContact *contact,
                       const gchar   *id)
@@ -486,6 +322,22 @@ empathy_contact_set_id (EmpathyContact *contact,
        g_object_notify (G_OBJECT (contact), "id");
 }
 
        g_object_notify (G_OBJECT (contact), "id");
 }
 
+const gchar *
+empathy_contact_get_name (EmpathyContact *contact)
+{
+       EmpathyContactPriv *priv;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
+
+       priv = GET_PRIV (contact);
+
+       if (G_STR_EMPTY (priv->name)) {
+               return empathy_contact_get_id (contact);
+       }
+
+       return priv->name;
+}
+
 void
 empathy_contact_set_name (EmpathyContact *contact,
                         const gchar   *name)
 void
 empathy_contact_set_name (EmpathyContact *contact,
                         const gchar   *name)
@@ -507,6 +359,18 @@ empathy_contact_set_name (EmpathyContact *contact,
        g_object_notify (G_OBJECT (contact), "name");
 }
 
        g_object_notify (G_OBJECT (contact), "name");
 }
 
+EmpathyAvatar *
+empathy_contact_get_avatar (EmpathyContact *contact)
+{
+       EmpathyContactPriv *priv;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+       priv = GET_PRIV (contact);
+
+       return priv->avatar;
+}
+
 void
 empathy_contact_set_avatar (EmpathyContact *contact,
                           EmpathyAvatar  *avatar)
 void
 empathy_contact_set_avatar (EmpathyContact *contact,
                           EmpathyAvatar  *avatar)
@@ -533,9 +397,21 @@ empathy_contact_set_avatar (EmpathyContact *contact,
        g_object_notify (G_OBJECT (contact), "avatar");
 }
 
        g_object_notify (G_OBJECT (contact), "avatar");
 }
 
+McAccount *
+empathy_contact_get_account (EmpathyContact *contact)
+{
+       EmpathyContactPriv *priv;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+       priv = GET_PRIV (contact);
+
+       return priv->account;
+}
+
 void
 empathy_contact_set_account (EmpathyContact *contact,
 void
 empathy_contact_set_account (EmpathyContact *contact,
-                           McAccount     *account)
+                            McAccount      *account)
 {
        EmpathyContactPriv *priv;
 
 {
        EmpathyContactPriv *priv;
 
@@ -556,9 +432,21 @@ empathy_contact_set_account (EmpathyContact *contact,
        g_object_notify (G_OBJECT (contact), "account");
 }
 
        g_object_notify (G_OBJECT (contact), "account");
 }
 
+EmpathyPresence *
+empathy_contact_get_presence (EmpathyContact *contact)
+{
+       EmpathyContactPriv *priv;
+
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+       priv = GET_PRIV (contact);
+
+       return priv->presence;
+}
+
 void
 empathy_contact_set_presence (EmpathyContact  *contact,
 void
 empathy_contact_set_presence (EmpathyContact  *contact,
-                            EmpathyPresence *presence)
+                             EmpathyPresence *presence)
 {
        EmpathyContactPriv *priv;
 
 {
        EmpathyContactPriv *priv;
 
@@ -582,34 +470,21 @@ empathy_contact_set_presence (EmpathyContact  *contact,
        g_object_notify (G_OBJECT (contact), "presence");
 }
 
        g_object_notify (G_OBJECT (contact), "presence");
 }
 
-void
-empathy_contact_set_groups (EmpathyContact *contact,
-                          GList         *groups)
+guint
+empathy_contact_get_handle (EmpathyContact *contact)
 {
        EmpathyContactPriv *priv;
 {
        EmpathyContactPriv *priv;
-       GList             *old_groups, *l;
 
 
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
 
        priv = GET_PRIV (contact);
 
 
        priv = GET_PRIV (contact);
 
-       old_groups = priv->groups;
-       priv->groups = NULL;
-
-       for (l = groups; l; l = l->next) {
-               priv->groups = g_list_append (priv->groups,
-                                             g_strdup (l->data));
-       }
-
-       g_list_foreach (old_groups, (GFunc) g_free, NULL);
-       g_list_free (old_groups);
-
-       g_object_notify (G_OBJECT (contact), "groups");
+       return priv->handle;
 }
 
 void
 }
 
 void
-empathy_contact_set_subscription (EmpathyContact      *contact,
-                                EmpathySubscription  subscription)
+empathy_contact_set_handle (EmpathyContact *contact,
+                          guint          handle)
 {
        EmpathyContactPriv *priv;
 
 {
        EmpathyContactPriv *priv;
 
@@ -617,32 +492,25 @@ empathy_contact_set_subscription (EmpathyContact      *contact,
 
        priv = GET_PRIV (contact);
 
 
        priv = GET_PRIV (contact);
 
-       if (priv->subscription == subscription) {
+       if (priv->handle == handle) {
                return;
        }
 
                return;
        }
 
-       priv->subscription = subscription;
+       priv->handle = handle;
 
 
-       g_object_notify (G_OBJECT (contact), "subscription");
+       g_object_notify (G_OBJECT (contact), "handle");
 }
 
 }
 
-void
-empathy_contact_set_handle (EmpathyContact *contact,
-                          guint          handle)
+gboolean
+empathy_contact_is_user (EmpathyContact *contact)
 {
        EmpathyContactPriv *priv;
 
 {
        EmpathyContactPriv *priv;
 
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
 
        priv = GET_PRIV (contact);
 
 
        priv = GET_PRIV (contact);
 
-       if (priv->handle == handle) {
-               return;
-       }
-
-       priv->handle = handle;
-
-       g_object_notify (G_OBJECT (contact), "handle");
+       return priv->is_user;
 }
 
 void
 }
 
 void
@@ -664,43 +532,6 @@ empathy_contact_set_is_user (EmpathyContact *contact,
        g_object_notify (G_OBJECT (contact), "is-user");
 }
 
        g_object_notify (G_OBJECT (contact), "is-user");
 }
 
-void
-empathy_contact_add_group (EmpathyContact *contact,
-                         const gchar   *group)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-       g_return_if_fail (group != NULL);
-
-       priv = GET_PRIV (contact);
-
-       if (!g_list_find_custom (priv->groups, group, (GCompareFunc) strcmp)) {
-               priv->groups = g_list_prepend (priv->groups, g_strdup (group));
-               g_object_notify (G_OBJECT (contact), "groups");
-       }
-}
-
-void
-empathy_contact_remove_group (EmpathyContact *contact,
-                            const gchar   *group)
-{
-       EmpathyContactPriv *priv;
-       GList             *l;
-
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-       g_return_if_fail (group != NULL);
-
-       priv = GET_PRIV (contact);
-
-       l = g_list_find_custom (priv->groups, group, (GCompareFunc) strcmp);
-       if (l) {
-               g_free (l->data);
-               priv->groups = g_list_delete_link (priv->groups, l);
-               g_object_notify (G_OBJECT (contact), "groups");
-       }
-}
-
 gboolean
 empathy_contact_is_online (EmpathyContact *contact)
 {
 gboolean
 empathy_contact_is_online (EmpathyContact *contact)
 {
@@ -717,24 +548,6 @@ empathy_contact_is_online (EmpathyContact *contact)
        return (empathy_presence_get_state (priv->presence) > MC_PRESENCE_OFFLINE);
 }
 
        return (empathy_presence_get_state (priv->presence) > MC_PRESENCE_OFFLINE);
 }
 
-gboolean
-empathy_contact_is_in_group (EmpathyContact *contact,
-                           const gchar   *group)
-{
-       EmpathyContactPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
-       g_return_val_if_fail (!G_STR_EMPTY (group), FALSE);
-
-       priv = GET_PRIV (contact);
-
-       if (g_list_find_custom (priv->groups, group, (GCompareFunc) strcmp)) {
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
 const gchar *
 empathy_contact_get_status (EmpathyContact *contact)
 {
 const gchar *
 empathy_contact_get_status (EmpathyContact *contact)
 {
index b32d451bbd5cb2444eb1209243d194f07b1b2dba..87a26f0dd9de793f827d0994db662402c112019f 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2004 Imendio AB
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2004 Imendio AB
+ * 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
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * License along with this program; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  * 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: Mikael Hallendal <micke@imendio.com>
+ *          Martyn Russell <martyn@imendio.com>
+ *          Xavier Claessens <xclaesse@gmail.com>
  */
 
 #ifndef __EMPATHY_CONTACT_H__
  */
 
 #ifndef __EMPATHY_CONTACT_H__
@@ -30,7 +35,7 @@
 
 G_BEGIN_DECLS
 
 
 G_BEGIN_DECLS
 
-#define EMPATHY_TYPE_CONTACT         (empathy_contact_get_gtype ())
+#define EMPATHY_TYPE_CONTACT         (empathy_contact_get_type ())
 #define EMPATHY_CONTACT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CONTACT, EmpathyContact))
 #define EMPATHY_CONTACT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_CONTACT, EmpathyContactClass))
 #define EMPATHY_IS_CONTACT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CONTACT))
 #define EMPATHY_CONTACT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CONTACT, EmpathyContact))
 #define EMPATHY_CONTACT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_CONTACT, EmpathyContactClass))
 #define EMPATHY_IS_CONTACT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CONTACT))
@@ -48,57 +53,37 @@ struct _EmpathyContactClass {
        GObjectClass parent_class;
 };
 
        GObjectClass parent_class;
 };
 
-typedef enum {
-       EMPATHY_SUBSCRIPTION_NONE = 0,
-       EMPATHY_SUBSCRIPTION_TO   = 1 << 0,     /* We send our presence to that contact */
-       EMPATHY_SUBSCRIPTION_FROM = 1 << 1,     /* That contact sends his presence to us */
-       EMPATHY_SUBSCRIPTION_BOTH = EMPATHY_SUBSCRIPTION_TO | EMPATHY_SUBSCRIPTION_FROM
-} EmpathySubscription;
-
-GType              empathy_contact_get_gtype                 (void) G_GNUC_CONST;
-
-EmpathyContact *    empathy_contact_new                       (McAccount          *account);
-EmpathyContact *    empathy_contact_new_full                  (McAccount          *account,
-                                                            const gchar        *id,
-                                                            const gchar        *name);
-const gchar *      empathy_contact_get_id                    (EmpathyContact      *contact);
-const gchar *      empathy_contact_get_name                  (EmpathyContact      *contact);
-EmpathyAvatar *     empathy_contact_get_avatar                (EmpathyContact      *contact);
-McAccount *        empathy_contact_get_account               (EmpathyContact      *contact);
-EmpathyPresence *   empathy_contact_get_presence              (EmpathyContact      *contact);
-GList *            empathy_contact_get_groups                (EmpathyContact      *contact);
-EmpathySubscription empathy_contact_get_subscription          (EmpathyContact      *contact);
-guint              empathy_contact_get_handle                (EmpathyContact      *contact);
-gboolean           empathy_contact_is_user                   (EmpathyContact      *contact);
-void               empathy_contact_set_id                    (EmpathyContact      *contact,
-                                                            const gchar        *id);
-void               empathy_contact_set_name                  (EmpathyContact      *contact,
-                                                            const gchar        *name);
-void               empathy_contact_set_avatar                (EmpathyContact      *contact,
-                                                            EmpathyAvatar       *avatar);
-void               empathy_contact_set_account               (EmpathyContact      *contact,
-                                                            McAccount          *account);
-void               empathy_contact_set_presence              (EmpathyContact      *contact,
-                                                            EmpathyPresence     *presence);
-void               empathy_contact_set_groups                (EmpathyContact      *contact,
-                                                            GList              *categories);
-void               empathy_contact_set_subscription          (EmpathyContact      *contact,
-                                                            EmpathySubscription  subscription);
-void               empathy_contact_set_handle                (EmpathyContact      *contact,
-                                                            guint               handle);
-void               empathy_contact_set_is_user               (EmpathyContact      *contact,
-                                                            gboolean            is_user);
-void               empathy_contact_add_group                 (EmpathyContact      *contact,
-                                                            const gchar        *group);
-void               empathy_contact_remove_group              (EmpathyContact      *contact,
-                                                            const gchar        *group);
-gboolean           empathy_contact_is_online                 (EmpathyContact      *contact);
-gboolean           empathy_contact_is_in_group               (EmpathyContact      *contact,
-                                                            const gchar        *group);
-const gchar *      empathy_contact_get_status                (EmpathyContact      *contact);
-gboolean           empathy_contact_equal                     (gconstpointer       v1,
-                                                            gconstpointer       v2);
-guint              empathy_contact_hash                      (gconstpointer       key);
+GType             empathy_contact_get_type     (void) G_GNUC_CONST;
+EmpathyContact *  empathy_contact_new          (McAccount       *account);
+EmpathyContact *  empathy_contact_new_full     (McAccount       *account,
+                                               const gchar     *id,
+                                               const gchar     *name);
+const gchar *     empathy_contact_get_id       (EmpathyContact  *contact);
+void              empathy_contact_set_id       (EmpathyContact  *contact,
+                                               const gchar     *id);
+const gchar *     empathy_contact_get_name     (EmpathyContact  *contact);
+void              empathy_contact_set_name     (EmpathyContact  *contact,
+                                               const gchar     *name);
+EmpathyAvatar *   empathy_contact_get_avatar   (EmpathyContact  *contact);
+void              empathy_contact_set_avatar   (EmpathyContact  *contact,
+                                               EmpathyAvatar   *avatar);
+McAccount *       empathy_contact_get_account  (EmpathyContact  *contact);
+void              empathy_contact_set_account  (EmpathyContact  *contact,
+                                               McAccount       *account);
+EmpathyPresence * empathy_contact_get_presence (EmpathyContact  *contact);
+void              empathy_contact_set_presence (EmpathyContact  *contact,
+                                               EmpathyPresence *presence);
+guint             empathy_contact_get_handle   (EmpathyContact  *contact);
+void              empathy_contact_set_handle   (EmpathyContact  *contact,
+                                               guint            handle);
+gboolean          empathy_contact_is_user      (EmpathyContact  *contact);
+void              empathy_contact_set_is_user  (EmpathyContact  *contact,
+                                               gboolean         is_user);
+gboolean          empathy_contact_is_online    (EmpathyContact  *contact);
+const gchar *     empathy_contact_get_status   (EmpathyContact  *contact);
+gboolean          empathy_contact_equal        (gconstpointer    v1,
+                                               gconstpointer    v2);
+guint             empathy_contact_hash         (gconstpointer    key);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
index e234ec521c383531af83f1ce17230cd1d6b4e38b..e47f50fb83ac6c6345781a5257b00cc6940aa9ad 100644 (file)
@@ -634,24 +634,22 @@ log_manager_get_dir (EmpathyLogManager *manager,
 {
        const gchar *account_id;
        gchar       *basedir;
 {
        const gchar *account_id;
        gchar       *basedir;
-       gchar       *str;
 
        account_id = mc_account_get_unique_name (account);
 
        account_id = mc_account_get_unique_name (account);
-       basedir = 
-       str = g_build_path (G_DIR_SEPARATOR_S,
-                           log_manager_get_basedir (manager),
-                           account_id,
-                           chat_id,
-                           NULL);
 
        if (chatroom) {
                basedir = g_build_path (G_DIR_SEPARATOR_S,
 
        if (chatroom) {
                basedir = g_build_path (G_DIR_SEPARATOR_S,
-                                       str,
+                                       log_manager_get_basedir (manager),
+                                       account_id,
                                        LOG_DIR_CHATROOMS,
                                        LOG_DIR_CHATROOMS,
+                                       chat_id,
                                        NULL);
                                        NULL);
-               g_free (str);
        } else {
        } else {
-               basedir = str;
+               basedir = g_build_path (G_DIR_SEPARATOR_S,
+                                       log_manager_get_basedir (manager),
+                                       account_id,
+                                       chat_id,
+                                       NULL);
        }
 
        return basedir;
        }
 
        return basedir;
index 3b36b7be08a1495829b7816f3d552f156331c651..383bfbbedd0b98f6ca3f6a20957eb09801ee7b7b 100644 (file)
@@ -1,10 +1,14 @@
 VOID:OBJECT,UINT
 VOID:OBJECT,UINT
-VOID:OBJECT,OBJECT
-VOID:OBJECT,OBJECT,UINT
 VOID:OBJECT,BOOLEAN
 VOID:OBJECT,BOOLEAN
-VOID:OBJECT,STRING,STRING
+VOID:OBJECT,POINTER
 VOID:OBJECT,STRING
 VOID:OBJECT,STRING
-VOID:POINTER,UINT,UINT,STRING
+VOID:OBJECT,STRING,STRING
+VOID:OBJECT,STRING,BOOLEAN
+VOID:OBJECT,OBJECT
+VOID:OBJECT,OBJECT,UINT
+VOID:OBJECT,OBJECT,UINT,STRING
+VOID:OBJECT,OBJECT,UINT,STRING,BOOLEAN
+VOID:OBJECT,OBJECT,STRING
 VOID:INT,STRING
 VOID:UINT,BOOLEAN
 
 VOID:INT,STRING
 VOID:UINT,BOOLEAN
 
index 077afe36e31dc8f5e14f9845282bfbdaf81575c8..fc943f0c610b23494ffd97a22f582ae1ab63da2a 100644 (file)
@@ -31,8 +31,7 @@
 #include <libtelepathy/tp-props-iface.h>
 
 #include "empathy-tp-chat.h"
 #include <libtelepathy/tp-props-iface.h>
 
 #include "empathy-tp-chat.h"
-#include "empathy-contact-manager.h"
-#include "empathy-tp-contact-list.h"
+#include "empathy-contact-factory.h"
 #include "empathy-marshal.h"
 #include "empathy-debug.h"
 #include "empathy-time.h"
 #include "empathy-marshal.h"
 #include "empathy-debug.h"
 #include "empathy-time.h"
@@ -44,8 +43,8 @@
 #define DEBUG_DOMAIN "TpChat"
 
 struct _EmpathyTpChatPriv {
 #define DEBUG_DOMAIN "TpChat"
 
 struct _EmpathyTpChatPriv {
-       EmpathyTpContactList  *list;
-       EmpathyContactManager *manager;
+       EmpathyContactFactory *factory;
+       EmpathyContact        *user;
        McAccount             *account;
        gchar                 *id;
        MissionControl        *mc;
        McAccount             *account;
        gchar                 *id;
        MissionControl        *mc;
@@ -363,11 +362,11 @@ tp_chat_finalize (GObject *object)
                g_object_unref (priv->tp_chan);
        }
 
                g_object_unref (priv->tp_chan);
        }
 
-       if (priv->manager) {
-               g_object_unref (priv->manager);
+       if (priv->factory) {
+               g_object_unref (priv->factory);
        }
        }
-       if (priv->list) {
-               g_object_unref (priv->list);
+       if (priv->user) {
+               g_object_unref (priv->user);
        }
        if (priv->account) {
                g_object_unref (priv->account);
        }
        if (priv->account) {
                g_object_unref (priv->account);
@@ -392,10 +391,9 @@ tp_chat_constructor (GType                  type,
 
        priv = GET_PRIV (chat);
 
 
        priv = GET_PRIV (chat);
 
-       priv->manager = empathy_contact_manager_new ();
-       priv->list = empathy_contact_manager_get_list (priv->manager, priv->account);
+       priv->factory = empathy_contact_factory_new ();
+       priv->user = empathy_contact_factory_get_user (priv->factory, priv->account);
        priv->mc = empathy_mission_control_new ();
        priv->mc = empathy_mission_control_new ();
-       g_object_ref (priv->list);
 
        priv->text_iface = tp_chan_get_interface (priv->tp_chan,
                                                  TELEPATHY_CHAN_IFACE_TEXT_QUARK);
 
        priv->text_iface = tp_chan_get_interface (priv->tp_chan,
                                                  TELEPATHY_CHAN_IFACE_TEXT_QUARK);
@@ -750,12 +748,10 @@ empathy_tp_chat_get_id (EmpathyTpChat *chat)
 
        priv = GET_PRIV (chat);
 
 
        priv = GET_PRIV (chat);
 
-       if (priv->id) {
-               return priv->id;
+       if (!priv->id) {
+               priv->id = empathy_inspect_channel (priv->account, priv->tp_chan);
        }
 
        }
 
-       priv->id = empathy_inspect_channel (priv->account, priv->tp_chan);
-
        return priv->id;
 }
 
        return priv->id;
 }
 
@@ -885,7 +881,9 @@ tp_chat_state_changed_cb (DBusGProxy                *chat_state_iface,
 
        priv = GET_PRIV (chat);
 
 
        priv = GET_PRIV (chat);
 
-       contact = empathy_tp_contact_list_get_from_handle (priv->list, handle);
+       contact = empathy_contact_factory_get_from_handle (priv->factory,
+                                                          priv->account,
+                                                          handle);
 
        empathy_debug (DEBUG_DOMAIN, "Chat state changed for %s (%d): %d",
                      empathy_contact_get_name (contact),
 
        empathy_debug (DEBUG_DOMAIN, "Chat state changed for %s (%d): %d",
                      empathy_contact_get_name (contact),
@@ -906,22 +904,21 @@ tp_chat_build_message (EmpathyTpChat *chat,
        EmpathyTpChatPriv *priv;
        EmpathyMessage    *message;
        EmpathyContact    *sender;
        EmpathyTpChatPriv *priv;
        EmpathyMessage    *message;
        EmpathyContact    *sender;
-       EmpathyContact    *receiver;
 
        priv = GET_PRIV (chat);
 
 
        priv = GET_PRIV (chat);
 
-       receiver = empathy_tp_contact_list_get_user (priv->list);
        if (from_handle == 0) {
        if (from_handle == 0) {
-               sender = g_object_ref (receiver);
+               sender = g_object_ref (priv->user);
        } else {
        } else {
-               sender = empathy_tp_contact_list_get_from_handle (priv->list,
+               sender = empathy_contact_factory_get_from_handle (priv->factory,
+                                                                 priv->account,
                                                                  from_handle);
        }
 
        message = empathy_message_new (message_body);
        empathy_message_set_type (message, type);
        empathy_message_set_sender (message, sender);
                                                                  from_handle);
        }
 
        message = empathy_message_new (message_body);
        empathy_message_set_type (message, type);
        empathy_message_set_sender (message, sender);
-       empathy_message_set_receiver (message, receiver);
+       empathy_message_set_receiver (message, priv->user);
        empathy_message_set_timestamp (message, (EmpathyTime) timestamp);
 
        g_object_unref (sender);
        empathy_message_set_timestamp (message, (EmpathyTime) timestamp);
 
        g_object_unref (sender);
index 32716865d046ea67d5cf5967332f2d9b07ee7e31..72f0839422416c09c8634e63e7135790ffe185f9 100644 (file)
@@ -23,9 +23,8 @@
 #include <config.h>
 
 #include "empathy-tp-chatroom.h"
 #include <config.h>
 
 #include "empathy-tp-chatroom.h"
-#include "empathy-tp-contact-list.h"
 #include "empathy-contact-list.h"
 #include "empathy-contact-list.h"
-#include "empathy-contact-manager.h"
+#include "empathy-contact-factory.h"
 #include "empathy-tp-group.h"
 #include "empathy-utils.h"
 #include "empathy-debug.h"
 #include "empathy-tp-group.h"
 #include "empathy-utils.h"
 #include "empathy-debug.h"
@@ -36,8 +35,7 @@
 #define DEBUG_DOMAIN "TpChatroom"
 
 struct _EmpathyTpChatroomPriv {
 #define DEBUG_DOMAIN "TpChatroom"
 
 struct _EmpathyTpChatroomPriv {
-       EmpathyContactManager *manager;
-       EmpathyTpContactList  *list;
+       EmpathyContactFactory *factory;
        EmpathyTpGroup        *group;
 
        gboolean               is_invited;
        EmpathyTpGroup        *group;
 
        gboolean               is_invited;
@@ -49,21 +47,18 @@ static void            empathy_tp_chatroom_class_init (EmpathyTpChatroomClass  *
 static void            tp_chatroom_iface_init         (EmpathyContactListIface *iface);
 static void            empathy_tp_chatroom_init       (EmpathyTpChatroom       *chatroom);
 static void            tp_chatroom_finalize           (GObject                 *object);
 static void            tp_chatroom_iface_init         (EmpathyContactListIface *iface);
 static void            empathy_tp_chatroom_init       (EmpathyTpChatroom       *chatroom);
 static void            tp_chatroom_finalize           (GObject                 *object);
-static void            tp_chatroom_members_added_cb   (EmpathyTpGroup          *group,
-                                                      GArray                  *handles,
-                                                      guint                    actor_handle,
+static void            tp_chatroom_member_added_cb    (EmpathyTpGroup          *group,
+                                                      EmpathyContact          *contact,
+                                                      EmpathyContact          *actor,
                                                       guint                    reason,
                                                       const gchar             *message,
                                                       guint                    reason,
                                                       const gchar             *message,
-                                                      EmpathyTpChatroom       *list);
-static void            tp_chatroom_members_removed_cb (EmpathyTpGroup          *group,
-                                                      GArray                  *handles,
-                                                      guint                    actor_handle,
+                                                      EmpathyTpChatroom       *chatroom);
+static void            tp_chatroom_member_removed_cb  (EmpathyTpGroup          *group,
+                                                      EmpathyContact          *contact,
+                                                      EmpathyContact          *actor,
                                                       guint                    reason,
                                                       const gchar             *message,
                                                       guint                    reason,
                                                       const gchar             *message,
-                                                      EmpathyTpChatroom       *list);
-static void            tp_chatroom_setup              (EmpathyContactList      *list);
-static EmpathyContact * tp_chatroom_find               (EmpathyContactList      *list,
-                                                      const gchar             *id);
+                                                      EmpathyTpChatroom       *chatroom);
 static void            tp_chatroom_add                (EmpathyContactList      *list,
                                                       EmpathyContact           *contact,
                                                       const gchar             *message);
 static void            tp_chatroom_add                (EmpathyContactList      *list,
                                                       EmpathyContact           *contact,
                                                       const gchar             *message);
@@ -89,8 +84,6 @@ empathy_tp_chatroom_class_init (EmpathyTpChatroomClass *klass)
 static void
 tp_chatroom_iface_init (EmpathyContactListIface *iface)
 {
 static void
 tp_chatroom_iface_init (EmpathyContactListIface *iface)
 {
-       iface->setup       = tp_chatroom_setup;
-       iface->find        = tp_chatroom_find;
        iface->add         = tp_chatroom_add;
        iface->remove      = tp_chatroom_remove;
        iface->get_members = tp_chatroom_get_members;
        iface->add         = tp_chatroom_add;
        iface->remove      = tp_chatroom_remove;
        iface->get_members = tp_chatroom_get_members;
@@ -111,7 +104,7 @@ tp_chatroom_finalize (GObject *object)
        priv = GET_PRIV (chatroom);
 
        g_object_unref (priv->group);
        priv = GET_PRIV (chatroom);
 
        g_object_unref (priv->group);
-       g_object_unref (priv->manager);
+       g_object_unref (priv->factory);
 
        if (priv->invitor) {
                g_object_unref (priv->invitor);
 
        if (priv->invitor) {
                g_object_unref (priv->invitor);
@@ -129,7 +122,7 @@ empathy_tp_chatroom_new (McAccount *account,
        EmpathyTpChatroomPriv *priv;
        EmpathyTpChatroom     *chatroom;
        GList                 *members, *l;
        EmpathyTpChatroomPriv *priv;
        EmpathyTpChatroom     *chatroom;
        GList                 *members, *l;
-       guint                  self_handle;
+       EmpathyContact        *user;
 
        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 (MC_IS_ACCOUNT (account), NULL);
        g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
@@ -141,40 +134,41 @@ empathy_tp_chatroom_new (McAccount *account,
 
        priv = GET_PRIV (chatroom);
 
 
        priv = GET_PRIV (chatroom);
 
-       priv->manager = empathy_contact_manager_new ();
-       priv->list = empathy_contact_manager_get_list (priv->manager, account);
+       priv->factory = empathy_contact_factory_new ();
        priv->group = empathy_tp_group_new (account, tp_chan);
 
        priv->group = empathy_tp_group_new (account, tp_chan);
 
-       g_signal_connect (priv->group, "members-added",
-                         G_CALLBACK (tp_chatroom_members_added_cb),
+       g_signal_connect (priv->group, "member-added",
+                         G_CALLBACK (tp_chatroom_member_added_cb),
                          chatroom);
                          chatroom);
-       g_signal_connect (priv->group, "members-removed",
-                         G_CALLBACK (tp_chatroom_members_removed_cb),
+       g_signal_connect (priv->group, "member-removed",
+                         G_CALLBACK (tp_chatroom_member_removed_cb),
                          chatroom);
 
        /* Check if we are invited to join the chat */
                          chatroom);
 
        /* Check if we are invited to join the chat */
-       self_handle = empathy_tp_group_get_self_handle (priv->group);
-       members = empathy_tp_group_get_local_pending_members_with_info (priv->group);
+       user = empathy_tp_group_get_self_contact (priv->group);
+       members = empathy_tp_group_get_local_pendings (priv->group);
        for (l = members; l; l = l->next) {
        for (l = members; l; l = l->next) {
-               EmpathyTpGroupInfo *info;
+               EmpathyPendingInfo *info;
 
                info = l->data;
 
 
                info = l->data;
 
-               if (info->member != self_handle) {
+               if (!empathy_contact_equal (user, info->member)) {
                        continue;
                }
 
                        continue;
                }
 
-               priv->invitor = empathy_tp_contact_list_get_from_handle (priv->list,
-                                                                        info->actor);
+               priv->invitor = g_object_ref (info->actor);
                priv->invit_message = g_strdup (info->message);
                priv->is_invited = TRUE;
 
                priv->invit_message = g_strdup (info->message);
                priv->is_invited = TRUE;
 
-               empathy_debug (DEBUG_DOMAIN, "We are invited to join by %s: %s",
-                             empathy_contact_get_name (priv->invitor),
-                             priv->invit_message);
+               empathy_debug (DEBUG_DOMAIN, "We are invited to join by %s (%d): %s",
+                              empathy_contact_get_id (priv->invitor),
+                              empathy_contact_get_handle (priv->invitor),
+                              priv->invit_message);
        }
 
        }
 
-       empathy_tp_group_info_list_free (members);
+       g_list_foreach (members, (GFunc) empathy_pending_info_free, NULL);
+       g_list_free (members);
+       g_object_unref (user);
 
        return chatroom;
 }
 
        return chatroom;
 }
@@ -204,7 +198,7 @@ void
 empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom)
 {
        EmpathyTpChatroomPriv *priv;
 empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom)
 {
        EmpathyTpChatroomPriv *priv;
-       guint                  self_handle;
+       EmpathyContact        *user;
 
        g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom));
 
 
        g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom));
 
@@ -220,80 +214,42 @@ empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom)
        priv->invit_message = NULL;
 
        /* Add ourself in the members of the room */
        priv->invit_message = NULL;
 
        /* Add ourself in the members of the room */
-       self_handle = empathy_tp_group_get_self_handle (priv->group);
-       empathy_tp_group_add_member (priv->group, self_handle,
-                                          "Just for fun");
+       user = empathy_tp_group_get_self_contact (priv->group);
+       empathy_tp_group_add_member (priv->group, user, "");
+       g_object_unref (user);
 }
 
 void
 empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom,
                               const gchar       *topic)
 {
 }
 
 void
 empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom,
                               const gchar       *topic)
 {
+       /* FIXME: not implemented */
 }
 
 static void
 }
 
 static void
-tp_chatroom_members_added_cb (EmpathyTpGroup    *group,
-                             GArray            *handles,
-                             guint              actor_handle,
-                             guint              reason,
-                             const gchar       *message,
-                             EmpathyTpChatroom *chatroom)
+tp_chatroom_member_added_cb (EmpathyTpGroup    *group,
+                            EmpathyContact    *contact,
+                            EmpathyContact    *actor,
+                            guint              reason,
+                            const gchar       *message,
+                            EmpathyTpChatroom *chatroom)
 {
 {
-       EmpathyTpChatroomPriv *priv;
-       GList                 *contacts, *l;
-
-       priv = GET_PRIV (chatroom);
-
-       contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
-       for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact;
-
-               contact = l->data;
-
-               g_signal_emit_by_name (chatroom, "contact-added", contact);
-
-               g_object_unref (contact);
-       }
-       g_list_free (contacts);
-}
-
-static void
-tp_chatroom_members_removed_cb (EmpathyTpGroup    *group,
-                               GArray            *handles,
-                               guint              actor_handle,
-                               guint              reason,
-                               const gchar       *message,
-                               EmpathyTpChatroom *chatroom)
-{
-       EmpathyTpChatroomPriv *priv;
-       GList                 *contacts, *l;
-
-       priv = GET_PRIV (chatroom);
-
-       contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
-       for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact;
-
-               contact = l->data;
-
-               g_signal_emit_by_name (chatroom, "contact-removed", contact);
-
-               g_object_unref (contact);
-       }
-       g_list_free (contacts);
+       g_signal_emit_by_name (chatroom, "members-changed",
+                              contact, actor, reason, message,
+                              TRUE);
 }
 
 static void
 }
 
 static void
-tp_chatroom_setup (EmpathyContactList *list)
-{
-       /* Nothing to do */
-}
-
-static EmpathyContact *
-tp_chatroom_find (EmpathyContactList *list,
-                 const gchar        *id)
+tp_chatroom_member_removed_cb (EmpathyTpGroup    *group,
+                              EmpathyContact    *contact,
+                              EmpathyContact    *actor,
+                              guint              reason,
+                              const gchar       *message,
+                              EmpathyTpChatroom *chatroom)
 {
 {
-       return NULL;
+       g_signal_emit_by_name (chatroom, "members-changed",
+                              contact, actor, reason, message,
+                              FALSE);
 }
 
 static void
 }
 
 static void
@@ -308,9 +264,7 @@ tp_chatroom_add (EmpathyContactList *list,
 
        priv = GET_PRIV (list);
 
 
        priv = GET_PRIV (list);
 
-       empathy_tp_group_add_member (priv->group,
-                                    empathy_contact_get_handle (contact),
-                                    message);
+       empathy_tp_group_add_member (priv->group, contact, message);
 }
 
 static void
 }
 
 static void
@@ -325,26 +279,18 @@ tp_chatroom_remove (EmpathyContactList *list,
 
        priv = GET_PRIV (list);
 
 
        priv = GET_PRIV (list);
 
-       empathy_tp_group_remove_member (priv->group,
-                                       empathy_contact_get_handle (contact),
-                                       message);
+       empathy_tp_group_remove_member (priv->group, contact, message);
 }
 
 static GList *
 tp_chatroom_get_members (EmpathyContactList *list)
 {
        EmpathyTpChatroomPriv *priv;
 }
 
 static GList *
 tp_chatroom_get_members (EmpathyContactList *list)
 {
        EmpathyTpChatroomPriv *priv;
-       GArray                *members;
-       GList                 *contacts;
 
        g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL);
 
        priv = GET_PRIV (list);
 
 
        g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL);
 
        priv = GET_PRIV (list);
 
-       members = empathy_tp_group_get_members (priv->group);
-       contacts = empathy_tp_contact_list_get_from_handles (priv->list, members);
-       g_array_free (members, TRUE);
-
-       return contacts;
+       return empathy_tp_group_get_members (priv->group);
 }
 
 }
 
index a5c54b74e6158ef4b0076a15d8a3313dd0e50059..16ecad80774dd46823e5fcff442151ae19bd411b 100644 (file)
@@ -30,9 +30,6 @@
 #include <libtelepathy/tp-conn.h>
 #include <libtelepathy/tp-chan.h>
 #include <libtelepathy/tp-chan-type-contact-list-gen.h>
 #include <libtelepathy/tp-conn.h>
 #include <libtelepathy/tp-chan.h>
 #include <libtelepathy/tp-chan-type-contact-list-gen.h>
-#include <libtelepathy/tp-conn-iface-aliasing-gen.h>
-#include <libtelepathy/tp-conn-iface-presence-gen.h>
-#include <libtelepathy/tp-conn-iface-avatars-gen.h>
 
 #include "empathy-tp-contact-list.h"
 #include "empathy-contact-list.h"
 
 #include "empathy-tp-contact-list.h"
 #include "empathy-contact-list.h"
                       EMPATHY_TYPE_TP_CONTACT_LIST, EmpathyTpContactListPriv))
 
 #define DEBUG_DOMAIN "TpContactList"
                       EMPATHY_TYPE_TP_CONTACT_LIST, EmpathyTpContactListPriv))
 
 #define DEBUG_DOMAIN "TpContactList"
-#define MAX_AVATAR_REQUESTS 10
 
 struct _EmpathyTpContactListPriv {
        TpConn         *tp_conn;
        McAccount      *account;
        MissionControl *mc;
 
 struct _EmpathyTpContactListPriv {
        TpConn         *tp_conn;
        McAccount      *account;
        MissionControl *mc;
-       EmpathyContact *user_contact;
-       gboolean        setup;
        const gchar    *protocol_group;
 
        EmpathyTpGroup *publish;
        EmpathyTpGroup *subscribe;
        const gchar    *protocol_group;
 
        EmpathyTpGroup *publish;
        EmpathyTpGroup *subscribe;
-
-       GHashTable     *groups;
-       GHashTable     *contacts;
        GList          *members;
        GList          *members;
-       GList          *local_pending;
+       GList          *pendings;
 
 
-       DBusGProxy     *aliasing_iface;
-       DBusGProxy     *avatars_iface;
-       DBusGProxy     *presence_iface;
+       GList          *groups;
+       GHashTable     *contacts_groups;
 };
 
 typedef enum {
        TP_CONTACT_LIST_TYPE_PUBLISH,
        TP_CONTACT_LIST_TYPE_SUBSCRIBE,
 };
 
 typedef enum {
        TP_CONTACT_LIST_TYPE_PUBLISH,
        TP_CONTACT_LIST_TYPE_SUBSCRIBE,
-       TP_CONTACT_LIST_TYPE_UNKNOWN,
-       TP_CONTACT_LIST_TYPE_COUNT
+       TP_CONTACT_LIST_TYPE_UNKNOWN
 } TpContactListType;
 
 } TpContactListType;
 
-typedef struct {
-       guint  handle;
-       GList *new_groups;
-} TpContactListData;
-
-typedef struct {
-       EmpathyTpContactList *list;
-       guint                 handle;
-} TpContactListAvatarRequestData;
-
-typedef struct {
-       EmpathyTpContactList *list;
-       guint                *handles;
-} TpContactListAliasesRequestData;
-
-static void               empathy_tp_contact_list_class_init       (EmpathyTpContactListClass       *klass);
-static void               tp_contact_list_iface_init               (EmpathyContactListIface         *iface);
-static void               empathy_tp_contact_list_init             (EmpathyTpContactList            *list);
-static void               tp_contact_list_finalize                 (GObject                         *object);
-static void               tp_contact_list_finalize_proxies         (EmpathyTpContactList            *list);
-static void               tp_contact_list_setup                    (EmpathyContactList              *list);
-static EmpathyContact *   tp_contact_list_find                     (EmpathyContactList              *list,
-                                                                   const gchar                     *id);
-static void               tp_contact_list_add                      (EmpathyContactList              *list,
-                                                                   EmpathyContact                  *contact,
-                                                                   const gchar                     *message);
-static void               tp_contact_list_remove                   (EmpathyContactList              *list,
-                                                                   EmpathyContact                  *contact,
-                                                                   const gchar                     *message);
-static GList *            tp_contact_list_get_members              (EmpathyContactList              *list);
-static GList *            tp_contact_list_get_local_pending        (EmpathyContactList              *list);
-static void               tp_contact_list_process_pending          (EmpathyContactList              *list,
-                                                                   EmpathyContact                  *contact,
-                                                                   gboolean                         accept);
-static void               tp_contact_list_remove_local_pending     (EmpathyTpContactList            *list,
-                                                                   EmpathyContact                  *contact);
-static void               tp_contact_list_contact_removed_foreach  (guint                            handle,
-                                                                   EmpathyContact                  *contact,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_destroy_cb               (DBusGProxy                      *proxy,
-                                                                   EmpathyTpContactList            *list);
-static gboolean           tp_contact_list_find_foreach             (guint                            handle,
-                                                                   EmpathyContact                  *contact,
-                                                                   gchar                           *id);
-static void               tp_contact_list_newchannel_cb            (DBusGProxy                      *proxy,
-                                                                   const gchar                     *object_path,
-                                                                   const gchar                     *channel_type,
-                                                                   TelepathyHandleType              handle_type,
-                                                                   guint                            channel_handle,
-                                                                   gboolean                         suppress_handle,
-                                                                   EmpathyTpContactList            *list);
-static TpContactListType  tp_contact_list_get_type                 (EmpathyTpContactList            *list,
-                                                                   EmpathyTpGroup                  *group);
-static void               tp_contact_list_added_cb                 (EmpathyTpGroup                  *group,
-                                                                   GArray                          *handles,
-                                                                   guint                            actor_handle,
-                                                                   guint                            reason,
-                                                                   const gchar                     *message,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_removed_cb               (EmpathyTpGroup                  *group,
-                                                                   GArray                          *handles,
-                                                                   guint                            actor_handle,
-                                                                   guint                            reason,
-                                                                   const gchar                     *message,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_pending_cb               (EmpathyTpGroup                  *group,
-                                                                   GArray                          *handles,
-                                                                   guint                            actor_handle,
-                                                                   guint                            reason,
-                                                                   const gchar                     *message,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_groups_updated_cb        (EmpathyContact                  *contact,
-                                                                   GParamSpec                      *param,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_name_updated_cb          (EmpathyContact                  *contact,
-                                                                   GParamSpec                      *param,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_update_groups_foreach    (gchar                           *object_path,
-                                                                   EmpathyTpGroup                  *group,
-                                                                   TpContactListData               *data);
-static EmpathyTpGroup *   tp_contact_list_get_group                (EmpathyTpContactList            *list,
-                                                                   const gchar                     *name);
-static gboolean           tp_contact_list_find_group               (gchar                           *key,
-                                                                   EmpathyTpGroup                  *group,
-                                                                   gchar                           *group_name);
-static void               tp_contact_list_get_groups_foreach       (gchar                           *key,
-                                                                   EmpathyTpGroup                  *group,
-                                                                   GList                          **groups);
-static void               tp_contact_list_group_channel_closed_cb  (TpChan                          *channel,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_group_members_added_cb   (EmpathyTpGroup                  *group,
-                                                                   GArray                          *members,
-                                                                   guint                            actor_handle,
-                                                                   guint                            reason,
-                                                                   const gchar                     *message,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_group_members_removed_cb (EmpathyTpGroup                  *group,
-                                                                   GArray                          *members,
-                                                                   guint                            actor_handle,
-                                                                   guint                            reason,
-                                                                   const gchar                     *message,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_get_info                 (EmpathyTpContactList            *list,
-                                                                   GArray                          *handles);
-static void               tp_contact_list_request_avatar           (EmpathyTpContactList            *list,
-                                                                   guint                            handle);
-static void               tp_contact_list_start_avatar_requests    (void);
-static void               tp_contact_list_avatar_update_cb         (DBusGProxy                      *proxy,
-                                                                   guint                            handle,
-                                                                   gchar                           *new_token,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_request_avatar_cb        (DBusGProxy                      *proxy,
-                                                                   GArray                          *avatar_data,
-                                                                   gchar                           *mime_type,
-                                                                   GError                          *error,
-                                                                   TpContactListAvatarRequestData  *data);
-static void               tp_contact_list_aliases_update_cb        (DBusGProxy                      *proxy,
-                                                                   GPtrArray                       *handlers,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_request_aliases_cb       (DBusGProxy                      *proxy,
-                                                                   gchar                          **contact_names,
-                                                                   GError                          *error,
-                                                                   TpContactListAliasesRequestData *data);
-static void               tp_contact_list_presence_update_cb       (DBusGProxy                      *proxy,
-                                                                   GHashTable                      *handle_table,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_parse_presence_foreach   (guint                            handle,
-                                                                   GValueArray                     *presence_struct,
-                                                                   EmpathyTpContactList            *list);
-static void               tp_contact_list_presences_table_foreach  (const gchar                     *state_str,
-                                                                   GHashTable                      *presences_table,
-                                                                   EmpathyPresence                 **presence);
-static void               tp_contact_list_status_changed_cb        (MissionControl                  *mc,
-                                                                   TelepathyConnectionStatus        status,
-                                                                   McPresence                       presence,
-                                                                   TelepathyConnectionStatusReason  reason,
-                                                                   const gchar                     *unique_name,
-                                                                   EmpathyTpContactList            *list);
-
-enum {
-       DESTROY,
-       LAST_SIGNAL
-};
-
-static guint  signals[LAST_SIGNAL];
-GList        *avatar_requests_queue = NULL;
-guint         n_avatar_requests = 0;
-
-G_DEFINE_TYPE_WITH_CODE (EmpathyTpContactList, empathy_tp_contact_list, G_TYPE_OBJECT,
-                        G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
-                                               tp_contact_list_iface_init));
-
-static void
-empathy_tp_contact_list_class_init (EmpathyTpContactListClass *klass)
-{
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-       object_class->finalize = tp_contact_list_finalize;
-
-       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 (EmpathyTpContactListPriv));
-}
-
-static void
-tp_contact_list_iface_init (EmpathyContactListIface *iface)
-{
-       iface->setup             = tp_contact_list_setup;
-       iface->find              = tp_contact_list_find;
-       iface->add               = tp_contact_list_add;
-       iface->remove            = tp_contact_list_remove;
-       iface->get_members       = tp_contact_list_get_members;
-       iface->get_local_pending = tp_contact_list_get_local_pending;
-       iface->process_pending   = tp_contact_list_process_pending;
-}
-
-static void
-empathy_tp_contact_list_init (EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       priv = GET_PRIV (list);
-
-       priv->groups = g_hash_table_new_full (g_str_hash,
-                                             g_str_equal,
-                                             (GDestroyNotify) g_free,
-                                             (GDestroyNotify) g_object_unref);
-       priv->contacts = g_hash_table_new_full (g_direct_hash,
-                                               g_direct_equal,
-                                               NULL,
-                                               (GDestroyNotify) g_object_unref);
-}
-
-static void
-tp_contact_list_finalize (GObject *object)
-{
-       EmpathyTpContactListPriv *priv;
-       EmpathyTpContactList     *list;
-
-       list = EMPATHY_TP_CONTACT_LIST (object);
-       priv = GET_PRIV (list);
-
-       empathy_debug (DEBUG_DOMAIN, "finalize: %p", object);
-
-       dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
-                                       "AccountStatusChanged",
-                                       G_CALLBACK (tp_contact_list_status_changed_cb),
-                                       list);
-
-       tp_contact_list_finalize_proxies (list);
-
-       if (priv->tp_conn) {
-               g_object_unref (priv->tp_conn);
-       }
-       if (priv->subscribe) {
-               g_object_unref (priv->subscribe);
-       }
-       if (priv->publish) {
-               g_object_unref (priv->publish);
-       }
-
-       g_object_unref (priv->account);
-       g_object_unref (priv->user_contact);
-       g_object_unref (priv->mc);
-       g_hash_table_destroy (priv->groups);
-       g_hash_table_destroy (priv->contacts);
-
-       g_list_foreach (priv->local_pending, (GFunc) empathy_contact_list_info_free, NULL);
-       g_list_free (priv->local_pending);
-
-       g_list_foreach (priv->members, (GFunc) g_object_unref, NULL);
-       g_list_free (priv->members);
-
-       G_OBJECT_CLASS (empathy_tp_contact_list_parent_class)->finalize (object);
-}
-
-EmpathyTpContactList *
-empathy_tp_contact_list_new (McAccount *account)
-{
-       EmpathyTpContactListPriv *priv;
-       EmpathyTpContactList     *list;
-       MissionControl           *mc;
-       McProfile                *profile;
-       const gchar              *protocol_name;
-       guint                     handle;
-       GError                   *error = NULL;
-
-       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
-
-       mc = empathy_mission_control_new ();
-
-       if (mission_control_get_connection_status (mc, account, NULL) != 0) {
-               /* The account is not connected, nothing to do. */
-               return NULL;
-       }
-
-       list = g_object_new (EMPATHY_TYPE_TP_CONTACT_LIST, NULL);
-       priv = GET_PRIV (list);
-
-       priv->tp_conn = mission_control_get_connection (mc, account, NULL);
-       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, "local-xmpp") == 0) {
-               priv->protocol_group = _("People nearby");
-       }
-       g_object_unref (profile);
-
-       g_signal_connect (priv->tp_conn, "destroy",
-                         G_CALLBACK (tp_contact_list_destroy_cb),
-                         list);
-       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
-                                    "AccountStatusChanged",
-                                    G_CALLBACK (tp_contact_list_status_changed_cb),
-                                    list, NULL);
-
-       priv->aliasing_iface = tp_conn_get_interface (priv->tp_conn,
-                                                     TELEPATHY_CONN_IFACE_ALIASING_QUARK);
-       priv->avatars_iface = tp_conn_get_interface (priv->tp_conn,
-                                                    TELEPATHY_CONN_IFACE_AVATARS_QUARK);
-       priv->presence_iface = tp_conn_get_interface (priv->tp_conn,
-                                                     TELEPATHY_CONN_IFACE_PRESENCE_QUARK);
-
-       if (priv->aliasing_iface) {
-               dbus_g_proxy_connect_signal (priv->aliasing_iface,
-                                            "AliasesChanged",
-                                            G_CALLBACK (tp_contact_list_aliases_update_cb),
-                                            list, NULL);
-       }
-
-       if (priv->avatars_iface) {
-               dbus_g_proxy_connect_signal (priv->avatars_iface,
-                                            "AvatarUpdated",
-                                            G_CALLBACK (tp_contact_list_avatar_update_cb),
-                                            list, NULL);
-       }
-
-       if (priv->presence_iface) {
-               dbus_g_proxy_connect_signal (priv->presence_iface,
-                                            "PresenceUpdate",
-                                            G_CALLBACK (tp_contact_list_presence_update_cb),
-                                            list, NULL);
-       }
-
-       /* Get our own handle and contact */
-       if (!tp_conn_get_self_handle (DBUS_G_PROXY (priv->tp_conn),
-                                     &handle, &error)) {
-               empathy_debug (DEBUG_DOMAIN, "GetSelfHandle Error: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-       } else {
-               priv->user_contact = empathy_tp_contact_list_get_from_handle (list, handle);
-               empathy_contact_set_is_user (priv->user_contact, TRUE);
-       }
-
-       return list;
-}
-
-static void
-tp_contact_list_setup (EmpathyContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       GPtrArray                *channels;
-       GError                   *error = NULL;
-       guint                     i;
-
-       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
-
-       priv = GET_PRIV (list);
-
-       empathy_debug (DEBUG_DOMAIN, "setup contact list: %p", list);
-
-       priv->setup = TRUE;
-       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->tp_conn), "NewChannel",
-                                    G_CALLBACK (tp_contact_list_newchannel_cb),
-                                    list, NULL);
-
-       /* Get existing channels */
-       if (!tp_conn_list_channels (DBUS_G_PROXY (priv->tp_conn),
-                                   &channels,
-                                   &error)) {
-               empathy_debug (DEBUG_DOMAIN,
-                             "Failed to get list of open channels: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               return;
-       }
-
-       for (i = 0; channels->len > i; i++) {
-               GValueArray         *chan_struct;
-               const gchar         *object_path;
-               const gchar         *chan_iface;
-               TelepathyHandleType  handle_type;
-               guint                handle;
-
-               chan_struct = g_ptr_array_index (channels, i);
-               object_path = g_value_get_boxed (g_value_array_get_nth (chan_struct, 0));
-               chan_iface = g_value_get_string (g_value_array_get_nth (chan_struct, 1));
-               handle_type = g_value_get_uint (g_value_array_get_nth (chan_struct, 2));
-               handle = g_value_get_uint (g_value_array_get_nth (chan_struct, 3));
-
-               tp_contact_list_newchannel_cb (DBUS_G_PROXY (priv->tp_conn),
-                                              object_path, chan_iface,
-                                              handle_type, handle,
-                                              FALSE,
-                                              EMPATHY_TP_CONTACT_LIST (list));
-
-               g_value_array_free (chan_struct);
-       }
-
-       g_ptr_array_free (channels, TRUE);
-}
-
-static EmpathyContact *
-tp_contact_list_find (EmpathyContactList *list,
-                     const gchar        *id)
-{
-       EmpathyTpContactListPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       priv = GET_PRIV (list);
-
-       return g_hash_table_find (priv->contacts,
-                                 (GHRFunc) tp_contact_list_find_foreach,
-                                 (gchar*) id);
-}
-
-static void
-tp_contact_list_add (EmpathyContactList *list,
-                    EmpathyContact      *contact,
-                    const gchar        *message)
-{
-       EmpathyTpContactListPriv *priv;
-       guint                     handle;
-
-       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
-
-       priv = GET_PRIV (list);
-
-       handle = empathy_contact_get_handle (contact);
-       empathy_tp_group_add_member (priv->subscribe, handle, message);
-}
-
-static void
-tp_contact_list_remove (EmpathyContactList *list,
-                       EmpathyContact      *contact,
-                       const gchar        *message)
-{
-       EmpathyTpContactListPriv *priv;
-       guint                     handle;
+static void empathy_tp_contact_list_class_init (EmpathyTpContactListClass *klass);
+static void empathy_tp_contact_list_init       (EmpathyTpContactList      *list);
+static void tp_contact_list_iface_init         (EmpathyContactListIface   *iface);
 
 
-       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
-
-       priv = GET_PRIV (list);
-
-       handle = empathy_contact_get_handle (contact);
-       empathy_tp_group_remove_member (priv->subscribe, handle, message);
-}
-
-static GList *
-tp_contact_list_get_members (EmpathyContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       priv = GET_PRIV (list);
-
-       g_list_foreach (priv->members, (GFunc) g_object_ref, NULL);
-       return g_list_copy (priv->members);
-}
-
-static GList *
-tp_contact_list_get_local_pending (EmpathyContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       priv = GET_PRIV (list);
-
-       return g_list_copy (priv->local_pending);
-}
-
-static void
-tp_contact_list_process_pending (EmpathyContactList *list,
-                                EmpathyContact      *contact,
-                                gboolean            accept)
-{
-       EmpathyTpContactListPriv *priv;
-       guint                     handle;
-
-       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
-       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-       priv = GET_PRIV (list);
-
-       handle = empathy_contact_get_handle (contact);
-       if (accept) {
-               empathy_tp_group_add_member (priv->publish, handle, NULL);
-               empathy_tp_group_add_member (priv->subscribe, handle, NULL);
-       } else {
-               empathy_tp_group_remove_member (priv->publish, handle, NULL);
-       }
-}
-
-McAccount *
-empathy_tp_contact_list_get_account (EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       priv = GET_PRIV (list);
-
-       return priv->account;
-}
-
-EmpathyContact *
-empathy_tp_contact_list_get_user (EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       priv = GET_PRIV (list);
-       
-       return priv->user_contact;
-}
-
-EmpathyContact *
-empathy_tp_contact_list_get_from_id (EmpathyTpContactList *list,
-                                    const gchar          *id)
-{
-       EmpathyTpContactListPriv *priv;
-       EmpathyContact            *contact;
-       const gchar              *contact_ids[] = {id, NULL};
-       GArray                   *handles;
-       guint                     handle;
-       GError                   *error = NULL;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-       g_return_val_if_fail (id != NULL, NULL);
-       
-       priv = GET_PRIV (list);
-
-       contact = tp_contact_list_find (EMPATHY_CONTACT_LIST (list), id);
-       if (contact) {
-               return g_object_ref (contact);
-       }
-
-       /* The id is unknown, requests a new handle */
-       if (!tp_conn_request_handles (DBUS_G_PROXY (priv->tp_conn),
-                                     TP_HANDLE_TYPE_CONTACT,
-                                     contact_ids,
-                                     &handles, &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "RequestHandle for %s failed: %s", id,
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               return NULL;
-       }
-
-       handle = g_array_index(handles, guint, 0);
-       g_array_free (handles, TRUE);
-
-       return empathy_tp_contact_list_get_from_handle (list, handle);
-}
-
-EmpathyContact *
-empathy_tp_contact_list_get_from_handle (EmpathyTpContactList *list,
-                                        guint                 handle)
-{
-       EmpathyContact *contact;
-       GArray        *handles;
-       GList         *contacts;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       handles = g_array_new (FALSE, FALSE, sizeof (guint));
-       g_array_append_val (handles, handle);
-
-       contacts = empathy_tp_contact_list_get_from_handles (list, handles);
-       g_array_free (handles, TRUE);
-
-       if (!contacts) {
-               return NULL;
-       }
-
-       contact = contacts->data;
-       g_list_free (contacts);
-
-       return contact;
-}
-
-GList *
-empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list,
-                                         GArray               *handles)
-{
-       EmpathyTpContactListPriv  *priv;
-       gchar                    **handles_names;
-       gchar                    **id;
-       GArray                    *new_handles;
-       GList                     *contacts = NULL;
-       guint                      i;
-       GError                    *error = NULL;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-       g_return_val_if_fail (handles != NULL, NULL);
-
-       priv = GET_PRIV (list);
-
-       /* Search all handles we already have */
-       new_handles = g_array_new (FALSE, FALSE, sizeof (guint));
-       for (i = 0; i < handles->len; i++) {
-               EmpathyContact *contact;
-               guint          handle;
-
-               handle = g_array_index (handles, guint, i);
-
-               if (handle == 0) {
-                       continue;
-               }
-
-               contact = g_hash_table_lookup (priv->contacts,
-                                              GUINT_TO_POINTER (handle));
-
-               if (contact) {
-                       contacts = g_list_prepend (contacts,
-                                                  g_object_ref (contact));
-               } else {
-                       g_array_append_val (new_handles, handle);
-               }
-       }
-
-       if (new_handles->len == 0) {
-               g_array_free (new_handles, TRUE);
-               return contacts;
-       }
-
-       /* Holds all handles we don't have yet.
-        * FIXME: We should release them at some point. */
-       if (!tp_conn_hold_handles (DBUS_G_PROXY (priv->tp_conn),
-                                  TP_HANDLE_TYPE_CONTACT,
-                                  new_handles, &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "HoldHandles Error: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               g_array_free (new_handles, TRUE);
-               return contacts;
-       }
-
-       /* Get the IDs of all new handles */
-       if (!tp_conn_inspect_handles (DBUS_G_PROXY (priv->tp_conn),
-                                     TP_HANDLE_TYPE_CONTACT,
-                                     new_handles,
-                                     &handles_names,
-                                     &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "InspectHandle Error: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               g_array_free (new_handles, TRUE);
-               return contacts;
-       }
-
-       /* Create contact objects */
-       for (i = 0, id = handles_names; *id && i < new_handles->len; id++, i++) {
-               EmpathyContact *contact;
-               guint           handle;
-
-               handle = g_array_index (new_handles, guint, i);
-               contact = g_object_new (EMPATHY_TYPE_CONTACT,
-                                       "account", priv->account,
-                                       "id", *id,
-                                       "handle", handle,
-                                       NULL);
-
-               if (priv->protocol_group) {
-                       empathy_contact_add_group (contact, priv->protocol_group);
-               }
-
-               if (!priv->presence_iface) {
-                       EmpathyPresence *presence;
-
-                       /* We have no presence iface, set default presence
-                        * to available */
-                       presence = empathy_presence_new_full (MC_PRESENCE_AVAILABLE,
-                                                            NULL);
-
-                       empathy_contact_set_presence (contact, presence);
-                       g_object_unref (presence);
-               }
-
-               g_signal_connect (contact, "notify::groups",
-                                 G_CALLBACK (tp_contact_list_groups_updated_cb),
-                                 list);
-               g_signal_connect (contact, "notify::name",
-                                 G_CALLBACK (tp_contact_list_name_updated_cb),
-                                 list);
-
-               empathy_debug (DEBUG_DOMAIN, "new contact created: %s (%d)",
-                             *id, handle);
-
-               g_hash_table_insert (priv->contacts,
-                                    GUINT_TO_POINTER (handle),
-                                    contact);
-
-               contacts = g_list_prepend (contacts, g_object_ref (contact));
-       }
-
-       tp_contact_list_get_info (list, new_handles);
-
-       g_array_free (new_handles, TRUE);
-       g_strfreev (handles_names);
-
-       return contacts;
-}
-
-void
-empathy_tp_contact_list_rename_group (EmpathyTpContactList *list,
-                                     const gchar          *old_group,
-                                     const gchar          *new_group)
-{
-       EmpathyTpContactListPriv *priv;
-       EmpathyTpGroup           *group;
-       GArray                   *members;
-
-       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
-       g_return_if_fail (old_group != NULL);
-       g_return_if_fail (new_group != NULL);
-
-       priv = GET_PRIV (list);
-
-       group = g_hash_table_find (priv->groups,
-                                  (GHRFunc) tp_contact_list_find_group,
-                                  (gchar*) old_group);
-       if (!group) {
-               /* The group doesn't exists on this account */
-               return;
-       }
-
-       empathy_debug (DEBUG_DOMAIN, "rename group %s to %s", group, new_group);
-
-       /* Remove all members from the old group */
-       members = empathy_tp_group_get_members (group);
-       empathy_tp_group_remove_members (group, members, "");
-       tp_contact_list_group_members_removed_cb (group, members, 
-                                                 0, 
-                                                 TP_CHANNEL_GROUP_CHANGE_REASON_NONE, 
-                                                 NULL, list);
-       g_hash_table_remove (priv->groups,
-                            empathy_tp_group_get_object_path (group));
-
-       /* Add all members to the new group */
-       group = tp_contact_list_get_group (list, new_group);
-       if (group) {
-               empathy_tp_group_add_members (group, members, "");
-       }
-}
-
-GList *
-empathy_tp_contact_list_get_groups (EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       GList                    *groups = NULL;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-
-       priv = GET_PRIV (list);
-
-       g_hash_table_foreach (priv->groups,
-                             (GHFunc) tp_contact_list_get_groups_foreach,
-                             &groups);
-
-       groups = g_list_sort (groups, (GCompareFunc) strcmp);
-
-       return groups;
-}
-
-static void
-tp_contact_list_finalize_proxies (EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       priv = GET_PRIV (list);
-
-       if (priv->tp_conn) {
-               g_signal_handlers_disconnect_by_func (priv->tp_conn,
-                                                     tp_contact_list_destroy_cb,
-                                                     list);
-               dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->tp_conn), "NewChannel",
-                                               G_CALLBACK (tp_contact_list_newchannel_cb),
-                                               list);
-       }
-
-       if (priv->aliasing_iface) {
-               dbus_g_proxy_disconnect_signal (priv->aliasing_iface,
-                                               "AliasesChanged",
-                                               G_CALLBACK (tp_contact_list_aliases_update_cb),
-                                               list);
-       }
-
-       if (priv->avatars_iface) {
-               dbus_g_proxy_disconnect_signal (priv->avatars_iface,
-                                               "AvatarUpdated",
-                                               G_CALLBACK (tp_contact_list_avatar_update_cb),
-                                               list);
-       }
-
-       if (priv->presence_iface) {
-               dbus_g_proxy_disconnect_signal (priv->presence_iface,
-                                               "PresenceUpdate",
-                                               G_CALLBACK (tp_contact_list_presence_update_cb),
-                                               list);
-       }
-}
-
-static void
-tp_contact_list_destroy_cb (DBusGProxy           *proxy,
-                           EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-
-       priv = GET_PRIV (list);
-
-       empathy_debug (DEBUG_DOMAIN, "Connection destroyed... "
-                     "Account disconnected or CM crashed");
-
-       /* DBus proxies should NOT be used anymore */
-       g_object_unref (priv->tp_conn);
-       priv->tp_conn = NULL;
-       priv->aliasing_iface = NULL;
-       priv->avatars_iface = NULL;
-       priv->presence_iface = NULL;
-
-       /* Remove all contacts */
-       g_hash_table_foreach (priv->contacts,
-                             (GHFunc) tp_contact_list_contact_removed_foreach,
-                             list);
-       g_hash_table_remove_all (priv->contacts);
-
-       /* Tell the world to not use us anymore */
-       g_signal_emit (list, signals[DESTROY], 0);
-}
-
-static void
-tp_contact_list_contact_removed_foreach (guint                 handle,
-                                        EmpathyContact        *contact,
-                                        EmpathyTpContactList *list)
-{
-       g_signal_handlers_disconnect_by_func (contact,
-                                             tp_contact_list_groups_updated_cb,
-                                             list);
-       g_signal_handlers_disconnect_by_func (contact,
-                                             tp_contact_list_name_updated_cb,
-                                             list);
-
-       g_signal_emit_by_name (list, "contact-removed", contact);
-}
-
-static void
-tp_contact_list_block_contact (EmpathyTpContactList *list,
-                              EmpathyContact        *contact)
-{
-       g_signal_handlers_block_by_func (contact,
-                                        tp_contact_list_groups_updated_cb,
-                                        list);
-       g_signal_handlers_block_by_func (contact,
-                                        tp_contact_list_name_updated_cb,
-                                        list);
-}
-
-static void
-tp_contact_list_unblock_contact (EmpathyTpContactList *list,
-                                EmpathyContact        *contact)
-{
-       g_signal_handlers_unblock_by_func (contact,
-                                          tp_contact_list_groups_updated_cb,
-                                          list);
-       g_signal_handlers_unblock_by_func (contact,
-                                          tp_contact_list_name_updated_cb,
-                                          list);
-}
-
-static gboolean
-tp_contact_list_find_foreach (guint          handle,
-                             EmpathyContact *contact,
-                             gchar         *id)
-{
-       if (strcmp (empathy_contact_get_id (contact), id) == 0) {
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-static void
-tp_contact_list_newchannel_cb (DBusGProxy           *proxy,
-                              const gchar          *object_path,
-                              const gchar          *channel_type,
-                              TelepathyHandleType   handle_type,
-                              guint                 channel_handle,
-                              gboolean              suppress_handle,
-                              EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       EmpathyTpGroup           *group;
-       TpChan                   *new_chan;
-       const gchar              *bus_name;
-       GArray                   *members;
-
-       priv = GET_PRIV (list);
-
-       if (strcmp (channel_type, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST) != 0 ||
-           suppress_handle ||
-           !priv->setup) {
-               return;
-       }
-
-       bus_name = dbus_g_proxy_get_bus_name (DBUS_G_PROXY (priv->tp_conn));
-       new_chan = tp_chan_new (tp_get_bus (),
-                               bus_name,
-                               object_path,
-                               channel_type, handle_type, channel_handle);
-       g_return_if_fail (TELEPATHY_IS_CHAN (new_chan));
-
-       if (handle_type == TP_HANDLE_TYPE_LIST) {
-               TpContactListType list_type;
-
-               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) {
-                       empathy_debug (DEBUG_DOMAIN,
-                                     "Type of contact list channel unknown: %s",
-                                     empathy_tp_group_get_name (group));
-
-                       g_object_unref (new_chan);
-                       g_object_unref (group);
-                       return;
-               } else {
-                       empathy_debug (DEBUG_DOMAIN,
-                                     "New contact list channel of type: %d",
-                                     list_type);
-               }
-
-               g_signal_connect (group, "members-added",
-                                 G_CALLBACK (tp_contact_list_added_cb),
-                                 list);
-               g_signal_connect (group, "members-removed",
-                                 G_CALLBACK (tp_contact_list_removed_cb),
-                                 list);
+enum {
+       DESTROY,
+       LAST_SIGNAL
+};
 
 
-               if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
-                       GList *pendings, *l;
+static guint signals[LAST_SIGNAL];
 
 
-                       if (priv->publish) {
-                               g_object_unref (priv->publish);
-                       }
-                       priv->publish = group;
+G_DEFINE_TYPE_WITH_CODE (EmpathyTpContactList, empathy_tp_contact_list, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
+                                               tp_contact_list_iface_init));
 
 
-                       /* Makes no sense to be in remote-pending */
-                       g_signal_connect (group, "local-pending",
-                                         G_CALLBACK (tp_contact_list_pending_cb),
-                                         list);
+static void
+tp_contact_list_group_destroy_cb (EmpathyTpGroup       *group,
+                                 EmpathyTpContactList *list)
+{
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
 
 
-                       pendings = empathy_tp_group_get_local_pending_members_with_info (group);
-                       if (pendings) {
-                               GArray *pending;
-
-                               pending = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
-                               for (l = pendings; l; l = l->next) {
-                                       EmpathyTpGroupInfo *info;
-
-                                       info = l->data;
-
-                                       g_array_insert_val (pending, 0, info->member);
-                                       tp_contact_list_pending_cb (group, pending,
-                                                                   info->actor,
-                                                                   info->reason,
-                                                                   info->message,
-                                                                   list);
-                               }
-                               g_array_free (pending, TRUE);
-                               empathy_tp_group_info_list_free (pendings);
-                       }
-               }
-               if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
-                       GArray *remote_pendings = NULL;
+       empathy_debug (DEBUG_DOMAIN, "Group destroyed: %s",
+                      empathy_tp_group_get_name (group));
 
 
-                       if (priv->subscribe) {
-                               g_object_unref (priv->subscribe);
-                       }
-                       priv->subscribe = group;
+       priv->groups = g_list_remove (priv->groups, group);
+       g_object_unref (group);
+}
 
 
-                       /* Makes no sense to be in local-pending */
-                       g_signal_connect (group, "remote-pending",
-                                         G_CALLBACK (tp_contact_list_pending_cb),
-                                         list);
-                       empathy_tp_group_get_all_members (group,
-                                                         &members,
-                                                         NULL,
-                                                         &remote_pendings);
-
-                       tp_contact_list_pending_cb (group, remote_pendings, 0,
-                                                   TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
-                                                   NULL,
-                                                   list);
-                       g_array_free (remote_pendings, TRUE);
-               } else {
-                       members = empathy_tp_group_get_members (group);
-               }
+static void
+tp_contact_list_group_member_added_cb (EmpathyTpGroup       *group,
+                                      EmpathyContact       *contact,
+                                      EmpathyContact       *actor,
+                                      guint                 reason,
+                                      const gchar          *message,
+                                      EmpathyTpContactList *list)
+{
+       EmpathyTpContactListPriv  *priv = GET_PRIV (list);
+       const gchar               *group_name;
+       GList                    **groups;
 
 
-               tp_contact_list_added_cb (group, members, 0,
-                                         TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
-                                         NULL, list);
-               g_array_free (members, TRUE);
+       if (!g_list_find (priv->members, contact)) {
+               return;
        }
        }
-       else if (handle_type == TP_HANDLE_TYPE_GROUP) {
-               const gchar *object_path;
 
 
-               object_path = dbus_g_proxy_get_path (DBUS_G_PROXY (new_chan));
-               if (g_hash_table_lookup (priv->groups, object_path)) {
-                       g_object_unref (new_chan);
-                       return;
-               }
+       groups = g_hash_table_lookup (priv->contacts_groups, contact);
+       if (!groups) {
+               groups = g_slice_new0 (GList*);
+               g_hash_table_insert (priv->contacts_groups,
+                                    g_object_ref (contact),
+                                    groups);
+       }
 
 
-               group = empathy_tp_group_new (priv->account, new_chan);
+       group_name = empathy_tp_group_get_name (group);
+       if (!g_list_find_custom (*groups, group_name, (GCompareFunc) strcmp)) {
+               empathy_debug (DEBUG_DOMAIN, "Contact %s (%d) added to group %s",
+                              empathy_contact_get_id (contact),
+                              empathy_contact_get_handle (contact),
+                              group_name);
+               *groups = g_list_prepend (*groups, g_strdup (group_name));
+               g_signal_emit_by_name (list, "groups-changed", contact,
+                                      group_name,
+                                      TRUE);
+       }
+}
 
 
-               empathy_debug (DEBUG_DOMAIN, "New server-side group channel: %s",
-                             empathy_tp_group_get_name (group));
+static void
+tp_contact_list_group_member_removed_cb (EmpathyTpGroup       *group,
+                                        EmpathyContact       *contact,
+                                        EmpathyContact       *actor,
+                                        guint                 reason,
+                                        const gchar          *message,
+                                        EmpathyTpContactList *list)
+{
+       EmpathyTpContactListPriv  *priv = GET_PRIV (list);
+       const gchar               *group_name;
+       GList                    **groups, *l;
 
 
-               dbus_g_proxy_connect_signal (DBUS_G_PROXY (new_chan), "Closed",
-                                            G_CALLBACK
-                                            (tp_contact_list_group_channel_closed_cb),
-                                            list, NULL);
+       if (!g_list_find (priv->members, contact)) {
+               return;
+       }
 
 
-               g_hash_table_insert (priv->groups, g_strdup (object_path), group);
-               g_signal_connect (group, "members-added",
-                                 G_CALLBACK (tp_contact_list_group_members_added_cb),
-                                 list);
-               g_signal_connect (group, "members-removed",
-                                 G_CALLBACK (tp_contact_list_group_members_removed_cb),
-                                 list);
+       groups = g_hash_table_lookup (priv->contacts_groups, contact);
+       if (!groups) {
+               return;
+       }
 
 
-               members = empathy_tp_group_get_members (group);
-               tp_contact_list_group_members_added_cb (group, members, 0,
-                                                       TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
-                                                       NULL, list);
-               g_array_free (members, TRUE);
+       group_name = empathy_tp_group_get_name (group);
+       if ((l = g_list_find_custom (*groups, group_name, (GCompareFunc) strcmp))) {
+               empathy_debug (DEBUG_DOMAIN, "Contact %s (%d) removed from group %s",
+                              empathy_contact_get_id (contact),
+                              empathy_contact_get_handle (contact),
+                              group_name);
+               *groups = g_list_delete_link (*groups, l);
+               g_signal_emit_by_name (list, "groups-changed", contact,
+                                      group_name,
+                                      FALSE);
        }
        }
+}
 
 
-       g_object_unref (new_chan);
+static EmpathyTpGroup *
+tp_contact_list_find_group (EmpathyTpContactList *list,
+                           const gchar          *group)
+{
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       GList                    *l;
+
+       for (l = priv->groups; l; l = l->next) {
+               if (strcmp (group, empathy_tp_group_get_name (l->data)) == 0) {
+                       return l->data;
+               }
+       }
+       return NULL;
 }
 
 static TpContactListType
 }
 
 static TpContactListType
@@ -1127,808 +199,795 @@ tp_contact_list_get_type (EmpathyTpContactList *list,
        return list_type;
 }
 
        return list_type;
 }
 
+static void
+tp_contact_list_add_member (EmpathyTpContactList *list,
+                           EmpathyContact       *contact,
+                           EmpathyContact       *actor,
+                           guint                 reason,
+                           const gchar          *message)
+{
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       GList                    *l;
+
+       /* Add to the list and emit signal */
+       priv->members = g_list_prepend (priv->members, g_object_ref (contact));
+       g_signal_emit_by_name (list, "members-changed",
+                              contact, actor, reason, message,
+                              TRUE);
+
+       /* This contact is now member, implicitly accept pending. */
+       if (g_list_find (priv->pendings, contact)) {
+               empathy_tp_group_add_member (priv->publish, contact, "");
+       }
+
+       /* Update groups of the contact */
+       for (l = priv->groups; l; l = l->next) {
+               if (empathy_tp_group_is_member (l->data, contact)) {
+                       tp_contact_list_group_member_added_cb (l->data, contact,
+                                                              NULL, 0, NULL, 
+                                                              list);
+               }
+       }
+}
+
 static void
 tp_contact_list_added_cb (EmpathyTpGroup       *group,
 static void
 tp_contact_list_added_cb (EmpathyTpGroup       *group,
-                         GArray               *handles,
-                         guint                 actor_handle,
+                         EmpathyContact       *contact,
+                         EmpathyContact       *actor,
                          guint                 reason,
                          const gchar          *message,
                          EmpathyTpContactList *list)
 {
                          guint                 reason,
                          const gchar          *message,
                          EmpathyTpContactList *list)
 {
-       EmpathyTpContactListPriv *priv;
-       GList                    *added_list, *l;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
        TpContactListType         list_type;
 
        TpContactListType         list_type;
 
-       priv = GET_PRIV (list);
-
        list_type = tp_contact_list_get_type (list, group);
        list_type = tp_contact_list_get_type (list, group);
-
-       added_list = empathy_tp_contact_list_get_from_handles (list, handles);
-       for (l = added_list; l; l = l->next) {
-               EmpathyContact      *contact;
-               EmpathySubscription  subscription;
-
-               contact = EMPATHY_CONTACT (l->data);
-
-               empathy_debug (DEBUG_DOMAIN, "Contact '%s' added to list type %d",
-                             empathy_contact_get_name (contact),
-                             list_type);
-
-               subscription = empathy_contact_get_subscription (contact);
-               if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
-                       subscription |= EMPATHY_SUBSCRIPTION_FROM;
-               }
-               else if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
-                       subscription |= EMPATHY_SUBSCRIPTION_TO;
-                       tp_contact_list_remove_local_pending (list, contact);
-               }
-
-               tp_contact_list_block_contact (list, contact);
-               empathy_contact_set_subscription (contact, subscription);
-               tp_contact_list_unblock_contact (list, contact);
-
-               if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
-                       if (!g_list_find (priv->members, contact)) {
-                               priv->members = g_list_prepend (priv->members,
-                                                               g_object_ref (contact));
-                               g_signal_emit_by_name (list, "contact-added", contact);
-                       }
-               }
-
+       empathy_debug (DEBUG_DOMAIN, "Contact %s (%d) added to list type %d",
+                     empathy_contact_get_id (contact),
+                     empathy_contact_get_handle (contact),
+                     list_type);
+
+       /* We now get the presence of that contact, add it to members */
+       if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE &&
+           !g_list_find (priv->members, contact)) {
+               tp_contact_list_add_member (list, contact, actor, reason, message);
+       }
+
+       /* We now send our presence to that contact, remove it from pendings */
+       if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH &&
+           g_list_find (priv->pendings, contact)) {
+               g_signal_emit_by_name (list, "pendings-changed",
+                                      contact, actor, reason, message,
+                                      FALSE);
+               priv->pendings = g_list_remove (priv->pendings, contact);
                g_object_unref (contact);
        }
                g_object_unref (contact);
        }
-
-       g_list_free (added_list);
 }
 
 static void
 tp_contact_list_removed_cb (EmpathyTpGroup       *group,
 }
 
 static void
 tp_contact_list_removed_cb (EmpathyTpGroup       *group,
-                           GArray               *handles,
-                           guint                 actor_handle,
+                           EmpathyContact       *contact,
+                           EmpathyContact       *actor,
                            guint                 reason,
                            const gchar          *message,
                            EmpathyTpContactList *list)
 {
                            guint                 reason,
                            const gchar          *message,
                            EmpathyTpContactList *list)
 {
-       EmpathyTpContactListPriv *priv;
-       GList                    *removed_list, *l;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
        TpContactListType         list_type;
 
        TpContactListType         list_type;
 
-       priv = GET_PRIV (list);
-
        list_type = tp_contact_list_get_type (list, group);
        list_type = tp_contact_list_get_type (list, group);
-
-       removed_list = empathy_tp_contact_list_get_from_handles (list, handles);
-       for (l = removed_list; l; l = l->next) {
-               EmpathyContact      *contact;
-               EmpathySubscription  subscription;
-
-               contact = EMPATHY_CONTACT (l->data);
-
-               empathy_debug (DEBUG_DOMAIN, "Contact '%s' removed from list type %d",
-                             empathy_contact_get_name (contact),
-                             list_type);
-
-               subscription = empathy_contact_get_subscription (contact);
-               if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
-                       subscription &= !EMPATHY_SUBSCRIPTION_FROM;
-               }
-               else if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
-                       subscription &= !EMPATHY_SUBSCRIPTION_TO;
-                       tp_contact_list_remove_local_pending (list, contact);
-               }
-
-               tp_contact_list_block_contact (list, contact);
-               empathy_contact_set_subscription (contact, subscription);
-               tp_contact_list_unblock_contact (list, contact);
-
-               if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
-                       GList *l;
-
-                       if ((l = g_list_find (priv->members, contact))) {
-                               g_signal_emit_by_name (list, "contact-removed", contact);
-                               priv->members = g_list_delete_link (priv->members, l);
-                               g_object_unref (contact);
-                       }
-               }
+       empathy_debug (DEBUG_DOMAIN, "Contact %s (%d) removed from list type %d",
+                     empathy_contact_get_id (contact),
+                     empathy_contact_get_handle (contact),
+                     list_type);
+
+       /* This contact refuses to send us his presence, remove from members. */
+       if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE &&
+           g_list_find (priv->members, contact)) {
+               g_signal_emit_by_name (list, "members-changed",
+                                      contact, actor, reason, message,
+                                      FALSE);
+               priv->members = g_list_remove (priv->members, contact);
                g_object_unref (contact);
        }
 
                g_object_unref (contact);
        }
 
-       g_list_free (removed_list);
+       /* We refuse to send our presence to that contact, remove from pendings */
+       if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH &&
+           g_list_find (priv->pendings, contact)) {
+               g_signal_emit_by_name (list, "pendings-changed",
+                                      contact, actor, reason, message,
+                                      FALSE);
+               priv->pendings = g_list_remove (priv->pendings, contact);
+               g_object_unref (contact);
+       }
 }
 
 static void
 tp_contact_list_pending_cb (EmpathyTpGroup       *group,
 }
 
 static void
 tp_contact_list_pending_cb (EmpathyTpGroup       *group,
-                           GArray               *handles,
-                           guint                 actor_handle,
+                           EmpathyContact       *contact,
+                           EmpathyContact       *actor,
                            guint                 reason,
                            const gchar          *message,
                            EmpathyTpContactList *list)
 {
                            guint                 reason,
                            const gchar          *message,
                            EmpathyTpContactList *list)
 {
-       EmpathyTpContactListPriv *priv;
-       GList                    *pending_list, *l;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
        TpContactListType         list_type;
 
        TpContactListType         list_type;
 
-       priv = GET_PRIV (list);
-
        list_type = tp_contact_list_get_type (list, group);
        list_type = tp_contact_list_get_type (list, group);
-
-       pending_list = empathy_tp_contact_list_get_from_handles (list, handles);
-       for (l = pending_list; l; l = l->next) {
-               EmpathyContact *contact;
-
-               contact = EMPATHY_CONTACT (l->data);
-
-               empathy_debug (DEBUG_DOMAIN, "Contact '%s' pending in list type %d",
-                             empathy_contact_get_name (contact),
-                             list_type);
-
-               if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
-                       if (!g_list_find (priv->members, contact)) {
-                               EmpathyContactListInfo *info;
-
-                               info = empathy_contact_list_info_new (contact, message);
-                               priv->local_pending = g_list_prepend (priv->local_pending,
-                                                                     info);
-
-                               g_signal_emit_by_name (list, "local-pending",
-                                                      contact, message);
-                       } else {
-                               guint handle;
-
-                               /* That contact wants our presence and he is
-                                * in our roster. Accept to publish our presence
-                                * without asking the user. */
-                               handle = empathy_contact_get_handle (contact);
-                               empathy_tp_group_add_member (priv->publish,
-                                                            handle, "");
-                       }
-               }
-               else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
-                       if (!g_list_find (priv->members, contact)) {
-                               priv->members = g_list_prepend (priv->members,
-                                                               g_object_ref (contact));
-                               g_signal_emit_by_name (list, "contact-added", contact);
-                       }
+       empathy_debug (DEBUG_DOMAIN, "Contact %s (%d) pending in list type %d",
+                     empathy_contact_get_id (contact),
+                     empathy_contact_get_handle (contact),
+                     list_type);
+
+       /* We want this contact in our contact list but we don't get its 
+        * presence yet. Add to members anyway. */
+       if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE &&
+           !g_list_find (priv->members, contact)) {
+               tp_contact_list_add_member (list, contact, actor, reason, message);
+       }
+
+       /* This contact wants our presence, auto accept if he is member,
+        * otherwise he is pending. */
+       if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH &&
+           !g_list_find (priv->pendings, contact)) {
+               if (g_list_find (priv->members, contact)) {
+                       empathy_tp_group_add_member (priv->publish, contact, "");
+               } else {
+                       priv->pendings = g_list_prepend (priv->pendings,
+                                                        g_object_ref (contact));
+                       g_signal_emit_by_name (list, "pendings-changed",
+                                              contact, actor, reason, message,
+                                              TRUE);
                }
                }
-
-               g_object_unref (contact);
        }
        }
-
-       g_list_free (pending_list);
 }
 
 static void
 }
 
 static void
-tp_contact_list_remove_local_pending (EmpathyTpContactList *list,
-                                     EmpathyContact        *contact)
+tp_contact_list_newchannel_cb (DBusGProxy           *proxy,
+                              const gchar          *object_path,
+                              const gchar          *channel_type,
+                              TelepathyHandleType   handle_type,
+                              guint                 channel_handle,
+                              gboolean              suppress_handle,
+                              EmpathyTpContactList *list)
 {
 {
-       EmpathyTpContactListPriv *priv;
-       GList                    *l;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       EmpathyTpGroup           *group;
+       TpChan                   *new_chan;
+       const gchar              *bus_name;
 
 
-       priv = GET_PRIV (list);
+       if (strcmp (channel_type, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST) != 0 ||
+           suppress_handle) {
+               return;
+       }
 
 
-       for (l = priv->local_pending; l; l = l->next) {
-               EmpathyContactListInfo *info;
+       bus_name = dbus_g_proxy_get_bus_name (DBUS_G_PROXY (priv->tp_conn));
+       new_chan = tp_chan_new (tp_get_bus (),
+                               bus_name,
+                               object_path,
+                               channel_type,
+                               handle_type,
+                               channel_handle);
+       g_return_if_fail (TELEPATHY_IS_CHAN (new_chan));
 
 
-               info = l->data;
-               if (empathy_contact_equal (contact, info->contact)) {
-                       empathy_debug (DEBUG_DOMAIN, "Contact no more local-pending: %s",
-                                     empathy_contact_get_name (contact));
+       group = empathy_tp_group_new (priv->account, new_chan);
+       g_object_unref (new_chan);
 
 
-                       priv->local_pending = g_list_delete_link (priv->local_pending, l);
-                       empathy_contact_list_info_free (info);
-                       break;
-               }
-       }
-}
+       if (handle_type == TP_HANDLE_TYPE_LIST) {
+               TpContactListType  list_type;
+               GList             *contacts, *l;
 
 
-static void
-tp_contact_list_groups_updated_cb (EmpathyContact       *contact,
-                                  GParamSpec           *param,
-                                  EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       TpContactListData         data;
-       GList                    *groups, *l;
+               list_type = tp_contact_list_get_type (list, group);
+               if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH && !priv->publish) {
+                       priv->publish = group;
 
 
-       priv = GET_PRIV (list);
+                       /* Publish is the list of contacts to who we send our
+                        * presence. Makes no sense to be in remote-pending */
+                       g_signal_connect (group, "local-pending",
+                                         G_CALLBACK (tp_contact_list_pending_cb),
+                                         list);
 
 
-       /* Make sure all groups are created */
-       groups = empathy_contact_get_groups (contact);
-       for (l = groups; l; l = l->next) {
-               tp_contact_list_get_group (list, l->data);
-       }
+                       contacts = empathy_tp_group_get_local_pendings (group);
+                       for (l = contacts; l; l = l->next) {
+                               EmpathyPendingInfo *info = l->data;
+
+                               tp_contact_list_pending_cb (group,
+                                                           info->member,
+                                                           info->actor,
+                                                           0,
+                                                           info->message,
+                                                           list);
+                               empathy_pending_info_free (info);
+                       }
+                       g_list_free (contacts);
+               }
+               else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE && !priv->subscribe) {
+                       priv->subscribe = group;
 
 
-       data.handle = empathy_contact_get_handle (contact);
-       data.new_groups = groups;
+                       /* Subscribe is the list of contacts from who we
+                        * receive presence. Makes no sense to be in
+                        * local-pending */
+                       g_signal_connect (group, "remote-pending",
+                                         G_CALLBACK (tp_contact_list_pending_cb),
+                                         list);
 
 
-       g_hash_table_foreach (priv->groups,
-                             (GHFunc) tp_contact_list_update_groups_foreach,
-                             &data);
-}
+                       contacts = empathy_tp_group_get_remote_pendings (group);
+                       for (l = contacts; l; l = l->next) {
+                               tp_contact_list_pending_cb (group,
+                                                           l->data,
+                                                           NULL, 0,
+                                                           NULL, list);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free (contacts);
+               } else {
+                       empathy_debug (DEBUG_DOMAIN,
+                                     "Type of contact list channel unknown "
+                                     "or aleady have that list: %s",
+                                     empathy_tp_group_get_name (group));
+                       g_object_unref (group);
+                       return;
+               }
+               empathy_debug (DEBUG_DOMAIN,
+                              "New contact list channel of type: %d",
+                              list_type);
 
 
-static void
-tp_contact_list_name_updated_cb (EmpathyContact        *contact,
-                                GParamSpec           *param,
-                                EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       GHashTable               *new_alias;
-       const gchar              *new_name;
-       guint                     handle;
-       GError                   *error = NULL;
+               g_signal_connect (group, "member-added",
+                                 G_CALLBACK (tp_contact_list_added_cb),
+                                 list);
+               g_signal_connect (group, "member-removed",
+                                 G_CALLBACK (tp_contact_list_removed_cb),
+                                 list);
 
 
-       priv = GET_PRIV (list);
-       
-       if (!priv->aliasing_iface) {
-               return;
+               contacts = empathy_tp_group_get_members (group);
+               for (l = contacts; l; l = l->next) {
+                       tp_contact_list_added_cb (group,
+                                                 l->data,
+                                                 NULL, 0, NULL,
+                                                 list);
+                       g_object_unref (l->data);
+               }
+               g_list_free (contacts);
        }
        }
+       else if (handle_type == TP_HANDLE_TYPE_GROUP) {
+               const gchar *group_name;
+               GList       *contacts, *l;
 
 
-       handle = empathy_contact_get_handle (contact);
-       new_name = empathy_contact_get_name (contact);
+               /* Check if already exists */
+               group_name = empathy_tp_group_get_name (group);
+               if (tp_contact_list_find_group (list, group_name)) {
+                       g_object_unref (group);
+                       return;
+               }
 
 
-       empathy_debug (DEBUG_DOMAIN, "renaming handle %d to %s",
-                     handle, new_name);
+               empathy_debug (DEBUG_DOMAIN, "New server-side group channel: %s",
+                              group_name);
 
 
-       new_alias = g_hash_table_new_full (g_direct_hash,
-                                          g_direct_equal,
-                                          NULL,
-                                          g_free);
+               priv->groups = g_list_prepend (priv->groups, group);
 
 
-       g_hash_table_insert (new_alias,
-                            GUINT_TO_POINTER (handle),
-                            g_strdup (new_name));
+               g_signal_connect (group, "member-added",
+                                 G_CALLBACK (tp_contact_list_group_member_added_cb),
+                                 list);
+               g_signal_connect (group, "member-removed",
+                                 G_CALLBACK (tp_contact_list_group_member_removed_cb),
+                                 list);
+               g_signal_connect (group, "destroy",
+                                 G_CALLBACK (tp_contact_list_group_destroy_cb),
+                                 list);
 
 
-       if (!tp_conn_iface_aliasing_set_aliases (priv->aliasing_iface,
-                                                new_alias,
-                                                &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "Couldn't rename contact: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
+               contacts = empathy_tp_group_get_members (group);
+               for (l = contacts; l; l = l->next) {
+                       tp_contact_list_group_member_added_cb (group, l->data,
+                                                              NULL, 0, NULL,
+                                                              list);
+                       g_object_unref (l->data);
+               }
+               g_list_free (contacts);
+       } else {
+               empathy_debug (DEBUG_DOMAIN,
+                              "Unknown handle type (%d) for contact list channel",
+                              handle_type);
+               g_object_unref (group);
        }
        }
-
-       g_hash_table_destroy (new_alias);
 }
 
 static void
 }
 
 static void
-tp_contact_list_update_groups_foreach (gchar             *object_path,
-                                      EmpathyTpGroup    *group,
-                                      TpContactListData *data)
+tp_contact_list_remove_all (EmpathyTpContactList *list)
 {
 {
-       gboolean     is_member;
-       gboolean     found = FALSE;
-       const gchar *group_name;
-       GList       *l;
-
-       is_member = empathy_tp_group_is_member (group, data->handle);
-       group_name = empathy_tp_group_get_name (group);
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       GList                    *l;
 
 
-       for (l = data->new_groups; l; l = l->next) {
-               if (strcmp (group_name, l->data) == 0) {
-                       found = TRUE;
-                       break;
-               }
+       for (l = priv->members; l; l = l->next) {
+               g_signal_emit_by_name (list, "members-changed", l->data,
+                                      NULL, 0, NULL,
+                                      FALSE);
+               g_object_unref (l->data);
        }
        }
-
-       if (is_member && !found) {
-               /* We are no longer member of this group */
-               empathy_debug (DEBUG_DOMAIN, "Contact %d removed from group '%s'",
-                             data->handle, group_name);
-               empathy_tp_group_remove_member (group, data->handle, "");
+       for (l = priv->pendings; l; l = l->next) {
+               g_signal_emit_by_name (list, "pendings-changed", l->data,
+                                      NULL, 0, NULL,
+                                      FALSE);
+               g_object_unref (l->data);
        }
 
        }
 
-       if (!is_member && found) {
-               /* We are now member of this group */
-               empathy_debug (DEBUG_DOMAIN, "Contact %d added to group '%s'",
-                             data->handle, group_name);
-               empathy_tp_group_add_member (group, data->handle, "");
-       }
+       g_list_free (priv->members);
+       g_list_free (priv->pendings);
+       priv->members = NULL;
+       priv->pendings = NULL;
 }
 
 }
 
-static EmpathyTpGroup *
-tp_contact_list_get_group (EmpathyTpContactList *list,
-                          const gchar          *name)
+static void
+tp_contact_list_destroy_cb (TpConn               *tp_conn,
+                           EmpathyTpContactList *list)
 {
 {
-       EmpathyTpContactListPriv *priv;
-       EmpathyTpGroup           *group;
-       TpChan                   *group_channel;
-       GArray                   *handles;
-       guint                     group_handle;
-       char                     *group_object_path;
-       const char               *names[2] = {name, NULL};
-       GError                   *error = NULL;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
 
 
-       priv = GET_PRIV (list);
-
-       group = g_hash_table_find (priv->groups,
-                                  (GHRFunc) tp_contact_list_find_group,
-                                  (gchar*) name);
-       if (group) {
-               return group;
-       }
+       empathy_debug (DEBUG_DOMAIN, "Account disconnected or CM crashed");
 
 
-       empathy_debug (DEBUG_DOMAIN, "creating new group: %s", name);
+       /* DBus proxie should NOT be used anymore */
+       g_object_unref (priv->tp_conn);
+       priv->tp_conn = NULL;
 
 
-       if (!tp_conn_request_handles (DBUS_G_PROXY (priv->tp_conn),
-                                     TP_HANDLE_TYPE_GROUP,
-                                     names,
-                                     &handles,
-                                     &error)) {
-               empathy_debug (DEBUG_DOMAIN,
-                             "Couldn't request the creation of a new handle for group: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               return NULL;
-       }
-       group_handle = g_array_index (handles, guint, 0);
-       g_array_free (handles, TRUE);
+       tp_contact_list_remove_all (list);
 
 
-       if (!tp_conn_request_channel (DBUS_G_PROXY (priv->tp_conn),
-                                     TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
-                                     TP_HANDLE_TYPE_GROUP,
-                                     group_handle,
-                                     FALSE,
-                                     &group_object_path,
-                                     &error)) {
-               empathy_debug (DEBUG_DOMAIN,
-                             "Couldn't request the creation of a new group channel: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               return NULL;
-       }
+       /* Tell the world to not use us anymore */
+       g_signal_emit (list, signals[DESTROY], 0);
+}
 
 
-       group_channel = tp_chan_new (tp_get_bus (),
-                                    dbus_g_proxy_get_bus_name (DBUS_G_PROXY (priv->tp_conn)),
-                                    group_object_path,
-                                    TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
-                                    TP_HANDLE_TYPE_GROUP,
-                                    group_handle);
-
-       dbus_g_proxy_connect_signal (DBUS_G_PROXY (group_channel),
-                                    "Closed",
-                                    G_CALLBACK
-                                    (tp_contact_list_group_channel_closed_cb),
-                                    list,
-                                    NULL);
-
-       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),
-                         list);
-       g_signal_connect (group, "members-removed",
-                         G_CALLBACK (tp_contact_list_group_members_removed_cb),
-                         list);
+static void
+tp_contact_list_disconnect (EmpathyTpContactList *list)
+{
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
 
 
-       return group;
+       if (priv->tp_conn) {
+               g_signal_handlers_disconnect_by_func (priv->tp_conn,
+                                                     tp_contact_list_destroy_cb,
+                                                     list);
+               dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->tp_conn), "NewChannel",
+                                               G_CALLBACK (tp_contact_list_newchannel_cb),
+                                               list);
+       }
 }
 
 }
 
-static gboolean
-tp_contact_list_find_group (gchar          *key,
-                           EmpathyTpGroup *group,
-                           gchar          *group_name)
+static void
+tp_contact_list_status_changed_cb (MissionControl                  *mc,
+                                  TelepathyConnectionStatus        status,
+                                  McPresence                       presence,
+                                  TelepathyConnectionStatusReason  reason,
+                                  const gchar                     *unique_name,
+                                  EmpathyTpContactList            *list)
 {
 {
-       if (strcmp (group_name, empathy_tp_group_get_name (group)) == 0) {
-               return TRUE;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       McAccount                *account;
+
+       account = mc_account_lookup (unique_name);
+       if (status != TP_CONN_STATUS_CONNECTED &&
+           empathy_account_equal (account, priv->account)) {
+               /* We are disconnected */
+               tp_contact_list_disconnect (list);
+               tp_contact_list_destroy_cb (priv->tp_conn, list);
        }
 
        }
 
-       return FALSE;
+       g_object_unref (account);
 }
 
 static void
 }
 
 static void
-tp_contact_list_get_groups_foreach (gchar          *key,
-                                   EmpathyTpGroup *group,
-                                   GList          **groups)
+tp_contact_list_group_list_free (GList **groups)
 {
 {
-       const gchar *name;
-
-       name = empathy_tp_group_get_name (group);
-       *groups = g_list_append (*groups, g_strdup (name));
+       g_list_foreach (*groups, (GFunc) g_free, NULL);
+       g_list_free (*groups);
+       g_slice_free (GList*, groups);
 }
 
 static void
 }
 
 static void
-tp_contact_list_group_channel_closed_cb (TpChan             *channel,
-                                        EmpathyTpContactList *list)
+tp_contact_list_finalize (GObject *object)
 {
        EmpathyTpContactListPriv *priv;
 {
        EmpathyTpContactListPriv *priv;
+       EmpathyTpContactList     *list;
 
 
+       list = EMPATHY_TP_CONTACT_LIST (object);
        priv = GET_PRIV (list);
 
        priv = GET_PRIV (list);
 
-       g_hash_table_remove (priv->groups,
-                            dbus_g_proxy_get_path (DBUS_G_PROXY (channel)));
-}
+       empathy_debug (DEBUG_DOMAIN, "finalize: %p", object);
 
 
-static void
-tp_contact_list_group_members_added_cb (EmpathyTpGroup       *group,
-                                       GArray               *members,
-                                       guint                 actor_handle,
-                                       guint                 reason,
-                                       const gchar          *message,
-                                       EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       GList                    *added_list, *l;
-       const gchar              *group_name;
+       tp_contact_list_disconnect (list);
+       tp_contact_list_remove_all (list);
 
 
-       priv = GET_PRIV (list);
+       if (priv->mc) {
+               dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
+                                               "AccountStatusChanged",
+                                               G_CALLBACK (tp_contact_list_status_changed_cb),
+                                               list);
+               g_object_unref (priv->mc);
+       }
 
 
-       group_name = empathy_tp_group_get_name (group);
-       added_list = empathy_tp_contact_list_get_from_handles (list, members);
+       if (priv->subscribe) {
+               g_object_unref (priv->subscribe);
+       }
+       if (priv->publish) {
+               g_object_unref (priv->publish);
+       }
+       if (priv->account) {
+               g_object_unref (priv->account);
+       }
+       if (priv->tp_conn) {
+               g_object_unref (priv->tp_conn);
+       }
+
+       g_hash_table_destroy (priv->contacts_groups);
+       g_list_foreach (priv->groups, (GFunc) g_object_unref, NULL);
+       g_list_free (priv->groups);
+
+       G_OBJECT_CLASS (empathy_tp_contact_list_parent_class)->finalize (object);
+}
 
 
-       for (l = added_list; l; l = l->next) {
-               EmpathyContact *contact;
+static void
+empathy_tp_contact_list_class_init (EmpathyTpContactListClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 
-               contact = EMPATHY_CONTACT (l->data);
+       object_class->finalize = tp_contact_list_finalize;
 
 
-               tp_contact_list_block_contact (list, contact);
-               empathy_contact_add_group (contact, group_name);
-               tp_contact_list_unblock_contact (list, contact);
+       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_object_unref (contact);
-       }
+       g_type_class_add_private (object_class, sizeof (EmpathyTpContactListPriv));
+}
 
 
-       g_list_free (added_list);
+static void
+empathy_tp_contact_list_init (EmpathyTpContactList *list)
+{
 }
 
 static void
 }
 
 static void
-tp_contact_list_group_members_removed_cb (EmpathyTpGroup       *group,
-                                         GArray               *members,
-                                         guint                 actor_handle,
-                                         guint                 reason,
-                                         const gchar          *message,
-                                         EmpathyTpContactList *list)
+tp_contact_list_setup (EmpathyTpContactList *list)
 {
 {
-       EmpathyTpContactListPriv *priv;
-       GList                    *removed_list, *l;
-       const gchar              *group_name;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       GPtrArray                *channels;
+       guint                     i;
+       GError                   *error = NULL;
 
 
-       priv = GET_PRIV (list);
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
 
 
-       group_name = empathy_tp_group_get_name (group);
-       removed_list = empathy_tp_contact_list_get_from_handles (list, members);
+       /* Get existing channels */
+       if (!tp_conn_list_channels (DBUS_G_PROXY (priv->tp_conn),
+                                   &channels,
+                                   &error)) {
+               empathy_debug (DEBUG_DOMAIN,
+                             "Failed to get list of open channels: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+               return;
+       }
 
 
-       for (l = removed_list; l; l = l->next) {
-               EmpathyContact *contact;
+       for (i = 0; i < channels->len; i++) {
+               GValueArray         *chan_struct;
+               const gchar         *object_path;
+               const gchar         *chan_iface;
+               TelepathyHandleType  handle_type;
+               guint                handle;
 
 
-               contact = l->data;
+               chan_struct = g_ptr_array_index (channels, i);
+               object_path = g_value_get_boxed (g_value_array_get_nth (chan_struct, 0));
+               chan_iface = g_value_get_string (g_value_array_get_nth (chan_struct, 1));
+               handle_type = g_value_get_uint (g_value_array_get_nth (chan_struct, 2));
+               handle = g_value_get_uint (g_value_array_get_nth (chan_struct, 3));
 
 
-               tp_contact_list_block_contact (list, contact);
-               empathy_contact_remove_group (contact, group_name);
-               tp_contact_list_unblock_contact (list, contact);
+               tp_contact_list_newchannel_cb (DBUS_G_PROXY (priv->tp_conn),
+                                              object_path, chan_iface,
+                                              handle_type, handle,
+                                              FALSE,
+                                              list);
 
 
-               g_object_unref (contact);
+               g_value_array_free (chan_struct);
        }
        }
-
-       g_list_free (removed_list);
+       g_ptr_array_free (channels, TRUE);
 }
 
 }
 
-static void
-tp_contact_list_get_info (EmpathyTpContactList *list,
-                         GArray               *handles)
+EmpathyTpContactList *
+empathy_tp_contact_list_new (McAccount *account)
 {
        EmpathyTpContactListPriv *priv;
 {
        EmpathyTpContactListPriv *priv;
-       GError                   *error = NULL;
+       EmpathyTpContactList     *list;
+       MissionControl           *mc;
+       TpConn                   *tp_conn = NULL;
+       McProfile                *profile;
+       const gchar              *protocol_name;
 
 
-       priv = GET_PRIV (list);
+       g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
 
 
-       if (priv->presence_iface) {
-               /* FIXME: We should use GetPresence instead */
-               if (!tp_conn_iface_presence_request_presence (priv->presence_iface,
-                                                             handles, &error)) {
-                       empathy_debug (DEBUG_DOMAIN, 
-                                     "Could not request presences: %s",
-                                     error ? error->message : "No error given");
-                       g_clear_error (&error);
-               }
+       mc = empathy_mission_control_new ();
+
+       /* status==0 means CONNECTED */
+       if (mission_control_get_connection_status (mc, account, NULL) == 0) {
+               tp_conn = mission_control_get_connection (mc, account, NULL);
+       }
+       if (!tp_conn) {
+               /* The account is not connected, nothing to do. */
+               g_object_unref (mc);
+               return NULL;
        }
 
        }
 
-       if (priv->aliasing_iface) {
-               TpContactListAliasesRequestData *data;
+       list = g_object_new (EMPATHY_TYPE_TP_CONTACT_LIST, NULL);
+       priv = GET_PRIV (list);
 
 
-               data = g_slice_new (TpContactListAliasesRequestData);
-               data->list = list;
-               data->handles = g_memdup (handles->data, handles->len * sizeof (guint));
+       priv->tp_conn = tp_conn;
+       priv->account = g_object_ref (account);
+       priv->mc = mc;
+       priv->contacts_groups = g_hash_table_new_full (empathy_contact_hash,
+                                                      empathy_contact_equal,
+                                                      (GDestroyNotify) g_object_unref,
+                                                      (GDestroyNotify) tp_contact_list_group_list_free);
 
 
-               tp_conn_iface_aliasing_request_aliases_async (priv->aliasing_iface,
-                                                             handles,
-                                                             (tp_conn_iface_aliasing_request_aliases_reply)
-                                                             tp_contact_list_request_aliases_cb,
-                                                             data);
+       /* 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, "local-xmpp") == 0) {
+               priv->protocol_group = _("People nearby");
        }
        }
+       g_object_unref (profile);
 
 
-       if (priv->avatars_iface) {
-               guint i;
+       /* Connect signals */
+       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
+                                    "AccountStatusChanged",
+                                    G_CALLBACK (tp_contact_list_status_changed_cb),
+                                    list, NULL);
+       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->tp_conn), "NewChannel",
+                                    G_CALLBACK (tp_contact_list_newchannel_cb),
+                                    list, NULL);
+       g_signal_connect (priv->tp_conn, "destroy",
+                         G_CALLBACK (tp_contact_list_destroy_cb),
+                         list);
 
 
-               for (i = 0; i < handles->len; i++) {
-                       guint handle;
+       tp_contact_list_setup (list);
 
 
-                       handle = g_array_index (handles, gint, i);
-                       tp_contact_list_request_avatar (list, handle);
-               }
-       }
+       return list;
 }
 
 }
 
-static void
-tp_contact_list_request_avatar (EmpathyTpContactList *list,
-                               guint                 handle)
+McAccount *
+empathy_tp_contact_list_get_account (EmpathyTpContactList *list)
 {
 {
-       EmpathyTpContactListPriv       *priv;
-       TpContactListAvatarRequestData *data;
+       EmpathyTpContactListPriv *priv;
+
+       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
 
        priv = GET_PRIV (list);
 
        priv = GET_PRIV (list);
-       
-       /* We queue avatar requests to not send too many dbus async
-        * calls at once. If we don't we reach the dbus's limit of
-        * pending calls */
-       data = g_slice_new (TpContactListAvatarRequestData);
-       data->list = g_object_ref (list);
-       data->handle = handle;
-       avatar_requests_queue = g_list_append (avatar_requests_queue, data);
-       tp_contact_list_start_avatar_requests ();
+
+       return priv->account;
 }
 
 static void
 }
 
 static void
-tp_contact_list_start_avatar_requests (void)
+tp_contact_list_add (EmpathyContactList *list,
+                    EmpathyContact     *contact,
+                    const gchar        *message)
 {
 {
-       empathy_debug (DEBUG_DOMAIN, "Start avatar requests, pending calls: %d",
-                      n_avatar_requests);
-
-       while (n_avatar_requests <  MAX_AVATAR_REQUESTS && avatar_requests_queue) {
-               EmpathyTpContactListPriv       *priv;
-               TpContactListAvatarRequestData *data;
-
-               data = avatar_requests_queue->data;
-               priv = GET_PRIV (data->list);
-
-               n_avatar_requests++;
-               avatar_requests_queue = g_list_delete_link (avatar_requests_queue,
-                                                           avatar_requests_queue);
-
-               empathy_debug (DEBUG_DOMAIN, "Calling RequestAvatar async");
-               tp_conn_iface_avatars_request_avatar_async (priv->avatars_iface,
-                                                           data->handle,
-                                                           (tp_conn_iface_avatars_request_avatar_reply)
-                                                           tp_contact_list_request_avatar_cb,
-                                                           data);
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
+
+       empathy_tp_group_add_member (priv->subscribe, contact, message);
+       if (g_list_find (priv->pendings, contact)) {
+               empathy_tp_group_add_member (priv->publish, contact, message);          
        }
 }
 
 static void
        }
 }
 
 static void
-tp_contact_list_avatar_update_cb (DBusGProxy           *proxy,
-                                 guint                 handle,
-                                 gchar                *new_token,
-                                 EmpathyTpContactList *list)
+tp_contact_list_remove (EmpathyContactList *list,
+                       EmpathyContact     *contact,
+                       const gchar        *message)
 {
 {
-       EmpathyTpContactListPriv *priv;
-
-       priv = GET_PRIV (list);
-
-       if (!g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle))) {
-               /* We don't know this contact, skip */
-               return;
-       }
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
 
 
-       empathy_debug (DEBUG_DOMAIN, "Changing avatar for %d to %s",
-                     handle, new_token);
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
 
 
-       tp_contact_list_request_avatar (list, handle);
+       empathy_tp_group_remove_member (priv->subscribe, contact, message);
+       empathy_tp_group_remove_member (priv->publish, contact, message);               
 }
 
 }
 
-static void
-tp_contact_list_request_avatar_cb (DBusGProxy                     *proxy,
-                                  GArray                         *avatar_data,
-                                  gchar                          *mime_type,
-                                  GError                         *error,
-                                  TpContactListAvatarRequestData *data)
+static GList *
+tp_contact_list_get_members (EmpathyContactList *list)
 {
 {
-       EmpathyContact *contact;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
 
 
-       contact = empathy_tp_contact_list_get_from_handle (data->list, data->handle);
+       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
 
 
-       if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error requesting avatar for %s: %s",
-                             empathy_contact_get_name (contact),
-                             error ? error->message : "No error given");
-       } else {
-               EmpathyAvatar *avatar;
+       g_list_foreach (priv->members, (GFunc) g_object_ref, NULL);
+       return g_list_copy (priv->members);
+}
 
 
-               empathy_debug (DEBUG_DOMAIN, "Avatar received for %s (%d)",
-                              empathy_contact_get_id (contact),
-                              data->handle);
-
-               avatar = empathy_avatar_new (avatar_data->data,
-                                           avatar_data->len,
-                                           mime_type);
-               tp_contact_list_block_contact (data->list, contact);
-               empathy_contact_set_avatar (contact, avatar);
-               tp_contact_list_unblock_contact (data->list, contact);
-               empathy_avatar_unref (avatar);
-       }
+static GList *
+tp_contact_list_get_pendings (EmpathyContactList *list)
+{
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
 
 
-       n_avatar_requests--;
-       tp_contact_list_start_avatar_requests ();
+       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
 
 
-       g_object_unref (contact);
-       g_object_unref (data->list);
-       g_slice_free (TpContactListAvatarRequestData, data);
+       g_list_foreach (priv->pendings, (GFunc) g_object_ref, NULL);
+       return g_list_copy (priv->pendings);
 }
 
 }
 
-static void
-tp_contact_list_aliases_update_cb (DBusGProxy           *proxy,
-                                  GPtrArray            *renamed_handlers,
-                                  EmpathyTpContactList *list)
+static GList *
+tp_contact_list_get_all_groups (EmpathyContactList *list)
 {
 {
-       EmpathyTpContactListPriv *priv;
-       guint                     i;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       GList                    *groups = NULL, *l;
 
 
-       priv = GET_PRIV (list);
+       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
 
 
-       for (i = 0; renamed_handlers->len > i; i++) {
-               guint          handle;
-               const gchar   *alias;
-               GValueArray   *renamed_struct;
-               EmpathyContact *contact;
+       for (l = priv->groups; l; l = l->next) {
+               const gchar *name;
 
 
-               renamed_struct = g_ptr_array_index (renamed_handlers, i);
-               handle = g_value_get_uint(g_value_array_get_nth (renamed_struct, 0));
-               alias = g_value_get_string(g_value_array_get_nth (renamed_struct, 1));
+               name = empathy_tp_group_get_name (l->data);
+               groups = g_list_prepend (groups, g_strdup (name));
+       }
 
 
-               if (!g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle))) {
-                       /* We don't know this contact, skip */
-                       continue;
-               }
+       return groups;
+}
 
 
-               if (G_STR_EMPTY (alias)) {
-                       alias = NULL;
-               }
+static GList *
+tp_contact_list_get_groups (EmpathyContactList *list,
+                           EmpathyContact     *contact)
+{
+       EmpathyTpContactListPriv  *priv = GET_PRIV (list);
+       GList                    **groups;
+       GList                     *ret = NULL, *l;
 
 
-               contact = empathy_tp_contact_list_get_from_handle (list, handle);
-               tp_contact_list_block_contact (list, contact);
-               empathy_contact_set_name (contact, alias);
-               tp_contact_list_unblock_contact (list, contact);
-               g_object_unref (contact);
+       g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
+
+       groups = g_hash_table_lookup (priv->contacts_groups, contact);
+       if (!groups) {
+               return NULL;
+       }
 
 
-               empathy_debug (DEBUG_DOMAIN, "contact %d renamed to %s (update cb)",
-                             handle, alias);
+       for (l = *groups; l; l = l->next) {
+               ret = g_list_prepend (ret, g_strdup (l->data));
        }
        }
+
+       return ret;
 }
 
 }
 
-static void
-tp_contact_list_request_aliases_cb (DBusGProxy                       *proxy,
-                                   gchar                           **contact_names,
-                                   GError                           *error,
-                                   TpContactListAliasesRequestData  *data)
+static EmpathyTpGroup *
+tp_contact_list_get_group (EmpathyTpContactList *list,
+                          const gchar          *group)
 {
 {
-       guint   i = 0;
-       gchar **name;
+       EmpathyTpContactListPriv *priv = GET_PRIV (list);
+       EmpathyTpGroup           *tp_group;
+       gchar                    *object_path;
+       guint                     handle;
+       GArray                   *handles;
+       const char               *names[2] = {group, NULL};
+       GError                   *error = NULL;
 
 
-       if (error) {
-               empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
-                             error->message);
+       tp_group = tp_contact_list_find_group (list, group);
+       if (tp_group) {
+               return tp_group;
        }
 
        }
 
-       for (name = contact_names; *name && !error; name++) {
-               EmpathyContact *contact;
+       empathy_debug (DEBUG_DOMAIN, "creating new group: %s", group);
 
 
-               contact = empathy_tp_contact_list_get_from_handle (data->list,
-                                                                  data->handles[i]);
-               tp_contact_list_block_contact (data->list, contact);
-               empathy_contact_set_name (contact, *name);
-               tp_contact_list_unblock_contact (data->list, contact);
-               g_object_unref (contact);
-
-               empathy_debug (DEBUG_DOMAIN, "contact %d renamed to %s (request cb)",
-                             data->handles[i], *name);
+       if (!tp_conn_request_handles (DBUS_G_PROXY (priv->tp_conn),
+                                     TP_HANDLE_TYPE_GROUP,
+                                     names,
+                                     &handles,
+                                     &error)) {
+               empathy_debug (DEBUG_DOMAIN,
+                             "Failed to RequestHandles: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+               return NULL;
+       }
+       handle = g_array_index (handles, guint, 0);
+       g_array_free (handles, TRUE);
 
 
-               i++;
+       if (!tp_conn_request_channel (DBUS_G_PROXY (priv->tp_conn),
+                                     TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
+                                     TP_HANDLE_TYPE_GROUP,
+                                     handle,
+                                     FALSE,
+                                     &object_path,
+                                     &error)) {
+               empathy_debug (DEBUG_DOMAIN,
+                             "Failed to RequestChannel: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+               return NULL;
        }
 
        }
 
-       g_free (data->handles);
-       g_slice_free (TpContactListAliasesRequestData, data);
-}
+       tp_contact_list_newchannel_cb (DBUS_G_PROXY (priv->tp_conn),
+                                      object_path,
+                                      TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
+                                      TP_HANDLE_TYPE_GROUP,
+                                      handle, FALSE,
+                                      list);
+       g_free (object_path);
 
 
-static void
-tp_contact_list_presence_update_cb (DBusGProxy           *proxy,
-                                   GHashTable           *handle_table,
-                                   EmpathyTpContactList *list)
-{
-       g_hash_table_foreach (handle_table,
-                             (GHFunc) tp_contact_list_parse_presence_foreach,
-                             list);
+       return tp_contact_list_find_group (list, group);
 }
 
 static void
 }
 
 static void
-tp_contact_list_parse_presence_foreach (guint                 handle,
-                                       GValueArray          *presence_struct,
-                                       EmpathyTpContactList *list)
+tp_contact_list_add_to_group (EmpathyContactList *list,
+                             EmpathyContact     *contact,
+                             const gchar        *group)
 {
 {
-       EmpathyTpContactListPriv *priv;
-       GHashTable     *presences_table;
-       EmpathyContact  *contact;
-       EmpathyPresence *presence = NULL;
-
-       priv = GET_PRIV (list);
-
-       if (!g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle))) {
-               /* We don't know this contact, skip */
-               return;
-       }
-
-       contact = empathy_tp_contact_list_get_from_handle (list, handle);
-       presences_table = g_value_get_boxed (g_value_array_get_nth (presence_struct, 1));
+       EmpathyTpGroup *tp_group;
 
 
-       g_hash_table_foreach (presences_table,
-                             (GHFunc) tp_contact_list_presences_table_foreach,
-                             &presence);
-
-       empathy_debug (DEBUG_DOMAIN, "Presence changed for %s (%d) to %s (%d)",
-                     empathy_contact_get_name (contact),
-                     handle,
-                     presence ? empathy_presence_get_status (presence) : "unset",
-                     presence ? empathy_presence_get_state (presence) : MC_PRESENCE_UNSET);
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
 
 
-       tp_contact_list_block_contact (list, contact);
-       empathy_contact_set_presence (contact, presence);
-       tp_contact_list_unblock_contact (list, contact);
+       tp_group = tp_contact_list_get_group (EMPATHY_TP_CONTACT_LIST (list),
+                                             group);
 
 
-       g_object_unref (contact);
+       empathy_tp_group_add_member (tp_group, contact, "");
 }
 
 static void
 }
 
 static void
-tp_contact_list_presences_table_foreach (const gchar     *state_str,
-                                        GHashTable      *presences_table,
-                                        EmpathyPresence **presence)
+tp_contact_list_remove_from_group (EmpathyContactList *list,
+                                  EmpathyContact     *contact,
+                                  const gchar        *group)
 {
 {
-       McPresence    state;
-       const GValue *message;
-
-       state = empathy_presence_state_from_str (state_str);
-       if ((state == MC_PRESENCE_UNSET) || (state == MC_PRESENCE_OFFLINE)) {
-               return;
-       }
+       EmpathyTpGroup *tp_group;
 
 
-       if (*presence) {
-               g_object_unref (*presence);
-               *presence = NULL;
-       }
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
 
 
-       *presence = empathy_presence_new ();
-       empathy_presence_set_state (*presence, state);
+       tp_group = tp_contact_list_find_group (EMPATHY_TP_CONTACT_LIST (list),
+                                              group);
 
 
-       message = g_hash_table_lookup (presences_table, "message");
-       if (message != NULL) {
-               empathy_presence_set_status (*presence,
-                                           g_value_get_string (message));
+       if (tp_group) {
+               empathy_tp_group_remove_member (tp_group, contact, "");
        }
 }
 
 static void
        }
 }
 
 static void
-tp_contact_list_status_changed_cb (MissionControl                  *mc,
-                                  TelepathyConnectionStatus        status,
-                                  McPresence                       presence,
-                                  TelepathyConnectionStatusReason  reason,
-                                  const gchar                     *unique_name,
-                                  EmpathyTpContactList            *list)
+tp_contact_list_rename_group (EmpathyContactList *list,
+                             const gchar        *old_group,
+                             const gchar        *new_group)
 {
 {
-       EmpathyTpContactListPriv *priv;
-       McAccount                *account;
+       EmpathyTpGroup *tp_group;
+       GList          *members;
 
 
-       priv = GET_PRIV (list);
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
 
 
-       account = mc_account_lookup (unique_name);
-       if (status != TP_CONN_STATUS_DISCONNECTED ||
-           !empathy_account_equal (account, priv->account) ||
-           !priv->tp_conn) {
-               g_object_unref (account);
+       tp_group = tp_contact_list_find_group (EMPATHY_TP_CONTACT_LIST (list),
+                                              old_group);
+       if (!tp_group) {
                return;
        }
 
                return;
        }
 
-       /* We are disconnected, do just like if the connection was destroyed */
-       g_signal_handlers_disconnect_by_func (priv->tp_conn,
-                                             tp_contact_list_destroy_cb,
-                                             list);
-       tp_contact_list_destroy_cb (DBUS_G_PROXY (priv->tp_conn), list);
+       empathy_debug (DEBUG_DOMAIN, "rename group %s to %s", old_group, new_group);
 
 
-       g_object_unref (account);
+       /* Remove all members from the old group */
+       members = empathy_tp_group_get_members (tp_group);
+       empathy_tp_group_remove_members (tp_group, members, "");
+       empathy_tp_group_close (tp_group);
+
+       /* Add all members to the new group */
+       tp_group = tp_contact_list_get_group (EMPATHY_TP_CONTACT_LIST (list),
+                                             new_group);
+       empathy_tp_group_add_members (tp_group, members, "");
+
+       g_list_foreach (members, (GFunc) g_object_unref, NULL);
+       g_list_free (members);
+}
+
+static void
+tp_contact_list_iface_init (EmpathyContactListIface *iface)
+{
+       iface->add               = tp_contact_list_add;
+       iface->remove            = tp_contact_list_remove;
+       iface->get_members       = tp_contact_list_get_members;
+       iface->get_pendings      = tp_contact_list_get_pendings;
+       iface->get_all_groups    = tp_contact_list_get_all_groups;
+       iface->get_groups        = tp_contact_list_get_groups;
+       iface->add_to_group      = tp_contact_list_add_to_group;
+       iface->remove_from_group = tp_contact_list_remove_from_group;
+       iface->rename_group      = tp_contact_list_rename_group;
 }
 
 }
 
index f0eccb37525979a7a03f2281166b913a1e39eac4..6ac4662fae718e3f44137b1a8ec4cfa324a736c9 100644 (file)
@@ -50,20 +50,9 @@ struct _EmpathyTpContactListClass {
        GObjectClass parent_class;
 };
 
        GObjectClass parent_class;
 };
 
-GType                  empathy_tp_contact_list_get_type         (void) G_GNUC_CONST;
-EmpathyTpContactList * empathy_tp_contact_list_new              (McAccount            *account);
-McAccount *            empathy_tp_contact_list_get_account      (EmpathyTpContactList *list);
-EmpathyContact *        empathy_tp_contact_list_get_user         (EmpathyTpContactList *list);
-EmpathyContact *        empathy_tp_contact_list_get_from_id      (EmpathyTpContactList *list,
-                                                                const gchar          *id);
-EmpathyContact *        empathy_tp_contact_list_get_from_handle  (EmpathyTpContactList *list,
-                                                                guint                 handle);
-GList *                empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list,
-                                                                GArray               *handles);
-void                   empathy_tp_contact_list_rename_group     (EmpathyTpContactList *list,
-                                                                const gchar          *old_group,
-                                                                const gchar          *new_group);
-GList *                empathy_tp_contact_list_get_groups       (EmpathyTpContactList *list);
+GType                  empathy_tp_contact_list_get_type    (void) G_GNUC_CONST;
+EmpathyTpContactList * empathy_tp_contact_list_new         (McAccount            *account);
+McAccount *            empathy_tp_contact_list_get_account (EmpathyTpContactList *list);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
index b86a00e28139a56cd989738a21f200acc249a3b1..1ffab9ecd2d27a8078ed40aacc43824e710cd4c3 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2006 Xavier Claessens <xclaesse@gmail.com>
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2006 Xavier Claessens <xclaesse@gmail.com>
+ * 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
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * License along with this program; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  * 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 <dbus/dbus-glib.h>
 #include <libtelepathy/tp-chan.h>
  */
 
 #include <config.h>
 
 #include <dbus/dbus-glib.h>
 #include <libtelepathy/tp-chan.h>
+#include <libtelepathy/tp-chan-gen.h>
 #include <libtelepathy/tp-chan-iface-group-gen.h>
 #include <libtelepathy/tp-constants.h>
 #include <libtelepathy/tp-conn.h>
 
 #include <libtelepathy/tp-chan-iface-group-gen.h>
 #include <libtelepathy/tp-constants.h>
 #include <libtelepathy/tp-conn.h>
 
-#include "empathy-debug.h"
 #include "empathy-tp-group.h"
 #include "empathy-tp-group.h"
+#include "empathy-contact-factory.h"
+#include "empathy-debug.h"
 #include "empathy-utils.h"
 #include "empathy-marshal.h"
 
 #include "empathy-utils.h"
 #include "empathy-marshal.h"
 
 #define DEBUG_DOMAIN "TpGroup"
 
 struct _EmpathyTpGroupPriv {
 #define DEBUG_DOMAIN "TpGroup"
 
 struct _EmpathyTpGroupPriv {
-       McAccount  *account;
-       DBusGProxy *group_iface;
-       TpChan     *tp_chan;
-       gchar      *group_name;
+       EmpathyContactFactory *factory;
+       McAccount             *account;
+       DBusGProxy            *group_iface;
+       TpChan                *tp_chan;
+       gchar                 *group_name;
+       guint                  self_handle;
+
+       GList                 *members;
+       GList                 *local_pendings;
+       GList                 *remote_pendings;
 };
 
 static void empathy_tp_group_class_init (EmpathyTpGroupClass *klass);
 static void empathy_tp_group_init       (EmpathyTpGroup      *group);
 };
 
 static void empathy_tp_group_class_init (EmpathyTpGroupClass *klass);
 static void empathy_tp_group_init       (EmpathyTpGroup      *group);
-static void tp_group_finalize           (GObject             *object);
-static void tp_group_destroy_cb         (DBusGProxy          *proxy,
-                                        EmpathyTpGroup      *group);
-static void tp_group_members_changed_cb (DBusGProxy          *group_iface,
-                                        gchar               *message,
-                                        GArray              *added,
-                                        GArray              *removed,
-                                        GArray              *local_pending,
-                                        GArray              *remote_pending,
-                                        guint                actor,
-                                        guint                reason,
-                                        EmpathyTpGroup      *group);
 
 enum {
 
 enum {
-       MEMBERS_ADDED,
-       MEMBERS_REMOVED,
+       MEMBER_ADDED,
+       MEMBER_REMOVED,
        LOCAL_PENDING,
        REMOTE_PENDING,
        LOCAL_PENDING,
        REMOTE_PENDING,
+       DESTROY,
        LAST_SIGNAL
 };
 
        LAST_SIGNAL
 };
 
@@ -70,6 +70,409 @@ static guint signals[LAST_SIGNAL];
 
 G_DEFINE_TYPE (EmpathyTpGroup, empathy_tp_group, G_TYPE_OBJECT);
 
 
 G_DEFINE_TYPE (EmpathyTpGroup, empathy_tp_group, G_TYPE_OBJECT);
 
+static EmpathyContact *
+tp_group_get_contact (EmpathyTpGroup *group,
+                     guint           handle)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       EmpathyContact     *contact = NULL;
+       
+       if (handle != 0) {
+               contact = empathy_contact_factory_get_from_handle (priv->factory,
+                                                                  priv->account,
+                                                                  handle);
+       }
+
+       if (contact && empathy_contact_get_handle (contact) == priv->self_handle) {
+               empathy_contact_set_is_user (contact, TRUE);
+       }
+
+       return contact;
+}
+
+static GList *
+tp_group_get_contacts (EmpathyTpGroup *group,
+                      GArray         *handles)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GList              *contacts,  *l;
+
+       if (!handles) {
+               return NULL;
+       }
+
+       contacts = empathy_contact_factory_get_from_handles (priv->factory,
+                                                            priv->account,
+                                                            handles);
+
+       /* FIXME: Only useful if the group has a different self handle than
+        * the connection, otherwise the contact factory already set that
+        * property. That can be known using group flags. */
+       for (l = contacts; l; l = l->next) {
+               if (empathy_contact_get_handle (l->data) == priv->self_handle) {
+                       empathy_contact_set_is_user (l->data, TRUE);
+               }
+       }
+
+       return contacts;
+}
+
+EmpathyPendingInfo *
+empathy_pending_info_new (EmpathyContact *member,
+                         EmpathyContact *actor,
+                         const gchar    *message)
+{
+       EmpathyPendingInfo *info;
+
+       info = g_slice_new0 (EmpathyPendingInfo);
+
+       if (member) {
+               info->member = g_object_ref (member);
+       }
+       if (actor) {
+               info->actor = g_object_ref (actor);
+       }
+       if (message) {
+               info->message = g_strdup (message);
+       }
+
+       return info;
+}
+
+void
+empathy_pending_info_free (EmpathyPendingInfo *info)
+{
+       if (!info) {
+               return;
+       }
+
+       if (info->member) {
+               g_object_unref (info->member);
+       }
+       if (info->actor) {
+               g_object_unref (info->actor);
+       }
+       g_free (info->message);
+
+       g_slice_free (EmpathyPendingInfo, info);
+}
+
+static gint
+tp_group_local_pending_find (gconstpointer a,
+                            gconstpointer b)
+{
+       const EmpathyPendingInfo *info = a;
+
+       return (info->member != b);
+}
+
+static void
+tp_group_remove_from_pendings (EmpathyTpGroup *group,
+                              EmpathyContact *contact)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GList              *l;
+
+       /* local pending */
+       l = g_list_find_custom (priv->local_pendings,
+                               contact,
+                               tp_group_local_pending_find);
+       if (l) {
+               empathy_pending_info_free (l->data);
+               priv->local_pendings = g_list_delete_link (priv->local_pendings, l);
+       }
+
+       /* remote pending */
+       l = g_list_find (priv->remote_pendings, contact);
+       if (l) {
+               g_object_unref (l->data);
+               priv->remote_pendings = g_list_delete_link (priv->remote_pendings, l);
+       }
+}
+
+static void
+tp_group_members_changed_cb (DBusGProxy     *group_iface,
+                            const gchar    *message,
+                            GArray         *added,
+                            GArray         *removed,
+                            GArray         *local_pending,
+                            GArray         *remote_pending,
+                            guint           actor,
+                            guint           reason,
+                            EmpathyTpGroup *group)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       EmpathyContact     *actor_contact = NULL;
+       GList              *contacts, *l, *ll;
+
+       actor_contact = tp_group_get_contact (group, actor);
+
+       empathy_debug (DEBUG_DOMAIN, "Members changed for list %s:\n"
+                                    "  added-len=%d, current-len=%d\n"
+                                    "  removed-len=%d\n"
+                                    "  local-pending-len=%d, current-len=%d\n"
+                                    "  remote-pending-len=%d, current-len=%d",
+                      empathy_tp_group_get_name (group),
+                      added ? added->len : 0, g_list_length (priv->members),
+                      removed ? removed->len : 0,
+                      local_pending ? local_pending->len : 0,
+                      g_list_length (priv->local_pendings),
+                      remote_pending ? remote_pending->len : 0,
+                      g_list_length (priv->remote_pendings));
+
+       /* Contacts added */
+       contacts = tp_group_get_contacts (group, added);
+       for (l = contacts; l; l = l->next) {
+               tp_group_remove_from_pendings (group, l->data);
+
+               /* If the contact is not yet member, add it and emit signal */
+               if (!g_list_find (priv->members, l->data)) {
+                       priv->members = g_list_prepend (priv->members,
+                                                       g_object_ref (l->data));
+                       g_signal_emit (group, signals[MEMBER_ADDED], 0,
+                                      l->data, actor_contact, reason, message);
+               }
+               g_object_unref (l->data);
+       }
+       g_list_free (contacts);
+
+       /* Contacts removed */
+       contacts = tp_group_get_contacts (group, removed);
+       for (l = contacts; l; l = l->next) {
+               tp_group_remove_from_pendings (group, l->data);
+
+               /* If the contact is member, remove it and emit signal */
+               if ((ll = g_list_find (priv->members, l->data))) {
+                       g_object_unref (ll->data);
+                       priv->members = g_list_delete_link (priv->members, ll);
+                       g_signal_emit (group, signals[MEMBER_REMOVED], 0,
+                                      l->data, actor_contact, reason, message);
+               }
+               g_object_unref (l->data);
+       }
+       g_list_free (contacts);
+
+       /* Contacts local pending */
+       contacts = tp_group_get_contacts (group, local_pending);
+       for (l = contacts; l; l = l->next) {
+               /* If the contact is not yet local-pending, add it and emit signal */
+               if (!g_list_find_custom (priv->members, l->data,
+                                        tp_group_local_pending_find)) {
+                       EmpathyPendingInfo *info;
+
+                       info = empathy_pending_info_new (l->data,
+                                                        actor_contact,
+                                                        message);
+
+                       priv->local_pendings = g_list_prepend (priv->local_pendings, info);
+                       g_signal_emit (group, signals[LOCAL_PENDING], 0,
+                                      l->data, actor_contact, reason, message);
+               }
+               g_object_unref (l->data);
+       }
+       g_list_free (contacts);
+
+       /* Contacts remote pending */
+       contacts = tp_group_get_contacts (group, remote_pending);
+       for (l = contacts; l; l = l->next) {
+               /* If the contact is not yet remote-pending, add it and emit signal */
+               if (!g_list_find (priv->remote_pendings, l->data)) {
+                       priv->remote_pendings = g_list_prepend (priv->remote_pendings,
+                                                               g_object_ref (l->data));
+                       g_signal_emit (group, signals[REMOTE_PENDING], 0,
+                                      l->data, actor_contact, reason, message);
+               }
+               g_object_unref (l->data);
+       }
+       g_list_free (contacts);
+
+       if (actor_contact) {
+               g_object_unref (actor_contact);
+       }
+
+       empathy_debug (DEBUG_DOMAIN, "Members changed done for list %s:\n"
+                                    "  members-len=%d\n"
+                                    "  local-pendings-len=%d\n"
+                                    "  remote-pendings-len=%d",
+                      empathy_tp_group_get_name (group),
+                      g_list_length (priv->members),
+                      g_list_length (priv->local_pendings),
+                      g_list_length (priv->remote_pendings));
+}
+
+static void
+tp_group_destroy_cb (TpChan         *tp_chan,
+                    EmpathyTpGroup *group)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+
+       empathy_debug (DEBUG_DOMAIN, "Account disconnected or CM crashed");
+
+       g_object_unref (priv->tp_chan);
+       priv->group_iface = NULL;
+       priv->tp_chan = NULL;
+
+       g_signal_emit (group, signals[DESTROY], 0);
+}
+
+static void tp_group_closed_cb (DBusGProxy     *proxy,
+                               EmpathyTpGroup *group);
+
+static void
+tp_group_disconnect (EmpathyTpGroup *group)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+
+       if (priv->group_iface) {
+               dbus_g_proxy_disconnect_signal (priv->group_iface, "MembersChanged",
+                                               G_CALLBACK (tp_group_members_changed_cb),
+                                               group);
+       }
+       if (priv->tp_chan) {
+               g_signal_handlers_disconnect_by_func (priv->tp_chan,
+                                                     tp_group_destroy_cb,
+                                                     group);
+               dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->tp_chan), "Closed",
+                                               G_CALLBACK (tp_group_closed_cb),
+                                               group);
+       }
+}
+
+static void
+tp_group_closed_cb (DBusGProxy     *proxy,
+                   EmpathyTpGroup *group)
+{
+       tp_group_disconnect (group);
+       tp_group_destroy_cb (TELEPATHY_CHAN (proxy), group);
+}
+
+static void
+tp_group_get_members_cb (DBusGProxy *proxy,
+                        GArray     *handles,
+                        GError     *error,
+                        gpointer    user_data)
+{
+       EmpathyTpGroup     *group = user_data;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Failed to get members: %s",
+                              error->message);
+               return;
+       }
+
+       tp_group_members_changed_cb (priv->group_iface,
+                                    NULL,    /* message */
+                                    handles, /* added */
+                                    NULL,    /* removed */
+                                    NULL,    /* local_pending */
+                                    NULL,    /* remote_pending */
+                                    0,       /* actor */
+                                    0,       /* reason */
+                                    group);
+}
+
+static void
+tp_group_get_local_pending_cb (DBusGProxy *proxy,
+                              GPtrArray  *array,
+                              GError     *error,
+                              gpointer    user_data)
+{
+       EmpathyTpGroup     *group = user_data;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GArray             *handles;
+       guint               i;
+       
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Failed to get local pendings: %s",
+                              error->message);
+               return;
+       }
+
+       handles = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
+       for (i = 0; array->len > i; i++) {
+               GValueArray        *pending_struct;
+               const gchar        *message;
+               guint               member_handle;
+               guint               actor_handle;
+               guint               reason;
+
+               pending_struct = g_ptr_array_index (array, i);
+               member_handle = g_value_get_uint (g_value_array_get_nth (pending_struct, 0));
+               actor_handle = g_value_get_uint (g_value_array_get_nth (pending_struct, 1));
+               reason = g_value_get_uint (g_value_array_get_nth (pending_struct, 2));
+               message = g_value_get_string (g_value_array_get_nth (pending_struct, 3));
+
+               g_array_insert_val (handles, 0, member_handle);
+               tp_group_members_changed_cb (priv->group_iface,
+                                            message,      /* message */
+                                            NULL,         /* added */
+                                            NULL,         /* removed */
+                                            handles,      /* local_pending */
+                                            NULL,         /* remote_pending */
+                                            actor_handle, /* actor */
+                                            reason,       /* reason */
+                                            group);
+       }
+       g_array_free (handles, TRUE);
+}
+
+static void
+tp_group_get_remote_pending_cb (DBusGProxy *proxy,
+                               GArray     *handles,
+                               GError     *error,
+                               gpointer    user_data)
+{
+       EmpathyTpGroup     *group = user_data;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "Failed to get remote pendings: %s",
+                              error->message);
+               return;
+       }
+
+       tp_group_members_changed_cb (priv->group_iface,
+                                    NULL,    /* message */
+                                    NULL,    /* added */
+                                    NULL,    /* removed */
+                                    NULL,    /* local_pending */
+                                    handles, /* remote_pending */
+                                    0,       /* actor */
+                                    0,       /* reason */
+                                    group);
+}
+
+static void
+tp_group_finalize (GObject *object)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (object);
+
+       tp_group_disconnect (EMPATHY_TP_GROUP (object));
+
+       if (priv->tp_chan) {
+               g_object_unref (priv->tp_chan);
+       }
+       if (priv->account) {
+               g_object_unref (priv->account);
+       }
+       if (priv->factory) {
+               g_object_unref (priv->factory);
+       }
+       g_free (priv->group_name);
+
+       g_list_foreach (priv->members, (GFunc) g_object_unref, NULL);
+       g_list_free (priv->members);
+
+       g_list_foreach (priv->local_pendings, (GFunc) empathy_pending_info_free, NULL);
+       g_list_free (priv->local_pendings);
+
+       g_list_foreach (priv->remote_pendings, (GFunc) g_object_unref, NULL);
+       g_list_free (priv->remote_pendings);
+
+       G_OBJECT_CLASS (empathy_tp_group_parent_class)->finalize (object);
+}
+
 static void
 empathy_tp_group_class_init (EmpathyTpGroupClass *klass)
 {
 static void
 empathy_tp_group_class_init (EmpathyTpGroupClass *klass)
 {
@@ -77,25 +480,25 @@ empathy_tp_group_class_init (EmpathyTpGroupClass *klass)
 
        object_class->finalize = tp_group_finalize;
 
 
        object_class->finalize = tp_group_finalize;
 
-       signals[MEMBERS_ADDED] =
-               g_signal_new ("members-added",
+       signals[MEMBER_ADDED] =
+               g_signal_new ("member-added",
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__POINTER_UINT_UINT_STRING,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING);
+                             4, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT, G_TYPE_UINT, G_TYPE_STRING);
 
 
-       signals[MEMBERS_REMOVED] =
-               g_signal_new ("members-removed",
+       signals[MEMBER_REMOVED] =
+               g_signal_new ("member-removed",
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__POINTER_UINT_UINT_STRING,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING);
+                             4, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT, G_TYPE_UINT, G_TYPE_STRING);
 
        signals[LOCAL_PENDING] =
                g_signal_new ("local-pending",
 
        signals[LOCAL_PENDING] =
                g_signal_new ("local-pending",
@@ -103,9 +506,9 @@ empathy_tp_group_class_init (EmpathyTpGroupClass *klass)
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__POINTER_UINT_UINT_STRING,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING);
+                             4, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT, G_TYPE_UINT, G_TYPE_STRING);
 
        signals[REMOTE_PENDING] =
                g_signal_new ("remote-pending",
 
        signals[REMOTE_PENDING] =
                g_signal_new ("remote-pending",
@@ -113,9 +516,19 @@ empathy_tp_group_class_init (EmpathyTpGroupClass *klass)
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
                              G_SIGNAL_RUN_LAST,
                              0,
                              NULL, NULL,
-                             empathy_marshal_VOID__POINTER_UINT_UINT_STRING,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
                              G_TYPE_NONE,
                              G_TYPE_NONE,
-                             4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING);
+                             4, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT, G_TYPE_UINT, G_TYPE_STRING);
+
+       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 (EmpathyTpGroupPriv));
 }
 
        g_type_class_add_private (object_class, sizeof (EmpathyTpGroupPriv));
 }
@@ -125,36 +538,6 @@ empathy_tp_group_init (EmpathyTpGroup *group)
 {
 }
 
 {
 }
 
-static void
-tp_group_finalize (GObject *object)
-{
-       EmpathyTpGroupPriv *priv;
-
-       priv = GET_PRIV (object);
-
-       if (priv->group_iface) {
-               g_signal_handlers_disconnect_by_func (priv->group_iface,
-                                                     tp_group_destroy_cb,
-                                                     object);
-               dbus_g_proxy_disconnect_signal (priv->group_iface, "MembersChanged",
-                                               G_CALLBACK (tp_group_members_changed_cb),
-                                               object);
-               g_object_unref (priv->group_iface);
-       }
-
-       if (priv->account) {
-               g_object_unref (priv->account);
-       }
-
-       if (priv->tp_chan) {
-               g_object_unref (priv->tp_chan);
-       }
-
-       g_free (priv->group_name);
-
-       G_OBJECT_CLASS (empathy_tp_group_parent_class)->finalize (object);
-}
-
 EmpathyTpGroup *
 empathy_tp_group_new (McAccount *account,
                      TpChan    *tp_chan)
 EmpathyTpGroup *
 empathy_tp_group_new (McAccount *account,
                      TpChan    *tp_chan)
@@ -162,6 +545,7 @@ empathy_tp_group_new (McAccount *account,
        EmpathyTpGroup     *group;
        EmpathyTpGroupPriv *priv;
        DBusGProxy         *group_iface;
        EmpathyTpGroup     *group;
        EmpathyTpGroupPriv *priv;
        DBusGProxy         *group_iface;
+       GError             *error;
 
        g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
        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 (MC_IS_ACCOUNT (account), NULL);
@@ -175,262 +559,205 @@ empathy_tp_group_new (McAccount *account,
 
        priv->account = g_object_ref (account);
        priv->tp_chan = g_object_ref (tp_chan);
 
        priv->account = g_object_ref (account);
        priv->tp_chan = g_object_ref (tp_chan);
-       priv->group_iface = g_object_ref (group_iface);
+       priv->group_iface = group_iface;
+       priv->factory = empathy_contact_factory_new ();
+
+       if (!tp_chan_iface_group_get_self_handle (priv->group_iface,
+                                                 &priv->self_handle,
+                                                 &error)) {
+               empathy_debug (DEBUG_DOMAIN, 
+                             "Failed to get self handle: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+       }
 
        dbus_g_proxy_connect_signal (priv->group_iface, "MembersChanged",
                                     G_CALLBACK (tp_group_members_changed_cb),
                                     group, NULL);
 
        dbus_g_proxy_connect_signal (priv->group_iface, "MembersChanged",
                                     G_CALLBACK (tp_group_members_changed_cb),
                                     group, NULL);
-       g_signal_connect (group_iface, "destroy",
+       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->tp_chan), "Closed",
+                                    G_CALLBACK (tp_group_closed_cb),
+                                    group, NULL);
+       g_signal_connect (priv->tp_chan, "destroy",
                          G_CALLBACK (tp_group_destroy_cb),
                          group);
 
                          G_CALLBACK (tp_group_destroy_cb),
                          group);
 
+       tp_chan_iface_group_get_members_async (priv->group_iface,
+                                              tp_group_get_members_cb,
+                                              group);
+       tp_chan_iface_group_get_local_pending_members_with_info_async (priv->group_iface,
+                                                                      tp_group_get_local_pending_cb,
+                                                                      group);
+       tp_chan_iface_group_get_remote_pending_members_async (priv->group_iface,
+                                                             tp_group_get_remote_pending_cb,
+                                                             group);
+
        return group;
 }
 
        return group;
 }
 
+static void
+tp_group_async_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
+{
+       const gchar *msg = user_data;
+
+       if (error) {
+               empathy_debug (DEBUG_DOMAIN, "%s: %s", msg, error->message);
+       }
+}
+
+void
+empathy_tp_group_close  (EmpathyTpGroup *group)
+{
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+
+       tp_chan_close_async (DBUS_G_PROXY (priv->tp_chan),
+                            tp_group_async_cb,
+                            "Failed to close");
+}
+
+static GArray *
+tp_group_get_handles (GList *contacts)
+{
+       GArray *handles;
+       guint   length;
+       GList  *l;
+
+       length = g_list_length (contacts);
+       handles = g_array_sized_new (FALSE, FALSE, sizeof (guint), length);
+
+       for (l = contacts; l; l = l->next) {
+               guint handle;
+
+               handle = empathy_contact_get_handle (l->data);
+               g_array_append_val (handles, handle);
+       }
+
+       return handles;
+}
+
 void
 empathy_tp_group_add_members (EmpathyTpGroup *group,
 void
 empathy_tp_group_add_members (EmpathyTpGroup *group,
-                             GArray         *handles,
+                             GList          *contacts,
                              const gchar    *message)
 {
                              const gchar    *message)
 {
-       EmpathyTpGroupPriv *priv;
-       GError             *error = NULL;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GArray             *handles;
 
        g_return_if_fail (EMPATHY_IS_TP_GROUP (group));
 
        g_return_if_fail (EMPATHY_IS_TP_GROUP (group));
-       g_return_if_fail (handles != NULL);
+       g_return_if_fail (contacts != NULL);
 
 
-       priv = GET_PRIV (group);
+       handles = tp_group_get_handles (contacts);
+       tp_chan_iface_group_add_members_async (priv->group_iface,
+                                              handles,
+                                              message,
+                                              tp_group_async_cb,
+                                              "Failed to add members");
 
 
-       if (!tp_chan_iface_group_add_members (priv->group_iface,
-                                             handles,
-                                             message,
-                                             &error)) {
-               empathy_debug (DEBUG_DOMAIN,
-                             "Failed to add members: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-       }
+       g_array_free (handles, TRUE);
 }
 
 void
 empathy_tp_group_add_member (EmpathyTpGroup *group,
 }
 
 void
 empathy_tp_group_add_member (EmpathyTpGroup *group,
-                            guint           handle,
+                            EmpathyContact *contact,
                             const gchar    *message)
 {
                             const gchar    *message)
 {
-       GArray *handles;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GArray             *handles;
+       guint               handle;
 
 
+       handle = empathy_contact_get_handle (contact);
        handles = g_array_new (FALSE, FALSE, sizeof (guint));
        g_array_append_val (handles, handle);
 
        handles = g_array_new (FALSE, FALSE, sizeof (guint));
        g_array_append_val (handles, handle);
 
-       empathy_tp_group_add_members (group, handles, message);
+       tp_chan_iface_group_add_members_async (priv->group_iface,
+                                              handles,
+                                              message,
+                                              tp_group_async_cb,
+                                              "Failed to add member");
 
        g_array_free (handles, TRUE);
 }
 
 void
 empathy_tp_group_remove_members (EmpathyTpGroup *group,
 
        g_array_free (handles, TRUE);
 }
 
 void
 empathy_tp_group_remove_members (EmpathyTpGroup *group,
-                                GArray         *handles,
+                                GList          *contacts,
                                 const gchar    *message)
 {
                                 const gchar    *message)
 {
-       EmpathyTpGroupPriv *priv;
-       GError             *error = NULL;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GArray             *handles;
 
        g_return_if_fail (EMPATHY_IS_TP_GROUP (group));
 
        g_return_if_fail (EMPATHY_IS_TP_GROUP (group));
+       g_return_if_fail (contacts != NULL);
 
 
-       priv = GET_PRIV (group);
+       handles = tp_group_get_handles (contacts);
+       tp_chan_iface_group_remove_members_async (priv->group_iface,
+                                                 handles,
+                                                 message,
+                                                 tp_group_async_cb,
+                                                 "Failed to remove members");
 
 
-       if (!tp_chan_iface_group_remove_members (priv->group_iface,
-                                                handles,
-                                                message,
-                                                &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "Failed to remove members: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-       }
+       g_array_free (handles, TRUE);
 }
 
 void
 empathy_tp_group_remove_member (EmpathyTpGroup *group,
 }
 
 void
 empathy_tp_group_remove_member (EmpathyTpGroup *group,
-                               guint           handle,
+                               EmpathyContact *contact,
                                const gchar    *message)
 {
                                const gchar    *message)
 {
-       GArray *handles;
-
-       g_return_if_fail (EMPATHY_IS_TP_GROUP (group));
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GArray             *handles;
+       guint               handle;
 
 
+       handle = empathy_contact_get_handle (contact);
        handles = g_array_new (FALSE, FALSE, sizeof (guint));
        g_array_append_val (handles, handle);
 
        handles = g_array_new (FALSE, FALSE, sizeof (guint));
        g_array_append_val (handles, handle);
 
-       empathy_tp_group_remove_members (group, handles, message);
+       tp_chan_iface_group_remove_members_async (priv->group_iface,
+                                                 handles,
+                                                 message,
+                                                 tp_group_async_cb,
+                                                 "Failed to remove member");
 
        g_array_free (handles, TRUE);
 }
 
 
        g_array_free (handles, TRUE);
 }
 
-GArray *
+GList *
 empathy_tp_group_get_members (EmpathyTpGroup *group)
 {
 empathy_tp_group_get_members (EmpathyTpGroup *group)
 {
-       EmpathyTpGroupPriv *priv;
-       GArray             *members;
-       GError             *error = NULL;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
 
 
-       g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL);
+       g_list_foreach (priv->members, (GFunc) g_object_ref, NULL);
 
 
-       priv = GET_PRIV (group);
-
-       if (!tp_chan_iface_group_get_members (priv->group_iface,
-                                             &members,
-                                             &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "Couldn't get members: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               return NULL;
-       }
-
-       return members;
-}
-
-void
-empathy_tp_group_get_all_members (EmpathyTpGroup  *group,
-                                 GArray         **members,
-                                 GArray         **local_pending,
-                                 GArray         **remote_pending)
-{
-       EmpathyTpGroupPriv *priv;
-       GError             *error = NULL;
-
-       g_return_if_fail (EMPATHY_IS_TP_GROUP (group));
-
-       priv = GET_PRIV (group);
-
-       if (!tp_chan_iface_group_get_all_members (priv->group_iface,
-                                                 members,
-                                                 local_pending,
-                                                 remote_pending,
-                                                 &error)) {
-               empathy_debug (DEBUG_DOMAIN,
-                             "Couldn't get all members: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-       }
+       return g_list_copy (priv->members);
 }
 
 GList *
 }
 
 GList *
-empathy_tp_group_get_local_pending_members_with_info (EmpathyTpGroup *group)
-{
-       EmpathyTpGroupPriv *priv;
-       GPtrArray          *array;
-       guint               i;
-       GList              *infos = NULL;
-       GError             *error = NULL;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL);
-
-       priv = GET_PRIV (group);
-
-       if (!tp_chan_iface_group_get_local_pending_members_with_info (priv->group_iface,
-                                                                     &array,
-                                                                     &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "GetLocalPendingMembersWithInfo failed: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-
-               return NULL;
-       }
-
-       if (!array) {
-               /* This happens with butterfly because
-                * GetLocalPendingMembersWithInfo is not 
-                * implemented */
-               return NULL;
-       }
-
-       for (i = 0; array->len > i; i++) {
-               GValueArray        *pending_struct;
-               EmpathyTpGroupInfo *info;
-               const gchar        *message;
-
-               info = g_slice_new (EmpathyTpGroupInfo);
-
-               pending_struct = g_ptr_array_index (array, i);
-               info->member = g_value_get_uint (g_value_array_get_nth (pending_struct, 0));
-               info->actor = g_value_get_uint (g_value_array_get_nth (pending_struct, 1));
-               info->reason = g_value_get_uint (g_value_array_get_nth (pending_struct, 2));
-               message = g_value_get_string (g_value_array_get_nth (pending_struct, 3));
-               info->message = g_strdup (message);
-               g_value_array_free (pending_struct);
-
-               infos = g_list_prepend (infos, info);
-       }
-       g_ptr_array_free (array, TRUE);
-
-       return infos;
-}
-
-void
-empathy_tp_group_info_list_free (GList *infos)
+empathy_tp_group_get_local_pendings (EmpathyTpGroup *group)
 {
 {
-       GList *l;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+       GList              *pendings = NULL, *l;
 
 
-       for (l = infos; l; l = l->next) {
-               EmpathyTpGroupInfo *info;
+       for (l = priv->local_pendings; l; l = l->next) {
+               EmpathyPendingInfo *info;
+               EmpathyPendingInfo *new_info;
 
                info = l->data;
 
                info = l->data;
-
-               g_free (info->message);
-               g_slice_free (EmpathyTpGroupInfo, info);
+               new_info = empathy_pending_info_new (info->member,
+                                                    info->actor,
+                                                    info->message);
+               pendings = g_list_prepend (pendings, new_info);
        }
        }
-       g_list_free (infos);
-}
 
 
-
-static void
-tp_group_destroy_cb (DBusGProxy     *proxy,
-                    EmpathyTpGroup *group)
-{
-       EmpathyTpGroupPriv *priv;
-
-       priv = GET_PRIV (group);
-
-       g_object_unref (priv->group_iface);
-       g_object_unref (priv->tp_chan);
-       priv->group_iface = NULL;
-       priv->tp_chan = NULL;
+       return pendings;
 }
 
 }
 
-static void
-tp_group_members_changed_cb (DBusGProxy     *group_iface,
-                            gchar          *message,
-                            GArray         *added,
-                            GArray         *removed,
-                            GArray         *local_pending,
-                            GArray         *remote_pending,
-                            guint           actor,
-                            guint           reason,
-                            EmpathyTpGroup *group)
+GList *
+empathy_tp_group_get_remote_pendings (EmpathyTpGroup *group)
 {
 {
-       EmpathyTpGroupPriv *priv;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
 
 
-       priv = GET_PRIV (group);
+       g_list_foreach (priv->remote_pendings, (GFunc) g_object_ref, NULL);
 
 
-       /* emit signals */
-       if (added->len > 0) {
-               g_signal_emit (group, signals[MEMBERS_ADDED], 0, 
-                              added, actor, reason, message);
-       }
-       if (removed->len > 0) {
-               g_signal_emit (group, signals[MEMBERS_REMOVED], 0, 
-                              removed, actor, reason, message);
-       }
-       if (local_pending->len > 0) {
-               g_signal_emit (group, signals[LOCAL_PENDING], 0,
-                              local_pending, actor, reason, message);
-       }
-       if (remote_pending->len > 0) {
-               g_signal_emit (group, signals[REMOTE_PENDING], 0,
-                              remote_pending, actor, reason, message);
-       }
+       return g_list_copy (priv->remote_pendings);
 }
 
 const gchar *
 }
 
 const gchar *
@@ -443,35 +770,21 @@ empathy_tp_group_get_name (EmpathyTpGroup *group)
        priv = GET_PRIV (group);
 
        /* Lazy initialisation */
        priv = GET_PRIV (group);
 
        /* Lazy initialisation */
-       if (priv->group_name) {
-               return priv->group_name;
+       if (!priv->group_name) {
+               priv->group_name = empathy_inspect_channel (priv->account, priv->tp_chan);
        }
 
        }
 
-       priv->group_name = empathy_inspect_channel (priv->account, priv->tp_chan);
-
        return priv->group_name;
 }
 
        return priv->group_name;
 }
 
-guint 
-empathy_tp_group_get_self_handle (EmpathyTpGroup *group)
+EmpathyContact *
+empathy_tp_group_get_self_contact (EmpathyTpGroup *group)
 {
 {
-       EmpathyTpGroupPriv *priv;
-       guint               handle;
-       GError             *error = NULL;
-
-       g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), 0 );
-
-       priv = GET_PRIV (group);
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
 
 
-       if (!tp_chan_iface_group_get_self_handle (priv->group_iface, &handle, &error)) {
-               empathy_debug (DEBUG_DOMAIN, 
-                             "Failed to get self handle: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-               return 0;
-       }
+       g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL);
 
 
-       return handle;
+       return tp_group_get_contact (group, priv->self_handle);
 }
 
 const gchar *
 }
 
 const gchar *
@@ -488,21 +801,10 @@ empathy_tp_group_get_object_path (EmpathyTpGroup *group)
 
 gboolean
 empathy_tp_group_is_member (EmpathyTpGroup *group,
 
 gboolean
 empathy_tp_group_is_member (EmpathyTpGroup *group,
-                           guint           handle)
+                           EmpathyContact *contact)
 {
 {
-       GArray   *members;
-       guint     i;
-       gboolean  found = FALSE;
-
-       members = empathy_tp_group_get_members (group);
-       for (i = 0; i < members->len; i++) {
-               if (g_array_index (members, guint, i) == handle) {
-                       found = TRUE;
-                       break;
-               }
-       }
-       g_array_free (members, TRUE);
-       
-       return found;
+       EmpathyTpGroupPriv *priv = GET_PRIV (group);
+
+       return g_list_find (priv->members, contact) != NULL;
 }
 
 }
 
index 5ea7bfc710f092ba1daf2fa89eef0c93f995c621..14cbd4649992b6b5d51908278cbc76a27bb645de 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2006 Xavier Claessens <xclaesse@gmail.com>
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2006 Xavier Claessens <xclaesse@gmail.com>
+ * 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
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,6 +17,8 @@
  * License along with this program; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  * 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_GROUP_H__
  */
 
 #ifndef __EMPATHY_TP_GROUP_H__
 #include <glib.h>
 
 #include <libtelepathy/tp-chan.h>
 #include <glib.h>
 
 #include <libtelepathy/tp-chan.h>
+#include <libtelepathy/tp-constants.h>
 #include <libmissioncontrol/mc-account.h>
 
 #include <libmissioncontrol/mc-account.h>
 
+#include "empathy-contact.h"
+
 G_BEGIN_DECLS
 
 #define EMPATHY_TYPE_TP_GROUP         (empathy_tp_group_get_type ())
 G_BEGIN_DECLS
 
 #define EMPATHY_TYPE_TP_GROUP         (empathy_tp_group_get_type ())
@@ -48,39 +54,40 @@ struct _EmpathyTpGroupClass {
 };
 
 typedef struct {
 };
 
 typedef struct {
-       guint  member;
-       guint  actor;
-       guint  reason;
-       gchar *message;
-} EmpathyTpGroupInfo;
+       EmpathyContact *member;
+       EmpathyContact *actor;
+       gchar          *message;
+       guint           reason;
+} EmpathyPendingInfo;
 
 
-GType            empathy_tp_group_get_type                            (void) G_GNUC_CONST;
-EmpathyTpGroup * empathy_tp_group_new                                 (McAccount       *account,
-                                                                      TpChan          *tp_chan);
-void             empathy_tp_group_add_members                         (EmpathyTpGroup  *group,
-                                                                      GArray          *handles,
-                                                                      const gchar     *message);
-void             empathy_tp_group_add_member                          (EmpathyTpGroup  *group,
-                                                                      guint            handle,
-                                                                      const gchar     *message);
-void             empathy_tp_group_remove_members                      (EmpathyTpGroup  *group,
-                                                                      GArray          *handle,
-                                                                      const gchar     *message);
-void             empathy_tp_group_remove_member                       (EmpathyTpGroup  *group,
-                                                                      guint            handle,
-                                                                      const gchar     *message);
-GArray *         empathy_tp_group_get_members                         (EmpathyTpGroup  *group);
-void             empathy_tp_group_get_all_members                     (EmpathyTpGroup  *group,
-                                                                      GArray         **members,
-                                                                      GArray         **local_pending,
-                                                                      GArray         **remote_pending);
-GList *          empathy_tp_group_get_local_pending_members_with_info (EmpathyTpGroup  *group);
-void             empathy_tp_group_info_list_free                      (GList           *infos);
-const gchar *    empathy_tp_group_get_name                            (EmpathyTpGroup  *group);
-guint            empathy_tp_group_get_self_handle                     (EmpathyTpGroup  *group);
-const gchar *    empathy_tp_group_get_object_path                     (EmpathyTpGroup  *group);
-gboolean         empathy_tp_group_is_member                           (EmpathyTpGroup  *group,
-                                                                      guint            handle);
+GType               empathy_tp_group_get_type            (void) G_GNUC_CONST;
+EmpathyTpGroup *    empathy_tp_group_new                 (McAccount          *account,
+                                                         TpChan             *tp_chan);
+void                empathy_tp_group_close               (EmpathyTpGroup     *group);
+void                empathy_tp_group_add_members         (EmpathyTpGroup     *group,
+                                                         GList              *contacts,
+                                                         const gchar        *message);
+void                empathy_tp_group_add_member          (EmpathyTpGroup     *group,
+                                                         EmpathyContact     *contact,
+                                                         const gchar        *message);
+void                empathy_tp_group_remove_members      (EmpathyTpGroup     *group,
+                                                         GList              *contacts,
+                                                         const gchar        *message);
+void                empathy_tp_group_remove_member       (EmpathyTpGroup     *group,
+                                                         EmpathyContact     *contact,
+                                                         const gchar        *message);
+GList *             empathy_tp_group_get_members         (EmpathyTpGroup     *group);
+GList *             empathy_tp_group_get_local_pendings  (EmpathyTpGroup     *group);
+GList *             empathy_tp_group_get_remote_pendings (EmpathyTpGroup     *group);
+const gchar *       empathy_tp_group_get_name            (EmpathyTpGroup     *group);
+EmpathyContact *    empathy_tp_group_get_self_contact    (EmpathyTpGroup     *group);
+const gchar *       empathy_tp_group_get_object_path     (EmpathyTpGroup     *group);
+gboolean            empathy_tp_group_is_member           (EmpathyTpGroup     *group,
+                                                         EmpathyContact     *contact);
+EmpathyPendingInfo *empathy_pending_info_new             (EmpathyContact     *member,
+                                                         EmpathyContact     *actor,
+                                                         const gchar        *message);
+void                empathy_pending_info_free            (EmpathyPendingInfo *info);
 
 G_END_DECLS
 
 
 G_END_DECLS
 
diff --git a/python/README b/python/README
new file mode 100644 (file)
index 0000000..f9c121b
--- /dev/null
@@ -0,0 +1,19 @@
+To update python binding:
+1)
+  $ make distclean
+  $ python /usr/share/pygtk/2.0/codegen/h2def.py libempathy/*.h > python/pyempathy/pyempathy.defs
+  $ python /usr/share/pygtk/2.0/codegen/h2def.py libempathy-gtk/*.h > python/pyempathygtk/pyempathygtk.defs
+
+2)
+Manually modify pyempathy.defs, ContactList is not an object but an interface:
+(define-interface ContactList
+  (in-module "Empathy")
+  (c-name "EmpathyContactList")
+  (gtype-id "EMPATHY_TYPE_CONTACT_LIST")
+)
+
+ContactManager, TpChatroom and TpContactList implements ContactList interface:
+  (implements "EmpathyContactList")
+
+3)
+Manually update headers in pyempathy.override and pyempathygtk.override.
index eea0b76d3b37731734474429b18a0304d559b465..97f7b6ac9bd39b337ae2bb253bfc1a892758d62e 100644 (file)
   (gtype-id "EMPATHY_TYPE_CONTACT")
 )
 
   (gtype-id "EMPATHY_TYPE_CONTACT")
 )
 
+(define-object ContactFactory
+  (in-module "Empathy")
+  (parent "GObject")
+  (c-name "EmpathyContactFactory")
+  (gtype-id "EMPATHY_TYPE_CONTACT_FACTORY")
+)
+
 (define-object ContactManager
   (in-module "Empathy")
   (parent "GObject")
 (define-object ContactManager
   (in-module "Empathy")
   (parent "GObject")
   (gtype-id "EMPATHY_TYPE_TP_GROUP")
 )
 
   (gtype-id "EMPATHY_TYPE_TP_GROUP")
 )
 
-;; Enumerations and flags ...
-
-(define-flags Subscription
+(define-object TpRoomlist
   (in-module "Empathy")
   (in-module "Empathy")
-  (c-name "EmpathySubscription")
-  (gtype-id "EMPATHY_TYPE_SUBSCRIPTION")
-  (values
-    '("none" "EMPATHY_SUBSCRIPTION_NONE")
-    '("to" "EMPATHY_SUBSCRIPTION_TO")
-    '("from" "EMPATHY_SUBSCRIPTION_FROM")
-    '("both" "EMPATHY_SUBSCRIPTION_BOTH")
-  )
+  (parent "GObject")
+  (c-name "EmpathyTpRoomlist")
+  (gtype-id "EMPATHY_TYPE_TP_ROOMLIST")
 )
 
 )
 
+;; Enumerations and flags ...
+
 (define-enum MessageType
   (in-module "Empathy")
   (c-name "EmpathyMessageType")
 (define-enum MessageType
   (in-module "Empathy")
   (c-name "EmpathyMessageType")
 
 ;; From empathy-avatar.h
 
 
 ;; From empathy-avatar.h
 
-(define-function empathy_avatar_get_gtype
-  (c-name "empathy_avatar_get_gtype")
+(define-function empathy_avatar_get_type
+  (c-name "empathy_avatar_get_type")
   (return-type "GType")
 )
 
   (return-type "GType")
 )
 
 
 
 
 
 
 
-;; From empathy-chandler-glue.h
-
-(define-function dbus_glib_marshal_empathy_chandler_BOOLEAN__STRING_BOXED_STRING_BOXED_UINT_UINT_POINTER
-  (c-name "dbus_glib_marshal_empathy_chandler_BOOLEAN__STRING_BOXED_STRING_BOXED_UINT_UINT_POINTER")
-  (return-type "none")
-  (parameters
-    '("GClosure*" "closure")
-    '("GValue*" "return_value")
-    '("guint" "n_param_values")
-    '("const-GValue*" "param_values")
-    '("gpointer" "invocation_hint")
-    '("gpointer" "marshal_data")
-  )
-)
-
-
-
 ;; From empathy-chandler.h
 
 (define-function empathy_chandler_get_type
 ;; From empathy-chandler.h
 
 (define-function empathy_chandler_get_type
 
 
 
 
 
 
-;; From empathy-chatroom-manager.h
-
-(define-function empathy_chatroom_manager_get_type
-  (c-name "empathy_chatroom_manager_get_type")
-  (return-type "GType")
-)
-
-(define-function empathy_chatroom_manager_new
-  (c-name "empathy_chatroom_manager_new")
-  (is-constructor-of "EmpathyChatroomManager")
-  (return-type "EmpathyChatroomManager*")
-)
-
-(define-method add
-  (of-object "EmpathyChatroomManager")
-  (c-name "empathy_chatroom_manager_add")
-  (return-type "gboolean")
-  (parameters
-    '("EmpathyChatroom*" "chatroom")
-  )
-)
-
-(define-method remove
-  (of-object "EmpathyChatroomManager")
-  (c-name "empathy_chatroom_manager_remove")
-  (return-type "none")
-  (parameters
-    '("EmpathyChatroom*" "chatroom")
-  )
-)
-
-(define-method find
-  (of-object "EmpathyChatroomManager")
-  (c-name "empathy_chatroom_manager_find")
-  (return-type "EmpathyChatroom*")
-  (parameters
-    '("McAccount*" "account")
-    '("const-gchar*" "room")
-  )
-)
-
-(define-method get_chatrooms
-  (of-object "EmpathyChatroomManager")
-  (c-name "empathy_chatroom_manager_get_chatrooms")
-  (return-type "GList*")
-  (parameters
-    '("McAccount*" "account")
-  )
-)
-
-(define-method get_count
-  (of-object "EmpathyChatroomManager")
-  (c-name "empathy_chatroom_manager_get_count")
-  (return-type "guint")
-  (parameters
-    '("McAccount*" "account")
-  )
-)
-
-(define-method store
-  (of-object "EmpathyChatroomManager")
-  (c-name "empathy_chatroom_manager_store")
-  (return-type "none")
-)
-
-
-
 ;; From empathy-chatroom.h
 
 (define-function empathy_chatroom_get_type
 ;; From empathy-chatroom.h
 
 (define-function empathy_chatroom_get_type
 
 
 
 
 
 
+;; From empathy-chatroom-manager.h
+
+(define-function empathy_chatroom_manager_get_type
+  (c-name "empathy_chatroom_manager_get_type")
+  (return-type "GType")
+)
+
+(define-function empathy_chatroom_manager_new
+  (c-name "empathy_chatroom_manager_new")
+  (is-constructor-of "EmpathyChatroomManager")
+  (return-type "EmpathyChatroomManager*")
+)
+
+(define-method add
+  (of-object "EmpathyChatroomManager")
+  (c-name "empathy_chatroom_manager_add")
+  (return-type "gboolean")
+  (parameters
+    '("EmpathyChatroom*" "chatroom")
+  )
+)
+
+(define-method remove
+  (of-object "EmpathyChatroomManager")
+  (c-name "empathy_chatroom_manager_remove")
+  (return-type "none")
+  (parameters
+    '("EmpathyChatroom*" "chatroom")
+  )
+)
+
+(define-method find
+  (of-object "EmpathyChatroomManager")
+  (c-name "empathy_chatroom_manager_find")
+  (return-type "EmpathyChatroom*")
+  (parameters
+    '("McAccount*" "account")
+    '("const-gchar*" "room")
+  )
+)
+
+(define-method get_chatrooms
+  (of-object "EmpathyChatroomManager")
+  (c-name "empathy_chatroom_manager_get_chatrooms")
+  (return-type "GList*")
+  (parameters
+    '("McAccount*" "account")
+  )
+)
+
+(define-method get_count
+  (of-object "EmpathyChatroomManager")
+  (c-name "empathy_chatroom_manager_get_count")
+  (return-type "guint")
+  (parameters
+    '("McAccount*" "account")
+  )
+)
+
+(define-method store
+  (of-object "EmpathyChatroomManager")
+  (c-name "empathy_chatroom_manager_store")
+  (return-type "none")
+)
+
+
+
 ;; From empathy-conf.h
 
 (define-function empathy_conf_get_type
 ;; From empathy-conf.h
 
 (define-function empathy_conf_get_type
 
 
 
 
 
 
-;; From empathy-contact-list.h
+;; From empathy-contact-factory.h
 
 
-(define-function contact_list_get_type
-  (c-name "empathy_contact_list_get_type")
+(define-function empathy_contact_factory_get_type
+  (c-name "empathy_contact_factory_get_type")
   (return-type "GType")
 )
 
   (return-type "GType")
 )
 
-(define-method list_info_new
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_list_info_new")
-  (return-type "EmpathyContactListInfo*")
-  (parameters
-    '("const-gchar*" "message")
-  )
-)
-
-(define-method free
-  (of-object "EmpathyContactListInfo")
-  (c-name "empathy_contact_list_info_free")
-  (return-type "none")
-)
-
-(define-method setup
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_setup")
-  (return-type "none")
+(define-function empathy_contact_factory_new
+  (c-name "empathy_contact_factory_new")
+  (is-constructor-of "EmpathyContactFactory")
+  (return-type "EmpathyContactFactory*")
 )
 
 )
 
-(define-method find
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_find")
+(define-method get_user
+  (of-object "EmpathyContactFactory")
+  (c-name "empathy_contact_factory_get_user")
   (return-type "EmpathyContact*")
   (parameters
   (return-type "EmpathyContact*")
   (parameters
-    '("const-gchar*" "id")
-  )
-)
-
-(define-method add
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_add")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-    '("const-gchar*" "message")
-  )
-)
-
-(define-method remove
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_remove")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-    '("const-gchar*" "message")
-  )
-)
-
-(define-method get_members
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_get_members")
-  (return-type "GList*")
-)
-
-(define-method get_local_pending
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_get_local_pending")
-  (return-type "GList*")
-)
-
-(define-method process_pending
-  (of-object "EmpathyContactList")
-  (c-name "empathy_contact_list_process_pending")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-    '("gboolean" "accept")
+    '("McAccount*" "account")
   )
 )
 
   )
 )
 
-(define-virtual setup
-  (of-object "EmpathyContactList")
-  (return-type "none")
-)
-
-(define-virtual find
-  (of-object "EmpathyContactList")
+(define-method get_from_id
+  (of-object "EmpathyContactFactory")
+  (c-name "empathy_contact_factory_get_from_id")
   (return-type "EmpathyContact*")
   (return-type "EmpathyContact*")
-  (parameters
-    '("const-gchar*" "id")
-  )
-)
-
-(define-virtual add
-  (of-object "EmpathyContactList")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-    '("const-gchar*" "message")
-  )
-)
-
-(define-virtual remove
-  (of-object "EmpathyContactList")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-    '("const-gchar*" "message")
-  )
-)
-
-(define-virtual get_members
-  (of-object "EmpathyContactList")
-  (return-type "GList*")
-)
-
-(define-virtual get_local_pending
-  (of-object "EmpathyContactList")
-  (return-type "GList*")
-)
-
-(define-virtual process_pending
-  (of-object "EmpathyContactList")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-    '("gboolean" "accept")
-  )
-)
-
-;; From empathy-contact-manager.h
-
-(define-function empathy_contact_manager_get_type
-  (c-name "empathy_contact_manager_get_type")
-  (return-type "GType")
-)
-
-(define-function empathy_contact_manager_new
-  (c-name "empathy_contact_manager_new")
-  (is-constructor-of "EmpathyContactManager")
-  (return-type "EmpathyContactManager*")
-)
-
-(define-method get_list
-  (of-object "EmpathyContactManager")
-  (c-name "empathy_contact_manager_get_list")
-  (return-type "EmpathyTpContactList*")
   (parameters
     '("McAccount*" "account")
   (parameters
     '("McAccount*" "account")
+    '("const-gchar*" "id")
   )
 )
 
   )
 )
 
-(define-method get_user
-  (of-object "EmpathyContactManager")
-  (c-name "empathy_contact_manager_get_user")
+(define-method get_from_handle
+  (of-object "EmpathyContactFactory")
+  (c-name "empathy_contact_factory_get_from_handle")
   (return-type "EmpathyContact*")
   (parameters
     '("McAccount*" "account")
   (return-type "EmpathyContact*")
   (parameters
     '("McAccount*" "account")
+    '("guint" "handle")
   )
 )
 
   )
 )
 
-(define-method create
-  (of-object "EmpathyContactManager")
-  (c-name "empathy_contact_manager_create")
-  (return-type "EmpathyContact*")
+(define-method get_from_handles
+  (of-object "EmpathyContactFactory")
+  (c-name "empathy_contact_factory_get_from_handles")
+  (return-type "GList*")
   (parameters
     '("McAccount*" "account")
   (parameters
     '("McAccount*" "account")
-    '("const-gchar*" "id")
+    '("GArray*" "handles")
   )
 )
 
   )
 )
 
-(define-method rename_group
-  (of-object "EmpathyContactManager")
-  (c-name "empathy_contact_manager_rename_group")
+(define-method set_name
+  (of-object "EmpathyContactFactory")
+  (c-name "empathy_contact_factory_set_name")
   (return-type "none")
   (parameters
   (return-type "none")
   (parameters
-    '("const-gchar*" "old_group")
-    '("const-gchar*" "new_group")
+    '("EmpathyContact*" "contact")
+    '("const-gchar*" "name")
   )
 )
 
   )
 )
 
-(define-method get_groups
-  (of-object "EmpathyContactManager")
-  (c-name "empathy_contact_manager_get_groups")
-  (return-type "GList*")
-)
-
 
 
 ;; From empathy-contact.h
 
 
 
 ;; From empathy-contact.h
 
-(define-function empathy_contact_get_gtype
-  (c-name "empathy_contact_get_gtype")
+(define-function empathy_contact_get_type
+  (c-name "empathy_contact_get_type")
   (return-type "GType")
 )
 
   (return-type "GType")
 )
 
   (return-type "const-gchar*")
 )
 
   (return-type "const-gchar*")
 )
 
+(define-method set_id
+  (of-object "EmpathyContact")
+  (c-name "empathy_contact_set_id")
+  (return-type "none")
+  (parameters
+    '("const-gchar*" "id")
+  )
+)
+
 (define-method get_name
   (of-object "EmpathyContact")
   (c-name "empathy_contact_get_name")
   (return-type "const-gchar*")
 )
 
 (define-method get_name
   (of-object "EmpathyContact")
   (c-name "empathy_contact_get_name")
   (return-type "const-gchar*")
 )
 
+(define-method set_name
+  (of-object "EmpathyContact")
+  (c-name "empathy_contact_set_name")
+  (return-type "none")
+  (parameters
+    '("const-gchar*" "name")
+  )
+)
+
 (define-method get_avatar
   (of-object "EmpathyContact")
   (c-name "empathy_contact_get_avatar")
   (return-type "EmpathyAvatar*")
 )
 
 (define-method get_avatar
   (of-object "EmpathyContact")
   (c-name "empathy_contact_get_avatar")
   (return-type "EmpathyAvatar*")
 )
 
+(define-method set_avatar
+  (of-object "EmpathyContact")
+  (c-name "empathy_contact_set_avatar")
+  (return-type "none")
+  (parameters
+    '("EmpathyAvatar*" "avatar")
+  )
+)
+
 (define-method get_account
   (of-object "EmpathyContact")
   (c-name "empathy_contact_get_account")
   (return-type "McAccount*")
 )
 
 (define-method get_account
   (of-object "EmpathyContact")
   (c-name "empathy_contact_get_account")
   (return-type "McAccount*")
 )
 
-(define-method get_presence
+(define-method set_account
   (of-object "EmpathyContact")
   (of-object "EmpathyContact")
-  (c-name "empathy_contact_get_presence")
-  (return-type "EmpathyPresence*")
+  (c-name "empathy_contact_set_account")
+  (return-type "none")
+  (parameters
+    '("McAccount*" "account")
+  )
 )
 
 )
 
-(define-method get_groups
+(define-method get_presence
   (of-object "EmpathyContact")
   (of-object "EmpathyContact")
-  (c-name "empathy_contact_get_groups")
-  (return-type "GList*")
+  (c-name "empathy_contact_get_presence")
+  (return-type "EmpathyPresence*")
 )
 
 )
 
-(define-method get_subscription
+(define-method set_presence
   (of-object "EmpathyContact")
   (of-object "EmpathyContact")
-  (c-name "empathy_contact_get_subscription")
-  (return-type "EmpathySubscription")
+  (c-name "empathy_contact_set_presence")
+  (return-type "none")
+  (parameters
+    '("EmpathyPresence*" "presence")
+  )
 )
 
 (define-method get_handle
 )
 
 (define-method get_handle
   (return-type "guint")
 )
 
   (return-type "guint")
 )
 
+(define-method set_handle
+  (of-object "EmpathyContact")
+  (c-name "empathy_contact_set_handle")
+  (return-type "none")
+  (parameters
+    '("guint" "handle")
+  )
+)
+
 (define-method is_user
   (of-object "EmpathyContact")
   (c-name "empathy_contact_is_user")
   (return-type "gboolean")
 )
 
 (define-method is_user
   (of-object "EmpathyContact")
   (c-name "empathy_contact_is_user")
   (return-type "gboolean")
 )
 
-(define-method set_id
+(define-method set_is_user
   (of-object "EmpathyContact")
   (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_id")
+  (c-name "empathy_contact_set_is_user")
   (return-type "none")
   (parameters
   (return-type "none")
   (parameters
-    '("const-gchar*" "id")
+    '("gboolean" "is_user")
   )
 )
 
   )
 )
 
-(define-method set_name
+(define-method is_online
   (of-object "EmpathyContact")
   (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_name")
-  (return-type "none")
+  (c-name "empathy_contact_is_online")
+  (return-type "gboolean")
+)
+
+(define-method get_status
+  (of-object "EmpathyContact")
+  (c-name "empathy_contact_get_status")
+  (return-type "const-gchar*")
+)
+
+(define-function empathy_contact_equal
+  (c-name "empathy_contact_equal")
+  (return-type "gboolean")
   (parameters
   (parameters
-    '("const-gchar*" "name")
+    '("gconstpointer" "v1")
+    '("gconstpointer" "v2")
   )
 )
 
   )
 )
 
-(define-method set_avatar
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_avatar")
-  (return-type "none")
+(define-function empathy_contact_hash
+  (c-name "empathy_contact_hash")
+  (return-type "guint")
   (parameters
   (parameters
-    '("EmpathyAvatar*" "avatar")
+    '("gconstpointer" "key")
   )
 )
 
   )
 )
 
-(define-method set_account
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_account")
-  (return-type "none")
-  (parameters
-    '("McAccount*" "account")
-  )
+
+
+;; From empathy-contact-list.h
+
+(define-function empathy_contact_list_get_type
+  (c-name "empathy_contact_list_get_type")
+  (return-type "GType")
 )
 
 )
 
-(define-method set_presence
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_presence")
+(define-method add
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_add")
   (return-type "none")
   (parameters
   (return-type "none")
   (parameters
-    '("EmpathyPresence*" "presence")
+    '("EmpathyContact*" "contact")
+    '("const-gchar*" "message")
   )
 )
 
   )
 )
 
-(define-method set_groups
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_groups")
+(define-method remove
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_remove")
   (return-type "none")
   (parameters
   (return-type "none")
   (parameters
-    '("GList*" "categories")
+    '("EmpathyContact*" "contact")
+    '("const-gchar*" "message")
   )
 )
 
   )
 )
 
-(define-method set_subscription
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_subscription")
-  (return-type "none")
-  (parameters
-    '("EmpathySubscription" "subscription")
-  )
+(define-method get_members
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_get_members")
+  (return-type "GList*")
 )
 
 )
 
-(define-method set_handle
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_handle")
-  (return-type "none")
-  (parameters
-    '("guint" "handle")
-  )
+(define-method get_pendings
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_get_pendings")
+  (return-type "GList*")
 )
 
 )
 
-(define-method set_is_user
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_set_is_user")
-  (return-type "none")
+(define-method get_all_groups
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_get_all_groups")
+  (return-type "GList*")
+)
+
+(define-method get_groups
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_get_groups")
+  (return-type "GList*")
   (parameters
   (parameters
-    '("gboolean" "is_user")
+    '("EmpathyContact*" "contact")
   )
 )
 
   )
 )
 
-(define-method add_group
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_add_group")
+(define-method add_to_group
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_add_to_group")
   (return-type "none")
   (parameters
   (return-type "none")
   (parameters
+    '("EmpathyContact*" "contact")
     '("const-gchar*" "group")
   )
 )
 
     '("const-gchar*" "group")
   )
 )
 
-(define-method remove_group
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_remove_group")
+(define-method remove_from_group
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_remove_from_group")
   (return-type "none")
   (parameters
   (return-type "none")
   (parameters
+    '("EmpathyContact*" "contact")
     '("const-gchar*" "group")
   )
 )
 
     '("const-gchar*" "group")
   )
 )
 
-(define-method is_online
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_is_online")
-  (return-type "gboolean")
-)
-
-(define-method is_in_group
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_is_in_group")
-  (return-type "gboolean")
+(define-method rename_group
+  (of-object "EmpathyContactList")
+  (c-name "empathy_contact_list_rename_group")
+  (return-type "none")
   (parameters
   (parameters
-    '("const-gchar*" "group")
+    '("const-gchar*" "old_group")
+    '("const-gchar*" "new_group")
   )
 )
 
   )
 )
 
-(define-method get_status
-  (of-object "EmpathyContact")
-  (c-name "empathy_contact_get_status")
-  (return-type "const-gchar*")
+
+
+;; From empathy-contact-manager.h
+
+(define-function empathy_contact_manager_get_type
+  (c-name "empathy_contact_manager_get_type")
+  (return-type "GType")
 )
 
 )
 
-(define-function empathy_contact_equal
-  (c-name "empathy_contact_equal")
-  (return-type "gboolean")
-  (parameters
-    '("gconstpointer" "v1")
-    '("gconstpointer" "v2")
-  )
+(define-function empathy_contact_manager_new
+  (c-name "empathy_contact_manager_new")
+  (is-constructor-of "EmpathyContactManager")
+  (return-type "EmpathyContactManager*")
 )
 
 )
 
-(define-function empathy_contact_hash
-  (c-name "empathy_contact_hash")
-  (return-type "guint")
+(define-method get_list
+  (of-object "EmpathyContactManager")
+  (c-name "empathy_contact_manager_get_list")
+  (return-type "EmpathyTpContactList*")
   (parameters
   (parameters
-    '("gconstpointer" "key")
+    '("McAccount*" "account")
   )
 )
 
   )
 )
 
   (varargs #t)
 )
 
   (varargs #t)
 )
 
-
-
-;; From empathy-filter-glue.h
-
-(define-function dbus_glib_marshal_empathy_filter_BOOLEAN__STRING_BOXED_STRING_BOXED_UINT_UINT_UINT_POINTER
-  (c-name "dbus_glib_marshal_empathy_filter_BOOLEAN__STRING_BOXED_STRING_BOXED_UINT_UINT_UINT_POINTER")
+(define-function empathy_debug_set_log_file_from_env
+  (c-name "empathy_debug_set_log_file_from_env")
   (return-type "none")
   (return-type "none")
-  (parameters
-    '("GClosure*" "closure")
-    '("GValue*" "return_value")
-    '("guint" "n_param_values")
-    '("const-GValue*" "param_values")
-    '("gpointer" "invocation_hint")
-    '("gpointer" "marshal_data")
-  )
 )
 
 
 )
 
 
   )
 )
 
   )
 )
 
+(define-method get_messages_for_file
+  (of-object "EmpathyLogManager")
+  (c-name "empathy_log_manager_get_messages_for_file")
+  (return-type "GList*")
+  (parameters
+    '("const-gchar*" "filename")
+  )
+)
+
 (define-method get_messages_for_date
   (of-object "EmpathyLogManager")
   (c-name "empathy_log_manager_get_messages_for_date")
 (define-method get_messages_for_date
   (of-object "EmpathyLogManager")
   (c-name "empathy_log_manager_get_messages_for_date")
   )
 )
 
   )
 )
 
+(define-method get_messages_for_file
+  (of-object "EmpathyLogManager")
+  (c-name "empathy_log_manager_get_messages_for_file")
+  (return-type "GList*")
+  (parameters
+    '("const-gchar*" "filename")
+  )
+)
+
 (define-method get_chats
   (of-object "EmpathyLogManager")
   (c-name "empathy_log_manager_get_chats")
 (define-method get_chats
   (of-object "EmpathyLogManager")
   (c-name "empathy_log_manager_get_chats")
 
 
 
 
 
 
-;; From empathy-marshal.h
-
-
-
 ;; From empathy-message.h
 
 (define-function empathy_message_get_gtype
 ;; From empathy-message.h
 
 (define-function empathy_message_get_gtype
   )
 )
 
   )
 )
 
+(define-function empathy_message_type_from_str
+  (c-name "empathy_message_type_from_str")
+  (return-type "EmpathyMessageType")
+  (parameters
+    '("const-gchar*" "type_str")
+  )
+)
+
+(define-method to_str
+  (of-object "EmpathyMessageType")
+  (c-name "empathy_message_type_to_str")
+  (return-type "const-gchar*")
+)
+
 
 
 ;; From empathy-presence.h
 
 
 ;; From empathy-presence.h
   (return-type "McAccount*")
 )
 
   (return-type "McAccount*")
 )
 
-(define-method get_user
-  (of-object "EmpathyTpContactList")
-  (c-name "empathy_tp_contact_list_get_user")
-  (return-type "EmpathyContact*")
-)
-
-(define-method get_from_id
-  (of-object "EmpathyTpContactList")
-  (c-name "empathy_tp_contact_list_get_from_id")
-  (return-type "EmpathyContact*")
-  (parameters
-    '("const-gchar*" "id")
-  )
-)
-
-(define-method get_from_handle
-  (of-object "EmpathyTpContactList")
-  (c-name "empathy_tp_contact_list_get_from_handle")
-  (return-type "EmpathyContact*")
-  (parameters
-    '("guint" "handle")
-  )
-)
-
-(define-method get_from_handles
-  (of-object "EmpathyTpContactList")
-  (c-name "empathy_tp_contact_list_get_from_handles")
-  (return-type "GList*")
-  (parameters
-    '("GArray*" "handles")
-  )
-)
-
-(define-method rename_group
-  (of-object "EmpathyTpContactList")
-  (c-name "empathy_tp_contact_list_rename_group")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "old_group")
-    '("const-gchar*" "new_group")
-  )
-)
-
-(define-method get_groups
-  (of-object "EmpathyTpContactList")
-  (c-name "empathy_tp_contact_list_get_groups")
-  (return-type "GList*")
-)
-
 
 
 ;; From empathy-tp-group.h
 
 
 ;; From empathy-tp-group.h
   (is-constructor-of "EmpathyTpGroup")
   (return-type "EmpathyTpGroup*")
   (parameters
   (is-constructor-of "EmpathyTpGroup")
   (return-type "EmpathyTpGroup*")
   (parameters
+    '("McAccount*" "account")
     '("TpChan*" "tp_chan")
     '("TpChan*" "tp_chan")
-    '("TpConn*" "tp_conn")
   )
 )
 
   )
 )
 
+(define-method close
+  (of-object "EmpathyTpGroup")
+  (c-name "empathy_tp_group_close")
+  (return-type "none")
+)
+
 (define-method add_members
   (of-object "EmpathyTpGroup")
   (c-name "empathy_tp_group_add_members")
   (return-type "none")
   (parameters
 (define-method add_members
   (of-object "EmpathyTpGroup")
   (c-name "empathy_tp_group_add_members")
   (return-type "none")
   (parameters
-    '("GArray*" "handles")
+    '("GList*" "contacts")
     '("const-gchar*" "message")
   )
 )
     '("const-gchar*" "message")
   )
 )
   (c-name "empathy_tp_group_add_member")
   (return-type "none")
   (parameters
   (c-name "empathy_tp_group_add_member")
   (return-type "none")
   (parameters
-    '("guint" "handle")
+    '("EmpathyContact*" "contact")
     '("const-gchar*" "message")
   )
 )
     '("const-gchar*" "message")
   )
 )
   (c-name "empathy_tp_group_remove_members")
   (return-type "none")
   (parameters
   (c-name "empathy_tp_group_remove_members")
   (return-type "none")
   (parameters
-    '("GArray*" "handle")
+    '("GList*" "contacts")
     '("const-gchar*" "message")
   )
 )
     '("const-gchar*" "message")
   )
 )
   (c-name "empathy_tp_group_remove_member")
   (return-type "none")
   (parameters
   (c-name "empathy_tp_group_remove_member")
   (return-type "none")
   (parameters
-    '("guint" "handle")
+    '("EmpathyContact*" "contact")
     '("const-gchar*" "message")
   )
 )
     '("const-gchar*" "message")
   )
 )
 (define-method get_members
   (of-object "EmpathyTpGroup")
   (c-name "empathy_tp_group_get_members")
 (define-method get_members
   (of-object "EmpathyTpGroup")
   (c-name "empathy_tp_group_get_members")
-  (return-type "GArray*")
+  (return-type "GList*")
 )
 
 )
 
-(define-method get_all_members
+(define-method get_local_pendings
   (of-object "EmpathyTpGroup")
   (of-object "EmpathyTpGroup")
-  (c-name "empathy_tp_group_get_all_members")
-  (return-type "none")
-  (parameters
-    '("GArray**" "members")
-    '("GArray**" "local_pending")
-    '("GArray**" "remote_pending")
-  )
+  (c-name "empathy_tp_group_get_local_pendings")
+  (return-type "GList*")
 )
 
 )
 
-(define-method get_local_pending_members_with_info
+(define-method get_remote_pendings
   (of-object "EmpathyTpGroup")
   (of-object "EmpathyTpGroup")
-  (c-name "empathy_tp_group_get_local_pending_members_with_info")
+  (c-name "empathy_tp_group_get_remote_pendings")
   (return-type "GList*")
 )
 
   (return-type "GList*")
 )
 
-(define-function empathy_tp_group_info_list_free
-  (c-name "empathy_tp_group_info_list_free")
-  (return-type "none")
-  (parameters
-    '("GList*" "infos")
-  )
-)
-
 (define-method get_name
   (of-object "EmpathyTpGroup")
   (c-name "empathy_tp_group_get_name")
   (return-type "const-gchar*")
 )
 
 (define-method get_name
   (of-object "EmpathyTpGroup")
   (c-name "empathy_tp_group_get_name")
   (return-type "const-gchar*")
 )
 
-(define-method get_self_handle
+(define-method get_self_contact
   (of-object "EmpathyTpGroup")
   (of-object "EmpathyTpGroup")
-  (c-name "empathy_tp_group_get_self_handle")
-  (return-type "guint")
+  (c-name "empathy_tp_group_get_self_contact")
+  (return-type "EmpathyContact*")
 )
 
 (define-method get_object_path
 )
 
 (define-method get_object_path
   (c-name "empathy_tp_group_is_member")
   (return-type "gboolean")
   (parameters
   (c-name "empathy_tp_group_is_member")
   (return-type "gboolean")
   (parameters
-    '("guint" "handle")
+    '("EmpathyContact*" "contact")
+  )
+)
+
+(define-function empathy_pending_info_new
+  (c-name "empathy_pending_info_new")
+  (is-constructor-of "EmpathyPendingInfo")
+  (return-type "EmpathyPendingInfo*")
+  (parameters
+    '("EmpathyContact*" "member")
+    '("EmpathyContact*" "actor")
+    '("const-gchar*" "message")
+  )
+)
+
+(define-method free
+  (of-object "EmpathyPendingInfo")
+  (c-name "empathy_pending_info_free")
+  (return-type "none")
+)
+
+
+
+;; From empathy-tp-roomlist.h
+
+(define-function empathy_tp_roomlist_get_type
+  (c-name "empathy_tp_roomlist_get_type")
+  (return-type "GType")
+)
+
+(define-function empathy_tp_roomlist_new
+  (c-name "empathy_tp_roomlist_new")
+  (is-constructor-of "EmpathyTpRoomlist")
+  (return-type "EmpathyTpRoomlist*")
+  (parameters
+    '("McAccount*" "account")
   )
 )
 
   )
 )
 
+(define-method is_listing
+  (of-object "EmpathyTpRoomlist")
+  (c-name "empathy_tp_roomlist_is_listing")
+  (return-type "gboolean")
+)
+
+(define-method start
+  (of-object "EmpathyTpRoomlist")
+  (c-name "empathy_tp_roomlist_start")
+  (return-type "none")
+)
+
+(define-method stop
+  (of-object "EmpathyTpRoomlist")
+  (c-name "empathy_tp_roomlist_stop")
+  (return-type "none")
+)
+
 
 
 ;; From empathy-utils.h
 
 
 ;; From empathy-utils.h
   (return-type "MissionControl*")
 )
 
   (return-type "MissionControl*")
 )
 
-(define-function empathy_get_channel_id
-  (c-name "empathy_get_channel_id")
+(define-function empathy_inspect_handle
+  (c-name "empathy_inspect_handle")
+  (return-type "gchar*")
+  (parameters
+    '("McAccount*" "account")
+    '("guint" "handle")
+    '("guint" "handle_type")
+  )
+)
+
+(define-function empathy_inspect_channel
+  (c-name "empathy_inspect_channel")
   (return-type "gchar*")
   (parameters
     '("McAccount*" "account")
   (return-type "gchar*")
   (parameters
     '("McAccount*" "account")
   )
 )
 
   )
 )
 
+(define-function empathy_strdiff
+  (c-name "empathy_strdiff")
+  (return-type "gboolean")
+  (parameters
+    '("const-gchar*" "left")
+    '("const-gchar*" "right")
+  )
+)
+
+
index 607a9e520f8f97688fd1e484f1e0b57483a78764..dd816e23a2b1fdd6c0585b17df38c4daafb970c3 100644 (file)
@@ -21,15 +21,10 @@ headers
 #include "empathy-tp-chatroom.h"
 #include "empathy-tp-contact-list.h"
 #include "empathy-tp-group.h"
 #include "empathy-tp-chatroom.h"
 #include "empathy-tp-contact-list.h"
 #include "empathy-tp-group.h"
+#include "empathy-tp-roomlist.h"
 #include "empathy-utils.h"
 #include "empathy-utils.h"
-
-
-/* FIXME */
-#define MC_TYPE_PRESENCE 1
-#define EMPATHY_TYPE_SUBSCRIPTION 2
-#define EMPATHY_TYPE_MESSAGE_TYPE 3
-#define EMPATHY_TYPE_REG_EX_TYPE 4
-
+#include "empathy-contact-factory.h"
+#include "empathy-enum-types.h"
 
 void empathy_add_constants(PyObject *module, const gchar *strip_prefix);
 void empathy_register_classes(PyObject *d);
 
 void empathy_add_constants(PyObject *module, const gchar *strip_prefix);
 void empathy_register_classes(PyObject *d);
@@ -62,22 +57,3 @@ _wrap_empathy_contact_list_get_members(PyGObject *self, PyObject *args, PyObject
 
 }
 %%
 
 }
 %%
-override empathy_contact_get_groups kwargs
-static PyObject *
-_wrap_empathy_contact_get_groups(PyGObject *self, PyObject *args, PyObject *kwargs)
-{
-
-       GList *groups = empathy_contact_get_groups(EMPATHY_CONTACT(self->obj));
-       PyObject *py_groups = PyList_New(0);
-       GList *l;
-
-       for(l = groups; l; l = l->next) {
-               const gchar *group;
-               group = l->data;
-               PyList_Append(py_groups, PyString_FromString(group));
-       }
-
-       return py_groups;
-
-}
-%%
index c41ea45c7fdec37231c8f1a5b56bd4c04eef71fe..71a4437b657d08a72f7cd10ca9e5f0ad1e9e1a76 100644 (file)
 
 
 
 
 
 
+;; From empathy-account-widget-salut.h
+
+(define-function empathy_account_widget_salut_new
+  (c-name "empathy_account_widget_salut_new")
+  (is-constructor-of "EmpathyAccountWidgetSalut")
+  (return-type "GtkWidget*")
+  (parameters
+    '("McAccount*" "account")
+  )
+)
+
+
+
 ;; From empathy-cell-renderer-expander.h
 
 (define-function empathy_cell_renderer_expander_get_type
 ;; From empathy-cell-renderer-expander.h
 
 (define-function empathy_cell_renderer_expander_get_type
   )
 )
 
   )
 )
 
-(define-method set_contact_groups_func
-  (of-object "EmpathyContactListStore")
-  (c-name "empathy_contact_list_store_set_contact_groups_func")
-  (return-type "none")
-  (parameters
-    '("EmpathyContactGroupsFunc" "func")
-    '("gpointer" "user_data")
-  )
-)
-
-(define-method update_contact_groups
-  (of-object "EmpathyContactListStore")
-  (c-name "empathy_contact_list_store_update_contact_groups")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-  )
-)
-
 
 
 ;; From empathy-contact-list-view.h
 
 
 ;; From empathy-contact-list-view.h
   (return-type "GtkWidget*")
 )
 
   (return-type "GtkWidget*")
 )
 
-(define-method set_filter
-  (of-object "EmpathyContactListView")
-  (c-name "empathy_contact_list_view_set_filter")
-  (return-type "none")
-  (parameters
-    '("const-gchar*" "filter")
-  )
-)
-
-(define-method set_drag_received_func
-  (of-object "EmpathyContactListView")
-  (c-name "empathy_contact_list_view_set_drag_received_func")
-  (return-type "none")
-  (parameters
-    '("EmpathyContactListViewDragReceivedFunc" "func")
-    '("gpointer" "user_data")
-  )
-)
-
 
 
 ;; From empathy-contact-widget.h
 
 
 ;; From empathy-contact-widget.h