shortcuts.c 37.8 KB
Newer Older
1
2
/* See LICENSE file for license and copyright information */

3
4
5
6
#include <girara/session.h>
#include <girara/settings.h>
#include <girara/datastructures.h>
#include <girara/shortcuts.h>
7
#include <girara/utils.h>
Moritz Lipp's avatar
Moritz Lipp committed
8
#include <gtk/gtk.h>
9
#include <glib/gi18n.h>
Moritz Lipp's avatar
Moritz Lipp committed
10
11

#include "callbacks.h"
12
#include "shortcuts.h"
13
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
14
#include "zathura.h"
15
#include "render.h"
16
#include "utils.h"
Moritz Lipp's avatar
Moritz Lipp committed
17
#include "page.h"
Moritz Lipp's avatar
Moritz Lipp committed
18
#include "print.h"
19
#include "page-widget.h"
20
#include "adjustment.h"
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/* Helper function; see sc_display_link and sc_follow. */
static bool
draw_links(zathura_t* zathura)
{
  /* set pages to draw links */
  bool show_links = false;
  unsigned int page_offset = 0;
  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
    if (page == NULL) {
      continue;
    }

    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
    g_object_set(page_widget, "search-results", NULL, NULL);
    if (zathura_page_get_visibility(page) == true) {
      g_object_set(page_widget, "draw-links", TRUE, NULL);

      int number_of_links = 0;
      g_object_get(page_widget, "number-of-links", &number_of_links, NULL);
      if (number_of_links != 0) {
        show_links = true;
      }
      g_object_set(page_widget, "offset-links", page_offset, NULL);
      page_offset += number_of_links;
    } else {
      g_object_set(page_widget, "draw-links", FALSE, NULL);
    }
  }
  return show_links;
}

Moritz Lipp's avatar
Moritz Lipp committed
55
bool
56
sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
57
         girara_event_t* UNUSED(event), unsigned int UNUSED(t))
58
{
Moritz Lipp's avatar
Moritz Lipp committed
59
  g_return_val_if_fail(session != NULL, false);
60
61
62
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

63
64
65
  bool clear_search = true;
  girara_setting_get(session, "abort-clear-search", &clear_search);

Moritz Lipp's avatar
Moritz Lipp committed
66
  if (zathura->document != NULL) {
67
    unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
68
69
    for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
      zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
Moritz Lipp's avatar
Moritz Lipp committed
70
71
72
73
      if (page == NULL) {
        continue;
      }

74
      g_object_set(zathura_page_get_widget(zathura, page), "draw-links", FALSE, NULL);
75
      if (clear_search == true) {
76
77
        g_object_set(zathura_page_get_widget(zathura, page), "search-results", NULL, NULL);
      }
78
79
    }
  }
Moritz Lipp's avatar
Moritz Lipp committed
80

Moritz Lipp's avatar
Moritz Lipp committed
81
  girara_mode_set(session, session->modes.normal);
Moritz Lipp's avatar
Moritz Lipp committed
82
  girara_sc_abort(session, NULL, NULL, 0);
Moritz Lipp's avatar
Moritz Lipp committed
83

Moritz Lipp's avatar
Moritz Lipp committed
84
  return false;
85
86
}

87
88
bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
89
                 girara_event_t* UNUSED(event), unsigned int UNUSED(t))
90
{
91
92
93
94
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
95

96
97
  unsigned int pages_per_row = 1;
  girara_setting_get(session, "pages-per-row", &pages_per_row);
Moritz Lipp's avatar
Moritz Lipp committed
98

99
100
101
  unsigned int first_page_column = 1;
  girara_setting_get(session, "first-page-column", &first_page_column);

102
103
104
  int padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &padding);

105
  if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
106
107
108
    goto error_ret;
  }

109
110
  zathura_document_set_adjust_mode(zathura->document, argument->n);
  if (argument->n == ZATHURA_ADJUST_NONE) {
111
112
113
    /* there is nothing todo */
    goto error_ret;
  }
114

Moritz Lipp's avatar
Moritz Lipp committed
115
  /* get window size */
116
117
  GtkAllocation allocation;
  gtk_widget_get_allocation(session->gtk.view, &allocation);
118
119
  unsigned int width  = allocation.width;
  unsigned int height = allocation.height;
Moritz Lipp's avatar
Moritz Lipp committed
120

121
122
123
124
125
  /* scrollbar spacing */
  gint spacing;
  gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL);
  width -= spacing;

