]> git.0d.be Git - empathy.git/blob - libempathy-gtk/gossip-chatrooms-window.c
Fix warning when selecting all accounts.
[empathy.git] / libempathy-gtk / gossip-chatrooms-window.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2004-2007 Imendio AB
4  * Copyright (C) 2007 Collabora Ltd.
5  *
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.
10  *
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.
15  *
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.
20  *
21  * Authors: Xavier Claessens <xclaesse@gmail.com>
22  *          Martyn Russell <martyn@imendio.com>
23  *          Mikael Hallendal <micke@imendio.com>
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29 #include <stdio.h>
30
31 #include <gtk/gtk.h>
32 #include <glade/glade.h>
33 #include <glib.h>
34 #include <glib/gi18n.h>
35
36 #include <libempathy/gossip-chatroom-manager.h>
37 #include <libempathy/gossip-utils.h>
38
39 #include "gossip-account-chooser.h"
40 #include "gossip-chatrooms-window.h"
41 //#include "gossip-edit-chatroom-dialog.h"
42 #include "gossip-new-chatroom-dialog.h"
43 #include "gossip-ui-utils.h"
44
45 typedef struct {
46         GossipChatroomManager *manager;
47
48         GtkWidget             *window;
49         GtkWidget             *hbox_account;
50         GtkWidget             *label_account;
51         GtkWidget             *account_chooser;
52         GtkWidget             *treeview;
53         GtkWidget             *button_remove;
54         GtkWidget             *button_edit;
55         GtkWidget             *button_close;
56
57         gint                   room_column;
58 } GossipChatroomsWindow;
59
60 static void             chatrooms_window_destroy_cb                      (GtkWidget             *widget,
61                                                                           GossipChatroomsWindow *window);
62 static void             chatrooms_window_model_setup                     (GossipChatroomsWindow *window);
63 static void             chatrooms_window_model_add_columns               (GossipChatroomsWindow *window);
64 static void             chatrooms_window_model_refresh_data              (GossipChatroomsWindow *window,
65                                                                           gboolean               first_time);
66 static void             chatrooms_window_model_add                       (GossipChatroomsWindow *window,
67                                                                           GossipChatroom        *chatroom,
68                                                                           gboolean               set_active);
69 static void             chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle  *cell,
70                                                                           gchar                  *path_string,
71                                                                           GossipChatroomsWindow  *window);
72 static GossipChatroom * chatrooms_window_model_get_selected              (GossipChatroomsWindow *window);
73 static void             chatrooms_window_model_action_selected           (GossipChatroomsWindow *window);
74 static void             chatrooms_window_row_activated_cb                (GtkTreeView           *tree_view,
75                                                                           GtkTreePath           *path,
76                                                                           GtkTreeViewColumn     *column,
77                                                                           GossipChatroomsWindow *window);
78 static void             chatrooms_window_button_remove_clicked_cb        (GtkWidget             *widget,
79                                                                           GossipChatroomsWindow *window);
80 static void             chatrooms_window_button_edit_clicked_cb          (GtkWidget             *widget,
81                                                                           GossipChatroomsWindow *window);
82 static void             chatrooms_window_button_close_clicked_cb         (GtkWidget             *widget,
83                                                                           GossipChatroomsWindow *window);
84 static void             chatrooms_window_chatroom_added_cb               (GossipChatroomManager *manager,
85                                                                           GossipChatroom        *chatroom,
86                                                                           GossipChatroomsWindow *window);
87 static void             chatrooms_window_account_changed_cb              (GtkWidget             *combo_box,
88                                                                           GossipChatroomsWindow *window);
89
90 enum {
91         COL_IMAGE,
92         COL_NAME,
93         COL_ROOM,
94         COL_AUTO_CONNECT,
95         COL_POINTER,
96         COL_COUNT
97 };
98
99 void
100 gossip_chatrooms_window_show (GtkWindow *parent)
101 {
102         static GossipChatroomsWindow *window = NULL;
103         GladeXML                     *glade;
104
105         if (window) {
106                 gtk_window_present (GTK_WINDOW (window->window));
107                 return;
108         }
109
110         window = g_new0 (GossipChatroomsWindow, 1);
111
112         glade = gossip_glade_get_file ("gossip-chatrooms-window.glade",
113                                        "chatrooms_window",
114                                        NULL,
115                                        "chatrooms_window", &window->window,
116                                        "hbox_account", &window->hbox_account,
117                                        "label_account", &window->label_account,
118                                        "treeview", &window->treeview,
119                                        "button_edit", &window->button_edit,
120                                        "button_remove", &window->button_remove,
121                                        "button_close", &window->button_close,
122                                        NULL);
123
124         gossip_glade_connect (glade,
125                               window,
126                               "chatrooms_window", "destroy", chatrooms_window_destroy_cb,
127                               "button_remove", "clicked", chatrooms_window_button_remove_clicked_cb,
128                               "button_edit", "clicked", chatrooms_window_button_edit_clicked_cb,
129                               "button_close", "clicked", chatrooms_window_button_close_clicked_cb,
130                               NULL);
131
132         g_object_unref (glade);
133
134         g_object_add_weak_pointer (G_OBJECT (window->window), (gpointer) &window);
135
136         /* Get the session and chat room manager */
137         window->manager = gossip_chatroom_manager_new ();
138
139         g_signal_connect (window->manager, "chatroom-added",
140                           G_CALLBACK (chatrooms_window_chatroom_added_cb),
141                           window);
142
143         /* Account chooser for chat rooms */
144         window->account_chooser = gossip_account_chooser_new ();
145         gossip_account_chooser_set_account (GOSSIP_ACCOUNT_CHOOSER (window->account_chooser), NULL);
146         g_object_set (window->account_chooser, 
147                       "can-select-all", TRUE,
148                       "has-all-option", TRUE,
149                       NULL);
150
151         gtk_box_pack_start (GTK_BOX (window->hbox_account),
152                             window->account_chooser,
153                             TRUE, TRUE, 0);
154
155         g_signal_connect (window->account_chooser, "changed",
156                           G_CALLBACK (chatrooms_window_account_changed_cb),
157                           window);
158
159         gtk_widget_show (window->account_chooser);
160
161         /* Set up chatrooms */
162         chatrooms_window_model_setup (window);
163
164         /* Set focus */
165         gtk_widget_grab_focus (window->treeview);
166
167         /* Last touches */
168         if (parent) {
169                 gtk_window_set_transient_for (GTK_WINDOW (window->window),
170                                               GTK_WINDOW (parent));
171         }
172
173         gtk_widget_show (window->window);
174 }
175
176 static void
177 chatrooms_window_destroy_cb (GtkWidget             *widget,
178                              GossipChatroomsWindow *window)
179 {
180         g_object_unref (window->manager);
181         g_free (window);
182 }
183
184 static void
185 chatrooms_window_model_setup (GossipChatroomsWindow *window)
186 {
187         GtkTreeView      *view;
188         GtkListStore     *store;
189         GtkTreeSelection *selection;
190
191         /* View */
192         view = GTK_TREE_VIEW (window->treeview);
193
194         g_signal_connect (view, "row-activated",
195                           G_CALLBACK (chatrooms_window_row_activated_cb),
196                           window);
197
198         /* Store */
199         store = gtk_list_store_new (COL_COUNT,
200                                     G_TYPE_STRING,         /* Image */
201                                     G_TYPE_STRING,         /* Name */
202                                     G_TYPE_STRING,         /* Room */
203                                     G_TYPE_BOOLEAN,        /* Auto start */
204                                     GOSSIP_TYPE_CHATROOM); /* Chatroom */
205
206         gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
207
208         /* Selection */ 
209         selection = gtk_tree_view_get_selection (view);
210         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
211
212         /* Columns */
213         chatrooms_window_model_add_columns (window);
214
215         /* Add data */
216         chatrooms_window_model_refresh_data (window, TRUE);
217
218         /* Clean up */
219         g_object_unref (store);
220 }
221
222 static void
223 chatrooms_window_model_add_columns (GossipChatroomsWindow *window)
224 {
225         GtkTreeView       *view;
226         GtkTreeModel      *model;
227         GtkTreeViewColumn *column;
228         GtkCellRenderer   *cell;
229         gint               count;
230
231         view = GTK_TREE_VIEW (window->treeview);
232         model = gtk_tree_view_get_model (view);
233
234         gtk_tree_view_set_headers_visible (view, TRUE);
235         gtk_tree_view_set_headers_clickable (view, TRUE);
236
237         /* Name & Status */
238         column = gtk_tree_view_column_new ();
239         count = gtk_tree_view_append_column (view, column);
240
241         gtk_tree_view_column_set_title (column, _("Name"));
242         gtk_tree_view_column_set_expand (column, TRUE);
243         gtk_tree_view_column_set_sort_column_id (column, count - 1);
244
245         cell = gtk_cell_renderer_pixbuf_new ();
246         gtk_tree_view_column_pack_start (column, cell, FALSE);
247         gtk_tree_view_column_add_attribute (column, cell, "icon-name", COL_IMAGE);
248
249         cell = gtk_cell_renderer_text_new ();
250         g_object_set (cell,
251                       "xpad", 4,
252                       "ypad", 1,
253                       NULL);
254         gtk_tree_view_column_pack_start (column, cell, TRUE);
255         gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
256
257         /* Room */
258         cell = gtk_cell_renderer_text_new ();
259         column = gtk_tree_view_column_new_with_attributes (_("Room"), cell, 
260                                                            "text", COL_ROOM, 
261                                                            NULL);
262         count = gtk_tree_view_append_column (view, column);
263         gtk_tree_view_column_set_sort_column_id (column, count - 1);
264         window->room_column = count - 1;
265
266         /* Chatroom auto connect */
267         cell = gtk_cell_renderer_toggle_new ();
268         column = gtk_tree_view_column_new_with_attributes (_("Auto Connect"), cell,
269                                                            "active", COL_AUTO_CONNECT,
270                                                            NULL);
271         count = gtk_tree_view_append_column (view, column);
272         gtk_tree_view_column_set_sort_column_id (column, count - 1);
273
274         g_signal_connect (cell, "toggled",
275                           G_CALLBACK (chatrooms_window_model_cell_auto_connect_toggled),
276                           window);
277
278         /* Sort model */
279         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0, 
280                                               GTK_SORT_ASCENDING);
281 }
282
283 static void
284 chatrooms_window_model_refresh_data (GossipChatroomsWindow *window,
285                                      gboolean               first_time)
286 {
287         GtkTreeView           *view;
288         GtkTreeSelection      *selection;
289         GtkTreeModel          *model;
290         GtkListStore          *store;
291         GtkTreeIter            iter;
292         GtkTreeViewColumn     *column;
293         GossipAccountChooser  *account_chooser;
294         McAccount             *account;
295         GList                 *chatrooms, *l;
296
297         view = GTK_TREE_VIEW (window->treeview);
298         selection = gtk_tree_view_get_selection (view);
299         model = gtk_tree_view_get_model (view);
300         store = GTK_LIST_STORE (model);
301
302         /* Look up chatrooms */
303         account_chooser = GOSSIP_ACCOUNT_CHOOSER (window->account_chooser);
304         account = gossip_account_chooser_get_account (account_chooser);
305
306         chatrooms = gossip_chatroom_manager_get_chatrooms (window->manager, account);
307
308         /* Sort out columns, we only show the server column for
309          * selected protocol types, such as Jabber. 
310          */
311         if (account) {
312                 column = gtk_tree_view_get_column (view, window->room_column);
313                 gtk_tree_view_column_set_visible (column, TRUE);
314         } else {
315                 column = gtk_tree_view_get_column (view, window->room_column);
316                 gtk_tree_view_column_set_visible (column, FALSE);
317         }
318
319         /* Clean out the store */
320         gtk_list_store_clear (store);
321
322         /* Populate with chatroom list. */
323         for (l = chatrooms; l; l = l->next) {
324                 chatrooms_window_model_add (window, l->data,  FALSE);
325         }
326
327         if (gtk_tree_model_get_iter_first (model, &iter)) {
328                 gtk_tree_selection_select_iter (selection, &iter);
329         }
330
331         if (account) {
332                 g_object_unref (account);
333         }
334
335         g_list_free (chatrooms);
336 }
337
338 static void
339 chatrooms_window_model_add (GossipChatroomsWindow *window,
340                             GossipChatroom        *chatroom,
341                             gboolean               set_active)
342 {
343         GtkTreeView      *view;
344         GtkTreeModel     *model;
345         GtkTreeSelection *selection;
346         GtkListStore     *store;
347         GtkTreeIter       iter;
348
349         view = GTK_TREE_VIEW (window->treeview);
350         selection = gtk_tree_view_get_selection (view);
351         model = gtk_tree_view_get_model (view);
352         store = GTK_LIST_STORE (model);
353
354         gtk_list_store_append (store, &iter);
355         gtk_list_store_set (store, &iter,
356                             COL_NAME, gossip_chatroom_get_name (chatroom),
357                             COL_ROOM, gossip_chatroom_get_room (chatroom),
358                             COL_AUTO_CONNECT, gossip_chatroom_get_auto_connect (chatroom),
359                             COL_POINTER, chatroom,
360                             -1);
361
362         if (set_active) {
363                 gtk_tree_selection_select_iter (selection, &iter);
364         }
365 }
366
367 static void
368 chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle  *cell,
369                                                   gchar                  *path_string,
370                                                   GossipChatroomsWindow  *window)
371 {
372         GossipChatroom *chatroom;
373         gboolean        enabled;
374         GtkTreeView    *view;
375         GtkTreeModel   *model;
376         GtkListStore   *store;
377         GtkTreePath    *path;
378         GtkTreeIter     iter;
379
380         view = GTK_TREE_VIEW (window->treeview);
381         model = gtk_tree_view_get_model (view);
382         store = GTK_LIST_STORE (model);
383
384         path = gtk_tree_path_new_from_string (path_string);
385
386         gtk_tree_model_get_iter (model, &iter, path);
387         gtk_tree_model_get (model, &iter,
388                             COL_AUTO_CONNECT, &enabled,
389                             COL_POINTER, &chatroom,
390                             -1);
391
392         enabled = !enabled;
393
394         gossip_chatroom_set_auto_connect (chatroom, enabled);
395         gossip_chatroom_manager_store (window->manager);
396
397         gtk_list_store_set (store, &iter, COL_AUTO_CONNECT, enabled, -1);
398         gtk_tree_path_free (path);
399         g_object_unref (chatroom);
400 }
401
402 static GossipChatroom *
403 chatrooms_window_model_get_selected (GossipChatroomsWindow *window)
404 {
405         GtkTreeView      *view;
406         GtkTreeModel     *model;
407         GtkTreeSelection *selection;
408         GtkTreeIter       iter;
409         GossipChatroom   *chatroom = NULL;
410
411         view = GTK_TREE_VIEW (window->treeview);
412         selection = gtk_tree_view_get_selection (view);
413
414         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
415                 gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
416         }
417
418         return chatroom;
419 }
420
421 static void
422 chatrooms_window_model_action_selected (GossipChatroomsWindow *window)
423 {
424         GossipChatroom *chatroom;
425         GtkTreeView    *view;
426         GtkTreeModel   *model;
427
428         view = GTK_TREE_VIEW (window->treeview);
429         model = gtk_tree_view_get_model (view);
430
431         chatroom = chatrooms_window_model_get_selected (window);
432         if (!chatroom) {
433                 return;
434         }
435
436         //gossip_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom);
437
438         g_object_unref (chatroom);
439 }
440
441 static void
442 chatrooms_window_row_activated_cb (GtkTreeView           *tree_view,
443                                    GtkTreePath           *path,
444                                    GtkTreeViewColumn     *column,
445                                    GossipChatroomsWindow *window)
446 {
447         if (GTK_WIDGET_IS_SENSITIVE (window->button_edit)) {
448                 chatrooms_window_model_action_selected (window);
449         }
450 }
451
452 static void
453 chatrooms_window_button_remove_clicked_cb (GtkWidget             *widget,
454                                            GossipChatroomsWindow *window)
455 {
456         GossipChatroom        *chatroom;
457         GtkTreeView           *view;
458         GtkTreeModel          *model;
459         GtkTreeSelection      *selection;
460         GtkTreeIter            iter;
461
462         /* Remove from treeview */
463         view = GTK_TREE_VIEW (window->treeview);
464         selection = gtk_tree_view_get_selection (view);
465
466         if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
467                 return;
468         }
469
470         gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
471         gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
472
473         /* Remove from config */
474         gossip_chatroom_manager_remove (window->manager, chatroom);
475
476         g_object_unref (chatroom);
477 }
478
479 static void
480 chatrooms_window_button_edit_clicked_cb (GtkWidget             *widget,
481                                          GossipChatroomsWindow *window)
482 {
483         GossipChatroom *chatroom;
484
485         chatroom = chatrooms_window_model_get_selected (window);
486         if (!chatroom) {
487                 return;
488         }
489
490         //gossip_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom);
491
492         g_object_unref (chatroom);
493 }
494
495 static void
496 chatrooms_window_button_close_clicked_cb (GtkWidget             *widget,
497                                           GossipChatroomsWindow *window)
498 {
499         gtk_widget_destroy (window->window);
500 }
501
502 static void
503 chatrooms_window_chatroom_added_cb (GossipChatroomManager *manager,
504                                     GossipChatroom        *chatroom,
505                                     GossipChatroomsWindow *window)
506 {
507         GossipAccountChooser *account_chooser;
508         McAccount            *account;
509
510         account_chooser = GOSSIP_ACCOUNT_CHOOSER (window->account_chooser);
511         account = gossip_account_chooser_get_account (account_chooser);
512
513         if (!account) {
514                 chatrooms_window_model_add (window, chatroom, FALSE);
515         } else {
516                 if (gossip_account_equal (account, gossip_chatroom_get_account (chatroom))) {
517                         chatrooms_window_model_add (window, chatroom, FALSE);
518                 }
519
520                 g_object_unref (account);
521         }
522 }
523
524 static void
525 chatrooms_window_account_changed_cb (GtkWidget             *combo_box,
526                                      GossipChatroomsWindow *window)
527 {
528         chatrooms_window_model_refresh_data (window, FALSE);
529 }
530