aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--data/Makefile.am1
-rw-r--r--data/empathy.desktop.in.in2
-rw-r--r--data/gtalk.profile1
-rw-r--r--data/irc.profile7
-rw-r--r--data/jabber.profile1
-rw-r--r--data/msn.profile1
-rw-r--r--data/salut.profile1
-rw-r--r--libempathy-gtk/Makefile.am3
-rw-r--r--libempathy-gtk/empathy-main-window.c4
-rw-r--r--libempathy-gtk/gossip-account-chooser.c633
-rw-r--r--libempathy-gtk/gossip-account-chooser.h66
-rw-r--r--libempathy-gtk/gossip-account-widget-jabber.c14
-rw-r--r--libempathy-gtk/gossip-account-widget-jabber.glade59
-rw-r--r--libempathy-gtk/gossip-group-chat.c1
-rw-r--r--libempathy-gtk/gossip-new-chatroom-dialog.c770
-rw-r--r--libempathy-gtk/gossip-new-chatroom-dialog.glade519
-rw-r--r--libempathy-gtk/gossip-new-chatroom-dialog.h34
-rw-r--r--libempathy/empathy-tp-chatroom.c38
19 files changed, 2123 insertions, 54 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d5212877..ab67c3deb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2007-05-24 Xavier Claessens <xclaesse@gmail.com>
+
+ * libempathy-gtk/gossip-account-chooser.c:
+ * libempathy-gtk/gossip-new-chatroom-dialog.c:
+ * libempathy-gtk/gossip-account-widget-jabber.c:
+ * libempathy-gtk/gossip-account-chooser.h:
+ * libempathy-gtk/gossip-new-chatroom-dialog.h:
+ * libempathy-gtk/gossip-group-chat.c:
+ * libempathy-gtk/empathy-main-window.c:
+ * libempathy-gtk/gossip-new-chatroom-dialog.glade:
+ * libempathy-gtk/gossip-account-widget-jabber.glade:
+ * libempathy-gtk/Makefile.am:
+ * libempathy/empathy-tp-chatroom.c:
+ * data/gtalk.profile:
+ * data/jabber.profile:
+ * data/salut.profile:
+ * data/Makefile.am:
+ * data/empathy.desktop.in.in:
+ * data/msn.profile:
+ * data/irc.profile: New objects: GossipAccountChooser and
+ GossipNewChatroom, we can now join any chatroom. Adding IRC profile.
+
2007-05-21 Xavier Claessens <xclaesse@gmail.com>
* libempathy/empathy-idle.c: If we are offline do not set away on idle.
diff --git a/data/Makefile.am b/data/Makefile.am
index eca5bf4a2..128f8aa64 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -5,6 +5,7 @@ profile_DATA = \
jabber.profile \
gtalk.profile \
salut.profile \
+ irc.profile \
msn.profile
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
diff --git a/data/empathy.desktop.in.in b/data/empathy.desktop.in.in
index eca31045b..abf48ce11 100644
--- a/data/empathy.desktop.in.in
+++ b/data/empathy.desktop.in.in
@@ -3,7 +3,7 @@ Version=1.0
Encoding=UTF-8
_Name=Empathy Instant Messenger
_Comment=Instant Messenger
-Exec=empathy
+Exec=empathy --no-connect
Icon=empathy
StartupNotify=false
Terminal=false
diff --git a/data/gtalk.profile b/data/gtalk.profile
index c8d5de9a1..f81dc27c3 100644
--- a/data/gtalk.profile
+++ b/data/gtalk.profile
@@ -4,6 +4,7 @@ Protocol=jabber
DisplayName=Google Talk
IconName = empathy-proto-google-talk
ConfigurationUI = jabber
+Capabilities = chat-p2p, chat-room, chat-room-list, voice-p2p, split-account, supports-avatars, supports-alias
DefaultAccountDomain = gmail.com, googlemail.com
Default-server = talk.google.com
Default-port = 5223
diff --git a/data/irc.profile b/data/irc.profile
new file mode 100644
index 000000000..90915c16d
--- /dev/null
+++ b/data/irc.profile
@@ -0,0 +1,7 @@
+[Profile]
+Manager=idle
+Protocol=irc
+DisplayName=IRC
+ConfigurationUI = irc
+Capabilities = chat-p2p, chat-room, chat-room-list, supports-alias
+SupportsInvisible = 0
diff --git a/data/jabber.profile b/data/jabber.profile
index 1d2ad2561..7da8254f4 100644
--- a/data/jabber.profile
+++ b/data/jabber.profile
@@ -4,5 +4,6 @@ Protocol=jabber
DisplayName=Jabber
IconName = empathy-proto-jabber
ConfigurationUI = jabber
+Capabilities = chat-p2p, chat-room, chat-room-list, voice-p2p, split-account, registration-ui, supports-avatars, supports-alias
DefaultAccountDomain = jabber.org
SupportsInvisible = 0
diff --git a/data/msn.profile b/data/msn.profile
index b344a4e6d..44058fc15 100644
--- a/data/msn.profile
+++ b/data/msn.profile
@@ -5,3 +5,4 @@ DisplayName=MSN
IconName = empathy-proto-msn
ConfigurationUI = msn
SupportsInvisible = 1
+Capabilities = chat-p2p, split-account, supports-avatars, supports-alias
diff --git a/data/salut.profile b/data/salut.profile
index 2082881ee..e9b346b39 100644
--- a/data/salut.profile
+++ b/data/salut.profile
@@ -4,4 +4,5 @@ Protocol=salut
DisplayName=Salut
IconName = empathy-proto-jabber
ConfigurationUI = salut
+Capabilities = chat-p2p, chat-room, chat-room-list, voice-p2p, supports-avatars, supports-alias
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 7a5d1893a..f28e7411c 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -32,6 +32,8 @@ libempathy_gtk_la_SOURCES = \
gossip-status-presets.c gossip-status-presets.h \
gossip-presence-chooser.c gossip-presence-chooser.h \
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-ui-utils.c gossip-ui-utils.h
libempathy_gtk_la_LIBADD = \
@@ -48,6 +50,7 @@ glade_DATA = \
gossip-presence-chooser.glade \
gossip-accounts-dialog.glade \
gossip-account-widget-jabber.glade \
+ gossip-new-chatroom-dialog.glade \
gossip-group-chat.glade \
gossip-chat.glade
diff --git a/libempathy-gtk/empathy-main-window.c b/libempathy-gtk/empathy-main-window.c
index 9f2e9daf0..aa49cffe0 100644
--- a/libempathy-gtk/empathy-main-window.c
+++ b/libempathy-gtk/empathy-main-window.c
@@ -45,7 +45,7 @@
#include "gossip-preferences.h"
#include "gossip-accounts-dialog.h"
#include "gossip-about-dialog.h"
-
+#include "gossip-new-chatroom-dialog.h"
#define DEBUG_DOMAIN "MainWindow"
@@ -403,7 +403,7 @@ static void
main_window_room_join_new_cb (GtkWidget *widget,
EmpathyMainWindow *window)
{
- //gossip_new_chatroom_dialog_show (GTK_WINDOW (window->window));
+ gossip_new_chatroom_dialog_show (GTK_WINDOW (window->window));
}
static void
diff --git a/libempathy-gtk/gossip-account-chooser.c b/libempathy-gtk/gossip-account-chooser.c
new file mode 100644
index 000000000..8d3439f7e
--- /dev/null
+++ b/libempathy-gtk/gossip-account-chooser.c
@@ -0,0 +1,633 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2005-2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * 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: Martyn Russell <martyn@imendio.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#include <libtelepathy/tp-conn.h>
+#include <libmissioncontrol/mc-account-monitor.h>
+#include <libmissioncontrol/mission-control.h>
+
+#include <libempathy/gossip-utils.h>
+
+#include "gossip-ui-utils.h"
+#include "gossip-account-chooser.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_ACCOUNT_CHOOSER, GossipAccountChooserPriv))
+
+typedef struct {
+ MissionControl *mc;
+ McAccountMonitor *monitor;
+
+ gboolean set_active_item;
+ gboolean can_select_all;
+ gboolean has_all_option;
+} GossipAccountChooserPriv;
+
+typedef struct {
+ GossipAccountChooser *chooser;
+ McAccount *account;
+ gboolean set;
+} SetAccountData;
+
+enum {
+ COL_ACCOUNT_IMAGE,
+ COL_ACCOUNT_TEXT,
+ COL_ACCOUNT_ENABLED, /* Usually tied to connected state */
+ COL_ACCOUNT_POINTER,
+ COL_ACCOUNT_COUNT
+};
+
+static void account_chooser_finalize (GObject *object);
+static void account_chooser_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void account_chooser_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void account_chooser_setup (GossipAccountChooser *chooser);
+static void account_chooser_account_created_cb (McAccountMonitor *monitor,
+ const gchar *unique_name,
+ GossipAccountChooser *chooser);
+static void account_chooser_account_add_foreach (McAccount *account,
+ GossipAccountChooser *chooser);
+static void account_chooser_account_deleted_cb (McAccountMonitor *monitor,
+ const gchar *unique_name,
+ GossipAccountChooser *chooser);
+static void account_chooser_account_remove_foreach (McAccount *account,
+ GossipAccountChooser *chooser);
+static void account_chooser_update_iter (GossipAccountChooser *chooser,
+ GtkTreeIter *iter,
+ McAccount *account);
+static void account_chooser_status_changed_cb (MissionControl *mc,
+ TelepathyConnectionStatus status,
+ McPresence presence,
+ TelepathyConnectionStatusReason reason,
+ const gchar *unique_name,
+ GossipAccountChooser *chooser);
+static gboolean account_chooser_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GossipAccountChooser *chooser);
+static gboolean account_chooser_set_account_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ SetAccountData *data);
+static gboolean account_chooser_set_enabled_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GossipAccountChooser *chooser);
+
+enum {
+ PROP_0,
+ PROP_CAN_SELECT_ALL,
+ PROP_HAS_ALL_OPTION,
+};
+
+G_DEFINE_TYPE (GossipAccountChooser, gossip_account_chooser, GTK_TYPE_COMBO_BOX);
+
+static void
+gossip_account_chooser_class_init (GossipAccountChooserClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = account_chooser_finalize;
+ object_class->get_property = account_chooser_get_property;
+ object_class->set_property = account_chooser_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_CAN_SELECT_ALL,
+ g_param_spec_boolean ("can-select-all",
+ "Can Select All",
+ "Should the user be able to select offline accounts",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_HAS_ALL_OPTION,
+ g_param_spec_boolean ("has-all-option",
+ "Has All Option",
+ "Have a separate option in the list to mean ALL accounts",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (GossipAccountChooserPriv));
+}
+
+static void
+gossip_account_chooser_init (GossipAccountChooser *chooser)
+{
+}
+
+static void
+account_chooser_finalize (GObject *object)
+{
+ GossipAccountChooser *chooser;
+ GossipAccountChooserPriv *priv;
+
+ chooser = GOSSIP_ACCOUNT_CHOOSER (object);
+ priv = GET_PRIV (object);
+
+ g_signal_handlers_disconnect_by_func (priv->monitor,
+ account_chooser_account_created_cb,
+ chooser);
+ g_signal_handlers_disconnect_by_func (priv->monitor,
+ account_chooser_account_deleted_cb,
+ chooser);
+ dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
+ "AccountStatusChanged",
+ G_CALLBACK (account_chooser_status_changed_cb),
+ chooser);
+ g_object_unref (priv->mc);
+ g_object_unref (priv->monitor);
+
+ G_OBJECT_CLASS (gossip_account_chooser_parent_class)->finalize (object);
+}
+
+static void
+account_chooser_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GossipAccountChooserPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_CAN_SELECT_ALL:
+ g_value_set_boolean (value, priv->can_select_all);
+ break;
+ case PROP_HAS_ALL_OPTION:
+ g_value_set_boolean (value, priv->has_all_option);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+static void
+account_chooser_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GossipAccountChooserPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_CAN_SELECT_ALL:
+ gossip_account_chooser_set_can_select_all (GOSSIP_ACCOUNT_CHOOSER (object),
+ g_value_get_boolean (value));
+ break;
+ case PROP_HAS_ALL_OPTION:
+ gossip_account_chooser_set_has_all_option (GOSSIP_ACCOUNT_CHOOSER (object),
+ g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+GtkWidget *
+gossip_account_chooser_new (void)
+{
+ GossipAccountChooserPriv *priv;
+ McAccountMonitor *monitor;
+ GtkWidget *chooser;
+
+ monitor = mc_account_monitor_new ();
+ chooser = g_object_new (GOSSIP_TYPE_ACCOUNT_CHOOSER, NULL);
+
+ priv = GET_PRIV (chooser);
+
+ priv->mc = gossip_mission_control_new ();
+ priv->monitor = mc_account_monitor_new ();
+
+ g_signal_connect (priv->monitor, "account-created",
+ G_CALLBACK (account_chooser_account_created_cb),
+ chooser);
+ g_signal_connect (priv->monitor, "account-deleted",
+ G_CALLBACK (account_chooser_account_deleted_cb),
+ chooser);
+ dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc), "AccountStatusChanged",
+ G_CALLBACK (account_chooser_status_changed_cb),
+ chooser, NULL);
+
+ account_chooser_setup (GOSSIP_ACCOUNT_CHOOSER (chooser));
+
+ return chooser;
+}
+
+McAccount *
+gossip_account_chooser_get_account (GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+ McAccount *account;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT_CHOOSER (chooser), NULL);
+
+ priv = GET_PRIV (chooser);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser));
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser), &iter);
+
+ gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1);
+
+ return account;
+}
+
+gboolean
+gossip_account_chooser_set_account (GossipAccountChooser *chooser,
+ McAccount *account)
+{
+ GtkComboBox *combobox;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ SetAccountData data;
+
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT_CHOOSER (chooser), FALSE);
+
+ combobox = GTK_COMBO_BOX (chooser);
+ model = gtk_combo_box_get_model (combobox);
+ gtk_combo_box_get_active_iter (combobox, &iter);
+
+ data.chooser = chooser;
+ data.account = account;
+
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc) account_chooser_set_account_foreach,
+ &data);
+
+ return data.set;
+}
+
+gboolean
+gossip_account_chooser_get_can_select_all (GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT_CHOOSER (chooser), FALSE);
+
+ priv = GET_PRIV (chooser);
+
+ return priv->can_select_all;
+}
+
+void
+gossip_account_chooser_set_can_select_all (GossipAccountChooser *chooser,
+ gboolean can_select_all)
+{
+ GossipAccountChooserPriv *priv;
+ GtkComboBox *combobox;
+ GtkTreeModel *model;
+
+ g_return_if_fail (GOSSIP_IS_ACCOUNT_CHOOSER (chooser));
+
+ priv = GET_PRIV (chooser);
+
+ if (priv->can_select_all == can_select_all) {
+ return;
+ }
+
+ combobox = GTK_COMBO_BOX (chooser);
+ model = gtk_combo_box_get_model (combobox);
+
+ priv->can_select_all = can_select_all;
+
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc) account_chooser_set_enabled_foreach,
+ chooser);
+
+ g_object_notify (G_OBJECT (chooser), "can-select-all");
+}
+
+gboolean
+gossip_account_chooser_get_has_all_option (GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_ACCOUNT_CHOOSER (chooser), FALSE);
+
+ priv = GET_PRIV (chooser);
+
+ return priv->has_all_option;
+}
+
+void
+gossip_account_chooser_set_has_all_option (GossipAccountChooser *chooser,
+ gboolean has_all_option)
+{
+ GossipAccountChooserPriv *priv;
+ GtkComboBox *combobox;
+ GtkListStore *store;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (GOSSIP_IS_ACCOUNT_CHOOSER (chooser));
+
+ priv = GET_PRIV (chooser);
+
+ if (priv->has_all_option == has_all_option) {
+ return;
+ }
+
+ combobox = GTK_COMBO_BOX (chooser);
+ model = gtk_combo_box_get_model (combobox);
+ store = GTK_LIST_STORE (model);
+
+ priv->has_all_option = has_all_option;
+
+ /*
+ * The first 2 options are the ALL and separator
+ */
+
+ if (has_all_option) {
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (chooser),
+ (GtkTreeViewRowSeparatorFunc)
+ account_chooser_separator_func,
+ chooser,
+ NULL);
+
+ gtk_list_store_prepend (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_ACCOUNT_TEXT, NULL,
+ COL_ACCOUNT_ENABLED, TRUE,
+ COL_ACCOUNT_POINTER, NULL,
+ -1);
+
+ gtk_list_store_prepend (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_ACCOUNT_TEXT, _("All"),
+ COL_ACCOUNT_ENABLED, TRUE,
+ COL_ACCOUNT_POINTER, NULL,
+ -1);
+ } else {
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) {
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ }
+ }
+
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (chooser),
+ (GtkTreeViewRowSeparatorFunc)
+ NULL,
+ NULL,
+ NULL);
+ }
+
+ g_object_notify (G_OBJECT (chooser), "has-all-option");
+}
+
+static void
+account_chooser_setup (GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+ GList *accounts;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ GtkComboBox *combobox;
+
+ priv = GET_PRIV (chooser);
+
+ /* Set up combo box with new store */
+ combobox = GTK_COMBO_BOX (chooser);
+
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (combobox));
+
+ store = gtk_list_store_new (COL_ACCOUNT_COUNT,
+ G_TYPE_STRING,
+ G_TYPE_STRING, /* Name */
+ G_TYPE_BOOLEAN, /* Enabled */
+ MC_TYPE_ACCOUNT);
+
+ gtk_combo_box_set_model (combobox, GTK_TREE_MODEL (store));
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
+ "icon-name", COL_ACCOUNT_IMAGE,
+ "sensitive", COL_ACCOUNT_ENABLED,
+ NULL);
+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
+ "text", COL_ACCOUNT_TEXT,
+ "sensitive", COL_ACCOUNT_ENABLED,
+ NULL);
+
+ /* Populate accounts */
+ accounts = mc_accounts_list ();
+ g_list_foreach (accounts,
+ (GFunc) account_chooser_account_add_foreach,
+ chooser);
+
+ mc_accounts_list_free (accounts);
+ g_object_unref (store);
+}
+
+static void
+account_chooser_account_created_cb (McAccountMonitor *monitor,
+ const gchar *unique_name,
+ GossipAccountChooser *chooser)
+{
+ McAccount *account;
+
+ account = mc_account_lookup (unique_name);
+ account_chooser_account_add_foreach (account, chooser);
+ g_object_unref (account);
+}
+
+static void
+account_chooser_account_add_foreach (McAccount *account,
+ GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+ GtkListStore *store;
+ GtkComboBox *combobox;
+ GtkTreeIter iter;
+
+ priv = GET_PRIV (chooser);
+
+ combobox = GTK_COMBO_BOX (chooser);
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (combobox));
+
+ gtk_list_store_append (store, &iter);
+ account_chooser_update_iter (chooser, &iter, account);
+}
+
+static void
+account_chooser_account_deleted_cb (McAccountMonitor *monitor,
+ const gchar *unique_name,
+ GossipAccountChooser *chooser)
+{
+ McAccount *account;
+
+ account = mc_account_lookup (unique_name);
+ account_chooser_account_remove_foreach (account, chooser);
+ g_object_unref (account);
+}
+
+static void
+account_chooser_account_remove_foreach (McAccount *account,
+ GossipAccountChooser *chooser)
+{
+ /* Fixme: TODO */
+}
+
+static void
+account_chooser_update_iter (GossipAccountChooser *chooser,
+ GtkTreeIter *iter,
+ McAccount *account)
+{
+ GossipAccountChooserPriv *priv;
+ GtkListStore *store;
+ GtkComboBox *combobox;
+ TpConn *tp_conn;
+ const gchar *icon_name;
+ gboolean is_enabled;
+
+ priv = GET_PRIV (chooser);
+
+ combobox = GTK_COMBO_BOX (chooser);
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (combobox));
+
+ icon_name = gossip_icon_name_from_account (account);
+ tp_conn = mission_control_get_connection (priv->mc, account, NULL);
+ is_enabled = (tp_conn != NULL || priv->can_select_all);
+
+ if (tp_conn) {
+ g_object_unref (tp_conn);
+ }
+
+ gtk_list_store_set (store, iter,
+ COL_ACCOUNT_IMAGE, icon_name,
+ COL_ACCOUNT_TEXT, mc_account_get_display_name (account),
+ COL_ACCOUNT_ENABLED, is_enabled,
+ COL_ACCOUNT_POINTER, account,
+ -1);
+
+ /* set first connected account as active account */
+ if (priv->set_active_item == FALSE && is_enabled) {
+ priv->set_active_item = TRUE;
+ gtk_combo_box_set_active_iter (combobox, iter);
+ }
+}
+
+static void
+account_chooser_status_changed_cb (MissionControl *mc,
+ TelepathyConnectionStatus status,
+ McPresence presence,
+ TelepathyConnectionStatusReason reason,
+ const gchar *unique_name,
+ GossipAccountChooser *chooser)
+{
+}
+
+static gboolean
+account_chooser_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+ gchar *text;
+ gboolean is_separator;
+
+ priv = GET_PRIV (chooser);
+
+ if (!priv->has_all_option) {
+ return FALSE;
+ }
+
+ gtk_tree_model_get (model, iter, COL_ACCOUNT_TEXT, &text, -1);
+ is_separator = text == NULL;
+ g_free (text);
+
+ return is_separator;
+}
+
+static gboolean
+account_chooser_set_account_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ SetAccountData *data)
+{
+ McAccount *account;
+ gboolean equal;
+
+ gtk_tree_model_get (model, iter, COL_ACCOUNT_POINTER, &account, -1);
+
+ /* Special case so we can make it possible to select the All option */
+ if (!data->account && !account) {
+ equal = TRUE;
+ } else {
+ equal = gossip_account_equal (data->account, account);
+ g_object_unref (account);
+ }
+
+ if (equal) {
+ GtkComboBox *combobox;
+
+ combobox = GTK_COMBO_BOX (data->chooser);
+ gtk_combo_box_set_active_iter (combobox, iter);
+
+ data->set = TRUE;
+ }
+
+ return equal;
+}
+
+static gboolean
+account_chooser_set_enabled_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GossipAccountChooser *chooser)
+{
+ GossipAccountChooserPriv *priv;
+ McAccount *account;
+
+ priv = GET_PRIV (chooser);
+
+ gtk_tree_model_get (model, iter, COL_ACCOUNT_POINTER, &account, -1);
+ if (!account) {
+ return FALSE;
+ }
+
+ account_chooser_update_iter (chooser, iter, account);
+ g_object_unref (account);
+
+ return FALSE;
+}
+
diff --git a/libempathy-gtk/gossip-account-chooser.h b/libempathy-gtk/gossip-account-chooser.h
new file mode 100644
index 000000000..b2d7c0cdd
--- /dev/null
+++ b/libempathy-gtk/gossip-account-chooser.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2005-2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * 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: Martyn Russell <martyn@imendio.com>
+ */
+
+#ifndef __GOSSIP_ACCOUNT_CHOOSER_H__
+#define __GOSSIP_ACCOUNT_CHOOSER_H__
+
+#include <gtk/gtkcombobox.h>
+
+#include <libmissioncontrol/mc-account.h>
+
+G_BEGIN_DECLS
+
+#define GOSSIP_TYPE_ACCOUNT_CHOOSER (gossip_account_chooser_get_type ())
+#define GOSSIP_ACCOUNT_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_ACCOUNT_CHOOSER, GossipAccountChooser))
+#define GOSSIP_ACCOUNT_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOSSIP_TYPE_ACCOUNT_CHOOSER, GossipAccountChooserClass))
+#define GOSSIP_IS_ACCOUNT_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOSSIP_TYPE_ACCOUNT_CHOOSER))
+#define GOSSIP_IS_ACCOUNT_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOSSIP_TYPE_ACCOUNT_CHOOSER))
+#define GOSSIP_ACCOUNT_CHOOSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOSSIP_TYPE_ACCOUNT_CHOOSER, GossipAccountChooserClass))
+
+typedef struct _GossipAccountChooser GossipAccountChooser;
+typedef struct _GossipAccountChooserClass GossipAccountChooserClass;
+
+struct _GossipAccountChooser {
+ GtkComboBox parent;
+};
+
+struct _GossipAccountChooserClass {
+ GtkComboBoxClass parent_class;
+};
+
+GType gossip_account_chooser_get_type (void) G_GNUC_CONST;
+GtkWidget * gossip_account_chooser_new (void);
+McAccount * gossip_account_chooser_get_account (GossipAccountChooser *chooser);
+gboolean gossip_account_chooser_set_account (GossipAccountChooser *chooser,
+ McAccount *account);
+gboolean gossip_account_chooser_get_can_select_all (GossipAccountChooser *chooser);
+
+void gossip_account_chooser_set_can_select_all (GossipAccountChooser *chooser,
+ gboolean can_select_all);
+gboolean gossip_account_chooser_get_has_all_option (GossipAccountChooser *chooser);
+void gossip_account_chooser_set_has_all_option (GossipAccountChooser *chooser,
+ gboolean has_all_option);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_ACCOUNT_CHOOSER_H__ */
+
diff --git a/libempathy-gtk/gossip-account-widget-jabber.c b/libempathy-gtk/gossip-account-widget-jabber.c
index 8282777bd..e7334b4b5 100644
--- a/libempathy-gtk/gossip-account-widget-jabber.c
+++ b/libempathy-gtk/gossip-account-widget-jabber.c
@@ -30,6 +30,8 @@
#include <gtk/gtk.h>
#include <glade/glade.h>
+#include <libmissioncontrol/mc-profile.h>
+
#include <libempathy/gossip-utils.h>
#include "gossip-account-widget-jabber.h"
@@ -187,6 +189,18 @@ account_widget_jabber_setup (GossipAccountWidgetJabber *settings)
mc_account_get_param_string (settings->account, "password", &password);
mc_account_get_param_boolean (settings->account, "old-ssl", &old_ssl);
+ if (!id) {
+ McProfile *profile;
+ const gchar *server;
+
+ profile = mc_account_get_profile (settings->account);
+ server = mc_profile_get_default_account_domain (profile);
+ if (server) {
+ id = g_strconcat ("user@", server, NULL);
+ }
+ g_object_unref (profile);
+ }
+
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (settings->checkbutton_ssl), old_ssl);
gtk_entry_set_text (GTK_ENTRY (settings->entry_id), id ? id : "");
gtk_entry_set_text (GTK_ENTRY (settings->entry_password), password ? password : "");
diff --git a/libempathy-gtk/gossip-account-widget-jabber.glade b/libempathy-gtk/gossip-account-widget-jabber.glade
index 19d13990a..12eec7576 100644
--- a/libempathy-gtk/gossip-account-widget-jabber.glade
+++ b/libempathy-gtk/gossip-account-widget-jabber.glade
@@ -309,62 +309,23 @@
</child>
<child>
- <widget class="GtkVBox" id="vbox1">
+ <widget class="GtkEntry" id="entry_id">
<property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkEntry" id="entry_id">
- <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="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;small&gt;&lt;b&gt;&lt;span foreground=&quot;#555&quot;&gt;Example: user@jabber.org&lt;/span&gt;&lt;/b&gt;&lt;/small&gt;</property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</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">False</property>
- </packing>
- </child>
+ <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">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
+ <property name="y_options"></property>
</packing>
</child>
</widget>
diff --git a/libempathy-gtk/gossip-group-chat.c b/libempathy-gtk/gossip-group-chat.c
index b955ee21e..6cf897d67 100644
--- a/libempathy-gtk/gossip-group-chat.c
+++ b/libempathy-gtk/gossip-group-chat.c
@@ -187,6 +187,7 @@ gossip_group_chat_new (McAccount *account,
/* Create contact list */
priv->store = gossip_contact_list_store_new (EMPATHY_CONTACT_LIST (priv->tp_chat));
priv->view = gossip_contact_list_view_new (priv->store);
+ gossip_contact_list_store_set_show_offline (priv->store, TRUE);
gtk_container_add (GTK_CONTAINER (priv->scrolled_window_contacts),
GTK_WIDGET (priv->view));
gtk_widget_show (GTK_WIDGET (priv->view));
diff --git a/libempathy-gtk/gossip-new-chatroom-dialog.c b/libempathy-gtk/gossip-new-chatroom-dialog.c
new file mode 100644
index 000000000..6c16ecb11
--- /dev/null
+++ b/libempathy-gtk/gossip-new-chatroom-dialog.c
@@ -0,0 +1,770 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006-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: Martyn Russell <martyn@imendio.com>
+ * Xavier Claessens <xclaesse@gmail.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 <libmissioncontrol/mission-control.h>
+#include <libmissioncontrol/mc-account.h>
+#include <libmissioncontrol/mc-profile.h>
+
+#include <libempathy/gossip-utils.h>
+#include <libempathy/gossip-debug.h>
+
+#include "gossip-new-chatroom-dialog.h"
+#include "gossip-account-chooser.h"
+//#include "gossip-chatrooms-window.h"
+#include "gossip-ui-utils.h"
+#include "ephy-spinner.h"
+
+#define DEBUG_DOMAIN "NewChatroomDialog"
+
+typedef struct {
+ GtkWidget *window;
+
+ GtkWidget *vbox_widgets;
+
+ GtkWidget *hbox_account;
+ GtkWidget *label_account;
+ GtkWidget *account_chooser;
+
+ GtkWidget *hbox_server;
+ GtkWidget *label_server;
+ GtkWidget *entry_server;
+ GtkWidget *togglebutton_refresh;
+
+ GtkWidget *hbox_room;
+ GtkWidget *label_room;
+ GtkWidget *entry_room;
+
+ GtkWidget *hbox_nick;
+ GtkWidget *label_nick;
+ GtkWidget *entry_nick;
+
+ GtkWidget *vbox_browse;
+ GtkWidget *image_status;
+ GtkWidget *label_status;
+ GtkWidget *hbox_status;
+ GtkWidget *throbber;
+ GtkWidget *treeview;
+ GtkTreeModel *model;
+ GtkTreeModel *filter;
+
+ GtkWidget *button_join;
+ GtkWidget *button_close;
+} GossipNewChatroomDialog;
+
+typedef struct {
+ guint handle;
+ gchar *channel_type;
+ gchar *name;
+ gchar *id;
+} EmpathyRoomListItem;
+
+enum {
+ COL_IMAGE,
+ COL_NAME,
+ COL_POINTER,
+ COL_COUNT
+};
+
+static void
+new_chatroom_dialog_response_cb (GtkWidget *widget,
+ gint response,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_destroy_cb (GtkWidget *widget,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_setup (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_add_columns (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_update_buttons (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_update_widgets (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_add (GossipNewChatroomDialog *dialog,
+ EmpathyRoomListItem *item);
+static void
+new_chatroom_dialog_model_clear (GossipNewChatroomDialog *dialog);
+static GList *
+new_chatroom_dialog_model_get_selected (GossipNewChatroomDialog *dialog);
+static gboolean
+new_chatroom_dialog_model_filter_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_set_defaults (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_join (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_request_handles_cb (DBusGProxy *proxy,
+ GArray *handles,
+ GError *error,
+ McAccount *account);
+static void
+new_chatroom_dialog_entry_changed_cb (GtkWidget *entry,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_browse_start (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_browse_stop (GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget,
+ GossipNewChatroomDialog *dialog);
+static void
+new_chatroom_dialog_togglebutton_refresh_toggled_cb (GtkWidget *widget,
+ GossipNewChatroomDialog *dialog);
+
+static GossipNewChatroomDialog *dialog_p = NULL;
+
+void
+gossip_new_chatroom_dialog_show (GtkWindow *parent)
+{
+ GossipNewChatroomDialog *dialog;
+ GladeXML *glade;
+ GList *accounts;
+ gint account_num;
+ GtkSizeGroup *size_group;
+
+ if (dialog_p) {
+ gtk_window_present (GTK_WINDOW (dialog_p->window));
+ return;
+ }
+
+ dialog_p = dialog = g_new0 (GossipNewChatroomDialog, 1);
+
+ glade = gossip_glade_get_file ("gossip-new-chatroom-dialog.glade",
+ "new_chatroom_dialog",
+ NULL,
+ "new_chatroom_dialog", &dialog->window,
+ "hbox_account", &dialog->hbox_account,
+ "label_account", &dialog->label_account,
+ "vbox_widgets", &dialog->vbox_widgets,
+ "label_server", &dialog->label_server,
+ "label_room", &dialog->label_room,
+ "label_nick", &dialog->label_nick,
+ "hbox_server", &dialog->hbox_server,
+ "hbox_room", &dialog->hbox_room,
+ "hbox_nick", &dialog->hbox_nick,
+ "entry_server", &dialog->entry_server,
+ "entry_room", &dialog->entry_room,
+ "entry_nick", &dialog->entry_nick,
+ "togglebutton_refresh", &dialog->togglebutton_refresh,
+ "vbox_browse", &dialog->vbox_browse,
+ "image_status", &dialog->image_status,
+ "label_status", &dialog->label_status,
+ "hbox_status", &dialog->hbox_status,
+ "treeview", &dialog->treeview,
+ "button_join", &dialog->button_join,
+ NULL);
+
+ gossip_glade_connect (glade,
+ dialog,
+ "new_chatroom_dialog", "response", new_chatroom_dialog_response_cb,
+ "new_chatroom_dialog", "destroy", new_chatroom_dialog_destroy_cb,
+ "entry_nick", "changed", new_chatroom_dialog_entry_changed_cb,
+ "entry_server", "changed", new_chatroom_dialog_entry_changed_cb,
+ "entry_server", "activate", new_chatroom_dialog_entry_server_activate_cb,
+ "entry_room", "changed", new_chatroom_dialog_entry_changed_cb,
+ "togglebutton_refresh", "toggled", new_chatroom_dialog_togglebutton_refresh_toggled_cb,
+ NULL);
+
+ g_object_unref (glade);
+
+ g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog_p);
+
+ /* Label alignment */
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ gtk_size_group_add_widget (size_group, dialog->label_account);
+ gtk_size_group_add_widget (size_group, dialog->label_server);
+ gtk_size_group_add_widget (size_group, dialog->label_room);
+ gtk_size_group_add_widget (size_group, dialog->label_nick);
+
+ g_object_unref (size_group);
+
+ /* Account chooser for custom */
+ dialog->account_chooser = gossip_account_chooser_new ();
+ gtk_box_pack_start (GTK_BOX (dialog->hbox_account),
+ dialog->account_chooser,
+ TRUE, TRUE, 0);
+ gtk_widget_show (dialog->account_chooser);
+
+ g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed",
+ G_CALLBACK (new_chatroom_dialog_account_changed_cb),
+ dialog);
+
+ /* Populate */
+ accounts = mc_accounts_list ();
+ account_num = g_list_length (accounts);
+
+ g_list_foreach (accounts, (GFunc) g_object_unref, NULL);
+ g_list_free (accounts);
+
+ if (account_num > 1) {
+ gtk_widget_show (dialog->hbox_account);
+ } else {
+ /* Show no accounts combo box */
+ gtk_widget_hide (dialog->hbox_account);
+ }
+
+ /* Add throbber */
+ dialog->throbber = ephy_spinner_new ();
+ ephy_spinner_set_size (EPHY_SPINNER (dialog->throbber), GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_widget_show (dialog->throbber);
+
+ gtk_box_pack_start (GTK_BOX (dialog->hbox_status), dialog->throbber,
+ FALSE, FALSE, 0);
+
+ /* Set up chatrooms treeview */
+ new_chatroom_dialog_model_setup (dialog);
+
+ /* Set things up according to the account type */
+ new_chatroom_dialog_update_widgets (dialog);
+
+ if (parent) {
+ gtk_window_set_transient_for (GTK_WINDOW (dialog->window),
+ GTK_WINDOW (parent));
+ }
+
+ gtk_widget_show (dialog->window);
+}
+
+static void
+new_chatroom_dialog_response_cb (GtkWidget *widget,
+ gint response,
+ GossipNewChatroomDialog *dialog)
+{
+ if (response == GTK_RESPONSE_OK) {
+ new_chatroom_dialog_join (dialog);
+ }
+
+ gtk_widget_destroy (widget);
+}
+
+static void
+new_chatroom_dialog_destroy_cb (GtkWidget *widget,
+ GossipNewChatroomDialog *dialog)
+{
+ g_object_unref (dialog->model);
+ g_object_unref (dialog->filter);
+
+ g_free (dialog);
+}
+
+static void
+new_chatroom_dialog_model_setup (GossipNewChatroomDialog *dialog)
+{
+ GtkTreeView *view;
+ GtkListStore *store;
+ GtkTreeSelection *selection;
+
+ /* View */
+ view = GTK_TREE_VIEW (dialog->treeview);
+
+ g_signal_connect (view, "row-activated",
+ G_CALLBACK (new_chatroom_dialog_model_row_activated_cb),
+ dialog);
+
+ /* Store/Model */
+ store = gtk_list_store_new (COL_COUNT,
+ G_TYPE_STRING, /* Image */
+ G_TYPE_STRING, /* Text */
+ G_TYPE_POINTER); /* infos */
+
+ dialog->model = GTK_TREE_MODEL (store);
+
+ /* Filter */
+ dialog->filter = gtk_tree_model_filter_new (dialog->model, NULL);
+
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (dialog->filter),
+ (GtkTreeModelFilterVisibleFunc)
+ new_chatroom_dialog_model_filter_func,
+ dialog,
+ NULL);
+
+ gtk_tree_view_set_model (view, dialog->filter);
+
+ g_signal_connect (dialog->filter, "row-inserted",
+ G_CALLBACK (new_chatroom_dialog_model_row_inserted_cb),
+ dialog);
+ g_signal_connect (dialog->filter, "row-deleted",
+ G_CALLBACK (new_chatroom_dialog_model_row_deleted_cb),
+ dialog);
+
+ /* Selection */
+ selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
+ COL_NAME, GTK_SORT_ASCENDING);
+
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (new_chatroom_dialog_model_selection_changed), dialog);
+
+ /* Columns */
+ new_chatroom_dialog_model_add_columns (dialog);
+}
+
+static void
+new_chatroom_dialog_model_add_columns (GossipNewChatroomDialog *dialog)
+{
+ GtkTreeView *view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell;
+
+ view = GTK_TREE_VIEW (dialog->treeview);
+ gtk_tree_view_set_headers_visible (view, FALSE);
+
+ /* Chatroom pointer */
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Chat Rooms"));
+
+ cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, cell, FALSE);
+
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set (cell,
+ "xpad", (guint) 4,
+ "ypad", (guint) 1,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ NULL);
+
+ gtk_tree_view_column_pack_start (column, cell, TRUE);
+
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_append_column (view, column);
+}
+
+static void
+new_chatroom_dialog_update_buttons (GossipNewChatroomDialog *dialog)
+{
+ GtkButton *button;
+ GtkWidget *image;
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ guint items;
+ const gchar *room;
+
+ /* Sort out Join button. */
+ button = GTK_BUTTON (dialog->button_join);
+
+ image = gtk_button_get_image (button);
+ if (!image) {
+ image = gtk_image_new ();
+ gtk_button_set_image (button, image);
+ }
+ //gtk_button_set_use_stock (button, FALSE);
+
+ room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
+
+ /* Collect necessary information first. */
+ view = GTK_TREE_VIEW (dialog->treeview);
+ model = gtk_tree_view_get_model (view);
+ items = gtk_tree_model_iter_n_children (model, NULL);
+
+ if (items < 1 && !G_STR_EMPTY (room)) {
+ gtk_button_set_label (button, _("Create"));
+ gtk_image_set_from_stock (GTK_IMAGE (image),
+ GTK_STOCK_NEW,
+ GTK_ICON_SIZE_BUTTON);
+ } else {
+ gtk_button_set_label (button, _("Join"));
+ gtk_image_set_from_stock (GTK_IMAGE (image),
+ GTK_STOCK_EXECUTE,
+ GTK_ICON_SIZE_BUTTON);
+ }
+
+ gtk_widget_set_sensitive (dialog->button_join, !G_STR_EMPTY (room));
+}
+
+static void
+new_chatroom_dialog_update_widgets (GossipNewChatroomDialog *dialog)
+{
+ GossipAccountChooser *account_chooser;
+ McAccount *account;
+ McProfile *profile;
+ const gchar *protocol;
+
+ account_chooser = GOSSIP_ACCOUNT_CHOOSER (dialog->account_chooser);
+ account = gossip_account_chooser_get_account (account_chooser);
+ profile = mc_account_get_profile (account);
+ protocol = mc_profile_get_protocol_name (profile);
+
+ /* hardcode here known protocols */
+ if (strcmp (protocol, "jabber") == 0 ||
+ strcmp (protocol, "salut") == 0) {
+ gtk_widget_show (dialog->hbox_server);
+ gtk_widget_show (dialog->hbox_nick);
+ gtk_widget_show (dialog->vbox_browse);
+ }
+ else if (strcmp (protocol, "irc") == 0) {
+ gtk_widget_hide (dialog->hbox_server);
+ gtk_widget_hide (dialog->hbox_nick);
+ gtk_widget_show (dialog->vbox_browse);
+ } else {
+ gtk_widget_hide (dialog->hbox_server);
+ gtk_widget_hide (dialog->hbox_nick);
+ gtk_widget_hide (dialog->vbox_browse);
+ }
+
+ new_chatroom_dialog_set_defaults (dialog);
+ new_chatroom_dialog_update_buttons (dialog);
+
+ /* Final set up of the dialog */
+ gtk_widget_grab_focus (dialog->entry_room);
+
+ g_object_unref (account);
+ g_object_unref (profile);
+}
+
+static void
+new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
+ GossipNewChatroomDialog *dialog)
+{
+ new_chatroom_dialog_update_widgets (dialog);
+}
+
+static void
+new_chatroom_dialog_model_add (GossipNewChatroomDialog *dialog,
+ EmpathyRoomListItem *item)
+{
+ GtkTreeView *view;
+ GtkTreeSelection *selection;
+ GtkListStore *store;
+ GtkTreeIter iter;
+
+ /* Add to model */
+ view = GTK_TREE_VIEW (dialog->treeview);
+ selection = gtk_tree_view_get_selection (view);
+ store = GTK_LIST_STORE (dialog->model);
+
+ gtk_list_store_append (store, &iter);
+
+ gtk_list_store_set (store, &iter,
+ COL_NAME, item->name,
+ COL_POINTER, item,
+ -1);
+}
+
+static void
+new_chatroom_dialog_model_clear (GossipNewChatroomDialog *dialog)
+{
+ GtkListStore *store;
+
+ store = GTK_LIST_STORE (dialog->model);
+ gtk_list_store_clear (store);
+}
+
+static GList *
+new_chatroom_dialog_model_get_selected (GossipNewChatroomDialog *dialog)
+{
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GList *rows, *l;
+ GList *chatrooms = NULL;
+
+ view = GTK_TREE_VIEW (dialog->treeview);
+ selection = gtk_tree_view_get_selection (view);
+ model = gtk_tree_view_get_model (view);
+
+ rows = gtk_tree_selection_get_selected_rows (selection, NULL);
+ for (l = rows; l; l = l->next) {
+ GtkTreeIter iter;
+ EmpathyRoomListItem *chatroom;
+
+ if (!gtk_tree_model_get_iter (model, &iter, l->data)) {
+ continue;
+ }
+
+ gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
+ chatrooms = g_list_append (chatrooms, chatroom);
+ }
+
+ g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (rows);
+
+ return chatrooms;
+}
+
+static gboolean
+new_chatroom_dialog_model_filter_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GossipNewChatroomDialog *dialog)
+{
+ EmpathyRoomListItem *chatroom;
+ const gchar *text;
+ gchar *room_nocase;
+ gchar *text_nocase;
+ gboolean found = FALSE;
+
+ gtk_tree_model_get (model, iter, COL_POINTER, &chatroom, -1);
+
+ if (!chatroom) {
+ return TRUE;
+ }
+
+ text = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
+
+ /* Casefold */
+ room_nocase = g_utf8_casefold (chatroom->id, -1);
+ text_nocase = g_utf8_casefold (text, -1);
+
+ /* Compare */
+ if (g_utf8_strlen (text_nocase, -1) < 1 ||
+ strstr (room_nocase, text_nocase)) {
+ found = TRUE;
+ }
+
+ g_free (room_nocase);
+ g_free (text_nocase);
+
+ return found;
+}
+
+static void
+new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GossipNewChatroomDialog *dialog)
+{
+ gtk_widget_activate (dialog->button_join);
+}
+
+static void
+new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GossipNewChatroomDialog *dialog)
+{
+ new_chatroom_dialog_update_buttons (dialog);
+}
+
+static void
+new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GossipNewChatroomDialog *dialog)
+{
+ new_chatroom_dialog_update_buttons (dialog);
+}
+
+static void
+new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection,
+ GossipNewChatroomDialog *dialog)
+{
+ new_chatroom_dialog_update_buttons (dialog);
+}
+
+static void
+new_chatroom_dialog_set_defaults (GossipNewChatroomDialog *dialog)
+{
+ McAccount *account;
+ McProfile *profile;
+ GossipAccountChooser *account_chooser;
+ const gchar *server;
+
+ account_chooser = GOSSIP_ACCOUNT_CHOOSER (dialog->account_chooser);
+ account = gossip_account_chooser_get_account (account_chooser);
+ profile = mc_account_get_profile (account);
+ server = mc_profile_get_default_account_domain (profile);
+
+ if (server) {
+ gchar *conference_server;
+
+ conference_server = g_strconcat ("conference.",
+ server, NULL);
+ gtk_entry_set_text (GTK_ENTRY (dialog->entry_server),
+ conference_server);
+ g_free (conference_server);
+ }
+
+ g_object_unref (account);
+ g_object_unref (profile);
+}
+
+static void
+new_chatroom_dialog_join (GossipNewChatroomDialog *dialog)
+{
+ McAccount *account;
+ GossipAccountChooser *account_chooser;
+ MissionControl *mc;
+ TpConn *tp_conn;
+ GList *chatrooms, *l;
+ const gchar *room;
+ const gchar *server;
+ gchar *room_name = NULL;
+ const gchar *room_names[2] = {NULL, NULL};
+
+ chatrooms = new_chatroom_dialog_model_get_selected (dialog);
+ if (chatrooms) {
+ for (l = chatrooms; l; l = l->next) {
+ /* Join it */
+ }
+ g_list_free (chatrooms);
+ return;
+ }
+
+ room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
+ server = gtk_entry_get_text (GTK_ENTRY (dialog->entry_server));
+ account_chooser = GOSSIP_ACCOUNT_CHOOSER (dialog->account_chooser);
+ account = gossip_account_chooser_get_account (account_chooser);
+ mc = gossip_mission_control_new ();
+ tp_conn = mission_control_get_connection (mc, account, NULL);
+
+ if (!tp_conn) {
+ g_object_unref (mc);
+ return;
+ }
+
+ if (!G_STR_EMPTY (server)) {
+ room_name = g_strconcat (room, "@", server, NULL);
+ room_names[0] = room_name;
+ } else {
+ room_names[0] = room;
+ }
+
+ gossip_debug (DEBUG_DOMAIN, "Requesting handle for room '%s'",
+ room_names[0]);
+
+ /* Gives the ref of account/tp_conn to the callback */
+ tp_conn_request_handles_async (DBUS_G_PROXY (tp_conn),
+ TP_HANDLE_TYPE_ROOM,
+ room_names,
+ (tp_conn_request_handles_reply)
+ new_chatroom_dialog_request_handles_cb,
+ account);
+ g_free (room_name);
+ g_object_unref (mc);
+}
+
+static void
+new_chatroom_dialog_request_handles_cb (DBusGProxy *proxy,
+ GArray *handles,
+ GError *error,
+ McAccount *account)
+{
+ MissionControl *mc;
+ guint handle;
+
+ if (error) {
+ gossip_debug (DEBUG_DOMAIN,
+ "Error requesting room handle: %s",
+ error ? error->message : "No error given");
+ goto OUT;
+ }
+
+ mc = gossip_mission_control_new ();
+ handle = g_array_index (handles, guint, 0);
+
+ gossip_debug (DEBUG_DOMAIN, "Got handle %d, requesting channel", handle);
+ mission_control_request_channel (mc,
+ account,
+ TP_IFACE_CHANNEL_TYPE_TEXT,
+ handle,
+ TP_HANDLE_TYPE_ROOM,
+ NULL, NULL);
+ g_object_unref (mc);
+
+OUT:
+ g_object_unref (account);
+ g_object_unref (proxy);
+}
+
+static void
+new_chatroom_dialog_entry_changed_cb (GtkWidget *entry,
+ GossipNewChatroomDialog *dialog)
+{
+ if (entry == dialog->entry_room) {
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (dialog->filter));
+ }
+
+ new_chatroom_dialog_update_buttons (dialog);
+}
+
+static void
+new_chatroom_dialog_browse_start (GossipNewChatroomDialog *dialog)
+{
+ if (0) {
+ new_chatroom_dialog_model_clear (dialog);
+ new_chatroom_dialog_model_add (dialog, NULL);
+ }
+}
+
+static void
+new_chatroom_dialog_browse_stop (GossipNewChatroomDialog *dialog)
+{
+}
+
+static void
+new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget,
+ GossipNewChatroomDialog *dialog)
+{
+ new_chatroom_dialog_togglebutton_refresh_toggled_cb (dialog->togglebutton_refresh,
+ dialog);
+}
+
+static void
+new_chatroom_dialog_togglebutton_refresh_toggled_cb (GtkWidget *widget,
+ GossipNewChatroomDialog *dialog)
+{
+ gboolean toggled;
+
+ toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ if (toggled) {
+ new_chatroom_dialog_browse_start (dialog);
+ } else {
+ new_chatroom_dialog_browse_stop (dialog);
+ }
+}
+
diff --git a/libempathy-gtk/gossip-new-chatroom-dialog.glade b/libempathy-gtk/gossip-new-chatroom-dialog.glade
new file mode 100644
index 000000000..49bdadb64
--- /dev/null
+++ b/libempathy-gtk/gossip-new-chatroom-dialog.glade
@@ -0,0 +1,519 @@
+<?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="new_chatroom_dialog">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Join New</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">350</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="icon_name">gtk-new</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-vbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area4">
+ <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-close</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">-7</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button_join">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox29">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-execute</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label79">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Join</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.5</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">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </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="GtkVBox" id="vbox_widgets">
+ <property name="border_width">5</property>
+ <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">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox_browse">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox_server">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkLabel" id="label_server">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Server:</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="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</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>
+ <property name="width_chars">25</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToggleButton" id="togglebutton_refresh">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Re_fresh</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>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</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="GtkHBox" id="hbox_room">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <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="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_room">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Enter the room name to join here or click on one or more rooms in the list.</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">True</property>
+ <property name="width_chars">32</property>
+ </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="GtkHBox" id="hbox_nick">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+
+ <child>
+ <widget class="GtkLabel" id="label_nick">
+ <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_nick</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">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry_nick">
+ <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="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>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox_browse">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox_status">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox35">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">3</property>
+
+ <child>
+ <widget class="GtkImage" id="image_status">
+ <property name="visible">True</property>
+ <property name="icon_size">2</property>
+ <property name="icon_name">gtk-find</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label_status">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Browse:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</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">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>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <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="tooltip" translatable="yes">This list represents all chat rooms hosted on the server you have entered.</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</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>
+ </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-new-chatroom-dialog.h b/libempathy-gtk/gossip-new-chatroom-dialog.h
new file mode 100644
index 000000000..44b7ce67f
--- /dev/null
+++ b/libempathy-gtk/gossip-new-chatroom-dialog.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006-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: Martyn Russell <martyn@imendio.com>
+ * Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __GOSSIP_NEW_CHATROOMS_WINDOW_H__
+#define __GOSSIP_NEW_CHATROOMS_WINDOW_H__
+
+G_BEGIN_DECLS
+
+void gossip_new_chatroom_dialog_show (GtkWindow *parent);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_NEW_CHATROOMS_WINDOW_H__ */
diff --git a/libempathy/empathy-tp-chatroom.c b/libempathy/empathy-tp-chatroom.c
index 34875c10c..eb47c9bb3 100644
--- a/libempathy/empathy-tp-chatroom.c
+++ b/libempathy/empathy-tp-chatroom.c
@@ -250,8 +250,6 @@ tp_chatroom_members_added_cb (GossipTelepathyGroup *group,
EmpathyTpChatroomPriv *priv;
GList *contacts, *l;
- g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom));
-
priv = GET_PRIV (chatroom);
contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
@@ -275,6 +273,22 @@ tp_chatroom_members_removed_cb (GossipTelepathyGroup *group,
const gchar *message,
EmpathyTpChatroom *chatroom)
{
+ EmpathyTpChatroomPriv *priv;
+ GList *contacts, *l;
+
+ priv = GET_PRIV (chatroom);
+
+ contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles);
+ for (l = contacts; l; l = l->next) {
+ GossipContact *contact;
+
+ contact = l->data;
+
+ g_signal_emit_by_name (chatroom, "contact-removed", contact);
+
+ g_object_unref (contact);
+ }
+ g_list_free (contacts);
}
static void
@@ -295,6 +309,16 @@ tp_chatroom_add (EmpathyContactList *list,
GossipContact *contact,
const gchar *message)
{
+ EmpathyTpChatroomPriv *priv;
+
+ g_return_if_fail (EMPATHY_IS_TP_CHATROOM (list));
+ g_return_if_fail (GOSSIP_IS_CONTACT (contact));
+
+ priv = GET_PRIV (list);
+
+ gossip_telepathy_group_add_member (priv->group,
+ gossip_contact_get_handle (contact),
+ message);
}
static void
@@ -302,6 +326,16 @@ tp_chatroom_remove (EmpathyContactList *list,
GossipContact *contact,
const gchar *message)
{
+ EmpathyTpChatroomPriv *priv;
+
+ g_return_if_fail (EMPATHY_IS_TP_CHATROOM (list));
+ g_return_if_fail (GOSSIP_IS_CONTACT (contact));
+
+ priv = GET_PRIV (list);
+
+ gossip_telepathy_group_remove_member (priv->group,
+ gossip_contact_get_handle (contact),
+ message);
}
static GList *