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-page-action-widget.c File Reference
#include "config.h"
#include <string.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <evince-document.h>
#include "ev-page-action-widget.h"
+ Include dependency graph for ev-page-action-widget.c:

Go to the source code of this file.

Data Structures

struct  _EvPageActionWidget
 

Macros

#define EPA_FILTER_MODEL_DATA   "epa-filter-model"
 

Enumerations

enum  { WIDGET_ACTIVATE_LINK, WIDGET_N_SIGNALS }
 

Functions

static void ev_page_action_widget_init (EvPageActionWidget *action_widget)
 
static void ev_page_action_widget_class_init (EvPageActionWidgetClass *action_widget)
 
static gboolean show_page_number_in_pages_label (EvPageActionWidget *action_widget, gint page)
 
static void update_pages_label (EvPageActionWidget *action_widget, gint page)
 
static void ev_page_action_widget_set_current_page (EvPageActionWidget *action_widget, gint page)
 
static void ev_page_action_widget_update_max_width (EvPageActionWidget *action_widget)
 
static void page_changed_cb (EvDocumentModel *model, gint old_page, gint new_page, EvPageActionWidget *action_widget)
 
static gboolean page_scroll_cb (EvPageActionWidget *action_widget, GdkEventScroll *event)
 
static void activate_cb (EvPageActionWidget *action_widget)
 
static gboolean focus_out_cb (EvPageActionWidget *action_widget)
 
static void ev_page_action_widget_set_document (EvPageActionWidget *action_widget, EvDocument *document)
 
static void ev_page_action_widget_document_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvPageActionWidget *action_widget)
 
void ev_page_action_widget_set_model (EvPageActionWidget *action_widget, EvDocumentModel *model)
 
static void ev_page_action_widget_finalize (GObject *object)
 
static void ev_page_action_widget_get_preferred_width (GtkWidget *widget, gint *minimum_width, gint *natural_width)
 
static gboolean match_selected_cb (GtkEntryCompletion *completion, GtkTreeModel *filter_model, GtkTreeIter *filter_iter, EvPageActionWidget *proxy)
 
static void display_completion_text (GtkCellLayout *cell_layout, GtkCellRenderer *renderer, GtkTreeModel *filter_model, GtkTreeIter *filter_iter, EvPageActionWidget *proxy)
 
static gboolean match_completion (GtkEntryCompletion *completion, const gchar *key, GtkTreeIter *filter_iter, EvPageActionWidget *proxy)
 
static gboolean build_new_tree_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
 
static GtkTreeModel * get_filter_model_from_model (GtkTreeModel *model)
 
void ev_page_action_widget_update_links_model (EvPageActionWidget *proxy, GtkTreeModel *model)
 
void ev_page_action_widget_grab_focus (EvPageActionWidget *proxy)
 

Variables

static guint widget_signals [WIDGET_N_SIGNALS] = {0, }
 

Macro Definition Documentation

#define EPA_FILTER_MODEL_DATA   "epa-filter-model"

Definition at line 477 of file ev-page-action-widget.c.

Enumeration Type Documentation

anonymous enum
Enumerator
WIDGET_ACTIVATE_LINK 
WIDGET_N_SIGNALS 

Definition at line 34 of file ev-page-action-widget.c.

35 {
38 };

Function Documentation

static void activate_cb ( EvPageActionWidget action_widget)
static

Definition at line 168 of file ev-page-action-widget.c.

169 {
170  EvDocumentModel *model;
171  const char *text;
172  EvLinkDest *link_dest;
173  EvLinkAction *link_action;
174  EvLink *link;
175  gchar *link_text;
176  gint current_page;
177 
178  model = action_widget->doc_model;
179  current_page = ev_document_model_get_page (model);
180 
181  text = gtk_entry_get_text (GTK_ENTRY (action_widget->entry));
182 
183  link_dest = ev_link_dest_new_page_label (text);
184  link_action = ev_link_action_new_dest (link_dest);
185  link_text = g_strdup_printf (_("Page %s"), text);
186  link = ev_link_new (link_text, link_action);
187 
188  g_signal_emit (action_widget, widget_signals[WIDGET_ACTIVATE_LINK], 0, link);
189 
190  g_object_unref (link_dest);
191  g_object_unref (link_action);
192  g_object_unref (link);
193  g_free (link_text);
194 
195  if (current_page == ev_document_model_get_page (model))
196  ev_page_action_widget_set_current_page (action_widget, current_page);
197 }

+ Here is the caller graph for this function:

