callbacks.c 18.6 KB
Newer Older
Moritz Lipp's avatar
Moritz Lipp committed
1
/* See LICENSE file for license and copyright information */
Moritz Lipp's avatar
Moritz Lipp committed
2

3
4
5
#include <girara/statusbar.h>
#include <girara/session.h>
#include <girara/settings.h>
Sebastian Ramacher's avatar
Sebastian Ramacher committed
6
#include <girara/utils.h>
Moritz Lipp's avatar
Moritz Lipp committed
7
#include <stdlib.h>
8
#include <gtk/gtk.h>
Moritz Lipp's avatar
Moritz Lipp committed
9
#include <string.h>
10
#include <glib/gi18n.h>
11
#include <math.h>
Moritz Lipp's avatar
Moritz Lipp committed
12

Sebastian Ramacher's avatar
Sebastian Ramacher committed
13
#include "callbacks.h"
Moritz Lipp's avatar
Moritz Lipp committed
14
#include "links.h"
Moritz Lipp's avatar
Moritz Lipp committed
15
#include "zathura.h"
Moritz Lipp's avatar
Moritz Lipp committed
16
#include "render.h"
17
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
18
#include "utils.h"
Sebastian Ramacher's avatar
Sebastian Ramacher committed
19
#include "shortcuts.h"
20
#include "page-widget.h"
Moritz Lipp's avatar
Moritz Lipp committed
21
#include "page.h"
22
#include "adjustment.h"
23
24
#include "synctex.h"
#include "dbus-interface.h"
Moritz Lipp's avatar
Moritz Lipp committed
25
26

gboolean
27
cb_destroy(GtkWidget* UNUSED(widget), zathura_t* zathura)
Moritz Lipp's avatar
Moritz Lipp committed
28
{
29
  if (zathura != NULL && zathura->document != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
30
    document_close(zathura, false);
31
32
  }

33
  gtk_main_quit();
Moritz Lipp's avatar
Moritz Lipp committed
34
35
  return TRUE;
}
Moritz Lipp's avatar
Moritz Lipp committed
36
37

void
Moritz Lipp's avatar
Moritz Lipp committed
38
cb_buffer_changed(girara_session_t* session)
Moritz Lipp's avatar
Moritz Lipp committed
39
40
{
  g_return_if_fail(session != NULL);
Moritz Lipp's avatar
Moritz Lipp committed
41
42
43
  g_return_if_fail(session->global.data != NULL);

  zathura_t* zathura = session->global.data;
Moritz Lipp's avatar
Moritz Lipp committed
44
45

  char* buffer = girara_buffer_get(session);
Moritz Lipp's avatar
Moritz Lipp committed
46
  if (buffer != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
47
    girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
Moritz Lipp's avatar
Moritz Lipp committed
48
    free(buffer);
Moritz Lipp's avatar
Moritz Lipp committed
49
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
50
    girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
51
  }
Moritz Lipp's avatar
Moritz Lipp committed
52
}
53

54
void
55
56
update_visible_pages(zathura_t* zathura)
{
57
  const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
58
59
60

  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);
61
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
62
    ZathuraPage* zathura_page_widget = ZATHURA_PAGE(page_widget);
63

64
65
    if (page_is_visible(zathura->document, page_id) == true) {
      /* make page visible */
66
      if (zathura_page_get_visibility(page) == false) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
67
        zathura_page_set_visibility(page, true);
68
        zathura_page_widget_update_view_time(zathura_page_widget);
69
        zathura_renderer_page_cache_add(zathura->sync.render_thread, zathura_page_get_index(page));
70
      }
71

