]> git.0d.be Git - empathy.git/blob - src/ev-sidebar.c
fix unused-but-set-variable warnings
[empathy.git] / src / ev-sidebar.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2004 Red Hat, Inc.
4  *            (C) 2007 Jan Arne Petersen
5  *
6  *  Authors:
7  *    Jonathan Blandford <jrb@alum.mit.edu>
8  *    Jan Arne Petersen <jpetersen@jpetersen.org>
9  *
10  * Evince is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * Evince is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301  USA.
23  *
24  * Thursday 03 May 2007: Bastien Nocera: Add exception clause.
25  * See license_change file for details.
26  *
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <gtk/gtk.h>
35 #include <gdk/gdkkeysyms.h>
36
37 #include "ev-sidebar.h"
38
39 enum
40 {
41         PAGE_COLUMN_ID,
42         PAGE_COLUMN_TITLE,
43         PAGE_COLUMN_NUM_COLS
44 };
45
46 struct _EvSidebarPrivate {
47         GtkWidget *combobox;
48         GtkWidget *notebook;
49 };
50
51 enum {
52         CLOSED,
53         LAST_SIGNAL
54 };
55
56 static int ev_sidebar_table_signals[LAST_SIGNAL] = { 0 };
57
58 G_DEFINE_TYPE (EvSidebar, ev_sidebar, GTK_TYPE_VBOX)
59
60 #define EV_SIDEBAR_GET_PRIVATE(object) \
61                 (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR, EvSidebarPrivate))
62
63 static void
64 ev_sidebar_class_init (EvSidebarClass *ev_sidebar_class)
65 {
66         GObjectClass *g_object_class;
67  
68         g_object_class = G_OBJECT_CLASS (ev_sidebar_class);
69            
70         g_type_class_add_private (g_object_class, sizeof (EvSidebarPrivate));
71
72         ev_sidebar_table_signals[CLOSED] =
73                 g_signal_new ("closed",
74                                 G_TYPE_FROM_CLASS (g_object_class),
75                                 G_SIGNAL_RUN_LAST,
76                                 G_STRUCT_OFFSET (EvSidebarClass, closed),
77                                 NULL, NULL,
78                                 g_cclosure_marshal_VOID__VOID,
79                                 G_TYPE_NONE, 0);
80
81 }
82
83 static void
84 ev_sidebar_close_clicked_cb (GtkWidget *widget,
85                              gpointer   user_data)
86 {
87         EvSidebar *ev_sidebar = EV_SIDEBAR (user_data);
88
89         g_signal_emit (G_OBJECT (ev_sidebar),
90                         ev_sidebar_table_signals[CLOSED], 0, NULL);
91         gtk_widget_hide (GTK_WIDGET (ev_sidebar));
92 }
93
94 static void
95 ev_sidebar_combobox_changed_cb (GtkComboBox *combo_box,
96                                 gpointer   user_data)
97 {
98         EvSidebar *ev_sidebar = EV_SIDEBAR (user_data);
99         GtkTreeModel *model;
100         GtkTreeIter iter;
101
102         model = gtk_combo_box_get_model (combo_box);
103
104         if (gtk_combo_box_get_active_iter (combo_box, &iter)) {
105                 GtkTreePath *path;
106                 gint *indices;
107
108                 path = gtk_tree_model_get_path (model, &iter);
109                 indices = gtk_tree_path_get_indices (path);
110
111                 if (indices != NULL) {
112                         gtk_notebook_set_current_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), indices[0]);
113                 }
114
115                 gtk_tree_path_free (path);
116         }
117 }
118
119 static void
120 ev_sidebar_init (EvSidebar *ev_sidebar)
121 {
122         GtkTreeModel *page_model;
123         GtkWidget *vbox, *hbox;
124         GtkWidget *close_button;
125         GtkCellRenderer *renderer;
126         GtkWidget *image;
127
128         ev_sidebar->priv = EV_SIDEBAR_GET_PRIVATE (ev_sidebar);
129
130         /* data model */
131         page_model = (GtkTreeModel *)
132                         gtk_list_store_new (PAGE_COLUMN_NUM_COLS,
133                                             G_TYPE_STRING,
134                                             G_TYPE_STRING,
135                                             GTK_TYPE_WIDGET,
136                                             G_TYPE_INT);
137
138         /* create a 6 6 6 0 border with GtkBoxes */
139         hbox = gtk_hbox_new (FALSE, 6);
140         gtk_box_pack_start (GTK_BOX (ev_sidebar), hbox, TRUE, TRUE, 6);
141
142         vbox = gtk_vbox_new (FALSE, 6);
143         gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
144         gtk_box_pack_start (GTK_BOX (hbox), gtk_vbox_new (FALSE, 0), FALSE, FALSE, 0);
145
146         /* top option menu */
147         hbox = gtk_hbox_new (FALSE, 6);
148         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
149         gtk_widget_show (hbox);
150
151         ev_sidebar->priv->combobox = gtk_combo_box_new_with_model (page_model);
152         g_signal_connect (ev_sidebar->priv->combobox, "changed",
153                           G_CALLBACK (ev_sidebar_combobox_changed_cb),
154                           ev_sidebar);
155
156         renderer = gtk_cell_renderer_text_new ();
157         gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (ev_sidebar->priv->combobox), renderer, TRUE);
158         gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (ev_sidebar->priv->combobox), renderer, "text", PAGE_COLUMN_TITLE);
159
160         gtk_box_pack_start (GTK_BOX (hbox), ev_sidebar->priv->combobox, TRUE, TRUE, 0);
161         gtk_widget_show (ev_sidebar->priv->combobox);
162
163         g_object_unref (G_OBJECT (page_model));
164
165         close_button = gtk_button_new ();
166         gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
167         g_signal_connect (close_button, "clicked",
168                           G_CALLBACK (ev_sidebar_close_clicked_cb),
169                           ev_sidebar);
170
171         image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
172                                           GTK_ICON_SIZE_MENU);
173         gtk_container_add (GTK_CONTAINER (close_button), image);
174         gtk_widget_show (image);
175    
176         gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
177         gtk_widget_show (close_button);
178    
179         ev_sidebar->priv->notebook = gtk_notebook_new ();
180         gtk_notebook_set_show_border (GTK_NOTEBOOK (ev_sidebar->priv->notebook), FALSE);
181         gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ev_sidebar->priv->notebook), FALSE);
182         gtk_box_pack_start (GTK_BOX (vbox), ev_sidebar->priv->notebook,
183                             TRUE, TRUE, 0);
184         gtk_widget_show (ev_sidebar->priv->notebook);
185 }
186
187 /* Public functions */
188
189 GtkWidget *
190 ev_sidebar_new (void)
191 {
192         GtkWidget *ev_sidebar;
193
194         ev_sidebar = g_object_new (EV_TYPE_SIDEBAR, NULL);
195
196         return ev_sidebar;
197 }
198
199 /* NOTE: Return values from this have to be g_free()d */
200 char *
201 ev_sidebar_get_current_page (EvSidebar *ev_sidebar)
202 {
203         GtkTreeModel *model;
204         GtkTreeIter iter;
205         char *id;
206
207         g_return_val_if_fail (EV_IS_SIDEBAR (ev_sidebar), NULL);
208         g_return_val_if_fail (ev_sidebar->priv != NULL, NULL);
209
210         model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox));
211
212         if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter)) {
213                 gtk_tree_model_get (model, &iter, PAGE_COLUMN_ID, &id, -1);
214
215                 return id;
216         }
217
218         return NULL;
219 }
220
221 static gboolean
222 ev_sidebar_get_iter_for_page_id (EvSidebar *ev_sidebar,
223                                  const char *new_page_id,
224                                  GtkTreeIter *iter)
225 {
226         GtkTreeModel *model;
227         gboolean valid;
228         gchar *page_id;
229
230         g_return_val_if_fail (EV_IS_SIDEBAR (ev_sidebar), FALSE);
231         g_return_val_if_fail (ev_sidebar->priv != NULL, FALSE);
232         g_return_val_if_fail (iter != NULL, FALSE);
233
234         model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox));
235
236         valid = gtk_tree_model_get_iter_first (model, iter);
237
238         while (valid) {
239                 gtk_tree_model_get (model, iter, PAGE_COLUMN_ID, &page_id, -1);
240
241                 if (page_id != NULL && strcmp (new_page_id, page_id) == 0) {
242                         g_free (page_id);
243                         return TRUE;
244                 }
245                 g_free (page_id);
246
247                 valid = gtk_tree_model_iter_next (model, iter);
248         }
249
250         return FALSE;
251 }
252
253 void
254 ev_sidebar_set_current_page (EvSidebar *ev_sidebar, const char *new_page_id)
255 {
256         GtkTreeIter iter;
257
258         g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar));
259         g_return_if_fail (new_page_id != NULL);
260
261
262         if (ev_sidebar_get_iter_for_page_id (ev_sidebar, new_page_id, &iter)) {
263                 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter);
264         }
265 }
266
267 void
268 ev_sidebar_add_page (EvSidebar   *ev_sidebar,
269                      const gchar *page_id,
270                      const gchar *title,
271                      GtkWidget   *main_widget)
272 {
273         GtkTreeIter iter, iter2;
274         GtkTreeModel *model;
275            
276         g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar));
277         g_return_if_fail (page_id != NULL);
278         g_return_if_fail (title != NULL);
279         g_return_if_fail (GTK_IS_WIDGET (main_widget));
280
281         model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox));
282
283         gtk_widget_set_sensitive (GTK_WIDGET (ev_sidebar), TRUE);
284
285         gtk_widget_show (main_widget);  
286         gtk_notebook_append_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), main_widget, NULL);
287
288         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
289         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
290                             PAGE_COLUMN_ID, page_id,
291                             PAGE_COLUMN_TITLE, title,
292                             -1);
293
294         if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter2)) {
295                 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter);
296         }
297 }
298
299 void
300 ev_sidebar_remove_page (EvSidebar   *ev_sidebar,
301                         const gchar *page_id)
302 {
303         GtkTreeIter iter;
304         GtkTreeModel *model;
305            
306         g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar));
307         g_return_if_fail (page_id != NULL);
308
309         model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox));
310
311         if (ev_sidebar_get_iter_for_page_id (ev_sidebar, page_id, &iter)) {
312                 GtkTreePath *path;
313                 gint *indices;
314
315                 path = gtk_tree_model_get_path (model, &iter);
316                 indices = gtk_tree_path_get_indices (path);
317
318                 g_assert (indices != NULL);
319                 gtk_notebook_remove_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), indices[0]);
320
321                 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
322
323                 if (gtk_tree_model_iter_n_children (model, NULL) != 0) {
324                         gtk_tree_path_prev (path);
325
326                         if (gtk_tree_model_get_iter (model, &iter, path)) {
327                                 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter);
328                         }
329                 } else {
330                         gtk_widget_set_sensitive (GTK_WIDGET (ev_sidebar), FALSE);
331                 }
332
333                 gtk_tree_path_free (path);
334         }
335 }
336