static gboolean build_new_tree_cb ( GtkTreeModel *  model,
GtkTreePath *  path,
GtkTreeIter *  iter,
gpointer  data 
)
static

Definition at line 480 of file ev-page-action-widget.c.

484 {
485  GtkTreeModel *filter_model = GTK_TREE_MODEL (data);
486  EvLink *link;
487  EvLinkAction *action;
488  EvLinkActionType type;
489 
490  gtk_tree_model_get (model, iter,
492  -1);
493 
494  if (!link)
495  return FALSE;
496 
497  action = ev_link_get_action (link);
498  if (!action) {
499  g_object_unref (link);
500  return FALSE;
501  }
502 
503  type = ev_link_action_get_action_type (action);
504 
505  if (type == EV_LINK_ACTION_TYPE_GOTO_DEST) {
506  GtkTreeIter filter_iter;
507 
508  gtk_list_store_append (GTK_LIST_STORE (filter_model), &filter_iter);
509  gtk_list_store_set (GTK_LIST_STORE (filter_model), &filter_iter,
510  0, iter,
511  -1);
512  }
513 
514  g_object_unref (link);
515 
516  return FALSE;
517 }

+ Here is the caller graph for this function:

static void display_completion_text ( GtkCellLayout *  cell_layout,
GtkCellRenderer *  renderer,
GtkTreeModel *  filter_model,
GtkTreeIter *  filter_iter,
EvPageActionWidget proxy 
)
static

Definition at line 400 of file ev-page-action-widget.c.

405 {
406  EvLink *link;
407  GtkTreeIter *iter;
408 
409  gtk_tree_model_get (filter_model, filter_iter,
410  0, &iter,
411  -1);
412  gtk_tree_model_get (proxy->model, iter,
414  -1);
415 
416  g_object_set (renderer, "text", ev_link_get_title (link), NULL);
417 
418  if (link)
419  g_object_unref (link);
420 
421  gtk_tree_iter_free (iter);
422 }

+ Here is the caller graph for this function:

static void ev_page_action_widget_class_init ( EvPageActionWidgetClass action_widget)
static

Definition at line 352 of file ev-page-action-widget.c.

353 {
354  GObjectClass *object_class = G_OBJECT_CLASS (klass);
355  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
356 
357  object_class->finalize = ev_page_action_widget_finalize;
358  widget_class->get_preferred_width = ev_page_action_widget_get_preferred_width;
359 
361  g_signal_new ("activate_link",
362  G_OBJECT_CLASS_TYPE (object_class),
363  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
364  G_STRUCT_OFFSET (EvPageActionWidgetClass, activate_link),
365  NULL, NULL,
366  g_cclosure_marshal_VOID__OBJECT,
367  G_TYPE_NONE, 1,
368  G_TYPE_OBJECT);
369 
370 }
static void ev_page_action_widget_document_changed_cb ( EvDocumentModel model,
GParamSpec *  pspec,
EvPageActionWidget action_widget 
)
static

Definition at line 288 of file ev-page-action-widget.c.

291 {
293 }

+ Here is the caller graph for this function:

static void ev_page_action_widget_finalize ( GObject *  object)
static

Definition at line 314 of file ev-page-action-widget.c.

315 {
316  EvPageActionWidget *action_widget = EV_PAGE_ACTION_WIDGET (object);
317 
318  if (action_widget->doc_model != NULL) {
319  if (action_widget->signal_id > 0) {
320  g_signal_handler_disconnect (action_widget->doc_model,
321  action_widget->signal_id);
322  action_widget->signal_id = 0;
323  }
324  g_object_remove_weak_pointer (G_OBJECT (action_widget->doc_model),
325  (gpointer)&action_widget->doc_model);
326  action_widget->doc_model = NULL;
327  }
328 
329  ev_page_action_widget_set_document (action_widget, NULL);
330 
331  G_OBJECT_CLASS (ev_page_action_widget_parent_class)->finalize (object);
332 }

+ Here is the caller graph for this function:

static void ev_page_action_widget_get_preferred_width ( GtkWidget *  widget,
gint *  minimum_width,
gint *  natural_width 
)
static

Definition at line 335 of file ev-page-action-widget.c.

338 {
339  GtkWidget *child;
340 
341  *minimum_width = *natural_width = 0;
342 
343  child = gtk_bin_get_child (GTK_BIN (widget));
344  if (!child || !gtk_widget_get_visible (child))
345  return;
346 
347  gtk_widget_get_preferred_width (child, minimum_width, natural_width);
348  *natural_width = *minimum_width;
349 }

+ Here is the caller graph for this function:

void ev_page_action_widget_grab_focus ( EvPageActionWidget proxy)

