callbacks.c 12 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>
Moritz Lipp's avatar
Moritz Lipp committed
11

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

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

29
  gtk_main_quit();
Moritz Lipp's avatar
Moritz Lipp committed
30
31
  return TRUE;
}
Moritz Lipp's avatar
Moritz Lipp committed
32
33

void
Moritz Lipp's avatar
Moritz Lipp committed
34
cb_buffer_changed(girara_session_t* session)
Moritz Lipp's avatar
Moritz Lipp committed
35
36
{
  g_return_if_fail(session != NULL);
Moritz Lipp's avatar
Moritz Lipp committed
37
38
39
  g_return_if_fail(session->global.data != NULL);

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

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

void
51
cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data)
52
{
Moritz Lipp's avatar
Moritz Lipp committed
53
  zathura_t* zathura = data;
54
  if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) {
55
56
57
    return;
  }

58
59
60
  GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
  GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));

61
62
63
64
65
66
67
  /* current adjustment values */
  GdkRectangle view_rect = {
    .x      = 0,
    .y      = 0,
    .width  = gtk_adjustment_get_page_size(view_hadjustment),
    .height = gtk_adjustment_get_page_size(view_vadjustment)
  };
68
69
70

  int page_padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
71

72
73
74
75
76
77
  GdkRectangle center = {
    .x      = (view_rect.width  + 1) / 2,
    .y      = (view_rect.height + 1) / 2,
    .width  = (2 * page_padding) + 1,
    .height = (2 * page_padding) + 1
  };
78

79
80
81
  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  double scale = zathura_document_get_scale(zathura->document);

82
  bool updated = false;
83
  /* find page that fits */
84
85
  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
86

87
88
89
90
    GdkRectangle page_rect = {
      .width  = zathura_page_get_width(page)  * scale,
      .height = zathura_page_get_height(page) * scale
    };
91
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Moritz Lipp's avatar
Moritz Lipp committed
92
    gtk_widget_translate_coordinates(page_widget,
Moritz Lipp's avatar
Moritz Lipp committed
93
                                     zathura->ui.session->gtk.view, 0, 0, &page_rect.x, &page_rect.y);
94

95
    if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) {
Moritz Lipp's avatar
Moritz Lipp committed
96
      zathura_page_set_visibility(page, true);
97
98
      if (zathura->global.update_page_number == true && updated == false
          && gdk_rectangle_intersect(&center, &page_rect, NULL) == TRUE) {
99
        zathura_document_set_current_page_number(zathura->document, page_id);
100
101
        updated = true;
      }
102
    } else {
Moritz Lipp's avatar
Moritz Lipp committed
103
      zathura_page_set_visibility(page, false);
104
    }
Moritz Lipp's avatar
Moritz Lipp committed
105
    zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget));
106
  }
107
108

  statusbar_page_number_update(zathura);
109
}
110
111

void
112
cb_pages_per_row_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
113
{
114
  g_return_if_fail(value != NULL);
115
116
117
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  zathura_t* zathura = session->global.data;
118
119

  int pages_per_row = *(int*) value;
120

Moritz Lipp's avatar
Moritz Lipp committed
121
  if (pages_per_row < 1) {
122
    pages_per_row = 1;
Moritz Lipp's avatar
Moritz Lipp committed
123
  }
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  unsigned int first_page_column = 1;
  girara_setting_get(session, "first-page-column", &first_page_column);

  page_widget_set_mode(zathura, pages_per_row, first_page_column);

  if (zathura->document != NULL) {
    unsigned int current_page = zathura_document_get_current_page_number(zathura->document);
    page_set_delayed(zathura, current_page);
  }
}

void
cb_first_page_column_value_changed(girara_session_t* session, const char* UNUSED(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);
  zathura_t* zathura = session->global.data;

  int first_page_column = *(int*) value;

  if (first_page_column < 1) {
    first_page_column = 1;
  }

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

  page_widget_set_mode(zathura, pages_per_row, first_page_column);
154
155

  if (zathura->document != NULL) {
156
    unsigned int current_page = zathura_document_get_current_page_number(zathura->document);
157
158
    page_set_delayed(zathura, current_page);
  }
159
}
160
161

