callbacks.c 14.5 KB
Newer Older
1 2 3 4 5 6 7 8 9
/* See LICENSE file for license and copyright information */

#include <girara/statusbar.h>
#include <girara/session.h>
#include <girara/settings.h>
#include <girara/utils.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <string.h>
10
#include <glib/gi18n.h>
11 12

#include "callbacks.h"
13
#include "links.h"
14 15 16 17 18
#include "zathura.h"
#include "render.h"
#include "document.h"
#include "utils.h"
#include "shortcuts.h"
19
#include "page-widget.h"
20
#include "page.h"
21
#include "adjustment.h"
22 23

gboolean
24
cb_destroy(GtkWidget* UNUSED(widget), zathura_t* zathura)
25
{
26
  if (zathura != NULL && zathura->document != NULL) {
27
    document_close(zathura, false);
28 29
  }

30 31 32 33 34 35 36 37 38 39 40 41 42
  gtk_main_quit();
  return TRUE;
}

void
cb_buffer_changed(girara_session_t* session)
{
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);

  zathura_t* zathura = session->global.data;

  char* buffer = girara_buffer_get(session);
43
  if (buffer != NULL) {
44 45 46 47 48 49 50 51 52 53 54
    girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
    free(buffer);
  } else {
    girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
  }
}

void
cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data)
{
  zathura_t* zathura = data;
55
  if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) {
56 57 58 59 60 61
    return;
  }

  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));

62 63 64 65 66 67 68
  /* 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)
  };
69 70 71 72

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

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

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

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

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

    if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) {
97 98 99 100 101
      if (zathura_page_get_visibility(page) == false) {
	zathura_page_set_visibility(page, true);
	zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget));
	zathura_page_cache_add(zathura, zathura_page_get_index(page));
      }
102 103
      if (zathura->global.update_page_number == true && updated == false
          && gdk_rectangle_intersect(&center, &page_rect, NULL) == TRUE) {
104
        zathura_document_set_current_page_number(zathura->document, page_id);
105 106 107
        updated = true;
      }
    } else {
108
      zathura_page_set_visibility(page, false);
109 110 111 112 113 114
    }
  }

  statusbar_page_number_update(zathura);
}

115 116 117 118 119 120 121 122 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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
void
cb_view_hadjustment_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  g_return_if_fail(zathura != NULL);

  zathura_adjust_mode_t adjust_mode =
    zathura_document_get_adjust_mode(zathura->document);

  gdouble lower, upper, page_size, value, ratio;
  bool zoom_center = false;

  switch (adjust_mode) {
    center:
    case ZATHURA_ADJUST_BESTFIT:
    case ZATHURA_ADJUST_WIDTH:
      lower = gtk_adjustment_get_lower(adjustment);
      upper = gtk_adjustment_get_upper(adjustment);
      page_size = gtk_adjustment_get_page_size(adjustment);
      value = ((upper - lower) - page_size) / 2.0;
      zathura_adjustment_set_value(adjustment, value);
      break;
    default:
      girara_setting_get(zathura->ui.session, "zoom-center", &zoom_center);
      if (zoom_center) {
        goto center;
      }

      ratio = zathura_adjustment_get_ratio(zathura->ui.hadjustment);
      zathura_adjustment_set_value_from_ratio(adjustment, ratio);
      break;
  }
}

void
cb_view_vadjustment_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  g_return_if_fail(zathura != NULL);

  zathura_adjust_mode_t adjust_mode =
    zathura_document_get_adjust_mode(zathura->document);

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

  double ratio = zathura_adjustment_get_ratio(zathura->ui.vadjustment);
  zathura_adjustment_set_value_from_ratio(adjustment, ratio);
}

void
cb_adjustment_track_value(GtkAdjustment* adjustment, gpointer data)
{
  GtkAdjustment* tracker = data;

  gdouble lower = gtk_adjustment_get_lower(adjustment);
  gdouble upper = gtk_adjustment_get_upper(adjustment);
  if (lower != gtk_adjustment_get_lower(tracker) ||
      upper != gtk_adjustment_get_upper(tracker)) {
    return;
  }

  gdouble value = gtk_adjustment_get_value(adjustment);
  gtk_adjustment_set_value(tracker, value);
}

void
cb_adjustment_track_bounds(GtkAdjustment* adjustment, gpointer data)
{
  GtkAdjustment* tracker = data;
  gdouble value = gtk_adjustment_get_value(adjustment);
  gdouble lower = gtk_adjustment_get_lower(adjustment);
  gdouble upper = gtk_adjustment_get_upper(adjustment);
  gdouble page_size = gtk_adjustment_get_page_size(adjustment);
  gtk_adjustment_set_value(tracker, value);
  gtk_adjustment_set_lower(tracker, lower);
  gtk_adjustment_set_upper(tracker, upper);
  gtk_adjustment_set_page_size(tracker, page_size);
}

197 198 199 200 201 202 203 204 205 206 207 208 209 210
void
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))
{
  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 pages_per_row = *(int*) value;

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

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
  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);
240 241

  if (zathura->document != NULL) {
242
    unsigned int current_page = zathura_document_get_current_page_number(zathura->document);
243 244 245 246 247 248
    page_set_delayed(zathura, current_page);
  }
}

void
cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
249
                       GtkTreeViewColumn* UNUSED(column), void* data)
250 251 252 253 254 255 256 257 258 259 260
{
  zathura_t* zathura = data;
  if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) {
    return;
  }

  GtkTreeModel  *model;
  GtkTreeIter   iter;

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

261
  if(gtk_tree_model_get_iter(model, &iter, path)) {
262 263 264 265 266 267 268
    zathura_index_element_t* index_element;
    gtk_tree_model_get(model, &iter, 2, &index_element, -1);

    if (index_element == NULL) {
      return;
    }

269
    sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
270 271

    /* zathura_jumplist_save is called when entering index mode */