Definition at line 581 of file ev-page-action-widget.c.

582 {
583  gtk_widget_grab_focus (proxy->entry);
584 }

+ Here is the caller graph for this function:

static void ev_page_action_widget_init ( EvPageActionWidget action_widget)
static

Definition at line 208 of file ev-page-action-widget.c.

209 {
210  GtkWidget *hbox;
211  AtkObject *obj;
212  GtkStyleContext *style_context;
213 
214  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
215 
216  style_context = gtk_widget_get_style_context (hbox);
217  gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_RAISED);
218  gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_LINKED);
219 
220  action_widget->entry = gtk_entry_new ();
221  gtk_widget_add_events (action_widget->entry,
222  GDK_BUTTON_MOTION_MASK);
223  gtk_entry_set_width_chars (GTK_ENTRY (action_widget->entry), 5);
224  gtk_entry_set_text (GTK_ENTRY (action_widget->entry), "");
225  g_signal_connect_swapped (action_widget->entry, "scroll-event",
226  G_CALLBACK (page_scroll_cb),
227  action_widget);
228  g_signal_connect_swapped (action_widget->entry, "activate",
229  G_CALLBACK (activate_cb),
230  action_widget);
231  g_signal_connect_swapped (action_widget->entry, "focus-out-event",
232  G_CALLBACK (focus_out_cb),
233  action_widget);
234 
235  obj = gtk_widget_get_accessible (action_widget->entry);
236  atk_object_set_name (obj, "page-label-entry");
237 
238  gtk_box_pack_start (GTK_BOX (hbox), action_widget->entry,
239  FALSE, FALSE, 0);
240  gtk_widget_show (action_widget->entry);
241 
242  action_widget->label = gtk_entry_new ();
243  gtk_widget_set_sensitive (action_widget->label, FALSE);
244  gtk_entry_set_width_chars (GTK_ENTRY (action_widget->label), 5);
245  gtk_box_pack_start (GTK_BOX (hbox), action_widget->label,
246  FALSE, FALSE, 0);
247  gtk_widget_show (action_widget->label);
248 
249  gtk_container_add (GTK_CONTAINER (action_widget), hbox);
250  gtk_widget_show (hbox);
251 
252  gtk_widget_set_sensitive (GTK_WIDGET (action_widget), FALSE);
253 }
static void ev_page_action_widget_set_current_page ( EvPageActionWidget action_widget,
gint  page 
)
static

Definition at line 92 of file ev-page-action-widget.c.

94 {
95  if (page >= 0) {
96  gchar *page_label;
97 
98  page_label = ev_document_get_page_label (action_widget->document, page);
99  gtk_entry_set_text (GTK_ENTRY (action_widget->entry), page_label);
100  gtk_editable_set_position (GTK_EDITABLE (action_widget->entry), -1);
101  g_free (page_label);
102  } else {
103  gtk_entry_set_text (GTK_ENTRY (action_widget->entry), "");
104  }
105 
106  update_pages_label (action_widget, page);
107 }

+ Here is the caller graph for this function:

static void ev_page_action_widget_set_document ( EvPageActionWidget action_widget,
EvDocument document 
)
static

Definition at line 256 of file ev-page-action-widget.c.

258 {
259  if (document) {
260  g_object_ref (document);
261  gtk_widget_set_sensitive (GTK_WIDGET (action_widget), ev_document_get_n_pages (document) > 0);
262  }
263 
264  if (action_widget->signal_id > 0) {
265  g_signal_handler_disconnect (action_widget->doc_model,
266  action_widget->signal_id);
267  action_widget->signal_id = 0;
268  }
269 
270  if (action_widget->document)
271  g_object_unref (action_widget->document);
272  action_widget->document = document;
273  if (!action_widget->document)
274  return;
275 
276  action_widget->signal_id =
277  g_signal_connect (action_widget->doc_model,
278  "page-changed",
279  G_CALLBACK (page_changed_cb),
280  action_widget);
281 
283  ev_document_model_get_page (action_widget->doc_model));
285 }

+ Here is the caller graph for this function:

void ev_page_action_widget_set_model ( EvPageActionWidget action_widget,
EvDocumentModel model 
)

Definition at line 296 of file ev-page-action-widget.c.

298 {
299  if (action_widget->doc_model) {
300  g_object_remove_weak_pointer (G_OBJECT (action_widget->doc_model),
301  (gpointer)&action_widget->doc_model);
302  }
303  action_widget->doc_model = model;
304  g_object_add_weak_pointer (G_OBJECT (model),
305  (gpointer)&action_widget->doc_model);
306 
308  g_signal_connect (model, "notify::document",
310  action_widget);
311 }