72
    } else {
73
      /* make page invisible */
74
75
76
77
      if (zathura_page_get_visibility(page) == true) {
        zathura_page_set_visibility(page, false);
        /* If a page becomes invisible, abort the render request. */
        zathura_page_widget_abort_render_request(zathura_page_widget);
78
      }
Marwan Tanager's avatar
Marwan Tanager committed
79

80
      /* reset current search result */
Marwan Tanager's avatar
Marwan Tanager committed
81
      girara_list_t* results = NULL;
Sebastian Ramacher's avatar
Sebastian Ramacher committed
82
83
      GObject* obj_page_widget = G_OBJECT(page_widget);
      g_object_get(obj_page_widget, "search-results", &results, NULL);
Marwan Tanager's avatar
Marwan Tanager committed
84
      if (results != NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
85
        g_object_set(obj_page_widget, "search-current", 0, NULL);
Marwan Tanager's avatar
Marwan Tanager committed
86
      }
87
88
    }
  }
89
90
91
92
93
94
95
96
97
98
}

void
cb_view_hadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

99
100
101
102
103
  /* Do nothing in index mode */
  if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
    return;
  }

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  update_visible_pages(zathura);

  double position_x = zathura_adjustment_get_ratio(adjustment);
  double position_y = zathura_document_get_position_y(zathura->document);
  unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);

  zathura_document_set_position_x(zathura->document, position_x);
  zathura_document_set_position_y(zathura->document, position_y);
  zathura_document_set_current_page_number(zathura->document, page_id);

  statusbar_page_number_update(zathura);
}

void
cb_view_vadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

125
126
127
128
129
  /* Do nothing in index mode */
  if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
    return;
  }

130
131
132
133
134
135
136
137
138
  update_visible_pages(zathura);

  double position_x = zathura_document_get_position_x(zathura->document);
  double position_y = zathura_adjustment_get_ratio(adjustment);
  unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);

  zathura_document_set_position_x(zathura->document, position_x);
  zathura_document_set_position_y(zathura->document, position_y);
  zathura_document_set_current_page_number(zathura->document, page_id);
139
140

  statusbar_page_number_update(zathura);
141
}
142

Sebastian Ramacher's avatar
Sebastian Ramacher committed
143
144
145
static void
cb_view_adjustment_changed(GtkAdjustment* adjustment, zathura_t* zathura,
    bool width)
146
{
147
148
149
150
151
  /* Do nothing in index mode */
  if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
    return;
  }

Sebastian Ramacher's avatar
Sebastian Ramacher committed
152
153
154
155
  const zathura_adjust_mode_t adjust_mode =
    zathura_document_get_adjust_mode(zathura->document);

  /* Don't scroll, we're focusing the inputbar. */
156
157
  if (adjust_mode == ZATHURA_ADJUST_INPUTBAR) {
    return;
158
  }
159

Sebastian Ramacher's avatar
Sebastian Ramacher committed
160
161
162
163
164
165
166
  /* Save the viewport size */
  unsigned int size = (unsigned int)floor(gtk_adjustment_get_page_size(adjustment));
  if (width == true) {
    zathura_document_set_viewport_width(zathura->document, size);
  } else {
    zathura_document_set_viewport_height(zathura->document, size);
  }
167
168

  /* reset the adjustment, in case bounds have changed */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
169
170
  const double ratio = width == true ?
    zathura_document_get_position_x(zathura->document) :
Sebastian Ramacher's avatar
Sebastian Ramacher committed
171
    zathura_document_get_position_y(zathura->document);
172
  zathura_adjustment_set_value_from_ratio(adjustment, ratio);
173
174
175
}

void
Sebastian Ramacher's avatar
Sebastian Ramacher committed
176
cb_view_hadjustment_changed(GtkAdjustment* adjustment, gpointer data)
177
178
179
180
{
  zathura_t* zathura = data;
  g_return_if_fail(zathura != NULL);

Sebastian Ramacher's avatar
Sebastian Ramacher committed
181
182
  cb_view_adjustment_changed(adjustment, zathura, true);
}
183

Sebastian Ramacher's avatar
Sebastian Ramacher committed
184
185
186
187
188
void
cb_view_vadjustment_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  g_return_if_fail(zathura != NULL);
189

Sebastian Ramacher's avatar
Sebastian Ramacher committed
190
  cb_view_adjustment_changed(adjustment, zathura, false);
