1 /* ev-sidebar-bookmarks.c
2  *  this file is part of evince, a gnome document viewer
3  *
4  * Copyright (C) 2010 Carlos Garcia Campos  <carlosgc@gnome.org>
5  * Copyright (C) 2020 Germán Poo-Caamaño  <gpoo@gnome.org>
6  *
7  * Evince is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * Evince is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #include "config.h"
23 
24 #include <glib/gi18n.h>
25 
26 #include "ev-sidebar-bookmarks.h"
27 
28 #include "ev-document.h"
29 #include "ev-document-misc.h"
30 #include "ev-sidebar-page.h"
31 #include "ev-utils.h"
32 
33 enum {
34         PROP_0,
35         PROP_WIDGET
36 };
37 
38 enum {
39         COLUMN_MARKUP,
40         COLUMN_PAGE,
41         N_COLUMNS
42 };
43 
44 enum {
45         ACTIVATED,
46         N_SIGNALS
47 };
48 
49 static guint signals[N_SIGNALS] = { 0 };
50 
51 struct _EvSidebarBookmarksPrivate {
52         EvDocumentModel *model;
53         EvBookmarks     *bookmarks;
54 
55         GtkWidget       *tree_view;
56         GtkWidget       *del_button;
57         GtkWidget       *add_button;
58 
59         /* Popup menu */
60         GtkWidget       *popup;
61 };
62 
63 static void ev_sidebar_bookmarks_page_iface_init (EvSidebarPageInterface *iface);
64 static void ev_sidebar_bookmarks_selection_changed (GtkTreeSelection   *selection,
65 						    EvSidebarBookmarks *sidebar_bookmarks);
66 static void ev_sidebar_bookmarks_page_changed (EvSidebarBookmarks *sidebar_bookmarks,
67                                                gint                old_page,
68                                                gint                new_page);
69 
70 G_DEFINE_TYPE_EXTENDED (EvSidebarBookmarks,
71                         ev_sidebar_bookmarks,
72                         GTK_TYPE_BOX,
73                         0,
74                         G_ADD_PRIVATE (EvSidebarBookmarks)
75                         G_IMPLEMENT_INTERFACE (EV_TYPE_SIDEBAR_PAGE,
76                                                ev_sidebar_bookmarks_page_iface_init))
77 
78 static gint
ev_sidebar_bookmarks_get_selected_page(EvSidebarBookmarks * sidebar_bookmarks,GtkTreeSelection * selection)79 ev_sidebar_bookmarks_get_selected_page (EvSidebarBookmarks *sidebar_bookmarks,
80                                         GtkTreeSelection   *selection)
81 {
82         GtkTreeModel *model;
83         GtkTreeIter   iter;
84 
85         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
86                 guint page;
87 
88                 gtk_tree_model_get (model, &iter,
89                                     COLUMN_PAGE, &page,
90                                     -1);
91                 return page;
92         }
93 
94         return -1;
95 }
96 
97 static void
ev_bookmarks_popup_cmd_open_bookmark(GSimpleAction * action,GVariant * parameter,gpointer sidebar_bookmarks)98 ev_bookmarks_popup_cmd_open_bookmark (GSimpleAction *action,
99 				      GVariant      *parameter,
100                                       gpointer       sidebar_bookmarks)
101 {
102         EvSidebarBookmarksPrivate *priv = EV_SIDEBAR_BOOKMARKS (sidebar_bookmarks)->priv;
103         GtkTreeSelection          *selection;
104         gint                       page;
105         gint old_page = ev_document_model_get_page (priv->model);
106 
107         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
108         page = ev_sidebar_bookmarks_get_selected_page (sidebar_bookmarks, selection);
109         g_signal_emit (sidebar_bookmarks, signals[ACTIVATED], 0, old_page, page);
110         ev_document_model_set_page (priv->model, page);
111 }
112 
113 static void
ev_bookmarks_popup_cmd_rename_bookmark(GSimpleAction * action,GVariant * parameter,gpointer sidebar_bookmarks)114 ev_bookmarks_popup_cmd_rename_bookmark (GSimpleAction *action,
115 					GVariant      *parameter,
116                                         gpointer       sidebar_bookmarks)
117 {
118         EvSidebarBookmarksPrivate *priv = EV_SIDEBAR_BOOKMARKS (sidebar_bookmarks)->priv;
119         GtkTreeView               *tree_view = GTK_TREE_VIEW (priv->tree_view);
120         GtkTreeSelection          *selection;
121         GtkTreeModel              *model;
122         GtkTreeIter                iter;
123 
124 
125         selection = gtk_tree_view_get_selection (tree_view);
126         if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
127                 GtkTreePath *path;
128 
129                 path = gtk_tree_model_get_path (model, &iter);
130                 gtk_tree_view_set_cursor (tree_view, path,
131                                           gtk_tree_view_get_column (tree_view, 0),
132                                           TRUE);
133                 gtk_tree_path_free (path);
134         }
135 }
136 
137 static void
ev_bookmarks_popup_cmd_delete_bookmark(GSimpleAction * action,GVariant * parameter,gpointer sidebar_bookmarks)138 ev_bookmarks_popup_cmd_delete_bookmark (GSimpleAction *action,
139 					GVariant      *parameter,
140                                         gpointer       sidebar_bookmarks)
141 {
142         EvSidebarBookmarksPrivate *priv = EV_SIDEBAR_BOOKMARKS (sidebar_bookmarks)->priv;
143         GtkTreeSelection          *selection;
144         gint                       page;
145         EvBookmark                 bm;
146 
147         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
148         page = ev_sidebar_bookmarks_get_selected_page (sidebar_bookmarks, selection);
149         bm.page = page;
150         bm.title = NULL;
151         ev_bookmarks_delete (priv->bookmarks, &bm);
152 	if (gtk_widget_get_sensitive (priv->del_button))
153 		gtk_widget_set_sensitive (priv->del_button, FALSE);
154 }
155 
156 static GActionGroup *
create_action_group(EvSidebarBookmarks * sidebar_bookmarks)157 create_action_group (EvSidebarBookmarks *sidebar_bookmarks) {
158 	const GActionEntry popup_entries[] = {
159 		{ "open-bookmark", ev_bookmarks_popup_cmd_open_bookmark },
160 		{ "rename-bookmark", ev_bookmarks_popup_cmd_rename_bookmark },
161 		{ "delete-bookmark", ev_bookmarks_popup_cmd_delete_bookmark }
162 	};
163 	GSimpleActionGroup *group;
164 
165 	group = g_simple_action_group_new ();
166 	g_action_map_add_action_entries (G_ACTION_MAP (group),
167 					 popup_entries,
168 					 G_N_ELEMENTS (popup_entries),
169 					 sidebar_bookmarks);
170 
171 	return G_ACTION_GROUP (group);
172 }
173 
174 static gint
compare_bookmarks(EvBookmark * a,EvBookmark * b)175 compare_bookmarks (EvBookmark *a,
176                    EvBookmark *b)
177 {
178         if (a->page < b->page)
179                 return -1;
180         if (a->page > b->page)
181                 return 1;
182         return 0;
183 }
184 
185 static void
ev_sidebar_bookmarks_update(EvSidebarBookmarks * sidebar_bookmarks)186 ev_sidebar_bookmarks_update (EvSidebarBookmarks *sidebar_bookmarks)
187 {
188         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
189         GtkListStore              *model;
190         GList                     *items, *l;
191         GtkTreeIter                iter;
192         GtkTreeView               *tree_view = GTK_TREE_VIEW (priv->tree_view);
193         GtkTreeSelection          *selection = gtk_tree_view_get_selection (tree_view);
194 
195         model = GTK_LIST_STORE (gtk_tree_view_get_model (tree_view));
196 
197         g_signal_handlers_block_by_func (selection,
198                                          ev_sidebar_bookmarks_selection_changed,
199                                          sidebar_bookmarks);
200         gtk_list_store_clear (model);
201         g_signal_handlers_unblock_by_func (selection,
202                                            ev_sidebar_bookmarks_selection_changed,
203                                            sidebar_bookmarks);
204 
205         if (!priv->bookmarks) {
206                 g_object_set (priv->tree_view, "has-tooltip", FALSE, NULL);
207                 return;
208         }
209 
210         items = ev_bookmarks_get_bookmarks (priv->bookmarks);
211         items = g_list_sort (items, (GCompareFunc)compare_bookmarks);
212         for (l = items; l; l = g_list_next (l)) {
213                 EvBookmark *bm = (EvBookmark *)l->data;
214 
215                 gtk_list_store_append (model, &iter);
216                 gtk_list_store_set (model, &iter,
217                                     COLUMN_MARKUP, bm->title,
218                                     COLUMN_PAGE, bm->page,
219                                     -1);
220         }
221         g_list_free (items);
222         g_object_set (priv->tree_view, "has-tooltip", TRUE, NULL);
223 }
224 
225 static void
ev_sidebar_bookmarks_changed(EvBookmarks * bookmarks,EvSidebarBookmarks * sidebar_bookmarks)226 ev_sidebar_bookmarks_changed (EvBookmarks        *bookmarks,
227                               EvSidebarBookmarks *sidebar_bookmarks)
228 {
229         ev_sidebar_bookmarks_update (sidebar_bookmarks);
230 }
231 
232 static void
ev_sidebar_bookmarks_selection_changed(GtkTreeSelection * selection,EvSidebarBookmarks * sidebar_bookmarks)233 ev_sidebar_bookmarks_selection_changed (GtkTreeSelection   *selection,
234                                         EvSidebarBookmarks *sidebar_bookmarks)
235 {
236         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
237         gint                       page;
238 
239         page = ev_sidebar_bookmarks_get_selected_page (sidebar_bookmarks, selection);
240         if (page >= 0) {
241                 gint old_page = ev_document_model_get_page (priv->model);
242                 g_signal_emit (sidebar_bookmarks, signals[ACTIVATED], 0, old_page, page);
243                 ev_document_model_set_page (priv->model, page);
244                 gtk_widget_set_sensitive (priv->del_button, TRUE);
245         } else {
246                 gtk_widget_set_sensitive (priv->del_button, FALSE);
247         }
248 }
249 
ev_sidebar_bookmarks_page_changed(EvSidebarBookmarks * sidebar_bookmarks,gint old_page,gint new_page)250 static void ev_sidebar_bookmarks_page_changed (EvSidebarBookmarks *sidebar_bookmarks,
251                                                gint                old_page,
252                                                gint                new_page)
253 {
254         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
255         GtkTreeSelection          *selection;
256         gint                       selected_page;
257 
258         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
259         selected_page = ev_sidebar_bookmarks_get_selected_page (sidebar_bookmarks, selection);
260 
261         if (selected_page != new_page)
262                 gtk_tree_selection_unselect_all (selection);
263 }
264 
265 static void
ev_sidebar_bookmarks_del_clicked(GtkWidget * button,EvSidebarBookmarks * sidebar_bookmarks)266 ev_sidebar_bookmarks_del_clicked (GtkWidget          *button,
267                                   EvSidebarBookmarks *sidebar_bookmarks)
268 {
269         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
270         GtkTreeSelection          *selection;
271         gint                       page;
272         EvBookmark                 bm;
273 
274         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
275         page = ev_sidebar_bookmarks_get_selected_page (sidebar_bookmarks, selection);
276         if (page < 0)
277                 return;
278 
279         bm.page = page;
280         bm.title = NULL;
281         ev_bookmarks_delete (priv->bookmarks, &bm);
282 	if (gtk_widget_get_sensitive (priv->del_button))
283 		gtk_widget_set_sensitive (priv->del_button, FALSE);
284 }
285 
286 static void
ev_sidebar_bookmarks_bookmark_renamed(GtkCellRendererText * renderer,const gchar * path_string,const gchar * new_text,EvSidebarBookmarks * sidebar_bookmarks)287 ev_sidebar_bookmarks_bookmark_renamed (GtkCellRendererText *renderer,
288                                        const gchar         *path_string,
289                                        const gchar         *new_text,
290                                        EvSidebarBookmarks  *sidebar_bookmarks)
291 {
292         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
293         GtkTreePath               *path = gtk_tree_path_new_from_string (path_string);
294         GtkTreeModel              *model;
295         GtkTreeIter                iter;
296         guint                      page;
297         EvBookmark                 bm;
298 
299         if (!new_text || new_text[0] == '\0')
300                 return;
301 
302         model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree_view));
303         gtk_tree_model_get_iter (model, &iter, path);
304         gtk_tree_model_get (model, &iter,
305                             COLUMN_PAGE, &page,
306                             -1);
307         gtk_tree_path_free (path);
308 
309         bm.page = page;
310         bm.title = g_markup_escape_text (new_text, -1);
311         ev_bookmarks_update (priv->bookmarks, &bm);
312 }
313 
314 static gboolean
ev_sidebar_bookmarks_query_tooltip(GtkWidget * widget,gint x,gint y,gboolean keyboard_tip,GtkTooltip * tooltip,EvSidebarBookmarks * sidebar_bookmarks)315 ev_sidebar_bookmarks_query_tooltip (GtkWidget          *widget,
316                                     gint                x,
317                                     gint                y,
318                                     gboolean            keyboard_tip,
319                                     GtkTooltip         *tooltip,
320                                     EvSidebarBookmarks *sidebar_bookmarks)
321 {
322         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
323         GtkTreeModel              *model;
324         GtkTreeIter                iter;
325         GtkTreePath               *path = NULL;
326         EvDocument                *document;
327         guint                      page;
328         gchar                     *page_label;
329         gchar                     *text;
330 
331         model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree_view));
332         if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (priv->tree_view),
333                                                 &x, &y, keyboard_tip,
334                                                 &model, &path, &iter))
335                 return FALSE;
336 
337         gtk_tree_model_get (model, &iter,
338                             COLUMN_PAGE, &page,
339                             -1);
340 
341         document = ev_document_model_get_document (priv->model);
342         page_label = ev_document_get_page_label (document, page);
343         text = g_strdup_printf (_("Page %s"), page_label);
344         gtk_tooltip_set_text (tooltip, text);
345         g_free (text);
346         g_free (page_label);
347 
348         gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (priv->tree_view),
349                                        tooltip, path);
350         gtk_tree_path_free (path);
351 
352         return TRUE;
353 }
354 
355 static gboolean
ev_sidebar_bookmarks_popup_menu_show(EvSidebarBookmarks * sidebar_bookmarks,gint x,gint y,gboolean keyboard_mode)356 ev_sidebar_bookmarks_popup_menu_show (EvSidebarBookmarks *sidebar_bookmarks,
357                                       gint                x,
358                                       gint                y,
359                                       gboolean            keyboard_mode)
360 {
361         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
362         GtkTreeView               *tree_view = GTK_TREE_VIEW (sidebar_bookmarks->priv->tree_view);
363         GtkTreeSelection          *selection = gtk_tree_view_get_selection (tree_view);
364 
365         if (keyboard_mode) {
366                 if (!gtk_tree_selection_get_selected (selection, NULL, NULL))
367                         return FALSE;
368         } else {
369                 GtkTreePath *path;
370 
371                 if (!gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, NULL, NULL, NULL))
372                         return FALSE;
373 
374                 g_signal_handlers_block_by_func (selection,
375                                                  ev_sidebar_bookmarks_selection_changed,
376                                                  sidebar_bookmarks);
377                 gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
378                 g_signal_handlers_unblock_by_func (selection,
379                                                    ev_sidebar_bookmarks_selection_changed,
380                                                    sidebar_bookmarks);
381 		if (!gtk_widget_get_sensitive (priv->del_button))
382 			gtk_widget_set_sensitive (priv->del_button, TRUE);
383                 gtk_tree_path_free (path);
384         }
385 
386         if (keyboard_mode) {
387                 ev_gui_menu_popup_at_tree_view_selection (GTK_MENU (priv->popup),
388                                                           tree_view);
389         } else {
390                 gtk_menu_popup_at_pointer (GTK_MENU (priv->popup), NULL);
391         }
392 
393         return TRUE;
394 }
395 
396 static gboolean
ev_sidebar_bookmarks_button_press(GtkWidget * widget,GdkEventButton * event,EvSidebarBookmarks * sidebar_bookmarks)397 ev_sidebar_bookmarks_button_press (GtkWidget          *widget,
398                                    GdkEventButton     *event,
399                                    EvSidebarBookmarks *sidebar_bookmarks)
400 {
401         if (event->button != 3)
402                 return FALSE;
403 
404         return ev_sidebar_bookmarks_popup_menu_show (sidebar_bookmarks, event->x, event->y, FALSE);
405 }
406 
407 static gboolean
ev_sidebar_bookmarks_popup_menu(GtkWidget * widget)408 ev_sidebar_bookmarks_popup_menu (GtkWidget *widget)
409 {
410         EvSidebarBookmarks *sidebar_bookmarks = EV_SIDEBAR_BOOKMARKS (widget);
411         gint                x, y;
412 
413         ev_document_misc_get_pointer_position (widget, &x, &y);
414         return ev_sidebar_bookmarks_popup_menu_show (sidebar_bookmarks, x, y, TRUE);
415 }
416 
417 static void
ev_sidebar_bookmarks_dispose(GObject * object)418 ev_sidebar_bookmarks_dispose (GObject *object)
419 {
420         EvSidebarBookmarks *sidebar_bookmarks = EV_SIDEBAR_BOOKMARKS (object);
421         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
422 
423         if (priv->model) {
424                 g_object_unref (priv->model);
425                 priv->model = NULL;
426         }
427 
428         if (priv->bookmarks) {
429                 g_object_unref (priv->bookmarks);
430                 priv->bookmarks = NULL;
431         }
432 
433         G_OBJECT_CLASS (ev_sidebar_bookmarks_parent_class)->dispose (object);
434 }
435 
436 static void
ev_sidebar_bookmarks_init(EvSidebarBookmarks * sidebar_bookmarks)437 ev_sidebar_bookmarks_init (EvSidebarBookmarks *sidebar_bookmarks)
438 {
439         EvSidebarBookmarksPrivate *priv;
440         GtkWidget                 *swindow;
441         GtkWidget                 *hbox;
442         GtkListStore              *model;
443         GtkCellRenderer           *renderer;
444         GtkTreeSelection          *selection;
445 	GtkBuilder                *builder;
446 	GMenuModel                *popup_model;
447 
448         sidebar_bookmarks->priv = ev_sidebar_bookmarks_get_instance_private (sidebar_bookmarks);
449         priv = sidebar_bookmarks->priv;
450 
451         swindow = gtk_scrolled_window_new (NULL, NULL);
452         gtk_box_pack_start (GTK_BOX (sidebar_bookmarks), swindow, TRUE, TRUE, 0);
453         gtk_widget_show (swindow);
454 
455         model = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_UINT);
456         priv->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
457         g_object_unref (model);
458         g_signal_connect (priv->tree_view, "query-tooltip",
459                           G_CALLBACK (ev_sidebar_bookmarks_query_tooltip),
460                           sidebar_bookmarks);
461         g_signal_connect (priv->tree_view,
462                           "button-press-event",
463                           G_CALLBACK (ev_sidebar_bookmarks_button_press),
464                           sidebar_bookmarks);
465         gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE);
466         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
467         g_signal_connect (selection, "changed",
468                           G_CALLBACK (ev_sidebar_bookmarks_selection_changed),
469                           sidebar_bookmarks);
470 
471         renderer = gtk_cell_renderer_text_new ();
472         g_object_set (renderer,
473                       "ellipsize", PANGO_ELLIPSIZE_END,
474                       "editable", TRUE,
475                       NULL);
476         g_signal_connect (renderer, "edited",
477                           G_CALLBACK (ev_sidebar_bookmarks_bookmark_renamed),
478                           sidebar_bookmarks);
479         gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view),
480                                                      0, NULL, renderer,
481                                                      "markup", COLUMN_MARKUP,
482                                                      NULL);
483         gtk_container_add (GTK_CONTAINER (swindow), priv->tree_view);
484         gtk_widget_show (priv->tree_view);
485 
486         hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
487         g_object_set (hbox, "margin", 6, NULL);
488         gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
489         gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_EXPAND);
490 	gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
491 
492         priv->add_button = gtk_button_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
493         gtk_widget_set_tooltip_text (priv->add_button, _("Add bookmark"));
494         atk_object_set_name (gtk_widget_get_accessible (priv->add_button), _("Add bookmark"));
495         gtk_actionable_set_action_name (GTK_ACTIONABLE (priv->add_button),
496                                         "win.add-bookmark");
497         gtk_widget_set_sensitive (priv->add_button, FALSE);
498         gtk_box_pack_start (GTK_BOX (hbox), priv->add_button, FALSE, FALSE, 0);
499         gtk_widget_show (priv->add_button);
500 
501         priv->del_button = gtk_button_new_from_icon_name ("list-remove-symbolic", GTK_ICON_SIZE_MENU);
502         gtk_widget_set_tooltip_text (priv->del_button, _("Remove bookmark"));
503         atk_object_set_name (gtk_widget_get_accessible (priv->del_button), _("Remove bookmark"));
504         g_signal_connect (priv->del_button, "clicked",
505                           G_CALLBACK (ev_sidebar_bookmarks_del_clicked),
506                           sidebar_bookmarks);
507         gtk_widget_set_sensitive (priv->del_button, FALSE);
508         gtk_box_pack_start (GTK_BOX (hbox), priv->del_button, FALSE, FALSE, 0);
509         gtk_widget_show (priv->del_button);
510 
511         gtk_box_pack_end (GTK_BOX (sidebar_bookmarks), hbox, FALSE, TRUE, 0);
512         gtk_widget_show (hbox);
513         gtk_widget_show (GTK_WIDGET (sidebar_bookmarks));
514 
515         /* Popup menu */
516 	builder = gtk_builder_new_from_resource ("/org/gnome/evince/gtk/menus.ui");
517 	popup_model = g_object_ref (G_MENU_MODEL (gtk_builder_get_object (builder, "bookmarks-popup")));
518 	priv->popup = gtk_menu_new_from_model (popup_model);
519 	gtk_widget_insert_action_group (priv->popup,
520 					"bookmarks",
521 					create_action_group (sidebar_bookmarks));
522 	g_object_unref (builder);
523 }
524 
525 static void
ev_sidebar_bookmarks_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)526 ev_sidebar_bookmarks_get_property (GObject    *object,
527                                    guint       prop_id,
528                                    GValue     *value,
529                                    GParamSpec *pspec)
530 {
531         EvSidebarBookmarks *sidebar_bookmarks;
532 
533         sidebar_bookmarks = EV_SIDEBAR_BOOKMARKS (object);
534 
535         switch (prop_id) {
536         case PROP_WIDGET:
537                 g_value_set_object (value, sidebar_bookmarks->priv->tree_view);
538                 break;
539         default:
540                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
541                 break;
542         }
543 }
544 
545 static void
ev_sidebar_bookmarks_class_init(EvSidebarBookmarksClass * klass)546 ev_sidebar_bookmarks_class_init (EvSidebarBookmarksClass *klass)
547 {
548         GObjectClass   *g_object_class = G_OBJECT_CLASS (klass);
549         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
550 
551         g_object_class->get_property = ev_sidebar_bookmarks_get_property;
552         g_object_class->dispose = ev_sidebar_bookmarks_dispose;
553 
554         widget_class->popup_menu = ev_sidebar_bookmarks_popup_menu;
555 
556         g_object_class_override_property (g_object_class, PROP_WIDGET, "main-widget");
557 	/* Signals */
558         signals[ACTIVATED] =
559                 g_signal_new ("bookmark-activated",
560                               EV_TYPE_SIDEBAR_BOOKMARKS,
561                               G_SIGNAL_RUN_LAST,
562                               G_STRUCT_OFFSET (EvSidebarBookmarksClass, activated),
563                               NULL, NULL,
564                               NULL,
565                               G_TYPE_NONE, 2,
566                               G_TYPE_INT, G_TYPE_INT);
567 }
568 
569 GtkWidget *
ev_sidebar_bookmarks_new(void)570 ev_sidebar_bookmarks_new (void)
571 {
572         return GTK_WIDGET (g_object_new (EV_TYPE_SIDEBAR_BOOKMARKS,
573                                          "orientation", GTK_ORIENTATION_VERTICAL,
574                                          NULL));
575 }
576 
577 void
ev_sidebar_bookmarks_set_bookmarks(EvSidebarBookmarks * sidebar_bookmarks,EvBookmarks * bookmarks)578 ev_sidebar_bookmarks_set_bookmarks (EvSidebarBookmarks *sidebar_bookmarks,
579                                     EvBookmarks        *bookmarks)
580 {
581         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
582 
583         g_return_if_fail (EV_IS_BOOKMARKS (bookmarks));
584 
585         if (priv->bookmarks == bookmarks)
586                 return;
587 
588         if (priv->bookmarks)
589                 g_object_unref (priv->bookmarks);
590         priv->bookmarks = g_object_ref (bookmarks);
591         g_signal_connect (priv->bookmarks, "changed",
592                           G_CALLBACK (ev_sidebar_bookmarks_changed),
593                           sidebar_bookmarks);
594 
595         gtk_widget_set_sensitive (priv->add_button, TRUE);
596         ev_sidebar_bookmarks_update (sidebar_bookmarks);
597 }
598 
599 /* EvSidebarPageIface */
600 static void
ev_sidebar_bookmarks_set_model(EvSidebarPage * sidebar_page,EvDocumentModel * model)601 ev_sidebar_bookmarks_set_model (EvSidebarPage   *sidebar_page,
602                                 EvDocumentModel *model)
603 {
604         EvSidebarBookmarks *sidebar_bookmarks = EV_SIDEBAR_BOOKMARKS (sidebar_page);
605         EvSidebarBookmarksPrivate *priv = sidebar_bookmarks->priv;
606 
607         if (priv->model == model)
608                 return;
609 
610         if (priv->model)
611                 g_object_unref (priv->model);
612         priv->model = g_object_ref (model);
613         g_signal_connect_swapped (model, "page-changed",
614                                   G_CALLBACK (ev_sidebar_bookmarks_page_changed),
615                                   sidebar_page);
616 }
617 
618 static gboolean
ev_sidebar_bookmarks_support_document(EvSidebarPage * sidebar_page,EvDocument * document)619 ev_sidebar_bookmarks_support_document (EvSidebarPage *sidebar_page,
620                                        EvDocument    *document)
621 {
622         return TRUE;
623 }
624 
625 static const gchar *
ev_sidebar_bookmarks_get_label(EvSidebarPage * sidebar_page)626 ev_sidebar_bookmarks_get_label (EvSidebarPage *sidebar_page)
627 {
628         return _("Bookmarks");
629 }
630 
631 static void
ev_sidebar_bookmarks_page_iface_init(EvSidebarPageInterface * iface)632 ev_sidebar_bookmarks_page_iface_init (EvSidebarPageInterface *iface)
633 {
634         iface->support_document = ev_sidebar_bookmarks_support_document;
635         iface->set_model = ev_sidebar_bookmarks_set_model;
636         iface->get_label = ev_sidebar_bookmarks_get_label;
637 }
638