+ Here is the caller graph for this function:

void ev_page_action_widget_update_links_model ( EvPageActionWidget proxy,
GtkTreeModel *  model 
)

Definition at line 540 of file ev-page-action-widget.c.

541 {
542  GtkTreeModel *filter_model;
543  GtkEntryCompletion *completion;
544  GtkCellRenderer *renderer;
545 
546  if (!model || model == proxy->model)
547  return;
548 
549  /* Magik */
550  proxy->model = model;
551  filter_model = get_filter_model_from_model (model);
552 
553  completion = gtk_entry_completion_new ();
554  g_object_set (G_OBJECT (completion),
555  "popup-set-width", FALSE,
556  "model", filter_model,
557  NULL);
558 
559  g_signal_connect (completion, "match-selected", G_CALLBACK (match_selected_cb), proxy);
560  gtk_entry_completion_set_match_func (completion,
561  (GtkEntryCompletionMatchFunc) match_completion,
562  proxy, NULL);
563 
564  /* Set up the layout */
565  renderer = (GtkCellRenderer *)
566  g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
567  "ellipsize", PANGO_ELLIPSIZE_END,
568  "width_chars", 30,
569  NULL);
570  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
571  gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion),
572  renderer,
573  (GtkCellLayoutDataFunc) display_completion_text,
574  proxy, NULL);
575  gtk_entry_set_completion (GTK_ENTRY (proxy->entry), completion);
576 
577  g_object_unref (completion);
578 }

+ Here is the caller graph for this function:

static void ev_page_action_widget_update_max_width ( EvPageActionWidget action_widget)
static

Definition at line 110 of file ev-page-action-widget.c.

111 {
112  gchar *max_label;
113  gint n_pages;
114  gint max_label_len;
115  gchar *max_page_label;
116  gchar *max_page_numeric_label;
117 
118  n_pages = ev_document_get_n_pages (action_widget->document);
119 
120  max_page_label = ev_document_get_page_label (action_widget->document, n_pages - 1);
121  max_page_numeric_label = g_strdup_printf ("%d", n_pages);
122  if (ev_document_has_text_page_labels (action_widget->document) != 0) {
123  max_label = g_strdup_printf (_("(%d of %d)"), n_pages, n_pages);
124  /* Do not take into account the parentheses for the size computation */
125  max_label_len = g_utf8_strlen (max_label, -1) - 2;
126  } else {
127  max_label = g_strdup_printf (_("of %d"), n_pages);
128  max_label_len = g_utf8_strlen (max_label, -1);
129  }
130  g_free (max_page_label);
131 
132  gtk_entry_set_width_chars (GTK_ENTRY (action_widget->label), max_label_len);
133  g_free (max_label);
134 
135  max_label_len = ev_document_get_max_label_len (action_widget->document);
136  gtk_entry_set_width_chars (GTK_ENTRY (action_widget->entry),
137  CLAMP (max_label_len, strlen (max_page_numeric_label) + 1, 12));
138  g_free (max_page_numeric_label);
139 }

+ Here is the caller graph for this function:

static gboolean focus_out_cb ( EvPageActionWidget action_widget)
static

Definition at line 200 of file ev-page-action-widget.c.

201 {
203  ev_document_model_get_page (action_widget->doc_model));
204  return FALSE;
205 }

+ Here is the caller graph for this function:

static GtkTreeModel* get_filter_model_from_model ( GtkTreeModel *  model)
static

Definition at line 520 of file ev-page-action-widget.c.

521 {
522  GtkTreeModel *filter_model;
523 
524  filter_model =
525  (GtkTreeModel *) g_object_get_data (G_OBJECT (model), EPA_FILTER_MODEL_DATA);
526  if (filter_model == NULL) {
527  filter_model = (GtkTreeModel *) gtk_list_store_new (1, GTK_TYPE_TREE_ITER);
528 
529  gtk_tree_model_foreach (model,
531  filter_model);
532  g_object_set_data_full (G_OBJECT (model), EPA_FILTER_MODEL_DATA, filter_model, g_object_unref);
533  }
534 
535  return filter_model;
536 }

+ Here is the caller graph for this function:

static gboolean match_completion ( GtkEntryCompletion *  completion,
const gchar *  key,
GtkTreeIter *  filter_iter,
EvPageActionWidget proxy 
)
static

Definition at line 425 of file ev-page-action-widget.c.

