1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2004-2007 Imendio AB
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Martyn Russell <martyn@imendio.com>
27 #include <glib/gi18n.h>
29 #include <libgossip/gossip-account.h>
30 #include <libgossip/gossip-event.h>
31 #include <libgossip/gossip-session.h>
32 #include <libgossip/gossip-message.h>
33 #include <libgossip/gossip-debug.h>
34 #include <libgossip/gossip-event-manager.h>
36 #include "gossip-app.h"
37 #include "gossip-chat.h"
38 #include "gossip-chat-manager.h"
40 #define DEBUG_DOMAIN "ChatManager"
42 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CHAT_MANAGER, GossipChatManagerPriv))
44 typedef struct _GossipChatManagerPriv GossipChatManagerPriv;
46 struct _GossipChatManagerPriv {
51 static void chat_manager_finalize (GObject *object);
52 static void chat_manager_new_message_cb (GossipSession *session,
54 GossipChatManager *manager);
55 static void chat_manager_event_activated_cb (GossipEventManager *event_manager,
58 static void chat_manager_get_chats_foreach (GossipContact *contact,
59 GossipPrivateChat *chat,
61 static void chat_manager_chat_removed_cb (GossipChatManager *manager,
63 gboolean is_last_ref);
65 G_DEFINE_TYPE (GossipChatManager, gossip_chat_manager, G_TYPE_OBJECT);
68 gossip_chat_manager_class_init (GossipChatManagerClass *class)
70 GObjectClass *object_class;
72 object_class = G_OBJECT_CLASS (class);
74 object_class->finalize = chat_manager_finalize;
76 g_type_class_add_private (object_class, sizeof (GossipChatManagerPriv));
80 gossip_chat_manager_init (GossipChatManager *manager)
82 GossipChatManagerPriv *priv;
84 priv = GET_PRIV (manager);
86 priv->chats = g_hash_table_new_full (gossip_contact_hash,
88 (GDestroyNotify) g_object_unref,
89 (GDestroyNotify) g_object_unref);
91 priv->events = g_hash_table_new_full (gossip_contact_hash,
93 (GDestroyNotify) g_object_unref,
94 (GDestroyNotify) g_object_unref);
96 /* Connect to signals on GossipSession to listen for new messages */
97 g_signal_connect (gossip_app_get_session (),
99 G_CALLBACK (chat_manager_new_message_cb),
104 chat_manager_finalize (GObject *object)
106 GossipChatManagerPriv *priv;
108 priv = GET_PRIV (object);
110 g_hash_table_destroy (priv->chats);
111 g_hash_table_destroy (priv->events);
113 G_OBJECT_CLASS (gossip_chat_manager_parent_class)->finalize (object);
117 chat_manager_new_message_cb (GossipSession *session,
118 GossipMessage *message,
119 GossipChatManager *manager)
121 GossipChatManagerPriv *priv;
122 GossipPrivateChat *chat;
123 GossipContact *sender;
124 GossipEvent *event = NULL;
125 GossipEvent *old_event;
127 priv = GET_PRIV (manager);
129 sender = gossip_message_get_sender (message);
130 chat = g_hash_table_lookup (priv->chats, sender);
132 old_event = g_hash_table_lookup (priv->events, sender);
134 /* Add event to event manager if one doesn't exist already. */
136 gossip_debug (DEBUG_DOMAIN, "New chat for: %s",
137 gossip_contact_get_id (sender));
138 chat = gossip_chat_manager_get_chat (manager, sender);
141 event = gossip_event_new (GOSSIP_EVENT_NEW_MESSAGE);
144 GossipChatWindow *window;
146 window = gossip_chat_get_window (GOSSIP_CHAT (chat));
148 if (!window && !old_event) {
149 event = gossip_event_new (GOSSIP_EVENT_NEW_MESSAGE);
153 gossip_private_chat_append_message (chat, message);
158 str = g_strdup_printf (_("New message from %s"),
159 gossip_contact_get_name (sender));
166 gossip_event_manager_add (gossip_app_get_event_manager (),
168 chat_manager_event_activated_cb,
171 g_hash_table_insert (priv->events,
172 g_object_ref (sender),
173 g_object_ref (event));
178 chat_manager_event_activated_cb (GossipEventManager *event_manager,
182 GossipMessage *message;
183 GossipContact *contact;
185 message = GOSSIP_MESSAGE (gossip_event_get_data (event));
186 contact = gossip_message_get_sender (message);
188 gossip_chat_manager_show_chat (GOSSIP_CHAT_MANAGER (object), contact);
192 chat_manager_get_chats_foreach (GossipContact *contact,
193 GossipPrivateChat *chat,
196 const gchar *contact_id;
198 contact_id = gossip_contact_get_id (contact);
199 *chats = g_list_prepend (*chats, g_strdup (contact_id));
203 gossip_chat_manager_new (void)
205 return g_object_new (GOSSIP_TYPE_CHAT_MANAGER, NULL);
209 chat_manager_chat_removed_cb (GossipChatManager *manager,
211 gboolean is_last_ref)
213 GossipChatManagerPriv *priv;
214 GossipContact *contact;
220 priv = GET_PRIV (manager);
222 contact = gossip_chat_get_contact (chat);
224 gossip_debug (DEBUG_DOMAIN,
225 "Removing an old chat:'%s'",
226 gossip_contact_get_id (contact));
228 g_hash_table_remove (priv->chats, contact);
232 gossip_chat_manager_get_chat (GossipChatManager *manager,
233 GossipContact *contact)
235 GossipChatManagerPriv *priv;
236 GossipPrivateChat *chat;
238 g_return_val_if_fail (GOSSIP_IS_CHAT_MANAGER (manager), NULL);
239 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
241 priv = GET_PRIV (manager);
243 chat = g_hash_table_lookup (priv->chats, contact);
246 GossipSession *session;
247 GossipAccount *account;
248 GossipContact *own_contact;
250 session = gossip_app_get_session ();
251 account = gossip_contact_get_account (contact);
252 own_contact = gossip_session_get_own_contact (session, account);
254 chat = gossip_private_chat_new (own_contact, contact);
255 g_hash_table_insert (priv->chats,
256 g_object_ref (contact),
258 g_object_add_toggle_ref (G_OBJECT (chat),
259 (GToggleNotify) chat_manager_chat_removed_cb,
262 gossip_debug (DEBUG_DOMAIN,
263 "Creating a new chat:'%s'",
264 gossip_contact_get_id (contact));
271 gossip_chat_manager_get_chats (GossipChatManager *manager)
273 GossipChatManagerPriv *priv;
276 g_return_val_if_fail (GOSSIP_IS_CHAT_MANAGER (manager), NULL);
278 priv = GET_PRIV (manager);
280 g_hash_table_foreach (priv->chats,
281 (GHFunc) chat_manager_get_chats_foreach,
284 chats = g_list_sort (chats, (GCompareFunc) strcmp);
290 gossip_chat_manager_remove_events (GossipChatManager *manager,
291 GossipContact *contact)
293 GossipChatManagerPriv *priv;
296 g_return_if_fail (GOSSIP_IS_CHAT_MANAGER (manager));
297 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
299 gossip_debug (DEBUG_DOMAIN,
300 "Removing events for contact:'%s'",
301 gossip_contact_get_id (contact));
303 priv = GET_PRIV (manager);
305 event = g_hash_table_lookup (priv->events, contact);
307 gossip_event_manager_remove (gossip_app_get_event_manager (),
308 event, G_OBJECT (manager));
309 g_hash_table_remove (priv->events, contact);
314 gossip_chat_manager_show_chat (GossipChatManager *manager,
315 GossipContact *contact)
317 GossipPrivateChat *chat;
319 g_return_if_fail (GOSSIP_IS_CHAT_MANAGER (manager));
320 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
322 chat = gossip_chat_manager_get_chat (manager, contact);
324 gossip_chat_present (GOSSIP_CHAT (chat));
326 gossip_chat_manager_remove_events(manager, contact);