aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog47
-rw-r--r--TODO2
-rw-r--r--libempathy-gtk/Makefile.am2
-rw-r--r--libempathy-gtk/empathy-main-window.c270
-rw-r--r--libempathy-gtk/empathy-status-icon.c2
-rw-r--r--libempathy-gtk/gossip-account-chooser.c3
-rw-r--r--libempathy-gtk/gossip-accounts-dialog.c7
-rw-r--r--libempathy-gtk/gossip-accounts-dialog.h2
-rw-r--r--libempathy-gtk/gossip-chat-window.c52
-rw-r--r--libempathy-gtk/gossip-chat-window.h5
-rw-r--r--libempathy-gtk/gossip-chat.c3
-rw-r--r--libempathy-gtk/gossip-chatrooms-window.c530
-rw-r--r--libempathy-gtk/gossip-chatrooms-window.glade477
-rw-r--r--libempathy-gtk/gossip-chatrooms-window.h35
-rw-r--r--libempathy-gtk/gossip-preferences.c7
-rw-r--r--libempathy-gtk/gossip-preferences.h4
-rw-r--r--libempathy/Makefile.am9
-rw-r--r--libempathy/empathy-tp-chat.c56
-rw-r--r--libempathy/empathy-tp-chat.h4
-rw-r--r--libempathy/empathy-tp-contact-list.c7
-rw-r--r--libempathy/gossip-chatroom-manager.c500
-rw-r--r--libempathy/gossip-chatroom-manager.dtd17
-rw-r--r--libempathy/gossip-chatroom-manager.h72
-rw-r--r--libempathy/gossip-chatroom.c360
-rw-r--r--libempathy/gossip-chatroom.h78
-rw-r--r--libempathy/gossip-utils.c49
-rw-r--r--libempathy/gossip-utils.h13
-rw-r--r--src/empathy-accounts-main.c2
-rw-r--r--src/empathy-chat-main.c6
29 files changed, 2443 insertions, 178 deletions
diff --git a/ChangeLog b/ChangeLog
index 568362887..ff1c7e124 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2007-05-31 Xavier Claessens <xclaesse@gmail.com>
+
+ * libempathy-gtk/gossip-account-chooser.c: Fix warning when selecting
+ all accounts.
+
+ * src/empathy-accounts-main.c:
+ * libempathy-gtk/empathy-status-icon.c:
+ * libempathy-gtk/gossip-accounts-dialog.h:
+ * libempathy-gtk/gossip-accounts-dialog.c:
+ * libempathy-gtk/gossip-preferences.h:
+ * libempathy-gtk/gossip-preferences.c: Set parent window.
+
+ * libempathy-gtk/empathy-main-window.c: Implement favorite chatroom
+ menu and fix a leak.
+
+ * libempathy-gtk/Makefile.am:
+ * libempathy/Makefile.am:
+ * libempathy/gossip-chatroom.c:
+ * libempathy/gossip-chatroom.h:
+ * libempathy/gossip-chatroom-manager.c:
+ * libempathy/gossip-chatroom-manager.h:
+ * libempathy/gossip-chatroom-manager.dtd:
+ * libempathy-gtk/gossip-chatrooms-window.glade:
+ * libempathy-gtk/gossip-chatrooms-window.c:
+ * libempathy-gtk/gossip-chatrooms-window.h: New files to implement
+ favorite chatrooms and a window to show them.
+
+
+ * libempathy-gtk/gossip-chat.c: Fix tooltip leaked.
+
+ * libempathy-gtk/gossip-chat-window.h:
+ * libempathy-gtk/gossip-chat-window.c: Do not use deprecated
+ gtk_object_sink(). Implement favorite chatroom features. Find a chat
+ by comparing the account AND the chat ID.
+
+ * src/empathy-chat-main.c:
+ * libempathy/empathy-tp-chat.h:
+ * libempathy/empathy-tp-chat.c:
+ * libempathy/gossip-utils.h:
+ * libempathy/gossip-utils.c: empathy_tp_chat_get_id() returns the Text
+ channel's name. The chat ID is unique only for a specified account.
+
+ * libempathy/empathy-tp-contact-list.c: Fix some leaks and add a FIXME
+ comment for a leak not yet fixed.
+
+ * TODO: Would be cool to have a glade catalog for libempathy-gtk.
+
2007-05-26 Xavier Claessens <xclaesse@gmail.com>
* libempathy-gtk/gossip-contact-list-store.c: Do not highlight contacts
diff --git a/TODO b/TODO
index da967a331..8367547b0 100644
--- a/TODO
+++ b/TODO
@@ -3,7 +3,7 @@ Things you can do if you want to help:
- Rename all files and functions name to use the empathy namespace.
- Porting gossip-account-widget-*.{c,h} from gossip project (Guillaume is already working on IRC widget).
- Porting various UI widgets from gossip to libempathy-gtk for contact info, adding contact, personal info, etc.
- - GtkWidget-ify gossip widgets imported in libempathy-gtk. Actually most window/dialog do not inherit from GtkWindow/GtkDialog...
+ - GtkWidget-ify gossip widgets imported in libempathy-gtk. Actually most window/dialog do not inherit from GtkWindow/GtkDialog. Need to create a glade catalog.
- Fix setting subscription for contacts in EmpathyTpContactList.
- Filter channels before dispatching them. For example we need a GtkStatusIcon that blink when an event arrives (text/voip/ft channel) and tells the MC to dispatch the channel only when the user clicked the icon. Like in gossip. For that we need a filter DBus API in MC, not yet written.
- Make use of NetworkManager to set the presence
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index f28e7411c..183f7d8e2 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -34,6 +34,7 @@ libempathy_gtk_la_SOURCES = \
gossip-about-dialog.c gossip-about-dialog.h \
gossip-account-chooser.c gossip-account-chooser.h \
gossip-new-chatroom-dialog.c gossip-new-chatroom-dialog.h \
+ gossip-chatrooms-window.c gossip-chatrooms-window.h \
gossip-ui-utils.c gossip-ui-utils.h
libempathy_gtk_la_LIBADD = \
@@ -52,6 +53,7 @@ glade_DATA = \
gossip-account-widget-jabber.glade \
gossip-new-chatroom-dialog.glade \
gossip-group-chat.glade \
+ gossip-chatrooms-window.glade \
gossip-chat.glade
dtddir = $(datadir)/empathy
diff --git a/libempathy-gtk/empathy-main-window.c b/libempathy-gtk/empathy-main-window.c
index b10f6c8d6..befe2f531 100644
--- a/libempathy-gtk/empathy-main-window.c
+++ b/libempathy-gtk/empathy-main-window.c
@@ -31,6 +31,8 @@
#include <libempathy/gossip-contact.h>
#include <libempathy/gossip-debug.h>
#include <libempathy/gossip-utils.h>
+#include <libempathy/gossip-chatroom-manager.h>
+#include <libempathy/gossip-chatroom.h>
#include <libempathy/empathy-contact-list.h>
#include <libempathy/empathy-contact-manager.h>
@@ -46,6 +48,7 @@
#include "gossip-accounts-dialog.h"
#include "gossip-about-dialog.h"
#include "gossip-new-chatroom-dialog.h"
+#include "gossip-chatrooms-window.h"
#define DEBUG_DOMAIN "MainWindow"
@@ -62,6 +65,7 @@ typedef struct {
GossipContactListView *list_view;
GossipContactListStore *list_store;
MissionControl *mc;
+ GossipChatroomManager *chatroom_manager;
/* Main widgets */
GtkWidget *window;
@@ -93,68 +97,79 @@ typedef struct {
guint size_timeout_id;
} EmpathyMainWindow;
-static void main_window_destroy_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_favorite_chatroom_menu_setup (void);
-static void main_window_chat_quit_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_chat_new_message_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_chat_history_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_room_join_new_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_room_join_favorites_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_room_manage_favorites_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_chat_add_contact_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_chat_show_offline_cb (GtkCheckMenuItem *item,
- EmpathyMainWindow *window);
-static gboolean main_window_edit_button_press_event_cb (GtkWidget *widget,
- GdkEventButton *event,
- EmpathyMainWindow *window);
-static void main_window_edit_accounts_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_edit_personal_information_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_edit_preferences_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_help_about_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static void main_window_help_contents_cb (GtkWidget *widget,
- EmpathyMainWindow *window);
-static gboolean main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox,
- GdkEventButton *event,
- gpointer user_data);
-static void main_window_status_changed_cb (MissionControl *mc,
- TelepathyConnectionStatus status,
- McPresence presence,
- TelepathyConnectionStatusReason reason,
- const gchar *unique_name,
- EmpathyMainWindow *window);
-static void main_window_update_status (EmpathyMainWindow *window);
-static void main_window_accels_load (void);
-static void main_window_accels_save (void);
-static void main_window_connection_items_setup (EmpathyMainWindow *window,
- GladeXML *glade);
-static gboolean main_window_configure_event_timeout_cb (EmpathyMainWindow *window);
-static gboolean main_window_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- EmpathyMainWindow *window);
-static void main_window_notify_show_offline_cb (GossipConf *conf,
- const gchar *key,
- gpointer check_menu_item);
-static void main_window_notify_show_avatars_cb (GossipConf *conf,
- const gchar *key,
- EmpathyMainWindow *window);
-static void main_window_notify_compact_contact_list_cb (GossipConf *conf,
- const gchar *key,
- EmpathyMainWindow *window);
-static void main_window_notify_sort_criterium_cb (GossipConf *conf,
- const gchar *key,
- EmpathyMainWindow *window);
+static void main_window_destroy_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_favorite_chatroom_menu_setup (EmpathyMainWindow *window);
+static void main_window_favorite_chatroom_menu_added_cb (GossipChatroomManager *manager,
+ GossipChatroom *chatroom,
+ EmpathyMainWindow *window);
+static void main_window_favorite_chatroom_menu_removed_cb (GossipChatroomManager *manager,
+ GossipChatroom *chatroom,
+ EmpathyMainWindow *window);
+static void main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item,
+ GossipChatroom *chatroom);
+static void main_window_favorite_chatroom_menu_update (EmpathyMainWindow *window);
+static void main_window_favorite_chatroom_menu_add (EmpathyMainWindow *window,
+ GossipChatroom *chatroom);
+static void main_window_chat_quit_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_chat_new_message_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_chat_history_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_room_join_new_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_room_join_favorites_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_room_manage_favorites_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_chat_add_contact_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_chat_show_offline_cb (GtkCheckMenuItem *item,
+ EmpathyMainWindow *window);
+static gboolean main_window_edit_button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ EmpathyMainWindow *window);
+static void main_window_edit_accounts_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_edit_personal_information_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_edit_preferences_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_help_about_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static void main_window_help_contents_cb (GtkWidget *widget,
+ EmpathyMainWindow *window);
+static gboolean main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox,
+ GdkEventButton *event,
+ EmpathyMainWindow *window);
+static void main_window_status_changed_cb (MissionControl *mc,
+ TelepathyConnectionStatus status,
+ McPresence presence,
+ TelepathyConnectionStatusReason reason,
+ const gchar *unique_name,
+ EmpathyMainWindow *window);
+static void main_window_update_status (EmpathyMainWindow *window);
+static void main_window_accels_load (void);
+static void main_window_accels_save (void);
+static void main_window_connection_items_setup (EmpathyMainWindow *window,
+ GladeXML *glade);
+static gboolean main_window_configure_event_timeout_cb (EmpathyMainWindow *window);
+static gboolean main_window_configure_event_cb (GtkWidget *widget,
+ GdkEventConfigure *event,
+ EmpathyMainWindow *window);
+static void main_window_notify_show_offline_cb (GossipConf *conf,
+ const gchar *key,
+ gpointer check_menu_item);
+static void main_window_notify_show_avatars_cb (GossipConf *conf,
+ const gchar *key,
+ EmpathyMainWindow *window);
+static void main_window_notify_compact_contact_list_cb (GossipConf *conf,
+ const gchar *key,
+ EmpathyMainWindow *window);
+static void main_window_notify_sort_criterium_cb (GossipConf *conf,
+ const gchar *key,
+ EmpathyMainWindow *window);
GtkWidget *
empathy_main_window_show (void)
@@ -227,7 +242,7 @@ empathy_main_window_show (void)
window, NULL);
/* Set up menu */
- main_window_favorite_chatroom_menu_setup ();
+ main_window_favorite_chatroom_menu_setup (window);
gtk_widget_hide (window->edit_context);
gtk_widget_hide (window->edit_context_separator);
@@ -263,7 +278,7 @@ empathy_main_window_show (void)
g_signal_connect (ebox,
"button-press-event",
G_CALLBACK (main_window_throbber_button_press_event_cb),
- NULL);
+ window);
/* Set up contact list. */
gossip_status_presets_get_all ();
@@ -374,8 +389,116 @@ main_window_destroy_cb (GtkWidget *widget,
}
static void
-main_window_favorite_chatroom_menu_setup (void)
+main_window_favorite_chatroom_menu_setup (EmpathyMainWindow *window)
{
+ GList *chatrooms, *l;
+
+ window->chatroom_manager = gossip_chatroom_manager_new ();
+ chatrooms = gossip_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL);
+ window->room_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (window->room));
+
+ for (l = chatrooms; l; l = l->next) {
+ main_window_favorite_chatroom_menu_add (window, l->data);
+ }
+
+ if (!chatrooms) {
+ gtk_widget_hide (window->room_sep);
+ }
+
+ gtk_widget_set_sensitive (window->room_join_favorites, chatrooms != NULL);
+
+ g_signal_connect (window->chatroom_manager, "chatroom-added",
+ G_CALLBACK (main_window_favorite_chatroom_menu_added_cb),
+ window);
+ g_signal_connect (window->chatroom_manager, "chatroom-removed",
+ G_CALLBACK (main_window_favorite_chatroom_menu_removed_cb),
+ window);
+
+ g_list_free (chatrooms);
+}
+
+static void
+main_window_favorite_chatroom_menu_added_cb (GossipChatroomManager *manager,
+ GossipChatroom *chatroom,
+ EmpathyMainWindow *window)
+{
+ main_window_favorite_chatroom_menu_add (window, chatroom);
+ gtk_widget_show (window->room_sep);
+ gtk_widget_set_sensitive (window->room_join_favorites, TRUE);
+}
+
+static void
+main_window_favorite_chatroom_menu_removed_cb (GossipChatroomManager *manager,
+ GossipChatroom *chatroom,
+ EmpathyMainWindow *window)
+{
+ GtkWidget *menu_item;
+
+ menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
+
+ g_object_set_data (G_OBJECT (chatroom), "menu_item", NULL);
+ gtk_widget_destroy (menu_item);
+
+ main_window_favorite_chatroom_menu_update (window);
+}
+
+static void
+main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item,
+ GossipChatroom *chatroom)
+{
+/*FIXME:
+ GossipSession *session;
+ GossipAccount *account;
+ GossipChatroomProvider *provider;
+
+ session = gossip_app_get_session ();
+ account = gossip_chatroom_get_account (chatroom);
+ provider = gossip_session_get_chatroom_provider (session, account);
+
+ gossip_group_chat_new (provider, chatroom);
+*/
+}
+
+static void
+main_window_favorite_chatroom_menu_update (EmpathyMainWindow *window)
+{
+ GList *chatrooms;
+
+ chatrooms = gossip_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL);
+
+ if (chatrooms) {
+ gtk_widget_show (window->room_sep);
+ } else {
+ gtk_widget_hide (window->room_sep);
+ }
+
+ gtk_widget_set_sensitive (window->room_join_favorites, chatrooms != NULL);
+ g_list_free (chatrooms);
+}
+
+static void
+main_window_favorite_chatroom_menu_add (EmpathyMainWindow *window,
+ GossipChatroom *chatroom)
+{
+ GtkWidget *menu_item;
+ const gchar *name;
+
+ if (g_object_get_data (G_OBJECT (chatroom), "menu_item")) {
+ return;
+ }
+
+ name = gossip_chatroom_get_name (chatroom);
+ menu_item = gtk_menu_item_new_with_label (name);
+
+ g_object_set_data (G_OBJECT (chatroom), "menu_item", menu_item);
+ g_signal_connect (menu_item, "activate",
+ G_CALLBACK (main_window_favorite_chatroom_menu_activate_cb),
+ chatroom);
+
+ gtk_menu_shell_insert (GTK_MENU_SHELL (window->room_menu),
+ menu_item, 3);
+
+ gtk_widget_show (menu_item);
}
static void
@@ -417,7 +540,7 @@ static void
main_window_room_manage_favorites_cb (GtkWidget *widget,
EmpathyMainWindow *window)
{
- //gossip_chatrooms_window_show (NULL, FALSE);
+ gossip_chatrooms_window_show (GTK_WINDOW (window->window));
}
static void
@@ -510,7 +633,7 @@ static void
main_window_edit_accounts_cb (GtkWidget *widget,
EmpathyMainWindow *window)
{
- gossip_accounts_dialog_show ();
+ gossip_accounts_dialog_show (GTK_WINDOW (window->window));
}
static void
@@ -524,7 +647,7 @@ static void
main_window_edit_preferences_cb (GtkWidget *widget,
EmpathyMainWindow *window)
{
- gossip_preferences_show ();
+ gossip_preferences_show (GTK_WINDOW (window->window));
}
static void
@@ -542,16 +665,16 @@ main_window_help_contents_cb (GtkWidget *widget,
}
static gboolean
-main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox,
- GdkEventButton *event,
- gpointer user_data)
+main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox,
+ GdkEventButton *event,
+ EmpathyMainWindow *window)
{
if (event->type != GDK_BUTTON_PRESS ||
event->button != 1) {
return FALSE;
}
- gossip_accounts_dialog_show ();
+ gossip_accounts_dialog_show (GTK_WINDOW (window->window));
return FALSE;
}
@@ -614,8 +737,6 @@ main_window_update_status (EmpathyMainWindow *window)
for (l = window->widgets_disconnected; l; l = l->next) {
gtk_widget_set_sensitive (l->data, (disconnected > 0));
}
-
- //app_favorite_chatroom_menu_update ();
}
/*
@@ -768,6 +889,7 @@ main_window_notify_sort_criterium_cb (GossipConf *conf,
type = gossip_contact_list_store_sort_get_type ();
enum_class = G_ENUM_CLASS (g_type_class_peek (type));
enum_value = g_enum_get_value_by_nick (enum_class, str);
+ g_free (str);
if (enum_value) {
gossip_contact_list_store_set_sort_criterium (window->list_store,
diff --git a/libempathy-gtk/empathy-status-icon.c b/libempathy-gtk/empathy-status-icon.c
index 21082276a..01a542493 100644
--- a/libempathy-gtk/empathy-status-icon.c
+++ b/libempathy-gtk/empathy-status-icon.c
@@ -231,7 +231,7 @@ status_icon_toggle_visibility (EmpathyStatusIcon *icon)
} else {
gossip_debug (DEBUG_DOMAIN,
"No enabled account, Showing account dialog");
- gossip_accounts_dialog_show ();
+ gossip_accounts_dialog_show (GTK_WINDOW (priv->window));
}
}
}
diff --git a/libempathy-gtk/gossip-account-chooser.c b/libempathy-gtk/gossip-account-chooser.c
index 9cb8e5d41..dfed1bb54 100644
--- a/libempathy-gtk/gossip-account-chooser.c
+++ b/libempathy-gtk/gossip-account-chooser.c
@@ -593,6 +593,9 @@ account_chooser_set_account_foreach (GtkTreeModel *model,
/* Special case so we can make it possible to select the All option */
if (!data->account && !account) {
equal = TRUE;
+ }
+ else if ((data->account && !account) || (!data->account && account)) {
+ equal = FALSE;
} else {
equal = gossip_account_equal (data->account, account);
g_object_unref (account);
diff --git a/libempathy-gtk/gossip-accounts-dialog.c b/libempathy-gtk/gossip-accounts-dialog.c
index 6d7934544..2a3a92764 100644
--- a/libempathy-gtk/gossip-accounts-dialog.c
+++ b/libempathy-gtk/gossip-accounts-dialog.c
@@ -944,7 +944,7 @@ accounts_dialog_destroy_cb (GtkWidget *widget,
}
GtkWidget *
-gossip_accounts_dialog_show (void)
+gossip_accounts_dialog_show (GtkWindow *parent)
{
static GossipAccountsDialog *dialog = NULL;
GladeXML *glade;
@@ -1026,6 +1026,11 @@ gossip_accounts_dialog_show (void)
accounts_dialog_setup (dialog);
accounts_dialog_model_select_first (dialog);
+ if (parent) {
+ gtk_window_set_transient_for (GTK_WINDOW (dialog->window),
+ GTK_WINDOW (parent));
+ }
+
gtk_widget_show (dialog->window);
return dialog->window;
diff --git a/libempathy-gtk/gossip-accounts-dialog.h b/libempathy-gtk/gossip-accounts-dialog.h
index e78b33506..5b058e6a4 100644
--- a/libempathy-gtk/gossip-accounts-dialog.h
+++ b/libempathy-gtk/gossip-accounts-dialog.h
@@ -28,7 +28,7 @@
G_BEGIN_DECLS
-GtkWidget *gossip_accounts_dialog_show (void);
+GtkWidget *gossip_accounts_dialog_show (GtkWindow *parent);
G_END_DECLS
diff --git a/libempathy-gtk/gossip-chat-window.c b/libempathy-gtk/gossip-chat-window.c
index 35f3f9ae7..6979e450e 100644
--- a/libempathy-gtk/gossip-chat-window.c
+++ b/libempathy-gtk/gossip-chat-window.c
@@ -36,10 +36,12 @@
#include <libempathy/empathy-contact-manager.h>
#include <libempathy/empathy-contact-list.h>
+#include <libempathy/gossip-chatroom-manager.h>
#include <libempathy/gossip-contact.h>
#include <libempathy/gossip-debug.h>
#include <libempathy/gossip-message.h>
#include <libempathy/gossip-conf.h>
+#include <libempathy/gossip-utils.h>
#include "gossip-chat-window.h"
#include "empathy-images.h"
@@ -274,8 +276,7 @@ gossip_chat_window_init (GossipChatWindow *window)
priv = GET_PRIV (window);
- priv->tooltips = g_object_ref (gtk_tooltips_new ());
- gtk_object_sink (GTK_OBJECT (priv->tooltips));
+ priv->tooltips = g_object_ref_sink (gtk_tooltips_new ());
glade = gossip_glade_get_file ("gossip-chat.glade",
"chat_window",
@@ -762,9 +763,10 @@ chat_window_update_menu (GossipChatWindow *window)
is_connected = gossip_chat_is_connected (priv->current_chat);
if (gossip_chat_is_group_chat (priv->current_chat)) {
- GossipGroupChat *group_chat;
- gboolean saved = TRUE;
- gboolean show_contacts;
+ GossipGroupChat *group_chat;
+ GossipChatroom *chatroom;
+ GossipChatroomManager *manager;
+ gboolean show_contacts;
group_chat = GOSSIP_GROUP_CHAT (priv->current_chat);
@@ -778,13 +780,13 @@ chat_window_update_menu (GossipChatWindow *window)
/* Can we add this room to our favourites and are we
* connected to the room?
*/
- /* FIXME:
- manager = gossip_app_get_chatroom_manager ();
- id = gossip_chatroom_get_id (chatroom);
- saved = gossip_chatroom_manager_find (manager, id) != NULL;
- */
+ manager = gossip_chatroom_manager_new ();
+ chatroom = gossip_chatroom_manager_find (manager,
+ priv->current_chat->account,
+ gossip_chat_get_id (priv->current_chat));
+ g_object_unref (manager);
- gtk_widget_set_sensitive (priv->menu_room_add, !saved);
+ gtk_widget_set_sensitive (priv->menu_room_add, chatroom == NULL);
gtk_widget_set_sensitive (priv->menu_conv_insert_smiley, is_connected);
gtk_widget_set_sensitive (priv->menu_room_join_new, is_connected);
gtk_widget_set_sensitive (priv->menu_room_invite, is_connected);
@@ -1079,9 +1081,7 @@ static void
chat_window_room_add_activate_cb (GtkWidget *menuitem,
GossipChatWindow *window)
{
-/* FIXME:
GossipChatWindowPriv *priv;
- GossipGroupChat *group_chat;
GossipChatroomManager *manager;
GossipChatroom *chatroom;
@@ -1093,16 +1093,17 @@ chat_window_room_add_activate_cb (GtkWidget *menuitem,
return;
}
- group_chat = GOSSIP_GROUP_CHAT (priv->current_chat);
- chatroom = gossip_group_chat_get_chatroom (group_chat);
- gossip_chatroom_set_favourite (chatroom, TRUE);
+ chatroom = gossip_chatroom_new_full (priv->current_chat->account,
+ gossip_chat_get_id (priv->current_chat),
+ gossip_chat_get_name (priv->current_chat),
+ FALSE);
- manager = gossip_app_get_chatroom_manager ();
+ manager = gossip_chatroom_manager_new ();
gossip_chatroom_manager_add (manager, chatroom);
- gossip_chatroom_manager_store (manager);
-
chat_window_update_menu (window);
-*/
+
+ g_object_unref (chatroom);
+ g_object_unref (manager);
}
static void
@@ -1597,7 +1598,6 @@ chat_window_drag_data_received (GtkWidget *widget,
GossipChatWindow *old_window;
McAccount *account;
const gchar *id = NULL;
- gchar *chat_id;
if (selection) {
id = (const gchar*) selection->data;
@@ -1615,10 +1615,8 @@ chat_window_drag_data_received (GtkWidget *widget,
}
account = gossip_contact_get_account (contact);
- chat_id = empathy_tp_chat_build_id (account, id);
- chat = gossip_chat_window_find_chat_by_id (chat_id);
+ chat = gossip_chat_window_find_chat (account, id);
old_window = gossip_chat_get_window (chat);
- g_free (chat_id);
if (old_window) {
if (old_window == window) {
@@ -1882,7 +1880,8 @@ gossip_chat_window_has_focus (GossipChatWindow *window)
}
GossipChat *
-gossip_chat_window_find_chat_by_id (const gchar *id)
+gossip_chat_window_find_chat (McAccount *account,
+ const gchar *id)
{
GList *l;
@@ -1899,7 +1898,8 @@ gossip_chat_window_find_chat_by_id (const gchar *id)
chat = ll->data;
- if (strcmp (id, gossip_chat_get_id (chat)) == 0) {
+ if (gossip_account_equal (account, chat->account) &&
+ strcmp (id, gossip_chat_get_id (chat)) == 0) {
return chat;
}
}
diff --git a/libempathy-gtk/gossip-chat-window.h b/libempathy-gtk/gossip-chat-window.h
index 18b06ad90..b58e5dac3 100644
--- a/libempathy-gtk/gossip-chat-window.h
+++ b/libempathy-gtk/gossip-chat-window.h
@@ -30,6 +30,8 @@
#include <glib-object.h>
+#include <libmissioncontrol/mc-account.h>
+
G_BEGIN_DECLS
#define GOSSIP_TYPE_CHAT_WINDOW (gossip_chat_window_get_type ())
@@ -70,7 +72,8 @@ void gossip_chat_window_move_chat (GossipChatWindow *old_wind
void gossip_chat_window_switch_to_chat (GossipChatWindow *window,
GossipChat *chat);
gboolean gossip_chat_window_has_focus (GossipChatWindow *window);
-GossipChat * gossip_chat_window_find_chat_by_id (const gchar *id);
+GossipChat * gossip_chat_window_find_chat (McAccount *account,
+ const gchar *id);
G_END_DECLS
diff --git a/libempathy-gtk/gossip-chat.c b/libempathy-gtk/gossip-chat.c
index 4072b6eae..a29c31818 100644
--- a/libempathy-gtk/gossip-chat.c
+++ b/libempathy-gtk/gossip-chat.c
@@ -228,7 +228,7 @@ gossip_chat_init (GossipChat *chat)
priv = GET_PRIV (chat);
priv->manager = empathy_contact_manager_new ();
- priv->tooltips = gtk_tooltips_new ();
+ priv->tooltips = g_object_ref_sink (gtk_tooltips_new ());
priv->default_window_height = -1;
priv->vscroll_visible = FALSE;
priv->sensitive = TRUE;
@@ -337,6 +337,7 @@ chat_finalize (GObject *object)
chat_composing_remove_timeout (chat);
g_object_unref (chat->account);
g_object_unref (priv->manager);
+ g_object_unref (priv->tooltips);
if (priv->tp_chat) {
g_object_unref (priv->tp_chat);
diff --git a/libempathy-gtk/gossip-chatrooms-window.c b/libempathy-gtk/gossip-chatrooms-window.c
new file mode 100644
index 000000000..5ff5d8812
--- /dev/null
+++ b/libempathy-gtk/gossip-chatrooms-window.c
@@ -0,0 +1,530 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2004-2007 Imendio AB
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ * Martyn Russell <martyn@imendio.com>
+ * Mikael Hallendal <micke@imendio.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <libempathy/gossip-chatroom-manager.h>
+#include <libempathy/gossip-utils.h>
+
+#include "gossip-account-chooser.h"
+#include "gossip-chatrooms-window.h"
+//#include "gossip-edit-chatroom-dialog.h"
+#include "gossip-new-chatroom-dialog.h"
+#include "gossip-ui-utils.h"
+
+typedef struct {
+ GossipChatroomManager *manager;
+
+ GtkWidget *window;
+ GtkWidget *hbox_account;
+ GtkWidget *label_account;
+ GtkWidget *account_chooser;
+ GtkWidget *treeview;
+ GtkWidget *button_remove;
+ GtkWidget *button_edit;
+ GtkWidget *button_close;
+
+ gint room_column;
+} GossipChatroomsWindow;
+
+static void chatrooms_window_destroy_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window);
+static void chatrooms_window_model_setup (GossipChatroomsWindow *window);
+static void chatrooms_window_model_add_columns (GossipChatroomsWindow *window);
+static void chatrooms_window_model_refresh_data (GossipChatroomsWindow *window,
+ gboolean first_time);
+static void chatrooms_window_model_add (GossipChatroomsWindow *window,
+ GossipChatroom *chatroom,
+ gboolean set_active);
+static void chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle *cell,
+ gchar *path_string,
+ GossipChatroomsWindow *window);
+static GossipChatroom * chatrooms_window_model_get_selected (GossipChatroomsWindow *window);
+static void chatrooms_window_model_action_selected (GossipChatroomsWindow *window);
+static void chatrooms_window_row_activated_cb (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GossipChatroomsWindow *window);
+static void chatrooms_window_button_remove_clicked_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window);
+static void chatrooms_window_button_edit_clicked_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window);
+static void chatrooms_window_button_close_clicked_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window);
+static void chatrooms_window_chatroom_added_cb (GossipChatroomManager *manager,
+ GossipChatroom *chatroom,
+ GossipChatroomsWindow *window);
+static void chatrooms_window_account_changed_cb (GtkWidget *combo_box,
+ GossipChatroomsWindow *window);
+
+enum {
+ COL_IMAGE,
+ COL_NAME,
+ COL_ROOM,
+ COL_AUTO_CONNECT,
+ COL_POINTER,
+ COL_COUNT
+};
+
+void
+gossip_chatrooms_window_show (GtkWindow *parent)
+{
+ static GossipChatroomsWindow *window = NULL;
+ GladeXML *glade;
+
+ if (window) {
+ gtk_window_present (GTK_WINDOW (window->window));
+ return;
+ }
+
+ window = g_new0 (GossipChatroomsWindow, 1);
+
+ glade = gossip_glade_get_file ("gossip-chatrooms-window.glade",
+ "chatrooms_window",
+ NULL,
+ "chatrooms_window", &window->window,
+ "hbox_account", &window->hbox_account,
+ "label_account", &window->label_account,
+ "treeview", &window->treeview,
+ "button_edit", &window->button_edit,
+ "button_remove", &window->button_remove,
+ "button_close", &window->button_close,
+ NULL);
+
+ gossip_glade_connect (glade,
+ window,
+ "chatrooms_window", "destroy", chatrooms_window_destroy_cb,
+ "button_remove", "clicked", chatrooms_window_button_remove_clicked_cb,
+ "button_edit", "clicked", chatrooms_window_button_edit_clicked_cb,
+ "button_close", "clicked", chatrooms_window_button_close_clicked_cb,
+ NULL);
+
+ g_object_unref (glade);
+
+ g_object_add_weak_pointer (G_OBJECT (window->window), (gpointer) &window);
+
+ /* Get the session and chat room manager */
+ window->manager = gossip_chatroom_manager_new ();
+
+ g_signal_connect (window->manager, "chatroom-added",
+ G_CALLBACK (chatrooms_window_chatroom_added_cb),
+ window);
+
+ /* Account chooser for chat rooms */
+ window->account_chooser = gossip_account_chooser_new ();
+ gossip_account_chooser_set_account (GOSSIP_ACCOUNT_CHOOSER (window->account_chooser), NULL);
+ g_object_set (window->account_chooser,
+ "can-select-all", TRUE,
+ "has-all-option", TRUE,
+ NULL);
+
+ gtk_box_pack_start (GTK_BOX (window->hbox_account),
+ window->account_chooser,
+ TRUE, TRUE, 0);
+
+ g_signal_connect (window->account_chooser, "changed",
+ G_CALLBACK (chatrooms_window_account_changed_cb),
+ window);
+
+ gtk_widget_show (window->account_chooser);
+
+ /* Set up chatrooms */
+ chatrooms_window_model_setup (window);
+
+ /* Set focus */
+ gtk_widget_grab_focus (window->treeview);
+
+ /* Last touches */
+ if (parent) {
+ gtk_window_set_transient_for (GTK_WINDOW (window->window),
+ GTK_WINDOW (parent));
+ }
+
+ gtk_widget_show (window->window);
+}
+
+static void
+chatrooms_window_destroy_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window)
+{
+ g_object_unref (window->manager);
+ g_free (window);
+}
+
+static void
+chatrooms_window_model_setup (GossipChatroomsWindow *window)
+{
+ GtkTreeView *view;
+ GtkListStore *store;
+ GtkTreeSelection *selection;
+
+ /* View */
+ view = GTK_TREE_VIEW (window->treeview);
+
+ g_signal_connect (view, "row-activated",
+ G_CALLBACK (chatrooms_window_row_activated_cb),
+ window);
+
+ /* Store */
+ store = gtk_list_store_new (COL_COUNT,
+ G_TYPE_STRING, /* Image */
+ G_TYPE_STRING, /* Name */
+ G_TYPE_STRING, /* Room */
+ G_TYPE_BOOLEAN, /* Auto start */
+ GOSSIP_TYPE_CHATROOM); /* Chatroom */
+
+ gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
+
+ /* Selection */
+ selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+
+ /* Columns */
+ chatrooms_window_model_add_columns (window);
+
+ /* Add data */
+ chatrooms_window_model_refresh_data (window, TRUE);
+
+ /* Clean up */
+ g_object_unref (store);
+}
+
+static void
+chatrooms_window_model_add_columns (GossipChatroomsWindow *window)
+{
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell;
+ gint count;
+
+ view = GTK_TREE_VIEW (window->treeview);
+ model = gtk_tree_view_get_model (view);
+
+ gtk_tree_view_set_headers_visible (view, TRUE);
+ gtk_tree_view_set_headers_clickable (view, TRUE);
+
+ /* Name & Status */
+ column = gtk_tree_view_column_new ();
+ count = gtk_tree_view_append_column (view, column);
+
+ gtk_tree_view_column_set_title (column, _("Name"));
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_column_set_sort_column_id (column, count - 1);
+
+ cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, cell, FALSE);
+ gtk_tree_view_column_add_attribute (column, cell, "icon-name", COL_IMAGE);
+
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set (cell,
+ "xpad", 4,
+ "ypad", 1,
+ NULL);
+ gtk_tree_view_column_pack_start (column, cell, TRUE);
+ gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
+
+ /* Room */
+ cell = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Room"), cell,
+ "text", COL_ROOM,
+ NULL);
+ count = gtk_tree_view_append_column (view, column);
+ gtk_tree_view_column_set_sort_column_id (column, count - 1);
+ window->room_column = count - 1;
+
+ /* Chatroom auto connect */
+ cell = gtk_cell_renderer_toggle_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Auto Connect"), cell,
+ "active", COL_AUTO_CONNECT,
+ NULL);
+ count = gtk_tree_view_append_column (view, column);
+ gtk_tree_view_column_set_sort_column_id (column, count - 1);
+
+ g_signal_connect (cell, "toggled",
+ G_CALLBACK (chatrooms_window_model_cell_auto_connect_toggled),
+ window);
+
+ /* Sort model */
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0,
+ GTK_SORT_ASCENDING);
+}
+
+static void
+chatrooms_window_model_refresh_data (GossipChatroomsWindow *window,
+ gboolean first_time)
+{
+ GtkTreeView *view;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreeViewColumn *column;
+ GossipAccountChooser *account_chooser;
+ McAccount *account;
+ GList *chatrooms, *l;
+
+ view = GTK_TREE_VIEW (window->treeview);
+ selection = gtk_tree_view_get_selection (view);
+ model = gtk_tree_view_get_model (view);
+ store = GTK_LIST_STORE (model);
+
+ /* Look up chatrooms */
+ account_chooser = GOSSIP_ACCOUNT_CHOOSER (window->account_chooser);
+ account = gossip_account_chooser_get_account (account_chooser);
+
+ chatrooms = gossip_chatroom_manager_get_chatrooms (window->manager, account);
+
+ /* Sort out columns, we only show the server column for
+ * selected protocol types, such as Jabber.
+ */
+ if (account) {
+ column = gtk_tree_view_get_column (view, window->room_column);
+ gtk_tree_view_column_set_visible (column, TRUE);
+ } else {
+ column = gtk_tree_view_get_column (view, window->room_column);
+ gtk_tree_view_column_set_visible (column, FALSE);
+ }
+
+ /* Clean out the store */
+ gtk_list_store_clear (store);
+
+ /* Populate with chatroom list. */
+ for (l = chatrooms; l; l = l->next) {
+ chatrooms_window_model_add (window, l->data, FALSE);
+ }
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+
+ if (account) {
+ g_object_unref (account);
+ }
+
+ g_list_free (chatrooms);
+}
+
+static void
+chatrooms_window_model_add (GossipChatroomsWindow *window,
+ GossipChatroom *chatroom,
+ gboolean set_active)
+{
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkListStore *store;
+ GtkTreeIter iter;
+
+ view = GTK_TREE_VIEW (window->treeview);
+ selection = gtk_tree_view_get_selection (view);
+ model = gtk_tree_view_get_model (view);
+ store = GTK_LIST_STORE (model);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_NAME, gossip_chatroom_get_name (chatroom),
+ COL_ROOM, gossip_chatroom_get_room (chatroom),
+ COL_AUTO_CONNECT, gossip_chatroom_get_auto_connect (chatroom),
+ COL_POINTER, chatroom,
+ -1);
+
+ if (set_active) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+}
+
+static void
+chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle *cell,
+ gchar *path_string,
+ GossipChatroomsWindow *window)
+{
+ GossipChatroom *chatroom;
+ gboolean enabled;
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ view = GTK_TREE_VIEW (window->treeview);
+ model = gtk_tree_view_get_model (view);
+ store = GTK_LIST_STORE (model);
+
+ path = gtk_tree_path_new_from_string (path_string);
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
+ COL_AUTO_CONNECT, &enabled,
+ COL_POINTER, &chatroom,
+ -1);
+
+ enabled = !enabled;
+
+ gossip_chatroom_set_auto_connect (chatroom, enabled);
+ gossip_chatroom_manager_store (window->manager);
+
+ gtk_list_store_set (store, &iter, COL_AUTO_CONNECT, enabled, -1);
+ gtk_tree_path_free (path);
+ g_object_unref (chatroom);
+}
+
+static GossipChatroom *
+chatrooms_window_model_get_selected (GossipChatroomsWindow *window)
+{
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GossipChatroom *chatroom = NULL;
+
+ view = GTK_TREE_VIEW (window->treeview);
+ selection = gtk_tree_view_get_selection (view);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
+ }
+
+ return chatroom;
+}
+
+static void
+chatrooms_window_model_action_selected (GossipChatroomsWindow *window)
+{
+ GossipChatroom *chatroom;
+ GtkTreeView *view;
+ GtkTreeModel *model;
+
+ view = GTK_TREE_VIEW (window->treeview);
+ model = gtk_tree_view_get_model (view);
+
+ chatroom = chatrooms_window_model_get_selected (window);
+ if (!chatroom) {
+ return;
+ }
+
+ //gossip_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom);
+
+ g_object_unref (chatroom);
+}
+
+static void
+chatrooms_window_row_activated_cb (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GossipChatroomsWindow *window)
+{
+ if (GTK_WIDGET_IS_SENSITIVE (window->button_edit)) {
+ chatrooms_window_model_action_selected (window);
+ }
+}
+
+static void
+chatrooms_window_button_remove_clicked_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window)
+{
+ GossipChatroom *chatroom;
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ /* Remove from treeview */
+ view = GTK_TREE_VIEW (window->treeview);
+ selection = gtk_tree_view_get_selection (view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+
+ /* Remove from config */
+ gossip_chatroom_manager_remove (window->manager, chatroom);
+
+ g_object_unref (chatroom);
+}
+
+static void
+chatrooms_window_button_edit_clicked_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window)
+{
+ GossipChatroom *chatroom;
+
+ chatroom = chatrooms_window_model_get_selected (window);
+ if (!chatroom) {
+ return;
+ }
+
+ //gossip_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom);
+
+ g_object_unref (chatroom);
+}
+
+static void
+chatrooms_window_button_close_clicked_cb (GtkWidget *widget,
+ GossipChatroomsWindow *window)
+{
+ gtk_widget_destroy (window->window);
+}
+
+static void
+chatrooms_window_chatroom_added_cb (GossipChatroomManager *manager,
+ GossipChatroom *chatroom,
+ GossipChatroomsWindow *window)
+{
+ GossipAccountChooser *account_chooser;
+ McAccount *account;
+
+ account_chooser = GOSSIP_ACCOUNT_CHOOSER (window->account_chooser);
+ account = gossip_account_chooser_get_account (account_chooser);
+
+ if (!account) {
+ chatrooms_window_model_add (window, chatroom, FALSE);
+ } else {
+ if (gossip_account_equal (account, gossip_chatroom_get_account (chatroom))) {
+ chatrooms_window_model_add (window, chatroom, FALSE);
+ }
+
+ g_object_unref (account);
+ }
+}
+
+static void
+chatrooms_window_account_changed_cb (GtkWidget *combo_box,
+ GossipChatroomsWindow *window)
+{
+ chatrooms_window_model_refresh_data (window, FALSE);
+}
+
diff --git a/libempathy-gtk/gossip-chatrooms-window.glade b/libempathy-gtk/gossip-chatrooms-window.glade
new file mode 100644
index 000000000..ad2971e00
--- /dev/null
+++ b/libempathy-gtk/gossip-chatrooms-window.glade
@@ -0,0 +1,477 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="edit_chatroom_dialog">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Edit Favorite Room</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="icon_name">gtk-edit</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area3">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button_save">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-save</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table4">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+
+ <child>
+ <widget class="GtkEntry" id="entry_room">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_server">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_nickname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label_room">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Room:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">entry_room</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label_server">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_erver:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">entry_server</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label_nickname">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Nickname:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">entry_nickname</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label_name">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">N_ame:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">entry_name</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">*</property>
+ <property name="activates_default">False</property>
+ <property name="width_chars">25</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="checkbutton_auto_connect">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Join this chat room when Gossip starts and you are connected</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Join room on start_up</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkWindow" id="chatrooms_window">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Manage Favorite Rooms</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox12">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox18">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">18</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox_account">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkLabel" id="label_account">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Account:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="height_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHButtonBox" id="hbuttonbox3">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkButton" id="button_close">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button_remove">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button_edit">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-edit</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/libempathy-gtk/gossip-chatrooms-window.h b/libempathy-gtk/gossip-chatrooms-window.h
new file mode 100644
index 000000000..d1314ec29
--- /dev/null
+++ b/libempathy-gtk/gossip-chatrooms-window.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2004-2007 Imendio AB
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ * Martyn Russell <martyn@imendio.com>
+ * Mikael Hallendal <micke@imendio.com>
+ */
+
+#ifndef __GOSSIP_CHATROOMS_WINDOW_H__
+#define __GOSSIP_CHATROOMS_WINDOW_H__
+
+G_BEGIN_DECLS
+
+void gossip_chatrooms_window_show (GtkWindow *parent);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_CHATROOMS_WINDOW_H__ */
diff --git a/libempathy-gtk/gossip-preferences.c b/libempathy-gtk/gossip-preferences.c
index 52c4a804c..fd93353df 100644
--- a/libempathy-gtk/gossip-preferences.c
+++ b/libempathy-gtk/gossip-preferences.c
@@ -914,7 +914,7 @@ preferences_destroy_cb (GtkWidget *widget,
}
GtkWidget *
-gossip_preferences_show (void)
+gossip_preferences_show (GtkWindow *parent)
{
static GossipPreferences *preferences;
GladeXML *glade;
@@ -973,6 +973,11 @@ gossip_preferences_show (void)
gtk_widget_show (page);
}
+ if (parent) {
+ gtk_window_set_transient_for (GTK_WINDOW (preferences->dialog),
+ GTK_WINDOW (parent));
+ }
+
gtk_widget_show (preferences->dialog);
return preferences->dialog;
diff --git a/libempathy-gtk/gossip-preferences.h b/libempathy-gtk/gossip-preferences.h
index 74ecc9041..35b26621f 100644
--- a/libempathy-gtk/gossip-preferences.h
+++ b/libempathy-gtk/gossip-preferences.h
@@ -25,7 +25,7 @@
#ifndef __GOSSIP_PREFERENCES_H__
#define __GOSSIP_PREFERENCES_H__
-#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
G_BEGIN_DECLS
@@ -49,7 +49,7 @@ G_BEGIN_DECLS
#define GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM GOSSIP_PREFS_PATH "/contacts/sort_criterium"
#define GOSSIP_PREFS_HINTS_CLOSE_MAIN_WINDOW GOSSIP_PREFS_PATH "/hints/close_main_window"
-GtkWidget * gossip_preferences_show (void);
+GtkWidget * gossip_preferences_show (GtkWindow *parent);
G_END_DECLS
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am
index 684d4e64b..2b1d75ecf 100644
--- a/libempathy/Makefile.am
+++ b/libempathy/Makefile.am
@@ -24,6 +24,8 @@ libempathy_la_SOURCES = \
gossip-debug.c gossip-debug.h \
gossip-utils.c gossip-utils.h \
gossip-message.c gossip-message.h \
+ gossip-chatroom-manager.c gossip-chatroom-manager.h \
+ gossip-chatroom.c gossip-chatroom.h \
empathy-contact-list.c empathy-contact-list.h \
empathy-contact-manager.c empathy-contact-manager.h \
empathy-tp-contact-list.c empathy-tp-contact-list.h \
@@ -49,8 +51,13 @@ libempathy_includedir = $(includedir)/empathy/
empathy-chandler-glue.h: empathy-chandler.xml
$(LIBTOOL) --mode=execute $(DBUS_BINDING_TOOL) --prefix=empathy_chandler --mode=glib-server --output=$@ $<
+dtddir = $(datadir)/empathy
+dtd_DATA = \
+ gossip-chatroom-manager.dtd
+
EXTRA_DIST = \
empathy-marshal.list \
- empathy-chandler.xml
+ empathy-chandler.xml \
+ $(dtd_DATA)
CLEANFILES = $(BUILT_SOURCES)
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 3c4f55423..ed6a49323 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -488,65 +488,11 @@ empathy_tp_chat_get_id (EmpathyTpChat *chat)
return priv->id;
}
- priv->id = empathy_tp_chat_build_id_for_chan (priv->account, priv->tp_chan);
+ priv->id = gossip_get_channel_id (priv->account, priv->tp_chan);
return priv->id;
}
-gchar *
-empathy_tp_chat_build_id (McAccount *account,
- const gchar *contact_id)
-{
- /* A handle name is unique only for a specific account */
- return g_strdup_printf ("%s/%s",
- mc_account_get_unique_name (account),
- contact_id);
-}
-
-gchar *
-empathy_tp_chat_build_id_for_chan (McAccount *account,
- TpChan *tp_chan)
-{
- MissionControl *mc;
- TpConn *tp_conn;
- GArray *handles;
- gchar **names;
- gchar *id;
- GError *error = NULL;
-
- g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
- g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
-
- mc = gossip_mission_control_new ();
- tp_conn = mission_control_get_connection (mc, account, NULL);
- g_object_unref (mc);
-
- /* Get the handle's name */
- handles = g_array_new (FALSE, FALSE, sizeof (guint));
- g_array_append_val (handles, tp_chan->handle);
- if (!tp_conn_inspect_handles (DBUS_G_PROXY (tp_conn),
- tp_chan->handle_type,
- handles,
- &names,
- &error)) {
- gossip_debug (DEBUG_DOMAIN,
- "Couldn't get id: %s",
- error ? error->message : "No error given");
- g_clear_error (&error);
- g_array_free (handles, TRUE);
- g_object_unref (tp_conn);
-
- return NULL;
- }
-
- id = empathy_tp_chat_build_id (account, *names);
-
- g_strfreev (names);
- g_object_unref (tp_conn);
-
- return id;
-}
-
static void
tp_chat_destroy_cb (TpChan *text_chan,
EmpathyTpChat *chat)
diff --git a/libempathy/empathy-tp-chat.h b/libempathy/empathy-tp-chat.h
index a9278c3f1..55bbfcd3d 100644
--- a/libempathy/empathy-tp-chat.h
+++ b/libempathy/empathy-tp-chat.h
@@ -65,10 +65,6 @@ void empathy_tp_chat_send (EmpathyTpChat *
void empathy_tp_chat_set_state (EmpathyTpChat *chat,
TelepathyChannelChatState state);
const gchar * empathy_tp_chat_get_id (EmpathyTpChat *chat);
-gchar * empathy_tp_chat_build_id (McAccount *account,
- const gchar *contact_id);
-gchar * empathy_tp_chat_build_id_for_chan (McAccount *account,
- TpChan *tp_chan);
G_END_DECLS
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index 64bec75ff..6af5ed064 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -641,6 +641,7 @@ empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list,
}
if (new_handles->len == 0) {
+ g_array_free (new_handles, TRUE);
return contacts;
}
@@ -1448,6 +1449,7 @@ tp_contact_list_group_members_added_cb (GossipTelepathyGroup *group,
contact = GOSSIP_CONTACT (l->data);
contact_groups = gossip_contact_get_groups (contact);
+ /* FIXME: this leaks */
if (!g_list_find_custom (contact_groups,
group_name,
(GCompareFunc) strcmp)) {
@@ -1663,6 +1665,7 @@ tp_contact_list_request_avatar_cb (DBusGProxy *proxy,
n_avatar_requests--;
tp_contact_list_start_avatar_requests (data->list);
+ g_object_unref (contact);
g_slice_free (TpContactListAvatarRequestData, data);
}
@@ -1699,6 +1702,7 @@ tp_contact_list_aliases_update_cb (DBusGProxy *proxy,
tp_contact_list_block_contact (list, contact);
gossip_contact_set_name (contact, alias);
tp_contact_list_unblock_contact (list, contact);
+ g_object_unref (contact);
gossip_debug (DEBUG_DOMAIN, "contact %d renamed to %s (update cb)",
handle, alias);
@@ -1727,6 +1731,7 @@ tp_contact_list_request_aliases_cb (DBusGProxy *proxy,
tp_contact_list_block_contact (data->list, contact);
gossip_contact_set_name (contact, *name);
tp_contact_list_unblock_contact (data->list, contact);
+ g_object_unref (contact);
gossip_debug (DEBUG_DOMAIN, "contact %d renamed to %s (request cb)",
data->handles[i], *name);
@@ -1781,6 +1786,8 @@ tp_contact_list_parse_presence_foreach (guint handle,
tp_contact_list_block_contact (list, contact);
gossip_contact_set_presence (contact, presence);
tp_contact_list_unblock_contact (list, contact);
+
+ g_object_unref (contact);
}
static void
diff --git a/libempathy/gossip-chatroom-manager.c b/libempathy/gossip-chatroom-manager.c
new file mode 100644
index 000000000..ade0b0ba0
--- /dev/null
+++ b/libempathy/gossip-chatroom-manager.c
@@ -0,0 +1,500 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2004-2007 Imendio AB
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ * Martyn Russell <martyn@imendio.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include "gossip-debug.h"
+#include "gossip-chatroom-manager.h"
+#include "gossip-utils.h"
+
+#define DEBUG_DOMAIN "ChatroomManager"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CHATROOM_MANAGER, GossipChatroomManagerPriv))
+
+#define CHATROOMS_XML_FILENAME "chatrooms.xml"
+#define CHATROOMS_DTD_FILENAME "gossip-chatroom-manager.dtd"
+
+struct _GossipChatroomManagerPriv {
+ GList *chatrooms;
+};
+
+static void gossip_chatroom_manager_class_init (GossipChatroomManagerClass *klass);
+static void gossip_chatroom_manager_init (GossipChatroomManager *manager);
+static void chatroom_manager_finalize (GObject *object);
+static gboolean chatroom_manager_get_all (GossipChatroomManager *manager);
+static gboolean chatroom_manager_file_parse (GossipChatroomManager *manager,
+ const gchar *filename);
+static void chatroom_manager_parse_chatroom (GossipChatroomManager *manager,
+ xmlNodePtr node);
+static gboolean chatroom_manager_file_save (GossipChatroomManager *manager);
+
+enum {
+ CHATROOM_ADDED,
+ CHATROOM_REMOVED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (GossipChatroomManager, gossip_chatroom_manager, G_TYPE_OBJECT);
+
+static void
+gossip_chatroom_manager_class_init (GossipChatroomManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = chatroom_manager_finalize;
+
+ signals[CHATROOM_ADDED] =
+ g_signal_new ("chatroom-added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, GOSSIP_TYPE_CHATROOM);
+ signals[CHATROOM_REMOVED] =
+ g_signal_new ("chatroom-removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, GOSSIP_TYPE_CHATROOM);
+
+ g_type_class_add_private (object_class,
+ sizeof (GossipChatroomManagerPriv));
+}
+
+static void
+gossip_chatroom_manager_init (GossipChatroomManager *manager)
+{
+}
+
+static void
+chatroom_manager_finalize (GObject *object)
+{
+ GossipChatroomManagerPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ g_list_foreach (priv->chatrooms, (GFunc) g_object_unref, NULL);
+ g_list_free (priv->chatrooms);
+
+ (G_OBJECT_CLASS (gossip_chatroom_manager_parent_class)->finalize) (object);
+}
+
+GossipChatroomManager *
+gossip_chatroom_manager_new (void)
+{
+ static GossipChatroomManager *manager = NULL;
+
+ if (!manager) {
+ GossipChatroomManagerPriv *priv;
+
+ manager = g_object_new (GOSSIP_TYPE_CHATROOM_MANAGER, NULL);
+ priv = GET_PRIV (manager);
+ chatroom_manager_get_all (manager);
+
+ g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager);
+ } else {
+ g_object_ref (manager);
+ }
+
+ return manager;
+}
+
+gboolean
+gossip_chatroom_manager_add (GossipChatroomManager *manager,
+ GossipChatroom *chatroom)
+{
+ GossipChatroomManagerPriv *priv;
+
+ 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_account (chatroom),
+ gossip_chatroom_get_room (chatroom))) {
+ priv->chatrooms = g_list_append (priv->chatrooms, g_object_ref (chatroom));
+ chatroom_manager_file_save (manager);
+
+ g_signal_emit (manager, signals[CHATROOM_ADDED], 0, chatroom);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+gossip_chatroom_manager_remove (GossipChatroomManager *manager,
+ GossipChatroom *chatroom)
+{
+ GossipChatroomManagerPriv *priv;
+ GList *l;
+
+ g_return_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager));
+ g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
+
+ priv = GET_PRIV (manager);
+
+ for (l = priv->chatrooms; l; l = l->next) {
+ GossipChatroom *this_chatroom;
+
+ this_chatroom = l->data;
+
+ if (gossip_chatroom_equal (chatroom, this_chatroom)) {
+ priv->chatrooms = g_list_delete_link (priv->chatrooms, l);
+
+ chatroom_manager_file_save (manager);
+
+ g_signal_emit (manager, signals[CHATROOM_REMOVED], 0, this_chatroom);
+ g_object_unref (this_chatroom);
+ break;
+ }
+ }
+}
+
+GossipChatroom *
+gossip_chatroom_manager_find (GossipChatroomManager *manager,
+ McAccount *account,
+ const gchar *room)
+{
+ GossipChatroomManagerPriv *priv;
+ GList *l;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager), NULL);
+ g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (room != NULL, NULL);
+
+ priv = GET_PRIV (manager);
+
+ for (l = priv->chatrooms; l; l = l->next) {
+ GossipChatroom *chatroom;
+ McAccount *this_account;
+ const gchar *this_room;
+
+ chatroom = l->data;
+ this_account = gossip_chatroom_get_account (chatroom);
+ this_room = gossip_chatroom_get_room (chatroom);
+
+ if (gossip_account_equal (account, this_account) &&
+ strcmp (this_room, room) == 0) {
+ return chatroom;
+ }
+ }
+
+ return NULL;
+}
+
+GList *
+gossip_chatroom_manager_get_chatrooms (GossipChatroomManager *manager,
+ McAccount *account)
+{
+ GossipChatroomManagerPriv *priv;
+ GList *chatrooms, *l;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager), NULL);
+
+ priv = GET_PRIV (manager);
+
+ if (!account) {
+ return g_list_copy (priv->chatrooms);
+ }
+
+ chatrooms = NULL;
+ for (l = priv->chatrooms; l; l = l->next) {
+ GossipChatroom *chatroom;
+
+ chatroom = l->data;
+
+ if (gossip_account_equal (account,
+ gossip_chatroom_get_account (chatroom))) {
+ chatrooms = g_list_append (chatrooms, chatroom);
+ }
+ }
+
+ return chatrooms;
+}
+
+guint
+gossip_chatroom_manager_get_count (GossipChatroomManager *manager,
+ McAccount *account)
+{
+ GossipChatroomManagerPriv *priv;
+ GList *l;
+ guint count = 0;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager), 0);
+
+ priv = GET_PRIV (manager);
+
+ if (!account) {
+ return g_list_length (priv->chatrooms);
+ }
+
+ for (l = priv->chatrooms; l; l = l->next) {
+ GossipChatroom *chatroom;
+
+ chatroom = l->data;
+
+ if (gossip_account_equal (account,
+ gossip_chatroom_get_account (chatroom))) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+void
+gossip_chatroom_manager_store (GossipChatroomManager *manager)
+{
+ g_return_if_fail (GOSSIP_IS_CHATROOM_MANAGER (manager));
+
+ chatroom_manager_file_save (manager);
+}
+
+/*
+ * API to save/load and parse the chatrooms file.
+ */
+
+static gboolean
+chatroom_manager_get_all (GossipChatroomManager *manager)
+{
+ GossipChatroomManagerPriv *priv;
+ gchar *dir;
+ gchar *file_with_path = NULL;
+
+ priv = GET_PRIV (manager);
+
+ dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
+ if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+ g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ }
+
+ file_with_path = g_build_filename (dir, CHATROOMS_XML_FILENAME, NULL);
+ g_free (dir);
+
+ /* read file in */
+ if (g_file_test (file_with_path, G_FILE_TEST_EXISTS) &&
+ !chatroom_manager_file_parse (manager, file_with_path)) {
+ g_free (file_with_path);
+ return FALSE;
+ }
+
+ g_free (file_with_path);
+
+ return TRUE;
+}
+
+static gboolean
+chatroom_manager_file_parse (GossipChatroomManager *manager,
+ const gchar *filename)
+{
+ GossipChatroomManagerPriv *priv;
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc;
+ xmlNodePtr chatrooms;
+ xmlNodePtr node;
+
+ priv = GET_PRIV (manager);
+
+ gossip_debug (DEBUG_DOMAIN, "Attempting to parse file:'%s'...", filename);
+
+ ctxt = xmlNewParserCtxt ();
+
+ /* Parse and validate the file. */
+ doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
+ if (!doc) {
+ g_warning ("Failed to parse file:'%s'", filename);
+ xmlFreeParserCtxt (ctxt);
+ return FALSE;
+ }
+
+ if (!gossip_xml_validate (doc, CHATROOMS_DTD_FILENAME)) {
+ g_warning ("Failed to validate file:'%s'", filename);
+ xmlFreeDoc(doc);
+ xmlFreeParserCtxt (ctxt);
+ return FALSE;
+ }
+
+ /* The root node, chatrooms. */
+ chatrooms = xmlDocGetRootElement (doc);
+
+ for (node = chatrooms->children; node; node = node->next) {
+ if (strcmp ((gchar *) node->name, "chatroom") == 0) {
+ chatroom_manager_parse_chatroom (manager, node);
+ }
+ }
+
+ gossip_debug (DEBUG_DOMAIN,
+ "Parsed %d chatrooms",
+ g_list_length (priv->chatrooms));
+
+ xmlFreeDoc(doc);
+ xmlFreeParserCtxt (ctxt);
+
+ return TRUE;
+}
+
+static void
+chatroom_manager_parse_chatroom (GossipChatroomManager *manager,
+ xmlNodePtr node)
+{
+ GossipChatroomManagerPriv *priv;
+ GossipChatroom *chatroom;
+ McAccount *account;
+ xmlNodePtr child;
+ gchar *str;
+ gchar *name;
+ gchar *room;
+ gchar *account_id;
+ gboolean auto_connect;
+
+ priv = GET_PRIV (manager);
+
+ /* default values. */
+ name = NULL;
+ room = NULL;
+ auto_connect = TRUE;
+ account_id = NULL;
+
+ for (child = node->children; child; child = child->next) {
+ gchar *tag;
+
+ if (xmlNodeIsText (child)) {
+ continue;
+ }
+
+ tag = (gchar *) child->name;
+ str = (gchar *) xmlNodeGetContent (child);
+
+ if (strcmp (tag, "name") == 0) {
+ name = g_strdup (str);
+ }
+ else if (strcmp (tag, "room") == 0) {
+ room = g_strdup (str);
+ }
+ else if (strcmp (tag, "auto_connect") == 0) {
+ if (strcmp (str, "yes") == 0) {
+ auto_connect = TRUE;
+ } else {
+ auto_connect = FALSE;
+ }
+ }
+ else if (strcmp (tag, "account") == 0) {
+ account_id = g_strdup (str);
+ }
+
+ xmlFree (str);
+ }
+
+ account = mc_account_lookup (account_id);
+ if (!account) {
+ g_free (name);
+ g_free (room);
+ g_free (account_id);
+ return;
+ }
+
+ chatroom = gossip_chatroom_new_full (account,
+ room,
+ name,
+ auto_connect);
+
+ priv->chatrooms = g_list_prepend (priv->chatrooms, chatroom);
+
+ g_object_unref (account);
+ g_free (name);
+ g_free (room);
+ g_free (account_id);
+}
+
+static gboolean
+chatroom_manager_file_save (GossipChatroomManager *manager)
+{
+ GossipChatroomManagerPriv *priv;
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ GList *l;
+ gchar *dir;
+ gchar *file;
+
+ priv = GET_PRIV (manager);
+
+ dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
+ if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+ g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ }
+
+ file = g_build_filename (dir, CHATROOMS_XML_FILENAME, NULL);
+ g_free (dir);
+
+ doc = xmlNewDoc ("1.0");
+ root = xmlNewNode (NULL, "chatrooms");
+ xmlDocSetRootElement (doc, root);
+
+ for (l = priv->chatrooms; l; l = l->next) {
+ GossipChatroom *chatroom;
+ xmlNodePtr node;
+ const gchar *account_id;
+
+ chatroom = l->data;
+ account_id = mc_account_get_unique_name (gossip_chatroom_get_account (chatroom));
+
+ node = xmlNewChild (root, NULL, "chatroom", NULL);
+ xmlNewTextChild (node, NULL, "name", gossip_chatroom_get_name (chatroom));
+ xmlNewTextChild (node, NULL, "room", gossip_chatroom_get_room (chatroom));
+ xmlNewTextChild (node, NULL, "account", account_id);
+ xmlNewTextChild (node, NULL, "auto_connect", gossip_chatroom_get_auto_connect (chatroom) ? "yes" : "no");
+ }
+
+ /* Make sure the XML is indented properly */
+ xmlIndentTreeOutput = 1;
+
+ gossip_debug (DEBUG_DOMAIN, "Saving file:'%s'", file);
+ xmlSaveFormatFileEnc (file, doc, "utf-8", 1);
+ xmlFreeDoc (doc);
+
+ xmlCleanupParser ();
+ xmlMemoryDump ();
+
+ g_free (file);
+
+ return TRUE;
+}
diff --git a/libempathy/gossip-chatroom-manager.dtd b/libempathy/gossip-chatroom-manager.dtd
new file mode 100644
index 000000000..5d94a57c2
--- /dev/null
+++ b/libempathy/gossip-chatroom-manager.dtd
@@ -0,0 +1,17 @@
+<!--
+ DTD for Gossips Chat Rooms.
+ by Martyn Russell <martyn@imendio.com>
+ v0.2
+-->
+
+<!-- Root element. -->
+<!ELEMENT chatrooms (chatroom*)>
+
+<!ELEMENT chatroom
+ (name,room,account,(auto_connect?))>
+
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT room (#PCDATA)>
+<!ELEMENT auto_connect (#PCDATA)>
+<!ELEMENT account (#PCDATA)>
+
diff --git a/libempathy/gossip-chatroom-manager.h b/libempathy/gossip-chatroom-manager.h
new file mode 100644
index 000000000..7d10a0fc1
--- /dev/null
+++ b/libempathy/gossip-chatroom-manager.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2004-2007 Imendio AB
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ * Martyn Russell <martyn@imendio.com>
+ */
+
+#ifndef __GOSSIP_CHATROOM_MANAGER_H__
+#define __GOSSIP_CHATROOM_MANAGER_H__
+
+#include <glib-object.h>
+
+#include <libmissioncontrol/mc-account.h>
+
+#include "gossip-chatroom.h"
+
+G_BEGIN_DECLS
+
+#define GOSSIP_TYPE_CHATROOM_MANAGER (gossip_chatroom_manager_get_type ())
+#define GOSSIP_CHATROOM_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_CHATROOM_MANAGER, GossipChatroomManager))
+#define GOSSIP_CHATROOM_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOSSIP_TYPE_CHATROOM_MANAGER, GossipChatroomManagerClass))
+#define GOSSIP_IS_CHATROOM_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOSSIP_TYPE_CHATROOM_MANAGER))
+#define GOSSIP_IS_CHATROOM_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOSSIP_TYPE_CHATROOM_MANAGER))
+#define GOSSIP_CHATROOM_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOSSIP_TYPE_CHATROOM_MANAGER, GossipChatroomManagerClass))
+
+typedef struct _GossipChatroomManager GossipChatroomManager;
+typedef struct _GossipChatroomManagerClass GossipChatroomManagerClass;
+typedef struct _GossipChatroomManagerPriv GossipChatroomManagerPriv;
+
+struct _GossipChatroomManager {
+ GObject parent;
+};
+
+struct _GossipChatroomManagerClass {
+ GObjectClass parent_class;
+};
+
+GType gossip_chatroom_manager_get_type (void) G_GNUC_CONST;
+GossipChatroomManager *gossip_chatroom_manager_new (void);
+gboolean gossip_chatroom_manager_add (GossipChatroomManager *manager,
+ GossipChatroom *chatroom);
+void gossip_chatroom_manager_remove (GossipChatroomManager *manager,
+ GossipChatroom *chatroom);
+GossipChatroom * gossip_chatroom_manager_find (GossipChatroomManager *manager,
+ McAccount *account,
+ const gchar *room);
+GList * gossip_chatroom_manager_get_chatrooms (GossipChatroomManager *manager,
+ McAccount *account);
+guint gossip_chatroom_manager_get_count (GossipChatroomManager *manager,
+ McAccount *account);
+void gossip_chatroom_manager_store (GossipChatroomManager *manager);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_CHATROOM_MANAGER_H__ */
diff --git a/libempathy/gossip-chatroom.c b/libempathy/gossip-chatroom.c
new file mode 100644
index 000000000..eccd2824c
--- /dev/null
+++ b/libempathy/gossip-chatroom.c
@@ -0,0 +1,360 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "gossip-chatroom.h"
+#include "gossip-utils.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CHATROOM, GossipChatroomPriv))
+
+struct _GossipChatroomPriv {
+ McAccount *account;
+ gchar *room;
+ gchar *name;
+ gboolean auto_connect;
+};
+
+static void gossip_chatroom_class_init (GossipChatroomClass *klass);
+static void gossip_chatroom_init (GossipChatroom *chatroom);
+static void chatroom_finalize (GObject *object);
+static void chatroom_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void chatroom_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT,
+ PROP_ROOM,
+ PROP_NAME,
+ PROP_AUTO_CONNECT,
+};
+
+G_DEFINE_TYPE (GossipChatroom, gossip_chatroom, G_TYPE_OBJECT);
+
+static void
+gossip_chatroom_class_init (GossipChatroomClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = chatroom_finalize;
+ object_class->get_property = chatroom_get_property;
+ 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",
+ MC_TYPE_ACCOUNT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_ROOM,
+ g_param_spec_string ("room",
+ "Chatroom Room",
+ "Chatroom represented as 'room@server'",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ "Chatroom Name",
+ "Chatroom name",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_AUTO_CONNECT,
+ g_param_spec_boolean ("auto_connect",
+ "Chatroom Auto Connect",
+ "Connect on startup",
+ FALSE,
+ G_PARAM_READWRITE));
+
+
+ g_type_class_add_private (object_class, sizeof (GossipChatroomPriv));
+}
+
+static void
+gossip_chatroom_init (GossipChatroom *chatroom)
+{
+}
+
+static void
+chatroom_finalize (GObject *object)
+{
+ GossipChatroomPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ g_object_unref (priv->account);
+ g_free (priv->room);
+ g_free (priv->name);
+
+ (G_OBJECT_CLASS (gossip_chatroom_parent_class)->finalize) (object);
+}
+
+static void
+chatroom_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GossipChatroomPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_ACCOUNT:
+ g_value_set_object (value, priv->account);
+ break;
+ case PROP_ROOM:
+ g_value_set_string (value, priv->room);
+ break;
+ case PROP_NAME:
+ g_value_set_string (value, priv->name);
+ break;
+ case PROP_AUTO_CONNECT:
+ g_value_set_boolean (value, priv->auto_connect);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+static void
+chatroom_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GossipChatroomPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_ACCOUNT:
+ gossip_chatroom_set_account (GOSSIP_CHATROOM (object),
+ g_value_get_object (value));
+ break;
+ case PROP_ROOM:
+ gossip_chatroom_set_room (GOSSIP_CHATROOM (object),
+ g_value_get_string (value));
+ break;
+ case PROP_NAME:
+ gossip_chatroom_set_name (GOSSIP_CHATROOM (object),
+ g_value_get_string (value));
+ break;
+ case PROP_AUTO_CONNECT:
+ gossip_chatroom_set_auto_connect (GOSSIP_CHATROOM (object),
+ g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+GossipChatroom *
+gossip_chatroom_new (McAccount *account,
+ const gchar *room)
+{
+ g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (room != NULL, NULL);
+
+ return g_object_new (GOSSIP_TYPE_CHATROOM,
+ "account", account,
+ "room", room,
+ NULL);
+}
+
+GossipChatroom *
+gossip_chatroom_new_full (McAccount *account,
+ const gchar *room,
+ const gchar *name,
+ gboolean auto_connect)
+{
+ g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (room != NULL, NULL);
+
+ return g_object_new (GOSSIP_TYPE_CHATROOM,
+ "account", account,
+ "room", room,
+ "name", name,
+ "auto_connect", auto_connect,
+ NULL);
+}
+
+McAccount *
+gossip_chatroom_get_account (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
+
+ priv = GET_PRIV (chatroom);
+ return priv->account;
+}
+
+void
+gossip_chatroom_set_account (GossipChatroom *chatroom,
+ McAccount *account)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
+ g_return_if_fail (MC_IS_ACCOUNT (account));
+
+ priv = GET_PRIV (chatroom);
+
+ if (account == priv->account) {
+ return;
+ }
+ if (priv->account) {
+ g_object_unref (priv->account);
+ }
+ priv->account = g_object_ref (account);
+
+ g_object_notify (G_OBJECT (chatroom), "account");
+}
+
+const gchar *
+gossip_chatroom_get_room (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
+
+ priv = GET_PRIV (chatroom);
+ return priv->room;
+}
+
+void
+gossip_chatroom_set_room (GossipChatroom *chatroom,
+ const gchar *room)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
+ g_return_if_fail (room != NULL);
+
+ priv = GET_PRIV (chatroom);
+
+ g_free (priv->room);
+ priv->room = g_strdup (room);
+
+ g_object_notify (G_OBJECT (chatroom), "room");
+}
+
+const gchar *
+gossip_chatroom_get_name (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), NULL);
+
+ priv = GET_PRIV (chatroom);
+
+ if (G_STR_EMPTY (priv->name)) {
+ return priv->room;
+ }
+
+ return priv->name;
+}
+
+void
+gossip_chatroom_set_name (GossipChatroom *chatroom,
+ const gchar *name)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
+ g_return_if_fail (name != NULL);
+
+ priv = GET_PRIV (chatroom);
+
+ g_free (priv->name);
+ priv->name = g_strdup (name);
+
+ g_object_notify (G_OBJECT (chatroom), "name");
+}
+
+gboolean
+gossip_chatroom_get_auto_connect (GossipChatroom *chatroom)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (chatroom), FALSE);
+
+ priv = GET_PRIV (chatroom);
+ return priv->auto_connect;
+}
+
+void
+gossip_chatroom_set_auto_connect (GossipChatroom *chatroom,
+ gboolean auto_connect)
+{
+ GossipChatroomPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CHATROOM (chatroom));
+
+ priv = GET_PRIV (chatroom);
+
+ priv->auto_connect = auto_connect;
+
+ g_object_notify (G_OBJECT (chatroom), "auto-connect");
+}
+
+gboolean
+gossip_chatroom_equal (gconstpointer v1,
+ gconstpointer v2)
+{
+ McAccount *account_a;
+ McAccount *account_b;
+ const gchar *room_a;
+ const gchar *room_b;
+
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (v1), FALSE);
+ g_return_val_if_fail (GOSSIP_IS_CHATROOM (v2), FALSE);
+
+ account_a = gossip_chatroom_get_account (GOSSIP_CHATROOM (v1));
+ account_b = gossip_chatroom_get_account (GOSSIP_CHATROOM (v2));
+
+ room_a = gossip_chatroom_get_room (GOSSIP_CHATROOM (v1));
+ room_b = gossip_chatroom_get_room (GOSSIP_CHATROOM (v2));
+
+ return gossip_account_equal (account_a, account_b) && g_str_equal (room_a, room_b);
+}
+
+
diff --git a/libempathy/gossip-chatroom.h b/libempathy/gossip-chatroom.h
new file mode 100644
index 000000000..70614a368
--- /dev/null
+++ b/libempathy/gossip-chatroom.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __GOSSIP_CHATROOM_H__
+#define __GOSSIP_CHATROOM_H__
+
+#include <glib-object.h>
+
+#include <libmissioncontrol/mc-account.h>
+
+G_BEGIN_DECLS
+
+#define GOSSIP_TYPE_CHATROOM (gossip_chatroom_get_type ())
+#define GOSSIP_CHATROOM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_CHATROOM, GossipChatroom))
+#define GOSSIP_CHATROOM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOSSIP_TYPE_CHATROOM, GossipChatroomClass))
+#define GOSSIP_IS_CHATROOM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOSSIP_TYPE_CHATROOM))
+#define GOSSIP_IS_CHATROOM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOSSIP_TYPE_CHATROOM))
+#define GOSSIP_CHATROOM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOSSIP_TYPE_CHATROOM, GossipChatroomClass))
+
+#define GOSSIP_TYPE_CHATROOM_INVITE (gossip_chatroom_invite_get_gtype ())
+
+typedef struct _GossipChatroom GossipChatroom;
+typedef struct _GossipChatroomClass GossipChatroomClass;
+typedef struct _GossipChatroomPriv GossipChatroomPriv;
+
+struct _GossipChatroom {
+ GObject parent;
+};
+
+struct _GossipChatroomClass {
+ GObjectClass parent_class;
+};
+
+GType gossip_chatroom_get_type (void) G_GNUC_CONST;
+GossipChatroom *gossip_chatroom_new (McAccount *account,
+ const gchar *room);
+GossipChatroom *gossip_chatroom_new_full (McAccount *account,
+ const gchar *room,
+ const gchar *name,
+ gboolean auto_connect);
+McAccount * gossip_chatroom_get_account (GossipChatroom *chatroom);
+void gossip_chatroom_set_account (GossipChatroom *chatroom,
+ McAccount *account);
+const gchar * gossip_chatroom_get_room (GossipChatroom *chatroom);
+void gossip_chatroom_set_room (GossipChatroom *chatroom,
+ const gchar *room);
+const gchar * gossip_chatroom_get_name (GossipChatroom *chatroom);
+void gossip_chatroom_set_name (GossipChatroom *chatroom,
+ const gchar *name);
+gboolean gossip_chatroom_get_auto_connect (GossipChatroom *chatroom);
+void gossip_chatroom_set_auto_connect (GossipChatroom *chatroom,
+ gboolean auto_connect);
+gboolean gossip_chatroom_equal (gconstpointer v1,
+ gconstpointer v2);
+
+
+G_BEGIN_DECLS
+
+#endif /* __GOSSIP_CHATROOM_H__ */
diff --git a/libempathy/gossip-utils.c b/libempathy/gossip-utils.c
index 6ab70ce4a..579981616 100644
--- a/libempathy/gossip-utils.c
+++ b/libempathy/gossip-utils.c
@@ -33,7 +33,6 @@
#include <glib/gi18n.h>
#include <libxml/uri.h>
-#include <libmissioncontrol/mc-account.h>
#include <libtelepathy/tp-helpers.h>
#include "gossip-debug.h"
@@ -447,3 +446,51 @@ gossip_mission_control_new (void)
return mc;
}
+gchar *
+gossip_get_channel_id (McAccount *account,
+ TpChan *tp_chan)
+{
+ MissionControl *mc;
+ TpConn *tp_conn;
+ GArray *handles;
+ gchar **names;
+ gchar *name;
+ GError *error;
+
+ g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
+
+ mc = gossip_mission_control_new ();
+ tp_conn = mission_control_get_connection (mc, account, NULL);
+ g_object_unref (mc);
+
+ if (!tp_conn) {
+ return NULL;
+ }
+
+ /* Get the handle's name */
+ handles = g_array_new (FALSE, FALSE, sizeof (guint));
+ g_array_append_val (handles, tp_chan->handle);
+ if (!tp_conn_inspect_handles (DBUS_G_PROXY (tp_conn),
+ tp_chan->handle_type,
+ handles,
+ &names,
+ &error)) {
+ gossip_debug (DEBUG_DOMAIN,
+ "Couldn't get id: %s",
+ error ? error->message : "No error given");
+
+ g_clear_error (&error);
+ g_array_free (handles, TRUE);
+ g_object_unref (tp_conn);
+
+ return NULL;
+ }
+
+ name = *names;
+ g_free (names);
+ g_object_unref (tp_conn);
+
+ return name;
+}
+
diff --git a/libempathy/gossip-utils.h b/libempathy/gossip-utils.h
index 052dfb781..638c114bd 100644
--- a/libempathy/gossip-utils.h
+++ b/libempathy/gossip-utils.h
@@ -32,6 +32,9 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
+#include <libtelepathy/tp-chan.h>
+
+#include <libmissioncontrol/mc-account.h>
#include <libmissioncontrol/mission-control.h>
#include "gossip-contact.h"
@@ -85,10 +88,12 @@ GValue * gossip_string_to_g_value (const gchar *str,
gboolean gossip_g_value_equal (const GValue *value1,
const GValue *value2);
-guint gossip_account_hash (gconstpointer key);
-gboolean gossip_account_equal (gconstpointer a,
- gconstpointer b);
-MissionControl *gossip_mission_control_new (void);
+guint gossip_account_hash (gconstpointer key);
+gboolean gossip_account_equal (gconstpointer a,
+ gconstpointer b);
+MissionControl *gossip_mission_control_new (void);
+gchar * gossip_get_channel_id (McAccount *account,
+ TpChan *tp_chan);
G_END_DECLS
diff --git a/src/empathy-accounts-main.c b/src/empathy-accounts-main.c
index 954b3cea7..1f53e131e 100644
--- a/src/empathy-accounts-main.c
+++ b/src/empathy-accounts-main.c
@@ -44,7 +44,7 @@ main (int argc, char *argv[])
gtk_init (&argc, &argv);
- dialog = gossip_accounts_dialog_show ();
+ dialog = gossip_accounts_dialog_show (NULL);
g_signal_connect (dialog, "destroy",
G_CALLBACK (destroy_cb),
diff --git a/src/empathy-chat-main.c b/src/empathy-chat-main.c
index 86b4608bd..fb0964934 100644
--- a/src/empathy-chat-main.c
+++ b/src/empathy-chat-main.c
@@ -113,8 +113,8 @@ new_channel_cb (EmpathyChandler *chandler,
mc = gossip_mission_control_new ();
account = mission_control_get_account_for_connection (mc, tp_conn, NULL);
- id = empathy_tp_chat_build_id_for_chan (account, tp_chan);
- chat = gossip_chat_window_find_chat_by_id (id);
+ id = gossip_get_channel_id (account, tp_chan);
+ chat = gossip_chat_window_find_chat (account, id);
g_free (id);
g_object_unref (mc);
@@ -185,7 +185,7 @@ main (int argc, char *argv[])
debug_mode = TRUE;
}
- exit_timeout_start ();
+ //sexit_timeout_start ();
chandler = empathy_chandler_new (BUS_NAME, OBJECT_PATH);
g_signal_connect (chandler, "new-channel",