126
127
128
129
130
131
  /* correct view size */
  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) {
    gtk_widget_get_allocation(session->gtk.inputbar, &allocation);
    height += allocation.height;
  }

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  double scale = 1.0;
  unsigned int cell_height = 0, cell_width = 0;
  unsigned int document_height = 0, document_width = 0;

  zathura_document_set_scale(zathura->document, scale);
  zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
  zathura_get_document_size(zathura, cell_height, cell_width,
                            &document_height, &document_width);

  double page_ratio   = (double)cell_height / (double)document_width;
  double window_ratio = (double)height / (double)width;

  if (argument->n == ZATHURA_ADJUST_WIDTH ||
      (argument->n == ZATHURA_ADJUST_BESTFIT && page_ratio < window_ratio)) {
    scale = (double)(width - (pages_per_row - 1) * padding) /
Benoît Knecht's avatar
Benoît Knecht committed
147
            (double)(pages_per_row * cell_width);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    zathura_document_set_scale(zathura->document, scale);

    bool show_scrollbars = false;
    girara_setting_get(session, "show-scrollbars", &show_scrollbars);

    if (show_scrollbars) {
      /* If the document is taller than the view, there's a vertical
       * scrollbar; we need to substract its width from the view's width. */
      zathura_get_document_size(zathura, cell_height, cell_width,
                                &document_height, &document_width);
      if (height < document_height) {
        GtkWidget* vscrollbar = gtk_scrolled_window_get_vscrollbar(
            GTK_SCROLLED_WINDOW(session->gtk.view));

        if (vscrollbar != NULL) {
          GtkRequisition requisition;
          gtk_widget_get_requisition(vscrollbar, &requisition);
          if (0 < requisition.width && (unsigned)requisition.width < width) {
            width -= requisition.width;
            scale = (double)(width - (pages_per_row - 1) * padding) /
Benoît Knecht's avatar
Benoît Knecht committed
168
                    (double)(pages_per_row * cell_width);
169
170
171
172
            zathura_document_set_scale(zathura->document, scale);
          }
        }
      }
Moritz Lipp's avatar
Moritz Lipp committed
173
174
    }
  }
175
176
177
  else if (argument->n == ZATHURA_ADJUST_BESTFIT) {
    scale = (double)height / (double)cell_height;
    zathura_document_set_scale(zathura->document, scale);
Moritz Lipp's avatar
Moritz Lipp committed
178
  }
179
180
  else {
    goto error_ret;
Moritz Lipp's avatar
Moritz Lipp committed
181
182
183
184
185
186
  }

  /* re-render all pages */
  render_all(zathura);

error_ret:
Moritz Lipp's avatar
Moritz Lipp committed
187

188
  return false;
189
190
}

Moritz Lipp's avatar
Moritz Lipp committed
191
bool
Moritz Lipp's avatar
Moritz Lipp committed
192
sc_change_mode(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
193
               girara_event_t* UNUSED(event), unsigned int UNUSED(t))
194
{
Moritz Lipp's avatar
Moritz Lipp committed
195
196
197
198
  g_return_val_if_fail(session != NULL, false);

  girara_mode_set(session, argument->n);

Moritz Lipp's avatar
Moritz Lipp committed
199
  return false;
200
201
}

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
bool
sc_display_link(girara_session_t* session, girara_argument_t* UNUSED(argument),
                girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  if (zathura->document == NULL || zathura->ui.session == NULL) {
    return false;
  }

  bool show_links = draw_links(zathura);

  /* ask for input */
  if (show_links) {
    girara_dialog(zathura->ui.session, "Display link:", FALSE, NULL,
        (girara_callback_inputbar_activate_t) cb_sc_display_link,
        zathura->ui.session);
  }

  return false;
}

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
bool
sc_focus_inputbar(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->gtk.inputbar_entry != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);

  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == false) {
    gtk_widget_show(GTK_WIDGET(session->gtk.inputbar));
  }

  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.notification_area)) == true) {
    gtk_widget_hide(GTK_WIDGET(session->gtk.notification_area));
  }

  gtk_widget_grab_focus(GTK_WIDGET(session->gtk.inputbar_entry));

  if (argument->data != NULL) {
    gtk_entry_set_text(session->gtk.inputbar_entry, (char*) argument->data);

    /* append filepath */
    if (argument->n == APPEND_FILEPATH && zathura->document != NULL) {
250
251
252
253
      const char* file_path = zathura_document_get_path(zathura->document);
      if (file_path == NULL) {
        return false;
      }
254

255
256
257
258
259
      char* path = g_path_get_dirname(file_path);
      char* escaped = girara_escape_string(path);
      char* tmp  = g_strdup_printf("%s%s/", (char*) argument->data, (g_strcmp0(path, "/") == 0) ? "" : escaped);
      g_free(path);
      g_free(escaped);
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

      gtk_entry_set_text(session->gtk.inputbar_entry, tmp);
      g_free(tmp);
    }

    /* we save the X clipboard that will be clear by "grab_focus" */
    gchar* x_clipboard_text = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY));

    gtk_editable_set_position(GTK_EDITABLE(session->gtk.inputbar_entry), -1);

    if (x_clipboard_text != NULL) {
      /* we reset the X clipboard with saved text */
      gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), x_clipboard_text, -1);
      g_free(x_clipboard_text);
    }
  }

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
280
bool
281
sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
282
          girara_event_t* UNUSED(event), unsigned int UNUSED(t))