429 {
430  EvLink *link;
431  GtkTreeIter *iter;
432  const gchar *text = NULL;
433 
434  gtk_tree_model_get (gtk_entry_completion_get_model (completion),
435  filter_iter,
436  0, &iter,
437  -1);
438  gtk_tree_model_get (proxy->model, iter,
440  -1);
441 
442 
443  if (link) {
444  text = ev_link_get_title (link);
445  g_object_unref (link);
446  }
447 
448  gtk_tree_iter_free (iter);
449 
450  if (text && key) {
451  gchar *normalized_text;
452  gchar *normalized_key;
453  gchar *case_normalized_text;
454  gchar *case_normalized_key;
455  gboolean retval = FALSE;
456 
457  normalized_text = g_utf8_normalize (text, -1, G_NORMALIZE_ALL);
458  normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
459  case_normalized_text = g_utf8_casefold (normalized_text, -1);
460  case_normalized_key = g_utf8_casefold (normalized_key, -1);
461 
462  if (strstr (case_normalized_text, case_normalized_key))
463  retval = TRUE;
464 
465  g_free (normalized_text);
466  g_free (normalized_key);
467  g_free (case_normalized_text);
468  g_free (case_normalized_key);
469 
470  return retval;
471  }
472 
473  return FALSE;
474 }

+ Here is the caller graph for this function:

static gboolean match_selected_cb ( GtkEntryCompletion *  completion,
GtkTreeModel *  filter_model,
GtkTreeIter *  filter_iter,
EvPageActionWidget proxy 
)
static

Definition at line 373 of file ev-page-action-widget.c.

377 {
378  EvLink *link;
379  GtkTreeIter *iter;
380 
381  gtk_tree_model_get (filter_model, filter_iter,
382  0, &iter,
383  -1);
384  gtk_tree_model_get (proxy->model, iter,
386  -1);
387 
388  g_signal_emit (proxy, widget_signals[WIDGET_ACTIVATE_LINK], 0, link);
389 
390  if (link)
391  g_object_unref (link);
392 
393  gtk_tree_iter_free (iter);
394 
395  return TRUE;
396 }

+ Here is the caller graph for this function:

static void page_changed_cb ( EvDocumentModel model,
gint  old_page,
gint  new_page,
EvPageActionWidget action_widget 
)
static

Definition at line 142 of file ev-page-action-widget.c.

146 {
147  ev_page_action_widget_set_current_page (action_widget, new_page);
148 }

+ Here is the caller graph for this function:

static gboolean page_scroll_cb ( EvPageActionWidget action_widget,
GdkEventScroll *  event 
)
static

Definition at line 151 of file ev-page-action-widget.c.

152 {
153  EvDocumentModel *model = action_widget->doc_model;
154  gint pageno;
155 
156  pageno = ev_document_model_get_page (model);
157  if ((event->direction == GDK_SCROLL_DOWN) &&
158  (pageno < ev_document_get_n_pages (action_widget->document) - 1))
159  pageno++;
160  if ((event->direction == GDK_SCROLL_UP) && (pageno > 0))
161  pageno--;
162  ev_document_model_set_page (model, pageno);
163 
164  return TRUE;
165 }

+ Here is the caller graph for this function:

static gboolean show_page_number_in_pages_label ( EvPageActionWidget action_widget,
gint  page 
)
static

Definition at line 59 of file ev-page-action-widget.c.

61 {
62  gchar *page_label;
63  gboolean retval;
64 
65  if (!ev_document_has_text_page_labels (action_widget->document))
66  return FALSE;
67 
68  page_label = g_strdup_printf ("%d", page + 1);
69  retval = g_strcmp0 (page_label, gtk_entry_get_text (GTK_ENTRY (action_widget->entry))) != 0;
70  g_free (page_label);
71 
72  return retval;
73 }

+ Here is the caller graph for this function:

static void update_pages_label ( EvPageActionWidget action_widget,
gint  page 
)
static

Definition at line 76 of file ev-page-action-widget.c.

78 {
79  char *label_text;
80  gint n_pages;
81 
82  n_pages = ev_document_get_n_pages (action_widget->document);
83  if (show_page_number_in_pages_label (action_widget, page))
84  label_text = g_strdup_printf (_("(%d of %d)"), page + 1, n_pages);
85  else
86  label_text = g_strdup_printf (_("of %d"), n_pages);
87  gtk_entry_set_text (GTK_ENTRY (action_widget->label), label_text);
88  g_free (label_text);
89 }

+ Here is the caller graph for this function:

Variable Documentation

guint widget_signals[WIDGET_N_SIGNALS] = {0, }
static

Definition at line 54 of file ev-page-action-widget.c.