191
192
}

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
void
cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

  unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
  zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
  if (page == NULL) {
    return;
  }

  GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
  GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));

  double position_x = zathura_document_get_position_x(zathura->document);
  double position_y = zathura_document_get_position_y(zathura->document);

  zathura_adjustment_set_value_from_ratio(vadj, position_y);
  zathura_adjustment_set_value_from_ratio(hadj, position_x);

  statusbar_page_number_update(zathura);
}

219
void
Moritz Lipp's avatar
Moritz Lipp committed
220
cb_page_layout_value_changed(girara_session_t* session, const char* name, girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
221
{
222
  g_return_if_fail(value != NULL);
223
224
225
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  zathura_t* zathura = session->global.data;
226

Moritz Lipp's avatar
Moritz Lipp committed
227
228
229
230
231
232
  /* pages-per-row must not be 0 */
  if (g_strcmp0(name, "pages-per-row") == 0) {
    unsigned int pages_per_row = *((unsigned int*) value);
    if (pages_per_row == 0) {
      pages_per_row = 1;
      girara_setting_set(session, name, &pages_per_row);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
233
      girara_notify(session, GIRARA_WARNING, _("'%s' must not be 0. Set to 1."), name);
Moritz Lipp's avatar
Moritz Lipp committed
234
235
236
237
      return;
    }
  }

238
239
240
241
  if (zathura->document == NULL) {
    /* no document has been openend yet */
    return;
  }
242

243
244
  unsigned int pages_per_row = 1;
  girara_setting_get(session, "pages-per-row", &pages_per_row);
245

246
247
248
249
250
251
252
  /* get list of first_page_column settings */
  char* first_page_column_list = NULL;
  girara_setting_get(session, "first-page-column", &first_page_column_list);

  /* find value for first_page_column */
  unsigned int first_page_column = find_first_page_column(first_page_column_list, pages_per_row);
  g_free(first_page_column_list);
253

254
  unsigned int page_padding = 1;
255
  girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
256
257
258

  page_widget_set_mode(zathura, page_padding, pages_per_row, first_page_column);
  zathura_document_set_page_layout(zathura->document, page_padding, pages_per_row, first_page_column);
259
}
260
261

void
Moritz Lipp's avatar
Moritz Lipp committed
262
cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
Moritz Lipp's avatar
Moritz Lipp committed
263
                       GtkTreeViewColumn* UNUSED(column), void* data)
264
{
Sebastian Ramacher's avatar
Sebastian Ramacher committed
265
  zathura_t* zathura = data;
266
267
268
269
270
271
272
  if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) {
    return;
  }

  GtkTreeModel  *model;
  GtkTreeIter   iter;

Sebastian Ramacher's avatar
Sebastian Ramacher committed
273
  g_object_get(G_OBJECT(tree_view), "model", &model, NULL);
274

Moritz Lipp's avatar
Moritz Lipp committed
275
  if(gtk_tree_model_get_iter(model, &iter, path)) {
276
    zathura_index_element_t* index_element;
Sebastian Ramacher's avatar
Sebastian Ramacher committed
277
    gtk_tree_model_get(model, &iter, 2, &index_element, -1);
278
279
280
281
282

    if (index_element == NULL) {
      return;
    }

Moritz Lipp's avatar
Moritz Lipp committed
283
    sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
284
    zathura_link_evaluate(zathura, index_element->link);
285
286
287
288
  }

  g_object_unref(model);
}
Moritz Lipp's avatar
Moritz Lipp committed
289

290
291
292
293
294
295
296
297
298
typedef enum zathura_link_action_e
{
  ZATHURA_LINK_ACTION_FOLLOW,
  ZATHURA_LINK_ACTION_DISPLAY
} zathura_link_action_t;

static bool
handle_link(GtkEntry* entry, girara_session_t* session,
            zathura_link_action_t action)
