gossip r2820 - in trunk: . data/glade libgossip src
- From: mr svn gnome org
- To: svn-commits-list gnome org
- Subject: gossip r2820 - in trunk: . data/glade libgossip src
- Date: Sat, 5 Jul 2008 12:58:07 +0000 (UTC)
Author: mr
Date: Sat Jul 5 12:58:07 2008
New Revision: 2820
URL: http://svn.gnome.org/viewvc/gossip?rev=2820&view=rev
Log:
Fixes 347026, 350333, 541651, reworked Jabber chatroom backend
Added:
trunk/libgossip/gossip-async.c
- copied, changed from r2819, /trunk/libgossip/gossip-jabber-private.h
Modified:
trunk/ChangeLog
trunk/data/glade/chat.glade
trunk/libgossip/Makefile.am
trunk/libgossip/gossip-async.h
trunk/libgossip/gossip-chatroom-invite.c
trunk/libgossip/gossip-chatroom-invite.h
trunk/libgossip/gossip-chatroom-manager.c
trunk/libgossip/gossip-chatroom-manager.h
trunk/libgossip/gossip-chatroom-provider.c
trunk/libgossip/gossip-chatroom-provider.h
trunk/libgossip/gossip-chatroom.c
trunk/libgossip/gossip-chatroom.h
trunk/libgossip/gossip-contact-manager.c
trunk/libgossip/gossip-contact-manager.h
trunk/libgossip/gossip-contact.c
trunk/libgossip/gossip-contact.h
trunk/libgossip/gossip-jabber-chatrooms.c
trunk/libgossip/gossip-jabber-disco.c
trunk/libgossip/gossip-jabber-ft.c
trunk/libgossip/gossip-jabber-private.h
trunk/libgossip/gossip-jabber-register.c
trunk/libgossip/gossip-jabber-utils.c
trunk/libgossip/gossip-jabber-utils.h
trunk/libgossip/gossip-jabber-vcard.c
trunk/libgossip/gossip-jabber.c
trunk/libgossip/gossip-jabber.h
trunk/libgossip/gossip-jid.c
trunk/libgossip/gossip-jid.h
trunk/libgossip/gossip-log.c
trunk/libgossip/gossip-private.h
trunk/libgossip/gossip-session.c
trunk/libgossip/gossip-session.h
trunk/src/gossip-app.c
trunk/src/gossip-chat-view.c
trunk/src/gossip-chat-window.c
trunk/src/gossip-chatrooms-window.c
trunk/src/gossip-contact-info-dialog.c
trunk/src/gossip-contact-list.c
trunk/src/gossip-dbus.c
trunk/src/gossip-edit-contact-dialog.c
trunk/src/gossip-group-chat.c
trunk/src/gossip-new-chatroom-dialog.c
trunk/src/gossip-theme.c
Modified: trunk/data/glade/chat.glade
==============================================================================
--- trunk/data/glade/chat.glade (original)
+++ trunk/data/glade/chat.glade Sat Jul 5 12:58:07 2008
@@ -339,7 +339,6 @@
<child>
<widget class="GtkMenuItem" id="menu_room_contact">
- <property name="visible">False</property>
<property name="label" translatable="yes">_Contact</property>
<property name="use_underline">True</property>
</widget>
@@ -697,7 +696,7 @@
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
- <property name="text" translatable="yes">You have been invited to join a chat conference.</property>
+ <property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">True</property>
Modified: trunk/libgossip/Makefile.am
==============================================================================
--- trunk/libgossip/Makefile.am (original)
+++ trunk/libgossip/Makefile.am Sat Jul 5 12:58:07 2008
@@ -45,6 +45,7 @@
gossip-account.h \
gossip-account-manager.c \
gossip-account-manager.h \
+ gossip-async.c \
gossip-async.h \
gossip-avatar.c \
gossip-avatar.h \
Copied: trunk/libgossip/gossip-async.c (from r2819, /trunk/libgossip/gossip-jabber-private.h)
==============================================================================
--- /trunk/libgossip/gossip-jabber-private.h (original)
+++ trunk/libgossip/gossip-async.c Sat Jul 5 12:58:07 2008
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2008 Imendio AB
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,25 +18,34 @@
* Boston, MA 02111-1307, USA.
*/
-#ifndef __GOSSIP_JABBER_PRIVATE_H__
-#define __GOSSIP_JABBER_PRIVATE_H__
+#include "gossip-async.h"
-#include <loudmouth/loudmouth.h>
-
-#include "gossip-jabber.h"
-#include "gossip-jabber-ft.h"
-
-G_BEGIN_DECLS
-
-LmConnection * gossip_jabber_new_connection (GossipJabber *jabber,
- GossipAccount *account);
-gboolean gossip_jabber_set_connection (LmConnection *connection,
- GossipJabber *jabber,
- GossipAccount *account);
-LmConnection * gossip_jabber_get_connection (GossipJabber *jabber);
-GossipJabberFTs *gossip_jabber_get_fts (GossipJabber *jabber);
-
-G_END_DECLS
-
-#endif /* __GOSSIP_JABBER_PRIVATE_H__ */
+GossipCallbackData *
+gossip_callback_data_new (gpointer callback,
+ gpointer user_data,
+ gpointer data1,
+ gpointer data2,
+ gpointer data3)
+{
+ GossipCallbackData *data;
+
+ data = g_slice_new0 (GossipCallbackData);
+
+ data->callback = callback;
+ data->user_data = user_data;
+ data->data1 = data1;
+ data->data2 = data2;
+ data->data3 = data3;
+
+ return data;
+}
+
+void
+gossip_callback_data_free (GossipCallbackData *data)
+{
+ if (!data) {
+ return;
+ }
+ g_slice_free (GossipCallbackData, data);
+}
Modified: trunk/libgossip/gossip-async.h
==============================================================================
--- trunk/libgossip/gossip-async.h (original)
+++ trunk/libgossip/gossip-async.h Sat Jul 5 12:58:07 2008
@@ -57,6 +57,13 @@
GossipVersionInfo *info,
gpointer user_data);
+GossipCallbackData *gossip_callback_data_new (gpointer callback,
+ gpointer user_data,
+ gpointer data1,
+ gpointer data2,
+ gpointer data3);
+void gossip_callback_data_free (GossipCallbackData *data);
+
G_END_DECLS
#endif /* __GOSSIP_ASYNC_H__ */
Modified: trunk/libgossip/gossip-chatroom-invite.c
==============================================================================
--- trunk/libgossip/gossip-chatroom-invite.c (original)
+++ trunk/libgossip/gossip-chatroom-invite.c Sat Jul 5 12:58:07 2008
@@ -27,7 +27,7 @@
struct _GossipChatroomInvite {
guint ref_count;
- GossipContact *invitor;
+ GossipContact *inviter;
gchar *id;
gchar *reason;
};
@@ -48,20 +48,20 @@
}
GossipChatroomInvite *
-gossip_chatroom_invite_new (GossipContact *invitor,
+gossip_chatroom_invite_new (GossipContact *inviter,
const gchar *id,
const gchar *reason)
{
GossipChatroomInvite *invite;
- g_return_val_if_fail (GOSSIP_IS_CONTACT (invitor), NULL);
+ g_return_val_if_fail (GOSSIP_IS_CONTACT (inviter), NULL);
g_return_val_if_fail (id != NULL, NULL);
invite = g_new0 (GossipChatroomInvite, 1);
invite->ref_count = 1;
- invite->invitor = g_object_ref (invitor);
+ invite->inviter = g_object_ref (inviter);
invite->id = g_strdup (id);
if (reason) {
@@ -94,8 +94,8 @@
return;
}
- if (invite->invitor) {
- g_object_unref (invite->invitor);
+ if (invite->inviter) {
+ g_object_unref (invite->inviter);
}
g_free (invite->id);
@@ -103,11 +103,11 @@
}
GossipContact *
-gossip_chatroom_invite_get_invitor (GossipChatroomInvite *invite)
+gossip_chatroom_invite_get_inviter (GossipChatroomInvite *invite)
{
g_return_val_if_fail (invite != NULL, NULL);
- return invite->invitor;
+ return invite->inviter;
}
const gchar *
Modified: trunk/libgossip/gossip-chatroom-invite.h
==============================================================================
--- trunk/libgossip/gossip-chatroom-invite.h (original)
+++ trunk/libgossip/gossip-chatroom-invite.h Sat Jul 5 12:58:07 2008
@@ -37,7 +37,7 @@
const gchar *reason);
GossipChatroomInvite *gossip_chatroom_invite_ref (GossipChatroomInvite *invite);
void gossip_chatroom_invite_unref (GossipChatroomInvite *invite);
-GossipContact * gossip_chatroom_invite_get_invitor (GossipChatroomInvite *invite);
+GossipContact * gossip_chatroom_invite_get_inviter (GossipChatroomInvite *invite);
const gchar * gossip_chatroom_invite_get_id (GossipChatroomInvite *invite);
const gchar * gossip_chatroom_invite_get_reason (GossipChatroomInvite *invite);
Modified: trunk/libgossip/gossip-chatroom-manager.c
==============================================================================
--- trunk/libgossip/gossip-chatroom-manager.c (original)
+++ trunk/libgossip/gossip-chatroom-manager.c Sat Jul 5 12:58:07 2008
@@ -47,31 +47,31 @@
struct _GossipChatroomManagerPriv {
GossipAccountManager *account_manager;
+ GossipContactManager *contact_manager;
GList *chatrooms;
gchar *chatrooms_file_name;
-
gchar *default_name;
};
-static void chatroom_manager_finalize (GObject *object);
-static void chatroom_manager_chatroom_enabled_cb (GossipChatroom *chatroom,
- GParamSpec *arg1,
- GossipChatroomManager *manager);
-static void chatroom_manager_chatroom_favourite_cb (GossipChatroom *chatroom,
- GParamSpec *arg1,
- GossipChatroomManager *manager);
-static gboolean chatroom_manager_get_all (GossipChatroomManager *manager);
-static gboolean chatroom_manager_file_parse (GossipChatroomManager *manager,
- const gchar *filename);
-static gboolean chatroom_manager_file_save (GossipChatroomManager *manager);
+static void chatroom_manager_finalize (GObject *object);
+static void chatroom_manager_chatroom_enabled_cb (GossipChatroom *chatroom,
+ GParamSpec *arg1,
+ GossipChatroomManager *manager);
+static void chatroom_manager_chatroom_favorite_cb (GossipChatroom *chatroom,
+ GParamSpec *arg1,
+ GossipChatroomManager *manager);
+static gboolean chatroom_manager_get_all (GossipChatroomManager *manager);
+static gboolean chatroom_manager_file_parse (GossipChatroomManager *manager,
+ const gchar *filename);
+static gboolean chatroom_manager_file_save (GossipChatroomManager *manager);
enum {
CHATROOM_ADDED,
CHATROOM_REMOVED,
CHATROOM_ENABLED,
- CHATROOM_FAVOURITE_UPDATE,
+ CHATROOM_FAVORITE_UPDATE,
NEW_DEFAULT,
LAST_SIGNAL
};
@@ -114,8 +114,8 @@
libgossip_marshal_VOID__OBJECT,
G_TYPE_NONE,
1, GOSSIP_TYPE_CHATROOM);
- signals[CHATROOM_FAVOURITE_UPDATE] =
- g_signal_new ("chatroom-favourite-update",
+ signals[CHATROOM_FAVORITE_UPDATE] =
+ g_signal_new ("chatroom-favorite-update",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
@@ -149,21 +149,26 @@
priv = GET_PRIV (object);
+ g_free (priv->chatrooms_file_name);
+ g_free (priv->default_name);
+
g_list_foreach (priv->chatrooms, (GFunc)g_object_unref, NULL);
g_list_free (priv->chatrooms);
+ if (priv->contact_manager) {
+ g_object_unref (priv->contact_manager);
+ }
+
if (priv->account_manager) {
g_object_unref (priv->account_manager);
}
- g_free (priv->chatrooms_file_name);
- g_free (priv->default_name);
-
(G_OBJECT_CLASS (gossip_chatroom_manager_parent_class)->finalize) (object);
}
GossipChatroomManager *
gossip_chatroom_manager_new (GossipAccountManager *account_manager,
+ GossipContactManager *contact_manager,
const gchar *filename)
{
@@ -171,6 +176,7 @@
GossipChatroomManagerPriv *priv;
g_return_val_if_fail (GOSSIP_IS_ACCOUNT_MANAGER (account_manager), NULL);
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_MANAGER (contact_manager), NULL);
manager = g_object_new (GOSSIP_TYPE_CHATROOM_MANAGER, NULL);
@@ -180,6 +186,10 @@
priv->account_manager = g_object_ref (account_manager);
}
+ if (contact_manager) {
+ priv->contact_manager = g_object_ref (contact_manager);
+ }
+
if (filename) {
priv->chatrooms_file_name = g_strdup (filename);
}
@@ -195,39 +205,48 @@
GossipChatroom *chatroom)
{
GossipChatroomManagerPriv *priv;
+ GossipContact *own_contact;
+ const gchar *name;
g_return_val_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager), FALSE);
g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), FALSE);
priv = GET_PRIV (manager);
- /* don't add more than once */
- if (!gossip_chatroom_manager_find (manager, gossip_chatroom_get_id (chatroom))) {
- const gchar *name;
-
- name = gossip_chatroom_get_name (chatroom);
-
- gossip_debug (DEBUG_DOMAIN, "Adding %s chatroom with name:'%s'",
- gossip_chatroom_get_auto_connect (chatroom) ? "connecting on startup " : "",
- name);
-
- g_signal_connect (chatroom, "notify::enabled",
- G_CALLBACK (chatroom_manager_chatroom_enabled_cb),
- manager);
-
- g_signal_connect (chatroom, "notify::favourite",
- G_CALLBACK (chatroom_manager_chatroom_favourite_cb),
- manager);
-
- priv->chatrooms = g_list_append (priv->chatrooms,
- g_object_ref (chatroom));
-
- g_signal_emit (manager, signals[CHATROOM_ADDED], 0, chatroom);
-
- return TRUE;
+ /* Don't add more than once */
+ if (gossip_chatroom_manager_find (manager, gossip_chatroom_get_id (chatroom))) {
+ return FALSE;
}
-
- return FALSE;
+
+ name = gossip_chatroom_get_name (chatroom);
+
+ gossip_debug (DEBUG_DOMAIN, "Adding %s chatroom with name:'%s'",
+ gossip_chatroom_get_auto_connect (chatroom) ? "connecting on startup " : "",
+ name);
+
+ /* Make sure we have an 'own_contact' */
+ own_contact = gossip_contact_manager_find_or_create (priv->contact_manager,
+ gossip_chatroom_get_account (chatroom),
+ GOSSIP_CONTACT_TYPE_CHATROOM,
+ gossip_chatroom_get_own_contact_id_str (chatroom),
+ NULL);
+
+ gossip_chatroom_set_own_contact (chatroom, own_contact);
+
+ g_signal_connect (chatroom, "notify::enabled",
+ G_CALLBACK (chatroom_manager_chatroom_enabled_cb),
+ manager);
+
+ g_signal_connect (chatroom, "notify::favorite",
+ G_CALLBACK (chatroom_manager_chatroom_favorite_cb),
+ manager);
+
+ priv->chatrooms = g_list_append (priv->chatrooms,
+ g_object_ref (chatroom));
+
+ g_signal_emit (manager, signals[CHATROOM_ADDED], 0, chatroom);
+
+ return TRUE;
}
void
@@ -251,7 +270,7 @@
manager);
g_signal_handlers_disconnect_by_func (chatroom,
- chatroom_manager_chatroom_favourite_cb,
+ chatroom_manager_chatroom_favorite_cb,
manager);
link = g_list_find (priv->chatrooms, chatroom);
@@ -291,11 +310,11 @@
}
static void
-chatroom_manager_chatroom_favourite_cb (GossipChatroom *chatroom,
+chatroom_manager_chatroom_favorite_cb (GossipChatroom *chatroom,
GParamSpec *arg1,
GossipChatroomManager *manager)
{
- g_signal_emit (manager, signals[CHATROOM_FAVOURITE_UPDATE], 0, chatroom);
+ g_signal_emit (manager, signals[CHATROOM_FAVORITE_UPDATE], 0, chatroom);
}
GList *
@@ -426,8 +445,6 @@
this_account = gossip_chatroom_get_account (chatroom);
if (this_account) {
same_account = gossip_account_equal (account, this_account);
- } else {
- same_account = FALSE;
}
}
@@ -441,6 +458,46 @@
return found;
}
+GossipChatroom *
+gossip_chatroom_manager_find_or_create (GossipChatroomManager *manager,
+ GossipAccount *account,
+ const gchar *server,
+ const gchar *room,
+ gboolean *created)
+{
+ GossipChatroom *chatroom;
+ GList *found;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager), NULL);
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (server != NULL, NULL);
+ g_return_val_if_fail (room != NULL, NULL);
+
+ found = gossip_chatroom_manager_find_extended (manager,
+ account,
+ server,
+ room);
+
+ if (g_list_length (found) > 1) {
+ g_warning ("Expected ONE chatroom to be found, actually found %d, using first",
+ g_list_length (found));
+ }
+
+ if (created) {
+ *created = found == NULL;
+ }
+
+ if (found) {
+ chatroom = found->data;
+ g_list_free (found);
+ } else {
+ chatroom = gossip_chatroom_new (account, server, room);
+ gossip_chatroom_manager_add (manager, chatroom);
+ }
+
+ return chatroom;
+}
+
void
gossip_chatroom_manager_set_default (GossipChatroomManager *manager,
GossipChatroom *chatroom)
@@ -556,7 +613,7 @@
gchar *str;
gchar *name, *nick, *server;
gchar *room, *password, *account_name;
- gboolean auto_connect, favourite;
+ gboolean auto_connect;
priv = GET_PRIV (manager);
@@ -567,7 +624,6 @@
room = NULL;
password = NULL;
auto_connect = TRUE;
- favourite = FALSE;
account_name = NULL;
child = node->children;
@@ -608,13 +664,6 @@
auto_connect = FALSE;
}
}
- else if (strcmp (tag, "favourite") == 0) {
- if (strcmp (str, "yes") == 0) {
- favourite = TRUE;
- } else {
- favourite = FALSE;
- }
- }
else if (strcmp (tag, "account") == 0) {
account_name = g_strdup (str);
}
@@ -625,13 +674,15 @@
}
if (name && server && room) {
- chatroom = g_object_new (GOSSIP_TYPE_CHATROOM,
- "name", name,
- "server", server,
- "room", room,
- "auto_connect", auto_connect,
- "favourite", favourite,
- NULL);
+ GossipAccount *account = NULL;
+
+ account = gossip_account_manager_find (priv->account_manager,
+ account_name);
+
+ chatroom = gossip_chatroom_new (account, server, room);
+ gossip_chatroom_set_name (chatroom, name);
+ gossip_chatroom_set_auto_connect (chatroom, auto_connect);
+ gossip_chatroom_set_favorite (chatroom, TRUE);
if (nick) {
gossip_chatroom_set_nick (chatroom, nick);
@@ -641,19 +692,6 @@
gossip_chatroom_set_password (chatroom, password);
}
- if (account_name) {
- GossipAccount *account = NULL;
-
- if (priv->account_manager) {
- account = gossip_account_manager_find (priv->account_manager,
- account_name);
- }
-
- if (account) {
- gossip_chatroom_set_account (chatroom, account);
- }
- }
-
gossip_chatroom_manager_add (manager, chatroom);
g_object_unref (chatroom);
@@ -779,6 +817,11 @@
chatroom = l->data;
+ /* We only save favorites */
+ if (!gossip_chatroom_get_favorite (chatroom)) {
+ continue;
+ }
+
node = xmlNewChild (root, NULL, "chatroom", NULL);
xmlNewChild (node, NULL, "type", "normal"); /* We should remove this */
xmlNewTextChild (node, NULL, "name", gossip_chatroom_get_name (chatroom));
@@ -789,12 +832,9 @@
xmlNewTextChild (node, NULL, "password", gossip_chatroom_get_password (chatroom));
xmlNewChild (node, NULL, "auto_connect", gossip_chatroom_get_auto_connect (chatroom) ? "yes" : "no");
- xmlNewChild (node, NULL, "favourite", gossip_chatroom_get_favourite (chatroom) ? "yes" : "no");
account = gossip_chatroom_get_account (chatroom);
- if (account) {
- xmlNewTextChild (node, NULL, "account", gossip_account_get_name (account));
- }
+ xmlNewTextChild (node, NULL, "account", gossip_account_get_name (account));
}
/* Make sure the XML is indented properly */
Modified: trunk/libgossip/gossip-chatroom-manager.h
==============================================================================
--- trunk/libgossip/gossip-chatroom-manager.h (original)
+++ trunk/libgossip/gossip-chatroom-manager.h Sat Jul 5 12:58:07 2008
@@ -60,6 +60,11 @@
GossipAccount *account,
const gchar *server,
const gchar *room);
+GossipChatroom *gossip_chatroom_manager_find_or_create (GossipChatroomManager *manager,
+ GossipAccount *account,
+ const gchar *server,
+ const gchar *room,
+ gboolean *created);
gboolean gossip_chatroom_manager_store (GossipChatroomManager *manager);
GList * gossip_chatroom_manager_get_chatrooms (GossipChatroomManager *manager,
GossipAccount *account);
@@ -68,7 +73,6 @@
GossipChatroom *gossip_chatroom_manager_get_default (GossipChatroomManager *manager);
void gossip_chatroom_manager_set_default (GossipChatroomManager *manager,
GossipChatroom *chatroom);
-
G_END_DECLS
#endif /* __GOSSIP_CHATROOM_MANAGER_H__ */
Modified: trunk/libgossip/gossip-chatroom-provider.c
==============================================================================
--- trunk/libgossip/gossip-chatroom-provider.c (original)
+++ trunk/libgossip/gossip-chatroom-provider.c Sat Jul 5 12:58:07 2008
@@ -30,8 +30,8 @@
static void chatroom_provider_base_init (gpointer g_class);
enum {
- CHATROOM_JOINED,
CHATROOM_KICKED,
+ CHATROOM_NICK_CHANGED,
CHATROOM_NEW_MESSAGE,
CHATROOM_NEW_EVENT,
CHATROOM_SUBJECT_CHANGED,
@@ -76,8 +76,8 @@
static gboolean initialized = FALSE;
if (!initialized) {
- signals[CHATROOM_JOINED] =
- g_signal_new ("chatroom-joined",
+ signals[CHATROOM_KICKED] =
+ g_signal_new ("chatroom-kicked",
G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_LAST,
0,
@@ -85,17 +85,15 @@
libgossip_marshal_VOID__INT,
G_TYPE_NONE,
1, G_TYPE_INT);
-
- signals[CHATROOM_KICKED] =
- g_signal_new ("chatroom-kicked",
+ signals[CHATROOM_NICK_CHANGED] =
+ g_signal_new ("chatroom-nick-changed",
G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- libgossip_marshal_VOID__INT,
+ libgossip_marshal_VOID__INT_OBJECT_STRING,
G_TYPE_NONE,
- 1, G_TYPE_INT);
-
+ 3, G_TYPE_INT, GOSSIP_TYPE_CONTACT, G_TYPE_STRING);
signals[CHATROOM_NEW_MESSAGE] =
g_signal_new ("chatroom-new-message",
G_TYPE_FROM_CLASS (g_class),
@@ -249,21 +247,6 @@
}
}
-GSList *
-gossip_chatroom_provider_get_contacts (GossipChatroomProvider *provider,
- GossipChatroomId id)
-{
- g_return_val_if_fail (GOSSIP_IS_CHATROOM_PROVIDER (provider), NULL);
- g_return_val_if_fail (id > 0, NULL);
-
- if (GOSSIP_CHATROOM_PROVIDER_GET_IFACE (provider)->get_contacts) {
- return GOSSIP_CHATROOM_PROVIDER_GET_IFACE (provider)->get_contacts (provider,
- id);
- }
-
- return NULL;
-}
-
GossipChatroom *
gossip_chatroom_provider_find_by_id (GossipChatroomProvider *provider,
GossipChatroomId id)
Modified: trunk/libgossip/gossip-chatroom-provider.h
==============================================================================
--- trunk/libgossip/gossip-chatroom-provider.h (original)
+++ trunk/libgossip/gossip-chatroom-provider.h Sat Jul 5 12:58:07 2008
@@ -72,8 +72,6 @@
GossipChatroomId id,
GossipContact *contact,
const gchar *reason);
- GSList * (*get_contacts) (GossipChatroomProvider *provider,
- GossipChatroomId id);
GossipChatroom * (*find_by_id) (GossipChatroomProvider *provider,
GossipChatroomId id);
GossipChatroom * (*find) (GossipChatroomProvider *provider,
@@ -122,6 +120,9 @@
const gchar *reason);
GSList * gossip_chatroom_provider_get_contacts (GossipChatroomProvider *provider,
GossipChatroomId id);
+GossipContact *
+ gossip_chatroom_provider_get_own_contacts (GossipChatroomProvider *provider,
+ GossipChatroomId id);
GossipChatroom *
gossip_chatroom_provider_find_by_id (GossipChatroomProvider *provider,
GossipChatroomId id);
Modified: trunk/libgossip/gossip-chatroom.c
==============================================================================
--- trunk/libgossip/gossip-chatroom.c (original)
+++ trunk/libgossip/gossip-chatroom.c Sat Jul 5 12:58:07 2008
@@ -26,6 +26,8 @@
#include <glib/gi18n.h>
#include "gossip-chatroom.h"
+#include "gossip-utils.h"
+#include "gossip-jid.h"
#include "libgossip-marshal.h"
@@ -47,7 +49,7 @@
gchar *room;
gchar *password;
gboolean auto_connect;
- gboolean favourite;
+ gboolean favorite;
GossipChatroomFeature features;
GossipChatroomStatus status;
@@ -57,6 +59,8 @@
GossipChatroomError last_error;
GHashTable *contacts;
+ GossipContact *own_contact;
+ gchar *own_contact_id_str;
};
static void gossip_chatroom_class_init (GossipChatroomClass *klass);
@@ -70,6 +74,7 @@
guint param_id,
const GValue *value,
GParamSpec *pspec);
+static void chatroom_contact_info_free (gpointer data);
enum {
PROP_0,
@@ -84,11 +89,12 @@
PROP_ROOM,
PROP_PASSWORD,
PROP_AUTO_CONNECT,
- PROP_FAVOURITE,
+ PROP_FAVORITE,
PROP_FEATURES,
PROP_STATUS,
PROP_OCCUPANTS,
PROP_LAST_ERROR,
+ PROP_OWN_CONTACT
};
enum {
@@ -171,6 +177,13 @@
object_class->set_property = chatroom_set_property;
g_object_class_install_property (object_class,
+ PROP_ACCOUNT,
+ g_param_spec_object ("account",
+ "Chatroom Account",
+ "The account associated with an chatroom",
+ GOSSIP_TYPE_ACCOUNT,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
PROP_ID,
g_param_spec_int ("id",
"Chatroom Id",
@@ -253,10 +266,10 @@
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
- PROP_FAVOURITE,
- g_param_spec_boolean ("favourite",
- "Chatroom Favourite",
- "Used to connect favourites quickly",
+ PROP_FAVORITE,
+ g_param_spec_boolean ("favorite",
+ "Chatroom Favorite",
+ "Used to connect favorites quickly",
FALSE,
G_PARAM_READWRITE));
@@ -300,11 +313,11 @@
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
- PROP_ACCOUNT,
- g_param_spec_object ("account",
- "Chatroom Account",
- "The account associated with an chatroom",
- GOSSIP_TYPE_ACCOUNT,
+ PROP_OWN_CONTACT,
+ g_param_spec_object ("own-contact",
+ "Chatroom Own Contact",
+ "The contact you are in this chatroom",
+ GOSSIP_TYPE_CONTACT,
G_PARAM_READWRITE));
signals[CONTACT_JOINED] =
@@ -346,17 +359,17 @@
priv = GET_PRIV (chatroom);
- priv->id = id++;
+ priv->id = id++;
priv->auto_connect = FALSE;
- priv->favourite = FALSE;
+ priv->favorite = FALSE;
- priv->status = GOSSIP_CHATROOM_STATUS_INACTIVE;
+ priv->status = GOSSIP_CHATROOM_STATUS_INACTIVE;
- priv->contacts = g_hash_table_new_full (gossip_contact_hash,
- gossip_contact_equal,
- (GDestroyNotify) g_object_unref,
- g_free);
+ priv->contacts = g_hash_table_new_full (gossip_contact_hash,
+ gossip_contact_equal,
+ (GDestroyNotify) g_object_unref,
+ chatroom_contact_info_free);
}
static void
@@ -366,6 +379,10 @@
priv = GET_PRIV (object);
+ if (priv->account) {
+ g_object_unref (priv->account);
+ }
+
g_free (priv->id_str);
g_free (priv->name);
@@ -374,12 +391,12 @@
g_free (priv->room);
g_free (priv->password);
- if (priv->account) {
- g_object_unref (priv->account);
- }
-
g_hash_table_destroy (priv->contacts);
+ if (priv->own_contact) {
+ g_object_unref (priv->own_contact);
+ }
+
(G_OBJECT_CLASS (gossip_chatroom_parent_class)->finalize) (object);
}
@@ -427,8 +444,8 @@
case PROP_AUTO_CONNECT:
g_value_set_boolean (value, priv->auto_connect);
break;
- case PROP_FAVOURITE:
- g_value_set_boolean (value, priv->favourite);
+ case PROP_FAVORITE:
+ g_value_set_boolean (value, priv->favorite);
break;
case PROP_FEATURES:
g_value_set_int (value, priv->features);
@@ -442,6 +459,9 @@
case PROP_LAST_ERROR:
g_value_set_enum (value, priv->last_error);
break;
+ case PROP_OWN_CONTACT:
+ g_value_set_object (value, priv->own_contact);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -495,9 +515,9 @@
gossip_chatroom_set_auto_connect (GOSSIP_CHATROOM (object),
g_value_get_boolean (value));
break;
- case PROP_FAVOURITE:
- gossip_chatroom_set_favourite (GOSSIP_CHATROOM (object),
- g_value_get_boolean (value));
+ case PROP_FAVORITE:
+ gossip_chatroom_set_favorite (GOSSIP_CHATROOM (object),
+ g_value_get_boolean (value));
break;
case PROP_FEATURES:
gossip_chatroom_set_features (GOSSIP_CHATROOM (object),
@@ -515,12 +535,100 @@
gossip_chatroom_set_last_error (GOSSIP_CHATROOM (object),
g_value_get_enum (value));
break;
+ case PROP_OWN_CONTACT:
+ gossip_chatroom_set_own_contact (GOSSIP_CHATROOM (object),
+ g_value_get_object (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
};
}
+static void
+update_id_str (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ priv = GET_PRIV (chatroom);
+
+ if (priv->room && priv->server) {
+ g_free (priv->id_str);
+ priv->id_str = g_strconcat (priv->room, "@", priv->server, NULL);
+ }
+}
+
+static void
+update_own_contact_id_str (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ priv = GET_PRIV (chatroom);
+
+ if (priv->id_str && priv->nick) {
+ g_free (priv->own_contact_id_str);
+ priv->own_contact_id_str = g_strconcat (priv->id_str, "/", priv->nick, NULL);
+ }
+}
+
+static void
+update_own_contact (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ priv = GET_PRIV (chatroom);
+
+ /* We can't do anything without an account, own contact or
+ * id_str (room and server) to generate the own
+ * contact.
+ */
+ if (!priv->account ||
+ !priv->own_contact ||
+ !priv->id_str ||
+ !priv->own_contact_id_str) {
+ return;
+ }
+
+ /* First try the nick that we have saved in the Chatroom */
+ if (G_STR_EMPTY (priv->nick)) {
+ const gchar *account_id;
+ gchar *part_name;
+
+ /* Second try to use the name part of the account ID */
+ account_id = gossip_account_get_id (priv->account);
+ part_name = gossip_jid_string_get_part_name (account_id);
+
+ /* Update nick if we don't have one */
+ gossip_chatroom_set_nick (chatroom, part_name);
+ g_free (part_name);
+ }
+
+ /* Update id and name */
+ gossip_contact_set_id (priv->own_contact, priv->own_contact_id_str);
+ gossip_contact_set_name (priv->own_contact, priv->nick);
+}
+
+GossipChatroom *
+gossip_chatroom_new (GossipAccount *account,
+ const gchar *server,
+ const gchar *room)
+{
+ GossipChatroom *chatroom;
+
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (server != NULL, NULL);
+ g_return_val_if_fail (room != NULL, NULL);
+
+ chatroom = g_object_new (GOSSIP_TYPE_CHATROOM,
+ "account", account,
+ "server", server,
+ "room", room,
+ "name", room, /* Use the room as the name */
+ NULL);
+
+ return chatroom;
+}
+
GossipAccount *
gossip_chatroom_get_account (GossipChatroom *chatroom)
{
@@ -653,7 +761,7 @@
}
gboolean
-gossip_chatroom_get_favourite (GossipChatroom *chatroom)
+gossip_chatroom_get_favorite (GossipChatroom *chatroom)
{
GossipChatroomPriv *priv;
@@ -661,7 +769,7 @@
priv = GET_PRIV (chatroom);
- return priv->favourite;
+ return priv->favorite;
}
GossipChatroomFeature
@@ -727,6 +835,46 @@
return g_hash_table_lookup (priv->contacts, contact);
}
+GList *
+gossip_chatroom_get_contacts (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
+
+ priv = GET_PRIV (chatroom);
+
+ return g_hash_table_get_keys (priv->contacts);
+}
+
+GossipContact *
+gossip_chatroom_get_own_contact (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
+
+ priv = GET_PRIV (chatroom);
+
+ return priv->own_contact;
+}
+
+const gchar *
+gossip_chatroom_get_own_contact_id_str (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
+
+ priv = GET_PRIV (chatroom);
+
+ if (!priv->own_contact_id_str) {
+ priv->own_contact_id_str = g_strdup ("");
+ }
+
+ return priv->own_contact_id_str;
+}
+
void
gossip_chatroom_set_account (GossipChatroom *chatroom,
GossipAccount *account)
@@ -743,6 +891,9 @@
priv->account = g_object_ref (account);
+ /* Update dependencies, like own-contact */
+ update_own_contact (chatroom);
+
g_object_notify (G_OBJECT (chatroom), "account");
}
@@ -811,6 +962,10 @@
g_free (priv->nick);
priv->nick = g_strdup (nick);
+ /* Update dependencies, like own-contact */
+ update_own_contact_id_str (chatroom);
+ update_own_contact (chatroom);
+
g_object_notify (G_OBJECT (chatroom), "nick");
}
@@ -828,10 +983,10 @@
g_free (priv->server);
priv->server = g_strdup (server);
- if (priv->room && priv->server) {
- g_free (priv->id_str);
- priv->id_str = g_strdup_printf ("%s %s", priv->room, priv->server);
- }
+ /* Update dependencies, like own-contact */
+ update_id_str (chatroom);
+ update_own_contact_id_str (chatroom);
+ update_own_contact (chatroom);
g_object_notify (G_OBJECT (chatroom), "server");
}
@@ -850,10 +1005,10 @@
g_free (priv->room);
priv->room = g_strdup (room);
- if (priv->room && priv->server) {
- g_free (priv->id_str);
- priv->id_str = g_strdup_printf ("%s %s", priv->room, priv->server);
- }
+ /* Update dependencies, like own-contact */
+ update_id_str (chatroom);
+ update_own_contact_id_str (chatroom);
+ update_own_contact (chatroom);
g_object_notify (G_OBJECT (chatroom), "room");
}
@@ -890,17 +1045,17 @@
}
void
-gossip_chatroom_set_favourite (GossipChatroom *chatroom,
- gboolean favourite)
+gossip_chatroom_set_favorite (GossipChatroom *chatroom,
+ gboolean favorite)
{
GossipChatroomPriv *priv;
g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
priv = GET_PRIV (chatroom);
- priv->favourite = favourite;
+ priv->favorite = favorite;
- g_object_notify (G_OBJECT (chatroom), "favourite");
+ g_object_notify (G_OBJECT (chatroom), "favorite");
}
static void
@@ -977,6 +1132,12 @@
g_object_notify (G_OBJECT (chatroom), "last-error");
}
+static void
+chatroom_contact_info_free (gpointer data)
+{
+ g_free (data);
+}
+
void
gossip_chatroom_set_contact_info (GossipChatroom *chatroom,
GossipContact *contact,
@@ -1002,36 +1163,67 @@
g_signal_emit (chatroom, signals[CONTACT_INFO_CHANGED], 0, contact);
}
+void
+gossip_chatroom_set_own_contact (GossipChatroom *chatroom,
+ GossipContact *own_contact)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
+ g_return_if_fail (GOSSIP_IS_CONTACT (own_contact));
+
+ priv = GET_PRIV (chatroom);
+
+ if (priv->own_contact) {
+ g_object_unref (priv->own_contact);
+ }
+
+ priv->own_contact = g_object_ref (own_contact);
+
+ g_object_notify (G_OBJECT (chatroom), "own-contact");
+}
+
guint
gossip_chatroom_hash (gconstpointer key)
{
- GossipChatroomPriv *priv;
+ const gchar *id_str;
+ guint hash = 0;
- g_return_val_if_fail (GOSSIP_IS_CHATROOM (key), 0);
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (key), +1);
- priv = GET_PRIV (key);
+ id_str = gossip_chatroom_get_id_str (GOSSIP_CHATROOM (key));
+ g_return_val_if_fail (!G_STR_EMPTY (id_str), +1);
- return g_int_hash (&priv->id);
+ hash += gossip_account_hash (gossip_chatroom_get_account (GOSSIP_CHATROOM (key)));
+ hash += g_str_hash (id_str);
+
+ return hash;
}
gboolean
-gossip_chatroom_equal (gconstpointer a,
- gconstpointer b)
+gossip_chatroom_equal (gconstpointer v1,
+ gconstpointer v2)
{
- GossipChatroomPriv *priv1;
- GossipChatroomPriv *priv2;
+ GossipAccount *account_a;
+ GossipAccount *account_b;
+ const gchar *id_a;
+ const gchar *id_b;
+ gboolean equal;
- g_return_val_if_fail (GOSSIP_IS_CHATROOM (a), FALSE);
- g_return_val_if_fail (GOSSIP_IS_CHATROOM (b), FALSE);
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (v1), FALSE);
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (v2), FALSE);
- priv1 = GET_PRIV (a);
- priv2 = GET_PRIV (b);
+ account_a = gossip_chatroom_get_account (GOSSIP_CHATROOM (v1));
+ account_b = gossip_chatroom_get_account (GOSSIP_CHATROOM (v2));
- if (!priv1 || !priv2) {
- return FALSE;
- }
+ id_a = gossip_chatroom_get_id_str (GOSSIP_CHATROOM (v1));
+ id_b = gossip_chatroom_get_id_str (GOSSIP_CHATROOM (v2));
+
+ equal = TRUE;
+ equal &= gossip_account_equal (account_a, account_b);
+ equal &= g_str_equal (id_a, id_b);
- return (priv1->id == priv2->id);
+ return equal;
}
gboolean
@@ -1109,31 +1301,38 @@
gossip_chatroom_error_to_string (GossipChatroomError error)
{
switch (error) {
+ case GOSSIP_CHATROOM_ERROR_NONE:
+ break;
case GOSSIP_CHATROOM_ERROR_PASSWORD_INVALID_OR_MISSING:
return _("The chat room you tried to join requires a password. "
- "You either failed to supply a password or the password you tried was incorrect.");
- case GOSSIP_CHATROOM_ERROR_USER_BANNED:
- return _("You have been banned from this chatroom.");
+ "You either failed to supply a password or the password you tried was incorrect"); case GOSSIP_CHATROOM_ERROR_USER_BANNED:
+ return _("You have been banned from this chatroom");
case GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND:
- return _("The conference room you tried to join could not be found.");
+ return _("The conference room you tried to join could not be found");
case GOSSIP_CHATROOM_ERROR_ROOM_CREATION_RESTRICTED:
- return _("Chatroom creation is restricted on this server.");
+ return _("Chatroom creation is restricted on this server");
case GOSSIP_CHATROOM_ERROR_USE_RESERVED_ROOM_NICK:
- return _("Chatroom reserved nick names must be used on this server.");
+ return _("Chatroom reserved nick names must be used on this server");
case GOSSIP_CHATROOM_ERROR_NOT_ON_MEMBERS_LIST:
- return _("You are not on the chatroom's members list.");
+ return _("You are not on the chatroom's members list");
case GOSSIP_CHATROOM_ERROR_NICK_IN_USE:
- return _("The nickname you have chosen is already in use.");
+ return _("The nickname you have chosen is already in use");
case GOSSIP_CHATROOM_ERROR_MAXIMUM_USERS_REACHED:
- return _("The maximum number of users for this chatroom has been reached.");
+ return _("The maximum number of users for this chatroom has been reached");
+ case GOSSIP_CHATROOM_ERROR_UNAUTHORIZED_REQUEST:
+ return _("Unauthorized request, you do not have privileges to do that");
+ case GOSSIP_CHATROOM_ERROR_FORBIDDEN:
+ return _("That action is forbidden");
+ case GOSSIP_CHATROOM_ERROR_ALREADY_OPEN:
+ break;
case GOSSIP_CHATROOM_ERROR_TIMED_OUT:
- return _("The remote conference server did not respond in a sensible time.");
- case GOSSIP_CHATROOM_ERROR_UNKNOWN:
- return _("An unknown error occurred, check your details are correct.");
+ return _("The remote conference server did not respond in a sensible time");
case GOSSIP_CHATROOM_ERROR_CANCELED:
- return _("Joining the chatroom was canceled.");
- default:
- break;
+ return _("Joining the chatroom was canceled");
+ case GOSSIP_CHATROOM_ERROR_BAD_REQUEST:
+ return _("A bad request was sent to the server");
+ case GOSSIP_CHATROOM_ERROR_UNKNOWN:
+ return _("An unknown error occurred, check your details are correct");
}
return "";
Modified: trunk/libgossip/gossip-chatroom.h
==============================================================================
--- trunk/libgossip/gossip-chatroom.h (original)
+++ trunk/libgossip/gossip-chatroom.h Sat Jul 5 12:58:07 2008
@@ -83,11 +83,14 @@
GOSSIP_CHATROOM_ERROR_NOT_ON_MEMBERS_LIST,
GOSSIP_CHATROOM_ERROR_NICK_IN_USE,
GOSSIP_CHATROOM_ERROR_MAXIMUM_USERS_REACHED,
+ GOSSIP_CHATROOM_ERROR_UNAUTHORIZED_REQUEST,
+ GOSSIP_CHATROOM_ERROR_FORBIDDEN,
/* Internal errors */
GOSSIP_CHATROOM_ERROR_ALREADY_OPEN,
GOSSIP_CHATROOM_ERROR_TIMED_OUT,
GOSSIP_CHATROOM_ERROR_CANCELED,
+ GOSSIP_CHATROOM_ERROR_BAD_REQUEST,
GOSSIP_CHATROOM_ERROR_UNKNOWN
} GossipChatroomError;
@@ -143,20 +146,24 @@
/* Chatroom */
GType gossip_chatroom_get_type (void) G_GNUC_CONST;
+GossipChatroom *
+ gossip_chatroom_new (GossipAccount *account,
+ const gchar *server,
+ const gchar *room);
GossipAccount *
- gossip_chatroom_get_account (GossipChatroom *chatroom);
+ gossip_chatroom_get_account (GossipChatroom *chatroom);
GossipChatroomId
- gossip_chatroom_get_id (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_id_str (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_name (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_description (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_subject (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_nick (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_server (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_room (GossipChatroom *chatroom);
-const gchar * gossip_chatroom_get_password (GossipChatroom *chatroom);
-gboolean gossip_chatroom_get_auto_connect (GossipChatroom *chatroom);
-gboolean gossip_chatroom_get_favourite (GossipChatroom *chatroom);
+ gossip_chatroom_get_id (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_id_str (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_name (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_description (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_subject (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_nick (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_server (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_room (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_password (GossipChatroom *chatroom);
+gboolean gossip_chatroom_get_auto_connect (GossipChatroom *chatroom);
+gboolean gossip_chatroom_get_favorite (GossipChatroom *chatroom);
GossipChatroomFeature
gossip_chatroom_get_features (GossipChatroom *chatroom);
@@ -168,7 +175,10 @@
GossipChatroomContactInfo *
gossip_chatroom_get_contact_info (GossipChatroom *chatroom,
GossipContact *contact);
+GList * gossip_chatroom_get_contacts (GossipChatroom *chatroom);
+GossipContact *gossip_chatroom_get_own_contact (GossipChatroom *chatroom);
+const gchar * gossip_chatroom_get_own_contact_id_str (GossipChatroom *chatroom);
void gossip_chatroom_set_account (GossipChatroom *chatroom,
GossipAccount *account);
void gossip_chatroom_set_name (GossipChatroom *chatroom,
@@ -187,8 +197,8 @@
const gchar *password);
void gossip_chatroom_set_auto_connect (GossipChatroom *chatroom,
gboolean auto_connect);
-void gossip_chatroom_set_favourite (GossipChatroom *chatroom,
- gboolean favourite);
+void gossip_chatroom_set_favorite (GossipChatroom *chatroom,
+ gboolean favorite);
void gossip_chatroom_set_features (GossipChatroom *chatroom,
GossipChatroomFeature features);
void gossip_chatroom_set_status (GossipChatroom *chatroom,
@@ -200,6 +210,8 @@
void gossip_chatroom_set_contact_info (GossipChatroom *chatroom,
GossipContact *contact,
GossipChatroomContactInfo *info);
+void gossip_chatroom_set_own_contact (GossipChatroom *chatroom,
+ GossipContact *contact);
/* Utils */
guint gossip_chatroom_hash (gconstpointer key);
Modified: trunk/libgossip/gossip-contact-manager.c
==============================================================================
--- trunk/libgossip/gossip-contact-manager.c (original)
+++ trunk/libgossip/gossip-contact-manager.c Sat Jul 5 12:58:07 2008
@@ -29,7 +29,7 @@
#include "gossip-session.h"
#include "gossip-debug.h"
-#include "gossip-jabber.h"
+#include "gossip-jabber-utils.h"
#include "gossip-contact-manager.h"
#include "gossip-account-manager.h"
#include "gossip-private.h"
@@ -49,7 +49,7 @@
struct _GossipContactManagerPriv {
GossipSession *session;
- GList *contacts;
+ GHashTable *contacts;
gchar *contacts_file_name;
guint store_timeout_id;
@@ -89,8 +89,7 @@
priv = GET_PRIV (object);
- g_list_foreach (priv->contacts, (GFunc) g_object_unref, NULL);
- g_list_free (priv->contacts);
+ g_hash_table_unref (priv->contacts);
g_free (priv->contacts_file_name);
@@ -129,6 +128,11 @@
G_CALLBACK (contact_manager_contact_added_cb),
manager);
+ priv->contacts = g_hash_table_new_full (gossip_contact_hash,
+ gossip_contact_equal,
+ g_object_unref,
+ NULL);
+
if (filename) {
priv->contacts_file_name = g_strdup (filename);
}
@@ -146,8 +150,6 @@
GossipContactManagerPriv *priv;
GossipAccount *account;
GossipContact *own_contact;
- const gchar *contact_id;
- gboolean found;
g_return_val_if_fail (GOSSIP_IS_CONTACT_MANAGER (manager), FALSE);
g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), FALSE);
@@ -155,27 +157,28 @@
priv = GET_PRIV (manager);
account = gossip_contact_get_account (contact);
- own_contact = gossip_session_get_own_contact (priv->session, account);
- contact_id = gossip_contact_get_id (contact);
+ own_contact = gossip_contact_manager_get_own_contact (manager, account);
/* Don't add if it is a self contact, since we do this ourselves */
if (gossip_contact_equal (own_contact, contact)) {
- return TRUE;
+ return FALSE;
}
/* Don't add more than once */
- found = gossip_contact_manager_find (manager, account, contact_id) != NULL;
-
- if (!found) {
- gossip_debug (DEBUG_DOMAIN,
- "Adding contact from account:'%s' with id:'%s'",
- gossip_account_get_name (account),
- contact_id);
-
- priv->contacts = g_list_append (priv->contacts, g_object_ref (contact));
+ if (g_hash_table_lookup (priv->contacts, contact)) {
+ return FALSE;
}
- return !found;
+ gossip_debug (DEBUG_DOMAIN,
+ "Adding contact with account:'%s' with id:'%s'",
+ gossip_account_get_name (account),
+ gossip_contact_get_id (contact));
+
+ g_hash_table_insert (priv->contacts,
+ g_object_ref (contact),
+ GINT_TO_POINTER (1));
+
+ return TRUE;
}
void
@@ -183,23 +186,20 @@
GossipContact *contact)
{
GossipContactManagerPriv *priv;
- GList *l;
+ GossipAccount *account;
g_return_if_fail (GOSSIP_IS_CONTACT_MANAGER (manager));
g_return_if_fail (GOSSIP_IS_CONTACT (contact));
priv = GET_PRIV (manager);
- gossip_debug (DEBUG_DOMAIN,
- "Removing contact with name:'%s'",
- gossip_contact_get_name (contact));
+ account = gossip_contact_get_account (contact);
+ gossip_debug (DEBUG_DOMAIN,
+ "Removing contact with account:'%s' with id:'%s'",
+ gossip_account_get_name (account),
+ gossip_contact_get_id (contact));
- l = g_list_find (priv->contacts, contact);
- if (l) {
- priv->contacts = g_list_remove_link (priv->contacts, l);
- g_object_unref (contact);
- g_list_free1 (l);
- }
+ g_hash_table_remove (priv->contacts, contact);
}
GossipContact *
@@ -208,34 +208,224 @@
const gchar *contact_id)
{
GossipContactManagerPriv *priv;
+ GossipContact *found = NULL;
+ GList *contacts;
GList *l;
g_return_val_if_fail (GOSSIP_IS_CONTACT_MANAGER (manager), NULL);
- g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
g_return_val_if_fail (contact_id != NULL, NULL);
priv = GET_PRIV (manager);
- for (l = priv->contacts; l; l = l->next) {
- GossipAccount *this_account;
+ contacts = g_hash_table_get_keys (priv->contacts);
+
+ for (l = contacts; l && !found; l = l->next) {
GossipContact *this_contact;
const gchar *this_contact_id;
+ gboolean equal;
this_contact = l->data;
- this_account = gossip_contact_get_account (this_contact);
this_contact_id = gossip_contact_get_id (this_contact);
if (!this_contact_id) {
continue;
}
- if (gossip_account_equal (account, this_account) &&
- strcmp (this_contact_id, contact_id) == 0) {
- return this_contact;
+ equal = TRUE;
+
+ if (account) {
+ GossipAccount *this_account;
+
+ this_account = gossip_contact_get_account (this_contact);
+ equal &= gossip_account_equal (account, this_account);
+ }
+
+ equal &= g_str_equal (contact_id, this_contact_id);
+
+ if (equal) {
+ found = this_contact;
}
}
- return NULL;
+ g_list_free (contacts);
+
+ return found;
+}
+
+GossipContact *
+gossip_contact_manager_find_extended (GossipContactManager *manager,
+ GossipAccount *account,
+ GossipContactType contact_type,
+ const gchar *contact_id)
+{
+ GossipContactManagerPriv *priv;
+ GossipContact *found = NULL;
+ GList *contacts;
+ GList *l;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_MANAGER (manager), NULL);
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (contact_id != NULL, NULL);
+
+ priv = GET_PRIV (manager);
+
+ contacts = g_hash_table_get_keys (priv->contacts);
+
+ for (l = contacts; l && !found; l = l->next) {
+ GossipContact *this_contact;
+ GossipContactType this_contact_type;
+ const gchar *this_contact_id;
+ gboolean equal;
+
+ this_contact = l->data;
+ this_contact_id = gossip_contact_get_id (this_contact);
+
+ if (!this_contact_id) {
+ continue;
+ }
+
+ equal = TRUE;
+
+ if (account) {
+ GossipAccount *this_account;
+
+ this_account = gossip_contact_get_account (this_contact);
+ equal &= gossip_account_equal (account, this_account);
+ }
+
+ this_contact_type = gossip_contact_get_type (this_contact);
+
+ equal &= contact_type == this_contact_type;
+ equal &= g_str_equal (contact_id, this_contact_id);
+
+ if (equal) {
+ found = this_contact;
+ }
+ }
+
+ g_list_free (contacts);
+
+ return found;
+}
+
+GossipContact *
+gossip_contact_manager_find_or_create (GossipContactManager *manager,
+ GossipAccount *account,
+ GossipContactType contact_type,
+ const gchar *contact_id,
+ gboolean *created)
+{
+ GossipContact *contact;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_MANAGER (manager), NULL);
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (contact_id != NULL, NULL);
+
+ /* Special case chatrooms, since we want to ONLY search for
+ * the contact id, account and type together for chatrooms,
+ * for other contacts, just account and contact id are fine
+ * because there is a chance that a contact is temporary until
+ * added to your contact list.
+ */
+ if (contact_type == GOSSIP_CONTACT_TYPE_CHATROOM) {
+ contact = gossip_contact_manager_find_extended (manager,
+ account,
+ contact_type,
+ contact_id);
+ } else {
+ contact = gossip_contact_manager_find (manager,
+ account,
+ contact_id);
+ }
+
+ if (created) {
+ *created = contact == NULL;
+ }
+
+ if (contact) {
+ gossip_debug (DEBUG_DOMAIN,
+ "Get contact:'%s', (%s)",
+ gossip_contact_get_id (contact),
+ gossip_contact_type_to_string (contact_type));
+
+ return contact;
+ } else {
+ gchar *name;
+
+ gossip_debug (DEBUG_DOMAIN,
+ "New contact:'%s' (%s)",
+ contact_id,
+ gossip_contact_type_to_string (contact_type));
+
+ name = gossip_jabber_get_name_to_use (contact_id, NULL, NULL, NULL);
+
+ /* Create the contact using a default name as the ID */
+ contact = gossip_contact_new (contact_type, account);
+ gossip_contact_set_id (contact, contact_id);
+ gossip_contact_set_name (contact, name);
+ g_free (name);
+
+ gossip_contact_manager_add (manager, contact);
+ gossip_contact_manager_store (manager);
+ }
+
+ return contact;
+}
+
+GossipContact *
+gossip_contact_manager_get_own_contact (GossipContactManager *manager,
+ GossipAccount *account)
+{
+ GossipContact *contact;
+ GossipContactType contact_type;
+ const gchar *contact_id;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_MANAGER (manager), NULL);
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), NULL);
+
+ contact_type = GOSSIP_CONTACT_TYPE_USER;
+ contact_id = gossip_account_get_id (account);
+
+ contact = gossip_contact_manager_find_extended (manager,
+ account,
+ contact_type,
+ contact_id);
+
+ if (contact) {
+ gossip_debug (DEBUG_DOMAIN,
+ "Get own contact:'%s', (%s)",
+ gossip_contact_get_id (contact),
+ gossip_contact_type_to_string (contact_type));
+
+ return contact;
+ } else {
+ GossipContactManagerPriv *priv;
+ gchar *name;
+
+ gossip_debug (DEBUG_DOMAIN,
+ "New own contact:'%s' (%s)",
+ contact_id,
+ gossip_contact_type_to_string (contact_type));
+
+ name = gossip_jabber_get_name_to_use (contact_id, NULL, NULL, NULL);
+
+ /* Create the contact using a default name as the ID */
+ contact = gossip_contact_new (contact_type, account);
+ gossip_contact_set_id (contact, contact_id);
+ gossip_contact_set_name (contact, name);
+ g_free (name);
+
+ /* Don't use _manager_add() - recursive loop */
+ priv = GET_PRIV (manager);
+
+ g_hash_table_insert (priv->contacts,
+ contact,
+ GINT_TO_POINTER (1));
+
+ gossip_contact_manager_store (manager);
+
+ return contact;
+ }
}
static gboolean
@@ -339,16 +529,15 @@
name = gossip_xml_node_get_child_content (node, "name");
if (id && name) {
- GossipContactManagerPriv *priv;
- GossipJabber *jabber;
- GossipContact *contact;
-
- priv = GET_PRIV (manager);
-
- jabber = gossip_session_get_protocol (priv->session, account);
- contact = gossip_jabber_new_contact (jabber, id, name);
+ GossipContact *contact;
- gossip_contact_manager_add (manager, contact);
+ contact = gossip_contact_manager_find_or_create (manager,
+ account,
+ GOSSIP_CONTACT_TYPE_TEMPORARY,
+ id,
+ NULL);
+
+ gossip_contact_set_name (contact, name);
}
xmlFree (name);
@@ -361,8 +550,7 @@
xmlNodePtr node)
{
GossipContactManagerPriv *priv;
- GossipJabber *jabber;
- GossipContact *contact;
+ GossipContact *own_contact;
const gchar *id;
const gchar *name;
gchar *new_name;
@@ -374,11 +562,10 @@
priv = GET_PRIV (manager);
- jabber = gossip_session_get_protocol (priv->session, account);
- contact = gossip_jabber_get_own_contact (jabber);
+ own_contact = gossip_contact_manager_get_own_contact (manager, account);
- id = gossip_contact_get_id (contact);
- name = gossip_contact_get_name (contact);
+ id = gossip_contact_get_id (own_contact);
+ name = gossip_contact_get_name (own_contact);
/* We only set the name here if it is the contact ID or NULL
* because this is only needed for offline purposes, we must
@@ -387,7 +574,7 @@
* correctly.
*/
if (G_STR_EMPTY (name) || (!G_STR_EMPTY (id) && strcmp (id, name) == 0)) {
- gossip_contact_set_name (contact, new_name);
+ gossip_contact_set_name (own_contact, new_name);
}
xmlFree (new_name);
@@ -483,7 +670,7 @@
gossip_debug (DEBUG_DOMAIN,
"Parsed %d contacts",
- g_list_length (priv->contacts));
+ g_hash_table_size (priv->contacts));
xmlFreeDoc(doc);
xmlFreeParserCtxt (ctxt);
@@ -506,6 +693,7 @@
xmlDocPtr doc;
xmlNodePtr root;
GList *accounts;
+ GList *contacts;
GList *l;
GHashTable *nodes;
gboolean create_file = FALSE;
@@ -571,8 +759,6 @@
account_manager = gossip_session_get_account_manager (priv->session);
accounts = gossip_account_manager_get_accounts (account_manager);
- gossip_debug (DEBUG_DOMAIN, "Checking account nodes exist");
-
for (l = accounts; l; l = l->next) {
xmlNodePtr node;
gboolean exists = FALSE;
@@ -605,16 +791,9 @@
}
if (exists) {
- gossip_debug (DEBUG_DOMAIN,
- "Using existing xml node for account:'%s'",
- account_name);
continue;
}
- gossip_debug (DEBUG_DOMAIN,
- "Creating xml node for account:'%s'",
- account_name);
-
/* Add node for this account */
node = xmlNewChild (root, NULL, "account", NULL);
xmlNewProp (node, "name", account_name);
@@ -625,26 +804,20 @@
/* This is a self contact */
for (l = accounts; l; l = l->next) {
xmlNodePtr node, child, p;
- GossipJabber *jabber;
- GossipContact *contact;
+ GossipContact *own_contact;
const gchar *name;
account = l->data;
- jabber = gossip_session_get_protocol (priv->session, account);
- contact = gossip_jabber_get_own_contact (jabber);
-
- name = gossip_contact_get_name (contact);
+ own_contact = gossip_contact_manager_get_own_contact (manager, account);
+
+ name = gossip_contact_get_name (own_contact);
node = g_hash_table_lookup (nodes, account);
/* Set self details */
p = gossip_xml_node_get_child (node, "self");
if (!p) {
- gossip_debug (DEBUG_DOMAIN,
- "Creating xml node for self contact for "
- "account:'%s'",
- gossip_account_get_name (account));
child = xmlNewChild (node, NULL, "self", NULL);
} else {
child = p;
@@ -655,26 +828,36 @@
child = xmlNewChild (child, NULL, "name", NULL);
} else {
child = p;
- }
-
- gossip_debug (DEBUG_DOMAIN,
- "Updating xml node for self contact for "
- "account:'%s' with name:'%s'",
- gossip_account_get_name (account),
- name);
-
+ }
+
xmlNodeSetContent (child, name);
}
- for (l = priv->contacts; l; l = l->next) {
- xmlNodePtr node, child, p;
- GossipContact *contact;
- const gchar *id;
- const gchar *name;
+ contacts = g_hash_table_get_keys (priv->contacts);
+
+ for (l = contacts; l; l = l->next) {
+ xmlNodePtr node, child, p;
+ GossipContact *contact;
+ GossipContactType type;
+ const gchar *id;
+ const gchar *name;
contact = l->data;
- account = gossip_contact_get_account (contact);
+ type = gossip_contact_get_type (contact);
+
+ if (type == GOSSIP_CONTACT_TYPE_CHATROOM ||
+ type == GOSSIP_CONTACT_TYPE_USER) {
+ /* Ignore the user contact since that is
+ * ourselves and we already added that above.
+ * Plus don't add chatroom contacts, they seem
+ * pointless, the nick is in the id itself so
+ * there is no need to store it offline.
+ */
+ continue;
+ }
+
+ account = gossip_contact_get_account (contact);
node = g_hash_table_lookup (nodes, account);
if (!node) {
@@ -693,11 +876,6 @@
/* This is a normal contact */
p = gossip_xml_node_find_child_prop_value (node, "id", id);
if (!p) {
- gossip_debug (DEBUG_DOMAIN,
- "Creating xml node for contact:'%s' for "
- "account:'%s'",
- id,
- gossip_account_get_name (account));
child = xmlNewChild (node, NULL, "contact", NULL);
xmlNewProp (child, "id", id);
} else {
@@ -706,22 +884,16 @@
p = gossip_xml_node_get_child (child, "name");
if (!p) {
- gossip_debug (DEBUG_DOMAIN, "Adding name node...");
child = xmlNewChild (child, NULL, "name", NULL);
} else {
child = p;
}
-
- gossip_debug (DEBUG_DOMAIN,
- "Updating xml node for contact:'%s' for "
- "account:'%s' to:'%s'",
- id,
- gossip_account_get_name (account),
- name);
-
+
xmlNodeSetContent (child, name);
}
+ g_list_free (contacts);
+
/* Save own contacts */
g_hash_table_destroy (nodes);
Modified: trunk/libgossip/gossip-contact-manager.h
==============================================================================
--- trunk/libgossip/gossip-contact-manager.h (original)
+++ trunk/libgossip/gossip-contact-manager.h Sat Jul 5 12:58:07 2008
@@ -46,15 +46,28 @@
GObjectClass parent_class;
};
-GType gossip_contact_manager_get_type (void) G_GNUC_CONST;
-gboolean gossip_contact_manager_add (GossipContactManager *manager,
+GType gossip_contact_manager_get_type (void) G_GNUC_CONST;
+
+gboolean gossip_contact_manager_add (GossipContactManager *manager,
GossipContact *contact);
-void gossip_contact_manager_remove (GossipContactManager *manager,
+void gossip_contact_manager_remove (GossipContactManager *manager,
GossipContact *contact);
-GossipContact * gossip_contact_manager_find (GossipContactManager *manager,
+GossipContact *gossip_contact_manager_find (GossipContactManager *manager,
+ GossipAccount *account,
+ const gchar *contact_id);
+GossipContact *gossip_contact_manager_find_extended (GossipContactManager *manager,
GossipAccount *account,
+ GossipContactType type,
const gchar *contact_id);
-gboolean gossip_contact_manager_store (GossipContactManager *manager);
+GossipContact *gossip_contact_manager_find_or_create (GossipContactManager *manager,
+ GossipAccount *account,
+ GossipContactType type,
+ const gchar *contact_id,
+ gboolean *created);
+GossipContact *gossip_contact_manager_get_own_contact (GossipContactManager *manager,
+ GossipAccount *account);
+gboolean gossip_contact_manager_store (GossipContactManager *manager);
+
G_END_DECLS
Modified: trunk/libgossip/gossip-contact.c
==============================================================================
--- trunk/libgossip/gossip-contact.c (original)
+++ trunk/libgossip/gossip-contact.c Sat Jul 5 12:58:07 2008
@@ -25,6 +25,7 @@
#include <glib/gi18n.h>
#include "gossip-contact.h"
+#include "gossip-jid.h"
#include "gossip-utils.h"
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CONTACT, GossipContactPriv))
@@ -61,8 +62,6 @@
guint param_id,
const GValue *value,
GParamSpec *pspec);
-static void contact_set_presences (GossipContact *contact,
- GList *presences);
enum {
PROP_0,
@@ -253,12 +252,13 @@
g_value_set_int (value, priv->type);
break;
case PROP_NAME:
- g_value_set_string (value,
- gossip_contact_get_name (GOSSIP_CONTACT (object)));
+ /* We call the function here because it returns
+ * something else if priv->name == NULL.
+ */
+ g_value_set_string (value, gossip_contact_get_name (GOSSIP_CONTACT (object)));
break;
case PROP_ID:
- g_value_set_string (value,
- gossip_contact_get_id (GOSSIP_CONTACT (object)));
+ g_value_set_string (value, priv->id);
break;
case PROP_PRESENCES:
g_value_set_pointer (value, priv->presences);
@@ -308,8 +308,8 @@
g_value_get_string (value));
break;
case PROP_PRESENCES:
- contact_set_presences (GOSSIP_CONTACT (object),
- g_value_get_pointer (value));
+ gossip_contact_set_presence_list (GOSSIP_CONTACT (object),
+ g_value_get_pointer (value));
break;
case PROP_GROUPS:
gossip_contact_set_groups (GOSSIP_CONTACT (object),
@@ -364,32 +364,24 @@
GossipContact *
gossip_contact_copy (GossipContact *contact)
{
- GossipContact *new_contact;
-
- new_contact = g_object_new (GOSSIP_TYPE_CONTACT, NULL);
- gossip_contact_copy_values (contact, new_contact);
-
- return new_contact;
-}
+ GossipContact *new_contact;
+ GossipContactPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
-void
-gossip_contact_copy_values (GossipContact *contact_from,
- GossipContact *contact_to)
-{
- GossipContactPriv *from_priv;
+ priv = GET_PRIV (contact);
- g_return_if_fail (GOSSIP_IS_CONTACT (contact_from));
- g_return_if_fail (GOSSIP_IS_CONTACT (contact_to));
+ new_contact = gossip_contact_new_full (gossip_contact_get_type (contact),
+ priv->account,
+ priv->id,
+ priv->name);
+
+ gossip_contact_set_subscription (new_contact, priv->subscription);
+ gossip_contact_set_avatar (new_contact, priv->avatar);
+ gossip_contact_set_groups (new_contact, priv->groups);
+ gossip_contact_set_presence_list (new_contact, priv->presences);
- from_priv = GET_PRIV (contact_from);
-
- gossip_contact_set_name (contact_to, from_priv->name);
- gossip_contact_set_id (contact_to, from_priv->id);
- gossip_contact_set_subscription (contact_to, from_priv->subscription);
- gossip_contact_set_avatar (contact_to, from_priv->avatar);
- gossip_contact_set_account (contact_to, from_priv->account);
- gossip_contact_set_groups (contact_to, from_priv->groups);
- contact_set_presences (contact_to, from_priv->presences);
+ return new_contact;
}
GossipContactType
@@ -542,6 +534,31 @@
return priv->presences;
}
+void
+gossip_contact_set_presence_list (GossipContact *contact,
+ GList *presences)
+{
+ GossipContactPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CONTACT (contact));
+
+ priv = GET_PRIV (contact);
+
+ if (priv->presences) {
+ g_list_foreach (priv->presences, (GFunc) g_object_unref, NULL);
+ g_list_free (priv->presences);
+ }
+
+ if (presences) {
+ priv->presences = g_list_copy (presences);
+ g_list_foreach (priv->presences, (GFunc) g_object_ref, NULL);
+ } else {
+ priv->presences = NULL;
+ }
+
+ g_object_notify (G_OBJECT (contact), "presences");
+}
+
GList *
gossip_contact_get_groups (GossipContact *contact)
{
@@ -614,25 +631,6 @@
g_object_notify (G_OBJECT (contact), "name");
}
-static void
-contact_set_presences (GossipContact *contact,
- GList *presences)
-{
- GossipContactPriv *priv;
-
- priv = GET_PRIV (contact);
-
- if (priv->presences) {
- g_list_foreach (priv->presences, (GFunc) g_object_unref, NULL);
- g_list_free (priv->presences);
- }
-
- priv->presences = g_list_copy (presences);
- g_list_foreach (priv->presences, (GFunc) g_object_ref, NULL);
-
- g_object_notify (G_OBJECT (contact), "presences");
-}
-
void
gossip_contact_set_avatar (GossipContact *contact,
GossipAvatar *avatar)
@@ -832,78 +830,66 @@
g_object_notify (G_OBJECT (contact), "subscription");
}
-gint
-gossip_contact_name_compare (gconstpointer a,
- gconstpointer b)
+guint
+gossip_contact_hash (gconstpointer key)
{
- g_return_val_if_fail (GOSSIP_IS_CONTACT (a), 0);
- g_return_val_if_fail (GOSSIP_IS_CONTACT (b), 0);
+ GossipContactPriv *priv;
+ guint hash = 0;
- return strcmp (gossip_contact_get_name (GOSSIP_CONTACT (a)),
- gossip_contact_get_name (GOSSIP_CONTACT (b)));
-}
+ g_return_val_if_fail (GOSSIP_IS_CONTACT (key), +1);
-gint
-gossip_contact_name_case_compare (gconstpointer a,
- gconstpointer b)
-{
- g_return_val_if_fail (GOSSIP_IS_CONTACT (a), 0);
- g_return_val_if_fail (GOSSIP_IS_CONTACT (b), 0);
+ priv = GET_PRIV (key);
- return gossip_contact_name_case_n_compare (a, b, -1);
-}
+ hash += gossip_account_hash (gossip_contact_get_account (GOSSIP_CONTACT (key)));
-gint
-gossip_contact_name_case_n_compare (gconstpointer a,
- gconstpointer b,
- gsize n)
-{
- const gchar *name_a, *name_b;
+ /* Use simple JID hash for all contacts except chatroom contacts */
+ if (priv->type == GOSSIP_CONTACT_TYPE_CHATROOM) {
+ if (priv->presences && priv->presences->data) {
+ GossipPresence *presence;
+ const gchar *resource;
- g_return_val_if_fail (GOSSIP_IS_CONTACT (a), 0);
- g_return_val_if_fail (GOSSIP_IS_CONTACT (b), 0);
+ presence = priv->presences->data;
+ resource = gossip_presence_get_resource (presence);
- name_a = gossip_contact_get_name (GOSSIP_CONTACT (a));
- name_b = gossip_contact_get_name (GOSSIP_CONTACT (b));
+ if (resource) {
+ hash += g_str_hash (resource);
+ }
+ }
+ }
- return gossip_strncasecmp (name_a, name_b, -1);
+ return hash;
}
gboolean
gossip_contact_equal (gconstpointer v1,
gconstpointer v2)
{
- GossipAccount *account_a;
- GossipAccount *account_b;
- const gchar *id_a;
- const gchar *id_b;
+ GossipAccount *account_a;
+ GossipAccount *account_b;
+ GossipContactType type_a;
+ GossipContactType type_b;
+ const gchar *id_a;
+ const gchar *id_b;
+ gboolean equal;
g_return_val_if_fail (GOSSIP_IS_CONTACT (v1), FALSE);
g_return_val_if_fail (GOSSIP_IS_CONTACT (v2), FALSE);
+ type_a = gossip_contact_get_type (GOSSIP_CONTACT (v1));
+ type_b = gossip_contact_get_type (GOSSIP_CONTACT (v2));
+
account_a = gossip_contact_get_account (GOSSIP_CONTACT (v1));
account_b = gossip_contact_get_account (GOSSIP_CONTACT (v2));
id_a = gossip_contact_get_id (GOSSIP_CONTACT (v1));
id_b = gossip_contact_get_id (GOSSIP_CONTACT (v2));
- return gossip_account_equal (account_a, account_b) && g_str_equal (id_a, id_b);
-}
-
-guint
-gossip_contact_hash (gconstpointer key)
-{
- GossipContactPriv *priv;
- guint hash = 0;
-
- g_return_val_if_fail (GOSSIP_IS_CONTACT (key), +1);
+ equal = TRUE;
+ equal &= type_a == type_b;
+ equal &= gossip_account_equal (account_a, account_b);
+ equal &= g_str_equal (id_a, id_b);
- priv = GET_PRIV (GOSSIP_CONTACT (key));
-
- hash += gossip_account_hash (gossip_contact_get_account (GOSSIP_CONTACT (key)));
- hash += g_str_hash (gossip_contact_get_id (GOSSIP_CONTACT (key)));
-
- return hash;
+ return equal;
}
gboolean
Modified: trunk/libgossip/gossip-contact.h
==============================================================================
--- trunk/libgossip/gossip-contact.h (original)
+++ trunk/libgossip/gossip-contact.h Sat Jul 5 12:58:07 2008
@@ -72,8 +72,7 @@
const gchar *id,
const gchar *name);
GossipContact * gossip_contact_copy (GossipContact *contact);
-void gossip_contact_copy_values (GossipContact *contact_from,
- GossipContact *contact_to);
+
GossipContactType gossip_contact_get_type (GossipContact *contact);
const gchar * gossip_contact_get_id (GossipContact *contact);
const gchar * gossip_contact_get_name (GossipContact *contact);
@@ -81,16 +80,9 @@
GdkPixbuf * gossip_contact_get_avatar_pixbuf (GossipContact *contact);
GossipAccount * gossip_contact_get_account (GossipContact *contact);
GossipVCard * gossip_contact_get_vcard (GossipContact *contact);
-void gossip_contact_add_presence (GossipContact *contact,
- GossipPresence *presence);
-void gossip_contact_remove_presence (GossipContact *contact,
- GossipPresence *presence);
-GossipPresence * gossip_contact_get_presence_for_resource (GossipContact *contact,
- const gchar *resource);
-GossipPresence * gossip_contact_get_active_presence (GossipContact *contact);
-GList * gossip_contact_get_presence_list (GossipContact *contact);
GList * gossip_contact_get_groups (GossipContact *contact);
GossipSubscription gossip_contact_get_subscription (GossipContact *contact);
+
void gossip_contact_set_type (GossipContact *contact,
GossipContactType type);
void gossip_contact_set_id (GossipContact *contact,
@@ -107,13 +99,20 @@
GList *categories);
void gossip_contact_set_subscription (GossipContact *contact,
GossipSubscription subscription);
-gint gossip_contact_name_compare (gconstpointer a,
- gconstpointer b);
-gint gossip_contact_name_case_compare (gconstpointer a,
- gconstpointer b);
-gint gossip_contact_name_case_n_compare (gconstpointer a,
- gconstpointer b,
- gsize n);
+
+/* Presence */
+void gossip_contact_add_presence (GossipContact *contact,
+ GossipPresence *presence);
+void gossip_contact_remove_presence (GossipContact *contact,
+ GossipPresence *presence);
+GossipPresence * gossip_contact_get_presence_for_resource (GossipContact *contact,
+ const gchar *resource);
+GossipPresence * gossip_contact_get_active_presence (GossipContact *contact);
+GList * gossip_contact_get_presence_list (GossipContact *contact);
+void gossip_contact_set_presence_list (GossipContact *contact,
+ GList *presences);
+
+/* Utility functions */
gboolean gossip_contact_equal (gconstpointer v1,
gconstpointer v2);
guint gossip_contact_hash (gconstpointer key);
Modified: trunk/libgossip/gossip-jabber-chatrooms.c
==============================================================================
--- trunk/libgossip/gossip-jabber-chatrooms.c (original)
+++ trunk/libgossip/gossip-jabber-chatrooms.c Sat Jul 5 12:58:07 2008
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Copyright (C) 2004-2006 Imendio AB
+ * Copyright (C) 2004-2008 Imendio AB
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -24,13 +24,14 @@
#include <string.h>
-#include <libgossip/gossip-debug.h>
-#include <libgossip/gossip-chatroom.h>
-#include <libgossip/gossip-chatroom-invite.h>
-#include <libgossip/gossip-ft.h>
-#include <libgossip/gossip-ft-provider.h>
-#include <libgossip/gossip-message.h>
-#include <libgossip/gossip-utils.h>
+#include "gossip-debug.h"
+#include "gossip-chatroom.h"
+#include "gossip-chatroom-invite.h"
+#include "gossip-chatroom-manager.h"
+#include "gossip-ft.h"
+#include "gossip-ft-provider.h"
+#include "gossip-message.h"
+#include "gossip-utils.h"
#include "gossip-jabber-chatrooms.h"
#include "gossip-jabber-disco.h"
@@ -48,83 +49,32 @@
#define JOIN_TIMEOUT 20000
struct _GossipJabberChatrooms {
- GossipJabber *jabber;
- GossipPresence *presence;
- LmConnection *connection;
+ GossipJabber *jabber;
+ GossipPresence *presence;
+ LmConnection *connection;
- GHashTable *room_id_hash;
- GHashTable *room_jid_hash;
+ GHashTable *chatrooms_by_id;
+ GHashTable *chatrooms_by_pointer;
+ GHashTable *chatrooms_by_jid;
+ GHashTable *join_timeouts;
+ GHashTable *join_callbacks;
};
-typedef struct {
- gint ref_count;
-
- GossipChatroom *chatroom;
-
- GossipJID *jid;
- GossipContact *own_contact;
-
- GSList *contacts;
-
- guint timeout_id;
-
- GossipJabberChatrooms *chatrooms;
- GossipChatroomJoinCb callback;
- gpointer user_data;
+static void logged_out_cb (GossipJabber *jabber,
+ GossipAccount *account,
+ gint reason,
+ GossipJabberChatrooms *chatrooms);
+static void join_timeout_destroy_notify_cb (gpointer data);
+static LmHandlerResult message_handler (LmMessageHandler *handler,
+ LmConnection *conn,
+ LmMessage *message,
+ GossipJabberChatrooms *chatrooms);
+static LmHandlerResult presence_handler (LmMessageHandler *handler,
+ LmConnection *conn,
+ LmMessage *message,
+ GossipJabberChatrooms *chatrooms);
- LmConnection *connection;
- LmMessageHandler *join_handler;
-} JabberChatroom;
-static void jabber_chatrooms_logged_out_cb (GossipJabber *jabber,
- GossipAccount *account,
- gint reason,
- GossipJabberChatrooms *chatrooms);
-static JabberChatroom * jabber_chatrooms_chatroom_new (GossipJabberChatrooms *chatrooms,
- GossipChatroom *chatroom);
-static JabberChatroom * jabber_chatrooms_chatroom_ref (JabberChatroom *room);
-static void jabber_chatrooms_chatroom_unref (JabberChatroom *room);
-static GossipChatroomId jabber_chatrooms_chatroom_get_id (JabberChatroom *room);
-static GossipContact * jabber_chatrooms_get_contact (JabberChatroom *room,
- GossipJID *jid,
- gboolean *new_contact);
-static LmHandlerResult jabber_chatrooms_message_handler (LmMessageHandler *handler,
- LmConnection *conn,
- LmMessage *message,
- GossipJabberChatrooms *chatrooms);
-static LmHandlerResult jabber_chatrooms_presence_handler (LmMessageHandler *handler,
- LmConnection *conn,
- LmMessage *message,
- GossipJabberChatrooms *chatrooms);
-static LmHandlerResult jabber_chatrooms_join_cb (LmMessageHandler *handler,
- LmConnection *connection,
- LmMessage *message,
- JabberChatroom *room);
-static void jabber_chatrooms_close (GossipJabberChatrooms *chatrooms,
- GossipChatroomId id);
-static GossipChatroomError
- jabber_chatrooms_error_from_code (gint code);
-static GArray * jabber_chatrooms_get_status (LmMessage *m);
-static gboolean jabber_chatrooms_has_status (GArray *status,
- gint code);
-static void jabber_chatrooms_get_rooms_foreach (gpointer key,
- JabberChatroom *room,
- GList **list);
-static void jabber_chatrooms_browse_rooms_cb (GossipJabberDisco *disco,
- GossipJabberDiscoItem *item,
- gboolean last_item,
- gboolean timeout,
- GError *error,
- GossipCallbackData *data);
-static void jabber_chatrooms_set_presence_foreach (gpointer key,
- JabberChatroom *room,
- GossipJabberChatrooms *chatrooms);
-
-static LmMessageNode * jabber_chatrooms_find_muc_user_node (LmMessageNode *parent_node);
-static GossipChatroomRole
- jabber_chatrooms_get_role (LmMessageNode *muc_node);
-static GossipChatroomAffiliation
- jabber_chatrooms_get_affiliation (LmMessageNode *muc_node);
GossipJabberChatrooms *
gossip_jabber_chatrooms_init (GossipJabber *jabber)
@@ -134,8 +84,8 @@
LmMessageHandler *handler;
g_return_val_if_fail (GOSSIP_IS_JABBER (jabber), NULL);
-
- connection = gossip_jabber_get_connection (jabber);
+
+ connection = _gossip_jabber_get_connection (jabber);
g_return_val_if_fail (connection != NULL, NULL);
chatrooms = g_new0 (GossipJabberChatrooms, 1);
@@ -144,18 +94,40 @@
chatrooms->connection = lm_connection_ref (connection);
chatrooms->presence = NULL;
- chatrooms->room_id_hash = g_hash_table_new (NULL, NULL);
- chatrooms->room_jid_hash = g_hash_table_new_full (gossip_jid_hash,
- gossip_jid_equal,
- (GDestroyNotify) gossip_jid_unref,
- NULL);
-
g_signal_connect (chatrooms->jabber, "disconnected",
- G_CALLBACK (jabber_chatrooms_logged_out_cb),
+ G_CALLBACK (logged_out_cb),
chatrooms);
- handler = lm_message_handler_new ((LmHandleMessageFunction) jabber_chatrooms_message_handler,
- chatrooms, NULL);
+ chatrooms->chatrooms_by_id =
+ g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify) g_object_unref);
+ chatrooms->chatrooms_by_pointer =
+ g_hash_table_new_full (gossip_chatroom_hash,
+ gossip_chatroom_equal,
+ (GDestroyNotify) g_object_unref,
+ NULL);
+ chatrooms->chatrooms_by_jid =
+ g_hash_table_new_full (gossip_jid_hash_without_resource,
+ gossip_jid_equal_without_resource,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+ chatrooms->join_timeouts =
+ g_hash_table_new_full (gossip_chatroom_hash,
+ gossip_chatroom_equal,
+ (GDestroyNotify) g_object_unref,
+ join_timeout_destroy_notify_cb);
+ chatrooms->join_callbacks =
+ g_hash_table_new_full (gossip_chatroom_hash,
+ gossip_chatroom_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) gossip_callback_data_free);
+
+ /* Set up message and presence handlers */
+ handler = lm_message_handler_new ((LmHandleMessageFunction) message_handler,
+ chatrooms,
+ NULL);
lm_connection_register_message_handler (chatrooms->connection,
handler,
@@ -163,8 +135,9 @@
LM_HANDLER_PRIORITY_NORMAL);
lm_message_handler_unref (handler);
- handler = lm_message_handler_new ((LmHandleMessageFunction) jabber_chatrooms_presence_handler,
- chatrooms, NULL);
+ handler = lm_message_handler_new ((LmHandleMessageFunction) presence_handler,
+ chatrooms,
+ NULL);
lm_connection_register_message_handler (chatrooms->connection,
handler,
@@ -186,13 +159,25 @@
return;
}
+ g_hash_table_unref (chatrooms->chatrooms_by_id);
+ chatrooms->chatrooms_by_id = NULL;
+
+ g_hash_table_unref (chatrooms->chatrooms_by_pointer);
+ chatrooms->chatrooms_by_pointer = NULL;
+
+ g_hash_table_unref (chatrooms->chatrooms_by_jid);
+ chatrooms->chatrooms_by_jid = NULL;
+
+ g_hash_table_unref (chatrooms->join_timeouts);
+ chatrooms->join_timeouts = NULL;
+
+ g_hash_table_unref (chatrooms->join_callbacks);
+ chatrooms->join_timeouts = NULL;
+
g_signal_handlers_disconnect_by_func (chatrooms->jabber,
- jabber_chatrooms_logged_out_cb,
+ logged_out_cb,
chatrooms);
- g_hash_table_destroy (chatrooms->room_id_hash);
- g_hash_table_destroy (chatrooms->room_jid_hash);
-
if (chatrooms->presence) {
g_object_unref (chatrooms->presence);
}
@@ -204,137 +189,42 @@
}
static void
-jabber_chatrooms_logged_out_cb (GossipJabber *jabber,
- GossipAccount *account,
- gint reason,
- GossipJabberChatrooms *chatrooms)
-{
- GList *rooms;
- GList *l;
-
- /* Clean up chat rooms */
- rooms = gossip_jabber_chatrooms_get_rooms (chatrooms);
-
- for (l = rooms; l; l = l->next) {
- GossipChatroomId id;
-
- id = GPOINTER_TO_INT (l->data);
- gossip_jabber_chatrooms_leave (chatrooms, id);
- }
-
- g_list_free (rooms);
-}
-
-static JabberChatroom *
-jabber_chatrooms_chatroom_new (GossipJabberChatrooms *chatrooms,
- GossipChatroom *chatroom)
+logged_out_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
- GossipJabber *jabber;
- GossipContact *own_contact;
- JabberChatroom *room;
- gchar *jid_str;
-
- jabber = chatrooms->jabber;
-
- room = g_new0 (JabberChatroom, 1);
-
- room->ref_count = 1;
- room->chatroom = g_object_ref (chatroom);
-
- jid_str = g_strdup_printf ("%s/%s",
- gossip_chatroom_get_id_str (chatroom),
- gossip_chatroom_get_nick (chatroom));
- room->jid = gossip_jid_new (jid_str);
- g_free (jid_str);
-
- room->contacts = NULL;
-
- /* What we do here is copy the contact instead of reference
- * it, plus we change the name according to how the user wants
- * their nickname in the chat room.
- */
- own_contact = gossip_jabber_get_own_contact (jabber);
- room->own_contact = gossip_contact_copy (own_contact);
- gossip_contact_set_name (room->own_contact,
- gossip_chatroom_get_nick (chatroom));
+ GossipJabberChatrooms *chatrooms;
+ GossipChatroomId id;
- return room;
-}
+ id = GPOINTER_TO_INT (key);
+ chatrooms = (GossipJabberChatrooms *) user_data;
-static JabberChatroom *
-jabber_chatrooms_chatroom_ref (JabberChatroom *room)
-{
- if (!room) {
- return NULL;
- }
-
- room->ref_count++;
- return room;
+ gossip_jabber_chatrooms_leave (chatrooms, id);
}
static void
-jabber_chatrooms_chatroom_unref (JabberChatroom *room)
+logged_out_cb (GossipJabber *jabber,
+ GossipAccount *account,
+ gint reason,
+ GossipJabberChatrooms *chatrooms)
{
- if (!room) {
- return;
- }
-
- room->ref_count--;
-
- if (room->ref_count > 0) {
- return;
- }
-
- g_object_unref (room->chatroom);
-
- gossip_jid_unref (room->jid);
-
- g_slist_foreach (room->contacts, (GFunc)g_object_unref, NULL);
- g_slist_free (room->contacts);
-
- g_object_unref (room->own_contact);
-
- if (room->timeout_id) {
- g_source_remove (room->timeout_id);
- room->timeout_id = 0;
- }
-
- if (room->join_handler) {
- lm_connection_unregister_message_handler (room->connection,
- room->join_handler,
- LM_MESSAGE_TYPE_PRESENCE);
- room->join_handler = NULL;
- }
-
- if (room->connection) {
- lm_connection_unref (room->connection);
- room->connection = NULL;
- }
-
- g_free (room);
-}
-
-static GossipChatroomId
-jabber_chatrooms_chatroom_get_id (JabberChatroom *room)
-{
- g_return_val_if_fail (room != NULL, 0);
- g_return_val_if_fail (GOSSIP_IS_CHATROOM (room->chatroom), 0);
-
- return gossip_chatroom_get_id (room->chatroom);
+ g_hash_table_foreach (chatrooms->chatrooms_by_id,
+ logged_out_foreach,
+ chatrooms);
}
static LmHandlerResult
-jabber_chatrooms_message_handler (LmMessageHandler *handler,
- LmConnection *conn,
- LmMessage *m,
- GossipJabberChatrooms *chatrooms)
+message_handler (LmMessageHandler *handler,
+ LmConnection *conn,
+ LmMessage *m,
+ GossipJabberChatrooms *chatrooms)
{
+ LmMessageNode *node;
GossipJID *jid;
- GossipMessage *message;
- GossipContact *contact;
+ GossipChatroom *chatroom;
GossipChatroomId id;
- JabberChatroom *room;
- LmMessageNode *node;
+ GossipContact *contact;
+ GossipMessage *message;
const gchar *from;
if (lm_message_get_sub_type (m) != LM_MESSAGE_SUB_TYPE_GROUPCHAT) {
@@ -344,38 +234,50 @@
from = lm_message_node_get_attribute (m->node, "from");
jid = gossip_jid_new (from);
- room = g_hash_table_lookup (chatrooms->room_jid_hash, jid);
- if (!room) {
- gossip_jid_unref (jid);
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_jid, jid);
+
+ if (!chatroom) {
+ g_object_unref (jid);
+ return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
- id = jabber_chatrooms_chatroom_get_id (room);
+ id = gossip_chatroom_get_id (chatroom);
+
+ contact = gossip_jabber_get_contact_from_jid (chatrooms->jabber,
+ from,
+ FALSE,
+ FALSE,
+ FALSE);
node = lm_message_node_get_child (m->node, "body");
if (node) {
if (gossip_jid_get_resource (jid) == NULL) {
g_signal_emit_by_name (chatrooms->jabber,
"chatroom-new-event",
- id, node->value);
+ id,
+ node->value);
} else {
GossipTime timestamp;
timestamp = gossip_jabber_get_message_timestamp (m);
+ /* NOTE: We don't use the chatroom contact
+ * here, we use the actual REAL contact
+ * instead, this is to keep things sane in
+ * the UI code.
+ */
message = gossip_message_new (GOSSIP_MESSAGE_TYPE_CHAT_ROOM,
- room->own_contact);
+ gossip_jabber_get_own_contact (chatrooms->jabber));
timestamp = gossip_jabber_get_message_timestamp (m);
gossip_message_set_timestamp (message, timestamp);
-
- contact = jabber_chatrooms_get_contact (room, jid, NULL);
gossip_message_set_sender (message, contact);
gossip_message_set_body (message, node->value);
g_signal_emit_by_name (chatrooms->jabber,
"chatroom-new-message",
- id, message);
+ id,
+ message);
g_object_unref (message);
}
@@ -383,319 +285,218 @@
node = lm_message_node_get_child (m->node, "subject");
if (node) {
- contact = jabber_chatrooms_get_contact (room, jid, NULL);
-
- g_signal_emit_by_name (chatrooms->jabber,
- "chatroom-subject-changed",
- id, contact, node->value);
+ /* We don't handle subject change twice! Above, you
+ * may notice that we emit the "chatroom-new-event"
+ * signal. This is used to emit the subject for the
+ * chatroom when there is NO contact. The subject
+ * here has the same content EXCEPT that it doesn't
+ * include the name of the person that set the
+ * subject, just what the subject _IS_. We only use
+ * this when we know the contact.
+ */
+ if (contact) {
+ g_signal_emit_by_name (chatrooms->jabber,
+ "chatroom-subject-changed",
+ id,
+ contact,
+ node->value);
+ }
}
- gossip_jid_unref (jid);
+ g_object_unref (jid);
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
-static GossipContact *
-jabber_chatrooms_get_contact (JabberChatroom *room,
- GossipJID *jid,
- gboolean *new_contact)
+static GossipChatroomError
+error_from_code (const gchar *xmlns,
+ gint code)
{
- GossipContact *contact;
- GSList *l;
- const gchar *id;
- const gchar *name;
-
- id = gossip_jid_get_full (jid);
-
- for (l = room->contacts; l; l = l->next) {
- contact = GOSSIP_CONTACT (l->data);
-
- if (g_ascii_strcasecmp (gossip_contact_get_id (contact), id) == 0) {
- if (new_contact) {
- *new_contact = FALSE;
- }
-
- return contact;
+ if (G_STR_EMPTY (xmlns)) {
+ /* 503 is really service not available,
+ * 403 is really subject change not authorized
+ * 405 is really kick/ban/etc not authorized
+ */
+ switch (code) {
+ case 400: return GOSSIP_CHATROOM_ERROR_BAD_REQUEST;
+ case 403: return GOSSIP_CHATROOM_ERROR_UNAUTHORIZED_REQUEST;
+ case 405: return GOSSIP_CHATROOM_ERROR_UNAUTHORIZED_REQUEST;
+ case 409: return GOSSIP_CHATROOM_ERROR_NICK_IN_USE;
+ case 503: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
+
+ /* Legacy Errors */
+ case 502: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
+ case 504: return GOSSIP_CHATROOM_ERROR_TIMED_OUT;
+ default:
+ break;
}
}
- if (new_contact) {
- *new_contact = TRUE;
- }
-
- name = gossip_jid_get_resource (jid);
- if (!name) {
- name = id;
- }
-
- contact = g_object_new (GOSSIP_TYPE_CONTACT,
- "account", gossip_contact_get_account (room->own_contact),
- "id", id,
- "name", name,
- NULL);
-
- room->contacts = g_slist_prepend (room->contacts, contact);
-
- return contact;
-}
-
-static GossipChatroomError
-jabber_chatrooms_error_from_code (gint code)
-{
- switch (code) {
- case 401: return GOSSIP_CHATROOM_ERROR_PASSWORD_INVALID_OR_MISSING;
- case 403: return GOSSIP_CHATROOM_ERROR_USER_BANNED;
- case 404: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
- case 405: return GOSSIP_CHATROOM_ERROR_ROOM_CREATION_RESTRICTED;
- case 406: return GOSSIP_CHATROOM_ERROR_USE_RESERVED_ROOM_NICK;
- case 407: return GOSSIP_CHATROOM_ERROR_NOT_ON_MEMBERS_LIST;
- case 409: return GOSSIP_CHATROOM_ERROR_NICK_IN_USE;
- case 503: return GOSSIP_CHATROOM_ERROR_MAXIMUM_USERS_REACHED;
-
- /* Legacy Errors */
- case 502: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
- case 504: return GOSSIP_CHATROOM_ERROR_TIMED_OUT;
-
- default:
- break;
+ if (strcmp (xmlns, XMPP_MUC_XMLNS) == 0) {
+ switch (code) {
+ /* 503 could mean room is full */
+ case 401: return GOSSIP_CHATROOM_ERROR_PASSWORD_INVALID_OR_MISSING;
+ case 403: return GOSSIP_CHATROOM_ERROR_USER_BANNED;
+ case 404: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
+ case 405: return GOSSIP_CHATROOM_ERROR_ROOM_CREATION_RESTRICTED;
+ case 406: return GOSSIP_CHATROOM_ERROR_USE_RESERVED_ROOM_NICK;
+ case 407: return GOSSIP_CHATROOM_ERROR_NOT_ON_MEMBERS_LIST;
+ case 409: return GOSSIP_CHATROOM_ERROR_NICK_IN_USE;
+ case 503: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
+ default:
+ break;
+ }
+ } else if (strcmp (xmlns, XMPP_MUC_USER_XMLNS) == 0) {
+ switch (code) {
+ case 401: return GOSSIP_CHATROOM_ERROR_PASSWORD_INVALID_OR_MISSING;
+ case 403: return GOSSIP_CHATROOM_ERROR_FORBIDDEN;
+ case 404: return GOSSIP_CHATROOM_ERROR_ROOM_NOT_FOUND;
+ case 405: return GOSSIP_CHATROOM_ERROR_ROOM_CREATION_RESTRICTED;
+ case 406: return GOSSIP_CHATROOM_ERROR_USE_RESERVED_ROOM_NICK;
+ case 407: return GOSSIP_CHATROOM_ERROR_NOT_ON_MEMBERS_LIST;
+ case 409: return GOSSIP_CHATROOM_ERROR_NICK_IN_USE;
+ default:
+ break;
+ }
+ } else if (strcmp (xmlns, XMPP_MUC_OWNER_XMLNS) == 0 ||
+ strcmp (xmlns, XMPP_MUC_ADMIN_XMLNS) == 0) {
+ switch (code) {
+ case 403: return GOSSIP_CHATROOM_ERROR_FORBIDDEN;
+ default:
+ break;
+ }
}
return GOSSIP_CHATROOM_ERROR_UNKNOWN;
}
-static GArray *
-jabber_chatrooms_get_status (LmMessage *m)
+static LmMessageNode *
+find_muc_user_node (LmMessageNode *parent_node)
{
- LmMessageNode *node;
- GArray *status = NULL;
+ LmMessageNode *child;
- if (!m) {
- return NULL;
- }
+ /* Should have a function in Loudmouth to find a child with xmlns */
+ child = parent_node->children;
- node = lm_message_node_get_child (m->node, "x");
- if (!node) {
+ if (!child) {
return NULL;
}
- node = node->children;
-
- while (node) {
- if (!node) {
- break;
- }
-
- if (node->name && strcmp (node->name, "status") == 0) {
- const gchar *code;
-
- code = lm_message_node_get_attribute (node, "code");
- if (code) {
- gint value;
+ while (child) {
+ if (strcmp (child->name, "x") == 0) {
+ const gchar *xmlns;
- if (!status) {
- status = g_array_new (FALSE, FALSE, sizeof (gint));
- }
+ xmlns = lm_message_node_get_attribute (child, "xmlns");
- value = atoi (code);
- g_array_append_val (status, value);
+ if (xmlns && strcmp (xmlns, XMPP_MUC_USER_XMLNS) == 0) {
+ return child;
}
}
- node = node->next;
+ child = child->next;
}
- return status;
+ return NULL;
}
-static gboolean
-jabber_chatrooms_has_status (GArray *status,
- gint code)
+static GossipChatroomRole
+get_role (LmMessageNode *muc_node)
{
- gint i = 0;
+ LmMessageNode *item_node;
+ const gchar *role;
- if (!status) {
- return FALSE;
- }
-
- for (i = 0; i < status->len; i++) {
- if (g_array_index (status, gint, i) == code) {
- return TRUE;
- }
+ if (!muc_node) {
+ return GOSSIP_CHATROOM_ROLE_NONE;
}
-
- return FALSE;
-}
-
-static LmHandlerResult
-jabber_chatrooms_presence_handler (LmMessageHandler *handler,
- LmConnection *conn,
- LmMessage *m,
- GossipJabberChatrooms *chatrooms)
-{
- const gchar *from;
- GossipJID *jid;
- JabberChatroom *room;
- GossipContact *contact;
- GossipPresence *presence;
- GossipPresenceState p_state;
- GossipChatroomId id;
- LmMessageSubType type;
- LmMessageNode *node;
- gboolean new_contact;
- gboolean was_offline;
- LmMessageNode *muc_user_node;
- GossipChatroomContactInfo muc_contact_info;
- from = lm_message_node_get_attribute (m->node, "from");
- jid = gossip_jid_new (from);
-
- room = g_hash_table_lookup (chatrooms->room_jid_hash, jid);
- if (!room) {
- gossip_jid_unref (jid);
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ item_node = lm_message_node_get_child (muc_node, "item");
+ if (!item_node) {
+ return GOSSIP_CHATROOM_ROLE_NONE;
}
- id = jabber_chatrooms_chatroom_get_id (room);
-
- gossip_debug (DEBUG_DOMAIN, "Presence from: %s", from);
-
- type = lm_message_get_sub_type (m);
- switch (type) {
- case LM_MESSAGE_SUB_TYPE_AVAILABLE:
- /* get details */
- contact = jabber_chatrooms_get_contact (room, jid,
- &new_contact);
-
- presence = gossip_presence_new ();
- node = lm_message_node_get_child (m->node, "show");
- if (node) {
- p_state = gossip_jabber_presence_state_from_str (node->value);
- gossip_presence_set_state (presence, p_state);
- }
- node = lm_message_node_get_child (m->node, "status");
- if (node) {
- gossip_presence_set_status (presence, node->value);
- }
-
- /* Should signal joined if contact was found but offline */
- was_offline = !gossip_contact_is_online (contact);
- gossip_contact_add_presence (contact, presence);
- g_object_unref (presence);
-
- muc_user_node = jabber_chatrooms_find_muc_user_node (m->node);
- muc_contact_info.role = jabber_chatrooms_get_role (muc_user_node);
- muc_contact_info.affiliation = jabber_chatrooms_get_affiliation (muc_user_node);
-
- /* Is contact new or updated */
- if (new_contact || was_offline) {
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Presence for new joining contact:'%s'",
- id, gossip_jid_get_full (jid));
- gossip_chatroom_contact_joined (room->chatroom,
- contact,
- &muc_contact_info);
- } else {
- gossip_chatroom_set_contact_info (room->chatroom,
- contact,
- &muc_contact_info);
- }
- break;
-
- case LM_MESSAGE_SUB_TYPE_UNAVAILABLE:
- contact = jabber_chatrooms_get_contact (room, jid, NULL);
- if (gossip_jid_equals (jid, room->jid)) {
- gossip_debug (DEBUG_DOMAIN, "ID[%d] We have been kicked!", id);
- gossip_chatroom_set_status (room->chatroom, GOSSIP_CHATROOM_STATUS_INACTIVE);
- g_signal_emit_by_name (chatrooms->jabber, "chatroom-kicked", id);
- jabber_chatrooms_close (chatrooms, id);
- } else {
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Contact left:'%s'",
- id, gossip_jid_get_full (jid));
- gossip_chatroom_contact_left (room->chatroom, contact);
- room->contacts = g_slist_remove (room->contacts, contact);
- g_object_unref (contact);
- }
- break;
-
- case LM_MESSAGE_SUB_TYPE_ERROR:
- node = lm_message_node_get_child (m->node, "error");
- if (node) {
- GossipChatroomError error;
- const gchar *str;
- gint code;
-
- str = lm_message_node_get_attribute (node, "code");
- code = str ? atoi (str) : 0;
-
- error = jabber_chatrooms_error_from_code (code);
- gossip_debug (DEBUG_DOMAIN, "ID[%d] %s",
- id, gossip_chatroom_error_to_string (error));
-
- g_signal_emit_by_name (chatrooms->jabber,
- "chatroom-error",
- id, error);
- }
- break;
-
- default:
- gossip_debug (DEBUG_DOMAIN, "Presence not handled for:'%s'",
- gossip_jid_get_full (jid));
- gossip_jid_unref (jid);
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ role = lm_message_node_get_attribute (item_node, "role");
+ if (!role) {
+ return GOSSIP_CHATROOM_ROLE_NONE;
}
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ if (strcmp (role, "moderator") == 0) {
+ return GOSSIP_CHATROOM_ROLE_MODERATOR;
+ }
+ else if (strcmp (role, "participant") == 0) {
+ return GOSSIP_CHATROOM_ROLE_PARTICIPANT;
+ }
+ else if (strcmp (role, "visitor") == 0) {
+ return GOSSIP_CHATROOM_ROLE_VISITOR;
+ } else {
+ return GOSSIP_CHATROOM_ROLE_NONE;
+ }
}
-static gboolean
-jabber_chatrooms_join_timeout_cb (JabberChatroom *room)
+static GossipChatroomAffiliation
+get_affiliation (LmMessageNode *muc_node)
{
- GossipChatroomId id;
- GossipChatroomError error;
- GossipJabberChatrooms *chatrooms;
-
- room->timeout_id = 0;
+ LmMessageNode *item_node;
+ const gchar *affiliation;
- if (room->join_handler) {
- lm_message_handler_unref (room->join_handler);
- room->join_handler = NULL;
+ if (!muc_node) {
+ return GOSSIP_CHATROOM_AFFILIATION_NONE;
}
- id = jabber_chatrooms_chatroom_get_id (room);
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Join timed out (internally)", id);
-
- /* Set chatroom status and error */
- error = GOSSIP_CHATROOM_ERROR_TIMED_OUT;
-
- gossip_chatroom_set_last_error (room->chatroom, error);
- gossip_chatroom_set_status (room->chatroom, GOSSIP_CHATROOM_STATUS_ERROR);
+ item_node = lm_message_node_get_child (muc_node, "item");
+ if (!item_node) {
+ return GOSSIP_CHATROOM_AFFILIATION_NONE;
+ }
- /* Call callback */
- chatrooms = room->chatrooms;
+ affiliation = lm_message_node_get_attribute (item_node, "affiliation");
+ if (!affiliation) {
+ return GOSSIP_CHATROOM_AFFILIATION_NONE;
+ }
- if (room->callback != NULL) {
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Calling back... (timed out)", id);
- (room->callback) (GOSSIP_CHATROOM_PROVIDER (chatrooms->jabber),
- id,
- error,
- room->user_data);
+ if (strcmp (affiliation, "owner") == 0) {
+ return GOSSIP_CHATROOM_AFFILIATION_OWNER;
+ }
+ else if (strcmp (affiliation, "admin") == 0) {
+ return GOSSIP_CHATROOM_AFFILIATION_ADMIN;
+ }
+ else if (strcmp (affiliation, "member") == 0) {
+ return GOSSIP_CHATROOM_AFFILIATION_MEMBER;
+ }
+ else if (strcmp (affiliation, "outcast") == 0) {
+ return GOSSIP_CHATROOM_AFFILIATION_OUTCAST;
+ } else {
+ return GOSSIP_CHATROOM_AFFILIATION_NONE;
}
+}
- /* Clean up */
- g_hash_table_remove (chatrooms->room_id_hash, GINT_TO_POINTER (id));
- g_hash_table_remove (chatrooms->room_jid_hash, room->jid);
+static void
+leave_chatroom (GossipJabberChatrooms *chatrooms,
+ GossipChatroom *chatroom)
+{
+ GossipJID *jid;
+ GossipChatroomId id;
- /* Clean up callback data */
- room->callback = NULL;
- room->user_data = NULL;
+ id = gossip_chatroom_get_id (chatroom);
- jabber_chatrooms_chatroom_unref (room);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Leaving room",
+ id);
- return FALSE;
+ gossip_chatroom_set_last_error (chatroom, GOSSIP_CHATROOM_ERROR_NONE);
+ gossip_chatroom_set_status (chatroom, GOSSIP_CHATROOM_STATUS_INACTIVE);
+
+ jid = gossip_jid_new (gossip_chatroom_get_id_str (chatroom));
+
+ g_hash_table_remove (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+ g_hash_table_remove (chatrooms->chatrooms_by_pointer, chatroom);
+ g_hash_table_remove (chatrooms->chatrooms_by_jid, jid);
+
+ g_object_unref (jid);
}
static void
-jabber_chatrooms_create_instant_room (JabberChatroom *room)
+create_instant_room (LmConnection *connection,
+ GossipChatroom *chatroom)
{
LmMessage *m;
LmMessageNode *node;
@@ -707,7 +508,7 @@
LM_MESSAGE_TYPE_IQ,
LM_MESSAGE_SUB_TYPE_SET);
- account = gossip_contact_get_account (room->own_contact);
+ account = gossip_chatroom_get_account (chatroom);
from = g_strconcat (gossip_account_get_id (account),
"/",
gossip_account_get_resource (account),
@@ -715,7 +516,7 @@
lm_message_node_set_attribute (m->node, "from", from);
g_free (from);
- to = gossip_chatroom_get_id_str (room->chatroom);
+ to = gossip_chatroom_get_id_str (chatroom);
lm_message_node_set_attribute (m->node, "to", to);
node = lm_message_node_add_child (m->node, "query", NULL);
@@ -727,12 +528,13 @@
"type", "submit",
NULL);
- lm_connection_send (room->connection, m, NULL);
+ lm_connection_send (connection, m, NULL);
lm_message_unref (m);
}
static void
-jabber_chatrooms_create_reserved_room (JabberChatroom *room)
+create_reserved_room (LmConnection *connection,
+ GossipChatroom *chatroom)
{
LmMessage *m;
LmMessageNode *node;
@@ -747,7 +549,7 @@
LM_MESSAGE_TYPE_IQ,
LM_MESSAGE_SUB_TYPE_SET);
- account = gossip_contact_get_account (room->own_contact);
+ account = gossip_chatroom_get_account (chatroom);
from = g_strconcat (gossip_account_get_id (account),
"/",
gossip_account_get_resource (account),
@@ -755,7 +557,7 @@
lm_message_node_set_attribute (m->node, "from", from);
g_free (from);
- to = gossip_chatroom_get_id_str (room->chatroom);
+ to = gossip_chatroom_get_id_str (chatroom);
lm_message_node_set_attribute (m->node, "to", to);
node = lm_message_node_add_child (m->node, "query", NULL);
@@ -768,8 +570,8 @@
NULL);
/* FIXME: This is a shortcut for now, we should use their forms */
- name = gossip_chatroom_get_name (room->chatroom);
- password = gossip_chatroom_get_password (room->chatroom);
+ name = gossip_chatroom_get_name (chatroom);
+ password = gossip_chatroom_get_password (chatroom);
child = lm_message_node_add_child (node, "field", NULL);
lm_message_node_set_attributes (child, "var", "muc#roomconfig_roomname", NULL);
@@ -784,12 +586,13 @@
lm_message_node_add_child (child, "value", G_STR_EMPTY (password) ? "" : password);
/* Finally send */
- lm_connection_send (room->connection, m, NULL);
+ lm_connection_send (connection, m, NULL);
lm_message_unref (m);
}
static void
-jabber_chatrooms_request_reserved_room (JabberChatroom *room)
+request_reserved_room (LmConnection *connection,
+ GossipChatroom *chatroom)
{
LmMessage *m;
LmMessageNode *node;
@@ -801,7 +604,7 @@
LM_MESSAGE_TYPE_IQ,
LM_MESSAGE_SUB_TYPE_GET);
- account = gossip_contact_get_account (room->own_contact);
+ account = gossip_chatroom_get_account (chatroom);
from = g_strconcat (gossip_account_get_id (account),
"/",
gossip_account_get_resource (account),
@@ -809,173 +612,410 @@
lm_message_node_set_attribute (m->node, "from", from);
g_free (from);
- to = gossip_chatroom_get_id_str (room->chatroom);
+ to = gossip_chatroom_get_id_str (chatroom);
lm_message_node_set_attribute (m->node, "to", to);
node = lm_message_node_add_child (m->node, "query", NULL);
lm_message_node_set_attributes (node, "xmlns", XMPP_MUC_OWNER_XMLNS, NULL);
- lm_connection_send (room->connection, m, NULL);
+ lm_connection_send (connection, m, NULL);
lm_message_unref (m);
}
-static LmHandlerResult
-jabber_chatrooms_join_cb (LmMessageHandler *handler,
- LmConnection *connection,
- LmMessage *m,
- JabberChatroom *room)
-{
- GossipJabberChatrooms *chatrooms;
- GossipChatroomError error;
- GossipChatroomStatus status;
- GossipChatroomId id;
- GossipChatroomId id_found;
- LmMessageSubType type;
- LmMessageNode *node = NULL;
- const gchar *from;
- GossipJID *jid;
- JabberChatroom *room_found;
- GArray *status_codes;
- gboolean room_match = FALSE;
+static gboolean
+join_finish (GossipJabberChatrooms *chatrooms,
+ GossipChatroom *chatroom,
+ LmMessage *m)
+{
+ GossipChatroomError error;
+ GossipChatroomStatus status;
+ GossipChatroomId id;
+ GossipCallbackData *data;
+ LmMessageSubType type;
+ LmMessageNode *node = NULL;
- if (!room || !room->join_handler) {
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
- }
+ /* Get room id */
+ id = gossip_chatroom_get_id (chatroom);
- chatrooms = room->chatrooms;
+ /* Clean up the join timeout */
+ g_hash_table_remove (chatrooms->join_timeouts, chatroom);
- /* Get room id */
- id = jabber_chatrooms_chatroom_get_id (room);
+ /* Check status code */
+ if (gossip_jabber_get_message_has_status (m, 201)) {
+ /* Room was created for us */
+ if (0) {
+ request_reserved_room (chatrooms->connection, chatroom);
+ create_instant_room (chatrooms->connection, chatroom);
+ } else {
+ create_reserved_room (chatrooms->connection, chatroom);
+ }
+ }
- from = lm_message_node_get_attribute (m->node, "from");
- jid = gossip_jid_new (from);
+ /* Check for error */
+ type = lm_message_get_sub_type (m);
+ if (type == LM_MESSAGE_SUB_TYPE_ERROR) {
+ node = lm_message_node_get_child (m->node, "error");
+ }
+
+ if (node) {
+ const gchar *xmlns = NULL;
+ const gchar *code_str;
+ gint code;
- room_found = g_hash_table_lookup (chatrooms->room_jid_hash, jid);
- gossip_jid_unref (jid);
+ code_str = lm_message_node_get_attribute (node, "code");
+ code = code_str ? atoi (code_str) : 0;
- if (room_found) {
- id_found = jabber_chatrooms_chatroom_get_id (room_found);
- if (id == id_found) {
- room_match = TRUE;
+ node = lm_message_node_get_child (m->node, "x");
+ if (node) {
+ xmlns = lm_message_node_get_attribute (node, "xmlns");
}
+
+ error = error_from_code (xmlns, code);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] %s",
+ id,
+ gossip_chatroom_error_to_string (error));
+
+ /* Set room state */
+ status = GOSSIP_CHATROOM_STATUS_ERROR;
+ } else {
+ error = GOSSIP_CHATROOM_ERROR_NONE;
+ status = GOSSIP_CHATROOM_STATUS_ACTIVE;
}
- if (!room_match) {
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ gossip_chatroom_set_last_error (chatroom, error);
+ gossip_chatroom_set_status (chatroom, status);
+
+ data = g_hash_table_lookup (chatrooms->join_callbacks, chatroom);
+
+ if (data && data->callback) {
+ GossipChatroomJoinCb func;
+
+ func = (GossipChatroomJoinCb) data->callback;
+
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Calling back...",
+ id);
+ (func) (GOSSIP_CHATROOM_PROVIDER (chatrooms->jabber),
+ id,
+ error,
+ data->user_data);
}
- /* Clean up the join timeout */
- if (room->timeout_id) {
- g_source_remove (room->timeout_id);
- room->timeout_id = 0;
+ /* Clean up the user data */
+ g_hash_table_remove (chatrooms->join_callbacks, chatroom);
+
+ /* If we have an error, clean up */
+ if (error != GOSSIP_CHATROOM_ERROR_NONE) {
+ GossipJID *jid;
+ GossipChatroomId id;
+
+ /* Clean up */
+ id = gossip_chatroom_get_id (chatroom);
+ jid = gossip_jid_new (gossip_chatroom_get_id_str (chatroom));
+
+ g_hash_table_remove (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+ g_hash_table_remove (chatrooms->chatrooms_by_pointer, chatroom);
+ g_hash_table_remove (chatrooms->chatrooms_by_jid, jid);
+
+ g_object_unref (jid);
+
+ return FALSE;
}
- /* Clean up handler */
- if (room->join_handler) {
- lm_message_handler_unref (room->join_handler);
- room->join_handler = NULL;
+ return TRUE;
+}
+
+static gchar *
+get_new_id_for_new_nick (GossipContact *contact,
+ const gchar *new_nick)
+{
+ GossipJID *jid;
+ const gchar *id_str;
+ const gchar *id_str_without_resource;
+ gchar *id_str_with_new_nick;
+
+ id_str = gossip_contact_get_id (contact);
+ jid = gossip_jid_new (id_str);
+ id_str_without_resource = gossip_jid_get_without_resource (jid);
+ id_str_with_new_nick = g_strconcat (id_str_without_resource, "/", new_nick, NULL);
+ g_object_unref (jid);
+
+ return id_str_with_new_nick;
+}
+
+static LmHandlerResult
+presence_handler (LmMessageHandler *handler,
+ LmConnection *connection,
+ LmMessage *m,
+ GossipJabberChatrooms *chatrooms)
+{
+ const gchar *from;
+ GossipJID *jid;
+ GossipContact *own_contact;
+ GossipContact *contact;
+ GossipPresence *presence;
+ GossipChatroom *chatroom;
+ GossipChatroomId id;
+ LmMessageSubType type;
+ LmMessageNode *node;
+ gboolean was_offline;
+ LmMessageNode *muc_user_node;
+ GossipChatroomContactInfo muc_contact_info;
+ gchar *new_nick;
+
+ from = lm_message_node_get_attribute (m->node, "from");
+ jid = gossip_jid_new (from);
+
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_jid, jid);
+
+ if (!chatroom) {
+ g_object_unref (jid);
+ return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ }
+
+ gossip_debug (DEBUG_DOMAIN,
+ "Presence from:'%s'",
+ from);
+
+ /* If this JID matches a room we are joining, first call the
+ * callback and clean up to show we are now joined and then
+ * continue to handle the first presence message we were sent.
+ */
+ if (g_hash_table_lookup (chatrooms->join_timeouts, chatroom)) {
+ /* If this returns FALSE, it means there was an
+ * error, and we have handled it, so don't handle it
+ * again here or any further messages from the room
+ */
+ if (!join_finish (chatrooms, chatroom, m)) {
+ g_object_unref (jid);
+ return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ }
}
- /* Check status code */
- status_codes = jabber_chatrooms_get_status (m);
- if (status_codes) {
- if (jabber_chatrooms_has_status (status_codes, 201)) {
- /* Room was created for us */
- if (0) {
- jabber_chatrooms_request_reserved_room (room);
- jabber_chatrooms_create_instant_room (room);
- } else {
- jabber_chatrooms_create_reserved_room (room);
+ id = gossip_chatroom_get_id (chatroom);
+
+ type = lm_message_get_sub_type (m);
+ switch (type) {
+ case LM_MESSAGE_SUB_TYPE_AVAILABLE:
+ /* Get details */
+ contact = gossip_jabber_get_contact_from_jid (chatrooms->jabber,
+ from,
+ FALSE,
+ FALSE,
+ FALSE);
+
+ presence = gossip_presence_new ();
+
+ node = lm_message_node_get_child (m->node, "show");
+ if (node) {
+ GossipPresenceState state;
+
+ state = gossip_jabber_presence_state_from_str (node->value);
+ gossip_presence_set_state (presence, state);
+ }
+
+ node = lm_message_node_get_child (m->node, "status");
+ if (node) {
+ gossip_presence_set_status (presence, node->value);
+ }
+
+ /* Should signal joined if contact was found but offline */
+ was_offline = !gossip_contact_is_online (contact);
+ gossip_contact_add_presence (contact, presence);
+ g_object_unref (presence);
+
+ muc_user_node = find_muc_user_node (m->node);
+ muc_contact_info.role = get_role (muc_user_node);
+ muc_contact_info.affiliation = get_affiliation (muc_user_node);
+
+ /* Is contact new or updated */
+ if (was_offline) {
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Presence for new joining contact:'%s'",
+ id,
+ gossip_jid_get_full (jid));
+ gossip_chatroom_contact_joined (chatroom,
+ contact,
+ &muc_contact_info);
+ } else {
+ gossip_chatroom_set_contact_info (chatroom,
+ contact,
+ &muc_contact_info);
+ }
+ break;
+
+ case LM_MESSAGE_SUB_TYPE_UNAVAILABLE:
+ contact = gossip_jabber_get_contact_from_jid (chatrooms->jabber,
+ from,
+ FALSE,
+ FALSE,
+ FALSE);
+
+ new_nick = NULL;
+
+ if (gossip_jabber_get_message_is_muc_new_nick (m, &new_nick)) {
+ gchar *old_nick;
+ gchar *new_id;
+
+ old_nick = g_strdup (gossip_contact_get_name (contact));
+ new_id = get_new_id_for_new_nick (contact, new_nick);
+ gossip_contact_set_id (contact, new_id);
+ gossip_contact_set_name (contact, new_nick);
+ g_free (new_id);
+ g_free (new_nick);
+
+ gossip_debug (DEBUG_DOMAIN,
+ "[%d] Nick changed for contact:'%s', old nick:'%s', new nick:'%s'",
+ id,
+ gossip_contact_get_id (contact),
+ old_nick,
+ gossip_contact_get_name (contact));
+
+ g_signal_emit_by_name (chatrooms->jabber,
+ "chatroom-nick-changed",
+ id,
+ contact,
+ old_nick);
+
+ g_free (old_nick);
+ } else {
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
+ if (gossip_contact_equal (contact, own_contact)) {
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] We have been kicked!",
+ id);
+
+ gossip_chatroom_set_status (chatroom,
+ GOSSIP_CHATROOM_STATUS_INACTIVE);
+
+ g_signal_emit_by_name (chatrooms->jabber,
+ "chatroom-kicked",
+ id);
+
+ leave_chatroom (chatrooms, chatroom);
+ } else {
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Contact left:'%s'",
+ id,
+ gossip_contact_get_id (contact));
+
+ gossip_chatroom_contact_left (chatroom, contact);
+ }
+ }
+ break;
+
+ case LM_MESSAGE_SUB_TYPE_ERROR:
+ node = lm_message_node_get_child (m->node, "error");
+ if (node) {
+ GossipChatroomError error;
+ const gchar *xmlns = NULL;
+ const gchar *code_str;
+ gint code;
+
+ code_str = lm_message_node_get_attribute (node, "code");
+ code = code_str ? atoi (code_str) : 0;
+
+ node = lm_message_node_get_child (m->node, "x");
+ if (node) {
+ xmlns = lm_message_node_get_attribute (node, "xmlns");
}
+
+ error = error_from_code (xmlns, code);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] %s",
+ id,
+ gossip_chatroom_error_to_string (error));
+
+ g_signal_emit_by_name (chatrooms->jabber,
+ "chatroom-error",
+ id,
+ error);
}
+ break;
- g_array_free (status_codes, TRUE);
+ default:
+ gossip_debug (DEBUG_DOMAIN,
+ "Presence not handled for:'%s'",
+ gossip_jid_get_full (jid));
+ break;
}
- /* Check for error */
- type = lm_message_get_sub_type (m);
- if (type == LM_MESSAGE_SUB_TYPE_ERROR) {
- node = lm_message_node_get_child (m->node, "error");
- }
+ g_object_unref (jid);
- if (node) {
- const gchar *str;
- gint code;
+ return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+}
- str = lm_message_node_get_attribute (node, "code");
- code = str ? atoi (str) : 0;
+static void
+join_timeout_destroy_notify_cb (gpointer data)
+{
+ guint timeout_id;
- error = jabber_chatrooms_error_from_code (code);
- gossip_debug (DEBUG_DOMAIN, "ID[%d] %s",
- id, gossip_chatroom_error_to_string (error));
+ timeout_id = GPOINTER_TO_UINT (data);
+ g_source_remove (timeout_id);
+}
- /* Set room state */
- status = GOSSIP_CHATROOM_STATUS_ERROR;
- } else {
- error = GOSSIP_CHATROOM_ERROR_NONE;
- status = GOSSIP_CHATROOM_STATUS_ACTIVE;
- }
+static gboolean
+join_timeout_cb (GossipCallbackData *timeout_data)
+{
+ GossipJID *jid;
+ GossipChatroomId id;
+ GossipChatroom *chatroom;
+ GossipJabberChatrooms *chatrooms;
+ GossipChatroomError error;
+ GossipCallbackData *data;
- gossip_chatroom_set_last_error (room->chatroom, error);
- gossip_chatroom_set_status (room->chatroom, status);
+ chatrooms = timeout_data->data1;
+ chatroom = timeout_data->data2;
- if (room->callback != NULL) {
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Calling back...", id);
- (room->callback) (GOSSIP_CHATROOM_PROVIDER (chatrooms->jabber),
- id,
- error,
- room->user_data);
- }
-
- /* Clean up callback data */
- room->callback = NULL;
- room->user_data = NULL;
-
- /* Articulate own contact presence so we appear in group chat */
- if (error == GOSSIP_CHATROOM_ERROR_NONE) {
- gossip_contact_add_presence (room->own_contact,
- chatrooms->presence);
-
- g_signal_emit_by_name (chatrooms->jabber,
- "chatroom-joined",
- id);
- } else {
- /* Clean up */
- g_hash_table_remove (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- g_hash_table_remove (chatrooms->room_jid_hash,
- room->jid);
- }
+ g_hash_table_remove (chatrooms->join_timeouts, chatroom);
- return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
-}
+ id = gossip_chatroom_get_id (chatroom);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Join timed out (internally)",
+ id);
-static void
-jabber_chatrooms_close (GossipJabberChatrooms *chatrooms,
- GossipChatroomId id)
-{
- JabberChatroom *room;
+ /* Set chatroom status and error */
+ error = GOSSIP_CHATROOM_ERROR_TIMED_OUT;
- g_return_if_fail (chatrooms != NULL);
+ gossip_chatroom_set_last_error (chatroom, error);
+ gossip_chatroom_set_status (chatroom, GOSSIP_CHATROOM_STATUS_ERROR);
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
- return;
+ /* Call callback */
+ data = g_hash_table_lookup (chatrooms->join_callbacks, chatroom);
+
+ if (data && data->callback) {
+ GossipChatroomJoinCb func;
+ GossipJabberChatrooms *chatrooms;
+
+ func = (GossipChatroomJoinCb) data->callback;
+ chatrooms = (GossipJabberChatrooms *) data->data1;
+
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Calling back... (timed out)",
+ id);
+ (func) (GOSSIP_CHATROOM_PROVIDER (chatrooms->jabber),
+ id,
+ error,
+ data->user_data);
}
- gossip_chatroom_set_last_error (room->chatroom, GOSSIP_CHATROOM_ERROR_NONE);
- gossip_chatroom_set_status (room->chatroom, GOSSIP_CHATROOM_STATUS_INACTIVE);
+ /* Clean up the user data */
+ g_hash_table_remove (chatrooms->join_callbacks, chatroom);
- g_hash_table_remove (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- g_hash_table_remove (chatrooms->room_jid_hash,
- room->jid);
+ /* Clean up */
+ jid = gossip_jid_new (gossip_chatroom_get_id_str (chatroom));
+
+ g_hash_table_remove (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+ g_hash_table_remove (chatrooms->chatrooms_by_pointer, chatroom);
+ g_hash_table_remove (chatrooms->chatrooms_by_jid, jid);
+
+ g_object_unref (jid);
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Leaving room, ref count is %d",
- id, room->ref_count - 1);
+ gossip_callback_data_free (timeout_data);
- jabber_chatrooms_chatroom_unref (room);
+ return FALSE;
}
GossipChatroomId
@@ -984,28 +1024,26 @@
GossipChatroomJoinCb callback,
gpointer user_data)
{
- GossipChatroomId id;
- JabberChatroom *room, *existing_room;
- LmMessage *m;
- LmMessageNode *node;
- const gchar *show = NULL;
- gchar *id_str;
- const gchar *password;
+ LmMessage *m;
+ LmMessageNode *node;
+ GossipContact *own_contact;
+ GossipChatroomId id;
+ gchar *id_str;
+ const gchar *jid_str;
+ const gchar *show = NULL;
+ const gchar *password;
+ guint timeout_id;
g_return_val_if_fail (chatrooms != NULL, 0);
g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), 0);
g_return_val_if_fail (callback != NULL, 0);
- room = jabber_chatrooms_chatroom_new (chatrooms, chatroom);
- existing_room = g_hash_table_lookup (chatrooms->room_jid_hash, room->jid);
-
- if (existing_room) {
- jabber_chatrooms_chatroom_unref (room);
-
+ if (g_hash_table_lookup (chatrooms->chatrooms_by_pointer, chatroom)) {
/* Duplicate room already exists. */
- id = jabber_chatrooms_chatroom_get_id (existing_room);
+ id = gossip_chatroom_get_id (chatroom);
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Join chatroom:'%s', room already exists.",
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Join chatroom:'%s', room already exists.",
id,
gossip_chatroom_get_room (chatroom));
@@ -1017,31 +1055,49 @@
return id;
}
+ jid_str = gossip_chatroom_get_id_str (chatroom);
+
/* Get real chatroom. */
- id = jabber_chatrooms_chatroom_get_id (room);
+ id = gossip_chatroom_get_id (chatroom);
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Join chatroom:'%s' on server:'%s'",
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Join chatroom:'%s' on server:'%s'",
id,
gossip_chatroom_get_room (chatroom),
gossip_chatroom_get_server (chatroom));
-
/* Add timeout for server response. */
- room->timeout_id = g_timeout_add (JOIN_TIMEOUT,
- (GSourceFunc) jabber_chatrooms_join_timeout_cb,
- room);
-
- room->chatrooms = chatrooms;
-
- /* Set callback data. */
- room->callback = callback;
- room->user_data = user_data;
+ timeout_id = g_timeout_add (JOIN_TIMEOUT,
+ (GSourceFunc) join_timeout_cb,
+ gossip_callback_data_new (NULL, NULL, chatrooms, chatroom, NULL));
+
+ g_hash_table_insert (chatrooms->join_timeouts,
+ g_object_ref (chatroom),
+ GUINT_TO_POINTER (timeout_id));
+ g_hash_table_insert (chatrooms->join_callbacks,
+ g_object_ref (chatroom),
+ gossip_callback_data_new (callback, user_data, chatrooms, NULL, NULL));
+ g_hash_table_insert (chatrooms->chatrooms_by_id,
+ GINT_TO_POINTER (id),
+ g_object_ref (chatroom));
+ g_hash_table_insert (chatrooms->chatrooms_by_pointer,
+ g_object_ref (chatroom),
+ GINT_TO_POINTER (1));
+ g_hash_table_insert (chatrooms->chatrooms_by_jid,
+ gossip_jid_new (jid_str),
+ g_object_ref (chatroom));
- gossip_chatroom_set_last_error (room->chatroom, GOSSIP_CHATROOM_ERROR_NONE);
+ gossip_chatroom_set_last_error (chatroom, GOSSIP_CHATROOM_ERROR_NONE);
gossip_chatroom_set_status (chatroom, GOSSIP_CHATROOM_STATUS_JOINING);
+ /* The other hash table inserts MUST occur before this, since
+ * we check to see if the contact is a chatroom contact and
+ * that does a hash tabe lookup.
+ */
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
/* Compose message. */
- m = lm_message_new_with_sub_type (gossip_jid_get_full (room->jid),
+ m = lm_message_new_with_sub_type (gossip_contact_get_id (own_contact),
LM_MESSAGE_TYPE_PRESENCE,
LM_MESSAGE_SUB_TYPE_AVAILABLE);
@@ -1054,15 +1110,6 @@
lm_message_node_add_child (node, "password", password);
}
- g_hash_table_insert (chatrooms->room_id_hash,
- GINT_TO_POINTER (id),
- jabber_chatrooms_chatroom_ref (room));
- g_hash_table_insert (chatrooms->room_jid_hash,
- room->jid,
- jabber_chatrooms_chatroom_ref (room));
-
- jabber_chatrooms_chatroom_unref (room);
-
show = gossip_jabber_presence_state_to_str (chatrooms->presence);
if (show) {
@@ -1073,20 +1120,6 @@
lm_message_node_set_attribute (m->node, "id", id_str);
g_free (id_str);
- /* Send message. */
- room->connection = lm_connection_ref (chatrooms->connection);
- room->join_handler = lm_message_handler_new ((LmHandleMessageFunction)
- jabber_chatrooms_join_cb,
- room, NULL);
-
- lm_connection_register_message_handler (chatrooms->connection,
- room->join_handler,
- LM_MESSAGE_TYPE_PRESENCE,
- LM_HANDLER_PRIORITY_FIRST);
-
- /* Some servers don't honor the id so we don't get a reply and
- * are waiting forever.
- */
lm_connection_send (chatrooms->connection, m, NULL);
lm_message_unref (m);
@@ -1097,47 +1130,52 @@
gossip_jabber_chatrooms_cancel (GossipJabberChatrooms *chatrooms,
GossipChatroomId id)
{
- JabberChatroom *room;
+ GossipChatroom *chatroom;
+ GossipJID *jid;
+ GossipCallbackData *data;
g_return_if_fail (chatrooms != NULL);
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+ if (!chatroom) {
return;
}
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Cancel joining room", id);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Cancel joining room",
+ id);
+
+ g_hash_table_remove (chatrooms->join_timeouts, chatroom);
- if (room->timeout_id) {
- g_source_remove (room->timeout_id);
- room->timeout_id = 0;
- }
+ gossip_chatroom_set_last_error (chatroom, GOSSIP_CHATROOM_ERROR_NONE);
+ gossip_chatroom_set_status (chatroom, GOSSIP_CHATROOM_STATUS_INACTIVE);
- if (room->join_handler) {
- lm_message_handler_unref (room->join_handler);
- room->join_handler = NULL;
- }
+ data = g_hash_table_lookup (chatrooms->join_callbacks, chatroom);
+
+ if (data && data->callback) {
+ GossipChatroomJoinCb func;
- gossip_chatroom_set_last_error (room->chatroom, GOSSIP_CHATROOM_ERROR_NONE);
- gossip_chatroom_set_status (room->chatroom, GOSSIP_CHATROOM_STATUS_INACTIVE);
+ func = (GossipChatroomJoinCb) data->callback;
- if (room->callback != NULL) {
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Calling back...", id);
- (room->callback) (GOSSIP_CHATROOM_PROVIDER (chatrooms->jabber),
- id,
- GOSSIP_CHATROOM_ERROR_CANCELED,
- room->user_data);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Calling back... (cancelled)",
+ id);
+ (func) (GOSSIP_CHATROOM_PROVIDER (chatrooms->jabber),
+ id,
+ GOSSIP_CHATROOM_ERROR_CANCELED,
+ data->user_data);
}
- /* Clean up callback data */
- room->callback = NULL;
- room->user_data = NULL;
+ /* Clean up the user data */
+ g_hash_table_remove (chatrooms->join_callbacks, chatroom);
- g_hash_table_remove (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- g_hash_table_remove (chatrooms->room_jid_hash,
- room->jid);
+ jid = gossip_jid_new (gossip_chatroom_get_id_str (chatroom));
+
+ g_hash_table_remove (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+ g_hash_table_remove (chatrooms->chatrooms_by_pointer, chatroom);
+ g_hash_table_remove (chatrooms->chatrooms_by_jid, jid);
+
+ g_object_unref (jid);
}
void
@@ -1146,21 +1184,27 @@
const gchar *message)
{
LmMessage *m;
- JabberChatroom *room;
+ GossipChatroom *chatroom;
+ const gchar *jid_str;
g_return_if_fail (chatrooms != NULL);
g_return_if_fail (message != NULL);
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
- g_warning ("ProtocolChatrooms: Unknown chatroom id: %d", id);
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id,
+ GINT_TO_POINTER (id));
+
+ if (!chatroom) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not send message, unknown chatroom id:%d", id);
return;
}
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Send message", id);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Send message",
+ id);
- m = lm_message_new_with_sub_type (gossip_jid_get_without_resource (room->jid),
+ jid_str = gossip_chatroom_get_id_str (chatroom);
+ m = lm_message_new_with_sub_type (jid_str,
LM_MESSAGE_TYPE_MESSAGE,
LM_MESSAGE_SUB_TYPE_GROUPCHAT);
lm_message_node_add_child (m->node, "body", message);
@@ -1174,26 +1218,29 @@
GossipChatroomId id,
const gchar *new_subject)
{
- JabberChatroom *room;
- const gchar *without_resource;
LmMessage *m;
+ GossipChatroom *chatroom;
+ const gchar *jid_str;
g_return_if_fail (chatrooms != NULL);
g_return_if_fail (new_subject != NULL);
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
- g_warning ("ProtocolChatrooms: Unknown chatroom id: %d", id);
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id,
+ GINT_TO_POINTER (id));
+
+ if (!chatroom) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not change subject, unknown chatroom id:%d", id);
return;
}
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Change subject to:'%s'",
- id, new_subject);
-
- without_resource = gossip_jid_get_without_resource (room->jid);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Change subject to:'%s'",
+ id,
+ new_subject);
- m = lm_message_new_with_sub_type (without_resource,
+ jid_str = gossip_chatroom_get_id_str (chatroom);
+ m = lm_message_new_with_sub_type (jid_str,
LM_MESSAGE_TYPE_MESSAGE,
LM_MESSAGE_SUB_TYPE_GROUPCHAT);
@@ -1209,25 +1256,40 @@
const gchar *new_nick)
{
LmMessage *m;
- JabberChatroom *room;
+ GossipChatroom *chatroom;
+ GossipContact *own_contact;
+ gchar *new_id;
g_return_if_fail (chatrooms != NULL);
g_return_if_fail (new_nick != NULL);
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
- g_warning ("ProtocolChatrooms: Unknown chatroom id: %d", id);
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+
+ if (!chatroom) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not change nick, unknown chatroom id:%d", id);
return;
}
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Change chatroom nick to:'%s'",
- id, new_nick);
-
- gossip_jid_set_resource (room->jid, new_nick);
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
+ if (!own_contact) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not get own contact, unknown chatroom id:%d", id);
+ return;
+ }
- m = lm_message_new (gossip_jid_get_full (room->jid),
- LM_MESSAGE_TYPE_PRESENCE);
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Change chatroom nick to:'%s'",
+ id,
+ new_nick);
+
+ /* NOTE: Don't change the nick until we get confirmation from
+ * the server that it has changed.
+ */
+ new_id = get_new_id_for_new_nick (own_contact, new_nick);
+ m = lm_message_new (new_id, LM_MESSAGE_TYPE_PRESENCE);
+ g_free (new_id);
lm_connection_send (chatrooms->connection, m, NULL);
lm_message_unref (m);
@@ -1238,24 +1300,40 @@
GossipChatroomId id)
{
LmMessage *m;
- JabberChatroom *room;
+ GossipChatroom *chatroom;
+ GossipContact *own_contact;
g_return_if_fail (chatrooms != NULL);
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+
+ if (!chatroom) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not leave chatroom, unknown chatroom id:%d", id);
+ return;
+ }
+
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
+ if (!own_contact) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not get own contact, unknown chatroom id:%d", id);
return;
}
- m = lm_message_new_with_sub_type (gossip_jid_get_full (room->jid),
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Leaving chatroom:'%s'",
+ id,
+ gossip_chatroom_get_id_str (chatroom));
+
+ m = lm_message_new_with_sub_type (gossip_contact_get_id (own_contact),
LM_MESSAGE_TYPE_PRESENCE,
LM_MESSAGE_SUB_TYPE_UNAVAILABLE);
lm_connection_send (chatrooms->connection, m, NULL);
lm_message_unref (m);
- jabber_chatrooms_close (chatrooms, id);
+ leave_chatroom (chatrooms, chatroom);
}
void
@@ -1266,8 +1344,8 @@
{
LmMessage *m;
LmMessageNode *node;
- JabberChatroom *room;
GossipAccount *account;
+ GossipChatroom *chatroom;
GossipJID *jid;
gchar *from;
const gchar *contact_id;
@@ -1277,9 +1355,13 @@
g_return_if_fail (chatrooms != NULL);
g_return_if_fail (GOSSIP_IS_CONTACT (contact));
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
+
+ if (!chatroom) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not kick:'%s', unknown chatroom id:%d",
+ gossip_contact_get_id (contact),
+ id);
return;
}
@@ -1287,7 +1369,7 @@
LM_MESSAGE_TYPE_IQ,
LM_MESSAGE_SUB_TYPE_SET);
- account = gossip_contact_get_account (room->own_contact);
+ account = gossip_chatroom_get_account (chatroom);
from = g_strconcat (gossip_account_get_id (account),
"/",
gossip_account_get_resource (account),
@@ -1295,7 +1377,7 @@
lm_message_node_set_attribute (m->node, "from", from);
g_free (from);
- to = gossip_chatroom_get_id_str (room->chatroom);
+ to = gossip_chatroom_get_id_str (chatroom);
lm_message_node_set_attribute (m->node, "to", to);
node = lm_message_node_add_child (m->node, "query", NULL);
@@ -1310,71 +1392,29 @@
"nick", nick,
"role", "none",
NULL);
- gossip_jid_unref (jid);
+ g_object_unref (jid);
lm_connection_send (chatrooms->connection, m, NULL);
lm_message_unref (m);
}
-GSList *
-gossip_jabber_chatrooms_get_contacts (GossipJabberChatrooms *chatrooms,
- GossipChatroomId id)
-{
- JabberChatroom *room;
-
- g_return_val_if_fail (chatrooms != NULL, NULL);
-
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
- return NULL;
- }
-
- return room->contacts;
-}
-
GossipChatroom *
gossip_jabber_chatrooms_find_by_id (GossipJabberChatrooms *chatrooms,
GossipChatroomId id)
{
- JabberChatroom *room;
-
- g_return_val_if_fail (chatrooms != NULL, NULL);
-
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
- if (!room) {
- return NULL;
- }
-
- return room->chatroom;
+ return g_hash_table_lookup (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
}
GossipChatroom *
gossip_jabber_chatrooms_find (GossipJabberChatrooms *chatrooms,
GossipChatroom *chatroom)
{
- JabberChatroom *room;
- GossipJID *jid;
- gchar *jid_str;
-
- g_return_val_if_fail (chatrooms != NULL, NULL);
- g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
-
- jid_str = g_strdup_printf ("%s/%s",
- gossip_chatroom_get_id_str (chatroom),
- gossip_chatroom_get_nick (chatroom));
- jid = gossip_jid_new (jid_str);
- g_free (jid_str);
-
- room = g_hash_table_lookup (chatrooms->room_jid_hash, jid);
- gossip_jid_unref (jid);
-
- if (!room) {
- return NULL;
+ /* FIXME: What is the point of this now? */
+ if (g_hash_table_lookup (chatrooms->chatrooms_by_pointer, chatroom)) {
+ return chatroom;
}
-
- return room->chatroom;
+
+ return NULL;
}
void
@@ -1386,28 +1426,40 @@
LmMessage *m;
LmMessageNode *parent;
LmMessageNode *node;
- JabberChatroom *room;
+ GossipChatroom *chatroom;
+ GossipContact *own_contact;
g_return_if_fail (chatrooms != NULL);
g_return_if_fail (GOSSIP_IS_CONTACT (contact));
- room = g_hash_table_lookup (chatrooms->room_id_hash,
- GINT_TO_POINTER (id));
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_id, GINT_TO_POINTER (id));
- if (!room) {
- g_warning ("ProtocolChatrooms: Unknown chatroom id: %d", id);
+ if (!chatroom) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not invite:'%s', unknown chatroom id:%d",
+ gossip_contact_get_id (contact),
+ id);
return;
}
- gossip_debug (DEBUG_DOMAIN, "ID[%d] Invitation to contact:'%s' from:'%s'",
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
+ if (!own_contact) {
+ /* FIXME: Should error this up? */
+ g_warning ("Could not get own contact, unknown chatroom id:%d", id);
+ return;
+ }
+
+ gossip_debug (DEBUG_DOMAIN,
+ "ID[%d] Invitation to contact:'%s' from:'%s'",
id,
gossip_contact_get_id (contact),
- gossip_contact_get_id (room->own_contact));
+ gossip_contact_get_id (own_contact));
- m = lm_message_new (gossip_jid_get_without_resource (room->jid),
+ m = lm_message_new (gossip_chatroom_get_id_str (chatroom),
LM_MESSAGE_TYPE_MESSAGE);
lm_message_node_set_attributes (m->node,
- "from", gossip_contact_get_id (room->own_contact),
+ "from", gossip_contact_get_id (own_contact),
NULL);
parent = lm_message_node_add_child (m->node, "x", NULL);
@@ -1428,19 +1480,20 @@
GossipChatroomInvite *invite,
const gchar *nickname)
{
- GossipChatroom *chatroom;
- GossipContact *contact;
- GossipAccount *account;
- gchar *room = NULL;
- const gchar *id;
- const gchar *server;
+ GossipSession *session;
+ GossipChatroom *chatroom;
+ GossipChatroomManager *chatroom_manager;
+ GossipContact *contact;
+ gchar *room = NULL;
+ const gchar *id;
+ const gchar *server;
g_return_if_fail (chatrooms != NULL);
g_return_if_fail (invite != NULL);
g_return_if_fail (callback != NULL);
id = gossip_chatroom_invite_get_id (invite);
- contact = gossip_chatroom_invite_get_invitor (invite);
+ contact = gossip_chatroom_invite_get_inviter (invite);
server = strstr (id, "@");
@@ -1452,15 +1505,15 @@
server++;
}
- account = gossip_contact_get_account (contact);
+ session = _gossip_jabber_get_session (chatrooms->jabber);
+ chatroom_manager = gossip_session_get_chatroom_manager (session);
+ chatroom = gossip_chatroom_manager_find_or_create (chatroom_manager,
+ gossip_contact_get_account (contact),
+ server,
+ room,
+ NULL);
- chatroom = g_object_new (GOSSIP_TYPE_CHATROOM,
- "account", account,
- "server", server,
- "name", room,
- "room", room,
- "nick", nickname,
- NULL);
+ gossip_chatroom_set_nick (chatroom, nickname);
gossip_jabber_chatrooms_join (chatrooms,
chatroom,
@@ -1486,11 +1539,13 @@
g_return_if_fail (invite != NULL);
own_contact = gossip_jabber_get_own_contact (chatrooms->jabber);
- contact = gossip_chatroom_invite_get_invitor (invite);
+ contact = gossip_chatroom_invite_get_inviter (invite);
id = gossip_chatroom_invite_get_id (invite);
- gossip_debug (DEBUG_DOMAIN, "Invitation decline to:'%s' into room:'%s'",
- gossip_contact_get_id (contact), id);
+ gossip_debug (DEBUG_DOMAIN,
+ "Invitation decline to:'%s' into room:'%s'",
+ gossip_contact_get_id (contact),
+ id);
m = lm_message_new (id, LM_MESSAGE_TYPE_MESSAGE);
lm_message_node_set_attributes (m->node,
@@ -1510,11 +1565,14 @@
}
static void
-jabber_chatrooms_get_rooms_foreach (gpointer key,
- JabberChatroom *room,
- GList **list)
+get_rooms_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
- *list = g_list_append (*list, key);
+ GList **list;
+
+ list = (GList **) user_data;
+ *list = g_list_prepend (*list, key);
}
GList *
@@ -1524,10 +1582,12 @@
g_return_val_if_fail (chatrooms != NULL, NULL);
- g_hash_table_foreach (chatrooms->room_id_hash,
- (GHFunc) jabber_chatrooms_get_rooms_foreach,
+ g_hash_table_foreach (chatrooms->chatrooms_by_id,
+ get_rooms_foreach,
&list);
+ list = g_list_reverse (list);
+
return list;
}
@@ -1542,7 +1602,6 @@
GossipJID *jid = NULL;
GossipJabberChatrooms *chatrooms;
GossipChatroom *chatroom = NULL;
- JabberChatroom *room = NULL;
GList *list;
gchar *server;
@@ -1556,14 +1615,12 @@
if (item) {
jid = gossip_jabber_disco_item_get_jid (item);
- room = g_hash_table_lookup (chatrooms->room_jid_hash, jid);
+ chatroom = g_hash_table_lookup (chatrooms->chatrooms_by_jid, jid);
}
- if (room) {
- chatroom = room->chatroom;
- }
-
- if (!room && !timeout && !error) {
+ if (!chatroom && !timeout && !error) {
+ GossipSession *session;
+ GossipChatroomManager *chatroom_manager;
GossipAccount *account;
const gchar *server;
gchar *room;
@@ -1577,11 +1634,13 @@
room = gossip_jid_get_part_name (jid);
/* Create new chatroom */
- chatroom = g_object_new (GOSSIP_TYPE_CHATROOM,
- "account", account,
- "server", server,
- "room", room,
- NULL);
+ session = _gossip_jabber_get_session (chatrooms->jabber);
+ chatroom_manager = gossip_session_get_chatroom_manager (session);
+ chatroom = gossip_chatroom_manager_find_or_create (chatroom_manager,
+ account,
+ server,
+ room,
+ NULL);
g_free (room);
}
@@ -1696,7 +1755,7 @@
g_free (server);
- g_free (data);
+ gossip_callback_data_free (data);
}
}
@@ -1709,13 +1768,12 @@
GossipJabberDisco *disco;
GossipCallbackData *data;
- data = g_new0 (GossipCallbackData, 1);
+ data = gossip_callback_data_new (callback,
+ user_data,
+ chatrooms,
+ g_strdup (server),
+ NULL);
- data->callback = callback;
- data->user_data = user_data;
- data->data1 = chatrooms;
- data->data2 = g_strdup (server);
-
disco = gossip_jabber_disco_request (chatrooms->jabber,
server,
(GossipJabberDiscoItemFunc)
@@ -1724,15 +1782,20 @@
}
static void
-jabber_chatrooms_set_presence_foreach (gpointer key,
- JabberChatroom *room,
- GossipJabberChatrooms *chatrooms)
+jabber_chatrooms_set_presence_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
- LmConnection *connection;
- LmMessage *m;
- const gchar *show;
- const gchar *status;
- GossipPresence *presence;
+ LmConnection *connection;
+ LmMessage *m;
+ GossipJabberChatrooms *chatrooms;
+ GossipChatroom *chatroom;
+ GossipPresence *presence;
+ const gchar *show;
+ const gchar *status;
+
+ chatroom = GOSSIP_CHATROOM (key);
+ chatrooms = (GossipJabberChatrooms *) user_data;
connection = chatrooms->connection;
presence = chatrooms->presence;
@@ -1740,7 +1803,7 @@
show = gossip_jabber_presence_state_to_str (presence);
status = gossip_presence_get_status (presence);
- m = lm_message_new_with_sub_type (gossip_jid_get_full (room->jid),
+ m = lm_message_new_with_sub_type (gossip_chatroom_get_id_str (chatroom),
LM_MESSAGE_TYPE_PRESENCE,
LM_MESSAGE_SUB_TYPE_AVAILABLE);
@@ -1756,104 +1819,6 @@
lm_message_unref (m);
}
-static LmMessageNode *
-jabber_chatrooms_find_muc_user_node (LmMessageNode *parent_node)
-{
- LmMessageNode *child;
-
- /* Should have a function in Loudmouth to find a child with xmlns */
- child = parent_node->children;
-
- if (!child) {
- return NULL;
- }
-
- while (child) {
- if (strcmp (child->name, "x") == 0) {
- const gchar *xmlns;
-
- xmlns = lm_message_node_get_attribute (child, "xmlns");
-
- if (xmlns && strcmp (xmlns, XMPP_MUC_USER_XMLNS) == 0) {
- return child;
- }
- }
-
- child = child->next;
- }
-
- return NULL;
-}
-
-static GossipChatroomRole
-jabber_chatrooms_get_role (LmMessageNode *muc_node)
-{
- LmMessageNode *item_node;
- const gchar *role;
-
- if (!muc_node) {
- return GOSSIP_CHATROOM_ROLE_NONE;
- }
-
- item_node = lm_message_node_get_child (muc_node, "item");
- if (!item_node) {
- return GOSSIP_CHATROOM_ROLE_NONE;
- }
-
- role = lm_message_node_get_attribute (item_node, "role");
- if (!role) {
- return GOSSIP_CHATROOM_ROLE_NONE;
- }
-
- if (strcmp (role, "moderator") == 0) {
- return GOSSIP_CHATROOM_ROLE_MODERATOR;
- }
- else if (strcmp (role, "participant") == 0) {
- return GOSSIP_CHATROOM_ROLE_PARTICIPANT;
- }
- else if (strcmp (role, "visitor") == 0) {
- return GOSSIP_CHATROOM_ROLE_VISITOR;
- } else {
- return GOSSIP_CHATROOM_ROLE_NONE;
- }
-}
-
-static GossipChatroomAffiliation
-jabber_chatrooms_get_affiliation (LmMessageNode *muc_node)
-{
- LmMessageNode *item_node;
- const gchar *affiliation;
-
- if (!muc_node) {
- return GOSSIP_CHATROOM_AFFILIATION_NONE;
- }
-
- item_node = lm_message_node_get_child (muc_node, "item");
- if (!item_node) {
- return GOSSIP_CHATROOM_AFFILIATION_NONE;
- }
-
- affiliation = lm_message_node_get_attribute (item_node, "affiliation");
- if (!affiliation) {
- return GOSSIP_CHATROOM_AFFILIATION_NONE;
- }
-
- if (strcmp (affiliation, "owner") == 0) {
- return GOSSIP_CHATROOM_AFFILIATION_OWNER;
- }
- else if (strcmp (affiliation, "admin") == 0) {
- return GOSSIP_CHATROOM_AFFILIATION_ADMIN;
- }
- else if (strcmp (affiliation, "member") == 0) {
- return GOSSIP_CHATROOM_AFFILIATION_MEMBER;
- }
- else if (strcmp (affiliation, "outcast") == 0) {
- return GOSSIP_CHATROOM_AFFILIATION_OUTCAST;
- } else {
- return GOSSIP_CHATROOM_AFFILIATION_NONE;
- }
-}
-
void
gossip_jabber_chatrooms_set_presence (GossipJabberChatrooms *chatrooms,
GossipPresence *presence)
@@ -1866,8 +1831,8 @@
chatrooms->presence = g_object_ref (presence);
- g_hash_table_foreach (chatrooms->room_id_hash,
- (GHFunc) jabber_chatrooms_set_presence_foreach,
+ g_hash_table_foreach (chatrooms->chatrooms_by_pointer,
+ jabber_chatrooms_set_presence_foreach,
chatrooms);
}
@@ -1878,13 +1843,17 @@
GossipJID *jid;
gboolean ret_val = FALSE;
+ if (!chatrooms->chatrooms_by_jid) {
+ return FALSE;
+ }
+
jid = gossip_jid_new (jid_str);
- if (g_hash_table_lookup (chatrooms->room_jid_hash, jid)) {
+ if (g_hash_table_lookup (chatrooms->chatrooms_by_jid, jid)) {
ret_val = TRUE;
}
- gossip_jid_unref (jid);
+ g_object_unref (jid);
return ret_val;
}
Modified: trunk/libgossip/gossip-jabber-disco.c
==============================================================================
--- trunk/libgossip/gossip-jabber-disco.c (original)
+++ trunk/libgossip/gossip-jabber-disco.c Sat Jul 5 12:58:07 2008
@@ -157,7 +157,7 @@
disco->jabber = g_object_ref (jabber);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
handler = lm_message_handler_new (jabber_disco_message_handler, disco, NULL);
disco->message_handler = handler;
@@ -180,9 +180,9 @@
inited = TRUE;
- discos = g_hash_table_new_full (gossip_jid_hash,
- gossip_jid_equal,
- (GDestroyNotify) gossip_jid_unref,
+ discos = g_hash_table_new_full (gossip_jid_hash_without_resource,
+ gossip_jid_equal_without_resource,
+ (GDestroyNotify) g_object_unref,
(GDestroyNotify) jabber_disco_free);
}
@@ -190,7 +190,7 @@
jabber_disco_destroy_items_foreach (GossipJabberDiscoItem *item,
gpointer user_data)
{
- gossip_jid_unref (item->jid);
+ g_object_unref (item->jid);
g_free (item->node);
g_free (item->name);
@@ -366,7 +366,7 @@
if (lm_message_get_sub_type (m) != LM_MESSAGE_SUB_TYPE_RESULT &&
lm_message_get_sub_type (m) != LM_MESSAGE_SUB_TYPE_ERROR) {
- gossip_jid_unref (from_jid);
+ g_object_unref (from_jid);
return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
@@ -439,7 +439,7 @@
"disco items to: %s",
gossip_jid_get_full (disco->to));
- connection = gossip_jabber_get_connection (disco->jabber);
+ connection = _gossip_jabber_get_connection (disco->jabber);
lm_message_node_add_child (m->node, "query", NULL);
node = lm_message_node_get_child (m->node, "query");
@@ -557,7 +557,7 @@
GList *l;
GossipJID *jid;
- connection = gossip_jabber_get_connection (disco->jabber);
+ connection = _gossip_jabber_get_connection (disco->jabber);
jid = gossip_jid_new ("users.jabber.org");
disco->items_total = disco->items_remaining = g_list_length (disco->items);
@@ -606,7 +606,7 @@
lm_message_unref (m);
}
- gossip_jid_unref (jid);
+ g_object_unref (jid);
}
static void
@@ -812,7 +812,7 @@
}
disco = jabber_disco_new (jabber);
- g_hash_table_insert (discos, gossip_jid_ref (jid), disco);
+ g_hash_table_insert (discos, g_object_ref (jid), disco);
disco->to = jid;
@@ -848,7 +848,7 @@
disco->destroying = TRUE;
- connection = gossip_jabber_get_connection (disco->jabber);
+ connection = _gossip_jabber_get_connection (disco->jabber);
handler = disco->message_handler;
if (handler) {
@@ -897,7 +897,7 @@
disco = g_hash_table_lookup (discos, jid);
if (disco) {
- gossip_jid_unref (jid);
+ g_object_unref (jid);
return disco;
}
@@ -907,7 +907,7 @@
disco->jabber = g_object_ref (jabber);
/* Set up handler */
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
handler = lm_message_handler_new (jabber_disco_message_handler, disco, NULL);
disco->message_handler = handler;
@@ -917,7 +917,7 @@
LM_HANDLER_PRIORITY_NORMAL);
/* Add disco and configure members */
- g_hash_table_insert (discos, gossip_jid_ref (jid), disco);
+ g_hash_table_insert (discos, g_object_ref (jid), disco);
disco->to = jid;
@@ -932,7 +932,7 @@
/* Add item */
item = g_slice_new0 (GossipJabberDiscoItem);
- item->jid = gossip_jid_ref (jid);
+ item->jid = g_object_ref (jid);
disco->items = g_list_append (disco->items, item);
@@ -991,7 +991,7 @@
}
if (have_category && can_register) {
- services = g_list_append (services, gossip_jid_ref (item->jid));
+ services = g_list_append (services, g_object_ref (item->jid));
}
}
@@ -1063,7 +1063,7 @@
}
if (have_category && have_type && can_register) {
- services = g_list_append (services, gossip_jid_ref (item->jid));
+ services = g_list_append (services, g_object_ref (item->jid));
}
}
@@ -1261,7 +1261,7 @@
g_return_if_fail (GOSSIP_IS_JABBER (jabber));
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
handler = lm_message_handler_new ((LmHandleMessageFunction) jabber_disco_info_handler,
jabber, NULL);
lm_connection_register_message_handler (connection,
Modified: trunk/libgossip/gossip-jabber-ft.c
==============================================================================
--- trunk/libgossip/gossip-jabber-ft.c (original)
+++ trunk/libgossip/gossip-jabber-ft.c Sat Jul 5 12:58:07 2008
@@ -122,7 +122,7 @@
gossip_debug (DEBUG_DOMAIN, "Initializing GossipJabberFT");
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
fts = g_new0 (GossipJabberFTs, 1);
@@ -213,7 +213,7 @@
GHashTable *jids;
gpointer id_ptr;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
g_return_val_if_fail (fts, 0);
jids = g_hash_table_lookup (fts->jid_sids, jid);
@@ -239,7 +239,7 @@
GossipFT *ft;
const gchar *id_str;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
id_str = g_hash_table_lookup (fts->str_ids, GUINT_TO_POINTER (id));
ft = g_hash_table_lookup (fts->ft_ids, id_str);
@@ -254,7 +254,7 @@
GossipJabberFTs *fts;
GossipFT *ft;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
ft = jabber_ft_get_ft_from_id (jabber, id);
gossip_debug (DEBUG_DOMAIN, "ID[%d] Transfer initiated", id);
@@ -269,7 +269,7 @@
GossipJabberFTs *fts;
GossipFT *ft;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
ft = jabber_ft_get_ft_from_id (jabber, id);
gossip_debug (DEBUG_DOMAIN, "ID[%d] Transfer complete", id);
@@ -285,7 +285,7 @@
GossipJabberFTs *fts;
GossipFT *ft;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
ft = jabber_ft_get_ft_from_id (jabber, id);
gossip_debug (DEBUG_DOMAIN, "ID[%d] Progress: %f %%", id, progress * 100);
@@ -302,7 +302,7 @@
GossipFT *ft;
GossipFTError error_code;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
ft = jabber_ft_get_ft_from_id (jabber, id);
switch (error->code) {
@@ -387,7 +387,7 @@
}
iq_id = lm_message_node_get_attribute (m->node, "id");
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
lm_bs_session_streamhost_activate (fts->bs_session, iq_id, attr);
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
@@ -438,7 +438,7 @@
}
iq_id = lm_message_node_get_attribute (m->node, "id");
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
lm_bs_session_set_iq_id (fts->bs_session, id, iq_id);
/* Get all children named "streamhost" */
@@ -484,7 +484,7 @@
guint id;
gchar *jid_str;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
g_return_if_fail (fts != NULL);
file_id = gossip_ft_get_id (ft);
@@ -549,7 +549,7 @@
LmMessageNode *node;
const gchar *attr;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
g_return_val_if_fail (fts != NULL, LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS);
node = lm_message_node_get_child (m->node, "si");
@@ -691,14 +691,14 @@
const gchar *file_mime;
const gchar *sid;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
g_return_if_fail (fts != NULL);
from_str = lm_message_node_get_attribute (m->node, "from");
id_str = lm_message_node_get_attribute (m->node, "id");
from = gossip_jabber_get_contact_from_jid (jabber,
from_str,
- NULL,
+ FALSE,
FALSE,
TRUE);
@@ -755,7 +755,7 @@
GossipContact *from;
LmMessageNode *node;
- fts = gossip_jabber_get_fts (jabber);
+ fts = _gossip_jabber_get_fts (jabber);
g_return_if_fail (fts != NULL);
id_str = lm_message_node_get_attribute (m->node, "id");
@@ -771,7 +771,7 @@
from_str = lm_message_node_get_attribute (m->node, "from");
from = gossip_jabber_get_contact_from_jid (jabber,
from_str,
- NULL,
+ FALSE,
FALSE,
TRUE);
@@ -965,7 +965,7 @@
g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
g_return_val_if_fail (file != NULL, NULL);
- connection = gossip_jabber_get_connection (fts->jabber);
+ connection = _gossip_jabber_get_connection (fts->jabber);
own_contact = gossip_jabber_get_own_contact (fts->jabber);
to = jabber_ft_get_contact_last_jid (contact);
@@ -1096,7 +1096,7 @@
gossip_debug (DEBUG_DOMAIN, "ID[%d] Accepting file transfer", id);
- connection = gossip_jabber_get_connection (fts->jabber);
+ connection = _gossip_jabber_get_connection (fts->jabber);
own_contact = gossip_jabber_get_own_contact (fts->jabber);
to_str = g_hash_table_lookup (fts->remote_ids, GUINT_TO_POINTER (id));
id_str = g_hash_table_lookup (fts->str_ids, GUINT_TO_POINTER (id));
@@ -1177,7 +1177,7 @@
gossip_debug (DEBUG_DOMAIN, "ID[%d] Declining file transfer", id);
- connection = gossip_jabber_get_connection (fts->jabber);
+ connection = _gossip_jabber_get_connection (fts->jabber);
own_contact = gossip_jabber_get_own_contact (fts->jabber);
to_str = g_hash_table_lookup (fts->remote_ids, GUINT_TO_POINTER (id));
@@ -1265,7 +1265,7 @@
g_return_if_fail (to != NULL);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new_with_sub_type (to,
LM_MESSAGE_TYPE_IQ,
@@ -1294,7 +1294,7 @@
g_return_if_fail (to != NULL);
g_return_if_fail (id != NULL);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new_with_sub_type (to,
LM_MESSAGE_TYPE_IQ,
@@ -1323,7 +1323,7 @@
g_return_if_fail (error_code != NULL);
g_return_if_fail (error_type != NULL);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new_with_sub_type (to,
LM_MESSAGE_TYPE_IQ,
@@ -1366,7 +1366,7 @@
g_return_if_fail (data != NULL);
g_return_if_fail (seq != NULL);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new (to, LM_MESSAGE_TYPE_MESSAGE);
@@ -1416,7 +1416,7 @@
g_return_if_fail (to != NULL);
g_return_if_fail (sid != NULL);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new_with_sub_type (to,
LM_MESSAGE_TYPE_IQ,
@@ -1445,7 +1445,7 @@
g_return_if_fail (to != NULL);
g_return_if_fail (id != NULL);
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new_with_sub_type (to,
LM_MESSAGE_TYPE_IQ,
Modified: trunk/libgossip/gossip-jabber-private.h
==============================================================================
--- trunk/libgossip/gossip-jabber-private.h (original)
+++ trunk/libgossip/gossip-jabber-private.h Sat Jul 5 12:58:07 2008
@@ -23,18 +23,20 @@
#include <loudmouth/loudmouth.h>
+#include "gossip-session.h"
#include "gossip-jabber.h"
#include "gossip-jabber-ft.h"
G_BEGIN_DECLS
-LmConnection * gossip_jabber_new_connection (GossipJabber *jabber,
- GossipAccount *account);
-gboolean gossip_jabber_set_connection (LmConnection *connection,
- GossipJabber *jabber,
- GossipAccount *account);
-LmConnection * gossip_jabber_get_connection (GossipJabber *jabber);
-GossipJabberFTs *gossip_jabber_get_fts (GossipJabber *jabber);
+LmConnection * _gossip_jabber_new_connection (GossipJabber *jabber,
+ GossipAccount *account);
+gboolean _gossip_jabber_set_connection (LmConnection *connection,
+ GossipJabber *jabber,
+ GossipAccount *account);
+LmConnection * _gossip_jabber_get_connection (GossipJabber *jabber);
+GossipSession * _gossip_jabber_get_session (GossipJabber *jabber);
+GossipJabberFTs *_gossip_jabber_get_fts (GossipJabber *jabber);
G_END_DECLS
Modified: trunk/libgossip/gossip-jabber-register.c
==============================================================================
--- trunk/libgossip/gossip-jabber-register.c (original)
+++ trunk/libgossip/gossip-jabber-register.c Sat Jul 5 12:58:07 2008
@@ -90,7 +90,7 @@
rd = g_new0 (RegisterData, 1);
- rd->connection = gossip_jabber_new_connection (jabber, account);
+ rd->connection = _gossip_jabber_new_connection (jabber, account);
if (!rd->connection) {
g_free (rd);
return NULL;
Modified: trunk/libgossip/gossip-jabber-utils.c
==============================================================================
--- trunk/libgossip/gossip-jabber-utils.c (original)
+++ trunk/libgossip/gossip-jabber-utils.c Sat Jul 5 12:58:07 2008
@@ -23,6 +23,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include <glib/gi18n.h>
@@ -33,6 +34,7 @@
#include "gossip-jabber.h"
#include "gossip-jabber-utils.h"
#include "gossip-jid.h"
+#include "gossip-utils.h"
#define DEBUG_DOMAIN "JabberUtils"
@@ -162,7 +164,7 @@
contact_id = lm_message_node_get_attribute (node, "from");
contact = gossip_jabber_get_contact_from_jid (jabber,
contact_id,
- NULL,
+ FALSE,
FALSE,
TRUE);
@@ -236,31 +238,160 @@
return FALSE;
}
+static GArray *
+get_status (LmMessage *m)
+{
+ LmMessageNode *node;
+ GArray *status = NULL;
+
+ if (!m) {
+ return NULL;
+ }
+
+ node = lm_message_node_get_child (m->node, "x");
+ if (!node) {
+ return NULL;
+ }
+
+ node = node->children;
+
+ while (node) {
+ if (!node) {
+ break;
+ }
+
+ if (node->name && strcmp (node->name, "status") == 0) {
+ const gchar *code;
+
+ code = lm_message_node_get_attribute (node, "code");
+ if (code) {
+ gint value;
+
+ if (!status) {
+ status = g_array_new (FALSE, FALSE, sizeof (gint));
+ }
+
+ value = atoi (code);
+ g_array_append_val (status, value);
+ }
+ }
+
+ node = node->next;
+ }
+
+ return status;
+}
+
+gboolean
+gossip_jabber_get_message_has_status (LmMessage *m,
+ gint code)
+{
+ GArray *codes;
+ gboolean found;
+ gint i;
+
+ g_return_val_if_fail (m != NULL, FALSE);
+ g_return_val_if_fail (code > 0, FALSE);
+
+ codes = get_status (m);
+ if (!codes) {
+ return FALSE;
+ }
+
+ for (i = 0, found = FALSE; i < codes->len && !found; i++) {
+ if (g_array_index (codes, gint, i) == code) {
+ found = TRUE;
+ }
+ }
+
+ g_array_free (codes, TRUE);
+
+ return found;
+}
+
+gboolean
+gossip_jabber_get_message_is_muc_new_nick (LmMessage *m,
+ gchar **new_nick)
+{
+ LmMessageNode *node;
+ const gchar *str;
+
+ g_return_val_if_fail (m != NULL, FALSE);
+
+ if (new_nick) {
+ *new_nick = NULL;
+ }
+
+ /* 303 = nick changed */
+ if (!gossip_jabber_get_message_has_status (m, 303)) {
+ return FALSE;
+ }
+
+ if (!new_nick) {
+ return TRUE;
+ }
+
+ node = lm_message_get_node (m);
+
+ node = lm_message_node_find_child (node, "x");
+ if (!node) {
+ return FALSE;
+ }
+
+ str = lm_message_node_get_attribute (node, "xmlns");
+ if (!str || strcmp (str, "http://jabber.org/protocol/muc#user") != 0) {
+ return FALSE;
+ }
+
+ node = lm_message_node_find_child (node, "item");
+ if (!node) {
+ return FALSE;
+ }
+
+ /* Get old nick */
+ str = lm_message_node_get_attribute (node, "nick");
+
+ *new_nick = g_strdup (str);
+
+ return TRUE;
+}
+
gchar *
gossip_jabber_get_name_to_use (const gchar *jid_str,
const gchar *nickname,
- const gchar *full_name)
+ const gchar *full_name,
+ const gchar *current_name)
{
- if (nickname && strlen (nickname) > 0) {
+ if (!G_STR_EMPTY (current_name)) {
+ gchar *part_name;
+ gboolean use_current_name;
+
+ part_name = gossip_jid_string_get_part_name (jid_str);
+
+ use_current_name =
+ g_ascii_strcasecmp (jid_str, current_name) != 0 &&
+ g_ascii_strcasecmp (part_name, current_name) != 0;
+
+ g_free (part_name);
+
+ if (use_current_name) {
+ return g_strdup (current_name);
+ }
+ }
+
+ if (!G_STR_EMPTY (nickname)) {
return g_strdup (nickname);
}
- if (full_name && strlen (full_name) > 0) {
+ if (!G_STR_EMPTY (full_name)) {
return g_strdup (full_name);
}
- if (jid_str && strlen (jid_str) > 0) {
- GossipJID *jid;
- gchar *part_name;
-
- jid = gossip_jid_new (jid_str);
- part_name = gossip_jid_get_part_name (jid);
- gossip_jid_unref (jid);
-
- return part_name;
+ if (!G_STR_EMPTY (jid_str)) {
+ return gossip_jid_string_get_part_name (jid_str);
}
- return "";
+ return g_strdup ("");
}
GError *
Modified: trunk/libgossip/gossip-jabber-utils.h
==============================================================================
--- trunk/libgossip/gossip-jabber-utils.h (original)
+++ trunk/libgossip/gossip-jabber-utils.h Sat Jul 5 12:58:07 2008
@@ -51,33 +51,39 @@
} GossipJabberAsyncData;
/* Data utils */
-GossipJabberAsyncData *gossip_jabber_async_data_new (GossipJabber *jabber,
- GossipErrorCallback callback,
- gpointer user_data);
-void gossip_jabber_async_data_free (GossipJabberAsyncData *ad);
+GossipJabberAsyncData *gossip_jabber_async_data_new (GossipJabber *jabber,
+ GossipErrorCallback callback,
+ gpointer user_data);
+void gossip_jabber_async_data_free (GossipJabberAsyncData *ad);
/* Presence utils */
-const gchar * gossip_jabber_presence_state_to_str (GossipPresence *presence);
-GossipPresenceState gossip_jabber_presence_state_from_str (const gchar *str);
+const gchar * gossip_jabber_presence_state_to_str (GossipPresence *presence);
+GossipPresenceState gossip_jabber_presence_state_from_str (const gchar *str);
+
/* Message utils */
-GossipTime gossip_jabber_get_message_timestamp (LmMessage *m);
-GossipChatroomInvite * gossip_jabber_get_message_conference (GossipJabber *jabber,
- LmMessage *m);
-gboolean gossip_jabber_get_message_is_event (LmMessage *m);
-gboolean gossip_jabber_get_message_is_composing (LmMessage *m);
+GossipTime gossip_jabber_get_message_timestamp (LmMessage *m);
+GossipChatroomInvite * gossip_jabber_get_message_conference (GossipJabber *jabber,
+ LmMessage *m);
+gboolean gossip_jabber_get_message_is_event (LmMessage *m);
+gboolean gossip_jabber_get_message_is_composing (LmMessage *m);
+gboolean gossip_jabber_get_message_has_status (LmMessage *m,
+ gint code);
+gboolean gossip_jabber_get_message_is_muc_new_nick (LmMessage *m,
+ gchar **new_nick);
/* Contact utils */
-gchar * gossip_jabber_get_name_to_use (const gchar *jid_str,
- const gchar *nickname,
- const gchar *full_name);
+gchar * gossip_jabber_get_name_to_use (const gchar *jid_str,
+ const gchar *nickname,
+ const gchar *full_name,
+ const gchar *current_name);
/* Error utils */
-GError * gossip_jabber_error_create (GossipJabberError code,
- const gchar *reason);
-void gossip_jabber_error (GossipJabber *jabber,
- GossipJabberError code);
-const gchar * gossip_jabber_error_to_string (GossipJabberError error);
+GError * gossip_jabber_error_create (GossipJabberError code,
+ const gchar *reason);
+void gossip_jabber_error (GossipJabber *jabber,
+ GossipJabberError code);
+const gchar * gossip_jabber_error_to_string (GossipJabberError error);
G_END_DECLS
Modified: trunk/libgossip/gossip-jabber-vcard.c
==============================================================================
--- trunk/libgossip/gossip-jabber-vcard.c (original)
+++ trunk/libgossip/gossip-jabber-vcard.c Sat Jul 5 12:58:07 2008
@@ -232,7 +232,7 @@
LmMessageHandler *handler;
GossipCallbackData *data;
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
gossip_debug (DEBUG_DOMAIN, "Requesting VCard, JID:'%s'", jid_str);
@@ -315,7 +315,7 @@
gossip_debug (DEBUG_DOMAIN, "Setting...");
- connection = gossip_jabber_get_connection (jabber);
+ connection = _gossip_jabber_get_connection (jabber);
m = lm_message_new_with_sub_type (NULL,
LM_MESSAGE_TYPE_IQ,
Modified: trunk/libgossip/gossip-jabber.c
==============================================================================
--- trunk/libgossip/gossip-jabber.c (original)
+++ trunk/libgossip/gossip-jabber.c Sat Jul 5 12:58:07 2008
@@ -25,22 +25,21 @@
#include <glib/gi18n.h>
-#include <libgossip/gossip-account.h>
-#include <libgossip/gossip-async.h>
-#include <libgossip/gossip-avatar.h>
-#include <libgossip/gossip-contact.h>
-#include <libgossip/gossip-contact-manager.h>
-#include <libgossip/gossip-conf.h>
-#include <libgossip/gossip-chatroom.h>
-#include <libgossip/gossip-debug.h>
-#include <libgossip/gossip-chatroom-provider.h>
-#include <libgossip/gossip-ft.h>
-#include <libgossip/gossip-ft-provider.h>
-#include <libgossip/gossip-message.h>
-#include <libgossip/gossip-session.h>
-#include <libgossip/gossip-utils.h>
-#include <libgossip/gossip-vcard.h>
-#include <libgossip/gossip-version-info.h>
+#include "gossip-jabber.h"
+#include "gossip-account.h"
+#include "gossip-avatar.h"
+#include "gossip-contact.h"
+#include "gossip-contact-manager.h"
+#include "gossip-conf.h"
+#include "gossip-chatroom.h"
+#include "gossip-debug.h"
+#include "gossip-chatroom-provider.h"
+#include "gossip-ft.h"
+#include "gossip-ft-provider.h"
+#include "gossip-utils.h"
+#include "gossip-vcard.h"
+#include "gossip-version-info.h"
+#include "gossip-session.h"
#include "gossip-jid.h"
#include "gossip-jabber-chatrooms.h"
@@ -53,7 +52,6 @@
#include "gossip-jabber-utils.h"
#include "libgossip-marshal.h"
-#include "gossip-jabber.h"
#include "gossip-jabber-private.h"
#include "gossip-sha.h"
@@ -82,16 +80,17 @@
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_JABBER, GossipJabberPriv))
struct _GossipJabberPriv {
+ GossipSession *session;
+
LmConnection *connection;
LmSSLStatus ssl_status;
gboolean ssl_disconnection;
- GossipContact *contact;
GossipAccount *account;
GossipPresence *presence;
GossipVCard *vcard;
- GHashTable *contacts;
+ GHashTable *contact_list;
/* Cancel registration attempt */
gboolean register_cancel;
@@ -138,8 +137,8 @@
static void jabber_finalize (GObject *object);
static gboolean jabber_login_timeout_cb (GossipJabber *jabber);
static gboolean jabber_logout_contact_foreach (gpointer key,
- GossipContact *contact,
- GossipJabber *jabber);
+ gpointer value,
+ gpointer user_data);
static void jabber_connected_cb (LmConnection *connection,
gboolean result,
GossipJabber *jabber);
@@ -165,13 +164,13 @@
static void jabber_contact_vcard_cb (GossipResult result,
GossipVCard *vcard,
JabberData *data);
-static void jabber_group_rename_foreach_cb (const gchar *jid,
- GossipContact *contact,
- RenameGroupData *rg);
+static void jabber_group_rename_foreach_cb (gpointer key,
+ gpointer value,
+ gpointer user_data);
static GossipPresence * jabber_get_presence (LmMessage *message);
-static void jabber_get_groups_foreach_cb (const gchar *jid,
- GossipContact *contact,
- GList **list);
+static void jabber_get_groups_foreach_cb (gpointer key,
+ gpointer value,
+ gpointer user_data);
static LmHandlerResult jabber_message_handler (LmMessageHandler *handler,
LmConnection *conn,
LmMessage *message,
@@ -220,8 +219,6 @@
GossipChatroomId id,
GossipContact *contact,
const gchar *reason);
-static GSList * jabber_chatroom_get_contacts (GossipChatroomProvider *provider,
- GossipChatroomId id);
static GossipChatroom * jabber_chatroom_find_by_id (GossipChatroomProvider *provider,
GossipChatroomId id);
static GossipChatroom * jabber_chatroom_find (GossipChatroomProvider *provider,
@@ -259,7 +256,7 @@
static JabberData * jabber_data_new (GossipJabber *jabber,
GossipContact *contact,
gpointer user_data);
-static void jabber_data_free (JabberData *data);
+static void jabber_data_free (gpointer data);
static const gchar *server_conversions[] = {
"gmail.com", "talk.google.com",
@@ -423,28 +420,28 @@
priv = GET_PRIV (jabber);
- priv->contacts =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
+ priv->contact_list =
+ g_hash_table_new_full (gossip_contact_hash,
+ gossip_contact_equal,
+ g_object_unref,
+ NULL);
priv->composing_ids =
g_hash_table_new_full (gossip_contact_hash,
gossip_contact_equal,
- (GDestroyNotify) g_object_unref,
- (GDestroyNotify) g_free);
+ g_object_unref,
+ g_free);
priv->composing_timeouts =
g_hash_table_new_full (gossip_contact_hash,
gossip_contact_equal,
- (GDestroyNotify) g_object_unref,
- (GDestroyNotify) jabber_data_free);
+ g_object_unref,
+ jabber_data_free);
priv->composing_requests =
g_hash_table_new_full (gossip_contact_hash,
gossip_contact_equal,
- (GDestroyNotify) g_object_unref,
+ g_object_unref,
NULL);
}
@@ -461,10 +458,6 @@
g_object_unref (priv->account);
}
- if (priv->contact) {
- g_object_unref (priv->contact);
- }
-
if (priv->vcard) {
g_object_unref (priv->vcard);
}
@@ -473,7 +466,11 @@
g_object_unref (priv->presence);
}
- g_hash_table_destroy (priv->contacts);
+ if (priv->session) {
+ g_object_unref (priv->session);
+ }
+
+ g_hash_table_unref (priv->contact_list);
/* finalize extended modules */
gossip_jabber_chatrooms_finalize (priv->chatrooms);
@@ -500,6 +497,22 @@
(G_OBJECT_CLASS (gossip_jabber_parent_class)->finalize) (object);
}
+GossipJabber *
+gossip_jabber_new (gpointer session)
+{
+ GossipJabber *jabber;
+ GossipJabberPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_SESSION (session), NULL);
+
+ jabber = g_object_new (GOSSIP_TYPE_JABBER, NULL);
+
+ priv = GET_PRIV (jabber);
+ priv->session = g_object_ref (session);
+
+ return jabber;
+}
+
GossipAccount *
gossip_jabber_new_account (void)
{
@@ -527,40 +540,17 @@
"use_ssl", gossip_jabber_is_ssl_supported (),
NULL);
- gossip_jid_unref (jid);
+ g_object_unref (jid);
return account;
}
-GossipContact *
-gossip_jabber_new_contact (GossipJabber *jabber,
- const gchar *id,
- const gchar *name)
-{
- GossipContact *contact;
- gboolean new_contact;
-
- g_return_val_if_fail (GOSSIP_IS_JABBER (jabber), NULL);
-
- contact = gossip_jabber_get_contact_from_jid (jabber,
- id,
- &new_contact,
- FALSE,
- FALSE);
- if (new_contact && !G_STR_EMPTY (name)) {
- gossip_contact_set_name (contact, name);
- }
-
- return contact;
-}
-
void
gossip_jabber_setup (GossipJabber *jabber,
GossipAccount *account)
{
GossipJabberPriv *priv;
LmMessageHandler *handler;
- const gchar *server;
g_return_if_fail (GOSSIP_IS_JABBER (jabber));
g_return_if_fail (GOSSIP_IS_ACCOUNT (account));
@@ -568,22 +558,20 @@
priv = GET_PRIV (jabber);
priv->account = g_object_ref (account);
- priv->contact = gossip_contact_new (GOSSIP_CONTACT_TYPE_USER,
- priv->account);
- /* Store the password for the next connection */
+ /* Update the connection details */
+ priv->connection = _gossip_jabber_new_connection (jabber, account);
- server = gossip_account_get_server (priv->account);
-
- priv->connection = gossip_jabber_new_connection (jabber, account);
-
- /* setup the connection to send keep alive messages every 30 seconds */
+ /* Setup the connection to send keep alive messages every 30
+ * seconds.
+ */
lm_connection_set_keep_alive_rate (priv->connection, 30);
lm_connection_set_disconnect_function (priv->connection,
(LmDisconnectFunction) jabber_disconnected_cb,
jabber, NULL);
+ /* Set up handlers for messages and presence */
handler = lm_message_handler_new ((LmHandleMessageFunction) jabber_message_handler,
jabber, NULL);
lm_connection_register_message_handler (priv->connection,
@@ -608,7 +596,7 @@
LM_HANDLER_PRIORITY_NORMAL);
lm_message_handler_unref (handler);
- /* initiate extended modules */
+ /* Initiate extended modules */
priv->chatrooms = gossip_jabber_chatrooms_init (jabber);
priv->fts = gossip_jabber_ft_init (jabber);
gossip_jabber_disco_init (jabber);
@@ -624,6 +612,7 @@
gossip_jabber_login (GossipJabber *jabber)
{
GossipJabberPriv *priv;
+ GossipContact *own_contact;
const gchar *id;
const gchar *password;
GError *error = NULL;
@@ -635,14 +624,20 @@
gossip_debug (DEBUG_DOMAIN, "Refreshing connection details");
- gossip_jabber_set_connection (priv->connection,
- jabber,
- priv->account);
+ own_contact = gossip_jabber_get_contact_from_jid (jabber,
+ gossip_account_get_id (priv->account),
+ TRUE,
+ FALSE,
+ FALSE);
+
+ _gossip_jabber_set_connection (priv->connection,
+ jabber,
+ priv->account);
/* Update connection details and own contact information */
id = gossip_account_get_id (priv->account);
- gossip_contact_set_id (priv->contact, id);
-
+ gossip_contact_set_id (own_contact, id);
+
/* Check the saved password */
password = gossip_account_get_password (priv->account);
if (G_STR_EMPTY (password)) {
@@ -772,33 +767,21 @@
}
static gboolean
-jabber_logout_contact_foreach (gpointer key,
- GossipContact *contact,
- GossipJabber *jabber)
+jabber_logout_contact_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
- GList *presences;
- GList *l;
- GossipPresence *presence;
+ GossipContact *contact;
+ GossipJabber *jabber;
- /* Set each contact to be offline, since they effectively are
- * now we don't know.
- */
- presences = g_list_copy (gossip_contact_get_presence_list (contact));
+ contact = GOSSIP_CONTACT (key);
+ jabber = GOSSIP_JABBER (user_data);
/* Copy the list since it will be modified during traversal
* otherwise.
*/
- for (l = presences; l; l = l->next) {
- presence = l->data;
-
- if (!presence) {
- continue;
- }
-
- gossip_contact_remove_presence (contact, presence);
- }
- g_list_free (presences);
+ gossip_contact_set_presence_list (contact, NULL);
g_signal_emit_by_name (jabber, "contact-removed", contact);
@@ -992,6 +975,7 @@
GossipJabber *jabber)
{
GossipJabberPriv *priv;
+ GossipContact *own_contact;
LmMessage *m;
LmMessageNode *node;
@@ -1025,15 +1009,22 @@
g_signal_emit_by_name (jabber, "connected", priv->account);
+ own_contact = gossip_jabber_get_contact_from_jid (jabber,
+ gossip_account_get_id (priv->account),
+ TRUE,
+ FALSE,
+ FALSE);
+
if (priv->vcard) {
gchar *name;
name = gossip_jabber_get_name_to_use
- (gossip_contact_get_id (priv->contact),
+ (gossip_contact_get_id (own_contact),
gossip_vcard_get_nickname (priv->vcard),
- gossip_vcard_get_name (priv->vcard));
+ gossip_vcard_get_name (priv->vcard),
+ gossip_contact_get_name (own_contact));
- gossip_contact_set_name (priv->contact, name);
+ gossip_contact_set_name (own_contact, name);
g_free (name);
/* Set the vcard waiting to be sent to our jabber server once
@@ -1049,7 +1040,7 @@
/* Request our vcard so we know what our nick name is to use
* in chats windows, etc.
*/
- jabber_contact_vcard (jabber, priv->contact);
+ jabber_contact_vcard (jabber, own_contact);
}
}
@@ -1069,9 +1060,9 @@
}
/* Signal removal of each contact */
- if (priv->contacts) {
- g_hash_table_foreach_remove (priv->contacts,
- (GHRFunc) jabber_logout_contact_foreach,
+ if (priv->contact_list) {
+ g_hash_table_foreach_remove (priv->contact_list,
+ jabber_logout_contact_foreach,
jabber);
}
@@ -1227,7 +1218,7 @@
lm_message_node_add_child (node, "username", gossip_jid_get_part_name (jid));
lm_message_node_add_child (node, "password", new_password);
- gossip_jid_unref (jid);
+ g_object_unref (jid);
ad = gossip_jabber_async_data_new (jabber, callback, user_data);
ad->message_handler = lm_message_handler_new ((LmHandleMessageFunction)
@@ -1371,7 +1362,7 @@
}
server = g_strdup (str);
- gossip_jid_unref (jid);
+ g_object_unref (jid);
return server;
}
@@ -1395,7 +1386,6 @@
const gchar *recipient_id;
const gchar *resource;
gchar *jid_str;
- gboolean new_contact;
g_return_if_fail (GOSSIP_IS_JABBER (jabber));
@@ -1406,17 +1396,11 @@
recipient_id = gossip_contact_get_id (recipient);
resource = gossip_message_get_explicit_resource (message);
- /* Getting contact from JID, this will add them to our
- * contacts hash table if they don't exist too.
- */
recipient = gossip_jabber_get_contact_from_jid (jabber,
recipient_id,
- &new_contact,
+ FALSE,
FALSE,
TRUE);
- if (new_contact) {
- g_object_unref (recipient);
- }
if (resource && g_utf8_strlen (resource, -1) > 0) {
jid_str = g_strdup_printf ("%s/%s", recipient_id, resource);
@@ -1638,26 +1622,6 @@
error);
}
-GossipContact *
-gossip_jabber_find_contact (GossipJabber *jabber, const gchar *id)
-{
- GossipJabberPriv *priv;
- GossipJID *jid;
- GossipContact *contact;
-
- g_return_val_if_fail (GOSSIP_IS_JABBER (jabber), NULL);
-
- priv = GET_PRIV (jabber);
-
- jid = gossip_jid_new (id);
- contact = g_hash_table_lookup (priv->contacts,
- gossip_jid_get_without_resource (jid));
-
- gossip_jid_unref (jid);
-
- return contact;
-}
-
void
gossip_jabber_add_contact (GossipJabber *jabber,
const gchar *id,
@@ -1682,7 +1646,12 @@
priv = GET_PRIV (jabber);
jid = gossip_jid_new (id);
- contact = g_hash_table_lookup (priv->contacts, gossip_jid_get_without_resource (jid));
+
+ contact = gossip_jabber_get_contact_from_jid (jabber,
+ gossip_jid_get_without_resource (jid),
+ FALSE,
+ FALSE,
+ FALSE);
if (contact) {
subscription = gossip_contact_get_subscription (contact);
@@ -1695,7 +1664,6 @@
* and it makes sense to use our provided name/group, etc
*/
add_to_roster = TRUE;
-/* add_to_roster = gossip_contact_get_type (contact) == GOSSIP_CONTACT_TYPE_TEMPORARY; */
if (add_to_roster) {
gossip_debug (DEBUG_DOMAIN, "Adding contact:'%s' to roster...", id);
@@ -1748,7 +1716,7 @@
"subscription is either TO or BOTH");
}
- gossip_jid_unref (jid);
+ g_object_unref (jid);
}
void
@@ -1829,8 +1797,6 @@
gossip_debug (DEBUG_DOMAIN,
"Contact:'%s' being removed with current ref count:%d",
gossip_contact_get_id (contact), G_OBJECT (contact)->ref_count);
-
- g_hash_table_remove (priv->contacts, contact);
}
void
@@ -1919,7 +1885,8 @@
name = gossip_jabber_get_name_to_use
(gossip_contact_get_id (data->contact),
gossip_vcard_get_nickname (vcard),
- gossip_vcard_get_name (vcard));
+ gossip_vcard_get_name (vcard),
+ gossip_contact_get_name (data->contact));
gossip_contact_set_name (data->contact, name);
g_free (name);
@@ -1951,44 +1918,23 @@
NULL);
}
-void
-gossip_jabber_rename_group (GossipJabber *jabber,
- const gchar *group,
- const gchar *new_name)
-{
- GossipJabberPriv *priv;
-
- RenameGroupData *rg;
-
- priv = GET_PRIV (jabber);
-
- rg = g_new0 (RenameGroupData, 1);
-
- rg->jabber = jabber;
- rg->group = g_strdup (group);
- rg->new_name = g_strdup (new_name);
-
- g_hash_table_foreach (priv->contacts,
- (GHFunc)jabber_group_rename_foreach_cb,
- rg);
-
- g_free (rg->group);
- g_free (rg->new_name);
- g_free (rg);
-}
-
static void
-jabber_group_rename_foreach_cb (const gchar *jid,
- GossipContact *contact,
- RenameGroupData *rg)
+jabber_group_rename_foreach_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
GossipJabberPriv *priv;
+ GossipContact *contact;
+ RenameGroupData *rg;
LmMessage *m;
LmMessageNode *node;
gchar *escaped;
GList *l;
gboolean found = FALSE;
+ contact = GOSSIP_CONTACT (key);
+ rg = (RenameGroupData *) user_data;
+
priv = GET_PRIV (rg->jabber);
for (l = gossip_contact_get_groups (contact); l && !found; l = l->next) {
@@ -2042,6 +1988,32 @@
lm_message_unref (m);
}
+void
+gossip_jabber_rename_group (GossipJabber *jabber,
+ const gchar *group,
+ const gchar *new_name)
+{
+ GossipJabberPriv *priv;
+
+ RenameGroupData *rg;
+
+ priv = GET_PRIV (jabber);
+
+ rg = g_new0 (RenameGroupData, 1);
+
+ rg->jabber = jabber;
+ rg->group = g_strdup (group);
+ rg->new_name = g_strdup (new_name);
+
+ g_hash_table_foreach (priv->contact_list,
+ (GHFunc) jabber_group_rename_foreach_cb,
+ rg);
+
+ g_free (rg->group);
+ g_free (rg->new_name);
+ g_free (rg);
+}
+
static GossipPresence *
jabber_get_presence (LmMessage *m)
{
@@ -2099,29 +2071,17 @@
return gossip_presence_get_resource (presence);
}
-GList *
-gossip_jabber_get_groups (GossipJabber *jabber)
-{
- GossipJabberPriv *priv;
- GList *list = NULL;
-
- priv = GET_PRIV (jabber);
-
- g_hash_table_foreach (priv->contacts,
- (GHFunc)jabber_get_groups_foreach_cb,
- &list);
-
- list = g_list_sort (list, (GCompareFunc)strcmp);
-
- return list;
-}
-
static void
-jabber_get_groups_foreach_cb (const gchar *jid,
- GossipContact *contact,
- GList **list)
+jabber_get_groups_foreach_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
- GList *l;
+ GossipContact *contact;
+ GList **list;
+ GList *l;
+
+ contact = GOSSIP_CONTACT (key);
+ list = (GList **) user_data;
if (!gossip_contact_get_groups (contact)) {
return;
@@ -2142,6 +2102,23 @@
}
}
+GList *
+gossip_jabber_get_groups (GossipJabber *jabber)
+{
+ GossipJabberPriv *priv;
+ GList *list = NULL;
+
+ priv = GET_PRIV (jabber);
+
+ g_hash_table_foreach (priv->contact_list,
+ (GHFunc) jabber_get_groups_foreach_cb,
+ &list);
+
+ list = g_list_sort (list, (GCompareFunc)strcmp);
+
+ return list;
+}
+
gboolean
gossip_jabber_get_vcard (GossipJabber *jabber,
GossipContact *contact,
@@ -2157,7 +2134,15 @@
if (contact) {
jid_str = gossip_contact_get_id (contact);
} else {
- jid_str = gossip_contact_get_id (priv->contact);
+ GossipContact *own_contact;
+
+ own_contact = gossip_jabber_get_contact_from_jid (jabber,
+ gossip_account_get_id (priv->account),
+ TRUE,
+ FALSE,
+ FALSE);
+
+ jid_str = gossip_contact_get_id (own_contact);
}
return gossip_jabber_vcard_get (jabber,
@@ -2211,6 +2196,7 @@
GossipMessage *message;
const gchar *from_str;
GossipContact *from;
+ GossipContact *own_contact;
const gchar *thread = NULL;
const gchar *subject = NULL;
const gchar *body = NULL;
@@ -2231,9 +2217,10 @@
}
from_str = lm_message_node_get_attribute (m->node, "from");
+
from = gossip_jabber_get_contact_from_jid (jabber,
from_str,
- NULL,
+ FALSE,
FALSE,
TRUE);
@@ -2301,12 +2288,12 @@
invite = gossip_jabber_get_message_conference (jabber, m);
if (invite) {
- GossipContact *invitor;
+ GossipContact *inviter;
- invitor = gossip_chatroom_invite_get_invitor (invite);
+ inviter = gossip_chatroom_invite_get_inviter (invite);
gossip_debug (DEBUG_DOMAIN, "Chat room invitiation from:'%s' for room:'%s', reason:'%s'",
- gossip_contact_get_id (invitor),
+ gossip_contact_get_id (inviter),
gossip_chatroom_invite_get_id (invite),
gossip_chatroom_invite_get_reason (invite));
@@ -2314,7 +2301,7 @@
* not the chatroom that sent the request on their
* behalf.
*/
- from = invitor;
+ from = inviter;
/* Make sure we have some sort of body for
* invitations, since it is not necessary but should
@@ -2342,8 +2329,13 @@
thread = node->value;
}
- message = gossip_message_new (GOSSIP_MESSAGE_TYPE_NORMAL,
- priv->contact);
+ own_contact = gossip_jabber_get_contact_from_jid (jabber,
+ gossip_account_get_id (priv->account),
+ TRUE,
+ FALSE,
+ FALSE);
+
+ message = gossip_message_new (GOSSIP_MESSAGE_TYPE_NORMAL, own_contact);
/* To make the sender right in private chat messages sent from
* groupchats, we take the name from the resource, which carries the
@@ -2362,7 +2354,7 @@
gossip_contact_set_name (from, resource);
- gossip_jid_unref (jid);
+ g_object_unref (jid);
}
gossip_message_set_sender (message, from);
@@ -2405,22 +2397,21 @@
GossipContact *contact;
const gchar *from;
const gchar *type;
- gboolean new_item = FALSE;
priv = GET_PRIV (jabber);
from = lm_message_node_get_attribute (m->node, "from");
- gossip_debug (DEBUG_DOMAIN, "New presence from:'%s'",
- lm_message_node_get_attribute (m->node, "from"));
- if (gossip_jabber_chatrooms_get_jid_is_chatroom (priv->chatrooms,
- from)) {
+ if (gossip_jabber_chatrooms_get_jid_is_chatroom (priv->chatrooms, from)) {
return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
+ gossip_debug (DEBUG_DOMAIN, "New presence from:'%s'",
+ lm_message_node_get_attribute (m->node, "from"));
+
contact = gossip_jabber_get_contact_from_jid (jabber,
from,
- &new_item,
+ FALSE,
FALSE,
TRUE);
@@ -2484,7 +2475,7 @@
g_object_unref (presence);
}
- gossip_jid_unref (jid);
+ g_object_unref (jid);
}
return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
@@ -2722,10 +2713,16 @@
contact = gossip_jabber_get_contact_from_jid (jabber,
jid_str,
- &added_item,
+ FALSE,
TRUE,
FALSE);
+ if (!g_hash_table_lookup (priv->contact_list, contact)) {
+ g_hash_table_insert (priv->contact_list,
+ g_object_ref (contact),
+ GINT_TO_POINTER (1));
+ }
+
type = gossip_contact_get_type (contact);
/* Subscription */
@@ -2735,7 +2732,7 @@
if (strcmp (subscription, "remove") == 0) {
g_signal_emit_by_name (jabber, "contact-removed", contact);
- g_hash_table_remove (priv->contacts, gossip_contact_get_id (contact));
+ g_hash_table_remove (priv->contact_list, contact);
continue;
} else if (strcmp (subscription, "both") == 0) {
subscription_type = GOSSIP_SUBSCRIPTION_BOTH;
@@ -2848,7 +2845,6 @@
iface->change_nick = jabber_chatroom_change_nick;
iface->leave = jabber_chatroom_leave;
iface->kick = jabber_chatroom_kick;
- iface->get_contacts = jabber_chatroom_get_contacts;
iface->find_by_id = jabber_chatroom_find_by_id;
iface->find = jabber_chatroom_find;
iface->invite = jabber_chatroom_invite;
@@ -2974,21 +2970,6 @@
gossip_jabber_chatrooms_kick (priv->chatrooms, id, contact, reason);
}
-static GSList *
-jabber_chatroom_get_contacts (GossipChatroomProvider *provider,
- GossipChatroomId id)
-{
- GossipJabber *jabber;
- GossipJabberPriv *priv;
-
- g_return_val_if_fail (GOSSIP_IS_JABBER (provider), NULL);
-
- jabber = GOSSIP_JABBER (provider);
- priv = GET_PRIV (jabber);
-
- return gossip_jabber_chatrooms_get_contacts (priv->chatrooms, id);
-}
-
static GossipChatroom *
jabber_chatroom_find_by_id (GossipChatroomProvider *provider,
GossipChatroomId id)
@@ -3214,21 +3195,25 @@
}
static void
-jabber_data_free (JabberData *data)
+jabber_data_free (gpointer data)
{
+ JabberData *jd;
+
if (!data) {
return;
}
- if (data->jabber) {
- g_object_unref (data->jabber);
+ jd = (JabberData *) data;
+
+ if (jd->jabber) {
+ g_object_unref (jd->jabber);
}
- if (data->contact) {
- g_object_unref (data->contact);
+ if (jd->contact) {
+ g_object_unref (jd->contact);
}
- g_slice_free (JabberData, data);
+ g_slice_free (JabberData, jd);
}
/*
@@ -3257,81 +3242,97 @@
gossip_jabber_get_own_contact (GossipJabber *jabber)
{
GossipJabberPriv *priv;
+ GossipContact *own_contact;
g_return_val_if_fail (GOSSIP_IS_JABBER (jabber), NULL);
priv = GET_PRIV (jabber);
- return priv->contact;
+ own_contact = gossip_jabber_get_contact_from_jid (jabber,
+ gossip_account_get_id (priv->account),
+ TRUE,
+ FALSE,
+ FALSE);
+
+ return own_contact;
}
GossipContact *
gossip_jabber_get_contact_from_jid (GossipJabber *jabber,
const gchar *jid_str,
- gboolean *new_item,
+ gboolean own_contact,
gboolean set_permanent,
gboolean get_vcard)
{
- GossipJabberPriv *priv;
- GossipContact *contact;
- GossipContactType type;
- GossipJID *jid;
- gboolean tmp_new_item = FALSE;
+ GossipJabberPriv *priv;
+ GossipContact *contact;
+ GossipContactManager *contact_manager;
+ GossipContactType type;
+ GossipJID *jid;
+ gboolean is_chatroom;
+ gboolean created;
priv = GET_PRIV (jabber);
+ contact_manager = gossip_session_get_contact_manager (priv->session);
+
jid = gossip_jid_new (jid_str);
+ is_chatroom = gossip_jabber_chatrooms_get_jid_is_chatroom (priv->chatrooms, jid_str);
+
+ if (is_chatroom) {
+ const gchar *resource;
+
+ resource = gossip_jid_get_resource (jid);
+
+ /* If there is no resource, this is the chatroom JID
+ * itself, it isn't a contact. So we don't set the
+ * name. Should we return NULL here as the contact?
+ */
+ if (!G_STR_EMPTY (resource)) {
+ type = GOSSIP_CONTACT_TYPE_CHATROOM;
- contact = g_hash_table_lookup (priv->contacts,
- gossip_jid_get_without_resource (jid));
+ contact = gossip_contact_manager_find_or_create (contact_manager,
+ priv->account,
+ type,
+ gossip_jid_get_full (jid),
+ &created);
+ gossip_contact_set_name (contact, resource);
- if (!contact) {
- if (set_permanent) {
+ if (!created && set_permanent) {
+ gossip_contact_set_type (contact, type);
+ }
+ } else {
+ contact = NULL;
+ }
+ } else {
+ if (own_contact) {
+ type = GOSSIP_CONTACT_TYPE_USER;
+ } else if (set_permanent) {
type = GOSSIP_CONTACT_TYPE_CONTACTLIST;
} else {
type = GOSSIP_CONTACT_TYPE_TEMPORARY;
}
- gossip_debug (DEBUG_DOMAIN,
- "New contact:'%s' (%s)",
- gossip_jid_get_full (jid),
- gossip_contact_type_to_string (type));
-
- contact = gossip_contact_new (type, priv->account);
- gossip_contact_set_id (contact, gossip_jid_get_full (jid));
- gossip_contact_set_name (contact, gossip_jid_get_without_resource (jid));
-
- tmp_new_item = TRUE;
-
- g_hash_table_insert (priv->contacts,
- g_strdup (gossip_jid_get_without_resource (jid)),
- contact);
+ contact = gossip_contact_manager_find_or_create (contact_manager,
+ priv->account,
+ type,
+ gossip_jid_get_without_resource (jid),
+ &created);
+ if (!created && set_permanent) {
+ gossip_contact_set_type (contact, type);
+ }
+
+ /* Don't get vcards for chatroom contacts */
if (get_vcard) {
/* Request contacts VCard details so we can get the
* real name for them for chat windows, etc
*/
jabber_contact_vcard (jabber, contact);
}
- } else {
- if (set_permanent) {
- gossip_contact_set_type (contact, GOSSIP_CONTACT_TYPE_CONTACTLIST);
- }
-
- type = gossip_contact_get_type (contact);
-
- gossip_debug (DEBUG_DOMAIN,
- "Get contact:'%s', type:%d-->'%s'",
- gossip_jid_get_full (jid),
- type,
- gossip_contact_type_to_string (type));
}
- gossip_jid_unref (jid);
-
- if (new_item) {
- *new_item = tmp_new_item;
- }
+ g_object_unref (jid);
return contact;
}
@@ -3449,9 +3450,9 @@
*/
gboolean
-gossip_jabber_set_connection (LmConnection *connection,
- GossipJabber *jabber,
- GossipAccount *account)
+_gossip_jabber_set_connection (LmConnection *connection,
+ GossipJabber *jabber,
+ GossipAccount *account)
{
GossipJID *jid;
const gchar *id;
@@ -3472,7 +3473,7 @@
gossip_debug (DEBUG_DOMAIN, "- ID:'%s'", id);
jid = gossip_jid_new (id);
lm_connection_set_jid (connection, gossip_jid_get_without_resource (jid));
- gossip_jid_unref (jid);
+ g_object_unref (jid);
}
@@ -3569,7 +3570,7 @@
}
LmConnection *
-gossip_jabber_new_connection (GossipJabber *jabber,
+_gossip_jabber_new_connection (GossipJabber *jabber,
GossipAccount *account)
{
LmConnection *connection;
@@ -3579,13 +3580,13 @@
server = gossip_account_get_server (account);
connection = lm_connection_new (server);
- gossip_jabber_set_connection (connection, jabber, account);
+ _gossip_jabber_set_connection (connection, jabber, account);
return connection;
}
LmConnection *
-gossip_jabber_get_connection (GossipJabber *jabber)
+_gossip_jabber_get_connection (GossipJabber *jabber)
{
GossipJabberPriv *priv;
@@ -3596,8 +3597,18 @@
return priv->connection;
}
+GossipSession *
+_gossip_jabber_get_session (GossipJabber *jabber)
+{
+ GossipJabberPriv *priv;
+
+ priv = GET_PRIV (jabber);
+
+ return priv->session;
+}
+
GossipJabberFTs *
-gossip_jabber_get_fts (GossipJabber *jabber)
+_gossip_jabber_get_fts (GossipJabber *jabber)
{
GossipJabberPriv *priv;
@@ -3607,4 +3618,3 @@
return priv->fts;
}
-
Modified: trunk/libgossip/gossip-jabber.h
==============================================================================
--- trunk/libgossip/gossip-jabber.h (original)
+++ trunk/libgossip/gossip-jabber.h Sat Jul 5 12:58:07 2008
@@ -22,6 +22,7 @@
#define __GOSSIP_JABBER_H__
#include <glib-object.h>
+
#include "gossip-async.h"
#include "gossip-message.h"
@@ -57,6 +58,8 @@
GQuark gossip_jabber_error_quark (void) G_GNUC_CONST;
+GossipJabber * gossip_jabber_new (gpointer session);
+
void gossip_jabber_setup (GossipJabber *jabber,
GossipAccount *account);
void gossip_jabber_login (GossipJabber *jabber);
@@ -66,7 +69,7 @@
GossipContact *gossip_jabber_get_own_contact (GossipJabber *jabber);
GossipContact *gossip_jabber_get_contact_from_jid (GossipJabber *jabber,
const gchar *jid,
- gboolean *new_item,
+ gboolean own_contact,
gboolean set_permanent,
gboolean get_vcard);
void gossip_jabber_send_presence (GossipJabber *jabber,
@@ -81,9 +84,6 @@
gchar * gossip_jabber_get_default_server (const gchar *username);
guint gossip_jabber_get_default_port (gboolean use_ssl);
gboolean gossip_jabber_is_ssl_supported (void);
-GossipContact *gossip_jabber_new_contact (GossipJabber *jabber,
- const gchar *id,
- const gchar *name);
gboolean gossip_jabber_is_connected (GossipJabber *jabber);
gboolean gossip_jabber_is_connecting (GossipJabber *jabber);
void gossip_jabber_send_message (GossipJabber *jabber,
@@ -101,8 +101,6 @@
GossipCallback callback,
gpointer user_data,
GError **error);
-GossipContact * gossip_jabber_find_contact (GossipJabber *jabber,
- const gchar *id);
void gossip_jabber_add_contact (GossipJabber *jabber,
const gchar *id,
const gchar *name,
Modified: trunk/libgossip/gossip-jid.c
==============================================================================
--- trunk/libgossip/gossip-jid.c (original)
+++ trunk/libgossip/gossip-jid.c Sat Jul 5 12:58:07 2008
@@ -29,27 +29,114 @@
#include "gossip-jid.h"
-struct GossipJID {
- gchar *full;
- gchar *no_resource;
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_JID, GossipJIDPriv))
+
+typedef struct _GossipJIDPriv GossipJIDPriv;
+
+struct _GossipJIDPriv {
+ gchar *full;
+ gchar *no_resource;
const gchar *resource;
+};
- guint ref_count;
+static void gossip_jid_class_init (GossipJIDClass *class);
+static void gossip_jid_init (GossipJID *jid);
+static void gossip_jid_finalize (GObject *object);
+static void jid_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static const gchar *jid_locate_resource (const gchar *str);
+
+enum {
+ PROP_0,
+ PROP_FULL,
+ PROP_WITHOUT_RESOURCE,
+ PROP_RESOURCE
};
-void jid_free (GossipJID *jid);
-const gchar *jid_locate_resource (const gchar *str);
+G_DEFINE_TYPE (GossipJID, gossip_jid, G_TYPE_OBJECT);
-void
-jid_free (GossipJID *jid)
+static void
+gossip_jid_class_init (GossipJIDClass *class)
{
- g_free (jid->full);
- g_free (jid->no_resource);
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = gossip_jid_finalize;
+ object_class->get_property = jid_get_property;
- g_slice_free (GossipJID, jid);
+ g_object_class_install_property (object_class,
+ PROP_FULL,
+ g_param_spec_string ("full",
+ "Full JID",
+ "Full JID",
+ NULL,
+ G_PARAM_READABLE));
+ g_object_class_install_property (object_class,
+ PROP_WITHOUT_RESOURCE,
+ g_param_spec_string ("without-resource",
+ "JID without the resource",
+ "JID without the resource",
+ NULL,
+ G_PARAM_READABLE));
+ g_object_class_install_property (object_class,
+ PROP_RESOURCE,
+ g_param_spec_string ("resource",
+ "Resource",
+ "Resource",
+ NULL,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (object_class, sizeof (GossipJIDPriv));
}
-const gchar *
+static void
+gossip_jid_init (GossipJID *jid)
+{
+}
+
+static void
+gossip_jid_finalize (GObject *object)
+{
+ GossipJIDPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ g_free (priv->full);
+ g_free (priv->no_resource);
+
+ (G_OBJECT_CLASS (gossip_jid_parent_class)->finalize) (object);
+}
+
+static void
+jid_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GossipJIDPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_FULL:
+ g_value_set_string (value, priv->full);
+ break;
+ case PROP_WITHOUT_RESOURCE:
+ g_value_set_string (value, priv->no_resource);
+ break;
+ case PROP_RESOURCE:
+ g_value_set_string (value, priv->resource);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static const gchar *
jid_locate_resource (const gchar *str)
{
gchar *ch;
@@ -83,91 +170,116 @@
}
GossipJID *
-gossip_jid_new (const gchar *str_jid)
+gossip_jid_new (const gchar *id)
{
- GossipJID *jid;
+ GossipJID *jid;
+ GossipJIDPriv *priv;
- g_return_val_if_fail (str_jid != NULL, NULL);
+ g_return_val_if_fail (id != NULL, NULL);
- jid = g_slice_new0 (GossipJID);
+ jid = g_object_new (GOSSIP_TYPE_JID, NULL);
+
+ priv = GET_PRIV (jid);
- jid->ref_count = 1;
- jid->full = jid_casefold_node (str_jid);
+ priv->full = jid_casefold_node (id);
+ priv->resource = jid_locate_resource (priv->full);
- jid->resource = jid_locate_resource (jid->full);
- if (jid->resource) {
- jid->no_resource = g_strndup (jid->full, jid->resource - 1 - jid->full);
+ if (priv->resource) {
+ priv->no_resource = g_strndup (priv->full,
+ priv->resource - 1 - priv->full);
} else {
- jid->no_resource = g_strdup (jid->full);
+ priv->no_resource = g_strdup (priv->full);
}
return jid;
}
void
-gossip_jid_set_without_resource (GossipJID *jid, const gchar *str)
+gossip_jid_set_without_resource (GossipJID *jid,
+ const gchar *str)
{
- gchar *resource = NULL;
+ GossipJIDPriv *priv;
+ gchar *resource = NULL;
+
+ g_return_if_fail (GOSSIP_IS_JID (jid));
- g_return_if_fail (jid != NULL);
+ priv = GET_PRIV (jid);
- if (jid->resource) {
- resource = g_strdup (jid->resource);
+ if (priv->resource) {
+ resource = g_strdup (priv->resource);
}
- g_free (jid->full);
- g_free (jid->no_resource);
+ g_free (priv->full);
+ g_free (priv->no_resource);
- jid->no_resource = jid_casefold_node (str);
+ priv->no_resource = jid_casefold_node (str);
if (resource) {
- jid->full = g_strdup_printf ("%s/%s",
- jid->no_resource, resource);
+ priv->full = g_strdup_printf ("%s/%s",
+ priv->no_resource,
+ resource);
g_free (resource);
- jid->resource = jid_locate_resource (jid->full);
+ priv->resource = jid_locate_resource (priv->full);
} else {
- jid->full = g_strdup (jid->no_resource);
+ priv->full = g_strdup (priv->no_resource);
}
}
void
-gossip_jid_set_resource (GossipJID *jid, const gchar *resource)
+gossip_jid_set_resource (GossipJID *jid,
+ const gchar *resource)
{
- g_return_if_fail (jid != NULL);
+ GossipJIDPriv *priv;
- g_free (jid->full);
+ g_return_if_fail (GOSSIP_IS_JID (jid));
- jid->full = g_strdup_printf ("%s/%s", jid->no_resource, resource);
- jid->resource = jid_locate_resource (jid->full);
+ priv = GET_PRIV (jid);
+
+ g_free (priv->full);
+
+ priv->full = g_strdup_printf ("%s/%s", priv->no_resource, resource);
+ priv->resource = jid_locate_resource (priv->full);
}
const gchar *
gossip_jid_get_full (GossipJID *jid)
{
- g_return_val_if_fail (jid != NULL, "");
+ GossipJIDPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_JID (jid), "");
- return jid->full;
+ priv = GET_PRIV (jid);
+
+ return priv->full;
}
const gchar *
gossip_jid_get_without_resource (GossipJID *jid)
{
- g_return_val_if_fail (jid != NULL, "");
+ GossipJIDPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_JID (jid), "");
+
+ priv = GET_PRIV (jid);
- if (jid->no_resource) {
- return jid->no_resource;
+ if (priv->no_resource) {
+ return priv->no_resource;
}
- return jid->full;
+ return priv->full;
}
const gchar *
gossip_jid_get_resource (GossipJID *jid)
{
- g_return_val_if_fail (jid != NULL, NULL);
+ GossipJIDPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_JID (jid), NULL);
+
+ priv = GET_PRIV (jid);
- if (jid->resource) {
- return jid->resource;
+ if (priv->resource) {
+ return priv->resource;
}
return NULL;
@@ -176,15 +288,19 @@
gboolean
gossip_jid_is_service (GossipJID *jid)
{
- gchar *ch;
+ GossipJIDPriv *priv;
+ gchar *ch;
+
+ g_return_val_if_fail (GOSSIP_IS_JID (jid), FALSE);
- /* this basically checks to see if there is an '@'
- sign in the jid, if not, we assume it is a component
- or service (for example msn.jabber.org.uk) */
+ /* This basically checks to see if there is an '@' sign in the
+ * jid, if not, we assume it is a component or service (for
+ * example msn.jabber.org.uk).
+ */
- g_return_val_if_fail (jid != NULL, FALSE);
+ priv = GET_PRIV (jid);
- ch = strchr (jid->full, '@');
+ ch = strchr (priv->full, '@');
if (!ch) {
return TRUE;
} else {
@@ -195,13 +311,16 @@
gchar *
gossip_jid_get_part_name (GossipJID *jid)
{
- gchar *ch;
+ GossipJIDPriv *priv;
+ gchar *ch;
+
+ g_return_val_if_fail (GOSSIP_IS_JID (jid), g_strdup (""));
- g_return_val_if_fail (jid != NULL, g_strdup (""));
+ priv = GET_PRIV (jid);
- for (ch = jid->full; *ch; ++ch) {
+ for (ch = priv->full; *ch; ++ch) {
if (*ch == '@') {
- return g_strndup (jid->full, ch - jid->full);
+ return g_strndup (priv->full, ch - priv->full);
}
}
@@ -213,7 +332,7 @@
{
const gchar *ch;
- g_return_val_if_fail (jid != NULL, "");
+ g_return_val_if_fail (GOSSIP_IS_JID (jid), g_strdup (""));
for (ch = gossip_jid_get_without_resource (jid); *ch; ++ch) {
if (*ch == '@') {
@@ -224,39 +343,25 @@
return "";
}
-GossipJID *
-gossip_jid_ref (GossipJID *jid)
-{
- g_return_val_if_fail (jid != NULL, NULL);
-
- jid->ref_count++;
-
- return jid;
-}
-
-void
-gossip_jid_unref (GossipJID *jid)
-{
- g_return_if_fail (jid != NULL);
-
- jid->ref_count--;
- if (jid->ref_count <= 0) {
- jid_free (jid);
- }
-}
-
gboolean
gossip_jid_equals (GossipJID *jid_a,
GossipJID *jid_b)
{
- g_return_val_if_fail (jid_a != NULL, FALSE);
- g_return_val_if_fail (jid_b != NULL, FALSE);
+ GossipJIDPriv *priv_a;
+ GossipJIDPriv *priv_b;
+
+ g_return_val_if_fail (GOSSIP_IS_JID (jid_a), FALSE);
+ g_return_val_if_fail (GOSSIP_IS_JID (jid_b), FALSE);
/* NOTE: This is not strictly correct, since the node and resource are
* UTF8, and the domain have other rules. The node is also already
* casefolded.
*/
- if (g_ascii_strcasecmp (jid_a->full, jid_b->full) == 0) {
+
+ priv_a = GET_PRIV (jid_a);
+ priv_b = GET_PRIV (jid_b);
+
+ if (g_ascii_strcasecmp (priv_a->full, priv_b->full) == 0) {
return TRUE;
}
@@ -269,8 +374,8 @@
{
const gchar *a, *b;
- g_return_val_if_fail (jid_a != NULL, FALSE);
- g_return_val_if_fail (jid_b != NULL, FALSE);
+ g_return_val_if_fail (GOSSIP_IS_JID (jid_a), FALSE);
+ g_return_val_if_fail (GOSSIP_IS_JID (jid_b), FALSE);
a = gossip_jid_get_without_resource (jid_a);
b = gossip_jid_get_without_resource (jid_b);
@@ -413,8 +518,8 @@
g_return_val_if_fail (v1 != NULL, FALSE);
g_return_val_if_fail (v2 != NULL, FALSE);
- a = gossip_jid_get_without_resource ((GossipJID *) v1);
- b = gossip_jid_get_without_resource ((GossipJID *) v2);
+ a = gossip_jid_get_full (GOSSIP_JID (v1));
+ b = gossip_jid_get_full (GOSSIP_JID (v2));
/* NOTE: This is not strictly correct, since the node and resource are
* UTF8, and the domain have other rules. The node is also already
@@ -426,7 +531,45 @@
guint
gossip_jid_hash (gconstpointer key)
{
- GossipJID *jid = (GossipJID *) key;
+ GossipJID *jid;
+ gchar *lower;
+ guint ret_val;
+
+ /* NOTE: This is not strictly correct, since the node and resource are
+ * UTF8, and the domain have other rules. The node is also already
+ * casefolded.
+ */
+ jid = GOSSIP_JID (key);
+ lower = g_ascii_strdown (gossip_jid_get_full (jid), -1);
+ ret_val = g_str_hash (lower);
+ g_free (lower);
+
+ return ret_val;
+}
+
+gboolean
+gossip_jid_equal_without_resource (gconstpointer v1,
+ gconstpointer v2)
+{
+ const gchar *a, *b;
+
+ g_return_val_if_fail (v1 != NULL, FALSE);
+ g_return_val_if_fail (v2 != NULL, FALSE);
+
+ a = gossip_jid_get_without_resource (GOSSIP_JID (v1));
+ b = gossip_jid_get_without_resource (GOSSIP_JID (v2));
+
+ /* NOTE: This is not strictly correct, since the node and resource are
+ * UTF8, and the domain have other rules. The node is also already
+ * casefolded.
+ */
+ return g_ascii_strcasecmp (a, b) == 0;
+}
+
+guint
+gossip_jid_hash_without_resource (gconstpointer key)
+{
+ GossipJID *jid;
gchar *lower;
guint ret_val;
@@ -434,6 +577,7 @@
* UTF8, and the domain have other rules. The node is also already
* casefolded.
*/
+ jid = GOSSIP_JID (key);
lower = g_ascii_strdown (gossip_jid_get_without_resource (jid), -1);
ret_val = g_str_hash (lower);
g_free (lower);
Modified: trunk/libgossip/gossip-jid.h
==============================================================================
--- trunk/libgossip/gossip-jid.h (original)
+++ trunk/libgossip/gossip-jid.h Sat Jul 5 12:58:07 2008
@@ -21,16 +21,31 @@
#ifndef __GOSSIP_JID_H__
#define __GOSSIP_JID_H__
-#include <glib.h>
+#include <glib-object.h>
G_BEGIN_DECLS
-typedef struct GossipJID GossipJID;
+#define GOSSIP_TYPE_JID (gossip_jid_get_type ())
+#define GOSSIP_JID(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_JID, GossipJID))
+#define GOSSIP_JID_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOSSIP_TYPE_JID, GossipJIDClass))
+#define GOSSIP_IS_JID(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOSSIP_TYPE_JID))
+#define GOSSIP_IS_JID_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOSSIP_TYPE_JID))
+#define GOSSIP_JID_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOSSIP_TYPE_JID, GossipJIDClass))
+
+typedef struct _GossipJID GossipJID;
+typedef struct _GossipJIDClass GossipJIDClass;
+
+struct _GossipJID {
+ GObject parent;
+};
+
+struct _GossipJIDClass {
+ GObjectClass parent_class;
+};
-GossipJID * gossip_jid_new (const gchar *str_jid);
-GossipJID * gossip_jid_ref (GossipJID *jid);
-void gossip_jid_unref (GossipJID *jid);
+GType gossip_jid_get_type (void) G_GNUC_CONST;
+GossipJID * gossip_jid_new (const gchar *str_jid);
void gossip_jid_set_without_resource (GossipJID *jid,
const gchar *str);
void gossip_jid_set_resource (GossipJID *jid,
@@ -63,6 +78,10 @@
gconstpointer v2);
guint gossip_jid_hash (gconstpointer key);
+gboolean gossip_jid_equal_without_resource (gconstpointer v1,
+ gconstpointer v2);
+guint gossip_jid_hash_without_resource (gconstpointer key);
+
const gchar *gossip_jid_get_example_string (void);
G_END_DECLS
Modified: trunk/libgossip/gossip-log.c
==============================================================================
--- trunk/libgossip/gossip-log.c (original)
+++ trunk/libgossip/gossip-log.c Sat Jul 5 12:58:07 2008
@@ -925,7 +925,6 @@
GossipLogManagerPriv *priv;
GossipChatroomManager *chatroom_manager;
GossipChatroom *chatroom;
- GList *found;
gchar *server;
gchar *room;
@@ -943,22 +942,11 @@
server++;
chatroom_manager = gossip_session_get_chatroom_manager (priv->session);
- found = gossip_chatroom_manager_find_extended (chatroom_manager, account, server, room);
-
- if (!found) {
- chatroom = g_object_new (GOSSIP_TYPE_CHATROOM,
- "account", account,
- "name", room,
- "server", server,
- "room", room,
- NULL);
- } else {
- /* FIXME: What do we do if there are more than
- * 1 chatrooms found.
- */
- chatroom = found->data;
- }
-
+ chatroom = gossip_chatroom_manager_find_or_create (chatroom_manager,
+ account,
+ server,
+ room,
+ NULL);
g_free (room);
return chatroom;
@@ -2442,10 +2430,6 @@
account,
contact_id);
if (!contact) {
- /* FIXME: What do we do here, do we
- * create a new contact explicitly for
- * this log entry?
- */
g_warning ("No contact for '%s' (escaping contact id to '%s'), ignoring",
filename, contact_id);
g_free (contact_id);
@@ -2630,160 +2614,3 @@
return hit->url;
}
-
-#if 0
-/* Function to convert links into new file format */
-GList *
-log_links_convert_old_to_new (GossipLogManager *manager)
-{
- GossipLogManagerPriv *priv;
- GossipContactManager *contact_manager;
- GList *files;
- GList *l;
- const gchar *filename;
- gchar *text_casefold = NULL;
- gchar *contents;
- gchar *contents_casefold;
- GList *hits = NULL;
-
- g_return_val_if_fail (GOSSIP_IS_LOG_MANAGER (manager), NULL);
-
- priv = GET_PRIV (manager);
-
- if (!G_STR_EMPTY (text)) {
- text_casefold = g_utf8_casefold (text, -1);
- }
-
- if (log_get_all_log_files (&files)) {
- gossip_debug (DEBUG_DOMAIN, "Found %d log files in total", g_list_length (files));
- } else {
- gossip_debug (DEBUG_DOMAIN, "Failed to retrieve all log files");
- }
-
- /* Do this here instead of for each file */
- contact_manager = gossip_session_get_contact_manager (priv->session);
-
- for (l = files; l; l = l->next) {
- GMappedFile *file;
- GArray *start, *end;
- gsize length;
- gint num_matches;
- gint i;
-
- filename = l->data;
-
- /* FIXME: Handle chatrooms */
- if (strstr (filename, LOG_DIR_CHATROOMS)) {
- gossip_debug (DEBUG_DOMAIN, "Ignoring chatroom filename:'%s'", filename);
- continue;
- }
-
- file = g_mapped_file_new (filename, FALSE, NULL);
- if (!file) {
- continue;
- }
-
- length = g_mapped_file_get_length (file);
- contents = g_mapped_file_get_contents (file);
-
- contents_casefold = g_utf8_casefold (contents, length);
-
- g_mapped_file_free (file);
-
- /* Use Regex to find links */
- start = g_array_new (FALSE, FALSE, sizeof (gint));
- end = g_array_new (FALSE, FALSE, sizeof (gint));
-
- num_matches = gossip_regex_match (GOSSIP_REGEX_BROWSER,
- contents_casefold,
- start, end);
-
- for (i = 0; i < num_matches; i++) {
- gchar *link;
- gint s = 0;
- gint e = 0;
- gboolean add_link = TRUE;
-
- s = g_array_index (start, gint, i);
- e = g_array_index (end, gint, i);
-
- link = gossip_substring (contents_casefold, s, e);
- if (G_STR_EMPTY (link) ||
- (!G_STR_EMPTY (text_casefold) &&
- !strstr (contents_casefold, text_casefold))) {
- add_link = FALSE;
- }
-
- if (add_link) {
- GossipLogSearchHit *hit;
- GossipAccount *account;
- GossipContact *contact;
- gchar *contact_id;
- gint len;
-
- /* FIX a nasty issue where we get the
- * </message> in part in the URL from
- * the log file format.
- */
- len = strlen (link);
- if (link[len - 1] == '<') {
- link[len - 1] = '\0';
- }
-
- account = log_get_account_from_filename (manager, filename);
- if (!account) {
- /* We must have other directories in
- * here which are not account
- * directories, so we just ignore them.
- */
- g_free (link);
- continue;
- }
-
- contact_id = log_get_contact_id_from_filename (filename);
- contact = gossip_contact_manager_find (contact_manager,
- account,
- contact_id);
- g_free (contact_id);
-
- if (!contact) {
- g_free (link);
- continue;
- }
-
- /* FIXME: Add function call here to remember link
- *
- */
-
- hit = g_new0 (GossipLogSearchHit, 1);
-
- hit->date = log_get_date_from_filename (filename);
- hit->filename = g_strdup (filename);
- hit->account = g_object_ref (account);
- hit->contact = g_object_ref (contact);
- hit->link = link;
-
- gossip_debug (DEBUG_DOMAIN,
- "Found link:'%s' in file:'%s' on date:'%s'...",
- link, hit->filename, hit->date);
- continue;
- }
-
- g_free (link);
- }
-
- g_array_free (start, TRUE);
- g_array_free (end, TRUE);
-
- g_free (contents_casefold);
- }
-
- g_list_foreach (files, (GFunc) g_free, NULL);
- g_list_free (files);
-
- g_free (text_casefold);
-
- return hits;
-}
-
-#endif
Modified: trunk/libgossip/gossip-private.h
==============================================================================
--- trunk/libgossip/gossip-private.h (original)
+++ trunk/libgossip/gossip-private.h Sat Jul 5 12:58:07 2008
@@ -31,7 +31,8 @@
#include "gossip-chatroom-manager.h"
#include "gossip-account-manager.h"
-GossipChatroomManager *gossip_chatroom_manager_new (GossipAccountManager *manager,
+GossipChatroomManager *gossip_chatroom_manager_new (GossipAccountManager *account_manager,
+ GossipContactManager *contact_manager,
const gchar *filename);
GossipContactManager * gossip_contact_manager_new (GossipSession *session,
const gchar *filename);
Modified: trunk/libgossip/gossip-session.c
==============================================================================
--- trunk/libgossip/gossip-session.c (original)
+++ trunk/libgossip/gossip-session.c Sat Jul 5 12:58:07 2008
@@ -655,34 +655,10 @@
static GossipJabber *
session_get_protocol (GossipSession *session, GossipContact *contact)
{
- GossipSessionPriv *priv;
- GList *l;
- const gchar *id;
-
g_return_val_if_fail (GOSSIP_IS_SESSION (session), NULL);
g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
- priv = GET_PRIV (session);
-
- id = gossip_contact_get_id (contact);
-
- for (l = priv->protocols; l; l = l->next) {
- GossipJabber *jabber;
- GossipContact *this_contact;
-
- jabber = l->data;
-
- this_contact = gossip_jabber_find_contact (jabber, id);
- if (!this_contact) {
- continue;
- }
-
- if (gossip_contact_equal (this_contact, contact)) {
- return jabber;
- }
- }
-
- return NULL;
+ return gossip_session_get_protocol (session, gossip_contact_get_account (contact));
}
GossipSession *
@@ -727,6 +703,7 @@
/* Set up chatroom manager */
priv->chatroom_manager = gossip_chatroom_manager_new (priv->account_manager,
+ priv->contact_manager,
chatrooms_file);
/* Set up log manager */
@@ -926,7 +903,7 @@
priv = GET_PRIV (session);
- jabber = g_object_new (GOSSIP_TYPE_JABBER, NULL);
+ jabber = gossip_jabber_new (session);
account = gossip_jabber_new_account ();
priv->protocols = g_list_append (priv->protocols,
@@ -963,7 +940,7 @@
return TRUE;
}
- jabber = g_object_new (GOSSIP_TYPE_JABBER, NULL);
+ jabber = gossip_jabber_new (session);
priv->protocols = g_list_append (priv->protocols,
g_object_ref (jabber));
@@ -1011,40 +988,6 @@
}
static void
-session_find_account_foreach_cb (GossipAccount *account,
- GossipJabber *jabber,
- FindAccount *fa)
-{
- const gchar *id;
-
- id = gossip_contact_get_id (fa->contact);
- if (gossip_jabber_find_contact (jabber, id)) {
- fa->account = g_object_ref (account);
- }
-}
-
-GossipAccount *
-gossip_session_find_account (GossipSession *session, GossipContact *contact)
-{
- GossipSessionPriv *priv;
- FindAccount fa;
-
- g_return_val_if_fail (GOSSIP_IS_SESSION (session), NULL);
- g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
-
- priv = GET_PRIV (session);
-
- fa.contact = contact;
- fa.account = NULL;
-
- g_hash_table_foreach (priv->accounts,
- (GHFunc) session_find_account_foreach_cb,
- &fa);
-
- return fa.account;
-}
-
-static void
session_find_account_for_own_contact_foreach_cb (GossipAccount *account,
GossipJabber *jabber,
FindAccount *fa)
@@ -1470,33 +1413,6 @@
return GOSSIP_FT_PROVIDER (jabber);
}
-GossipContact *
-gossip_session_find_contact (GossipSession *session,
- const gchar *id)
-{
- GossipSessionPriv *priv;
- GList *l;
-
- g_return_val_if_fail (GOSSIP_IS_SESSION (session), NULL);
- g_return_val_if_fail (id != NULL, NULL);
-
- priv = GET_PRIV (session);
-
- for (l = priv->protocols; l; l = l->next) {
- GossipJabber *jabber;
- GossipContact *contact;
-
- jabber = l->data;
-
- contact = gossip_jabber_find_contact (jabber, id);
- if (contact) {
- return contact;
- }
- }
-
- return NULL;
-}
-
void
gossip_session_add_contact (GossipSession *session,
GossipAccount *account,
@@ -1954,18 +1870,17 @@
jabber = session_get_protocol (session, contact);
if (!jabber) {
- /* Temporary contact. Use account */
- GossipAccount *account;
- GossipSessionPriv *priv = GET_PRIV (session);
+ GossipSessionPriv *priv;
+ GossipAccount *account;
- account = gossip_session_find_account (session, contact);
+ priv = GET_PRIV (session);
+
+ /* Temporary contact. Use account */
+ account = gossip_contact_get_account (contact);
g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), FALSE);
jabber = g_hash_table_lookup (priv->accounts, account);
- g_object_unref (account);
-
g_return_val_if_fail (jabber, FALSE);
-
}
return gossip_jabber_get_version (jabber, contact,
@@ -1993,7 +1908,7 @@
chatroom = l->data;
- if (!gossip_chatroom_get_favourite (chatroom)) {
+ if (!gossip_chatroom_get_favorite (chatroom)) {
continue;
}
Modified: trunk/libgossip/gossip-session.h
==============================================================================
--- trunk/libgossip/gossip-session.h (original)
+++ trunk/libgossip/gossip-session.h Sat Jul 5 12:58:07 2008
@@ -97,8 +97,6 @@
GossipAccount *account);
gboolean gossip_session_remove_account (GossipSession *session,
GossipAccount *account);
-GossipAccount * gossip_session_find_account (GossipSession *session,
- GossipContact *contact);
GossipAccount * gossip_session_find_account_for_own_contact
(GossipSession *session,
GossipContact *own_contact);
@@ -133,8 +131,6 @@
gsize *max_size,
gchar **format);
/* Contact management */
-GossipContact * gossip_session_find_contact (GossipSession *session,
- const gchar *str);
void gossip_session_add_contact (GossipSession *session,
GossipAccount *account,
const gchar *id,
Modified: trunk/src/gossip-app.c
==============================================================================
--- trunk/src/gossip-app.c (original)
+++ trunk/src/gossip-app.c Sat Jul 5 12:58:07 2008
@@ -1201,7 +1201,7 @@
account = gossip_chatroom_get_account (chatroom);
menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
- visible = gossip_chatroom_get_favourite (chatroom);
+ visible = gossip_chatroom_get_favorite (chatroom);
visible &= gossip_session_is_connected (priv->session, account);
if (visible) {
@@ -1237,7 +1237,7 @@
account = gossip_chatroom_get_account (chatroom);
menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
- visible = gossip_chatroom_get_favourite (chatroom);
+ visible = gossip_chatroom_get_favorite (chatroom);
visible &= gossip_session_is_connected (priv->session, account);
if (menu_item) {
@@ -1314,7 +1314,7 @@
account = gossip_chatroom_get_account (chatroom);
menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
- visible = gossip_chatroom_get_favourite (chatroom);
+ visible = gossip_chatroom_get_favorite (chatroom);
visible &= gossip_session_is_connected (priv->session, account);
g_signal_handlers_disconnect_by_func (chatroom,
@@ -1363,7 +1363,7 @@
gtk_widget_set_sensitive (priv->room_join_favorites, found);
- g_signal_connect (priv->chatroom_manager, "chatroom-favourite-update",
+ g_signal_connect (priv->chatroom_manager, "chatroom-favorite-update",
G_CALLBACK (app_favorite_chatroom_menu_update_cb),
NULL);
g_signal_connect (priv->chatroom_manager, "chatroom-added",
Modified: trunk/src/gossip-chat-view.c
==============================================================================
--- trunk/src/gossip-chat-view.c (original)
+++ trunk/src/gossip-chat-view.c Sat Jul 5 12:58:07 2008
@@ -712,7 +712,7 @@
gtk_widget_set_sensitive (button, FALSE);
gtk_widget_set_sensitive (other_button, FALSE);
- contact = gossip_chatroom_invite_get_invitor (invite);
+ contact = gossip_chatroom_invite_get_inviter (invite);
reason = gossip_chatroom_invite_get_reason (invite);
session = gossip_app_get_session ();
@@ -744,7 +744,7 @@
gtk_widget_set_sensitive (button, FALSE);
gtk_widget_set_sensitive (other_button, FALSE);
- contact = gossip_chatroom_invite_get_invitor (invite);
+ contact = gossip_chatroom_invite_get_inviter (invite);
session = gossip_app_get_session ();
account = gossip_contact_get_account (contact);
@@ -896,18 +896,17 @@
GossipMessage *message)
{
GossipChatViewPriv *priv;
- GossipContact *sender;
+ GossipContact *inviter;
GossipChatroomInvite *invite;
- const gchar *body;
GtkTextChildAnchor *anchor;
GtkTextIter iter;
GtkWidget *button_accept;
GtkWidget *button_decline;
- const gchar *id;
+ const gchar *id_str;
const gchar *reason;
gboolean bottom;
const gchar *tag;
- GString *s;
+ gchar *str;
g_return_if_fail (GOSSIP_IS_CHAT_VIEW (view));
@@ -917,50 +916,41 @@
bottom = chat_view_is_scrolled_down (view);
- sender = gossip_message_get_sender (message);
invite = gossip_message_get_invite (message);
- body = gossip_message_get_body (message);
+ inviter = gossip_chatroom_invite_get_inviter (invite);
+ id_str = gossip_chatroom_invite_get_id (invite);
- gossip_theme_append_timestamp (priv->theme, priv->theme_context,
+ gossip_theme_append_timestamp (priv->theme,
+ priv->theme_context,
view, message, TRUE, TRUE);
+
+ str = g_strdup_printf (_("You have been invited to join a chat "
+ "conference with '%s' in the room '%s'"),
+ gossip_contact_get_name (inviter),
+ id_str);
+
+ gossip_theme_append_text (priv->theme,
+ priv->theme_context,
+ view,
+ str,
+ tag,
+ NULL);
+ g_free (str);
reason = gossip_chatroom_invite_get_reason (invite);
- s = g_string_new ("");
- if (!G_STR_EMPTY (body)) {
- s = g_string_append (s, body);
- }
-
- /* Make sure the reason is not the body (or in the body) */
- if (!G_STR_EMPTY (reason) && !strstr (body, reason)) {
- if (s->len > 0) {
- s = g_string_append_c (s, '\n');
- }
-
- s = g_string_append (s, reason);
- }
-
- if (s->len < 1) {
- s = g_string_append
- (s, _("You have been invited to join a chat conference."));
- }
-
- /* Don't include the invite in the chat window if it is part of the
- * actual request - some chat clients send this and it looks weird
- * repeated.
- */
- id = gossip_chatroom_invite_get_id (invite);
+ if (!G_STR_EMPTY (reason)) {
+ str = g_strconcat ("\n", _("Reason: "), reason, NULL);
- if (!strstr (s->str, id)) {
- g_string_append_printf (s, "\n(%s)\n", id);
+ gossip_theme_append_text (priv->theme,
+ priv->theme_context,
+ view,
+ str,
+ tag,
+ NULL);
+ g_free (str);
}
- s = g_string_prepend_c (s, '\n');
-
- gossip_theme_append_text (priv->theme, priv->theme_context,
- view, s->str, tag, NULL);
- g_string_free (s, TRUE);
-
gtk_text_buffer_get_end_iter (priv->buffer, &iter);
anchor = gtk_text_buffer_create_child_anchor (priv->buffer, &iter);
Modified: trunk/src/gossip-chat-window.c
==============================================================================
--- trunk/src/gossip-chat-window.c (original)
+++ trunk/src/gossip-chat-window.c Sat Jul 5 12:58:07 2008
@@ -854,7 +854,7 @@
gtk_widget_hide (priv->menu_conv_info);
gtk_widget_hide (priv->menu_conv_separator);
- /* Can we add this room to our favourites and are we
+ /* Can we add this room to our favorites and are we
* connected to the room?
*/
manager = gossip_app_get_chatroom_manager ();
@@ -1209,7 +1209,7 @@
group_chat = GOSSIP_GROUP_CHAT (priv->current_chat);
chatroom = gossip_group_chat_get_chatroom (group_chat);
- gossip_chatroom_set_favourite (chatroom, TRUE);
+ gossip_chatroom_set_favorite (chatroom, TRUE);
manager = gossip_app_get_chatroom_manager ();
gossip_chatroom_manager_add (manager, chatroom);
@@ -1817,11 +1817,12 @@
GossipChatWindow *window)
{
if (info == DND_DRAG_TYPE_CONTACT_ID) {
- GossipChatManager *manager;
- GossipContact *contact;
- GossipChat *chat;
- GossipChatWindow *old_window;
- const gchar *id = NULL;
+ GossipChatManager *manager;
+ GossipContactManager *contact_manager;
+ GossipContact *contact;
+ GossipChat *chat;
+ GossipChatWindow *old_window;
+ const gchar *id = NULL;
if (selection) {
id = (const gchar*) selection->data;
@@ -1829,7 +1830,9 @@
gossip_debug (DEBUG_DOMAIN, "DND contact from roster with id:'%s'", id);
- contact = gossip_session_find_contact (gossip_app_get_session (), id);
+ contact_manager = gossip_session_get_contact_manager (gossip_app_get_session ());
+ contact = gossip_contact_manager_find (contact_manager, NULL, id);
+
if (!contact) {
gossip_debug (DEBUG_DOMAIN, "DND contact from roster not found");
return;
Modified: trunk/src/gossip-chatrooms-window.c
==============================================================================
--- trunk/src/gossip-chatrooms-window.c (original)
+++ trunk/src/gossip-chatrooms-window.c Sat Jul 5 12:58:07 2008
@@ -273,26 +273,14 @@
static void
chatrooms_window_model_action_selected (GossipChatroomsWindow *window)
{
- GossipSession *session;
- GossipAccount *account;
- GossipAccountChooser *account_chooser;
- GossipChatroomProvider *provider;
- GossipChatroom *chatroom;
- GossipChatroomStatus status;
- GtkTreeView *view;
- GtkTreeModel *model;
+ GossipSession *session;
+ GossipChatroom *chatroom;
+ GossipChatroomStatus status;
+ GtkTreeView *view;
+ GtkTreeModel *model;
session = gossip_app_get_session ();
- account_chooser = GOSSIP_ACCOUNT_CHOOSER (window->account_chooser);
- account = gossip_account_chooser_get_account (account_chooser);
-
- provider = gossip_session_get_chatroom_provider (session, account);
-
- if (account) {
- g_object_unref (account);
- }
-
view = GTK_TREE_VIEW (window->treeview);
model = gtk_tree_view_get_model (view);
@@ -385,6 +373,11 @@
const gchar *password_protected = NULL;
const gchar *auto_connect = NULL;
+ /* We only show favorites here, not EVERY chatroom */
+ if (!gossip_chatroom_get_favorite (chatroom)) {
+ return;
+ }
+
view = GTK_TREE_VIEW (window->treeview);
selection = gtk_tree_view_get_selection (view);
model = gtk_tree_view_get_model (view);
@@ -557,7 +550,7 @@
/* Remove from config */
manager = gossip_app_get_chatroom_manager ();
- gossip_chatroom_manager_remove (manager, chatroom);
+ gossip_chatroom_set_favorite (chatroom, FALSE);
gossip_chatroom_manager_store (manager);
g_object_unref (chatroom);
Modified: trunk/src/gossip-contact-info-dialog.c
==============================================================================
--- trunk/src/gossip-contact-info-dialog.c (original)
+++ trunk/src/gossip-contact-info-dialog.c Sat Jul 5 12:58:07 2008
@@ -538,7 +538,7 @@
}
session = gossip_app_get_session ();
- account = gossip_session_find_account (session, contact);
+ account = gossip_contact_get_account (contact);
dialog = g_new0 (GossipContactInfoDialog, 1);
Modified: trunk/src/gossip-contact-list.c
==============================================================================
--- trunk/src/gossip-contact-list.c (original)
+++ trunk/src/gossip-contact-list.c Sat Jul 5 12:58:07 2008
@@ -1947,6 +1947,8 @@
g_strfreev (uri_strv);
} else if (info == DND_DRAG_TYPE_CONTACT_ID) {
+ GossipContactManager *contact_manager;
+
priv = GET_PRIV (widget);
id = (const gchar*) selection->data;
@@ -1955,7 +1957,10 @@
context->action == GDK_ACTION_COPY ? "copy" : "",
id);
- contact = gossip_session_find_contact (priv->session, id);
+
+ contact_manager = gossip_session_get_contact_manager (priv->session);
+ contact = gossip_contact_manager_find (contact_manager, NULL, id);
+
if (!contact) {
gossip_debug (DEBUG_DOMAIN, "No contact found associated with drag & drop");
goto out;
@@ -1977,6 +1982,7 @@
}
gossip_contact_set_groups (contact, NULL);
+ drag_success = TRUE;
} else {
GList *l, *new_groups;
gchar *name;
@@ -2146,19 +2152,22 @@
GtkTreePath *path;
GtkTreeIter iter;
- priv = GET_PRIV (widget);
-
- GTK_WIDGET_CLASS (gossip_contact_list_parent_class)->drag_begin (widget,
- context);
-
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
return;
}
+
path = gtk_tree_model_get_path (model, &iter);
+ if (!path) {
+ return;
+ }
+
+ priv = GET_PRIV (widget);
priv->drag_row = gtk_tree_row_reference_new (model, path);
gtk_tree_path_free (path);
+
+ GTK_WIDGET_CLASS (gossip_contact_list_parent_class)->drag_begin (widget, context);
}
static void
Modified: trunk/src/gossip-dbus.c
==============================================================================
--- trunk/src/gossip-dbus.c (original)
+++ trunk/src/gossip-dbus.c Sat Jul 5 12:58:07 2008
@@ -233,7 +233,11 @@
id ? id : "SELF");
if (!G_STR_EMPTY (id)) {
- contact = gossip_session_find_contact (saved_session, id);
+ GossipContactManager *contact_manager;
+
+ contact_manager = gossip_session_get_contact_manager (saved_session);
+ contact = gossip_contact_manager_find (contact_manager, NULL, id);
+
if (!contact) {
gossip_debug (DEBUG_DOMAIN, "Contact:'%s' not recognised", id);
@@ -297,7 +301,11 @@
*name = NULL;
if (!G_STR_EMPTY (id)) {
- contact = gossip_session_find_contact (saved_session, id);
+ GossipContactManager *contact_manager;
+
+ contact_manager = gossip_session_get_contact_manager (saved_session);
+ contact = gossip_contact_manager_find (contact_manager, NULL, id);
+
if (!contact) {
gossip_debug (DEBUG_DOMAIN, "Contact:'%s' not recognised", id);
@@ -369,12 +377,15 @@
const gchar *contact_id,
GError **error)
{
- GossipChatManager *manager;
- GossipContact *contact;
+ GossipChatManager *manager;
+ GossipContactManager *contact_manager;
+ GossipContact *contact;
gossip_debug (DEBUG_DOMAIN, "Sending message to contact:'%s'", contact_id);
- contact = gossip_session_find_contact (saved_session, contact_id);
+ contact_manager = gossip_session_get_contact_manager (saved_session);
+ contact = gossip_contact_manager_find (contact_manager, NULL, contact_id);
+
if (!contact) {
g_set_error (error, gossip_dbus_error_quark (), 0,
"Contact:'%s' not found", contact_id);
Modified: trunk/src/gossip-edit-contact-dialog.c
==============================================================================
--- trunk/src/gossip-edit-contact-dialog.c (original)
+++ trunk/src/gossip-edit-contact-dialog.c Sat Jul 5 12:58:07 2008
@@ -612,7 +612,7 @@
message = _("I would like to add you to my contact list.");
session = gossip_app_get_session ();
- account = gossip_session_find_account (session, dialog->contact);
+ account = gossip_contact_get_account (dialog->contact);
gossip_session_add_contact (session,
account,
Modified: trunk/src/gossip-group-chat.c
==============================================================================
--- trunk/src/gossip-group-chat.c (original)
+++ trunk/src/gossip-group-chat.c Sat Jul 5 12:58:07 2008
@@ -58,8 +58,6 @@
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_GROUP_CHAT, GossipGroupChatPriv))
struct _GossipGroupChatPriv {
- GossipContact *own_contact;
-
GossipChatroomProvider *chatroom_provider;
GossipChatroom *chatroom;
GossipChatroomStatus last_status;
@@ -151,6 +149,11 @@
static void group_chat_kicked_cb (GossipChatroomProvider *provider,
gint id,
GossipGroupChat *chat);
+static void group_chat_nick_changed_cb (GossipChatroomProvider *provider,
+ gint id,
+ GossipContact *contact,
+ const gchar *old_nick,
+ GossipGroupChat *chat);
static void group_chat_new_message_cb (GossipChatroomProvider *provider,
gint id,
GossipMessage *message,
@@ -228,7 +231,7 @@
GossipGroupChat *chat);
static gboolean group_chat_cl_button_press_event_cb (GtkTreeView *view,
GdkEventButton *event,
- GossipGroupChat *chat);
+ GossipGroupChat *chat);
static gint group_chat_cl_sort_func (GtkTreeModel *model,
GtkTreeIter *iter_a,
GtkTreeIter *iter_b,
@@ -262,13 +265,13 @@
static GtkWidget * group_chat_cl_menu_create (GossipGroupChat *chat,
GossipContact *contact);
static void group_chat_cl_menu_destroy (GtkWidget *menu,
- GossipGroupChat *chat);
+ GossipGroupChat *chat);
static void group_chat_cl_menu_info_activate_cb (GtkMenuItem *menuitem,
- GossipGroupChat *chat);
+ GossipGroupChat *chat);
static void group_chat_cl_menu_chat_activate_cb (GtkMenuItem *menuitem,
- GossipGroupChat *chat);
+ GossipGroupChat *chat);
static void group_chat_cl_menu_kick_activate_cb (GtkMenuItem *menuitem,
- GossipGroupChat *chat);
+ GossipGroupChat *chat);
static void group_chat_set_scrolling_for_events (GossipGroupChat *chat,
gboolean disable);
static gboolean group_chat_scroll_down_when_idle_func (GossipGroupChat *chat);
@@ -354,9 +357,12 @@
static void
group_chat_finalize (GObject *object)
{
- GossipGroupChat *chat;
- GossipGroupChatPriv *priv;
- GossipChatroomId id;
+ GossipGroupChat *chat;
+ GossipGroupChatPriv *priv;
+ GossipChatroomId id;
+ GossipChatroomStatus status;
+ GList *l;
+ GList *contacts;
gossip_debug (DEBUG_DOMAIN, "Finalized:%p", object);
@@ -372,6 +378,18 @@
id = gossip_chatroom_get_id (priv->chatroom);
g_hash_table_steal (group_chats, GINT_TO_POINTER (id));
+ contacts = gossip_chatroom_get_contacts (priv->chatroom);
+ for (l = contacts; l; l = l->next) {
+ g_signal_handlers_disconnect_by_func (l->data,
+ group_chat_contact_updated_cb,
+ chat);
+ g_signal_handlers_disconnect_by_func (l->data,
+ group_chat_contact_presence_updated_cb,
+ chat);
+ }
+
+ g_list_free (contacts);
+
g_signal_handlers_disconnect_by_func (priv->chatroom,
group_chat_chatroom_name_cb,
chat);
@@ -382,6 +400,9 @@
group_chat_kicked_cb,
chat);
g_signal_handlers_disconnect_by_func (priv->chatroom_provider,
+ group_chat_nick_changed_cb,
+ chat);
+ g_signal_handlers_disconnect_by_func (priv->chatroom_provider,
group_chat_new_message_cb,
chat);
g_signal_handlers_disconnect_by_func (priv->chatroom_provider,
@@ -407,21 +428,17 @@
* because when we update the status, we get called back and
* the widget is destroyed.
*/
- if (priv->chatroom) {
- GossipChatroomStatus status;
-
- status = gossip_chatroom_get_status (priv->chatroom);
- if (status == GOSSIP_CHATROOM_STATUS_ACTIVE) {
- gossip_chatroom_provider_leave (priv->chatroom_provider,
- gossip_chatroom_get_id (priv->chatroom));
- } else if (status == GOSSIP_CHATROOM_STATUS_JOINING) {
- gossip_chatroom_provider_cancel (priv->chatroom_provider,
- gossip_chatroom_get_id (priv->chatroom));
- }
-
- g_object_unref (priv->chatroom);
+ status = gossip_chatroom_get_status (priv->chatroom);
+ if (status == GOSSIP_CHATROOM_STATUS_ACTIVE) {
+ gossip_chatroom_provider_leave (priv->chatroom_provider,
+ gossip_chatroom_get_id (priv->chatroom));
+ } else if (status == GOSSIP_CHATROOM_STATUS_JOINING) {
+ gossip_chatroom_provider_cancel (priv->chatroom_provider,
+ gossip_chatroom_get_id (priv->chatroom));
}
+ g_object_unref (priv->chatroom);
+
g_object_unref (priv->chatroom_provider);
g_free (priv->subject);
@@ -431,10 +448,6 @@
chat);
g_list_free (priv->private_chats);
- if (priv->own_contact) {
- g_object_unref (priv->own_contact);
- }
-
if (priv->scroll_idle_id) {
g_source_remove (priv->scroll_idle_id);
}
@@ -695,10 +708,13 @@
{
GossipGroupChatPriv *priv;
GossipAccount *this_account;
+ GossipContact *own_contact;
priv = GET_PRIV (chat);
- this_account = gossip_contact_get_account (priv->own_contact);
+ own_contact = gossip_chatroom_get_own_contact (priv->chatroom);
+ this_account = gossip_contact_get_account (own_contact);
+
if (!gossip_account_equal (this_account, account)) {
return;
}
@@ -886,16 +902,19 @@
GossipGroupChat *chat)
{
if (info == DND_DRAG_TYPE_CONTACT_ID) {
- GossipGroupChatPriv *priv;
- GossipContact *contact;
- const gchar *id;
- gchar *str;
+ GossipGroupChatPriv *priv;
+ GossipContactManager *contact_manager;
+ GossipContact *contact;
+ const gchar *id;
+ gchar *str;
priv = GET_PRIV (chat);
id = (const gchar*) selection->data;
- contact = gossip_session_find_contact (gossip_app_get_session (), id);
+ contact_manager = gossip_session_get_contact_manager (gossip_app_get_session ());
+ contact = gossip_contact_manager_find (contact_manager, NULL, id);
+
if (!contact) {
gossip_debug (DEBUG_DOMAIN,
"Drag data received, but no contact found by the id:'%s'",
@@ -1179,6 +1198,8 @@
{
GossipGroupChatPriv *priv;
GossipChatView *chatview;
+ GList *contacts;
+ GList *l;
priv = GET_PRIV (chat);
@@ -1190,6 +1211,17 @@
chatview = GOSSIP_CHAT (chat)->view;
+ contacts = gossip_chatroom_get_contacts (priv->chatroom);
+ for (l = contacts; l; l = l->next) {
+ g_signal_handlers_disconnect_by_func (l->data,
+ group_chat_contact_updated_cb,
+ chat);
+ g_signal_handlers_disconnect_by_func (l->data,
+ group_chat_contact_presence_updated_cb,
+ chat);
+ }
+ g_list_free (contacts);
+
gtk_widget_set_sensitive (priv->hbox_subject, FALSE);
gtk_widget_set_sensitive (priv->scrolled_window_contacts, FALSE);
gtk_widget_set_sensitive (priv->scrolled_window_input, FALSE);
@@ -1202,6 +1234,43 @@
}
static void
+group_chat_nick_changed_cb (GossipChatroomProvider *provider,
+ gint id,
+ GossipContact *contact,
+ const gchar *old_nick,
+ GossipGroupChat *chat)
+{
+ GossipGroupChatPriv *priv;
+ GossipChatView *chatview;
+ gchar *str;
+
+ priv = GET_PRIV (chat);
+
+ if (id != gossip_chatroom_get_id (priv->chatroom)) {
+ return;
+ }
+
+ gossip_debug (DEBUG_DOMAIN,
+ "[%d] Nick changed for contact:'%s', old nick:'%s', new nick:'%s'",
+ id,
+ gossip_contact_get_id (contact),
+ old_nick,
+ gossip_contact_get_name (contact));
+
+ chatview = GOSSIP_CHAT (chat)->view;
+
+ str = g_strdup_printf (_("%s is now known as %s"),
+ old_nick,
+ gossip_contact_get_name (contact));
+
+ group_chat_set_scrolling_for_events (GOSSIP_GROUP_CHAT (chat), TRUE);
+ gossip_chat_view_append_event (chatview, str);
+ group_chat_set_scrolling_for_events (GOSSIP_GROUP_CHAT (chat), FALSE);
+
+ g_free (str);
+}
+
+static void
group_chat_new_message_cb (GossipChatroomProvider *provider,
gint id,
GossipMessage *message,
@@ -1210,6 +1279,7 @@
GossipGroupChatPriv *priv;
GossipChatroomInvite *invite;
GossipContact *sender;
+ GossipContact *own_contact;
GossipLogManager *log_manager;
GossipTime timestamp;
gboolean is_incoming;
@@ -1225,7 +1295,9 @@
is_backlog = timestamp < priv->time_joined;
sender = gossip_message_get_sender (message);
- is_incoming = !gossip_contact_equal (sender, priv->own_contact);
+ own_contact = gossip_chatroom_get_own_contact (priv->chatroom);
+
+ is_incoming = !gossip_contact_equal (sender, own_contact);
gossip_debug (DEBUG_DOMAIN,
"[%d] New message with timestamp:%d, message %s backlog, %s incoming",
@@ -1246,13 +1318,13 @@
gossip_chat_view_append_message_from_other (
GOSSIP_CHAT (chat)->view,
message,
- priv->own_contact,
+ own_contact,
NULL);
} else {
gossip_chat_view_append_message_from_self (
GOSSIP_CHAT (chat)->view,
message,
- priv->own_contact,
+ own_contact,
NULL);
}
}
@@ -1260,7 +1332,7 @@
/* Play sound? */
if (!is_backlog &&
gossip_chat_should_play_sound (GOSSIP_CHAT (chat)) &&
- gossip_chat_should_highlight_nick (message, priv->own_contact)) {
+ gossip_chat_should_highlight_nick (message, own_contact)) {
gossip_sound_play (GOSSIP_SOUND_CHAT);
}
@@ -1316,18 +1388,31 @@
return;
}
- gossip_debug (DEBUG_DOMAIN, "[%d] Subject changed by:'%s' to:'%s'",
- id, gossip_contact_get_id (who), new_subject);
+ if (who) {
+ gossip_debug (DEBUG_DOMAIN,
+ "[%d] Subject changed by:'%s' to:'%s'",
+ id,
+ gossip_contact_get_id (who),
+ new_subject);
+
+ event = g_strdup_printf (_("%s has set the subject: %s"),
+ gossip_contact_get_name (who),
+ new_subject);
+ } else {
+ gossip_debug (DEBUG_DOMAIN,
+ "[%d] Subject set as:'%s'",
+ id,
+ new_subject);
+
+ event = g_strdup_printf (_("Subject is set as: %s"),
+ new_subject);
+ }
g_free (priv->subject);
priv->subject = g_strdup (new_subject);
gtk_label_set_text (GTK_LABEL (priv->label_subject), new_subject);
- event = g_strdup_printf (_("%s has set the subject: %s"),
- gossip_contact_get_name (who),
- new_subject);
-
group_chat_set_scrolling_for_events (chat, TRUE);
gossip_chat_view_append_event (GOSSIP_CHAT (chat)->view, event);
group_chat_set_scrolling_for_events (chat, FALSE);
@@ -1498,9 +1583,11 @@
GtkTreeViewColumn *col,
GossipGroupChat *chat)
{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GossipContact *contact;
+ GossipGroupChatPriv *priv;
+ GossipContact *own_contact;
+ GossipContact *contact;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
if (gtk_tree_path_get_depth (path) == 1) {
/* Do nothing for role groups */
@@ -1515,7 +1602,12 @@
COL_CONTACT, &contact,
-1);
- group_chat_private_chat_new (chat, contact);
+ priv = GET_PRIV (chat);
+ own_contact = gossip_chatroom_get_own_contact (priv->chatroom);
+
+ if (!gossip_contact_equal (own_contact, contact)) {
+ group_chat_private_chat_new (chat, contact);
+ }
g_object_unref (contact);
}
@@ -1886,11 +1978,13 @@
GossipGroupChat *chat)
{
GossipGroupChatPriv *priv;
+ GossipContact *own_contact;
priv = GET_PRIV (chat);
- gossip_debug (DEBUG_DOMAIN, "Contact joined:'%s'",
- gossip_contact_get_id (contact));
+ gossip_debug (DEBUG_DOMAIN, "Contact joined:'%s' (refs:%d)",
+ gossip_contact_get_id (contact),
+ G_OBJECT (contact)->ref_count);
group_chat_contact_add (chat, contact);
@@ -1901,10 +1995,12 @@
G_CALLBACK (group_chat_contact_updated_cb),
chat);
- g_signal_emit_by_name (chat, "contact_added", contact);
+ g_signal_emit_by_name (chat, "contact-added", contact);
/* Add event to chatroom */
- if (!gossip_contact_equal (priv->own_contact, contact)) {
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
+ if (!gossip_contact_equal (own_contact, contact)) {
gchar *str;
str = g_strdup_printf (_("%s has joined the room"),
@@ -1924,11 +2020,13 @@
GossipGroupChat *chat)
{
GossipGroupChatPriv *priv;
+ GossipContact *own_contact;
priv = GET_PRIV (chat);
- gossip_debug (DEBUG_DOMAIN, "Contact left:'%s'",
- gossip_contact_get_id (contact));
+ gossip_debug (DEBUG_DOMAIN, "Contact left:'%s' (refs:%d)",
+ gossip_contact_get_id (contact),
+ G_OBJECT (contact)->ref_count);
g_signal_handlers_disconnect_by_func (contact,
group_chat_contact_updated_cb,
@@ -1942,8 +2040,11 @@
g_signal_emit_by_name (chat, "contact_removed", contact);
/* Add event to chatroom */
- if (!gossip_contact_equal (priv->own_contact, contact)) {
+ own_contact = gossip_chatroom_get_own_contact (chatroom);
+
+ if (!gossip_contact_equal (own_contact, contact)) {
gchar *str;
+
str = g_strdup_printf (_("%s has left the room"),
gossip_contact_get_name (contact));
@@ -1956,9 +2057,9 @@
}
static void
-group_chat_contact_info_changed_cb (GossipChatroom *chatroom,
- GossipContact *contact,
- GossipGroupChat *chat)
+group_chat_contact_info_changed_cb (GossipChatroom *chatroom,
+ GossipContact *contact,
+ GossipGroupChat *chat)
{
group_chat_contact_remove (chat, contact);
group_chat_contact_add (chat, contact);
@@ -2177,14 +2278,13 @@
handled_command = TRUE;
}
else if (g_ascii_strncasecmp (msg, "/kick ", 6) == 0 && strlen (msg) > 6) {
- GSList *contacts, *l;
+ GList *contacts, *l;
GossipContact *contact = NULL;
const gchar *nick;
nick = msg + 6;
- contacts = gossip_chatroom_provider_get_contacts (priv->chatroom_provider,
- gossip_chatroom_get_id (priv->chatroom));
+ contacts = gossip_chatroom_get_contacts (priv->chatroom);
for (l = contacts; l && !contact; l = l->next) {
const gchar *name;
@@ -2202,6 +2302,8 @@
g_free (nick_caseless);
g_free (name_caseless);
}
+
+ g_list_free (contacts);
if (contact) {
gossip_group_chat_contact_kick (chat, contact);
@@ -2386,7 +2488,7 @@
group_chat = GOSSIP_GROUP_CHAT (chat);
priv = GET_PRIV (group_chat);
- return priv->own_contact;
+ return gossip_chatroom_get_own_contact (priv->chatroom);
}
static GossipChatroom *
@@ -2525,38 +2627,12 @@
}
}
-/* Copied from the jabber backend for now since we don't have an abstraction for
- * "contacts" for group chats. Casefolds the node part (the part before @).
- */
-static gchar *
-jid_casefold_node (const gchar *str)
-{
- gchar *tmp;
- gchar *ret;
- const gchar *at;
-
- at = strchr (str, '@');
- if (!at) {
- return g_strdup (str);
- }
-
- tmp = g_utf8_casefold (str, at - str);
- ret = g_strconcat (tmp, at, NULL);
- g_free (tmp);
-
- return ret;
-}
-
GossipGroupChat *
gossip_group_chat_new (GossipChatroomProvider *provider,
GossipChatroom *chatroom)
{
GossipGroupChat *chat;
GossipGroupChatPriv *priv;
- gchar *casefolded_id;
- gchar *own_contact_id;
- GossipContact *own_contact;
- GossipChatroom *chatroom_found;
GossipChatroomId id;
g_return_val_if_fail (GOSSIP_IS_CHATROOM_PROVIDER (provider), NULL);
@@ -2577,37 +2653,11 @@
return chat;
}
- chatroom_found = gossip_chatroom_provider_find (provider, chatroom);
- if (chatroom_found) {
- /* Check this group chat is not shown under another id */
- id = gossip_chatroom_get_id (chatroom_found);
- chat = g_hash_table_lookup (group_chats, GINT_TO_POINTER (id));
- if (chat) {
- gossip_chat_present (GOSSIP_CHAT (chat));
- return chat;
- }
- }
-
- /* FIXME: Jabberism --- Get important details like own contact, etc */
- casefolded_id = jid_casefold_node (gossip_chatroom_get_id_str (chatroom));
- own_contact_id = g_strdup_printf ("%s/%s",
- casefolded_id,
- gossip_chatroom_get_nick (chatroom));
- g_free (casefolded_id);
-
- own_contact = gossip_contact_new_full (GOSSIP_CONTACT_TYPE_TEMPORARY,
- gossip_chatroom_get_account (chatroom),
- own_contact_id,
- gossip_chatroom_get_nick (chatroom));
- g_free (own_contact_id);
-
/* Create new group chat object */
chat = g_object_new (GOSSIP_TYPE_GROUP_CHAT, NULL);
priv = GET_PRIV (chat);
- priv->own_contact = own_contact;
-
priv->chatroom = g_object_ref (chatroom);
priv->chatroom_provider = g_object_ref (provider);
priv->last_status = gossip_chatroom_get_status (chatroom);
@@ -2625,6 +2675,9 @@
g_signal_connect (provider, "chatroom-kicked",
G_CALLBACK (group_chat_kicked_cb),
chat);
+ g_signal_connect (provider, "chatroom-nick-changed",
+ G_CALLBACK (group_chat_nick_changed_cb),
+ chat);
g_signal_connect (provider, "chatroom-new-message",
G_CALLBACK (group_chat_new_message_cb),
chat);
@@ -2711,6 +2764,7 @@
{
GossipGroupChatPriv *priv;
GossipContact *contact;
+ GossipContact *own_contact;
GtkWidget *menu = NULL;
g_return_val_if_fail (GOSSIP_IS_GROUP_CHAT (group_chat), NULL);
@@ -2726,7 +2780,8 @@
return NULL;
}
- if (gossip_contact_equal (contact, priv->own_contact)) {
+ own_contact = gossip_chatroom_get_own_contact (priv->chatroom);
+ if (gossip_contact_equal (contact, own_contact)) {
g_object_unref (contact);
return NULL;
}
Modified: trunk/src/gossip-new-chatroom-dialog.c
==============================================================================
--- trunk/src/gossip-new-chatroom-dialog.c (original)
+++ trunk/src/gossip-new-chatroom-dialog.c Sat Jul 5 12:58:07 2008
@@ -736,13 +736,16 @@
/* New or existing? */
if (new_chatroom) {
- chatroom = g_object_new (GOSSIP_TYPE_CHATROOM,
- "account", account,
- "name", room,
- "server", server,
- "nick", nick,
- "room", room,
- NULL);
+ GossipChatroomManager *chatroom_manager;
+
+ chatroom_manager = gossip_session_get_chatroom_manager (session);
+ chatroom = gossip_chatroom_manager_find_or_create (chatroom_manager,
+ account,
+ server,
+ room,
+ NULL);
+
+ gossip_chatroom_set_nick (chatroom, nick);
if (!G_STR_EMPTY (password)) {
gossip_chatroom_set_password (chatroom, password);
Modified: trunk/src/gossip-theme.c
==============================================================================
--- trunk/src/gossip-theme.c (original)
+++ trunk/src/gossip-theme.c Sat Jul 5 12:58:07 2008
@@ -461,15 +461,15 @@
if (!link_tag) {
gtk_text_buffer_insert (buffer, &iter,
tmp, -1);
- }
-
- gtk_text_buffer_insert_with_tags_by_name (buffer,
- &iter,
- tmp,
- -1,
- link_tag,
- "link",
- NULL);
+ } else {
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ tmp,
+ -1,
+ link_tag,
+ "link",
+ NULL);
+ }
g_free (tmp);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]