283
{
Moritz Lipp's avatar
Moritz Lipp committed
284
  g_return_val_if_fail(session != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
285
286
287
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Moritz Lipp's avatar
Moritz Lipp committed
288
  if (zathura->document == NULL || zathura->ui.session == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
289
290
291
    return false;
  }

292
  bool show_links = draw_links(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
293

Moritz Lipp's avatar
Moritz Lipp committed
294
  /* ask for input */
Moritz Lipp's avatar
Moritz Lipp committed
295
  if (show_links == true) {
Moritz Lipp's avatar
Moritz Lipp committed
296
    girara_dialog(zathura->ui.session, "Follow link:", FALSE, NULL, (girara_callback_inputbar_activate_t) cb_sc_follow, zathura->ui.session);
Moritz Lipp's avatar
Moritz Lipp committed
297
  }
Moritz Lipp's avatar
Moritz Lipp committed
298

Moritz Lipp's avatar
Moritz Lipp committed
299
300
  return false;
}
301

Moritz Lipp's avatar
Moritz Lipp committed
302
bool
Moritz Lipp's avatar
Moritz Lipp committed
303
sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int t)
Moritz Lipp's avatar
Moritz Lipp committed
304
{
Moritz Lipp's avatar
Moritz Lipp committed
305
306
307
308
309
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);
310

311
  zathura_jumplist_save(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
312
  if (t != 0) {
313
    /* add offset */
314
    unsigned int page_offset = zathura_document_get_page_offset(zathura->document);
315
316
    if (page_offset > 0) {
      t += page_offset;
317
318
    }

319
    page_set(zathura, t-1);
Moritz Lipp's avatar
Moritz Lipp committed
320
  } else if (argument->n == TOP) {
Moritz Lipp's avatar
Moritz Lipp committed
321
    page_set(zathura, 0);
Moritz Lipp's avatar
Moritz Lipp committed
322
  } else if (argument->n == BOTTOM) {
323
    page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1);
324
325
  }

326
327
  zathura_jumplist_add(zathura);

Moritz Lipp's avatar
Moritz Lipp committed
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  return false;
}

bool
sc_mouse_scroll(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(event != NULL, false);

  if (zathura->document == NULL) {
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
344
345
346
347
348
349
350
  static int x = 0;
  static int y = 0;

  GtkAdjustment* x_adj = NULL;
  GtkAdjustment* y_adj = NULL;

  switch (event->type) {
Moritz Lipp's avatar
Moritz Lipp committed
351
      /* scroll */
Moritz Lipp's avatar
Moritz Lipp committed
352
353
354
355
356
357
    case GIRARA_EVENT_SCROLL_UP:
    case GIRARA_EVENT_SCROLL_DOWN:
    case GIRARA_EVENT_SCROLL_LEFT:
    case GIRARA_EVENT_SCROLL_RIGHT:
      return sc_scroll(session, argument, NULL, t);

Moritz Lipp's avatar
Moritz Lipp committed
358
      /* drag */
Moritz Lipp's avatar
Moritz Lipp committed
359
360
361
362
363
364
365
366
367
368
    case GIRARA_EVENT_BUTTON_PRESS:
      x = event->x;
      y = event->y;
      break;
    case GIRARA_EVENT_BUTTON_RELEASE:
      x = 0;
      y = 0;
      break;
    case GIRARA_EVENT_MOTION_NOTIFY:
      x_adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
369
      y_adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
370
371
372
373

      if (x_adj == NULL || y_adj == NULL) {
        return false;
      }
Moritz Lipp's avatar
Moritz Lipp committed
374

375
376
377
378
      zathura_adjustment_set_value(x_adj,
          gtk_adjustment_get_value(x_adj) - (event->x - x));
      zathura_adjustment_set_value(y_adj,
          gtk_adjustment_get_value(y_adj) - (event->y - y));
Moritz Lipp's avatar
Moritz Lipp committed
379
380
      break;

Moritz Lipp's avatar
Moritz Lipp committed
381
      /* unhandled events */
Moritz Lipp's avatar
Moritz Lipp committed
382
383
    default:
      break;
Moritz Lipp's avatar
Moritz Lipp committed
384
385
  }

Moritz Lipp's avatar
Moritz Lipp committed
386
  return false;
387
388
}

Moritz Lipp's avatar
Moritz Lipp committed
389
390
391
392
393
394
395
396
397
398
399
400
401
402
bool
sc_mouse_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(event != NULL, false);

  if (zathura->document == NULL) {
    return false;
  }

  /* scroll event */
403
404
405
406
407
408
409
410
411
  switch (event->type) {
    case GIRARA_EVENT_SCROLL_UP:
      argument->n = ZOOM_IN;
      break;
    case GIRARA_EVENT_SCROLL_DOWN:
      argument->n = ZOOM_OUT;
      break;
    default:
      return false;
Moritz Lipp's avatar
Moritz Lipp committed
412
413
  }

414
  return sc_zoom(session, argument, NULL, t);
415
416
}

