commands.c 17.6 KB
Newer Older
1
/* SPDX-License-Identifier: Zlib */
Moritz Lipp's avatar
Moritz Lipp committed
2

Moritz Lipp's avatar
Moritz Lipp committed
3
#include <string.h>
4
#include <stdlib.h>
5
#include <glib/gi18n.h>
Moritz Lipp's avatar
Moritz Lipp committed
6

Moritz Lipp's avatar
Moritz Lipp committed
7
#include "commands.h"
Moritz Lipp's avatar
Moritz Lipp committed
8
#include "shortcuts.h"
9 10
#include "bookmarks.h"
#include "database.h"
Moritz Lipp's avatar
Moritz Lipp committed
11
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
12
#include "zathura.h"
13
#include "print.h"
14
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
15
#include "utils.h"
16
#include "page-widget.h"
Moritz Lipp's avatar
Moritz Lipp committed
17
#include "page.h"
Moritz Lipp's avatar
Moritz Lipp committed
18
#include "plugin.h"
19
#include "internal.h"
20
#include "render.h"
21
#include "adjustment.h"
Moritz Lipp's avatar
Moritz Lipp committed
22

23
#include <girara/session.h>
24
#include <girara/settings.h>
Moritz Lipp's avatar
Moritz Lipp committed
25
#include <girara/commands.h>
26
#include <girara/datastructures.h>
Sebastian Ramacher's avatar
Sebastian Ramacher committed
27
#include <girara/utils.h>
28

Moritz Lipp's avatar
Moritz Lipp committed
29
bool
30
cmd_bookmark_create(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
31
{
32 33 34 35
  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) {
36
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
37 38 39 40 41
    return false;
  }

  const unsigned int argc = girara_list_size(argument_list);
  if (argc != 1) {
42
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
43 44 45 46 47
    return false;
  }

  const char* bookmark_name = girara_list_nth(argument_list, 0);
  zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name);
48
  bool update = bookmark != NULL ? true : false;
49

50
  bookmark = zathura_bookmark_add(zathura, bookmark_name, zathura_document_get_current_page_number(zathura->document) + 1);
51
  if (bookmark == NULL) {
52 53 54 55 56
    if (update == true) {
      girara_notify(session, GIRARA_ERROR, _("Could not update bookmark: %s"), bookmark_name);
    } else {
      girara_notify(session, GIRARA_ERROR, _("Could not create bookmark: %s"), bookmark_name);
    }
57
    return false;
58 59 60 61 62 63
  } else {
    if (update == true) {
      girara_notify(session, GIRARA_INFO, _("Bookmark successfully updated: %s"), bookmark_name);
    } else {
      girara_notify(session, GIRARA_INFO, _("Bookmark successfully created: %s"), bookmark_name);
    }
64 65
  }

Moritz Lipp's avatar
Moritz Lipp committed
66 67 68 69
  return true;
}

bool
Moritz Lipp's avatar
Moritz Lipp committed
70
cmd_bookmark_delete(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
71
{
72 73 74 75
  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) {
76
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
77 78 79 80 81
    return false;
  }

  const unsigned int argc = girara_list_size(argument_list);
  if (argc != 1) {
82
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
83 84 85 86 87
    return false;
  }

  const char* bookmark = girara_list_nth(argument_list, 0);
  if (zathura_bookmark_remove(zathura, bookmark)) {
88
    girara_notify(session, GIRARA_INFO, _("Removed bookmark: %s"), bookmark);
89
  } else {
90
    girara_notify(session, GIRARA_ERROR, _("Failed to remove bookmark: %s"), bookmark);
91 92
  }

Moritz Lipp's avatar
Moritz Lipp committed
93 94 95 96
  return true;
}

bool
97
cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
98
{
99 100 101 102
  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) {
103
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
104 105 106 107 108
    return false;
  }

  const unsigned int argc = girara_list_size(argument_list);
  if (argc != 1) {
109 110
    GString* string = g_string_new(NULL);

111
    GIRARA_LIST_FOREACH_BODY(zathura->bookmarks.bookmarks, zathura_bookmark_t*, bookmark,
112
      g_string_append_printf(string, "<b>%s</b>: %u\n", bookmark->id, bookmark->page);
113
    );
114 115 116 117 118 119 120 121 122

    if (strlen(string->str) > 0) {
      g_string_erase(string, strlen(string->str) - 1, 1);
      girara_notify(session, GIRARA_INFO, "%s", string->str);
    } else {
      girara_notify(session, GIRARA_INFO, _("No bookmarks available."));
    }

    g_string_free(string, TRUE);
123 124 125 126 127 128
    return false;
  }

  const char* bookmark_name = girara_list_nth(argument_list, 0);
  zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name);
  if (bookmark == NULL) {
129
    girara_notify(session, GIRARA_ERROR, _("No such bookmark: %s"), bookmark_name);
130 131 132
    return false;
  }