void
Moritz Lipp's avatar
Moritz Lipp committed
162
cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
Moritz Lipp's avatar
Moritz Lipp committed
163
                       GtkTreeViewColumn* UNUSED(column), void* data)
164
{
Sebastian Ramacher's avatar
Sebastian Ramacher committed
165
  zathura_t* zathura = data;
166
167
168
169
170
171
172
173
174
  if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) {
    return;
  }

  GtkTreeModel  *model;
  GtkTreeIter   iter;

  g_object_get(tree_view, "model", &model, NULL);

Moritz Lipp's avatar
Moritz Lipp committed
175
  if(gtk_tree_model_get_iter(model, &iter, path)) {
176
    zathura_index_element_t* index_element;
Sebastian Ramacher's avatar
Sebastian Ramacher committed
177
    gtk_tree_model_get(model, &iter, 2, &index_element, -1);
178
179
180
181
182

    if (index_element == NULL) {
      return;
    }

Moritz Lipp's avatar
Moritz Lipp committed
183
    sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
184
185

    /* zathura_jumplist_save is called when entering index mode */
186
    zathura_link_evaluate(zathura, index_element->link);
187
    zathura_jumplist_add(zathura);
188
189
190
191
  }

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

193
194
195
196
197
198
199
200
201
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
202
203
204
205
206
{
  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
207
  bool eval = true;
Moritz Lipp's avatar
Moritz Lipp committed
208
209

  char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
Moritz Lipp's avatar
Moritz Lipp committed
210
211
  if (input == NULL || strlen(input) == 0) {
    eval = false;
Moritz Lipp's avatar
Moritz Lipp committed
212
213
  }

Moritz Lipp's avatar
Moritz Lipp committed
214
215
216
217
  int index = 0;
  if (eval == true) {
    index = atoi(input);
    if (index == 0 && g_strcmp0(input, "0") != 0) {
218
      girara_notify(session, GIRARA_WARNING, _("Invalid input '%s' given."), input);
Moritz Lipp's avatar
Moritz Lipp committed
219
220
221
      eval = false;
    }
    index = index - 1;
Moritz Lipp's avatar
Moritz Lipp committed
222
223
224
225
  }

  /* set pages to draw links */
  bool invalid_index = true;
226
227
228
  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
229
    if (page == NULL || zathura_page_get_visibility(page) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
230
231
232
      continue;
    }

233
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Moritz Lipp's avatar
Moritz Lipp committed
234
    g_object_set(page_widget, "draw-links", FALSE, NULL);
235

Moritz Lipp's avatar
Moritz Lipp committed
236
    if (eval == true) {
Moritz Lipp's avatar
Moritz Lipp committed
237
      zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
238

Moritz Lipp's avatar
Moritz Lipp committed
239
240
      if (link != NULL) {
        invalid_index = false;
241
242
243
244
245
246
247
248
249
250
        switch (action) {
          case ZATHURA_LINK_ACTION_FOLLOW:
            zathura_jumplist_save(zathura);
            zathura_link_evaluate(zathura, link);
            zathura_jumplist_add(zathura);
            break;
          case ZATHURA_LINK_ACTION_DISPLAY:
            zathura_link_display(zathura, link);
            break;
        }
Moritz Lipp's avatar
Moritz Lipp committed
251
252
253
254
      }
    }
  }

Moritz Lipp's avatar
Moritz Lipp committed
255
  if (eval == true && invalid_index == true) {
256
    girara_notify(session, GIRARA_WARNING, _("Invalid index '%s' given."), input);
Moritz Lipp's avatar
Moritz Lipp committed
257
258
259
260
  }

  g_free(input);

Moritz Lipp's avatar
Moritz Lipp committed
261
  return (eval == TRUE) ? TRUE : FALSE;
