Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ev-toolbar.c
Go to the documentation of this file.
1 /* ev-toolbar.h
2  * this file is part of evince, a gnome document viewer
3  *
4  * Copyright (C) 2012-2014 Carlos Garcia Campos <carlosgc@gnome.org>
5  * Copyright (C) 2014 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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <glib/gi18n.h>
27 
28 #include "ev-toolbar.h"
29 
30 #include "ev-stock-icons.h"
31 #include "ev-zoom-action.h"
32 #include "ev-history-action.h"
33 #include "ev-application.h"
34 #include "ev-page-action-widget.h"
35 #include <math.h>
36 
37 enum
38 {
41 };
42 
45 
46  GtkWidget *view_menu_button;
47  GtkWidget *action_menu_button;
48  GtkWidget *history_action;
49  GtkWidget *zoom_action;
50  GtkWidget *page_selector;
51  GtkWidget *navigation_action;
52  GtkWidget *find_button;
53  GtkWidget *open_button;
54  GtkWidget *annots_button;
56 
58 };
59 
60 G_DEFINE_TYPE (EvToolbar, ev_toolbar, GTK_TYPE_HEADER_BAR)
61 
62 static void
63 ev_toolbar_set_property (GObject *object,
64  guint prop_id,
65  const GValue *value,
66  GParamSpec *pspec)
67 {
68  EvToolbar *ev_toolbar = EV_TOOLBAR (object);
69 
70  switch (prop_id) {
71  case PROP_WINDOW:
72  ev_toolbar->priv->window = g_value_get_object (value);
73  break;
74  default:
75  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
76  }
77 }
78 
79 static void
81  GtkButton *button,
82  const gchar *action_name,
83  const gchar *tooltip)
84 {
85  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), action_name);
86  gtk_button_set_label (button, NULL);
87  gtk_button_set_focus_on_click (button, FALSE);
88  gtk_widget_set_tooltip_text (GTK_WIDGET (button), tooltip);
89 }
90 
91 static GtkWidget *
93  const gchar *action_name,
94  const gchar *icon_name,
95  const gchar *tooltip)
96 {
97  GtkWidget *button = gtk_button_new ();
98  GtkWidget *image;
99 
100  image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
101 
102  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
103  gtk_button_set_image (GTK_BUTTON (button), image);
104  ev_toolbar_set_button_action (ev_toolbar, GTK_BUTTON (button), action_name, tooltip);
105 
106  return button;
107 }
108 
109 static GtkWidget *
111  const gchar *action_name,
112  const gchar *icon_name,
113  const gchar *tooltip)
114 {
115  GtkWidget *button = gtk_toggle_button_new ();
116  GtkWidget *image;
117 
118  image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
119 
120  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
121  gtk_button_set_image (GTK_BUTTON (button), image);
122  ev_toolbar_set_button_action (ev_toolbar, GTK_BUTTON (button), action_name, tooltip);
123 
124  return button;
125 }
126 
127 static GtkWidget *
129  const gchar *icon_name,
130  GMenuModel *menu,
131  GtkAlign menu_align)
132 {
133  GtkWidget *button;
134  GtkPopover *popup;
135 
136  button = gtk_menu_button_new ();
137  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
138  gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
139  gtk_image_set_from_icon_name (GTK_IMAGE (gtk_button_get_image (GTK_BUTTON (button))),
140  icon_name, GTK_ICON_SIZE_MENU);
141  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
142  popup = gtk_menu_button_get_popover (GTK_MENU_BUTTON (button));
143  gtk_popover_set_position (popup, GTK_POS_BOTTOM);
144  gtk_widget_set_halign (GTK_WIDGET (popup), menu_align);
145 
146  return button;
147 }
148 
149 static void
151  GMenuModel *bookmarks_submenu_model)
152 {
153  GMenu *bookmarks_section = toolbar->priv->bookmarks_section;
154 
155  /* The bookmarks section has one or two items: "Add Bookmark"
156  * and the "Bookmarks" submenu item. Hide the latter when there
157  * are no bookmarks.
158  */
159  if (g_menu_model_get_n_items (bookmarks_submenu_model) > 0) {
160  if (g_menu_model_get_n_items (G_MENU_MODEL (bookmarks_section)) == 1)
161  g_menu_append_submenu (bookmarks_section, _("Bookmarks"), bookmarks_submenu_model);
162  } else {
163  if (g_menu_model_get_n_items (G_MENU_MODEL (bookmarks_section)) == 2)
164  g_menu_remove (bookmarks_section, 1);
165  }
166 }
167 
168 static void
170  gint position,
171  gint removed,
172  gint added,
173  EvToolbar *toolbar)
174 {
175  ev_toolbar_setup_bookmarks_menu (toolbar, model);
176 }
177 
178 static void
179 zoom_selector_activated (GtkWidget *zoom_action,
180  EvToolbar *toolbar)
181 {
182  ev_window_focus_view (toolbar->priv->window);
183 }
184 
185 static void
186 ev_toolbar_constructed (GObject *object)
187 {
188  EvToolbar *ev_toolbar = EV_TOOLBAR (object);
189  GtkBuilder *builder;
190  GtkWidget *tool_item;
191  GtkWidget *hbox, *vbox;
192  GtkWidget *button;
193  GMenuModel *menu;
194  GMenuModel *bookmarks_submenu_model;
195 
196  G_OBJECT_CLASS (ev_toolbar_parent_class)->constructed (object);
197 
198  builder = gtk_builder_new_from_resource ("/org/gnome/evince/gtk/menus.ui");
199 
200  button = ev_toolbar_create_button (ev_toolbar, "win.open",
201  "document-open-symbolic",
202  _("Open an existing document"));
203  ev_toolbar->priv->open_button = button;
204  gtk_container_add (GTK_CONTAINER (ev_toolbar), button);
205  gtk_widget_set_margin_end (button, 6);
206 
207  /* Page selector */
208  /* Use EvPageActionWidget for now, since the page selector action is also used by the previewer */
209  tool_item = GTK_WIDGET (g_object_new (EV_TYPE_PAGE_ACTION_WIDGET, NULL));
210  gtk_widget_set_tooltip_text (tool_item, _("Select page or search in the index"));
211  atk_object_set_name (gtk_widget_get_accessible (tool_item), _("Select page"));
212  ev_toolbar->priv->page_selector = tool_item;
214  ev_window_get_document_model (ev_toolbar->priv->window));
215  gtk_widget_set_margin_end (tool_item, 6);
216  gtk_header_bar_pack_start (GTK_HEADER_BAR (ev_toolbar), tool_item);
217 
218  /* History */
219  hbox = ev_history_action_new (ev_window_get_history (ev_toolbar->priv->window));
220  ev_toolbar->priv->history_action = hbox;
221  gtk_widget_set_margin_end (hbox, 6);
222  gtk_header_bar_pack_start (GTK_HEADER_BAR (ev_toolbar), hbox);
223 
224  /* Find */
225  button = ev_toolbar_create_toggle_button (ev_toolbar, "win.toggle-find", "edit-find-symbolic",
226  _("Find a word or phrase in the document"));
227  ev_toolbar->priv->find_button = button;
228  gtk_widget_set_margin_end (button, 6);
229  gtk_header_bar_pack_start (GTK_HEADER_BAR (ev_toolbar), button);
230 
231  /* Edit Annots */
232  /* FIXME: Use a better icon for edit than text editor */
233  button = ev_toolbar_create_toggle_button (ev_toolbar, "win.toggle-edit-annots", "accessories-text-editor-symbolic",
234  _("Annotate the document"));
235  ev_toolbar->priv->annots_button = button;
236  gtk_widget_set_margin_end (button, 6);
237  gtk_header_bar_pack_start (GTK_HEADER_BAR (ev_toolbar), button);
238 
239  /* Action Menu */
240  menu = G_MENU_MODEL (gtk_builder_get_object (builder, "action-menu"));
241  button = ev_toolbar_create_menu_button (ev_toolbar, "open-menu-symbolic",
242  menu, GTK_ALIGN_END);
243  gtk_widget_set_tooltip_text (button, _("File options"));
244  atk_object_set_name (gtk_widget_get_accessible (button), _("File options"));
245 
246  ev_toolbar->priv->action_menu_button = button;
247  gtk_header_bar_pack_end (GTK_HEADER_BAR (ev_toolbar), button);
248 
249  /* View Menu */
250  menu = G_MENU_MODEL (gtk_builder_get_object (builder, "view-menu"));
251  button = ev_toolbar_create_menu_button (ev_toolbar, "document-properties-symbolic",
252  menu, GTK_ALIGN_END);
253  gtk_widget_set_tooltip_text (button, _("View options"));
254  atk_object_set_name (gtk_widget_get_accessible (button), _("View options"));
255  ev_toolbar->priv->view_menu_button = button;
256  gtk_header_bar_pack_end (GTK_HEADER_BAR (ev_toolbar), button);
257 
258  /* Zoom selector */
260  G_MENU (gtk_builder_get_object (builder, "zoom-menu")));
261  ev_toolbar->priv->zoom_action = vbox;
262  gtk_widget_set_tooltip_text (vbox, _("Select or set the zoom level of the document"));
263  atk_object_set_name (gtk_widget_get_accessible (vbox), _("Set zoom level"));
264  g_signal_connect (vbox, "activated",
265  G_CALLBACK (zoom_selector_activated),
266  ev_toolbar);
267  gtk_widget_set_margin_end (vbox, 6);
268  gtk_header_bar_pack_end (GTK_HEADER_BAR (ev_toolbar), vbox);
269 
270  ev_toolbar->priv->bookmarks_section = G_MENU (gtk_builder_get_object (builder, "bookmarks"));
271  bookmarks_submenu_model = ev_window_get_bookmarks_menu (ev_toolbar->priv->window);
272  g_signal_connect (bookmarks_submenu_model, "items-changed",
274  ev_toolbar);
275  ev_toolbar_setup_bookmarks_menu (ev_toolbar, bookmarks_submenu_model);
276 
277  g_object_unref (builder);
278 }
279 
280 static void
282 {
283  GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
284 
285  g_object_class->set_property = ev_toolbar_set_property;
286  g_object_class->constructed = ev_toolbar_constructed;
287 
288  g_object_class_install_property (g_object_class,
289  PROP_WINDOW,
290  g_param_spec_object ("window",
291  "Window",
292  "The evince window",
294  G_PARAM_WRITABLE |
295  G_PARAM_CONSTRUCT_ONLY |
296  G_PARAM_STATIC_STRINGS));
297 
298  g_type_class_add_private (g_object_class, sizeof (EvToolbarPrivate));
299 }
300 
301 static void
303 {
304  ev_toolbar->priv = G_TYPE_INSTANCE_GET_PRIVATE (ev_toolbar, EV_TYPE_TOOLBAR, EvToolbarPrivate);
306 }
307 
308 GtkWidget *
310 {
311  g_return_val_if_fail (EV_IS_WINDOW (window), NULL);
312 
313  return GTK_WIDGET (g_object_new (EV_TYPE_TOOLBAR,
314  "window", window,
315  NULL));
316 }
317 
318 gboolean
320 {
321  GtkPopover *popover;
322  EvToolbarPrivate *priv;
323 
324  g_return_val_if_fail (EV_IS_TOOLBAR (ev_toolbar), FALSE);
325 
326  priv = ev_toolbar->priv;
327 
328  popover = gtk_menu_button_get_popover (GTK_MENU_BUTTON (priv->view_menu_button));
329  if (gtk_widget_get_visible (GTK_WIDGET (popover)))
330  return TRUE;
331 
332  popover = gtk_menu_button_get_popover (GTK_MENU_BUTTON (priv->action_menu_button));
333  if (gtk_widget_get_visible (GTK_WIDGET (popover)))
334  return TRUE;
335 
337  return TRUE;
338 
340  return TRUE;
341 
342  return FALSE;
343 }
344 
345 void
347 {
348  g_return_if_fail (EV_IS_TOOLBAR (ev_toolbar));
349 
350  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ev_toolbar->priv->action_menu_button),
351  TRUE);
352 }
353 
354 GtkWidget *
356 {
357  g_return_val_if_fail (EV_IS_TOOLBAR (ev_toolbar), NULL);
358 
359  return ev_toolbar->priv->page_selector;
360 }
361 
362 void
364  EvToolbarMode mode)
365 {
366  EvToolbarPrivate *priv;
367 
368  g_return_if_fail (EV_IS_TOOLBAR (ev_toolbar));
369 
370  priv = ev_toolbar->priv;
371  priv->toolbar_mode = mode;
372 
373  switch (mode) {
375  gtk_widget_show (priv->view_menu_button);
376  gtk_widget_show (priv->action_menu_button);
377  gtk_widget_show (priv->history_action);
378  gtk_widget_show (priv->zoom_action);
379  gtk_widget_show (priv->page_selector);
380  gtk_widget_show (priv->find_button);
381  gtk_widget_show (priv->annots_button);
382  gtk_widget_hide (priv->open_button);
383  break;
385  gtk_widget_show (priv->view_menu_button);
386  gtk_widget_show (priv->action_menu_button);
387  gtk_widget_show (priv->history_action);
388  gtk_widget_show (priv->zoom_action);
389  gtk_widget_show (priv->page_selector);
390  gtk_widget_show (priv->find_button);
391  gtk_widget_show (priv->annots_button);
392  gtk_widget_hide (priv->open_button);
393  break;
395  gtk_widget_hide (priv->view_menu_button);
396  gtk_widget_hide (priv->action_menu_button);
397  gtk_widget_hide (priv->history_action);
398  gtk_widget_hide (priv->zoom_action);
399  gtk_widget_hide (priv->page_selector);
400  gtk_widget_hide (priv->find_button);
401  gtk_widget_hide (priv->annots_button);
402  gtk_widget_show (priv->open_button);
403  break;
404  }
405 }
406 
409 {
410  g_return_val_if_fail (EV_IS_TOOLBAR (ev_toolbar), EV_TOOLBAR_MODE_NORMAL);
411 
412  return ev_toolbar->priv->toolbar_mode;
413 }