Moritz Lipp's avatar
Moritz Lipp committed
417
bool
Moritz Lipp's avatar
Moritz Lipp committed
418
sc_navigate(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
419
            girara_event_t* UNUSED(event), unsigned int t)
420
{
Moritz Lipp's avatar
Moritz Lipp committed
421
422
423
424
425
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
426

427
428
  int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  int new_page        = zathura_document_get_current_page_number(zathura->document);
Moritz Lipp's avatar
Moritz Lipp committed
429

430
431
432
  bool scroll_wrap = false;
  girara_setting_get(session, "scroll-wrap", &scroll_wrap);

433
434
435
436
437
438
439
440
  bool columns_per_row_offset = false;
  girara_setting_get(session, "advance-pages-per-row", &columns_per_row_offset);

  int offset = 1;
  if (columns_per_row_offset == true) {
    girara_setting_get(session, "pages-per-row", &offset);
  }

Moritz Lipp's avatar
Moritz Lipp committed
441
  t = (t == 0) ? (unsigned int) offset : t;
Moritz Lipp's avatar
Moritz Lipp committed
442
  if (argument->n == NEXT) {
Benoît Knecht's avatar
Benoît Knecht committed
443
    if (scroll_wrap == false) {
444
445
446
447
      new_page = new_page + t;
    } else {
      new_page = (new_page + t) % number_of_pages;
    }
Moritz Lipp's avatar
Moritz Lipp committed
448
  } else if (argument->n == PREVIOUS) {
Benoît Knecht's avatar
Benoît Knecht committed
449
    if (scroll_wrap == false) {
450
451
452
453
454
455
      new_page = new_page - t;
    } else {
      new_page = (new_page + number_of_pages - t) % number_of_pages;
    }
  }

Benoît Knecht's avatar
Benoît Knecht committed
456
  if ((new_page < 0 || new_page >= number_of_pages) && !scroll_wrap) {
457
    return false;
Moritz Lipp's avatar
Moritz Lipp committed
458
459
  }

460
  page_set(zathura, new_page);
Moritz Lipp's avatar
Moritz Lipp committed
461

Moritz Lipp's avatar
Moritz Lipp committed
462
  return false;
463
464
}

Moritz Lipp's avatar
Moritz Lipp committed
465
466
bool
sc_print(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
467
         girara_event_t* UNUSED(event), unsigned int UNUSED(t))
Moritz Lipp's avatar
Moritz Lipp committed
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  if (zathura->document == NULL) {
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
    return false;
  }

  print(zathura);

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
483
bool
484
sc_recolor(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
485
           girara_event_t* UNUSED(event), unsigned int UNUSED(t))