Moritz Lipp's avatar
Moritz Lipp committed
262
}
Moritz Lipp's avatar
Moritz Lipp committed
263

264
265
266
267
268
269
270
271
272
273
274
275
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);
}

Moritz Lipp's avatar
Moritz Lipp committed
276
277
278
279
280
281
282
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
283
284
285
  switch (event) {
    case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
    case G_FILE_MONITOR_EVENT_CREATED:
286
      gdk_threads_enter();
Moritz Lipp's avatar
Moritz Lipp committed
287
      sc_reload(session, NULL, NULL, 0);
288
      gdk_threads_leave();
Moritz Lipp's avatar
Moritz Lipp committed
289
290
291
      break;
    default:
      return;
Moritz Lipp's avatar
Moritz Lipp committed
292
293
  }
}
294

295
296
297
298
static gboolean
password_dialog(gpointer data)
{
  zathura_password_dialog_info_t* dialog = data;
Moritz Lipp's avatar
Moritz Lipp committed
299

300
  if (dialog != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
301
    girara_dialog(
Moritz Lipp's avatar
Moritz Lipp committed
302
303
304
305
306
307
308
      dialog->zathura->ui.session,
      "Incorrect password. Enter password:",
      true,
      NULL,
      (girara_callback_inputbar_activate_t) cb_password_dialog,
      dialog
    );
309
  }
Moritz Lipp's avatar
Moritz Lipp committed
310

311
312
313
  return FALSE;
}

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
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);
    }

338
    gdk_threads_add_idle(password_dialog, dialog);
339
340
341
342
    return false;
  }

  /* try to open document again */
343
344
  if (document_open(dialog->zathura, dialog->path, input,
                    ZATHURA_PAGE_NUMBER_UNSPECIFIED) == false) {
345
    gdk_threads_add_idle(password_dialog, dialog);
346
347
348
349
  } else {
    g_free(dialog->path);
    free(dialog);
  }
350
351
352
353
354
355
356

  g_free(input);

  return true;

error_free:

Moritz Lipp's avatar
Moritz Lipp committed
357
358
  g_free(dialog->path);
  free(dialog);
359
360
361
362
363

error_ret:

  return false;
}
364
365

bool
366
cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* allocation, zathura_t* zathura)
367
368
369
370
371
{
  if (zathura == NULL || zathura->document == NULL) {
    return false;
  }

372
373
  static int height = -1;
  static int width = -1;
374

375
376
  /* adjust only if the allocation changed */
  if (width != allocation->width || height != allocation->height) {
377
    girara_argument_t argument = { zathura_document_get_adjust_mode(zathura->document), NULL };
378
    sc_adjust_window(zathura->ui.session, &argument, NULL, 0);
Moritz Lipp's avatar
Moritz Lipp committed
379
380

    width  = allocation->width;
381
382
383
384
    height = allocation->height;
  }

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

void
cb_setting_recolor_change(girara_session_t* session, const char* name,
Moritz Lipp's avatar
Moritz Lipp committed
389
                          girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
Moritz Lipp's avatar
Moritz Lipp committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
{
  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;

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

  if (zathura->global.recolor != bool_value) {
    zathura->global.recolor = bool_value;
    render_all(zathura);
  }
}
Moritz Lipp's avatar
Moritz Lipp committed
404

405
406
void
cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
Moritz Lipp's avatar
Moritz Lipp committed
407
                                   girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
{
  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;

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

  if (zathura->global.recolor_keep_hue != bool_value) {
    zathura->global.recolor_keep_hue = bool_value;
    render_all(zathura);
  }
}


Moritz Lipp's avatar
Moritz Lipp committed
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
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 */
  for (unsigned int i = 0; i < strlen(input); i++) {
    if (g_ascii_isdigit(input[i]) == FALSE) {
      return false;
    }
  }

444
  zathura_jumplist_save(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
445
  page_set(zathura, atoi(input) - 1);
446
  zathura_jumplist_add(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
447
448
449

  return true;
}