Moritz Lipp's avatar
Moritz Lipp committed
299
300
301
302
303
{
  g_return_val_if_fail(session != NULL, FALSE);
  g_return_val_if_fail(session->global.data != NULL, FALSE);

  zathura_t* zathura = session->global.data;
Moritz Lipp's avatar
Moritz Lipp committed
304
  bool eval = true;
Moritz Lipp's avatar
Moritz Lipp committed
305
306

  char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
Moritz Lipp's avatar
Moritz Lipp committed
307
308
  if (input == NULL || strlen(input) == 0) {
    eval = false;
Moritz Lipp's avatar
Moritz Lipp committed
309
310
  }

Moritz Lipp's avatar
Moritz Lipp committed
311
312
313
314
  int index = 0;
  if (eval == true) {
    index = atoi(input);
    if (index == 0 && g_strcmp0(input, "0") != 0) {
315
      girara_notify(session, GIRARA_WARNING, _("Invalid input '%s' given."), input);
Moritz Lipp's avatar
Moritz Lipp committed
316
317
318
      eval = false;
    }
    index = index - 1;
Moritz Lipp's avatar
Moritz Lipp committed
319
320
321
322
  }

  /* set pages to draw links */
  bool invalid_index = true;
323
324
325
  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);
Moritz Lipp's avatar
Moritz Lipp committed
326
    if (page == NULL || zathura_page_get_visibility(page) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
327
328
329
      continue;
    }

330
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
331
    g_object_set(G_OBJECT(page_widget), "draw-links", FALSE, NULL);
332

Moritz Lipp's avatar
Moritz Lipp committed
333
    if (eval == true) {
Moritz Lipp's avatar
Moritz Lipp committed
334
      zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
335

Moritz Lipp's avatar
Moritz Lipp committed
336
337
      if (link != NULL) {
        invalid_index = false;
338
339
340
341
342
343
344
345
        switch (action) {
          case ZATHURA_LINK_ACTION_FOLLOW:
            zathura_link_evaluate(zathura, link);
            break;
          case ZATHURA_LINK_ACTION_DISPLAY:
            zathura_link_display(zathura, link);
            break;
        }
Moritz Lipp's avatar
Moritz Lipp committed
346
347
348
349
      }
    }
  }

Moritz Lipp's avatar
Moritz Lipp committed
350
  if (eval == true && invalid_index == true) {
351
    girara_notify(session, GIRARA_WARNING, _("Invalid index '%s' given."), input);
Moritz Lipp's avatar
Moritz Lipp committed
352
353
354
355
  }

  g_free(input);

Moritz Lipp's avatar
Moritz Lipp committed
356
  return (eval == TRUE) ? TRUE : FALSE;
Moritz Lipp's avatar
Moritz Lipp committed
357
}
Moritz Lipp's avatar
Moritz Lipp committed
358

359
360
361
362
363
364
365
366
367
368
369
370
bool
cb_sc_follow(GtkEntry* entry, girara_session_t* session)
{
  return handle_link(entry, session, ZATHURA_LINK_ACTION_FOLLOW);
}

bool
cb_sc_display_link(GtkEntry* entry, girara_session_t* session)
{
  return handle_link(entry, session, ZATHURA_LINK_ACTION_DISPLAY);
}

371
372
373
374
375
376
377
static gboolean
file_monitor_reload(void* data)
{
  sc_reload((girara_session_t*) data, NULL, NULL, 0);
  return FALSE;
}

Moritz Lipp's avatar
Moritz Lipp committed
378
379
380
381
382
383
384
void
cb_file_monitor(GFileMonitor* monitor, GFile* file, GFile* UNUSED(other_file), GFileMonitorEvent event, girara_session_t* session)
{
  g_return_if_fail(monitor  != NULL);
  g_return_if_fail(file     != NULL);
  g_return_if_fail(session  != NULL);

Moritz Lipp's avatar
Moritz Lipp committed
385
386
387
  switch (event) {
    case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
    case G_FILE_MONITOR_EVENT_CREATED:
388
      g_main_context_invoke(NULL, file_monitor_reload, session);
Moritz Lipp's avatar
Moritz Lipp committed
389
390
391
      break;
    default:
      return;
Moritz Lipp's avatar
Moritz Lipp committed
392
393
  }
}
394