133
  zathura_jumplist_add(zathura);
134
  page_set(zathura, bookmark->page - 1);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
135
  if (bookmark->x != DBL_MIN && bookmark->y != DBL_MIN) {
136
    position_set(zathura, bookmark->x, bookmark->y);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
137
  }
138 139 140
  zathura_jumplist_add(zathura);

  return true;
Moritz Lipp's avatar
Moritz Lipp committed
141 142 143
}

bool
144
cmd_close(girara_session_t* session, girara_list_t* UNUSED(argument_list))
Moritz Lipp's avatar
Moritz Lipp committed
145
{
146 147 148
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
149 150 151
  if (zathura->document == NULL) {
    return true;
  }
152

153
  document_close(zathura, false);
Moritz Lipp's avatar
Moritz Lipp committed
154

Moritz Lipp's avatar
Moritz Lipp committed
155 156 157 158
  return true;
}

bool
Moritz Lipp's avatar
Moritz Lipp committed
159
cmd_info(girara_session_t* session, girara_list_t* UNUSED(argument_list))
Moritz Lipp's avatar
Moritz Lipp committed
160
{
Moritz Lipp's avatar
Moritz Lipp committed
161 162 163 164
  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) {
165
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Moritz Lipp's avatar
Moritz Lipp committed
166 167 168 169 170
    return false;
  }

  struct meta_field {
    char* name;
171
    zathura_document_information_type_t field;
Moritz Lipp's avatar
Moritz Lipp committed
172 173
  };

174 175 176 177 178 179 180 181 182
  const struct meta_field meta_fields[] = {
    { _("Title"),             ZATHURA_DOCUMENT_INFORMATION_TITLE },
    { _("Author"),            ZATHURA_DOCUMENT_INFORMATION_AUTHOR },
    { _("Subject"),           ZATHURA_DOCUMENT_INFORMATION_SUBJECT },
    { _("Keywords"),          ZATHURA_DOCUMENT_INFORMATION_KEYWORDS },
    { _("Creator"),           ZATHURA_DOCUMENT_INFORMATION_CREATOR },
    { _("Producer"),          ZATHURA_DOCUMENT_INFORMATION_PRODUCER },
    { _("Creation date"),     ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE },
    { _("Modification date"), ZATHURA_DOCUMENT_INFORMATION_MODIFICATION_DATE }
Moritz Lipp's avatar
Moritz Lipp committed
183 184
  };

185 186 187 188
  girara_list_t* information = zathura_document_get_information(zathura->document, NULL);
  if (information == NULL) {
    girara_notify(session, GIRARA_INFO, _("No information available."));
    return false;
Moritz Lipp's avatar
Moritz Lipp committed
189 190
  }

191
  GString* string = g_string_new(NULL);
Moritz Lipp's avatar
Moritz Lipp committed
192

193 194 195 196 197 198
  GIRARA_LIST_FOREACH_BODY(information, zathura_document_information_entry_t*, entry,
    if (entry != NULL) {
      for (unsigned int i = 0; i < LENGTH(meta_fields); i++) {
        if (meta_fields[i].field == entry->type) {
          g_string_append_printf(string, "<b>%s:</b> %s\n", meta_fields[i].name, entry->value);
        }
199
      }
Moritz Lipp's avatar
Moritz Lipp committed
200
    }
201
  );
Moritz Lipp's avatar
Moritz Lipp committed
202 203 204

  if (strlen(string->str) > 0) {
    g_string_erase(string, strlen(string->str) - 1, 1);
205
    girara_notify(session, GIRARA_INFO, "%s", string->str);
206 207
  } else {
    girara_notify(session, GIRARA_INFO, _("No information available."));
Moritz Lipp's avatar
Moritz Lipp committed
208 209 210 211 212
  }

  g_string_free(string, TRUE);

  return false;
Moritz Lipp's avatar
Moritz Lipp committed
213 214
}

