aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog258
-rw-r--r--configure.ac100
-rw-r--r--doc/libempathy-gtk/tmpl/empathy-contact-list-store.sgml19
-rw-r--r--doc/libempathy-gtk/tmpl/empathy-contact-list-view.sgml36
-rw-r--r--doc/libempathy-gtk/tmpl/empathy-images.sgml7
-rw-r--r--doc/libempathy-gtk/tmpl/empathy-preferences.sgml7
-rw-r--r--doc/libempathy/libempathy.types4
-rw-r--r--doc/libempathy/tmpl/empathy-avatar.sgml8
-rw-r--r--doc/libempathy/tmpl/empathy-contact-list.sgml88
-rw-r--r--doc/libempathy/tmpl/empathy-contact-manager.sgml40
-rw-r--r--doc/libempathy/tmpl/empathy-contact.sgml92
-rw-r--r--doc/libempathy/tmpl/empathy-tp-contact-list.sgml58
-rw-r--r--doc/libempathy/tmpl/empathy-tp-group.sgml68
-rw-r--r--libempathy-gtk/empathy-chat-window.c35
-rw-r--r--libempathy-gtk/empathy-contact-dialogs.c12
-rw-r--r--libempathy-gtk/empathy-contact-list-store.c373
-rw-r--r--libempathy-gtk/empathy-contact-list-store.h5
-rw-r--r--libempathy-gtk/empathy-contact-list-view.c346
-rw-r--r--libempathy-gtk/empathy-contact-list-view.h25
-rw-r--r--libempathy-gtk/empathy-contact-widget.c114
-rw-r--r--libempathy-gtk/empathy-group-chat.c49
-rw-r--r--libempathy-gtk/empathy-images.h2
-rw-r--r--libempathy-gtk/empathy-main-window.c1
-rw-r--r--libempathy-gtk/empathy-private-chat.c40
-rw-r--r--libempathy-gtk/empathy-status-icon.c49
-rw-r--r--libempathy-gtk/empathy-ui-utils.c10
-rw-r--r--libempathy/Makefile.am6
-rw-r--r--libempathy/empathy-avatar.c2
-rw-r--r--libempathy/empathy-avatar.h4
-rw-r--r--libempathy/empathy-contact-factory.c1102
-rw-r--r--libempathy/empathy-contact-factory.h72
-rw-r--r--libempathy/empathy-contact-list.c147
-rw-r--r--libempathy/empathy-contact-list.h79
-rw-r--r--libempathy/empathy-contact-manager.c684
-rw-r--r--libempathy/empathy-contact-manager.h17
-rw-r--r--libempathy/empathy-contact.c367
-rw-r--r--libempathy/empathy-contact.h89
-rw-r--r--libempathy/empathy-log-manager.c18
-rw-r--r--libempathy/empathy-marshal.list12
-rw-r--r--libempathy/empathy-tp-chat.c39
-rw-r--r--libempathy/empathy-tp-chatroom.c164
-rw-r--r--libempathy/empathy-tp-contact-list.c2205
-rw-r--r--libempathy/empathy-tp-contact-list.h17
-rw-r--r--libempathy/empathy-tp-group.c864
-rw-r--r--libempathy/empathy-tp-group.h71
-rw-r--r--python/README19
-rw-r--r--python/pyempathy/pyempathy.defs817
-rw-r--r--python/pyempathy/pyempathy.override30
-rw-r--r--python/pyempathygtk/pyempathygtk.defs51
49 files changed, 4085 insertions, 4637 deletions
diff --git a/ChangeLog b/ChangeLog
index fdb0c4d9a..976db9eba 100644
--- 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).
-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.
-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.
-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:
@@ -26,12 +72,12 @@
* 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.
-2007-08-24 Xavier Claessens <xclaesse@gmail.com>
+2007-08-24 Xavier Claessens <xclaesse@gmail.com>
* configure.ac:
* data/22x22/Makefile.am:
@@ -52,7 +98,7 @@
* 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:
@@ -67,14 +113,14 @@
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.
-2007-08-19 Xavier Claessens <xclaesse@gmail.com>
+2007-08-19 Xavier Claessens <xclaesse@gmail.com>
* python/pyempathy/pyempathy.defs:
* python/pyempathy/pyempathymodule.c:
@@ -89,12 +135,12 @@
* 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).
-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.
@@ -104,11 +150,11 @@
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.
-2007-08-12 Xavier Claessens <xclaesse@gmail.com>
+2007-08-12 Xavier Claessens <xclaesse@gmail.com>
* configure.ac: Update libtool version.
@@ -116,33 +162,33 @@
* 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.
-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).
-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)
-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).
-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).
-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:
@@ -156,7 +202,7 @@
* 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:
@@ -169,24 +215,24 @@
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.
-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).
-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).
-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.
@@ -217,12 +263,12 @@
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".
-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.
@@ -230,7 +276,7 @@
* 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
@@ -239,18 +285,18 @@
* 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.
-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.
-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:
@@ -258,18 +304,18 @@
* 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.
-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.
-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:
@@ -277,31 +323,31 @@
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).
-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).
-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.
-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.
-2007-07-29 Xavier Claessens <xclaesse@gmail.com>
+2007-07-29 Xavier Claessens <xclaesse@gmail.com>
* 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
@@ -313,36 +359,36 @@
* 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.
-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.
-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.
-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.
-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.
-2007-07-27 Xavier Claessens <xclaesse@gmail.com>
+2007-07-27 Xavier Claessens <xclaesse@gmail.com>
* libempathy/empathy-message.c:
* libempathy/empathy-message.h:
@@ -351,38 +397,38 @@
* 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.
-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).
-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).
-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).
-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.
-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:
@@ -396,32 +442,32 @@
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).
-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.
-2007-07-26 Xavier Claessens <xclaesse@gmail.com>
+2007-07-26 Xavier Claessens <xclaesse@gmail.com>
* 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.
-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.
-2007-07-20 Xavier Claessens <xclaesse@gmail.com>
+2007-07-20 Xavier Claessens <xclaesse@gmail.com>
* libempathy/Makefile.am:
* libempathy/empathy-tp-roomlist.h:
@@ -468,22 +514,22 @@
* 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.
-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.
-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.
-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
@@ -499,7 +545,7 @@
* 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.
@@ -508,26 +554,26 @@
* 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.
-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.
-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).
-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:
@@ -541,18 +587,18 @@
* 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.
-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.
-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.
@@ -575,7 +621,7 @@
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:
@@ -584,11 +630,11 @@
* 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/
-2007-06-22 Xavier Claessens <xclaesse@gmail.com>
+2007-06-22 Xavier Claessens <xclaesse@gmail.com>
* libempathy/*.[ch]:
* libempathy-gtk/*.[ch]:
@@ -596,15 +642,15 @@
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
-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.
-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:
@@ -618,12 +664,12 @@
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.
-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:
@@ -632,7 +678,7 @@
* 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.
@@ -645,12 +691,12 @@
* 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.
-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:
@@ -664,22 +710,22 @@
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.
-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.
-2007-06-14 Xavier Claessens <xclaesse@gmail.com>
+2007-06-14 Xavier Claessens <xclaesse@gmail.com>
* 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:
@@ -688,7 +734,7 @@
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:
@@ -723,7 +769,7 @@
* 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:
@@ -735,22 +781,22 @@
* 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).
-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.
-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.
-2007-06-09 Xavier Claessens <xclaesse@gmail.com>
+2007-06-09 Xavier Claessens <xclaesse@gmail.com>
* configure.ac: Bump version to 0.8
@@ -762,11 +808,11 @@
* 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.
-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:
@@ -779,12 +825,12 @@
* 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.
-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:
@@ -797,18 +843,18 @@
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).
-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.
-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:
@@ -825,7 +871,7 @@
* 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:
@@ -833,11 +879,11 @@
* 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.
-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:
@@ -852,7 +898,7 @@
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:
@@ -870,7 +916,7 @@
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
@@ -893,7 +939,7 @@
* 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
@@ -901,7 +947,7 @@
* 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
@@ -920,13 +966,13 @@
* 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)
-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:
diff --git a/configure.ac b/configure.ac
index c31afd82c..49a09b7b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -155,62 +155,58 @@ AC_ARG_ENABLE(python,
[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
- 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
-AM_CONDITIONAL(HAVE_PYTHON, test x$enable_python = xyes)
+
+AM_CONDITIONAL(HAVE_PYTHON, test "x$have_python" = "xyes")
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
])
diff --git a/doc/libempathy-gtk/tmpl/empathy-contact-list-store.sgml b/doc/libempathy-gtk/tmpl/empathy-contact-list-store.sgml
index a4430da49..cc74feef8 100644
--- a/doc/libempathy-gtk/tmpl/empathy-contact-list-store.sgml
+++ b/doc/libempathy-gtk/tmpl/empathy-contact-list-store.sgml
@@ -173,22 +173,3 @@ EmpathyContactListStore
@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:
-
-
diff --git a/doc/libempathy-gtk/tmpl/empathy-contact-list-view.sgml b/doc/libempathy-gtk/tmpl/empathy-contact-list-view.sgml
index ad7a1ff71..188033ebf 100644
--- a/doc/libempathy-gtk/tmpl/empathy-contact-list-view.sgml
+++ b/doc/libempathy-gtk/tmpl/empathy-contact-list-view.sgml
@@ -39,23 +39,6 @@ EmpathyContactListView
@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>
@@ -102,22 +85,3 @@ EmpathyContactListView
@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:
-
-
diff --git a/doc/libempathy-gtk/tmpl/empathy-images.sgml b/doc/libempathy-gtk/tmpl/empathy-images.sgml
index c55b21f1c..5b8c6541c 100644
--- a/doc/libempathy-gtk/tmpl/empathy-images.sgml
+++ b/doc/libempathy-gtk/tmpl/empathy-images.sgml
@@ -59,13 +59,6 @@ empathy-images
-<!-- ##### MACRO EMPATHY_IMAGE_PENDING ##### -->
-<para>
-
-</para>
-
-
-
<!-- ##### MACRO EMPATHY_IMAGE_MESSAGE ##### -->
<para>
diff --git a/doc/libempathy-gtk/tmpl/empathy-preferences.sgml b/doc/libempathy-gtk/tmpl/empathy-preferences.sgml
index d97f5b57b..0b7a7d27a 100644
--- a/doc/libempathy-gtk/tmpl/empathy-preferences.sgml
+++ b/doc/libempathy-gtk/tmpl/empathy-preferences.sgml
@@ -143,13 +143,6 @@ empathy-preferences
-<!-- ##### MACRO EMPATHY_PREFS_SALUT_ACCOUNT_CREATED ##### -->
-<para>
-
-</para>
-
-
-
<!-- ##### FUNCTION empathy_preferences_show ##### -->
<para>
diff --git a/doc/libempathy/libempathy.types b/doc/libempathy/libempathy.types
index 0211e40b1..15955d12b 100644
--- a/doc/libempathy/libempathy.types
+++ b/doc/libempathy/libempathy.types
@@ -16,7 +16,7 @@
#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
@@ -26,7 +26,7 @@ empathy_conf_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
diff --git a/doc/libempathy/tmpl/empathy-avatar.sgml b/doc/libempathy/tmpl/empathy-avatar.sgml
index 44035517e..3f71285c8 100644
--- a/doc/libempathy/tmpl/empathy-avatar.sgml
+++ b/doc/libempathy/tmpl/empathy-avatar.sgml
@@ -34,14 +34,6 @@ empathy-avatar
@format:
@refcount:
-<!-- ##### FUNCTION empathy_avatar_get_gtype ##### -->
-<para>
-
-</para>
-
-@Returns:
-
-
<!-- ##### FUNCTION empathy_avatar_new ##### -->
<para>
diff --git a/doc/libempathy/tmpl/empathy-contact-list.sgml b/doc/libempathy/tmpl/empathy-contact-list.sgml
index 1a2839fc7..a84646a8e 100644
--- a/doc/libempathy/tmpl/empathy-contact-list.sgml
+++ b/doc/libempathy/tmpl/empathy-contact-list.sgml
@@ -23,23 +23,29 @@ empathy-contact-list
</para>
-<!-- ##### SIGNAL EmpathyContactList::contact-added ##### -->
+<!-- ##### SIGNAL EmpathyContactList::groups-changed ##### -->
<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:
+@arg2:
+@arg3:
+@arg4:
+@arg5:
-<!-- ##### SIGNAL EmpathyContactList::local-pending ##### -->
+<!-- ##### SIGNAL EmpathyContactList::pendings-changed ##### -->
<para>
</para>
@@ -47,6 +53,9 @@ empathy-contact-list
@empathycontactlist: the object which received the signal.
@arg1:
@arg2:
+@arg3:
+@arg4:
+@arg5:
<!-- ##### STRUCT EmpathyContactListIface ##### -->
<para>
@@ -54,57 +63,15 @@ empathy-contact-list
</para>
@base_iface:
-@setup:
-@find:
@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>
@@ -135,22 +102,3 @@ empathy-contact-list
@Returns:
-<!-- ##### FUNCTION empathy_contact_list_get_local_pending ##### -->
-<para>
-
-</para>
-
-@list:
-@Returns:
-
-
-<!-- ##### FUNCTION empathy_contact_list_process_pending ##### -->
-<para>
-
-</para>
-
-@list:
-@contact:
-@accept:
-
-
diff --git a/doc/libempathy/tmpl/empathy-contact-manager.sgml b/doc/libempathy/tmpl/empathy-contact-manager.sgml
index 0defe4840..fe25eb7eb 100644
--- a/doc/libempathy/tmpl/empathy-contact-manager.sgml
+++ b/doc/libempathy/tmpl/empathy-contact-manager.sgml
@@ -47,43 +47,3 @@ EmpathyContactManager
@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:
-
-
diff --git a/doc/libempathy/tmpl/empathy-contact.sgml b/doc/libempathy/tmpl/empathy-contact.sgml
index 1ab2321af..861151fb6 100644
--- a/doc/libempathy/tmpl/empathy-contact.sgml
+++ b/doc/libempathy/tmpl/empathy-contact.sgml
@@ -33,11 +33,6 @@ EmpathyContact
</para>
-<!-- ##### ARG EmpathyContact:groups ##### -->
-<para>
-
-</para>
-
<!-- ##### ARG EmpathyContact:handle ##### -->
<para>
@@ -63,29 +58,6 @@ EmpathyContact
</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>
@@ -151,24 +123,6 @@ EmpathyContact
@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>
@@ -232,24 +186,6 @@ EmpathyContact
@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>
@@ -268,24 +204,6 @@ EmpathyContact
@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>
@@ -295,16 +213,6 @@ EmpathyContact
@Returns:
-<!-- ##### FUNCTION empathy_contact_is_in_group ##### -->
-<para>
-
-</para>
-
-@contact:
-@group:
-@Returns:
-
-
<!-- ##### FUNCTION empathy_contact_get_status ##### -->
<para>
diff --git a/doc/libempathy/tmpl/empathy-tp-contact-list.sgml b/doc/libempathy/tmpl/empathy-tp-contact-list.sgml
index 3420151db..a3ff09ef1 100644
--- a/doc/libempathy/tmpl/empathy-tp-contact-list.sgml
+++ b/doc/libempathy/tmpl/empathy-tp-contact-list.sgml
@@ -54,61 +54,3 @@ EmpathyTpContactList
@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:
-
-
diff --git a/doc/libempathy/tmpl/empathy-tp-group.sgml b/doc/libempathy/tmpl/empathy-tp-group.sgml
index 988b5d8f6..6ea6206e4 100644
--- a/doc/libempathy/tmpl/empathy-tp-group.sgml
+++ b/doc/libempathy/tmpl/empathy-tp-group.sgml
@@ -29,6 +29,13 @@ EmpathyTpGroup
</para>
+<!-- ##### SIGNAL EmpathyTpGroup::destroy ##### -->
+<para>
+
+</para>
+
+@empathytpgroup: the object which received the signal.
+
<!-- ##### SIGNAL EmpathyTpGroup::local-pending ##### -->
<para>
@@ -40,7 +47,7 @@ EmpathyTpGroup
@arg3:
@arg4:
-<!-- ##### SIGNAL EmpathyTpGroup::members-added ##### -->
+<!-- ##### SIGNAL EmpathyTpGroup::member-added ##### -->
<para>
</para>
@@ -51,7 +58,7 @@ EmpathyTpGroup
@arg3:
@arg4:
-<!-- ##### SIGNAL EmpathyTpGroup::members-removed ##### -->
+<!-- ##### SIGNAL EmpathyTpGroup::member-removed ##### -->
<para>
</para>
@@ -73,16 +80,6 @@ EmpathyTpGroup
@arg3:
@arg4:
-<!-- ##### STRUCT EmpathyTpGroupInfo ##### -->
-<para>
-
-</para>
-
-@member:
-@actor:
-@reason:
-@message:
-
<!-- ##### FUNCTION empathy_tp_group_new ##### -->
<para>
@@ -99,7 +96,7 @@ EmpathyTpGroup
</para>
@group:
-@handles:
+@contacts:
@message:
@@ -109,7 +106,7 @@ EmpathyTpGroup
</para>
@group:
-@handle:
+@contact:
@message:
@@ -119,7 +116,7 @@ EmpathyTpGroup
</para>
@group:
-@handle:
+@contacts:
@message:
@@ -129,7 +126,7 @@ EmpathyTpGroup
</para>
@group:
-@handle:
+@contact:
@message:
@@ -142,34 +139,6 @@ EmpathyTpGroup
@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>
@@ -179,15 +148,6 @@ EmpathyTpGroup
@Returns:
-<!-- ##### FUNCTION empathy_tp_group_get_self_handle ##### -->
-<para>
-
-</para>
-
-@group:
-@Returns:
-
-
<!-- ##### FUNCTION empathy_tp_group_get_object_path ##### -->
<para>
@@ -203,7 +163,7 @@ EmpathyTpGroup
</para>
@group:
-@handle:
+@contact:
@Returns:
diff --git a/libempathy-gtk/empathy-chat-window.c b/libempathy-gtk/empathy-chat-window.c
index 7d48abf8a..c1df38b15 100644
--- a/libempathy-gtk/empathy-chat-window.c
+++ b/libempathy-gtk/empathy-chat-window.c
@@ -34,7 +34,7 @@
#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>
@@ -823,17 +823,20 @@ chat_window_update_menu (EmpathyChatWindow *window)
window);
} else {
EmpathyPrivateChat *chat;
- EmpathySubscription subscription;
EmpathyContact *contact;
+ EmpathyPresence *presence;
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);
- 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);
@@ -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) {
- 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;
+ gchar **strv;
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);
- 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");
diff --git a/libempathy-gtk/empathy-contact-dialogs.c b/libempathy-gtk/empathy-contact-dialogs.c
index 437e255fa..553f85bcc 100644
--- a/libempathy-gtk/empathy-contact-dialogs.c
+++ b/libempathy-gtk/empathy-contact-dialogs.c
@@ -42,7 +42,7 @@ static GtkWidget *new_contact_dialog = NULL;
static gint
-contact_dialogs_find (GtkDialog *dialog,
+contact_dialogs_find (GtkDialog *dialog,
EmpathyContact *contact)
{
GtkWidget *contact_widget;
@@ -64,18 +64,18 @@ subscription_dialog_response_cb (GtkDialog *dialog,
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) {
- 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) {
- 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);
diff --git a/libempathy-gtk/empathy-contact-list-store.c b/libempathy-gtk/empathy-contact-list-store.c
index ac2fa62cd..9cf03bfe8 100644
--- a/libempathy-gtk/empathy-contact-list-store.c
+++ b/libempathy-gtk/empathy-contact-list-store.c
@@ -57,10 +57,10 @@ struct _EmpathyContactListStorePriv {
gboolean show_avatars;
gboolean is_compact;
gboolean show_active;
- EmpathyContactListStoreSort sort_criterium;
+ EmpathyContactListStoreSort sort_criterium;
guint inhibit_active;
- EmpathyContactGroupsFunc get_contact_groups;
+ EmpathyContactGroupsFunc get_contact_groups;
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 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,
@@ -317,24 +320,23 @@ empathy_contact_list_store_new (EmpathyContactList *list_iface)
/* 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,
- "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) {
- 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);
@@ -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) {
- 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);
@@ -611,80 +609,6 @@ empathy_contact_list_store_search_equal_func (GtkTreeModel *model,
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)
{
@@ -733,37 +657,73 @@ contact_list_store_inibit_active_cb (EmpathyContactListStore *store)
}
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,
- "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);
+ 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);
+ priv->show_active = show_active;
}
static void
@@ -780,14 +740,9 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
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,
@@ -800,15 +755,9 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
/* 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);
@@ -818,28 +767,12 @@ contact_list_store_add_contact (EmpathyContactListStore *store,
COL_IS_GROUP, FALSE,
COL_IS_SEPARATOR, FALSE,
-1);
+ g_free (l->data);
}
+ g_list_free (groups);
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
@@ -1029,16 +962,8 @@ contact_list_store_contact_update (EmpathyContactListStore *store,
}
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,
- GParamSpec *param,
+ GParamSpec *param,
EmpathyContactListStore *store)
{
empathy_debug (DEBUG_DOMAIN,
@@ -1180,10 +1105,10 @@ contact_list_store_get_group (EmpathyContactListStore *store,
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);
diff --git a/libempathy-gtk/empathy-contact-list-store.h b/libempathy-gtk/empathy-contact-list-store.h
index d7c9635f5..d096daafd 100644
--- a/libempathy-gtk/empathy-contact-list-store.h
+++ b/libempathy-gtk/empathy-contact-list-store.h
@@ -106,11 +106,6 @@ gboolean empathy_contact_list_store_search_equal_func (GtkTre
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
diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index 2a5cf3406..5b3f0de08 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -34,7 +34,7 @@
#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>
@@ -66,13 +66,8 @@
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 {
@@ -103,11 +98,6 @@ static void contact_list_view_row_has_child_toggled_cb (GtkTreeModel
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,
@@ -173,14 +163,6 @@ static void contact_list_view_row_expand_or_collapse_cb (EmpathyContactLi
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,
@@ -188,7 +170,6 @@ static void contact_list_view_action_activated (EmpathyContactLi
enum {
PROP_0,
- PROP_FILTER,
};
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_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));
}
@@ -389,10 +362,6 @@ contact_list_view_finalize (GObject *object)
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);
}
@@ -408,9 +377,6 @@ contact_list_view_get_property (GObject *object,
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;
@@ -428,10 +394,6 @@ contact_list_view_set_property (GObject *object,
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;
@@ -547,47 +509,6 @@ empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view,
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)
{
@@ -598,21 +519,11 @@ contact_list_view_setup (EmpathyContactListView *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);
- 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,
@@ -697,13 +608,13 @@ contact_list_view_setup (EmpathyContactListView *view)
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),
- GDK_ACTION_MOVE | GDK_ACTION_LINK);
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
}
static void
@@ -747,46 +658,6 @@ contact_list_view_row_has_child_toggled_cb (GtkTreeModel *model,
}
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,
gint x,
@@ -796,15 +667,18 @@ contact_list_view_drag_data_received (GtkWidget *widget,
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);
@@ -814,9 +688,18 @@ contact_list_view_drag_data_received (GtkWidget *widget,
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");
@@ -847,22 +730,17 @@ contact_list_view_drag_data_received (GtkWidget *widget,
}
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);
- 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);
@@ -976,11 +854,15 @@ contact_list_view_drag_data_get (GtkWidget *widget,
guint time)
{
EmpathyContactListViewPriv *priv;
- GtkTreePath *src_path;
- GtkTreeIter iter;
- GtkTreeModel *model;
+ GtkTreePath *src_path;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
EmpathyContact *contact;
- const gchar *id;
+ McAccount *account;
+ const gchar *contact_id;
+ const gchar *account_id;
+ gchar *str;
+
priv = GET_PRIV (widget);
@@ -1006,18 +888,20 @@ contact_list_view_drag_data_get (GtkWidget *widget,
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);
+ 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,
- (guchar*)id, strlen (id) + 1);
+ (guchar*)str, strlen (str) + 1);
break;
-
- default:
- return;
}
+
+ g_free (str);
}
static void
@@ -1329,124 +1213,6 @@ contact_list_view_row_expand_or_collapse_cb (EmpathyContactListView *view,
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)
diff --git a/libempathy-gtk/empathy-contact-list-view.h b/libempathy-gtk/empathy-contact-list-view.h
index 4d7cf1cb9..b9de24357 100644
--- a/libempathy-gtk/empathy-contact-list-view.h
+++ b/libempathy-gtk/empathy-contact-list-view.h
@@ -53,24 +53,13 @@ struct _EmpathyContactListViewClass {
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
diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c
index 5c8f6d3d8..b3081b130 100644
--- a/libempathy-gtk/empathy-contact-widget.c
+++ b/libempathy-gtk/empathy-contact-widget.c
@@ -31,7 +31,9 @@
#include <libmissioncontrol/mc-account.h>
+#include <libempathy/empathy-contact-factory.h>
#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-contact-list.h>
#include <libempathy/empathy-utils.h>
#include "empathy-contact-widget.h"
@@ -42,44 +44,45 @@
#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 */
- 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 */
- 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 */
- GtkWidget *vbox_details;
- GtkWidget *table_details;
- GtkWidget *hbox_details_requested;
+ GtkWidget *vbox_details;
+ GtkWidget *table_details;
+ GtkWidget *hbox_details_requested;
/* Client */
- GtkWidget *vbox_client;
- GtkWidget *table_client;
- GtkWidget *hbow_client_requested;
-
+ GtkWidget *vbox_client;
+ GtkWidget *table_client;
+ GtkWidget *hbow_client_requested;
} EmpathyContactWidget;
typedef struct {
@@ -151,6 +154,7 @@ empathy_contact_widget_new (EmpathyContact *contact,
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 {
@@ -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->factory) {
+ g_object_unref (information->factory);
+ }
+ if (information->manager) {
+ g_object_unref (information->manager);
+ }
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)) {
- 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);
}
- g_object_unref (manager);
}
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));
- empathy_contact_set_name (information->contact, name);
+ empathy_contact_factory_set_name (information->factory,
+ information->contact,
+ name);
}
return FALSE;
@@ -559,6 +569,7 @@ static void
contact_widget_groups_setup (EmpathyContactWidget *information)
{
if (information->type > CONTACT_WIDGET_TYPE_SHOW) {
+ information->manager = empathy_contact_manager_new ();
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)
{
- 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);
- 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;
@@ -691,7 +700,10 @@ contact_widget_groups_populate_data (EmpathyContactWidget *information)
-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 (my_groups);
}
static void
@@ -792,9 +804,13 @@ contact_widget_cell_toggled (GtkCellRendererToggle *cell,
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 {
- empathy_contact_add_group (information->contact, group);
+ empathy_contact_list_add_to_group (EMPATHY_CONTACT_LIST (information->manager),
+ information->contact,
+ group);
}
g_free (group);
@@ -846,7 +862,9 @@ contact_widget_button_group_clicked_cb (GtkButton *button,
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
diff --git a/libempathy-gtk/empathy-group-chat.c b/libempathy-gtk/empathy-group-chat.c
index ca046a3d7..48439302d 100644
--- a/libempathy-gtk/empathy-group-chat.c
+++ b/libempathy-gtk/empathy-group-chat.c
@@ -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_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 *actor,
+ guint reason,
+ gchar *message,
+ gboolean is_member,
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
-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 *actor,
+ guint reason,
+ gchar *message,
+ gboolean is_member,
EmpathyGroupChat *chat)
{
EmpathyGroupChatPriv *priv;
- gchar *str;
+ gchar *str;
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);
}
@@ -540,11 +534,8 @@ group_chat_set_tp_chat (EmpathyChat *chat,
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),
diff --git a/libempathy-gtk/empathy-images.h b/libempathy-gtk/empathy-images.h
index 227ebe599..ad6d43b28 100644
--- a/libempathy-gtk/empathy-images.h
+++ b/libempathy-gtk/empathy-images.h
@@ -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_PENDING "empathy-pending"
+#define EMPATHY_IMAGE_UNKNOWN "empathy-pending"
#define EMPATHY_IMAGE_MESSAGE "empathy-message"
#define EMPATHY_IMAGE_NEW_MESSAGE "empathy-new-message"
diff --git a/libempathy-gtk/empathy-main-window.c b/libempathy-gtk/empathy-main-window.c
index 13c578d89..4b89c4e67 100644
--- a/libempathy-gtk/empathy-main-window.c
+++ b/libempathy-gtk/empathy-main-window.c
@@ -288,7 +288,6 @@ empathy_main_window_show (void)
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);
diff --git a/libempathy-gtk/empathy-private-chat.c b/libempathy-gtk/empathy-private-chat.c
index 81f93c021..b187e98cd 100644
--- a/libempathy-gtk/empathy-private-chat.c
+++ b/libempathy-gtk/empathy-private-chat.c
@@ -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-contact-manager.h>
+#include <libempathy/empathy-contact-factory.h>
#include "empathy-private-chat.h"
#include "empathy-chat-view.h"
@@ -51,11 +51,12 @@
#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);
@@ -125,7 +126,9 @@ private_chat_finalize (GObject *object)
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);
@@ -327,27 +330,30 @@ EmpathyPrivateChat *
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);
- 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);
- 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);
- g_object_unref (manager);
+ g_object_unref (factory);
return chat;
}
diff --git a/libempathy-gtk/empathy-status-icon.c b/libempathy-gtk/empathy-status-icon.c
index 1ec1a21a5..1fdc00953 100644
--- a/libempathy-gtk/empathy-status-icon.c
+++ b/libempathy-gtk/empathy-status-icon.c
@@ -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);
-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,
+ gboolean is_pending,
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;
- GList *pending, *l;
+ GList *pendings, *l;
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->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);
- 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;
- 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
@@ -533,10 +540,13 @@ status_icon_show_hide_window_cb (GtkWidget *widget,
}
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;
@@ -545,6 +555,11 @@ status_icon_local_pending_cb (EmpathyContactManager *manager,
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;
diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c
index fb491cc5e..aedacb08b 100644
--- a/libempathy-gtk/empathy-ui-utils.c
+++ b/libempathy-gtk/empathy-ui-utils.c
@@ -378,8 +378,7 @@ empathy_icon_name_for_presence (EmpathyPresence *presence)
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);
@@ -389,12 +388,7 @@ empathy_icon_name_for_contact (EmpathyContact *contact)
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
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am
index 39dfa9b62..c24a16f21 100644
--- a/libempathy/Makefile.am
+++ b/libempathy/Makefile.am
@@ -17,7 +17,6 @@ lib_LTLIBRARIES = libempathy.la
libempathy_la_SOURCES = \
empathy-conf.c \
- empathy-contact.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-contact.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 \
@@ -50,7 +51,6 @@ libempathy_la_LDFLAGS = \
libempathy_headers = \
empathy-conf.h \
- empathy-contact.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-contact.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 \
diff --git a/libempathy/empathy-avatar.c b/libempathy/empathy-avatar.c
index e5a2a73a9..425f23f55 100644
--- a/libempathy/empathy-avatar.c
+++ b/libempathy/empathy-avatar.c
@@ -28,7 +28,7 @@
#define DEBUG_DOMAIN "Avatar"
GType
-empathy_avatar_get_gtype (void)
+empathy_avatar_get_type (void)
{
static GType type_id = 0;
diff --git a/libempathy/empathy-avatar.h b/libempathy/empathy-avatar.h
index 73d69cf79..6b28e8e7a 100644
--- a/libempathy/empathy-avatar.h
+++ b/libempathy/empathy-avatar.h
@@ -25,7 +25,7 @@
G_BEGIN_DECLS
-#define EMPATHY_TYPE_AVATAR (empathy_avatar_get_gtype ())
+#define EMPATHY_TYPE_AVATAR (empathy_avatar_get_type ())
typedef struct _EmpathyAvatar EmpathyAvatar;
@@ -36,7 +36,7 @@ struct _EmpathyAvatar {
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);
diff --git a/libempathy/empathy-contact-factory.c b/libempathy/empathy-contact-factory.c
new file mode 100644
index 000000000..1c91a65b6
--- /dev/null
+++ b/libempathy/empathy-contact-factory.c
@@ -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
index 000000000..1379371ab
--- /dev/null
+++ b/libempathy/empathy-contact-factory.h
@@ -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__ */
diff --git a/libempathy/empathy-contact-list.c b/libempathy/empathy-contact-list.c
index cc388d7ec..80308314e 100644
--- a/libempathy/empathy-contact-list.c
+++ b/libempathy/empathy-contact-list.c
@@ -53,149 +53,154 @@ contact_list_base_init (gpointer klass)
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_cclosure_marshal_VOID__OBJECT,
+ empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING_BOOLEAN,
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_cclosure_marshal_VOID__OBJECT,
+ empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING_BOOLEAN,
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,
- empathy_marshal_VOID__OBJECT_STRING,
+ empathy_marshal_VOID__OBJECT_STRING_BOOLEAN,
G_TYPE_NONE,
- 2, EMPATHY_TYPE_CONTACT, G_TYPE_STRING);
+ 3, EMPATHY_TYPE_CONTACT, G_TYPE_STRING, G_TYPE_BOOLEAN);
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
-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
-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 (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);
- 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;
}
-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 *
-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 (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;
}
-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
-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 (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);
}
}
diff --git a/libempathy/empathy-contact-list.h b/libempathy/empathy-contact-list.h
index 959f5c51f..4b027f083 100644
--- a/libempathy/empathy-contact-list.h
+++ b/libempathy/empathy-contact-list.h
@@ -26,6 +26,7 @@
#include <glib-object.h>
#include "empathy-contact.h"
+#include "empathy-tp-group.h"
G_BEGIN_DECLS
@@ -37,49 +38,53 @@ G_BEGIN_DECLS
typedef struct _EmpathyContactList EmpathyContactList;
typedef struct _EmpathyContactListIface EmpathyContactListIface;
-typedef struct {
- EmpathyContact *contact;
- gchar *message;
-} EmpathyContactListInfo;
-
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
diff --git a/libempathy/empathy-contact-manager.c b/libempathy/empathy-contact-manager.c
index cc00108c8..575814fab 100644
--- a/libempathy/empathy-contact-manager.c
+++ b/libempathy/empathy-contact-manager.c
@@ -39,100 +39,171 @@
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
-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
-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
@@ -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) {
- 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);
}
-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)
{
@@ -194,62 +250,28 @@ empathy_contact_manager_new (void)
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 (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,
- EmpathyContact *contact,
+ 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));
- 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);
@@ -264,14 +286,11 @@ contact_manager_remove (EmpathyContactList *manager,
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));
- 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);
@@ -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)
{
- EmpathyContactManagerPriv *priv;
+ EmpathyContactManagerPriv *priv = GET_PRIV (manager);
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);
@@ -298,337 +326,169 @@ contact_manager_get_members (EmpathyContactList *manager)
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
-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 (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);
- priv = GET_PRIV (manager);
-
g_hash_table_foreach (priv->lists,
- (GHFunc) contact_manager_get_groups_foreach,
+ (GHFunc) contact_manager_get_all_groups_foreach,
&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
-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
-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;
- 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
-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
-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
-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;
}
diff --git a/libempathy/empathy-contact-manager.h b/libempathy/empathy-contact-manager.h
index 768301ae7..41144cf43 100644
--- a/libempathy/empathy-contact-manager.h
+++ b/libempathy/empathy-contact-manager.h
@@ -51,19 +51,10 @@ struct _EmpathyContactManagerClass {
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
diff --git a/libempathy/empathy-contact.c b/libempathy/empathy-contact.c
index d3935ad6c..505e190c0 100644
--- a/libempathy/empathy-contact.c
+++ b/libempathy/empathy-contact.c
@@ -1,6 +1,7 @@
/* -*- 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
@@ -19,6 +20,7 @@
*
* Authors: Mikael Hallendal <micke@imendio.com>
* Martyn Russell <martyn@imendio.com>
+ * Xavier Claessens <xclaesse@gmail.com>
*/
#include "config.h"
@@ -41,26 +43,26 @@ typedef struct _EmpathyContactPriv EmpathyContactPriv;
struct _EmpathyContactPriv {
gchar *id;
gchar *name;
- EmpathyAvatar *avatar;
+ EmpathyAvatar *avatar;
McAccount *account;
- EmpathyPresence *presence;
- GList *groups;
- EmpathySubscription subscription;
+ EmpathyPresence *presence;
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,
@@ -75,41 +77,12 @@ enum {
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
-contact_class_init (EmpathyContactClass *class)
+empathy_contact_class_init (EmpathyContactClass *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;
@@ -156,23 +129,6 @@ contact_class_init (EmpathyContactClass *class)
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",
"Contact Handle",
@@ -193,7 +149,7 @@ contact_class_init (EmpathyContactClass *class)
}
static void
-contact_init (EmpathyContact *contact)
+empathy_contact_init (EmpathyContact *contact)
{
}
@@ -217,16 +173,11 @@ contact_finalize (GObject *object)
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);
}
- (G_OBJECT_CLASS (parent_class)->finalize) (object);
+ G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
}
static void
@@ -257,12 +208,6 @@ contact_get_property (GObject *object,
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;
@@ -306,14 +251,6 @@ contact_set_property (GObject *object,
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));
@@ -338,8 +275,8 @@ empathy_contact_new (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,
@@ -364,107 +301,6 @@ empathy_contact_get_id (EmpathyContact *contact)
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)
@@ -486,6 +322,22 @@ empathy_contact_set_id (EmpathyContact *contact,
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)
@@ -507,6 +359,18 @@ empathy_contact_set_name (EmpathyContact *contact,
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)
@@ -533,9 +397,21 @@ empathy_contact_set_avatar (EmpathyContact *contact,
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,
- McAccount *account)
+ McAccount *account)
{
EmpathyContactPriv *priv;
@@ -556,9 +432,21 @@ empathy_contact_set_account (EmpathyContact *contact,
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,
- EmpathyPresence *presence)
+ EmpathyPresence *presence)
{
EmpathyContactPriv *priv;
@@ -582,34 +470,21 @@ empathy_contact_set_presence (EmpathyContact *contact,
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;
- 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);
- 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
-empathy_contact_set_subscription (EmpathyContact *contact,
- EmpathySubscription subscription)
+empathy_contact_set_handle (EmpathyContact *contact,
+ guint handle)
{
EmpathyContactPriv *priv;
@@ -617,32 +492,25 @@ empathy_contact_set_subscription (EmpathyContact *contact,
priv = GET_PRIV (contact);
- if (priv->subscription == subscription) {
+ if (priv->handle == handle) {
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;
- g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
priv = GET_PRIV (contact);
- if (priv->handle == handle) {
- return;
- }
-
- priv->handle = handle;
-
- g_object_notify (G_OBJECT (contact), "handle");
+ return priv->is_user;
}
void
@@ -664,43 +532,6 @@ empathy_contact_set_is_user (EmpathyContact *contact,
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)
{
@@ -717,24 +548,6 @@ empathy_contact_is_online (EmpathyContact *contact)
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)
{
diff --git a/libempathy/empathy-contact.h b/libempathy/empathy-contact.h
index b32d451bb..87a26f0dd 100644
--- a/libempathy/empathy-contact.h
+++ b/libempathy/empathy-contact.h
@@ -1,6 +1,7 @@
/* -*- 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
@@ -16,6 +17,10 @@
* 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__
@@ -30,7 +35,7 @@
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))
@@ -48,57 +53,37 @@ struct _EmpathyContactClass {
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
diff --git a/libempathy/empathy-log-manager.c b/libempathy/empathy-log-manager.c
index e234ec521..e47f50fb8 100644
--- a/libempathy/empathy-log-manager.c
+++ b/libempathy/empathy-log-manager.c
@@ -634,24 +634,22 @@ log_manager_get_dir (EmpathyLogManager *manager,
{
const gchar *account_id;
gchar *basedir;
- gchar *str;
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,
- str,
+ log_manager_get_basedir (manager),
+ account_id,
LOG_DIR_CHATROOMS,
+ chat_id,
NULL);
- g_free (str);
} else {
- basedir = str;
+ basedir = g_build_path (G_DIR_SEPARATOR_S,
+ log_manager_get_basedir (manager),
+ account_id,
+ chat_id,
+ NULL);
}
return basedir;
diff --git a/libempathy/empathy-marshal.list b/libempathy/empathy-marshal.list
index 3b36b7be0..383bfbbed 100644
--- a/libempathy/empathy-marshal.list
+++ b/libempathy/empathy-marshal.list
@@ -1,10 +1,14 @@
VOID:OBJECT,UINT
-VOID:OBJECT,OBJECT
-VOID:OBJECT,OBJECT,UINT
VOID:OBJECT,BOOLEAN
-VOID:OBJECT,STRING,STRING
+VOID:OBJECT,POINTER
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
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 077afe36e..fc943f0c6 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -31,8 +31,7 @@
#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"
@@ -44,8 +43,8 @@
#define DEBUG_DOMAIN "TpChat"
struct _EmpathyTpChatPriv {
- EmpathyTpContactList *list;
- EmpathyContactManager *manager;
+ EmpathyContactFactory *factory;
+ EmpathyContact *user;
McAccount *account;
gchar *id;
MissionControl *mc;
@@ -363,11 +362,11 @@ tp_chat_finalize (GObject *object)
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);
@@ -392,10 +391,9 @@ tp_chat_constructor (GType type,
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 ();
- g_object_ref (priv->list);
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);
- 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;
}
@@ -885,7 +881,9 @@ tp_chat_state_changed_cb (DBusGProxy *chat_state_iface,
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),
@@ -906,22 +904,21 @@ tp_chat_build_message (EmpathyTpChat *chat,
EmpathyTpChatPriv *priv;
EmpathyMessage *message;
EmpathyContact *sender;
- EmpathyContact *receiver;
priv = GET_PRIV (chat);
- receiver = empathy_tp_contact_list_get_user (priv->list);
if (from_handle == 0) {
- sender = g_object_ref (receiver);
+ sender = g_object_ref (priv->user);
} 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);
- empathy_message_set_receiver (message, receiver);
+ empathy_message_set_receiver (message, priv->user);
empathy_message_set_timestamp (message, (EmpathyTime) timestamp);
g_object_unref (sender);
diff --git a/libempathy/empathy-tp-chatroom.c b/libempathy/empathy-tp-chatroom.c
index 32716865d..72f083942 100644
--- a/libempathy/empathy-tp-chatroom.c
+++ b/libempathy/empathy-tp-chatroom.c
@@ -23,9 +23,8 @@
#include <config.h>
#include "empathy-tp-chatroom.h"
-#include "empathy-tp-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"
@@ -36,8 +35,7 @@
#define DEBUG_DOMAIN "TpChatroom"
struct _EmpathyTpChatroomPriv {
- EmpathyContactManager *manager;
- EmpathyTpContactList *list;
+ EmpathyContactFactory *factory;
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_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,
- 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,
- 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);
@@ -89,8 +84,6 @@ empathy_tp_chatroom_class_init (EmpathyTpChatroomClass *klass)
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;
@@ -111,7 +104,7 @@ tp_chatroom_finalize (GObject *object)
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);
@@ -129,7 +122,7 @@ empathy_tp_chatroom_new (McAccount *account,
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);
@@ -141,40 +134,41 @@ empathy_tp_chatroom_new (McAccount *account,
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);
- 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);
- 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 */
- 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) {
- EmpathyTpGroupInfo *info;
+ EmpathyPendingInfo *info;
info = l->data;
- if (info->member != self_handle) {
+ if (!empathy_contact_equal (user, info->member)) {
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;
- 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;
}
@@ -204,7 +198,7 @@ void
empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom)
{
EmpathyTpChatroomPriv *priv;
- guint self_handle;
+ EmpathyContact *user;
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 */
- 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)
{
+ /* FIXME: not implemented */
}
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
-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
@@ -308,9 +264,7 @@ tp_chatroom_add (EmpathyContactList *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
@@ -325,26 +279,18 @@ tp_chatroom_remove (EmpathyContactList *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;
- GArray *members;
- GList *contacts;
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);
}
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index a5c54b74e..16ecad807 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -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-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"
@@ -44,906 +41,305 @@
EMPATHY_TYPE_TP_CONTACT_LIST, EmpathyTpContactListPriv))
#define DEBUG_DOMAIN "TpContactList"
-#define MAX_AVATAR_REQUESTS 10
struct _EmpathyTpContactListPriv {
TpConn *tp_conn;
McAccount *account;
MissionControl *mc;
- EmpathyContact *user_contact;
- gboolean setup;
const gchar *protocol_group;
EmpathyTpGroup *publish;
EmpathyTpGroup *subscribe;
-
- GHashTable *groups;
- GHashTable *contacts;
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,
- TP_CONTACT_LIST_TYPE_UNKNOWN,
- TP_CONTACT_LIST_TYPE_COUNT
+ TP_CONTACT_LIST_TYPE_UNKNOWN
} 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);
+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);
enum {
DESTROY,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL];
-GList *avatar_requests_queue = NULL;
-guint n_avatar_requests = 0;
+static guint signals[LAST_SIGNAL];
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)
+tp_contact_list_group_destroy_cb (EmpathyTpGroup *group,
+ EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
- priv = GET_PRIV (list);
+ empathy_debug (DEBUG_DOMAIN, "Group destroyed: %s",
+ empathy_tp_group_get_name (group));
- 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);
+ priv->groups = g_list_remove (priv->groups, group);
+ g_object_unref (group);
}
static void
-tp_contact_list_finalize (GObject *object)
+tp_contact_list_group_member_added_cb (EmpathyTpGroup *group,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ const gchar *message,
+ EmpathyTpContactList *list)
{
- 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);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ const gchar *group_name;
+ GList **groups;
- 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 (!g_list_find (priv->members, contact)) {
+ return;
}
- if (priv->presence_iface) {
- dbus_g_proxy_connect_signal (priv->presence_iface,
- "PresenceUpdate",
- G_CALLBACK (tp_contact_list_presence_update_cb),
- list, NULL);
+ 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);
}
- /* 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);
+ 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);
}
-
- return list;
}
static void
-tp_contact_list_setup (EmpathyContactList *list)
+tp_contact_list_group_member_removed_cb (EmpathyTpGroup *group,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ const gchar *message,
+ EmpathyTpContactList *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);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ const gchar *group_name;
+ GList **groups, *l;
- /* 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);
+ if (!g_list_find (priv->members, contact)) {
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);
+ groups = g_hash_table_lookup (priv->contacts_groups, contact);
+ if (!groups) {
+ return;
}
- 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;
-
- 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);
+ 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);
}
}
-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)
+static EmpathyTpGroup *
+tp_contact_list_find_group (EmpathyTpContactList *list,
+ const gchar *group)
{
- EmpathyTpContactListPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ GList *l;
- priv = GET_PRIV (list);
-
- return priv->user_contact;
+ for (l = priv->groups; l; l = l->next) {
+ if (strcmp (group, empathy_tp_group_get_name (l->data)) == 0) {
+ return l->data;
+ }
+ }
+ return NULL;
}
-EmpathyContact *
-empathy_tp_contact_list_get_from_id (EmpathyTpContactList *list,
- const gchar *id)
+static TpContactListType
+tp_contact_list_get_type (EmpathyTpContactList *list,
+ EmpathyTpGroup *group)
{
EmpathyTpContactListPriv *priv;
- EmpathyContact *contact;
- const gchar *contact_ids[] = {id, NULL};
- GArray *handles;
- guint handle;
- GError *error = NULL;
+ TpContactListType list_type;
+ const gchar *name;
- 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;
+ name = empathy_tp_group_get_name (group);
+ if (strcmp (name, "subscribe") == 0) {
+ list_type = TP_CONTACT_LIST_TYPE_SUBSCRIBE;
+ } else if (strcmp (name, "publish") == 0) {
+ list_type = TP_CONTACT_LIST_TYPE_PUBLISH;
+ } else {
+ list_type = TP_CONTACT_LIST_TYPE_UNKNOWN;
}
- contact = contacts->data;
- g_list_free (contacts);
-
- return contact;
+ return list_type;
}
-GList *
-empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list,
- GArray *handles)
+static void
+tp_contact_list_add_member (EmpathyTpContactList *list,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ const gchar *message)
{
- 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);
- }
- }
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ GList *l;
- if (new_handles->len == 0) {
- g_array_free (new_handles, TRUE);
- return contacts;
- }
+ /* 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);
- /* 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;
+ /* This contact is now member, implicitly accept pending. */
+ if (g_list_find (priv->pendings, contact)) {
+ empathy_tp_group_add_member (priv->publish, contact, "");
}
- /* 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);
+ /* 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);
}
-
- 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)
+static void
+tp_contact_list_added_cb (EmpathyTpGroup *group,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ const gchar *message,
+ EmpathyTpContactList *list)
{
- 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));
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ TpContactListType list_type;
- /* 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, "");
+ list_type = tp_contact_list_get_type (list, group);
+ 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);
}
}
-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)
+tp_contact_list_removed_cb (EmpathyTpGroup *group,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ const gchar *message,
+ 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);
- }
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ TpContactListType list_type;
- if (priv->avatars_iface) {
- dbus_g_proxy_disconnect_signal (priv->avatars_iface,
- "AvatarUpdated",
- G_CALLBACK (tp_contact_list_avatar_update_cb),
- list);
+ list_type = tp_contact_list_get_type (list, group);
+ 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);
}
- if (priv->presence_iface) {
- dbus_g_proxy_disconnect_signal (priv->presence_iface,
- "PresenceUpdate",
- G_CALLBACK (tp_contact_list_presence_update_cb),
- 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_destroy_cb (DBusGProxy *proxy,
+tp_contact_list_pending_cb (EmpathyTpGroup *group,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ const gchar *message,
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);
-}
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ TpContactListType list_type;
-static gboolean
-tp_contact_list_find_foreach (guint handle,
- EmpathyContact *contact,
- gchar *id)
-{
- if (strcmp (empathy_contact_get_id (contact), id) == 0) {
- return TRUE;
+ list_type = tp_contact_list_get_type (list, group);
+ 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);
+ }
}
-
- return FALSE;
}
static void
@@ -955,17 +351,13 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy,
gboolean suppress_handle,
EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
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) {
+ suppress_handle) {
return;
}
@@ -973,962 +365,629 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy,
new_chan = tp_chan_new (tp_get_bus (),
bus_name,
object_path,
- channel_type, handle_type, channel_handle);
+ 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);
+ g_object_unref (new_chan);
- group = empathy_tp_group_new (priv->account, new_chan);
+ if (handle_type == TP_HANDLE_TYPE_LIST) {
+ TpContactListType list_type;
+ GList *contacts, *l;
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);
-
- if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) {
- GList *pendings, *l;
-
- if (priv->publish) {
- g_object_unref (priv->publish);
- }
+ if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH && !priv->publish) {
priv->publish = group;
- /* Makes no sense to be in remote-pending */
+ /* 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);
- 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);
+ 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);
}
- if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE) {
- GArray *remote_pendings = NULL;
-
- if (priv->subscribe) {
- g_object_unref (priv->subscribe);
- }
+ else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE && !priv->subscribe) {
priv->subscribe = group;
- /* Makes no sense to be in local-pending */
+ /* 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);
- 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);
+
+ 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 {
- members = empathy_tp_group_get_members (group);
+ 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);
+
+ 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);
- tp_contact_list_added_cb (group, members, 0,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
- NULL, list);
- g_array_free (members, TRUE);
+ 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 *object_path;
+ const gchar *group_name;
+ GList *contacts, *l;
- 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);
+ /* 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;
}
- group = empathy_tp_group_new (priv->account, new_chan);
-
empathy_debug (DEBUG_DOMAIN, "New server-side group channel: %s",
- empathy_tp_group_get_name (group));
+ group_name);
- dbus_g_proxy_connect_signal (DBUS_G_PROXY (new_chan), "Closed",
- G_CALLBACK
- (tp_contact_list_group_channel_closed_cb),
- list, NULL);
+ priv->groups = g_list_prepend (priv->groups, group);
- 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),
+ g_signal_connect (group, "member-added",
+ G_CALLBACK (tp_contact_list_group_member_added_cb),
list);
- g_signal_connect (group, "members-removed",
- G_CALLBACK (tp_contact_list_group_members_removed_cb),
+ 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);
- 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);
+ 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_object_unref (new_chan);
}
-static TpContactListType
-tp_contact_list_get_type (EmpathyTpContactList *list,
- EmpathyTpGroup *group)
+static void
+tp_contact_list_remove_all (EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
- TpContactListType list_type;
- const gchar *name;
-
- priv = GET_PRIV (list);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ GList *l;
- name = empathy_tp_group_get_name (group);
- if (strcmp (name, "subscribe") == 0) {
- list_type = TP_CONTACT_LIST_TYPE_SUBSCRIBE;
- } else if (strcmp (name, "publish") == 0) {
- list_type = TP_CONTACT_LIST_TYPE_PUBLISH;
- } else {
- list_type = TP_CONTACT_LIST_TYPE_UNKNOWN;
+ 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);
+ }
+ 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);
}
- return list_type;
+ g_list_free (priv->members);
+ g_list_free (priv->pendings);
+ priv->members = NULL;
+ priv->pendings = NULL;
}
static void
-tp_contact_list_added_cb (EmpathyTpGroup *group,
- GArray *handles,
- guint actor_handle,
- guint reason,
- const gchar *message,
- EmpathyTpContactList *list)
+tp_contact_list_destroy_cb (TpConn *tp_conn,
+ EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
- GList *added_list, *l;
- TpContactListType list_type;
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
- priv = GET_PRIV (list);
+ empathy_debug (DEBUG_DOMAIN, "Account disconnected or CM crashed");
- 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);
+ /* DBus proxie should NOT be used anymore */
+ g_object_unref (priv->tp_conn);
+ priv->tp_conn = NULL;
- 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_remove_all (list);
- tp_contact_list_block_contact (list, contact);
- empathy_contact_set_subscription (contact, subscription);
- tp_contact_list_unblock_contact (list, contact);
+ /* Tell the world to not use us anymore */
+ g_signal_emit (list, signals[DESTROY], 0);
+}
- 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);
- }
- }
+static void
+tp_contact_list_disconnect (EmpathyTpContactList *list)
+{
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
- g_object_unref (contact);
+ 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);
}
-
- g_list_free (added_list);
}
static void
-tp_contact_list_removed_cb (EmpathyTpGroup *group,
- GArray *handles,
- guint actor_handle,
- guint reason,
- const gchar *message,
- EmpathyTpContactList *list)
+tp_contact_list_status_changed_cb (MissionControl *mc,
+ TelepathyConnectionStatus status,
+ McPresence presence,
+ TelepathyConnectionStatusReason reason,
+ const gchar *unique_name,
+ EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
- GList *removed_list, *l;
- TpContactListType list_type;
-
- priv = GET_PRIV (list);
-
- 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;
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ McAccount *account;
- 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);
- }
- }
- g_object_unref (contact);
+ 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);
}
- g_list_free (removed_list);
+ g_object_unref (account);
}
static void
-tp_contact_list_pending_cb (EmpathyTpGroup *group,
- GArray *handles,
- guint actor_handle,
- guint reason,
- const gchar *message,
- EmpathyTpContactList *list)
+tp_contact_list_group_list_free (GList **groups)
+{
+ g_list_foreach (*groups, (GFunc) g_free, NULL);
+ g_list_free (*groups);
+ g_slice_free (GList*, groups);
+}
+
+static void
+tp_contact_list_finalize (GObject *object)
{
EmpathyTpContactListPriv *priv;
- GList *pending_list, *l;
- TpContactListType list_type;
+ EmpathyTpContactList *list;
+ list = EMPATHY_TP_CONTACT_LIST (object);
priv = GET_PRIV (list);
- 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);
+ empathy_debug (DEBUG_DOMAIN, "finalize: %p", object);
- g_signal_emit_by_name (list, "local-pending",
- contact, message);
- } else {
- guint handle;
+ tp_contact_list_disconnect (list);
+ tp_contact_list_remove_all (list);
- /* 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);
- }
- }
+ 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);
+ }
- g_object_unref (contact);
+ 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_list_free (pending_list);
+ G_OBJECT_CLASS (empathy_tp_contact_list_parent_class)->finalize (object);
}
static void
-tp_contact_list_remove_local_pending (EmpathyTpContactList *list,
- EmpathyContact *contact)
+empathy_tp_contact_list_class_init (EmpathyTpContactListClass *klass)
{
- EmpathyTpContactListPriv *priv;
- GList *l;
-
- priv = GET_PRIV (list);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- for (l = priv->local_pending; l; l = l->next) {
- EmpathyContactListInfo *info;
+ object_class->finalize = tp_contact_list_finalize;
- 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));
+ 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);
- priv->local_pending = g_list_delete_link (priv->local_pending, l);
- empathy_contact_list_info_free (info);
- break;
- }
- }
+ g_type_class_add_private (object_class, sizeof (EmpathyTpContactListPriv));
}
static void
-tp_contact_list_groups_updated_cb (EmpathyContact *contact,
- GParamSpec *param,
- EmpathyTpContactList *list)
+empathy_tp_contact_list_init (EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
- TpContactListData data;
- GList *groups, *l;
-
- priv = GET_PRIV (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);
- }
-
- data.handle = empathy_contact_get_handle (contact);
- data.new_groups = groups;
-
- g_hash_table_foreach (priv->groups,
- (GHFunc) tp_contact_list_update_groups_foreach,
- &data);
}
static void
-tp_contact_list_name_updated_cb (EmpathyContact *contact,
- GParamSpec *param,
- EmpathyTpContactList *list)
+tp_contact_list_setup (EmpathyTpContactList *list)
{
- EmpathyTpContactListPriv *priv;
- GHashTable *new_alias;
- const gchar *new_name;
- guint handle;
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ GPtrArray *channels;
+ guint i;
GError *error = NULL;
- priv = GET_PRIV (list);
-
- if (!priv->aliasing_iface) {
- return;
- }
-
- handle = empathy_contact_get_handle (contact);
- new_name = empathy_contact_get_name (contact);
-
- empathy_debug (DEBUG_DOMAIN, "renaming handle %d to %s",
- handle, new_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 (new_name));
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
- if (!tp_conn_iface_aliasing_set_aliases (priv->aliasing_iface,
- new_alias,
- &error)) {
- empathy_debug (DEBUG_DOMAIN,
- "Couldn't rename contact: %s",
+ /* 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;
}
- g_hash_table_destroy (new_alias);
-}
-
-static void
-tp_contact_list_update_groups_foreach (gchar *object_path,
- EmpathyTpGroup *group,
- TpContactListData *data)
-{
- 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);
+ for (i = 0; i < channels->len; i++) {
+ GValueArray *chan_struct;
+ const gchar *object_path;
+ const gchar *chan_iface;
+ TelepathyHandleType handle_type;
+ guint handle;
- for (l = data->new_groups; l; l = l->next) {
- if (strcmp (group_name, l->data) == 0) {
- found = TRUE;
- break;
- }
- }
+ 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));
- 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, "");
- }
+ tp_contact_list_newchannel_cb (DBUS_G_PROXY (priv->tp_conn),
+ object_path, chan_iface,
+ handle_type, handle,
+ FALSE,
+ list);
- 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_value_array_free (chan_struct);
}
+ g_ptr_array_free (channels, TRUE);
}
-static EmpathyTpGroup *
-tp_contact_list_get_group (EmpathyTpContactList *list,
- const gchar *name)
+EmpathyTpContactList *
+empathy_tp_contact_list_new (McAccount *account)
{
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;
-
- priv = GET_PRIV (list);
+ EmpathyTpContactList *list;
+ MissionControl *mc;
+ TpConn *tp_conn = NULL;
+ McProfile *profile;
+ const gchar *protocol_name;
- group = g_hash_table_find (priv->groups,
- (GHRFunc) tp_contact_list_find_group,
- (gchar*) name);
- if (group) {
- return group;
- }
+ g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
- empathy_debug (DEBUG_DOMAIN, "creating new group: %s", name);
+ mc = empathy_mission_control_new ();
- 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;
+ /* status==0 means CONNECTED */
+ if (mission_control_get_connection_status (mc, account, NULL) == 0) {
+ tp_conn = mission_control_get_connection (mc, account, NULL);
}
- group_handle = g_array_index (handles, guint, 0);
- g_array_free (handles, TRUE);
-
- 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);
+ if (!tp_conn) {
+ /* The account is not connected, nothing to do. */
+ g_object_unref (mc);
return NULL;
}
- 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);
+ list = g_object_new (EMPATHY_TYPE_TP_CONTACT_LIST, NULL);
+ priv = GET_PRIV (list);
- return group;
-}
+ 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);
-static gboolean
-tp_contact_list_find_group (gchar *key,
- EmpathyTpGroup *group,
- gchar *group_name)
-{
- if (strcmp (group_name, empathy_tp_group_get_name (group)) == 0) {
- return TRUE;
+ /* 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);
- return FALSE;
-}
+ /* 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);
-static void
-tp_contact_list_get_groups_foreach (gchar *key,
- EmpathyTpGroup *group,
- GList **groups)
-{
- const gchar *name;
+ tp_contact_list_setup (list);
- name = empathy_tp_group_get_name (group);
- *groups = g_list_append (*groups, g_strdup (name));
+ return list;
}
-static void
-tp_contact_list_group_channel_closed_cb (TpChan *channel,
- EmpathyTpContactList *list)
+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);
- g_hash_table_remove (priv->groups,
- dbus_g_proxy_get_path (DBUS_G_PROXY (channel)));
+ return priv->account;
}
static void
-tp_contact_list_group_members_added_cb (EmpathyTpGroup *group,
- GArray *members,
- guint actor_handle,
- guint reason,
- const gchar *message,
- EmpathyTpContactList *list)
+tp_contact_list_add (EmpathyContactList *list,
+ EmpathyContact *contact,
+ const gchar *message)
{
- EmpathyTpContactListPriv *priv;
- GList *added_list, *l;
- const gchar *group_name;
-
- priv = GET_PRIV (list);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
- group_name = empathy_tp_group_get_name (group);
- added_list = empathy_tp_contact_list_get_from_handles (list, members);
-
- for (l = added_list; l; l = l->next) {
- EmpathyContact *contact;
-
- contact = EMPATHY_CONTACT (l->data);
-
- tp_contact_list_block_contact (list, contact);
- empathy_contact_add_group (contact, group_name);
- tp_contact_list_unblock_contact (list, contact);
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
- g_object_unref (contact);
+ 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);
}
-
- g_list_free (added_list);
}
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_remove (EmpathyContactList *list,
+ EmpathyContact *contact,
+ const gchar *message)
{
- EmpathyTpContactListPriv *priv;
- GList *removed_list, *l;
- const gchar *group_name;
-
- priv = GET_PRIV (list);
-
- group_name = empathy_tp_group_get_name (group);
- removed_list = empathy_tp_contact_list_get_from_handles (list, members);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
- for (l = removed_list; l; l = l->next) {
- EmpathyContact *contact;
-
- contact = l->data;
-
- tp_contact_list_block_contact (list, contact);
- empathy_contact_remove_group (contact, group_name);
- tp_contact_list_unblock_contact (list, contact);
-
- g_object_unref (contact);
- }
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
- g_list_free (removed_list);
+ empathy_tp_group_remove_member (priv->subscribe, contact, message);
+ empathy_tp_group_remove_member (priv->publish, contact, message);
}
-static void
-tp_contact_list_get_info (EmpathyTpContactList *list,
- GArray *handles)
+static GList *
+tp_contact_list_get_members (EmpathyContactList *list)
{
- EmpathyTpContactListPriv *priv;
- GError *error = NULL;
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
- priv = GET_PRIV (list);
-
- 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);
- }
- }
-
- if (priv->aliasing_iface) {
- TpContactListAliasesRequestData *data;
-
- data = g_slice_new (TpContactListAliasesRequestData);
- data->list = list;
- data->handles = g_memdup (handles->data, handles->len * sizeof (guint));
-
- 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);
- }
-
- if (priv->avatars_iface) {
- guint i;
-
- for (i = 0; i < handles->len; i++) {
- guint handle;
+ g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
- handle = g_array_index (handles, gint, i);
- tp_contact_list_request_avatar (list, handle);
- }
- }
+ g_list_foreach (priv->members, (GFunc) g_object_ref, NULL);
+ return g_list_copy (priv->members);
}
-static void
-tp_contact_list_request_avatar (EmpathyTpContactList *list,
- guint handle)
+static GList *
+tp_contact_list_get_pendings (EmpathyContactList *list)
{
- EmpathyTpContactListPriv *priv;
- TpContactListAvatarRequestData *data;
+ EmpathyTpContactListPriv *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 ();
-}
+ g_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
-static void
-tp_contact_list_start_avatar_requests (void)
-{
- 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);
- }
+ g_list_foreach (priv->pendings, (GFunc) g_object_ref, NULL);
+ return g_list_copy (priv->pendings);
}
-static void
-tp_contact_list_avatar_update_cb (DBusGProxy *proxy,
- guint handle,
- gchar *new_token,
- EmpathyTpContactList *list)
+static GList *
+tp_contact_list_get_all_groups (EmpathyContactList *list)
{
- EmpathyTpContactListPriv *priv;
+ 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);
- if (!g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle))) {
- /* We don't know this contact, skip */
- return;
- }
+ for (l = priv->groups; l; l = l->next) {
+ const gchar *name;
- empathy_debug (DEBUG_DOMAIN, "Changing avatar for %d to %s",
- handle, new_token);
+ name = empathy_tp_group_get_name (l->data);
+ groups = g_list_prepend (groups, g_strdup (name));
+ }
- tp_contact_list_request_avatar (list, handle);
+ return groups;
}
-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_groups (EmpathyContactList *list,
+ EmpathyContact *contact)
{
- EmpathyContact *contact;
-
- contact = empathy_tp_contact_list_get_from_handle (data->list, data->handle);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ GList **groups;
+ GList *ret = NULL, *l;
- 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_return_val_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list), NULL);
- 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);
+ groups = g_hash_table_lookup (priv->contacts_groups, contact);
+ if (!groups) {
+ return NULL;
}
- n_avatar_requests--;
- tp_contact_list_start_avatar_requests ();
+ for (l = *groups; l; l = l->next) {
+ ret = g_list_prepend (ret, g_strdup (l->data));
+ }
- g_object_unref (contact);
- g_object_unref (data->list);
- g_slice_free (TpContactListAvatarRequestData, data);
+ return ret;
}
-static void
-tp_contact_list_aliases_update_cb (DBusGProxy *proxy,
- GPtrArray *renamed_handlers,
- EmpathyTpContactList *list)
+static EmpathyTpGroup *
+tp_contact_list_get_group (EmpathyTpContactList *list,
+ const gchar *group)
{
- EmpathyTpContactListPriv *priv;
- guint i;
-
- priv = GET_PRIV (list);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ EmpathyTpGroup *tp_group;
+ gchar *object_path;
+ guint handle;
+ GArray *handles;
+ const char *names[2] = {group, NULL};
+ GError *error = NULL;
- for (i = 0; renamed_handlers->len > i; i++) {
- guint handle;
- const gchar *alias;
- GValueArray *renamed_struct;
- EmpathyContact *contact;
+ tp_group = tp_contact_list_find_group (list, group);
+ if (tp_group) {
+ return tp_group;
+ }
- 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));
+ empathy_debug (DEBUG_DOMAIN, "creating new group: %s", group);
- if (!g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle))) {
- /* We don't know this contact, skip */
- continue;
- }
+ 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);
- if (G_STR_EMPTY (alias)) {
- alias = NULL;
- }
+ 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;
+ }
- 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);
+ 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);
- empathy_debug (DEBUG_DOMAIN, "contact %d renamed to %s (update cb)",
- handle, alias);
- }
+ return tp_contact_list_find_group (list, group);
}
static void
-tp_contact_list_request_aliases_cb (DBusGProxy *proxy,
- gchar **contact_names,
- GError *error,
- TpContactListAliasesRequestData *data)
+tp_contact_list_add_to_group (EmpathyContactList *list,
+ EmpathyContact *contact,
+ const gchar *group)
{
- guint i = 0;
- gchar **name;
+ EmpathyTpGroup *tp_group;
- if (error) {
- empathy_debug (DEBUG_DOMAIN, "Error requesting aliases: %s",
- error->message);
- }
-
- for (name = contact_names; *name && !error; name++) {
- EmpathyContact *contact;
-
- 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);
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
- i++;
- }
+ tp_group = tp_contact_list_get_group (EMPATHY_TP_CONTACT_LIST (list),
+ group);
- g_free (data->handles);
- g_slice_free (TpContactListAliasesRequestData, data);
+ empathy_tp_group_add_member (tp_group, contact, "");
}
static void
-tp_contact_list_presence_update_cb (DBusGProxy *proxy,
- GHashTable *handle_table,
- EmpathyTpContactList *list)
+tp_contact_list_remove_from_group (EmpathyContactList *list,
+ EmpathyContact *contact,
+ const gchar *group)
{
- g_hash_table_foreach (handle_table,
- (GHFunc) tp_contact_list_parse_presence_foreach,
- list);
-}
+ EmpathyTpGroup *tp_group;
-static void
-tp_contact_list_parse_presence_foreach (guint handle,
- GValueArray *presence_struct,
- EmpathyTpContactList *list)
-{
- EmpathyTpContactListPriv *priv;
- GHashTable *presences_table;
- EmpathyContact *contact;
- EmpathyPresence *presence = NULL;
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
- priv = GET_PRIV (list);
+ tp_group = tp_contact_list_find_group (EMPATHY_TP_CONTACT_LIST (list),
+ group);
- if (!g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle))) {
- /* We don't know this contact, skip */
- return;
+ if (tp_group) {
+ empathy_tp_group_remove_member (tp_group, contact, "");
}
-
- contact = empathy_tp_contact_list_get_from_handle (list, handle);
- presences_table = g_value_get_boxed (g_value_array_get_nth (presence_struct, 1));
-
- 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);
-
- tp_contact_list_block_contact (list, contact);
- empathy_contact_set_presence (contact, presence);
- tp_contact_list_unblock_contact (list, contact);
-
- g_object_unref (contact);
}
static void
-tp_contact_list_presences_table_foreach (const gchar *state_str,
- GHashTable *presences_table,
- EmpathyPresence **presence)
+tp_contact_list_rename_group (EmpathyContactList *list,
+ const gchar *old_group,
+ const gchar *new_group)
{
- McPresence state;
- const GValue *message;
+ EmpathyTpGroup *tp_group;
+ GList *members;
- state = empathy_presence_state_from_str (state_str);
- if ((state == MC_PRESENCE_UNSET) || (state == MC_PRESENCE_OFFLINE)) {
+ g_return_if_fail (EMPATHY_IS_TP_CONTACT_LIST (list));
+
+ tp_group = tp_contact_list_find_group (EMPATHY_TP_CONTACT_LIST (list),
+ old_group);
+ if (!tp_group) {
return;
}
- if (*presence) {
- g_object_unref (*presence);
- *presence = NULL;
- }
+ empathy_debug (DEBUG_DOMAIN, "rename group %s to %s", old_group, new_group);
- *presence = empathy_presence_new ();
- empathy_presence_set_state (*presence, state);
+ /* 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);
- message = g_hash_table_lookup (presences_table, "message");
- if (message != NULL) {
- empathy_presence_set_status (*presence,
- g_value_get_string (message));
- }
+ /* 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_status_changed_cb (MissionControl *mc,
- TelepathyConnectionStatus status,
- McPresence presence,
- TelepathyConnectionStatusReason reason,
- const gchar *unique_name,
- EmpathyTpContactList *list)
+tp_contact_list_iface_init (EmpathyContactListIface *iface)
{
- EmpathyTpContactListPriv *priv;
- McAccount *account;
-
- priv = GET_PRIV (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);
- 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);
-
- g_object_unref (account);
+ 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;
}
diff --git a/libempathy/empathy-tp-contact-list.h b/libempathy/empathy-tp-contact-list.h
index f0eccb375..6ac4662fa 100644
--- a/libempathy/empathy-tp-contact-list.h
+++ b/libempathy/empathy-tp-contact-list.h
@@ -50,20 +50,9 @@ struct _EmpathyTpContactListClass {
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
diff --git a/libempathy/empathy-tp-group.c b/libempathy/empathy-tp-group.c
index b86a00e28..1ffab9ecd 100644
--- a/libempathy/empathy-tp-group.c
+++ b/libempathy/empathy-tp-group.c
@@ -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>
+ * 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
@@ -16,18 +17,22 @@
* 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 <libtelepathy/tp-chan-gen.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-contact-factory.h"
+#include "empathy-debug.h"
#include "empathy-utils.h"
#include "empathy-marshal.h"
@@ -37,32 +42,27 @@
#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 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 {
- MEMBERS_ADDED,
- MEMBERS_REMOVED,
+ MEMBER_ADDED,
+ MEMBER_REMOVED,
LOCAL_PENDING,
REMOTE_PENDING,
+ DESTROY,
LAST_SIGNAL
};
@@ -70,6 +70,409 @@ static guint signals[LAST_SIGNAL];
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)
{
@@ -77,25 +480,25 @@ empathy_tp_group_class_init (EmpathyTpGroupClass *klass)
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,
- empathy_marshal_VOID__POINTER_UINT_UINT_STRING,
+ empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
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,
- empathy_marshal_VOID__POINTER_UINT_UINT_STRING,
+ empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
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",
@@ -103,9 +506,9 @@ empathy_tp_group_class_init (EmpathyTpGroupClass *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,
- 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",
@@ -113,9 +516,19 @@ empathy_tp_group_class_init (EmpathyTpGroupClass *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,
- 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));
}
@@ -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)
@@ -162,6 +545,7 @@ empathy_tp_group_new (McAccount *account,
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);
@@ -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->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);
- 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);
+ 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;
}
+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,
- GArray *handles,
+ GList *contacts,
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 (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,
- guint handle,
+ EmpathyContact *contact,
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);
- 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,
- GArray *handles,
+ GList *contacts,
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 (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,
- guint handle,
+ EmpathyContact *contact,
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);
- 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);
}
-GArray *
+GList *
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 *
-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;
-
- 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 *
@@ -443,35 +770,21 @@ empathy_tp_group_get_name (EmpathyTpGroup *group)
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;
}
-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 *
@@ -488,21 +801,10 @@ empathy_tp_group_get_object_path (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;
}
diff --git a/libempathy/empathy-tp-group.h b/libempathy/empathy-tp-group.h
index 5ea7bfc71..14cbd4649 100644
--- a/libempathy/empathy-tp-group.h
+++ b/libempathy/empathy-tp-group.h
@@ -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>
+ * 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
@@ -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.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
*/
#ifndef __EMPATHY_TP_GROUP_H__
@@ -24,8 +27,11 @@
#include <glib.h>
#include <libtelepathy/tp-chan.h>
+#include <libtelepathy/tp-constants.h>
#include <libmissioncontrol/mc-account.h>
+#include "empathy-contact.h"
+
G_BEGIN_DECLS
#define EMPATHY_TYPE_TP_GROUP (empathy_tp_group_get_type ())
@@ -48,39 +54,40 @@ struct _EmpathyTpGroupClass {
};
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
diff --git a/python/README b/python/README
new file mode 100644
index 000000000..f9c121b5f
--- /dev/null
+++ b/python/README
@@ -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.
diff --git a/python/pyempathy/pyempathy.defs b/python/pyempathy/pyempathy.defs
index eea0b76d3..97f7b6ac9 100644
--- a/python/pyempathy/pyempathy.defs
+++ b/python/pyempathy/pyempathy.defs
@@ -43,6 +43,13 @@
(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")
@@ -116,20 +123,15 @@
(gtype-id "EMPATHY_TYPE_TP_GROUP")
)
-;; Enumerations and flags ...
-
-(define-flags Subscription
+(define-object TpRoomlist
(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")
@@ -159,8 +161,8 @@
;; 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")
)
@@ -189,23 +191,6 @@
-;; 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
@@ -225,73 +210,6 @@
-;; 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
@@ -391,6 +309,73 @@
+;; 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
@@ -510,198 +495,74 @@
-;; 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")
)
-(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
- '("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*")
(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")
+ '("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")
+ '("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")
- '("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
- '("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
-(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")
)
@@ -730,40 +591,73 @@
(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 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 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_presence
+(define-method set_account
(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")
- (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")
- (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
@@ -772,146 +666,166 @@
(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 set_id
+(define-method set_is_user
(of-object "EmpathyContact")
- (c-name "empathy_contact_set_id")
+ (c-name "empathy_contact_set_is_user")
(return-type "none")
(parameters
- '("const-gchar*" "id")
+ '("gboolean" "is_user")
)
)
-(define-method set_name
+(define-method is_online
(of-object "EmpathyContact")
- (c-name "empathy_contact_set_name")
- (return-type "none")
- (parameters
- '("const-gchar*" "name")
- )
+ (c-name "empathy_contact_is_online")
+ (return-type "gboolean")
)
-(define-method set_avatar
+(define-method get_status
(of-object "EmpathyContact")
- (c-name "empathy_contact_set_avatar")
- (return-type "none")
- (parameters
- '("EmpathyAvatar*" "avatar")
- )
+ (c-name "empathy_contact_get_status")
+ (return-type "const-gchar*")
)
-(define-method set_account
- (of-object "EmpathyContact")
- (c-name "empathy_contact_set_account")
- (return-type "none")
+(define-function empathy_contact_equal
+ (c-name "empathy_contact_equal")
+ (return-type "gboolean")
(parameters
- '("McAccount*" "account")
+ '("gconstpointer" "v1")
+ '("gconstpointer" "v2")
)
)
-(define-method set_presence
- (of-object "EmpathyContact")
- (c-name "empathy_contact_set_presence")
- (return-type "none")
+(define-function empathy_contact_hash
+ (c-name "empathy_contact_hash")
+ (return-type "guint")
(parameters
- '("EmpathyPresence*" "presence")
+ '("gconstpointer" "key")
)
)
-(define-method set_groups
- (of-object "EmpathyContact")
- (c-name "empathy_contact_set_groups")
- (return-type "none")
- (parameters
- '("GList*" "categories")
- )
+
+
+;; 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_subscription
- (of-object "EmpathyContact")
- (c-name "empathy_contact_set_subscription")
+(define-method add
+ (of-object "EmpathyContactList")
+ (c-name "empathy_contact_list_add")
(return-type "none")
(parameters
- '("EmpathySubscription" "subscription")
+ '("EmpathyContact*" "contact")
+ '("const-gchar*" "message")
)
)
-(define-method set_handle
- (of-object "EmpathyContact")
- (c-name "empathy_contact_set_handle")
+(define-method remove
+ (of-object "EmpathyContactList")
+ (c-name "empathy_contact_list_remove")
(return-type "none")
(parameters
- '("guint" "handle")
+ '("EmpathyContact*" "contact")
+ '("const-gchar*" "message")
)
)
-(define-method set_is_user
- (of-object "EmpathyContact")
- (c-name "empathy_contact_set_is_user")
- (return-type "none")
+(define-method get_members
+ (of-object "EmpathyContactList")
+ (c-name "empathy_contact_list_get_members")
+ (return-type "GList*")
+)
+
+(define-method get_pendings
+ (of-object "EmpathyContactList")
+ (c-name "empathy_contact_list_get_pendings")
+ (return-type "GList*")
+)
+
+(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
- '("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
+ '("EmpathyContact*" "contact")
'("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
+ '("EmpathyContact*" "contact")
'("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
- '("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
- '("gconstpointer" "key")
+ '("McAccount*" "account")
)
)
@@ -929,21 +843,9 @@
(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")
- (parameters
- '("GClosure*" "closure")
- '("GValue*" "return_value")
- '("guint" "n_param_values")
- '("const-GValue*" "param_values")
- '("gpointer" "invocation_hint")
- '("gpointer" "marshal_data")
- )
)
@@ -1096,6 +998,15 @@
)
)
+(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")
@@ -1119,6 +1030,15 @@
)
)
+(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")
@@ -1155,10 +1075,6 @@
-;; From empathy-marshal.h
-
-
-
;; From empathy-message.h
(define-function empathy_message_get_gtype
@@ -1250,6 +1166,20 @@
)
)
+(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
@@ -1535,55 +1465,6 @@
(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
@@ -1598,17 +1479,23 @@
(is-constructor-of "EmpathyTpGroup")
(return-type "EmpathyTpGroup*")
(parameters
+ '("McAccount*" "account")
'("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
- '("GArray*" "handles")
+ '("GList*" "contacts")
'("const-gchar*" "message")
)
)
@@ -1618,7 +1505,7 @@
(c-name "empathy_tp_group_add_member")
(return-type "none")
(parameters
- '("guint" "handle")
+ '("EmpathyContact*" "contact")
'("const-gchar*" "message")
)
)
@@ -1628,7 +1515,7 @@
(c-name "empathy_tp_group_remove_members")
(return-type "none")
(parameters
- '("GArray*" "handle")
+ '("GList*" "contacts")
'("const-gchar*" "message")
)
)
@@ -1638,7 +1525,7 @@
(c-name "empathy_tp_group_remove_member")
(return-type "none")
(parameters
- '("guint" "handle")
+ '("EmpathyContact*" "contact")
'("const-gchar*" "message")
)
)
@@ -1646,44 +1533,31 @@
(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")
- (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")
- (c-name "empathy_tp_group_get_local_pending_members_with_info")
+ (c-name "empathy_tp_group_get_remote_pendings")
(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_self_handle
+(define-method get_self_contact
(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
@@ -1697,10 +1571,63 @@
(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
@@ -1805,8 +1732,18 @@
(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")
@@ -1814,3 +1751,13 @@
)
)
+(define-function empathy_strdiff
+ (c-name "empathy_strdiff")
+ (return-type "gboolean")
+ (parameters
+ '("const-gchar*" "left")
+ '("const-gchar*" "right")
+ )
+)
+
+
diff --git a/python/pyempathy/pyempathy.override b/python/pyempathy/pyempathy.override
index 607a9e520..dd816e23a 100644
--- a/python/pyempathy/pyempathy.override
+++ b/python/pyempathy/pyempathy.override
@@ -21,15 +21,10 @@ headers
#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"
-
-
-/* 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);
@@ -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;
-
-}
-%%
diff --git a/python/pyempathygtk/pyempathygtk.defs b/python/pyempathygtk/pyempathygtk.defs
index c41ea45c7..71a4437b6 100644
--- a/python/pyempathygtk/pyempathygtk.defs
+++ b/python/pyempathygtk/pyempathygtk.defs
@@ -306,6 +306,19 @@
+;; 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
@@ -957,25 +970,6 @@
)
)
-(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
@@ -1021,25 +1015,6 @@
(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