]> git.0d.be Git - empathy.git/blob - src/empathy-chatrooms-window.c
Add en_GB in gitignore
[empathy.git] / src / empathy-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-2008 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/empathy-chatroom-manager.h>
37 #include <libempathy/empathy-utils.h>
38
39 #include <libempathy-gtk/empathy-account-chooser.h>
40 #include <libempathy-gtk/empathy-ui-utils.h>
41
42 #include "empathy-chatrooms-window.h"
43 #include "empathy-new-chatroom-dialog.h"
44
45 typedef struct {
46         EmpathyChatroomManager *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 } EmpathyChatroomsWindow;
59
60 static void             chatrooms_window_destroy_cb                      (GtkWidget             *widget,
61                                                                           EmpathyChatroomsWindow *window);
62 static void             chatrooms_window_model_setup                     (EmpathyChatroomsWindow *window);
63 static void             chatrooms_window_model_add_columns               (EmpathyChatroomsWindow *window);
64 static void             chatrooms_window_model_refresh_data              (EmpathyChatroomsWindow *window,
65                                                                           gboolean               first_time);
66 static void             chatrooms_window_model_add                       (EmpathyChatroomsWindow *window,
67                                                                           EmpathyChatroom        *chatroom,
68                                                                           gboolean               set_active);
69 static void             chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle  *cell,
70                                                                           gchar                  *path_string,
71                                                                           EmpathyChatroomsWindow  *window);
72 static EmpathyChatroom * chatrooms_window_model_get_selected              (EmpathyChatroomsWindow *window);
73 static void             chatrooms_window_model_action_selected           (EmpathyChatroomsWindow *window);
74 static void             chatrooms_window_row_activated_cb                (GtkTreeView           *tree_view,
75                                                                           GtkTreePath           *path,
76                                                                           GtkTreeViewColumn     *column,
77                                                                           EmpathyChatroomsWindow *window);
78 static void             chatrooms_window_button_remove_clicked_cb        (GtkWidget             *widget,
79                                                                           EmpathyChatroomsWindow *window);
80 static void             chatrooms_window_button_edit_clicked_cb          (GtkWidget             *widget,
81                                                                           EmpathyChatroomsWindow *window);
82 static void             chatrooms_window_button_close_clicked_cb         (GtkWidget             *widget,
83                                                                           EmpathyChatroomsWindow *window);
84 static void             chatrooms_window_chatroom_added_cb               (EmpathyChatroomManager *manager,
85                                                                           EmpathyChatroom        *chatroom,
86                                                                           EmpathyChatroomsWindow *window);
87 static void             chatrooms_window_chatroom_removed_cb             (EmpathyChatroomManager *manager,
88                                                                           EmpathyChatroom        *chatroom,
89                                                                           EmpathyChatroomsWindow *window);
90 static gboolean         chatrooms_window_remove_chatroom_foreach         (GtkTreeModel          *model,
91                                                                           GtkTreePath           *path,
92                                                                           GtkTreeIter           *iter,
93                                                                           EmpathyChatroom        *chatroom);
94 static void             chatrooms_window_account_changed_cb              (GtkWidget             *combo_box,
95                                                                           EmpathyChatroomsWindow *window);
96
97 enum {
98         COL_IMAGE,
99         COL_NAME,
100         COL_ROOM,
101         COL_AUTO_CONNECT,
102         COL_POINTER,
103         COL_COUNT
104 };
105
106 void
107 empathy_chatrooms_window_show (GtkWindow *parent)
108 {
109         static EmpathyChatroomsWindow *window = NULL;
110         GladeXML                     *glade;
111         gchar                        *filename;
112
113         if (window) {
114                 gtk_window_present (GTK_WINDOW (window->window));
115                 return;
116         }
117
118         window = g_new0 (EmpathyChatroomsWindow, 1);
119
120         filename = empathy_file_lookup ("empathy-chatrooms-window.glade", "src");
121         glade = empathy_glade_get_file (filename,
122                                        "chatrooms_window",
123                                        NULL,
124                                        "chatrooms_window", &window->window,
125                                        "hbox_account", &window->hbox_account,
126                                        "label_account", &window->label_account,
127                                        "treeview", &window->treeview,
128                                        "button_edit", &window->button_edit,
129                                        "button_remove", &window->button_remove,
130                                        "button_close", &window->button_close,
131                                        NULL);
132         g_free (filename);
133
134         empathy_glade_connect (glade,
135                               window,
136                               "chatrooms_window", "destroy", chatrooms_window_destroy_cb,
137                               "button_remove", "clicked", chatrooms_window_button_remove_clicked_cb,
138                               "button_edit", "clicked", chatrooms_window_button_edit_clicked_cb,
139                               "button_close", "clicked", chatrooms_window_button_close_clicked_cb,
140                               NULL);
141
142         g_object_unref (glade);
143
144         g_object_add_weak_pointer (G_OBJECT (window->window), (gpointer) &window);
145
146         /* Get the session and chat room manager */
147         window->manager = empathy_chatroom_manager_dup_singleton (NULL);
148
149         g_signal_connect (window->manager, "chatroom-added",
150                           G_CALLBACK (chatrooms_window_chatroom_added_cb),
151                           window);
152         g_signal_connect (window->manager, "chatroom-removed",
153                           G_CALLBACK (chatrooms_window_chatroom_removed_cb),
154                           window);
155
156         /* Account chooser for chat rooms */
157         window->account_chooser = empathy_account_chooser_new ();
158         empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser),
159                                             empathy_account_chooser_filter_is_connected,
160                                             NULL);
161         g_object_set (window->account_chooser, 
162                       "has-all-option", TRUE,
163                       NULL);
164         empathy_account_chooser_set_account (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser), NULL);
165
166         gtk_box_pack_start (GTK_BOX (window->hbox_account),
167                             window->account_chooser,
168                             TRUE, TRUE, 0);
169
170         g_signal_connect (window->account_chooser, "changed",
171                           G_CALLBACK (chatrooms_window_account_changed_cb),
172                           window);
173
174         gtk_widget_show (window->account_chooser);
175
176         /* Set up chatrooms */
177         chatrooms_window_model_setup (window);
178
179         /* Set focus */
180         gtk_widget_grab_focus (window->treeview);
181
182         /* Last touches */
183         if (parent) {
184                 gtk_window_set_transient_for (GTK_WINDOW (window->window),
185                                               GTK_WINDOW (parent));
186         }
187
188         gtk_widget_show (window->window);
189 }
190
191 static void
192 chatrooms_window_destroy_cb (GtkWidget             *widget,
193                              EmpathyChatroomsWindow *window)
194 {
195         g_signal_handlers_disconnect_by_func (window->manager,
196                                               chatrooms_window_chatroom_added_cb,
197                                               window);
198         g_signal_handlers_disconnect_by_func (window->manager,
199                                               chatrooms_window_chatroom_removed_cb,
200                                               window);
201         g_object_unref (window->manager);
202         g_free (window);
203 }
204
205 static void
206 chatrooms_window_model_setup (EmpathyChatroomsWindow *window)
207 {
208         GtkTreeView      *view;
209         GtkListStore     *store;
210         GtkTreeSelection *selection;
211
212         /* View */
213         view = GTK_TREE_VIEW (window->treeview);
214
215         g_signal_connect (view, "row-activated",
216                           G_CALLBACK (chatrooms_window_row_activated_cb),
217                           window);
218
219         /* Store */
220         store = gtk_list_store_new (COL_COUNT,
221                                     G_TYPE_STRING,         /* Image */
222                                     G_TYPE_STRING,         /* Name */
223                                     G_TYPE_STRING,         /* Room */
224                                     G_TYPE_BOOLEAN,        /* Auto start */
225                                     EMPATHY_TYPE_CHATROOM); /* Chatroom */
226
227         gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
228
229         /* Selection */ 
230         selection = gtk_tree_view_get_selection (view);
231         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
232
233         /* Columns */
234         chatrooms_window_model_add_columns (window);
235
236         /* Add data */
237         chatrooms_window_model_refresh_data (window, TRUE);
238
239         /* Clean up */
240         g_object_unref (store);
241 }
242
243 static void
244 chatrooms_window_model_add_columns (EmpathyChatroomsWindow *window)
245 {
246         GtkTreeView       *view;
247         GtkTreeModel      *model;
248         GtkTreeViewColumn *column;
249         GtkCellRenderer   *cell;
250         gint               count;
251
252         view = GTK_TREE_VIEW (window->treeview);
253         model = gtk_tree_view_get_model (view);
254
255         gtk_tree_view_set_headers_visible (view, TRUE);
256         gtk_tree_view_set_headers_clickable (view, TRUE);
257
258         /* Name & Status */
259         column = gtk_tree_view_column_new ();
260         count = gtk_tree_view_append_column (view, column);
261
262         gtk_tree_view_column_set_title (column, _("Name"));
263         gtk_tree_view_column_set_expand (column, TRUE);
264         gtk_tree_view_column_set_sort_column_id (column, count - 1);
265
266         cell = gtk_cell_renderer_pixbuf_new ();
267         gtk_tree_view_column_pack_start (column, cell, FALSE);
268         gtk_tree_view_column_add_attribute (column, cell, "icon-name", COL_IMAGE);
269
270         cell = gtk_cell_renderer_text_new ();
271         g_object_set (cell,
272                       "xpad", 4,
273                       "ypad", 1,
274                       NULL);
275         gtk_tree_view_column_pack_start (column, cell, TRUE);
276         gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
277
278         /* Room */
279         cell = gtk_cell_renderer_text_new ();
280         column = gtk_tree_view_column_new_with_attributes (_("Room"), cell, 
281                                                            "text", COL_ROOM, 
282                                                            NULL);
283         count = gtk_tree_view_append_column (view, column);
284         gtk_tree_view_column_set_sort_column_id (column, count - 1);
285         window->room_column = count - 1;
286
287         /* Chatroom auto connect */
288         cell = gtk_cell_renderer_toggle_new ();
289         column = gtk_tree_view_column_new_with_attributes (_("Auto-Connect"), cell,
290                                                            "active", COL_AUTO_CONNECT,
291                                                            NULL);
292         count = gtk_tree_view_append_column (view, column);
293         gtk_tree_view_column_set_sort_column_id (column, count - 1);
294
295         g_signal_connect (cell, "toggled",
296                           G_CALLBACK (chatrooms_window_model_cell_auto_connect_toggled),
297                           window);
298
299         /* Sort model */
300         gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0, 
301                                               GTK_SORT_ASCENDING);
302 }
303
304 static void
305 chatrooms_window_model_refresh_data (EmpathyChatroomsWindow *window,
306                                      gboolean               first_time)
307 {
308         GtkTreeView           *view;
309         GtkTreeSelection      *selection;
310         GtkTreeModel          *model;
311         GtkListStore          *store;
312         GtkTreeIter            iter;
313         GtkTreeViewColumn     *column;
314         EmpathyAccountChooser  *account_chooser;
315         McAccount             *account;
316         GList                 *chatrooms, *l;
317
318         view = GTK_TREE_VIEW (window->treeview);
319         selection = gtk_tree_view_get_selection (view);
320         model = gtk_tree_view_get_model (view);
321         store = GTK_LIST_STORE (model);
322
323         /* Look up chatrooms */
324         account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser);
325         account = empathy_account_chooser_get_account (account_chooser);
326
327         chatrooms = empathy_chatroom_manager_get_chatrooms (window->manager, account);
328
329         /* Sort out columns, we only show the server column for
330          * selected protocol types, such as Jabber. 
331          */
332         if (account) {
333                 column = gtk_tree_view_get_column (view, window->room_column);
334                 gtk_tree_view_column_set_visible (column, TRUE);
335         } else {
336                 column = gtk_tree_view_get_column (view, window->room_column);
337                 gtk_tree_view_column_set_visible (column, FALSE);
338         }
339
340         /* Clean out the store */
341         gtk_list_store_clear (store);
342
343         /* Populate with chatroom list. */
344         for (l = chatrooms; l; l = l->next) {
345                 chatrooms_window_model_add (window, l->data,  FALSE);
346         }
347
348         if (gtk_tree_model_get_iter_first (model, &iter)) {
349                 gtk_tree_selection_select_iter (selection, &iter);
350         }
351
352         if (account) {
353                 g_object_unref (account);
354         }
355
356         g_list_free (chatrooms);
357 }
358
359 static void
360 chatrooms_window_model_add (EmpathyChatroomsWindow *window,
361                             EmpathyChatroom        *chatroom,
362                             gboolean               set_active)
363 {
364         GtkTreeView      *view;
365         GtkTreeModel     *model;
366         GtkTreeSelection *selection;
367         GtkListStore     *store;
368         GtkTreeIter       iter;
369
370         view = GTK_TREE_VIEW (window->treeview);
371         selection = gtk_tree_view_get_selection (view);
372         model = gtk_tree_view_get_model (view);
373         store = GTK_LIST_STORE (model);
374
375         gtk_list_store_append (store, &iter);
376         gtk_list_store_set (store, &iter,
377                             COL_NAME, empathy_chatroom_get_name (chatroom),
378                             COL_ROOM, empathy_chatroom_get_room (chatroom),
379                             COL_AUTO_CONNECT, empathy_chatroom_get_auto_connect (chatroom),
380                             COL_POINTER, chatroom,
381                             -1);
382
383         if (set_active) {
384                 gtk_tree_selection_select_iter (selection, &iter);
385         }
386 }
387
388 static void
389 chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle  *cell,
390                                                   gchar                  *path_string,
391                                                   EmpathyChatroomsWindow  *window)
392 {
393         EmpathyChatroom *chatroom;
394         gboolean        enabled;
395         GtkTreeView    *view;
396         GtkTreeModel   *model;
397         GtkListStore   *store;
398         GtkTreePath    *path;
399         GtkTreeIter     iter;
400
401         view = GTK_TREE_VIEW (window->treeview);
402         model = gtk_tree_view_get_model (view);
403         store = GTK_LIST_STORE (model);
404
405         path = gtk_tree_path_new_from_string (path_string);
406
407         gtk_tree_model_get_iter (model, &iter, path);
408         gtk_tree_model_get (model, &iter,
409                             COL_AUTO_CONNECT, &enabled,
410                             COL_POINTER, &chatroom,
411                             -1);
412
413         enabled = !enabled;
414
415         empathy_chatroom_set_auto_connect (chatroom, enabled);
416
417         gtk_list_store_set (store, &iter, COL_AUTO_CONNECT, enabled, -1);
418         gtk_tree_path_free (path);
419         g_object_unref (chatroom);
420 }
421
422 static EmpathyChatroom *
423 chatrooms_window_model_get_selected (EmpathyChatroomsWindow *window)
424 {
425         GtkTreeView      *view;
426         GtkTreeModel     *model;
427         GtkTreeSelection *selection;
428         GtkTreeIter       iter;
429         EmpathyChatroom   *chatroom = NULL;
430
431         view = GTK_TREE_VIEW (window->treeview);
432         selection = gtk_tree_view_get_selection (view);
433
434         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
435                 gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
436         }
437
438         return chatroom;
439 }
440
441 static void
442 chatrooms_window_model_action_selected (EmpathyChatroomsWindow *window)
443 {
444         EmpathyChatroom *chatroom;
445         GtkTreeView    *view;
446         GtkTreeModel   *model;
447
448         view = GTK_TREE_VIEW (window->treeview);
449         model = gtk_tree_view_get_model (view);
450
451         chatroom = chatrooms_window_model_get_selected (window);
452         if (!chatroom) {
453                 return;
454         }
455
456         //empathy_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom);
457
458         g_object_unref (chatroom);
459 }
460
461 static void
462 chatrooms_window_row_activated_cb (GtkTreeView           *tree_view,
463                                    GtkTreePath           *path,
464                                    GtkTreeViewColumn     *column,
465                                    EmpathyChatroomsWindow *window)
466 {
467         if (GTK_WIDGET_IS_SENSITIVE (window->button_edit)) {
468                 chatrooms_window_model_action_selected (window);
469         }
470 }
471
472 static void
473 chatrooms_window_button_remove_clicked_cb (GtkWidget             *widget,
474                                            EmpathyChatroomsWindow *window)
475 {
476         EmpathyChatroom        *chatroom;
477         GtkTreeView           *view;
478         GtkTreeModel          *model;
479         GtkTreeSelection      *selection;
480         GtkTreeIter            iter;
481
482         /* Remove from treeview */
483         view = GTK_TREE_VIEW (window->treeview);
484         selection = gtk_tree_view_get_selection (view);
485
486         if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
487                 return;
488         }
489
490         gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1);
491         gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
492
493         /* Remove from config */
494         empathy_chatroom_manager_remove (window->manager, chatroom);
495
496         g_object_unref (chatroom);
497 }
498
499 static void
500 chatrooms_window_button_edit_clicked_cb (GtkWidget             *widget,
501                                          EmpathyChatroomsWindow *window)
502 {
503         EmpathyChatroom *chatroom;
504
505         chatroom = chatrooms_window_model_get_selected (window);
506         if (!chatroom) {
507                 return;
508         }
509
510         //empathy_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom);
511
512         g_object_unref (chatroom);
513 }
514
515 static void
516 chatrooms_window_button_close_clicked_cb (GtkWidget             *widget,
517                                           EmpathyChatroomsWindow *window)
518 {
519         gtk_widget_destroy (window->window);
520 }
521
522 static void
523 chatrooms_window_chatroom_added_cb (EmpathyChatroomManager *manager,
524                                     EmpathyChatroom        *chatroom,
525                                     EmpathyChatroomsWindow *window)
526 {
527         EmpathyAccountChooser *account_chooser;
528         McAccount            *account;
529
530         account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser);
531         account = empathy_account_chooser_get_account (account_chooser);
532
533         if (!account) {
534                 chatrooms_window_model_add (window, chatroom, FALSE);
535         } else {
536                 if (empathy_account_equal (account, empathy_chatroom_get_account (chatroom))) {
537                         chatrooms_window_model_add (window, chatroom, FALSE);
538                 }
539
540                 g_object_unref (account);
541         }
542 }
543
544 static void
545 chatrooms_window_chatroom_removed_cb (EmpathyChatroomManager *manager,
546                                       EmpathyChatroom        *chatroom,
547                                       EmpathyChatroomsWindow *window)
548 {
549         GtkTreeModel *model;
550
551         model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->treeview));
552
553         gtk_tree_model_foreach (model,
554                                 (GtkTreeModelForeachFunc) chatrooms_window_remove_chatroom_foreach,
555                                 chatroom);
556 }
557
558 static gboolean
559 chatrooms_window_remove_chatroom_foreach (GtkTreeModel   *model,
560                                           GtkTreePath    *path,
561                                           GtkTreeIter    *iter,
562                                           EmpathyChatroom *chatroom)
563 {
564         EmpathyChatroom *this_chatroom;
565
566         gtk_tree_model_get (model, iter, COL_POINTER, &this_chatroom, -1);
567
568         if (empathy_chatroom_equal (chatroom, this_chatroom)) {
569                 gtk_list_store_remove (GTK_LIST_STORE (model), iter);
570                 g_object_unref (this_chatroom);
571                 return TRUE;
572         }
573
574         g_object_unref (this_chatroom);
575
576         return FALSE;
577 }
578
579 static void
580 chatrooms_window_account_changed_cb (GtkWidget             *combo_box,
581                                      EmpathyChatroomsWindow *window)
582 {
583         chatrooms_window_model_refresh_data (window, FALSE);
584 }
585