215
bool
216
cmd_help(girara_session_t* UNUSED(session), girara_list_t*
Moritz Lipp's avatar
Moritz Lipp committed
217
         UNUSED(argument_list))
218 219 220 221
{
  return true;
}

222 223 224 225 226 227 228 229 230 231 232 233 234 235
bool
cmd_hlsearch(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  document_draw_search_results(zathura, true);
  render_all(zathura);

  return true;
}


236 237 238
bool
cmd_open(girara_session_t* session, girara_list_t* argument_list)
{
Sebastian Ramacher's avatar
Sebastian Ramacher committed
239 240 241 242 243 244
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  const int argc = girara_list_size(argument_list);
  if (argc > 2) {
245
    girara_notify(session, GIRARA_ERROR, _("Too many arguments."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
246
    return false;
Moritz Lipp's avatar
Moritz Lipp committed
247
  } else if (argc >= 1) {
248 249
    if (zathura->document != NULL) {
      document_close(zathura, false);
250 251
    }

252 253 254
    document_open_idle(zathura, girara_list_nth(argument_list, 0),
                       (argc == 2) ? girara_list_nth(argument_list, 1) : NULL,
                       ZATHURA_PAGE_NUMBER_UNSPECIFIED, NULL, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
255
  } else {
256
    girara_notify(session, GIRARA_ERROR, _("No arguments given."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
257 258 259
    return false;
  }

260 261 262
  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
263 264 265 266 267 268 269 270
bool
cmd_quit(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  sc_quit(session, NULL, NULL, 0);

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
271
bool
272
cmd_print(girara_session_t* session, girara_list_t* UNUSED(argument_list))
Moritz Lipp's avatar
Moritz Lipp committed
273
{
274 275 276 277
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Pavel Borzenkov's avatar
Pavel Borzenkov committed
278
  if (zathura->document == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
279
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Pavel Borzenkov's avatar
Pavel Borzenkov committed
280 281
    return false;
  }
282

Sebastian Ramacher's avatar
Sebastian Ramacher committed
283
  if (zathura->global.sandbox == ZATHURA_SANDBOX_STRICT) {
valoq's avatar
valoq committed
284 285 286 287
    girara_notify(zathura->ui.session, GIRARA_ERROR, _("Printing is not permitted in strict sandbox mode"));
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
288
  print(zathura);
289

Moritz Lipp's avatar
Moritz Lipp committed
290 291 292
  return true;
}

293 294 295
bool
cmd_nohlsearch(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
296
  sc_nohlsearch(session, NULL, NULL, 0);
297 298 299 300

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
301
bool
Moritz Lipp's avatar
Moritz Lipp committed
302
cmd_save(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
303
{
304 305 306 307
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Pavel Borzenkov's avatar
Pavel Borzenkov committed
308
  if (zathura->document == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
309
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Pavel Borzenkov's avatar
Pavel Borzenkov committed
310 311
    return false;
  }
312 313

  if (girara_list_size(argument_list) == 1) {
314
    if (document_save(zathura, girara_list_nth(argument_list, 0), false) == true) {
315
      girara_notify(session, GIRARA_INFO, _("Document saved."));
316
    } else {
317
      girara_notify(session, GIRARA_INFO, _("Failed to save document."));
318
    }
Moritz Lipp's avatar
Moritz Lipp committed
319
  } else {
320
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments."));
321 322 323 324 325 326 327 328 329 330 331 332 333
    return false;
  }

  return true;
}

bool
cmd_savef(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Pavel Borzenkov's avatar
Pavel Borzenkov committed
334
  if (zathura->document == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
335
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
336
    return false;
Pavel Borzenkov's avatar
Pavel Borzenkov committed
337
  }
338 339

  if (girara_list_size(argument_list) == 1) {
340
    if (document_save(zathura, girara_list_nth(argument_list, 0), true) == true) {
341
      girara_notify(session, GIRARA_INFO, _("Document saved."));
342
    } else {
343
      girara_notify(session, GIRARA_INFO, _("Failed to save document."));
344
    }
Moritz Lipp's avatar
Moritz Lipp committed
345
  } else {
346
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments."));
347 348 349
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
350 351
  return true;
}
Moritz Lipp's avatar
Moritz Lipp committed
352 353

bool
Sebastian Ramacher's avatar
Sebastian Ramacher committed
354
cmd_search(girara_session_t* session, const char* input, girara_argument_t* argument)
Moritz Lipp's avatar
Moritz Lipp committed
355 356 357 358 359 360 361
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(input != NULL, false);
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

362
  if (zathura->document == NULL || strlen(input) == 0) {
Moritz Lipp's avatar
Moritz Lipp committed
363 364 365
    return false;
  }

366
  zathura_error_t error = ZATHURA_ERROR_OK;
367

368 369
  /* set search direction */
  zathura->global.search_direction = argument->n;
370 371 372 373

  unsigned int number_of_pages     = zathura_document_get_number_of_pages(zathura->document);
  unsigned int current_page_number = zathura_document_get_current_page_number(zathura->document);

374 375 376 377 378
  /* reset search highlighting */
  bool nohlsearch = false;
  girara_setting_get(session, "nohlsearch", &nohlsearch);

  /* search pages */
379
  for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
380
    unsigned int index = (page_id + current_page_number) % number_of_pages;
381
    zathura_page_t* page = zathura_document_get_page(zathura->document, index);
382
    if (page == NULL) {
383 384 385
      continue;
    }

386
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
387 388
    GObject* obj_page_widget = G_OBJECT(page_widget);
    g_object_set(obj_page_widget, "draw-links", FALSE, NULL);
389

390
    zathura_renderer_lock(zathura->sync.render_thread);
391
    girara_list_t* result = zathura_page_search_text(page, input, &error);
392
    zathura_renderer_unlock(zathura->sync.render_thread);
393

394 395
    if (result == NULL || girara_list_size(result) == 0) {
      girara_list_free(result);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
396
      g_object_set(obj_page_widget, "search-results", NULL, NULL);
397

398
      if (error == ZATHURA_ERROR_NOT_IMPLEMENTED) {
399 400 401 402
        break;
      } else {
        continue;
      }
403 404
    }

Sebastian Ramacher's avatar
Sebastian Ramacher committed
405
    g_object_set(obj_page_widget, "search-results", result, NULL);
406 407 408

    if (argument->n == BACKWARD) {
      /* start at bottom hit in page */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
409
      g_object_set(obj_page_widget, "search-current", girara_list_size(result) - 1, NULL);
410
    } else {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
411
      g_object_set(obj_page_widget, "search-current", 0, NULL);
412
    }
413 414
  }

415 416 417 418
  girara_argument_t* arg = g_try_malloc0(sizeof(girara_argument_t));
  if (arg == NULL) {
    return false;
  }
419 420

  arg->n = FORWARD;
421
  arg->data = (void*) input;
422 423 424
  sc_search(session, arg, NULL, 0);
  g_free(arg);

Moritz Lipp's avatar
Moritz Lipp committed
425 426
  return true;
}
Sebastian Ramacher's avatar
Sebastian Ramacher committed
427 428 429 430 431 432 433 434

bool
cmd_export(girara_session_t* session, girara_list_t* argument_list)
{
  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) {
435
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
436 437 438
    return false;
  }

439
  if (girara_list_size(argument_list) != 2) {
440
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
441 442 443
    return false;
  }

444
  const char* file_identifier = girara_list_nth(argument_list, 0);
445 446
  const char* file_name       = girara_list_nth(argument_list, 1);

447
  if (file_name == NULL || file_identifier == NULL) {
448 449 450
    return false;
  }

451 452 453 454 455 456 457 458 459 460 461 462
  char* export_path = girara_fix_path(file_name);
  if (export_path == NULL) {
    return false;
  }

  /* attachment */
  if (strncmp(file_identifier, "attachment-", strlen("attachment-")) == 0) {
    if (zathura_document_attachment_save(zathura->document, file_identifier + strlen("attachment-"), export_path) == false) {
      girara_notify(session, GIRARA_ERROR, _("Couldn't write attachment '%s' to '%s'."), file_identifier, file_name);
    } else {
      girara_notify(session, GIRARA_INFO, _("Wrote attachment '%s' to '%s'."), file_identifier, export_path);
    }
Moritz Lipp's avatar
Moritz Lipp committed
463
    /* image */
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
  } else if (strncmp(file_identifier, "image-p", strlen("image-p")) == 0 && strlen(file_identifier) >= 10) {
    /* parse page id */
    const char* input = file_identifier + strlen("image-p");
    int page_id = atoi(input);
    if (page_id == 0) {
      goto image_error;
    }

    /* parse image id */
    input = strstr(input, "-");
    if (input == NULL) {
      goto image_error;
    }

    int image_id = atoi(input + 1);
    if (image_id == 0) {
      goto image_error;
    }

    /* get image */
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id - 1);
    if (page == NULL) {
      goto image_error;
    }

    girara_list_t* images = zathura_page_images_get(page, NULL);
    if (images == NULL) {
      goto image_error;
    }

    zathura_image_t* image = girara_list_nth(images, image_id - 1);
    if (image == NULL) {
      goto image_error;
    }

    cairo_surface_t* surface = zathura_page_image_get_cairo(page, image, NULL);
    if (surface == NULL) {
      goto image_error;
    }

    if (cairo_surface_write_to_png(surface, export_path) == CAIRO_STATUS_SUCCESS) {
      girara_notify(session, GIRARA_INFO, _("Wrote image '%s' to '%s'."), file_identifier, export_path);
    } else {
      girara_notify(session, GIRARA_ERROR, _("Couldn't write image '%s' to '%s'."), file_identifier, file_name);
    }

    goto error_ret;

image_error:

    girara_notify(session, GIRARA_ERROR, _("Unknown image '%s'."), file_identifier);
    goto error_ret;
Moritz Lipp's avatar
Moritz Lipp committed
516
    /* unknown */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
517
  } else {
518
    girara_notify(session, GIRARA_ERROR, _("Unknown attachment or image '%s'."), file_identifier);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
519 520
  }

521 522 523
error_ret:

  g_free(export_path);
524

Sebastian Ramacher's avatar
Sebastian Ramacher committed
525 526
  return true;
}
527

Moritz Lipp's avatar
Moritz Lipp committed
528 529 530 531 532 533 534
bool
cmd_exec(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

valoq's avatar
valoq committed
535
  if (zathura->global.sandbox == ZATHURA_SANDBOX_STRICT) {
valoq's avatar
valoq committed
536 537 538 539
    girara_notify(zathura->ui.session, GIRARA_ERROR, _("Exec is not permitted in strict sandbox mode"));
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
540 541 542
  if (zathura->document != NULL) {
    const char* path = zathura_document_get_path(zathura->document);

543
    GIRARA_LIST_FOREACH_BODY_WITH_ITER(argument_list, char*, iter, value,
Sebastian Ramacher's avatar
Sebastian Ramacher committed
544 545 546 547 548 549 550 551 552 553
      char* r = girara_replace_substring(value, "$FILE", path);

      if (r != NULL) {
        char* s = girara_replace_substring(r, "%", path);
        g_free(r);

        if (s != NULL) {
          girara_list_iterator_set(iter, s);
        }
      }
554
    );
Moritz Lipp's avatar
Moritz Lipp committed
555 556 557 558 559
  }

  return girara_exec_with_argument_list(session, argument_list);
}

560 561 562 563 564 565 566 567 568 569 570 571
bool
cmd_offset(girara_session_t* session, girara_list_t* argument_list)
{
  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;
  }

  /* no argument: take current page as offset */
Moritz Lipp's avatar
Moritz Lipp committed
572
  int page_offset = zathura_document_get_current_page_number(zathura->document);
573 574 575 576 577 578 579 580 581 582 583 584 585

  /* retrieve offset from argument */
  if (girara_list_size(argument_list) == 1) {
    const char* value = girara_list_nth(argument_list, 0);
    if (value != NULL) {
      page_offset = atoi(value);
      if (page_offset == 0 && strcmp(value, "0") != 0) {
        girara_notify(session, GIRARA_WARNING, _("Argument must be a number."));
        return false;
      }
    }
  }

Moritz Lipp's avatar
Moritz Lipp committed
586
  zathura_document_set_page_offset(zathura->document, page_offset);
587 588 589

  return true;
}
Moritz Lipp's avatar
Moritz Lipp committed
590 591 592 593 594 595 596 597

bool
cmd_version(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

598
  char* string = zathura_get_version_string(zathura, true);
Moritz Lipp's avatar
Moritz Lipp committed
599 600 601
  if (string == NULL) {
    return false;
  }
Moritz Lipp's avatar
Moritz Lipp committed
602 603

  /* display information */
604
  girara_notify(session, GIRARA_INFO, "%s", string);
Moritz Lipp's avatar
Moritz Lipp committed
605

606
  g_free(string);
Moritz Lipp's avatar
Moritz Lipp committed
607 608 609

  return true;
}