2 * Copyright (C) 2004-2007 Imendio AB
3 * Copyright (C) 2007-2010 Collabora Ltd.
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., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301 USA
20 * Authors: Xavier Claessens <xclaesse@gmail.com>
21 * Martyn Russell <martyn@imendio.com>
27 #include <sys/types.h>
30 #include <libxml/parser.h>
31 #include <libxml/tree.h>
33 #include <telepathy-glib/account-manager.h>
34 #include <telepathy-glib/interfaces.h>
35 #include <telepathy-glib/simple-observer.h>
36 #include <telepathy-glib/util.h>
38 #include "empathy-client-factory.h"
39 #include "empathy-tp-chat.h"
40 #include "empathy-chatroom-manager.h"
41 #include "empathy-utils.h"
43 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
44 #include "empathy-debug.h"
46 #define CHATROOMS_XML_FILENAME "chatrooms.xml"
47 #define CHATROOMS_DTD_FILENAME "empathy-chatroom-manager.dtd"
50 static EmpathyChatroomManager
*chatroom_manager_singleton
= NULL
;
52 static void observe_channels_cb (TpSimpleObserver
*observer
,
54 TpConnection
*connection
,
56 TpChannelDispatchOperation
*dispatch_operation
,
58 TpObserveChannelsContext
*context
,
61 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChatroomManager)
66 TpAccountManager
*account_manager
;
68 /* source id of the autosave timer */
71 GFileMonitor
*monitor
;
74 TpBaseClient
*observer
;
75 } EmpathyChatroomManagerPriv
;
83 static guint signals
[LAST_SIGNAL
];
93 G_DEFINE_TYPE (EmpathyChatroomManager
, empathy_chatroom_manager
, G_TYPE_OBJECT
);
96 * API to save/load and parse the chatrooms file.
100 chatroom_manager_file_save (EmpathyChatroomManager
*manager
)
102 EmpathyChatroomManagerPriv
*priv
;
107 priv
= GET_PRIV (manager
);
109 priv
->writing
= TRUE
;
111 doc
= xmlNewDoc ((const xmlChar
*) "1.0");
112 root
= xmlNewNode (NULL
, (const xmlChar
*) "chatrooms");
113 xmlDocSetRootElement (doc
, root
);
115 for (l
= priv
->chatrooms
; l
; l
= l
->next
)
117 EmpathyChatroom
*chatroom
;
119 const gchar
*account_id
;
123 if (!empathy_chatroom_is_favorite (chatroom
))
126 account_id
= tp_proxy_get_object_path (empathy_chatroom_get_account (
129 node
= xmlNewChild (root
, NULL
, (const xmlChar
*) "chatroom", NULL
);
130 xmlNewTextChild (node
, NULL
, (const xmlChar
*) "name",
131 (const xmlChar
*) empathy_chatroom_get_name (chatroom
));
132 xmlNewTextChild (node
, NULL
, (const xmlChar
*) "room",
133 (const xmlChar
*) empathy_chatroom_get_room (chatroom
));
134 xmlNewTextChild (node
, NULL
, (const xmlChar
*) "account",
135 (const xmlChar
*) account_id
);
136 xmlNewTextChild (node
, NULL
, (const xmlChar
*) "auto_connect",
137 empathy_chatroom_get_auto_connect (chatroom
) ?
138 (const xmlChar
*) "yes" : (const xmlChar
*) "no");
139 xmlNewTextChild (node
, NULL
, (const xmlChar
*) "always_urgent",
140 empathy_chatroom_is_always_urgent (chatroom
) ?
141 (const xmlChar
*) "yes" : (const xmlChar
*) "no");
144 /* Make sure the XML is indented properly */
145 xmlIndentTreeOutput
= 1;
147 DEBUG ("Saving file:'%s'", priv
->file
);
148 xmlSaveFormatFileEnc (priv
->file
, doc
, "utf-8", 1);
153 priv
->writing
= FALSE
;
158 save_timeout (EmpathyChatroomManager
*self
)
160 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
162 priv
->save_timer_id
= 0;
163 chatroom_manager_file_save (self
);
169 reset_save_timeout (EmpathyChatroomManager
*self
)
171 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
173 if (priv
->save_timer_id
> 0)
174 g_source_remove (priv
->save_timer_id
);
176 priv
->save_timer_id
= g_timeout_add_seconds (SAVE_TIMER
,
177 (GSourceFunc
) save_timeout
, self
);
181 chatroom_changed_cb (EmpathyChatroom
*chatroom
,
183 EmpathyChatroomManager
*self
)
185 reset_save_timeout (self
);
189 add_chatroom (EmpathyChatroomManager
*self
,
190 EmpathyChatroom
*chatroom
)
192 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
194 priv
->chatrooms
= g_list_prepend (priv
->chatrooms
, g_object_ref (chatroom
));
196 /* Watch only those properties which are exported in the save file */
197 g_signal_connect (chatroom
, "notify::name",
198 G_CALLBACK (chatroom_changed_cb
), self
);
199 g_signal_connect (chatroom
, "notify::room",
200 G_CALLBACK (chatroom_changed_cb
), self
);
201 g_signal_connect (chatroom
, "notify::account",
202 G_CALLBACK (chatroom_changed_cb
), self
);
203 g_signal_connect (chatroom
, "notify::auto-connect",
204 G_CALLBACK (chatroom_changed_cb
), self
);
205 g_signal_connect (chatroom
, "notify::always_urgent",
206 G_CALLBACK (chatroom_changed_cb
), self
);
210 chatroom_manager_parse_chatroom (EmpathyChatroomManager
*manager
,
213 EmpathyChatroom
*chatroom
= NULL
;
220 gboolean auto_connect
;
221 gboolean always_urgent
;
222 EmpathyClientFactory
*factory
;
223 GError
*error
= NULL
;
225 /* default values. */
229 always_urgent
= FALSE
;
232 for (child
= node
->children
; child
; child
= child
->next
)
236 if (xmlNodeIsText (child
))
239 tag
= (gchar
*) child
->name
;
240 str
= (gchar
*) xmlNodeGetContent (child
);
242 if (strcmp (tag
, "name") == 0)
244 name
= g_strdup (str
);
246 else if (strcmp (tag
, "room") == 0)
248 room
= g_strdup (str
);
250 else if (strcmp (tag
, "auto_connect") == 0)
252 if (strcmp (str
, "yes") == 0)
255 auto_connect
= FALSE
;
257 else if (!tp_strdiff (tag
, "always_urgent"))
259 if (strcmp (str
, "yes") == 0)
260 always_urgent
= TRUE
;
262 always_urgent
= FALSE
;
264 else if (strcmp (tag
, "account") == 0)
266 account_id
= g_strdup (str
);
272 /* account has to be a valid Account object path */
273 if (!tp_dbus_check_valid_object_path (account_id
, NULL
) ||
274 !g_str_has_prefix (account_id
, TP_ACCOUNT_OBJECT_PATH_BASE
))
277 factory
= empathy_client_factory_dup ();
279 account
= tp_simple_client_factory_ensure_account (
280 TP_SIMPLE_CLIENT_FACTORY (factory
), account_id
, NULL
, &error
);
281 g_object_unref (factory
);
285 DEBUG ("Failed to create account: %s", error
->message
);
286 g_error_free (error
);
294 chatroom
= empathy_chatroom_new_full (account
, room
, name
, auto_connect
);
295 empathy_chatroom_set_favorite (chatroom
, TRUE
);
296 empathy_chatroom_set_always_urgent (chatroom
, always_urgent
);
297 add_chatroom (manager
, chatroom
);
298 g_signal_emit (manager
, signals
[CHATROOM_ADDED
], 0, chatroom
);
304 tp_clear_object (&chatroom
);
308 chatroom_manager_file_parse (EmpathyChatroomManager
*manager
,
309 const gchar
*filename
)
311 EmpathyChatroomManagerPriv
*priv
;
312 xmlParserCtxtPtr ctxt
;
314 xmlNodePtr chatrooms
;
317 priv
= GET_PRIV (manager
);
319 DEBUG ("Attempting to parse file:'%s'...", filename
);
321 ctxt
= xmlNewParserCtxt ();
323 /* Parse and validate the file. */
324 doc
= xmlCtxtReadFile (ctxt
, filename
, NULL
, 0);
327 g_warning ("Failed to parse file:'%s'", filename
);
328 xmlFreeParserCtxt (ctxt
);
332 if (!empathy_xml_validate (doc
, CHATROOMS_DTD_FILENAME
))
334 g_warning ("Failed to validate file:'%s'", filename
);
336 xmlFreeParserCtxt (ctxt
);
340 /* The root node, chatrooms. */
341 chatrooms
= xmlDocGetRootElement (doc
);
343 for (node
= chatrooms
->children
; node
; node
= node
->next
)
345 if (strcmp ((gchar
*) node
->name
, "chatroom") == 0)
346 chatroom_manager_parse_chatroom (manager
, node
);
349 DEBUG ("Parsed %d chatrooms", g_list_length (priv
->chatrooms
));
352 xmlFreeParserCtxt (ctxt
);
358 chatroom_manager_get_all (EmpathyChatroomManager
*manager
)
360 EmpathyChatroomManagerPriv
*priv
;
362 priv
= GET_PRIV (manager
);
365 if (g_file_test (priv
->file
, G_FILE_TEST_EXISTS
) &&
366 !chatroom_manager_file_parse (manager
, priv
->file
))
372 g_object_notify (G_OBJECT (manager
), "ready");
379 empathy_chatroom_manager_get_property (GObject
*object
,
384 EmpathyChatroomManager
*self
= EMPATHY_CHATROOM_MANAGER (object
);
385 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
390 g_value_set_string (value
, priv
->file
);
393 g_value_set_boolean (value
, priv
->ready
);
396 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
402 empathy_chatroom_manager_set_property (GObject
*object
,
407 EmpathyChatroomManager
*self
= EMPATHY_CHATROOM_MANAGER (object
);
408 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
414 priv
->file
= g_value_dup_string (value
);
417 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
423 chatroom_manager_dispose (GObject
*object
)
425 EmpathyChatroomManagerPriv
*priv
;
427 priv
= GET_PRIV (object
);
429 tp_clear_object (&priv
->observer
);
430 tp_clear_object (&priv
->monitor
);
432 (G_OBJECT_CLASS (empathy_chatroom_manager_parent_class
)->dispose
) (object
);
436 clear_chatrooms (EmpathyChatroomManager
*self
)
438 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
441 tmp
= priv
->chatrooms
;
443 /* Unreffing the chatroom may result in destroying the underlying
444 * EmpathyTpChat which will fire the invalidated signal and so make us
445 * re-call this function. We already set priv->chatrooms to NULL so we won't
446 * try to destroy twice the same objects. */
447 priv
->chatrooms
= NULL
;
449 for (l
= tmp
; l
!= NULL
; l
= g_list_next (l
))
451 EmpathyChatroom
*chatroom
= l
->data
;
453 g_signal_handlers_disconnect_by_func (chatroom
, chatroom_changed_cb
,
455 g_signal_emit (self
, signals
[CHATROOM_REMOVED
], 0, chatroom
);
457 g_object_unref (chatroom
);
464 chatroom_manager_finalize (GObject
*object
)
466 EmpathyChatroomManager
*self
= EMPATHY_CHATROOM_MANAGER (object
);
467 EmpathyChatroomManagerPriv
*priv
;
469 priv
= GET_PRIV (object
);
471 g_object_unref (priv
->account_manager
);
473 if (priv
->save_timer_id
> 0)
475 /* have to save before destroy the object */
476 g_source_remove (priv
->save_timer_id
);
477 priv
->save_timer_id
= 0;
478 chatroom_manager_file_save (self
);
481 clear_chatrooms (self
);
485 (G_OBJECT_CLASS (empathy_chatroom_manager_parent_class
)->finalize
) (object
);
489 file_changed_cb (GFileMonitor
*monitor
,
492 GFileMonitorEvent event_type
,
495 EmpathyChatroomManager
*self
= user_data
;
496 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
498 if (event_type
!= G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT
)
504 DEBUG ("chatrooms file changed; reloading list");
506 clear_chatrooms (self
);
507 chatroom_manager_get_all (self
);
511 account_manager_ready_cb (GObject
*source_object
,
512 GAsyncResult
*result
,
515 EmpathyChatroomManager
*self
= EMPATHY_CHATROOM_MANAGER (user_data
);
516 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (self
);
517 TpAccountManager
*manager
= TP_ACCOUNT_MANAGER (source_object
);
518 GError
*error
= NULL
;
521 if (!tp_account_manager_prepare_finish (manager
, result
, &error
))
523 DEBUG ("Failed to prepare account manager: %s", error
->message
);
524 g_error_free (error
);
528 chatroom_manager_get_all (self
);
530 /* Set up file monitor */
531 file
= g_file_new_for_path (priv
->file
);
533 priv
->monitor
= g_file_monitor (file
, 0, NULL
, &error
);
534 if (priv
->monitor
== NULL
)
536 DEBUG ("Failed to create file monitor on %s: %s", priv
->file
,
539 g_error_free (error
);
543 g_signal_connect (priv
->monitor
, "changed", G_CALLBACK (file_changed_cb
),
547 tp_clear_object (&file
);
548 g_object_unref (self
);
552 empathy_chatroom_manager_constructor (GType type
,
554 GObjectConstructParam
*props
)
557 EmpathyChatroomManager
*self
;
558 EmpathyChatroomManagerPriv
*priv
;
559 GError
*error
= NULL
;
561 if (chatroom_manager_singleton
!= NULL
)
562 return g_object_ref (chatroom_manager_singleton
);
564 /* Parent constructor chain */
565 obj
= G_OBJECT_CLASS (empathy_chatroom_manager_parent_class
)->
566 constructor (type
, n_props
, props
);
568 self
= EMPATHY_CHATROOM_MANAGER (obj
);
569 priv
= GET_PRIV (self
);
573 chatroom_manager_singleton
= self
;
574 g_object_add_weak_pointer (obj
, (gpointer
) &chatroom_manager_singleton
);
576 priv
->account_manager
= tp_account_manager_dup ();
578 tp_account_manager_prepare_async (priv
->account_manager
, NULL
,
579 account_manager_ready_cb
, g_object_ref (self
));
581 if (priv
->file
== NULL
)
583 /* Set the default file path */
586 dir
= g_build_filename (g_get_user_config_dir (), PACKAGE_NAME
, NULL
);
587 if (!g_file_test (dir
, G_FILE_TEST_EXISTS
| G_FILE_TEST_IS_DIR
))
588 g_mkdir_with_parents (dir
, S_IRUSR
| S_IWUSR
| S_IXUSR
);
590 priv
->file
= g_build_filename (dir
, CHATROOMS_XML_FILENAME
, NULL
);
594 /* Setup a room observer */
595 priv
->observer
= tp_simple_observer_new_with_am (priv
->account_manager
, TRUE
,
596 "Empathy.ChatroomManager", TRUE
, observe_channels_cb
, self
, NULL
);
598 tp_base_client_take_observer_filter (priv
->observer
, tp_asv_new (
599 TP_PROP_CHANNEL_CHANNEL_TYPE
, G_TYPE_STRING
,
600 TP_IFACE_CHANNEL_TYPE_TEXT
,
601 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE
, G_TYPE_UINT
,
605 if (!tp_base_client_register (priv
->observer
, &error
))
607 g_critical ("Failed to register Observer: %s", error
->message
);
609 g_error_free (error
);
616 empathy_chatroom_manager_class_init (EmpathyChatroomManagerClass
*klass
)
618 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
619 GParamSpec
*param_spec
;
621 object_class
->constructor
= empathy_chatroom_manager_constructor
;
622 object_class
->get_property
= empathy_chatroom_manager_get_property
;
623 object_class
->set_property
= empathy_chatroom_manager_set_property
;
624 object_class
->dispose
= chatroom_manager_dispose
;
625 object_class
->finalize
= chatroom_manager_finalize
;
627 param_spec
= g_param_spec_string (
629 "path of the favorite file",
630 "The path of the XML file containing user's favorites",
632 G_PARAM_CONSTRUCT_ONLY
|
634 G_PARAM_STATIC_NAME
|
635 G_PARAM_STATIC_NICK
|
636 G_PARAM_STATIC_BLURB
);
637 g_object_class_install_property (object_class
, PROP_FILE
, param_spec
);
639 param_spec
= g_param_spec_boolean (
641 "whether the manager is ready yet",
642 "whether the manager is ready yet",
645 g_object_class_install_property (object_class
, PROP_READY
, param_spec
);
647 signals
[CHATROOM_ADDED
] = g_signal_new ("chatroom-added",
648 G_TYPE_FROM_CLASS (klass
),
651 g_cclosure_marshal_VOID__OBJECT
,
653 1, EMPATHY_TYPE_CHATROOM
);
655 signals
[CHATROOM_REMOVED
] = g_signal_new ("chatroom-removed",
656 G_TYPE_FROM_CLASS (klass
),
659 g_cclosure_marshal_VOID__OBJECT
,
661 1, EMPATHY_TYPE_CHATROOM
);
663 g_type_class_add_private (object_class
, sizeof (EmpathyChatroomManagerPriv
));
667 empathy_chatroom_manager_init (EmpathyChatroomManager
*manager
)
669 EmpathyChatroomManagerPriv
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (manager
,
670 EMPATHY_TYPE_CHATROOM_MANAGER
, EmpathyChatroomManagerPriv
);
672 manager
->priv
= priv
;
675 EmpathyChatroomManager
*
676 empathy_chatroom_manager_dup_singleton (const gchar
*file
)
678 return EMPATHY_CHATROOM_MANAGER (g_object_new (EMPATHY_TYPE_CHATROOM_MANAGER
,
679 "file", file
, NULL
));
683 empathy_chatroom_manager_add (EmpathyChatroomManager
*manager
,
684 EmpathyChatroom
*chatroom
)
686 g_return_val_if_fail (EMPATHY_IS_CHATROOM_MANAGER (manager
), FALSE
);
687 g_return_val_if_fail (EMPATHY_IS_CHATROOM (chatroom
), FALSE
);
689 /* don't add more than once */
690 if (!empathy_chatroom_manager_find (manager
,
691 empathy_chatroom_get_account (chatroom
),
692 empathy_chatroom_get_room (chatroom
)))
694 add_chatroom (manager
, chatroom
);
696 if (empathy_chatroom_is_favorite (chatroom
))
697 reset_save_timeout (manager
);
699 g_signal_emit (manager
, signals
[CHATROOM_ADDED
], 0, chatroom
);
707 chatroom_manager_remove_link (EmpathyChatroomManager
*manager
,
710 EmpathyChatroomManagerPriv
*priv
;
711 EmpathyChatroom
*chatroom
;
713 priv
= GET_PRIV (manager
);
717 if (empathy_chatroom_is_favorite (chatroom
))
718 reset_save_timeout (manager
);
720 priv
->chatrooms
= g_list_delete_link (priv
->chatrooms
, l
);
722 g_signal_emit (manager
, signals
[CHATROOM_REMOVED
], 0, chatroom
);
723 g_signal_handlers_disconnect_by_func (chatroom
, chatroom_changed_cb
, manager
);
725 g_object_unref (chatroom
);
729 empathy_chatroom_manager_remove (EmpathyChatroomManager
*manager
,
730 EmpathyChatroom
*chatroom
)
732 EmpathyChatroomManagerPriv
*priv
;
735 g_return_if_fail (EMPATHY_IS_CHATROOM_MANAGER (manager
));
736 g_return_if_fail (EMPATHY_IS_CHATROOM (chatroom
));
738 priv
= GET_PRIV (manager
);
740 for (l
= priv
->chatrooms
; l
; l
= l
->next
)
742 EmpathyChatroom
*this_chatroom
;
744 this_chatroom
= l
->data
;
746 if (this_chatroom
== chatroom
||
747 empathy_chatroom_equal (chatroom
, this_chatroom
))
749 chatroom_manager_remove_link (manager
, l
);
756 empathy_chatroom_manager_find (EmpathyChatroomManager
*manager
,
760 EmpathyChatroomManagerPriv
*priv
;
763 g_return_val_if_fail (EMPATHY_IS_CHATROOM_MANAGER (manager
), NULL
);
764 g_return_val_if_fail (room
!= NULL
, NULL
);
766 priv
= GET_PRIV (manager
);
768 for (l
= priv
->chatrooms
; l
; l
= l
->next
)
770 EmpathyChatroom
*chatroom
;
771 TpAccount
*this_account
;
772 const gchar
*this_room
;
775 this_account
= empathy_chatroom_get_account (chatroom
);
776 this_room
= empathy_chatroom_get_room (chatroom
);
778 if (this_account
&& this_room
&& account
== this_account
779 && strcmp (this_room
, room
) == 0)
787 empathy_chatroom_manager_ensure_chatroom (EmpathyChatroomManager
*manager
,
792 EmpathyChatroom
*chatroom
;
794 chatroom
= empathy_chatroom_manager_find (manager
, account
, room
);
798 return g_object_ref (chatroom
);
802 chatroom
= empathy_chatroom_new_full (account
,
806 empathy_chatroom_manager_add (manager
, chatroom
);
812 empathy_chatroom_manager_get_chatrooms (EmpathyChatroomManager
*manager
,
815 EmpathyChatroomManagerPriv
*priv
;
816 GList
*chatrooms
, *l
;
818 g_return_val_if_fail (EMPATHY_IS_CHATROOM_MANAGER (manager
), NULL
);
820 priv
= GET_PRIV (manager
);
823 return g_list_copy (priv
->chatrooms
);
826 for (l
= priv
->chatrooms
; l
; l
= l
->next
)
828 EmpathyChatroom
*chatroom
;
832 if (account
== empathy_chatroom_get_account (chatroom
))
833 chatrooms
= g_list_append (chatrooms
, chatroom
);
840 chatroom_manager_chat_invalidated_cb (EmpathyTpChat
*chat
,
846 EmpathyChatroomManagerPriv
*priv
= GET_PRIV (manager
);
849 for (l
= priv
->chatrooms
; l
; l
= l
->next
)
851 EmpathyChatroom
*chatroom
= l
->data
;
853 if (empathy_chatroom_get_tp_chat (chatroom
) != chat
)
856 empathy_chatroom_set_tp_chat (chatroom
, NULL
);
858 if (!empathy_chatroom_is_favorite (chatroom
))
860 /* Remove the chatroom from the list, unless it's in the list of
862 * FIXME this policy should probably not be in libempathy */
863 chatroom_manager_remove_link (manager
, l
);
871 observe_channels_cb (TpSimpleObserver
*observer
,
873 TpConnection
*connection
,
875 TpChannelDispatchOperation
*dispatch_operation
,
877 TpObserveChannelsContext
*context
,
880 EmpathyChatroomManager
*self
= user_data
;
883 for (l
= channels
; l
!= NULL
; l
= g_list_next (l
))
885 EmpathyTpChat
*tp_chat
= l
->data
;
886 const gchar
*roomname
;
887 EmpathyChatroom
*chatroom
;
889 if (tp_proxy_get_invalidated ((TpChannel
*) tp_chat
) != NULL
)
892 if (!EMPATHY_IS_TP_CHAT (tp_chat
))
895 roomname
= empathy_tp_chat_get_id (tp_chat
);
896 chatroom
= empathy_chatroom_manager_find (self
, account
, roomname
);
898 if (chatroom
== NULL
)
900 chatroom
= empathy_chatroom_new_full (account
, roomname
, roomname
,
902 empathy_chatroom_manager_add (self
, chatroom
);
903 g_object_unref (chatroom
);
906 empathy_chatroom_set_tp_chat (chatroom
, tp_chat
);
908 g_signal_connect (tp_chat
, "invalidated",
909 G_CALLBACK (chatroom_manager_chat_invalidated_cb
),
913 tp_observe_channels_context_accept (context
);