1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2006-2007 Imendio AB
4 * Copyright (C) 2007 Collabora Ltd.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
21 * Authors: Martyn Russell <martyn@imendio.com>
22 * Xavier Claessens <xclaesse@gmail.com>
31 #include <glade/glade.h>
33 #include <glib/gi18n.h>
35 #include <libmissioncontrol/mission-control.h>
36 #include <libmissioncontrol/mc-account.h>
37 #include <libmissioncontrol/mc-profile.h>
39 #include <libempathy/gossip-utils.h>
40 #include <libempathy/gossip-debug.h>
42 #include "gossip-new-chatroom-dialog.h"
43 #include "gossip-account-chooser.h"
44 //#include "gossip-chatrooms-window.h"
45 #include "gossip-ui-utils.h"
46 #include "ephy-spinner.h"
48 #define DEBUG_DOMAIN "NewChatroomDialog"
53 GtkWidget *vbox_widgets;
55 GtkWidget *hbox_account;
56 GtkWidget *label_account;
57 GtkWidget *account_chooser;
59 GtkWidget *hbox_server;
60 GtkWidget *label_server;
61 GtkWidget *entry_server;
62 GtkWidget *togglebutton_refresh;
65 GtkWidget *label_room;
66 GtkWidget *entry_room;
69 GtkWidget *label_nick;
70 GtkWidget *entry_nick;
72 GtkWidget *vbox_browse;
73 GtkWidget *image_status;
74 GtkWidget *label_status;
75 GtkWidget *hbox_status;
81 GtkWidget *button_join;
82 GtkWidget *button_close;
83 } GossipNewChatroomDialog;
90 } EmpathyRoomListItem;
99 static void new_chatroom_dialog_response_cb (GtkWidget *widget,
101 GossipNewChatroomDialog *dialog);
102 static void new_chatroom_dialog_destroy_cb (GtkWidget *widget,
103 GossipNewChatroomDialog *dialog);
104 static void new_chatroom_dialog_model_setup (GossipNewChatroomDialog *dialog);
105 static void new_chatroom_dialog_model_add_columns (GossipNewChatroomDialog *dialog);
106 static void new_chatroom_dialog_update_buttons (GossipNewChatroomDialog *dialog);
107 static void new_chatroom_dialog_update_widgets (GossipNewChatroomDialog *dialog);
108 static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
109 GossipNewChatroomDialog *dialog);
110 static void new_chatroom_dialog_model_add (GossipNewChatroomDialog *dialog,
111 EmpathyRoomListItem *item);
112 static void new_chatroom_dialog_model_clear (GossipNewChatroomDialog *dialog);
113 static GList * new_chatroom_dialog_model_get_selected (GossipNewChatroomDialog *dialog);
114 static gboolean new_chatroom_dialog_model_filter_func (GtkTreeModel *model,
116 GossipNewChatroomDialog *dialog);
117 static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view,
119 GtkTreeViewColumn *column,
120 GossipNewChatroomDialog *dialog);
121 static void new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model,
124 GossipNewChatroomDialog *dialog);
125 static void new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model,
127 GossipNewChatroomDialog *dialog);
128 static void new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection,
129 GossipNewChatroomDialog *dialog);
130 static void new_chatroom_dialog_join (GossipNewChatroomDialog *dialog);
131 static void new_chatroom_dialog_entry_changed_cb (GtkWidget *entry,
132 GossipNewChatroomDialog *dialog);
133 static void new_chatroom_dialog_browse_start (GossipNewChatroomDialog *dialog);
134 static void new_chatroom_dialog_browse_stop (GossipNewChatroomDialog *dialog);
135 static void new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget,
136 GossipNewChatroomDialog *dialog);
137 static void new_chatroom_dialog_togglebutton_refresh_toggled_cb (GtkWidget *widget,
138 GossipNewChatroomDialog *dialog);
140 static GossipNewChatroomDialog *dialog_p = NULL;
143 gossip_new_chatroom_dialog_show (GtkWindow *parent)
145 GossipNewChatroomDialog *dialog;
149 GtkSizeGroup *size_group;
152 gtk_window_present (GTK_WINDOW (dialog_p->window));
156 dialog_p = dialog = g_new0 (GossipNewChatroomDialog, 1);
158 glade = gossip_glade_get_file ("gossip-new-chatroom-dialog.glade",
159 "new_chatroom_dialog",
161 "new_chatroom_dialog", &dialog->window,
162 "hbox_account", &dialog->hbox_account,
163 "label_account", &dialog->label_account,
164 "vbox_widgets", &dialog->vbox_widgets,
165 "label_server", &dialog->label_server,
166 "label_room", &dialog->label_room,
167 "label_nick", &dialog->label_nick,
168 "hbox_server", &dialog->hbox_server,
169 "hbox_room", &dialog->hbox_room,
170 "hbox_nick", &dialog->hbox_nick,
171 "entry_server", &dialog->entry_server,
172 "entry_room", &dialog->entry_room,
173 "entry_nick", &dialog->entry_nick,
174 "togglebutton_refresh", &dialog->togglebutton_refresh,
175 "vbox_browse", &dialog->vbox_browse,
176 "image_status", &dialog->image_status,
177 "label_status", &dialog->label_status,
178 "hbox_status", &dialog->hbox_status,
179 "treeview", &dialog->treeview,
180 "button_join", &dialog->button_join,
183 gossip_glade_connect (glade,
185 "new_chatroom_dialog", "response", new_chatroom_dialog_response_cb,
186 "new_chatroom_dialog", "destroy", new_chatroom_dialog_destroy_cb,
187 "entry_nick", "changed", new_chatroom_dialog_entry_changed_cb,
188 "entry_server", "changed", new_chatroom_dialog_entry_changed_cb,
189 "entry_server", "activate", new_chatroom_dialog_entry_server_activate_cb,
190 "entry_room", "changed", new_chatroom_dialog_entry_changed_cb,
191 "togglebutton_refresh", "toggled", new_chatroom_dialog_togglebutton_refresh_toggled_cb,
194 g_object_unref (glade);
196 g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog_p);
198 /* Label alignment */
199 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
201 gtk_size_group_add_widget (size_group, dialog->label_account);
202 gtk_size_group_add_widget (size_group, dialog->label_server);
203 gtk_size_group_add_widget (size_group, dialog->label_room);
204 gtk_size_group_add_widget (size_group, dialog->label_nick);
206 g_object_unref (size_group);
208 /* Account chooser for custom */
209 dialog->account_chooser = gossip_account_chooser_new ();
210 gtk_box_pack_start (GTK_BOX (dialog->hbox_account),
211 dialog->account_chooser,
213 gtk_widget_show (dialog->account_chooser);
215 g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed",
216 G_CALLBACK (new_chatroom_dialog_account_changed_cb),
220 accounts = mc_accounts_list ();
221 account_num = g_list_length (accounts);
223 g_list_foreach (accounts, (GFunc) g_object_unref, NULL);
224 g_list_free (accounts);
226 if (account_num > 1) {
227 gtk_widget_show (dialog->hbox_account);
229 /* Show no accounts combo box */
230 gtk_widget_hide (dialog->hbox_account);
234 dialog->throbber = ephy_spinner_new ();
235 ephy_spinner_set_size (EPHY_SPINNER (dialog->throbber), GTK_ICON_SIZE_LARGE_TOOLBAR);
236 gtk_widget_show (dialog->throbber);
238 gtk_box_pack_start (GTK_BOX (dialog->hbox_status), dialog->throbber,
241 /* Set up chatrooms treeview */
242 new_chatroom_dialog_model_setup (dialog);
244 /* Set things up according to the account type */
245 new_chatroom_dialog_update_widgets (dialog);
248 gtk_window_set_transient_for (GTK_WINDOW (dialog->window),
249 GTK_WINDOW (parent));
252 gtk_widget_show (dialog->window);
256 new_chatroom_dialog_response_cb (GtkWidget *widget,
258 GossipNewChatroomDialog *dialog)
260 if (response == GTK_RESPONSE_OK) {
261 new_chatroom_dialog_join (dialog);
264 gtk_widget_destroy (widget);
268 new_chatroom_dialog_destroy_cb (GtkWidget *widget,
269 GossipNewChatroomDialog *dialog)
271 g_object_unref (dialog->model);
272 g_object_unref (dialog->filter);
278 new_chatroom_dialog_model_setup (GossipNewChatroomDialog *dialog)
282 GtkTreeSelection *selection;
285 view = GTK_TREE_VIEW (dialog->treeview);
287 g_signal_connect (view, "row-activated",
288 G_CALLBACK (new_chatroom_dialog_model_row_activated_cb),
292 store = gtk_list_store_new (COL_COUNT,
293 G_TYPE_STRING, /* Image */
294 G_TYPE_STRING, /* Text */
295 G_TYPE_POINTER); /* infos */
297 dialog->model = GTK_TREE_MODEL (store);
300 dialog->filter = gtk_tree_model_filter_new (dialog->model, NULL);
302 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (dialog->filter),
303 (GtkTreeModelFilterVisibleFunc)
304 new_chatroom_dialog_model_filter_func,
308 gtk_tree_view_set_model (view, dialog->filter);
310 g_signal_connect (dialog->filter, "row-inserted",
311 G_CALLBACK (new_chatroom_dialog_model_row_inserted_cb),
313 g_signal_connect (dialog->filter, "row-deleted",
314 G_CALLBACK (new_chatroom_dialog_model_row_deleted_cb),
318 selection = gtk_tree_view_get_selection (view);
319 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
320 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
321 COL_NAME, GTK_SORT_ASCENDING);
323 g_signal_connect (selection, "changed",
324 G_CALLBACK (new_chatroom_dialog_model_selection_changed), dialog);
327 new_chatroom_dialog_model_add_columns (dialog);
331 new_chatroom_dialog_model_add_columns (GossipNewChatroomDialog *dialog)
334 GtkTreeViewColumn *column;
335 GtkCellRenderer *cell;
337 view = GTK_TREE_VIEW (dialog->treeview);
338 gtk_tree_view_set_headers_visible (view, FALSE);
340 /* Chatroom pointer */
341 column = gtk_tree_view_column_new ();
342 gtk_tree_view_column_set_title (column, _("Chat Rooms"));
344 cell = gtk_cell_renderer_pixbuf_new ();
345 gtk_tree_view_column_pack_start (column, cell, FALSE);
347 cell = gtk_cell_renderer_text_new ();
351 "ellipsize", PANGO_ELLIPSIZE_END,
354 gtk_tree_view_column_pack_start (column, cell, TRUE);
356 gtk_tree_view_column_set_expand (column, TRUE);
357 gtk_tree_view_append_column (view, column);
361 new_chatroom_dialog_update_buttons (GossipNewChatroomDialog *dialog)
370 /* Sort out Join button. */
371 button = GTK_BUTTON (dialog->button_join);
373 image = gtk_button_get_image (button);
375 image = gtk_image_new ();
376 gtk_button_set_image (button, image);
378 //gtk_button_set_use_stock (button, FALSE);
380 room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
382 /* Collect necessary information first. */
383 view = GTK_TREE_VIEW (dialog->treeview);
384 model = gtk_tree_view_get_model (view);
385 items = gtk_tree_model_iter_n_children (model, NULL);
387 if (items < 1 && !G_STR_EMPTY (room)) {
388 gtk_button_set_label (button, _("Create"));
389 gtk_image_set_from_stock (GTK_IMAGE (image),
391 GTK_ICON_SIZE_BUTTON);
393 gtk_button_set_label (button, _("Join"));
394 gtk_image_set_from_stock (GTK_IMAGE (image),
396 GTK_ICON_SIZE_BUTTON);
399 gtk_widget_set_sensitive (dialog->button_join, !G_STR_EMPTY (room));
403 new_chatroom_dialog_update_widgets (GossipNewChatroomDialog *dialog)
405 GossipAccountChooser *account_chooser;
408 const gchar *protocol;
410 account_chooser = GOSSIP_ACCOUNT_CHOOSER (dialog->account_chooser);
411 account = gossip_account_chooser_get_account (account_chooser);
412 profile = mc_account_get_profile (account);
413 protocol = mc_profile_get_protocol_name (profile);
415 /* hardcode here known protocols */
416 if (strcmp (protocol, "jabber") == 0) {
419 server = mc_profile_get_default_account_domain (profile);
421 gchar *conference_server;
423 conference_server = g_strconcat ("conference.",
425 gtk_entry_set_text (GTK_ENTRY (dialog->entry_server),
427 g_free (conference_server);
430 gtk_widget_show (dialog->hbox_server);
431 gtk_widget_show (dialog->hbox_nick);
432 gtk_widget_show (dialog->vbox_browse);
435 else if (strcmp (protocol, "salut") == 0) {
436 gtk_widget_hide (dialog->hbox_server);
437 gtk_widget_show (dialog->hbox_nick);
438 gtk_widget_show (dialog->vbox_browse);
440 else if (strcmp (protocol, "irc") == 0) {
441 gtk_widget_hide (dialog->hbox_server);
442 gtk_widget_hide (dialog->hbox_nick);
443 gtk_widget_show (dialog->vbox_browse);
445 gtk_widget_hide (dialog->hbox_server);
446 gtk_widget_hide (dialog->hbox_nick);
447 gtk_widget_hide (dialog->vbox_browse);
450 new_chatroom_dialog_update_buttons (dialog);
452 /* Final set up of the dialog */
453 gtk_widget_grab_focus (dialog->entry_room);
455 g_object_unref (account);
456 g_object_unref (profile);
460 new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
461 GossipNewChatroomDialog *dialog)
463 new_chatroom_dialog_update_widgets (dialog);
467 new_chatroom_dialog_model_add (GossipNewChatroomDialog *dialog,
468 EmpathyRoomListItem *item)
471 GtkTreeSelection *selection;
476 view = GTK_TREE_VIEW (dialog->treeview);
477 selection = gtk_tree_view_get_selection (view);
478 store = GTK_LIST_STORE (dialog->model);
480 gtk_list_store_append (store, &iter);
482 gtk_list_store_set (store, &iter,
483 COL_NAME, item->name,
489 new_chatroom_dialog_model_clear (GossipNewChatroomDialog *dialog)
493 store = GTK_LIST_STORE (dialog->model);
494 gtk_list_store_clear (store);
498 new_chatroom_dialog_model_get_selected (GossipNewChatroomDialog *dialog)
502 GtkTreeSelection *selection;
504 GList *chatrooms = NULL;
506 view = GTK_TREE_VIEW (dialog->treeview);
507 selection = gtk_tree_view_get_selection (view);
508 model = gtk_tree_view_get_model (view);
510 rows = gtk_tree_selection_get_selected_rows (selection, NULL);
511 for (l = rows; l; l = l->next) {
513 EmpathyRoomListItem *chatroom;
515 if (!gtk_tree_model_get_iter (model, &iter, l->data)) {
519 gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
520 chatrooms = g_list_append (chatrooms, chatroom);
523 g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
530 new_chatroom_dialog_model_filter_func (GtkTreeModel *model,
532 GossipNewChatroomDialog *dialog)
534 EmpathyRoomListItem *chatroom;
538 gboolean found = FALSE;
540 gtk_tree_model_get (model, iter, COL_POINTER, &chatroom, -1);
546 text = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
549 room_nocase = g_utf8_casefold (chatroom->id, -1);
550 text_nocase = g_utf8_casefold (text, -1);
553 if (g_utf8_strlen (text_nocase, -1) < 1 ||
554 strstr (room_nocase, text_nocase)) {
558 g_free (room_nocase);
559 g_free (text_nocase);
565 new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view,
567 GtkTreeViewColumn *column,
568 GossipNewChatroomDialog *dialog)
570 gtk_widget_activate (dialog->button_join);
574 new_chatroom_dialog_model_row_inserted_cb (GtkTreeModel *model,
577 GossipNewChatroomDialog *dialog)
579 new_chatroom_dialog_update_buttons (dialog);
583 new_chatroom_dialog_model_row_deleted_cb (GtkTreeModel *model,
585 GossipNewChatroomDialog *dialog)
587 new_chatroom_dialog_update_buttons (dialog);
591 new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection,
592 GossipNewChatroomDialog *dialog)
594 new_chatroom_dialog_update_buttons (dialog);
598 new_chatroom_dialog_join (GossipNewChatroomDialog *dialog)
601 GossipAccountChooser *account_chooser;
603 GList *chatrooms, *l;
605 const gchar *server = NULL;
606 gchar *room_name = NULL;
608 chatrooms = new_chatroom_dialog_model_get_selected (dialog);
610 for (l = chatrooms; l; l = l->next) {
613 g_list_free (chatrooms);
617 room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
618 if (GTK_WIDGET_VISIBLE (dialog->hbox_server)) {
619 server = gtk_entry_get_text (GTK_ENTRY (dialog->entry_server));
621 account_chooser = GOSSIP_ACCOUNT_CHOOSER (dialog->account_chooser);
622 account = gossip_account_chooser_get_account (account_chooser);
624 if (!G_STR_EMPTY (server)) {
625 room_name = g_strconcat (room, "@", server, NULL);
627 room_name = g_strdup (room);
630 gossip_debug (DEBUG_DOMAIN, "Requesting channel for '%s'", room_name);
632 mc = gossip_mission_control_new ();
633 mission_control_request_channel_with_string_handle (mc,
635 TP_IFACE_CHANNEL_TYPE_TEXT,
644 new_chatroom_dialog_entry_changed_cb (GtkWidget *entry,
645 GossipNewChatroomDialog *dialog)
647 if (entry == dialog->entry_room) {
648 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (dialog->filter));
651 new_chatroom_dialog_update_buttons (dialog);
655 new_chatroom_dialog_browse_start (GossipNewChatroomDialog *dialog)
658 new_chatroom_dialog_model_clear (dialog);
659 new_chatroom_dialog_model_add (dialog, NULL);
664 new_chatroom_dialog_browse_stop (GossipNewChatroomDialog *dialog)
669 new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget,
670 GossipNewChatroomDialog *dialog)
672 new_chatroom_dialog_togglebutton_refresh_toggled_cb (dialog->togglebutton_refresh,
677 new_chatroom_dialog_togglebutton_refresh_toggled_cb (GtkWidget *widget,
678 GossipNewChatroomDialog *dialog)
682 toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
685 new_chatroom_dialog_browse_start (dialog);
687 new_chatroom_dialog_browse_stop (dialog);