486
{
Moritz Lipp's avatar
Moritz Lipp committed
487
  g_return_val_if_fail(session != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
488

Moritz Lipp's avatar
Moritz Lipp committed
489
490
491
492
  bool value = false;
  girara_setting_get(session, "recolor", &value);
  value = !value;
  girara_setting_set(session, "recolor", &value);
Moritz Lipp's avatar
Moritz Lipp committed
493

Moritz Lipp's avatar
Moritz Lipp committed
494
  return false;
495
496
}

Moritz Lipp's avatar
Moritz Lipp committed
497
bool
498
sc_reload(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
499
          girara_event_t* UNUSED(event), unsigned int UNUSED(t))
500
{
Moritz Lipp's avatar
Moritz Lipp committed
501
  g_return_val_if_fail(session != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
502
503
504
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Moritz Lipp's avatar
Moritz Lipp committed
505
  if (zathura->file_monitor.file_path == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
506
507
508
509
    return false;
  }

  /* close current document */
Moritz Lipp's avatar
Moritz Lipp committed
510
  document_close(zathura, true);
Moritz Lipp's avatar
Moritz Lipp committed
511
512

  /* reopen document */
513
514
515
  document_open(zathura, zathura->file_monitor.file_path,
                zathura->file_monitor.password,
                ZATHURA_PAGE_NUMBER_UNSPECIFIED);
Moritz Lipp's avatar
Moritz Lipp committed
516

Moritz Lipp's avatar
Moritz Lipp committed
517
  return false;
518
519
}

Moritz Lipp's avatar
Moritz Lipp committed
520
bool
521
sc_rotate(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
522
          girara_event_t* UNUSED(event), unsigned int t)
523
{
Moritz Lipp's avatar
Moritz Lipp committed
524
525
526
527
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(zathura->document != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
528

529
  unsigned int page_number = zathura_document_get_current_page_number(zathura->document);
530

531
532
533
534
535
  int angle = 90;
  if (argument != NULL && argument->n == ROTATE_CCW) {
    angle = 270;
  }

Moritz Lipp's avatar
Moritz Lipp committed
536
  /* update rotate value */
Moritz Lipp's avatar
Moritz Lipp committed
537
  t = (t == 0) ? 1 : t;
538
  unsigned int rotation = zathura_document_get_rotation(zathura->document);
Moritz Lipp's avatar
Moritz Lipp committed
539
  zathura_document_set_rotation(zathura->document, (rotation + angle * t) % 360);
Moritz Lipp's avatar
Moritz Lipp committed
540

541
542
543
544
  /* update scale */
  girara_argument_t new_argument = { zathura_document_get_adjust_mode(zathura->document), NULL };
  sc_adjust_window(zathura->ui.session, &new_argument, NULL, 0);

Moritz Lipp's avatar
Moritz Lipp committed
545
  /* render all pages again */
546
  render_all(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
547

548
549
  page_set_delayed(zathura, page_number);

Moritz Lipp's avatar
Moritz Lipp committed
550
  return false;
551
552
}

Moritz Lipp's avatar
Moritz Lipp committed
553
bool
Moritz Lipp's avatar
Moritz Lipp committed
554
sc_scroll(girara_session_t* session, girara_argument_t* argument,
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
555
          girara_event_t* UNUSED(event), unsigned int t)
556
{
Moritz Lipp's avatar
Moritz Lipp committed
557
558
559
560
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
561
562
563
  if (zathura->document == NULL) {
    return false;
  }
Moritz Lipp's avatar
Moritz Lipp committed
564

Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
565
  if (t == 0) {
566
567
568
    t = 1;
  }

Moritz Lipp's avatar
Moritz Lipp committed
569
  GtkAdjustment* adjustment = NULL;
570
  if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
Moritz Lipp's avatar
Moritz Lipp committed
571
       (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
Moritz Lipp's avatar
Moritz Lipp committed
572
    adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
573
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
574
    adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
575
  }
Moritz Lipp's avatar
Moritz Lipp committed
576

577
578
579
  gdouble view_size                  = gtk_adjustment_get_page_size(adjustment);
  gdouble value                      = gtk_adjustment_get_value(adjustment);
  gdouble max                        = gtk_adjustment_get_upper(adjustment) - view_size;
580
  zathura->global.update_page_number = true;
581

582
583
  float scroll_step = 40;
  girara_setting_get(session, "scroll-step", &scroll_step);
Julian Orth's avatar
Julian Orth committed
584
585
586
587
588
  float scroll_hstep = -1;
  girara_setting_get(session, "scroll-hstep", &scroll_hstep);
  if (scroll_hstep < 0) {
    scroll_hstep = scroll_step;
  }
589
  float scroll_full_overlap = 0.0;
590
  girara_setting_get(session, "scroll-full-overlap", &scroll_full_overlap);
Jonas Hoersch's avatar
Jonas Hoersch committed
591
592
  bool scroll_page_aware = false;
  girara_setting_get(session, "scroll-page-aware", &scroll_page_aware);
593

594
595
596
  bool scroll_wrap = false;
  girara_setting_get(session, "scroll-wrap", &scroll_wrap);

597
598
599
  int padding = 1;
  girara_setting_get(session, "page-padding", &padding);

600
  gdouble new_value;
Moritz Lipp's avatar
Moritz Lipp committed
601

Moritz Lipp's avatar
Moritz Lipp committed
602
  switch(argument->n) {
Moritz Lipp's avatar
Moritz Lipp committed
603
    case FULL_UP:
604
    case FULL_LEFT:
605
      new_value = value - (1.0 - scroll_full_overlap) * view_size - padding;
Moritz Lipp's avatar
Moritz Lipp committed
606
607
      break;
    case FULL_DOWN:
608
    case FULL_RIGHT:
609
      new_value = value + (1.0 - scroll_full_overlap) * view_size + padding;
Moritz Lipp's avatar
Moritz Lipp committed
610
611
      break;
    case HALF_UP:
612
    case HALF_LEFT:
613
      new_value = value - ((view_size + padding) / 2);
Moritz Lipp's avatar
Moritz Lipp committed
614
615
      break;
    case HALF_DOWN:
616
    case HALF_RIGHT:
617
      new_value = value + ((view_size + padding) / 2);
Moritz Lipp's avatar
Moritz Lipp committed
618
619
      break;
    case LEFT:
620
      new_value = value - scroll_hstep * t;
Julian Orth's avatar
Julian Orth committed
621
      break;
Moritz Lipp's avatar
Moritz Lipp committed
622
    case UP:
623
      new_value = value - scroll_step * t;
Moritz Lipp's avatar
Moritz Lipp committed
624
625
      break;
    case RIGHT:
626
      new_value = value + scroll_hstep * t;
Julian Orth's avatar
Julian Orth committed
627
      break;
Moritz Lipp's avatar
Moritz Lipp committed
628
    case DOWN:
629
      new_value = value + scroll_step * t;
Moritz Lipp's avatar
Moritz Lipp committed
630
631
632
633
634
635
636
637
      break;
    case TOP:
      new_value = 0;
      break;
    case BOTTOM:
      new_value = max;
      break;
    default:
Moritz Lipp's avatar
Moritz Lipp committed
638
      new_value = value;
Moritz Lipp's avatar
Moritz Lipp committed
639
640
  }

641
642
643
644
645
646
647
  if (scroll_wrap == true) {
    if (new_value < 0)
      new_value = max;
    else if (new_value > max)
      new_value = 0;
  }

Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
648
  if (scroll_page_aware == true) {
Jonas Hoersch's avatar
Jonas Hoersch committed
649
650
651
652
653
654
655
656
657
658
659
    int page_offset;
    double page_size;

    {
      unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
      zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
      page_offset_t offset;
      page_calculate_offset(zathura, page, &offset);

      double scale = zathura_document_get_scale(zathura->document);

Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
660
661
      if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
          (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
662
663
664
665
666
667
668
669
670
671
        page_offset = offset.x;
        page_size = zathura_page_get_width(page) * scale;
      } else {
        page_offset = offset.y;
        page_size = zathura_page_get_height(page) * scale;
      }

      page_offset -= padding / 2;
      page_size   += padding;
    }
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
672
673
674
675
676

    if ((argument->n == FULL_DOWN) || (argument->n == HALF_DOWN) ||
        (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
      if ((page_offset > value) &&
          (page_offset < value + view_size)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
677
        new_value = page_offset;
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
678
679
      } else if ((page_offset <= value) &&
                 (page_offset + page_size < value + view_size)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
680
        new_value = page_offset + page_size + 1;
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
681
682
      } else if ((page_offset <= value) &&
                 (page_offset + page_size < new_value + view_size)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
683
684
        new_value = page_offset + page_size - view_size + 1;
      }
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
685
686
687
688
    } else if ((argument->n == FULL_UP) || (argument->n == HALF_UP) ||
               (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT)) {
      if ((page_offset + 1 >= value) &&
          (page_offset < value + view_size)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
689
        new_value = page_offset - view_size;
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
690
691
      } else if ((page_offset <= value) &&
                 (page_offset + page_size + 1 < value + view_size)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
692
        new_value = page_offset + page_size - view_size;
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
693
694
      } else if ((page_offset <= value) &&
                 (page_offset > new_value)) {
Jonas Hoersch's avatar
Jonas Hoersch committed
695
696
        new_value = page_offset;
      }
Sebastian Ramacher's avatar
CS    
Sebastian Ramacher committed
697
    }
Jonas Hoersch's avatar
Jonas Hoersch committed
698
699
  }

700
  zathura_adjustment_set_value(adjustment, new_value);
Moritz Lipp's avatar
Moritz Lipp committed
701

Moritz Lipp's avatar
Moritz Lipp committed
702
  return false;
703
704
}

705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

bool
sc_jumplist(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

  zathura_jump_t* jump = NULL;
  switch(argument->n) {
    case FORWARD:
      zathura_jumplist_save(zathura);
      zathura_jumplist_forward(zathura);
      jump = zathura_jumplist_current(zathura);
      break;

    case BACKWARD:
      zathura_jumplist_save(zathura);
      zathura_jumplist_backward(zathura);
      jump = zathura_jumplist_current(zathura);
      break;
  }

730
731
732
733
734
  if (jump != NULL) {
    page_set(zathura, jump->page);
    const double s = zathura_document_get_scale(zathura->document);
    position_set_delayed(zathura, jump->x * s, jump->y * s);
  }
735
736
737
738

  return false;
}

Moritz Lipp's avatar
Moritz Lipp committed
739
bool
Moritz Lipp's avatar
Moritz Lipp committed
740
sc_search(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
741
          girara_event_t* UNUSED(event), unsigned int UNUSED(t))
742
{
Moritz Lipp's avatar
Moritz Lipp committed
743
744
745
746
747
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
748

749
750
  const int num_pages = zathura_document_get_number_of_pages(zathura->document);
  const int cur_page  = zathura_document_get_current_page_number(zathura->document);
751

752
  int diff = argument->n == FORWARD ? 1 : -1;
753
754
  if (zathura->global.search_direction == BACKWARD)
    diff = -diff;
755

Sebastian Ramacher's avatar
Sebastian Ramacher committed
756
757
758
  zathura_page_t* target_page = NULL;
  int target_idx = 0;

759
760
  for (int page_id = 0; page_id < num_pages; ++page_id) {
    int tmp = cur_page + diff * page_id;
761
    zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages);
762
763
764
765
    if (page == NULL) {
      continue;
    }

766
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Moritz Lipp's avatar
Moritz Lipp committed
767

768
    int num_search_results = 0, current = -1;
Moritz Lipp's avatar
Moritz Lipp committed
769
    g_object_get(page_widget, "search-current", &current,
Moritz Lipp's avatar
Moritz Lipp committed
770
                 "search-length", &num_search_results, NULL);
771
772
773
774
775
776
    if (num_search_results == 0 || current == -1) {
      continue;
    }

    if (diff == 1 && current < num_search_results - 1) {
      /* the next result is on the same page */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
777
778
      target_page = page;
      target_idx = current + 1;
779
    } else if (diff == -1 && current > 0) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
780
781
      target_page = page;
      target_idx = current - 1;
782
783
    } else {
      /* the next result is on a different page */
784
785
      zathura_jumplist_save(zathura);

Moritz Lipp's avatar
Moritz Lipp committed
786
      g_object_set(page_widget, "search-current", -1, NULL);
787
788
789

      for (int npage_id = 1; page_id < num_pages; ++npage_id) {
        int ntmp = cur_page + diff * (page_id + npage_id);
790
791
        zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages);
        zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(npage));
792
        GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage);
Moritz Lipp's avatar
Moritz Lipp committed
793
        g_object_get(npage_page_widget, "search-length", &num_search_results, NULL);
794
        if (num_search_results != 0) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
795
796
          target_page = npage;
          target_idx = diff == 1 ? 0 : num_search_results - 1;
797
798
799
          break;
        }
      }
800
801

      zathura_jumplist_add(zathura);
802
    }
803

804
805
    break;
  }
