marks.c 7.83 KB
Newer Older
Moritz Lipp's avatar
Moritz Lipp committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/* See LICENSE file for license and copyright information */

#include <stdlib.h>
#include <string.h>
#include <girara/session.h>
#include <girara/callbacks.h>
#include <girara/datastructures.h>

#include "callbacks.h"
#include "marks.h"
#include "document.h"
#include "render.h"
#include "utils.h"

static void mark_add(zathura_t* zathura, int key);
static void mark_evaluate(zathura_t* zathura, int key);
static bool cb_marks_view_key_press_event_add(GtkWidget* widget, GdkEventKey*
    event, girara_session_t* session);
static bool cb_marks_view_key_press_event_evaluate(GtkWidget* widget,
    GdkEventKey* event, girara_session_t* session);

struct zathura_mark_s {
  int key; /**> Marks key */
  double position_x; /**> Horizontal adjustment */
  double position_y; /**> Vertical adjustment */
26 27
  unsigned int page; /**> Page number */
  double scale; /**> Zoom level */
Moritz Lipp's avatar
Moritz Lipp committed
28 29 30 31
};

bool
sc_mark_add(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
32
            girara_event_t* UNUSED(event), unsigned int UNUSED(t))
Moritz Lipp's avatar
Moritz Lipp committed
33 34 35 36 37 38 39
{
  g_return_val_if_fail(session != NULL,           FALSE);
  g_return_val_if_fail(session->gtk.view != NULL, FALSE);

  /* redirect signal handler */
  g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed);
  session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event",
Moritz Lipp's avatar
Moritz Lipp committed
40
                                      G_CALLBACK(cb_marks_view_key_press_event_add), session);
Moritz Lipp's avatar
Moritz Lipp committed
41 42 43 44 45 46

  return true;
}

bool
sc_mark_evaluate(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
47
                 girara_event_t* UNUSED(event), unsigned int UNUSED(t))
Moritz Lipp's avatar
Moritz Lipp committed
48 49 50 51 52 53 54
{
  g_return_val_if_fail(session != NULL,           FALSE);
  g_return_val_if_fail(session->gtk.view != NULL, FALSE);

  /* redirect signal handler */
  g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed);
  session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event",
Moritz Lipp's avatar
Moritz Lipp committed
55
                                      G_CALLBACK(cb_marks_view_key_press_event_evaluate), session);
Moritz Lipp's avatar
Moritz Lipp committed
56 57 58 59 60 61

  return true;
}

bool
cb_marks_view_key_press_event_add(GtkWidget* UNUSED(widget), GdkEventKey* event,
Moritz Lipp's avatar
Moritz Lipp committed
62
                                  girara_session_t* session)
Moritz Lipp's avatar
Moritz Lipp committed
63 64 65 66 67 68 69 70 71
{
  g_return_val_if_fail(session != NULL,              FALSE);
  g_return_val_if_fail(session->gtk.view != NULL,    FALSE);
  g_return_val_if_fail(session->global.data != NULL, FALSE);
  zathura_t* zathura = (zathura_t*) session->global.data;

  /* reset signal handler */
  g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed);
  session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event",
Moritz Lipp's avatar
Moritz Lipp committed
72
                                      G_CALLBACK(girara_callback_view_key_press_event), session);
Moritz Lipp's avatar
Moritz Lipp committed
73 74

  /* evaluate key */
Moritz Lipp's avatar
Moritz Lipp committed
75 76 77 78
  if (((event->keyval >= '0' && event->keyval <= '9') ||
       (event->keyval >= 'a' && event->keyval <= 'z') ||
       (event->keyval >= 'A' && event->keyval <= 'Z')
       ) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
    return false;
  }

  mark_add(zathura, event->keyval);

  return true;
}

bool cb_marks_view_key_press_event_evaluate(GtkWidget* UNUSED(widget), GdkEventKey*
    event, girara_session_t* session)
{
  g_return_val_if_fail(session != NULL,              FALSE);
  g_return_val_if_fail(session->gtk.view != NULL,    FALSE);
  g_return_val_if_fail(session->global.data != NULL, FALSE);
  zathura_t* zathura = (zathura_t*) session->global.data;

  /* reset signal handler */
  g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed);
  session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event",
Moritz Lipp's avatar
Moritz Lipp committed
98
                                      G_CALLBACK(girara_callback_view_key_press_event), session);
Moritz Lipp's avatar
Moritz Lipp committed
99 100

  /* evaluate key */
Moritz Lipp's avatar
Moritz Lipp committed
101 102 103 104
  if (((event->keyval >= '0' && event->keyval <= '9') ||
       (event->keyval >= 'a' && event->keyval <= 'z') ||
       (event->keyval >= 'A' && event->keyval <= 'Z')
       ) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    return true;
  }

  mark_evaluate(zathura, event->keyval);

  return true;
}

