]> git.0d.be Git - empathy.git/commitdiff
New objects: GossipAccountChooser and GossipNewChatroom, we can now join
authorXavier Claessens <xclaesse@gmail.com>
Wed, 23 May 2007 23:01:46 +0000 (23:01 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Wed, 23 May 2007 23:01:46 +0000 (23:01 +0000)
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.

svn path=/trunk/; revision=89

19 files changed:
ChangeLog
data/Makefile.am
data/empathy.desktop.in.in
data/gtalk.profile
data/irc.profile [new file with mode: 0644]
data/jabber.profile
data/msn.profile
data/salut.profile
libempathy-gtk/Makefile.am
libempathy-gtk/empathy-main-window.c
libempathy-gtk/gossip-account-chooser.c [new file with mode: 0644]
libempathy-gtk/gossip-account-chooser.h [new file with mode: 0644]
libempathy-gtk/gossip-account-widget-jabber.c
libempathy-gtk/gossip-account-widget-jabber.glade
libempathy-gtk/gossip-group-chat.c
libempathy-gtk/gossip-new-chatroom-dialog.c [new file with mode: 0644]
libempathy-gtk/gossip-new-chatroom-dialog.glade [new file with mode: 0644]
libempathy-gtk/gossip-new-chatroom-dialog.h [new file with mode: 0644]
libempathy/empathy-tp-chatroom.c

index 5d5212877cfb7e12756bf33183bebabde7583702..ab67c3debf4bea7a6aabcb300cb139e1b6bbf797 100644 (file)
--- 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.
index eca5bf4a2830734b8fa394ecfc6c501853b835c2..128f8aa645d5115f23053ce7cad9d36210fdc25c 100644 (file)
@@ -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
index eca31045bd9af02604cd78a018d9abdb8d701fec..abf48ce11476cdc46da30c2d2b424b72ce0ac046 100644 (file)
@@ -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
index c8d5de9a18d22b82dd46d43616c08f0ce5e80d76..f81dc27c3672b4c83648356bd81ba5a97763e7af 100644 (file)
@@ -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 (file)
index 0000000..90915c1
--- /dev/null
@@ -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
index 1d2ad2561b6ffec3e2ac239170cde80253cb6d3b..7da8254f4786763e539777762bcc510be7c11bdc 100644 (file)
@@ -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
index b344a4e6d38522decdd69441a1fb618c33cd72c0..44058fc15d07199a738035536be3a117c1f8b691 100644 (file)
@@ -5,3 +5,4 @@ DisplayName=MSN
 IconName = empathy-proto-msn
 ConfigurationUI = msn
 SupportsInvisible = 1
+Capabilities = chat-p2p, split-account, supports-avatars, supports-alias
index 2082881ee2ee25d91e32a07e3a434ed5f5af6e51..e9b346b39eb25dc67118b3b45ce10d514240e417 100644 (file)
@@ -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
 
index 7a5d1893a59e5e99594a98f5eedf69b2288bdfcc..f28e7411c8f934f6eb2c286d41fbd3da38d63134 100644 (file)
@@ -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
 
index 9f2e9daf042c3630d5c8736f52d749c5c302db25..aa49cffe000e7e5dccdccf84a2a32e4854304a8e 100644 (file)
@@ -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 (file)
index 0000000..8d3439f
--- /dev/null
@@ -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 (file)
index 0000000..b2d7c0c
--- /dev/null
@@ -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__ */
+
index 8282777bda49144db9deb42798a1aad22a43514d..e7334b4b564f6d670d95622f5cf06046ebe8b813 100644 (file)
@@ -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 : "");
index 19d13990a891e1c744f90bfb062cdc1502780863..12eec7576d4b182733c5ed4f0714df5cc789ee38 100644 (file)
       </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>
index b955ee21e2a5949a38740157961294d6affe0a0c..6cf897d676f3691ad7567fb4a6348f9efcd12d0e 100644 (file)
@@ -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 (file)
index 0000000..6c16ecb
--- /dev/null
@@ -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 (file)
index 0000000..49bdadb
--- /dev/null
@@ -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 (file)
index 0000000..44b7ce6
--- /dev/null
@@ -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__ */
index 34875c10cf64eabd765206b1d4ef86900227a5da..eb47c9bb37cc911e09aba48d2bd9c771931ac446 100644 (file)
@@ -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 *