Moritz Lipp's avatar
Moritz Lipp committed
806

Sebastian Ramacher's avatar
Sebastian Ramacher committed
807
808
  if (target_page != NULL) {
    girara_list_t* results = NULL;
809
    GtkWidget* page_widget = zathura_page_get_widget(zathura, target_page);
Moritz Lipp's avatar
Moritz Lipp committed
810
811
    g_object_set(page_widget, "search-current", target_idx, NULL);
    g_object_get(page_widget, "search-results", &results, NULL);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
812
813
814
815

    zathura_rectangle_t* rect = girara_list_nth(results, target_idx);
    zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect);
    page_offset_t offset;
816
    page_calculate_offset(zathura, target_page, &offset);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
817
818
819

    GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
    int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
820
    zathura_adjustment_set_value(view_vadjustment, y);
Julian Orth's avatar
Julian Orth committed
821
822
823
824
825
826

    bool search_hadjust = true;
    girara_setting_get(session, "search-hadjust", &search_hadjust);
    if (search_hadjust == true) {
      GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
      int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1;
827
      zathura_adjustment_set_value(view_hadjustment, x);
Julian Orth's avatar
Julian Orth committed
828
    }
Sebastian Ramacher's avatar
Sebastian Ramacher committed
829
830
  }

Moritz Lipp's avatar
Moritz Lipp committed
831
  return false;