395
396
397
398
static gboolean
password_dialog(gpointer data)
{
  zathura_password_dialog_info_t* dialog = data;
Moritz Lipp's avatar
Moritz Lipp committed
399

400
  if (dialog != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
401
    girara_dialog(
Moritz Lipp's avatar
Moritz Lipp committed
402
403
404
405
406
407
408
      dialog->zathura->ui.session,
      "Incorrect password. Enter password:",
      true,
      NULL,
      (girara_callback_inputbar_activate_t) cb_password_dialog,
      dialog
    );
409
  }
Moritz Lipp's avatar
Moritz Lipp committed
410

411
412
413
  return FALSE;
}

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
bool
cb_password_dialog(GtkEntry* entry, zathura_password_dialog_info_t* dialog)
{
  if (entry == NULL || dialog == NULL) {
    goto error_ret;
  }

  if (dialog->path == NULL) {
    free(dialog);
    goto error_ret;
  }

  if (dialog->zathura == NULL) {
    goto error_free;
  }

  char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);

  /* no or empty password: ask again */
  if (input == NULL || strlen(input) == 0) {
    if (input != NULL) {
      g_free(input);
    }

438
    gdk_threads_add_idle(password_dialog, dialog);
439
440
441
442
    return false;
  }

  /* try to open document again */
443
444
  if (document_open(dialog->zathura, dialog->path, input,
                    ZATHURA_PAGE_NUMBER_UNSPECIFIED) == false) {
445
    gdk_threads_add_idle(password_dialog, dialog);
446
447
448
449
  } else {
    g_free(dialog->path);
    free(dialog);
  }
450
451
452
453
454
455
456

  g_free(input);

  return true;

error_free:

Moritz Lipp's avatar
Moritz Lipp committed
457
458
  g_free(dialog->path);
  free(dialog);
459
460
461
462
463

error_ret:

  return false;
}
464
465

bool
466
cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* UNUSED(allocation), zathura_t* zathura)
467
468
469
470
471
{
  if (zathura == NULL || zathura->document == NULL) {
    return false;
  }

472
473
  /* adjust the scale according to settings. If nothing needs to be resized,
     it does not trigger the resize event.
474

475
476
477
478
     The right viewport size is already in the document object, due to a
     previous call to adjustment_changed. We don't want to use the allocation in
     here, because we would have to subtract scrollbars, etc. */
  adjust_view(zathura);
479
480

  return false;
481
}
Moritz Lipp's avatar
Moritz Lipp committed
482
483
484

void
cb_setting_recolor_change(girara_session_t* session, const char* name,
Moritz Lipp's avatar
Moritz Lipp committed
485
                          girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
Moritz Lipp's avatar
Moritz Lipp committed
486
487
488
489
490
491
492
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  g_return_if_fail(name != NULL);
  zathura_t* zathura = session->global.data;

493
  const bool bool_value = *((bool*) value);
Moritz Lipp's avatar
Moritz Lipp committed
494

495
496
497
  if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_enabled(zathura->sync.render_thread) != bool_value) {
     zathura_renderer_enable_recolor(zathura->sync.render_thread, bool_value);
     render_all(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
498
499
  }
}
Moritz Lipp's avatar
Moritz Lipp committed
500

501
502
void
cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
Moritz Lipp's avatar
Moritz Lipp committed
503
                                   girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
504
505
506
507
508
509
510
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  g_return_if_fail(name != NULL);
  zathura_t* zathura = session->global.data;

511
  const bool bool_value = *((bool*) value);
512

513
514
515
  if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_hue_enabled(zathura->sync.render_thread) != bool_value) {
     zathura_renderer_enable_recolor_hue(zathura->sync.render_thread, bool_value);
     render_all(zathura);
516
517
518
  }
}

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
void
cb_setting_recolor_keep_reverse_video_change(girara_session_t* session, const char* name,
                                   girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  g_return_if_fail(name != NULL);
  zathura_t* zathura = session->global.data;

  const bool bool_value = *((bool*) value);

  if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_reverse_video_enabled(zathura->sync.render_thread) != bool_value) {
     zathura_renderer_enable_recolor_reverse_video(zathura->sync.render_thread, bool_value);
     render_all(zathura);
  }
}
536