272
    zathura_link_evaluate(zathura, index_element->link);
273
    zathura_jumplist_add(zathura);
274 275 276 277 278
  }

  g_object_unref(model);
}

279 280 281 282 283 284 285 286 287
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)
288 289 290 291 292 293 294 295 296 297 298 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;
  bool eval = true;

  char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
  if (input == NULL || strlen(input) == 0) {
    eval = false;
  }

  int index = 0;
  if (eval == true) {
    index = atoi(input);
    if (index == 0 && g_strcmp0(input, "0") != 0) {
304
      girara_notify(session, GIRARA_WARNING, _("Invalid input '%s' given."), input);
305 306 307 308 309 310 311
      eval = false;
    }
    index = index - 1;
  }

  /* set pages to draw links */
  bool invalid_index = true;
312 313 314 315
  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 || zathura_page_get_visibility(page) == false) {
316 317 318
      continue;
    }

319 320
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
    g_object_set(page_widget, "draw-links", FALSE, NULL);
321 322

    if (eval == true) {
323
      zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
324

325 326
      if (link != NULL) {
        invalid_index = false;
327 328 329 330 331 332 333 334 335 336
        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;
        }
337 338 339 340 341
      }
    }
  }

  if (eval == true && invalid_index == true) {
342
    girara_notify(session, GIRARA_WARNING, _("Invalid index '%s' given."), input);
343 344 345 346 347 348 349
  }

  g_free(input);

  return (eval == TRUE) ? TRUE : FALSE;
}

350 351 352 353 354 355 356 357 358 359 360 361
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);
}

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 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);

  switch (event) {
    case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
    case G_FILE_MONITOR_EVENT_CREATED:
      gdk_threads_enter();
      sc_reload(session, NULL, NULL, 0);
      gdk_threads_leave();
      break;
    default:
      return;
  }
}

static gboolean
password_dialog(gpointer data)
{
  zathura_password_dialog_info_t* dialog = data;
385

386
  if (dialog != NULL) {
387
    girara_dialog(
388 389 390 391 392 393 394
      dialog->zathura->ui.session,
      "Incorrect password. Enter password:",
      true,
      NULL,
      (girara_callback_inputbar_activate_t) cb_password_dialog,
      dialog
    );
395
  }
396

397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
  return FALSE;
}

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);
    }

    gdk_threads_add_idle(password_dialog, dialog);
    return false;
  }

  /* try to open document again */
429 430
  if (document_open(dialog->zathura, dialog->path, input,
                    ZATHURA_PAGE_NUMBER_UNSPECIFIED) == false) {
431 432 433 434 435 436 437 438 439 440 441 442
    gdk_threads_add_idle(password_dialog, dialog);
  } else {
    g_free(dialog->path);
    free(dialog);
  }

  g_free(input);

  return true;

error_free:

443 444
  g_free(dialog->path);
  free(dialog);
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462

error_ret:

  return false;
}

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

  static int height = -1;
  static int width = -1;

  /* adjust only if the allocation changed */
  if (width != allocation->width || height != allocation->height) {
463
    girara_argument_t argument = { zathura_document_get_adjust_mode(zathura->document), NULL };
464
    sc_adjust_window(zathura->ui.session, &argument, NULL, 0);
465 466

    width  = allocation->width;
467 468 469 470 471
    height = allocation->height;
  }

  return false;
}
472 473 474

void
cb_setting_recolor_change(girara_session_t* session, const char* name,
475
                          girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
476 477 478 479 480 481 482 483 484 485 486 487 488 489
{
  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);
  }
}
490

491 492
void
cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
493
                                   girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
{
  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);
  }
}


510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
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;
    }
  }

530
  zathura_jumplist_save(zathura);
531
  page_set(zathura, atoi(input) - 1);
532
  zathura_jumplist_add(zathura);
533 534 535

  return true;
}