832
833
}

Moritz Lipp's avatar
Moritz Lipp committed
834
bool
835
sc_navigate_index(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
836
                  girara_event_t* UNUSED(event), unsigned int UNUSED(t))
837
{
Moritz Lipp's avatar
Moritz Lipp committed
838
839
840
841
842
843
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

Moritz Lipp's avatar
Moritz Lipp committed
844
845
846
847
848
849
850
851
  if(zathura->ui.index == NULL) {
    return false;
  }

  GtkTreeView *tree_view = gtk_container_get_children(GTK_CONTAINER(zathura->ui.index))->data;
  GtkTreePath *path;

  gtk_tree_view_get_cursor(tree_view, &path, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
852
  if (path == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
853
854
855
856
857
858
859
860
861
862
863
    return false;
  }

  GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  GtkTreeIter   iter;
  GtkTreeIter   child_iter;

  gboolean is_valid_path = TRUE;

  switch(argument->n) {
    case UP:
864
      if (gtk_tree_path_prev(path) == FALSE) {
865
866
867
        /* For some reason gtk_tree_path_up returns TRUE although we're not
         * moving anywhere. */
        is_valid_path = gtk_tree_path_up(path) && (gtk_tree_path_get_depth(path) > 0);
Moritz Lipp's avatar
Moritz Lipp committed
868
869
870
871
872
      } else { /* row above */
        while(gtk_tree_view_row_expanded(tree_view, path)) {
          gtk_tree_model_get_iter(model, &iter, path);
          /* select last child */
          gtk_tree_model_iter_nth_child(model, &child_iter, &iter,
Moritz Lipp's avatar
Moritz Lipp committed
873
                                        gtk_tree_model_iter_n_children(model, &iter)-1);
Moritz Lipp's avatar
Moritz Lipp committed
874
875
876
877
878
879
          gtk_tree_path_free(path);
          path = gtk_tree_model_get_path(model, &child_iter);
        }
      }
      break;
    case COLLAPSE:
880
      if (gtk_tree_view_collapse_row(tree_view, path) == FALSE
Moritz Lipp's avatar
Moritz Lipp committed
881
          && gtk_tree_path_get_depth(path) > 1) {
Moritz Lipp's avatar
Moritz Lipp committed
882
883
884
885
886
        gtk_tree_path_up(path);
        gtk_tree_view_collapse_row(tree_view, path);
      }
      break;
    case DOWN:
887
      if (gtk_tree_view_row_expanded(tree_view, path) == TRUE) {
Moritz Lipp's avatar
Moritz Lipp committed
888
889
890
891
892
        gtk_tree_path_down(path);
      } else {
        do {
          gtk_tree_model_get_iter(model, &iter, path);
          if (gtk_tree_model_iter_next(model, &iter)) {
893
            gtk_tree_path_free(path);
Moritz Lipp's avatar
Moritz Lipp committed
894
895
896
897
            path = gtk_tree_model_get_path(model, &iter);
            break;
          }
        } while((is_valid_path = (gtk_tree_path_get_depth(path) > 1))
Moritz Lipp's avatar
Moritz Lipp committed
898
                && gtk_tree_path_up(path));
Moritz Lipp's avatar
Moritz Lipp committed
899
900
901
      }
      break;
    case EXPAND:
902
      if (gtk_tree_view_expand_row(tree_view, path, FALSE)) {
Moritz Lipp's avatar
Moritz Lipp committed
903
904
905
        gtk_tree_path_down(path);
      }
      break;
906
907
908
909
910
911
912
913
914
    case EXPAND_ALL:
      gtk_tree_view_expand_all(tree_view);
      break;
    case COLLAPSE_ALL:
      gtk_tree_view_collapse_all(tree_view);
      gtk_tree_path_free(path);
      path = gtk_tree_path_new_first();
      gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);
      break;
Moritz Lipp's avatar
Moritz Lipp committed
915
916
    case SELECT:
      cb_index_row_activated(tree_view, path, NULL, zathura);
917
      gtk_tree_path_free(path);
Moritz Lipp's avatar
Moritz Lipp committed
918
919
920
921
922
923
924
925
926
      return false;
  }

  if (is_valid_path) {
    gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);
  }

  gtk_tree_path_free(path);