Moritz Lipp's avatar
Moritz Lipp committed
537
538
539
540
541
542
543
544
545
546
547
548
549
550
bool
cb_unknown_command(girara_session_t* session, const char* input)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  g_return_val_if_fail(input != NULL, false);

  zathura_t* zathura = session->global.data;

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

  /* check for number */
551
552
  const size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
Moritz Lipp's avatar
Moritz Lipp committed
553
554
555
556
557
    if (g_ascii_isdigit(input[i]) == FALSE) {
      return false;
    }
  }

558
  zathura_jumplist_add(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
559
  page_set(zathura, atoi(input) - 1);
560
  zathura_jumplist_add(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
561
562
563

  return true;
}
564
565
566
567
568
569
570
571
572

void
cb_page_widget_text_selected(ZathuraPage* page, const char* text, void* data)
{
  g_return_if_fail(page != NULL);
  g_return_if_fail(text != NULL);
  g_return_if_fail(data != NULL);

  zathura_t* zathura = data;
573
574
575
576
577
  girara_mode_t mode = girara_mode_get(zathura->ui.session);
  if (mode != zathura->modes.normal && mode != zathura->modes.fullscreen) {
    return;
  }

578
579
580
581
582
583
  GdkAtom* selection = get_selection(zathura);

  /* copy to clipboard */
  if (selection != NULL) {
    gtk_clipboard_set_text(gtk_clipboard_get(*selection), text, -1);

584
585
    bool notification = true;
    girara_setting_get(zathura->ui.session, "selection-notification", &notification);
586

587
    if (notification == true) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
588
589
590
      char* target = NULL;
      girara_setting_get(zathura->ui.session, "selection-clipboard", &target);

591
592
      char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' ');
      char* escaped_text = g_markup_printf_escaped(
Sebastian Ramacher's avatar
Sebastian Ramacher committed
593
594
          _("Copied selected text to selection %s: %s"), target, stripped_text);
      g_free(target);
595
596
597
598
599
      g_free(stripped_text);

      girara_notify(zathura->ui.session, GIRARA_INFO, "%s", escaped_text);
      g_free(escaped_text);
    }
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  }

  g_free(selection);
}

void
cb_page_widget_image_selected(ZathuraPage* page, GdkPixbuf* pixbuf, void* data)
{
  g_return_if_fail(page != NULL);
  g_return_if_fail(pixbuf != NULL);
  g_return_if_fail(data != NULL);

  zathura_t* zathura = data;
  GdkAtom* selection = get_selection(zathura);

  if (selection != NULL) {
    gtk_clipboard_set_image(gtk_clipboard_get(*selection), pixbuf);
  }

  g_free(selection);
}
621
622
623
624
625
626
627
628
629

void
cb_page_widget_link(ZathuraPage* page, void* data)
{
  g_return_if_fail(page != NULL);

  bool enter = (bool) data;

  GdkWindow* window = gtk_widget_get_parent_window(GTK_WIDGET(page));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
630
631
  GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET(page));
  GdkCursor* cursor = gdk_cursor_new_for_display(display, enter == true ? GDK_HAND1 : GDK_LEFT_PTR);
632
633
634
  gdk_window_set_cursor(window, cursor);
  g_object_unref(cursor);
}
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669

void
cb_page_widget_scaled_button_release(ZathuraPage* page_widget, GdkEventButton* event,
    void* data)
{
  if (event->button != 1 || !(event->state & GDK_CONTROL_MASK)) {
    return;
  }

  zathura_t* zathura = data;

  bool synctex = false;
  girara_setting_get(zathura->ui.session, "synctex", &synctex);

  if (synctex == false) {
    return;
  }

  zathura_page_t* page = zathura_page_widget_get_page(page_widget);

  if (zathura->dbus != NULL) {
    zathura_dbus_edit(zathura->dbus, zathura_page_get_index(page), event->x, event->y);
  }

  char* editor = NULL;
  girara_setting_get(zathura->ui.session, "synctex-editor-command", &editor);
  if (editor == NULL || *editor == '\0') {
    g_free(editor);
    return;
  }

  synctex_edit(editor, page, event->x, event->y);
  g_free(editor);
}