bool
cmd_marks_add(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 = (zathura_t*) session->global.data;

  if (girara_list_size(argument_list) < 1) {
    return false;
  }

  char* key_string = girara_list_nth(argument_list, 0);

  if (key_string == NULL) {
    return false;
  }

  if (strlen(key_string) < 1 || strlen(key_string) > 1) {
    return false;
  }

  char key = key_string[0];

  if (((key >= 0x41 && key <= 0x5A) || (key >=
Moritz Lipp's avatar
Moritz Lipp committed
137
                                        0x61 && key <= 0x7A)) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
    return false;
  }

  mark_add(zathura, key);

  return false;
}

bool
cmd_marks_delete(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 = (zathura_t*) session->global.data;

  if (girara_list_size(argument_list) < 1) {
    return false;
  }

  if (girara_list_size(zathura->global.marks) == 0) {
    return false;
  }

  GIRARA_LIST_FOREACH(argument_list, char*, iter, key_string)
Moritz Lipp's avatar
Moritz Lipp committed
162 163 164 165 166 167 168 169
  if (key_string == NULL) {
    continue;
  }

  for (unsigned int i = 0; i < strlen(key_string); i++) {
    char key = key_string[i];
    if (((key >= 0x41 && key <= 0x5A) || (key >=
                                          0x61 && key <= 0x7A)) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
170 171 172
      continue;
    }

Moritz Lipp's avatar
Moritz Lipp committed
173 174 175 176 177
    /* search for existing mark */
    girara_list_iterator_t* mark_iter = girara_list_iterator(zathura->global.marks);
    do {
      zathura_mark_t* mark = (zathura_mark_t*) girara_list_iterator_data(mark_iter);
      if (mark == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
178 179 180
        continue;
      }

Moritz Lipp's avatar
Moritz Lipp committed
181 182 183 184 185 186 187
      if (mark->key == key) {
        girara_list_remove(zathura->global.marks, mark);
        continue;
      }
    } while (girara_list_iterator_next(mark_iter) != NULL);
    girara_list_iterator_free(mark_iter);
  }
Moritz Lipp's avatar
Moritz Lipp committed
188 189 190 191 192 193 194 195 196 197 198 199
  GIRARA_LIST_FOREACH_END(argument_list, char*, iter, key_string);

  return true;
}

void
mark_add(zathura_t* zathura, int key)
{
  if (zathura == NULL || zathura->document == NULL || zathura->global.marks == NULL) {
    return;
  }

200 201 202
  unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
  double position_x    = zathura_document_get_position_x(zathura->document);
  double position_y    = zathura_document_get_position_y(zathura->document);
Moritz Lipp's avatar
Moritz Lipp committed
203

204
  double scale      = zathura_document_get_scale(zathura->document);
Moritz Lipp's avatar
Moritz Lipp committed
205 206 207

  /* search for existing mark */
  GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark)
Moritz Lipp's avatar
Moritz Lipp committed
208
  if (mark->key == key) {
209
    mark->page       = page_id;
Moritz Lipp's avatar
Moritz Lipp committed
210 211 212 213 214
    mark->position_x = position_x;
    mark->position_y = position_y;
    mark->scale      = scale;
    return;
  }
Moritz Lipp's avatar
Moritz Lipp committed
215 216 217 218 219 220
  GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark);

  /* add new mark */
  zathura_mark_t* mark = g_malloc0(sizeof(zathura_mark_t));

  mark->key        = key;
221
  mark->page       = page_id;
Moritz Lipp's avatar
Moritz Lipp committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
  mark->position_x = position_x;
  mark->position_y = position_y;
  mark->scale      = scale;

  girara_list_append(zathura->global.marks, mark);
}

void
mark_evaluate(zathura_t* zathura, int key)
{
  if (zathura == NULL || zathura->global.marks == NULL) {
    return;
  }

  /* search for existing mark */
  GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark)
Moritz Lipp's avatar
Moritz Lipp committed
238 239 240
  if (mark != NULL && mark->key == key) {
    zathura_document_set_scale(zathura->document, mark->scale);
    render_all(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
241

Marwan Tanager's avatar
Marwan Tanager committed
242
    zathura_jumplist_add(zathura);
243
    page_set(zathura, mark->page);
Marwan Tanager's avatar
Marwan Tanager committed
244 245
    position_set(zathura, mark->position_x, mark->position_y);
    zathura_jumplist_add(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
246

Moritz Lipp's avatar
Moritz Lipp committed
247 248
    return;
  }
Moritz Lipp's avatar
Moritz Lipp committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262
  GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark);
}

void
mark_free(void* data)
{
  if (data == NULL) {
    return;
  }

  zathura_mark_t* mark = (zathura_mark_t*) data;

  g_free(mark);
}