Moritz Lipp's avatar
Moritz Lipp committed
927
  return false;
928
929
}

Moritz Lipp's avatar
Moritz Lipp committed
930
bool
931
sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
932
                girara_event_t* UNUSED(event), unsigned int UNUSED(t))
933
{
Moritz Lipp's avatar
Moritz Lipp committed
934
935
936
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
937
938
939
  if (zathura->document == NULL) {
    return false;
  }
940
941
942
943
944

  girara_tree_node_t* document_index = NULL;
  GtkWidget* treeview                = NULL;
  GtkTreeModel* model                = NULL;
  GtkCellRenderer* renderer          = NULL;
945
  GtkCellRenderer* renderer2         = NULL;
946

947
  if (zathura->ui.index == NULL) {
948
    /* create new index widget */
949
    zathura->ui.index = gtk_scrolled_window_new(NULL, NULL);
950

951
    if (zathura->ui.index == NULL) {
952
953
954
      goto error_ret;
    }

955
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index),
Moritz Lipp's avatar
Moritz Lipp committed
956
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
957
958

    /* create index */
959
    document_index = zathura_document_index_generate(zathura->document, NULL);
960
    if (document_index == NULL) {
961
      girara_notify(session, GIRARA_WARNING, _("This document does not contain any index"));
962
963
964
      goto error_free;
    }

Sebastian Ramacher's avatar
Sebastian Ramacher committed
965
    model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
    if (model == NULL) {
      goto error_free;
    }

    treeview = gtk_tree_view_new_with_model(model);
    if (treeview == NULL) {
      goto error_free;
    }

    g_object_unref(model);

    renderer = gtk_cell_renderer_text_new();
    if (renderer == NULL) {
      goto error_free;
    }

982
983
984
985
986
    renderer2 = gtk_cell_renderer_text_new();
    if (renderer2 == NULL) {
      goto error_free;
    }

987
988
989
990
991
    document_index_build(model, NULL, document_index);
    girara_node_free(document_index);

    /* setup widget */
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 0, "Title", renderer, "markup", 0, NULL);
992
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 1, "Target", renderer2, "text", 1, NULL);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
993

994
995
996
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
    g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    g_object_set(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)), "expand", TRUE, NULL);
997
    gtk_tree_view_column_set_alignment(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), 1.0f);
998
    gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE);
999
    g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), zathura);
1000

1001
    gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview);
1002
1003
1004
    gtk_widget_show(treeview);
  }

Moritz Lipp's avatar
Moritz Lipp committed
1005
1006
1007
  static double vvalue = 0;
  static double hvalue = 0;

1008
  if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) {
1009
    girara_set_view(session, zathura->ui.page_widget_alignment);
1010
    gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
1011
    girara_mode_set(zathura->ui.session, zathura->modes.normal);
Moritz Lipp's avatar
Moritz Lipp committed
1012
1013

    /* reset adjustment */
1014
    position_set_delayed(zathura, hvalue, vvalue);
1015
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
1016
    /* save adjustment */
1017
1018
1019
    GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
    GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));

Moritz Lipp's avatar
Moritz Lipp committed
1020
1021
1022
    vvalue = gtk_adjustment_get_value(vadjustment);
    hvalue = gtk_adjustment_get_value(hadjustment);

Abdó Roig-Maranges's avatar