From 7d92d5453975bf9b37429621fb4350039a63600f Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Sat, 21 Apr 2012 04:59:58 +0200 Subject: [PATCH] Implemented marks --- config.c | 7 +- marks.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++ marks.h | 61 ++++++++++++ shortcuts.c | 17 ---- utils.c | 20 ++++ utils.h | 2 + zathura.c | 44 ++++++--- zathura.h | 20 +++- 8 files changed, 396 insertions(+), 36 deletions(-) create mode 100644 marks.c create mode 100644 marks.h diff --git a/config.c b/config.c index 0f9d759..682e961 100644 --- a/config.c +++ b/config.c @@ -7,6 +7,7 @@ #include "shortcuts.h" #include "zathura.h" #include "render.h" +#include "marks.h" #include #include @@ -131,9 +132,6 @@ config_load_default(zathura_t* zathura) girara_shortcut_add(gsession, 0, GDK_KEY_a, NULL, sc_adjust_window, NORMAL, ZATHURA_ADJUST_BESTFIT, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_s, NULL, sc_adjust_window, NORMAL, ZATHURA_ADJUST_WIDTH, NULL); - girara_shortcut_add(gsession, 0, GDK_KEY_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL); - girara_shortcut_add(gsession, 0, GDK_KEY_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL); - girara_shortcut_add(gsession, 0, GDK_KEY_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); girara_shortcut_add(gsession, 0, GDK_KEY_question, NULL, sc_focus_inputbar, NORMAL, 0, &("?")); @@ -148,6 +146,9 @@ config_load_default(zathura_t* zathura) girara_shortcut_add(gsession, 0, 0, "G", sc_goto, NORMAL, BOTTOM, NULL); girara_shortcut_add(gsession, 0, 0, "G", sc_goto, FULLSCREEN, BOTTOM, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_m, NULL, sc_mark_add, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_apostrophe, NULL, sc_mark_evaluate, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_J, NULL, sc_navigate, NORMAL, NEXT, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL); girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_KEY_Right, NULL, sc_navigate, NORMAL, NEXT, NULL); diff --git a/marks.c b/marks.c new file mode 100644 index 0000000..876d025 --- /dev/null +++ b/marks.c @@ -0,0 +1,261 @@ +/* See LICENSE file for license and copyright information */ + +#include +#include +#include +#include +#include + +#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 */ + float scale; /**> Zoom level */ +}; + +bool +sc_mark_add(girara_session_t* session, girara_argument_t* UNUSED(argument), + girara_event_t* UNUSED(event), unsigned int UNUSED(t)) +{ + 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", + G_CALLBACK(cb_marks_view_key_press_event_add), session); + + return true; +} + +bool +sc_mark_evaluate(girara_session_t* session, girara_argument_t* UNUSED(argument), + girara_event_t* UNUSED(event), unsigned int UNUSED(t)) +{ + 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", + G_CALLBACK(cb_marks_view_key_press_event_evaluate), session); + + return true; +} + +bool +cb_marks_view_key_press_event_add(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", + G_CALLBACK(girara_callback_view_key_press_event), session); + + /* evaluate key */ + if (((event->keyval >= 0x41 && event->keyval <= 0x5A) || (event->keyval >= + 0x61 && event->keyval <= 0x7A)) == false) { + 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", + G_CALLBACK(girara_callback_view_key_press_event), session); + + /* evaluate key */ + if (((event->keyval >= 0x41 && event->keyval <= 0x5A) || (event->keyval >= + 0x61 && event->keyval <= 0x7A)) == false) { + 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 >= + 0x61 && key <= 0x7A)) == false) { + 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) + 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) { + continue; + } + + /* 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) { + continue; + } + + 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); + } + 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; + } + + GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); + GtkAdjustment* v_adjustment = gtk_scrolled_window_get_vadjustment(window); + GtkAdjustment* h_adjustment = gtk_scrolled_window_get_hadjustment(window); + + if (v_adjustment == NULL || h_adjustment == NULL) { + return; + } + + double position_x = gtk_adjustment_get_value(h_adjustment); + double position_y = gtk_adjustment_get_value(v_adjustment); + float scale = zathura_document_get_scale(zathura->document); + + /* search for existing mark */ + GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark) + if (mark->key == key) { + mark->position_x = position_x; + mark->position_y = position_y; + mark->scale = scale; + return; + } + 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; + 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) + if (mark != NULL && mark->key == key) { + double old_scale = zathura_document_get_scale(zathura->document); + zathura_document_set_scale(zathura->document, mark->scale); + readjust_view_after_zooming(zathura, old_scale); + render_all(zathura); + + position_set_delayed(zathura, mark->position_x, mark->position_y); + + cb_view_vadjustment_value_changed(NULL, zathura); + return; + } + 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); +} diff --git a/marks.h b/marks.h new file mode 100644 index 0000000..b821f52 --- /dev/null +++ b/marks.h @@ -0,0 +1,61 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef MARKS_H +#define MARKS_H + +#include + +#include "zathura.h" + +typedef struct zathura_mark_s zathura_mark_t; + +/** + * Saves a mark + * + * @param session The used girara session + * @param argument The used argument + * @param event Girara event + * @param t Number of executions + * @return true if no error occured otherwise false + */ +bool sc_mark_add(girara_session_t* session, girara_argument_t* argument, + girara_event_t* event, unsigned int t); + +/** + * Evaluates a mark + * + * @param session The used girara session + * @param argument The used argument + * @param event Girara event + * @param t Number of executions + * @return true if no error occured otherwise false + */ +bool sc_mark_evaluate(girara_session_t* session, girara_argument_t* argument, + girara_event_t* event, unsigned int t); + +/** + * Mark current location within the web page + * + * @param session The girara session + * @param argument_list Argument list + * @return true if no error occured otherwise false + */ +bool cmd_marks_add(girara_session_t* session, girara_list_t* argument_list); + +/** + * Delete the specified marks + * + * @param session The girara session + * @param argument_list Argument list + * @return true if no error occured otherwise false + */ +bool cmd_marks_delete(girara_session_t* session, girara_list_t* argument_list); + +/** + * Free function vor marks + * + * @param data + */ +void mark_free(void* data); + +#endif // MARKS_H diff --git a/shortcuts.c b/shortcuts.c index 40bf237..5457d93 100644 --- a/shortcuts.c +++ b/shortcuts.c @@ -18,23 +18,6 @@ #include "page.h" #include "page-widget.h" -static void -readjust_view_after_zooming(zathura_t *zathura, float old_zoom) { - if (zathura == NULL || zathura->document == NULL) { - return; - } - - GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); - GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); - GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); - - double scale = zathura_document_get_scale(zathura->document); - gdouble valx = gtk_adjustment_get_value(hadjustment) / old_zoom * scale; - gdouble valy = gtk_adjustment_get_value(vadjustment) / old_zoom * scale; - set_adjustment(hadjustment, valx); - set_adjustment(vadjustment, valy); -} - bool sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t)) diff --git a/utils.c b/utils.c index 0cbd687..95c512d 100644 --- a/utils.c +++ b/utils.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "utils.h" #include "zathura.h" @@ -302,3 +304,21 @@ zathura_page_get_widget(zathura_t* zathura, zathura_page_t* page) return zathura->pages[page_number]; } + +void +readjust_view_after_zooming(zathura_t *zathura, float old_zoom) { + if (zathura == NULL || zathura->document == NULL) { + return; + } + + GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); + GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); + GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); + + double scale = zathura_document_get_scale(zathura->document); + gdouble valx = gtk_adjustment_get_value(hadjustment) / old_zoom * scale; + gdouble valy = gtk_adjustment_get_value(vadjustment) / old_zoom * scale; + set_adjustment(hadjustment, valx); + set_adjustment(vadjustment, valy); +} + diff --git a/utils.h b/utils.h index 03568f3..0936f05 100644 --- a/utils.h +++ b/utils.h @@ -114,4 +114,6 @@ page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned */ GtkWidget* zathura_page_get_widget(zathura_t* zathura, zathura_page_t* page); +void readjust_view_after_zooming(zathura_t *zathura, float old_zoom); + #endif // UTILS_H diff --git a/zathura.c b/zathura.c index 698b93f..9ec1158 100644 --- a/zathura.c +++ b/zathura.c @@ -26,6 +26,7 @@ #include "shortcuts.h" #include "zathura.h" #include "utils.h" +#include "marks.h" #include "render.h" #include "page.h" #include "page-widget.h" @@ -47,12 +48,12 @@ typedef struct page_set_delayed_s typedef struct position_set_delayed_s { zathura_t* zathura; - zathura_fileinfo_t file_info; + double position_x; + double position_y; } position_set_delayed_t; static gboolean document_info_open(gpointer data); static gboolean purge_pages(gpointer data); -static gboolean position_set_delayed(gpointer data); /* function implementation */ zathura_t* @@ -199,7 +200,7 @@ zathura_init(int argc, char* argv[]) zathura->ui.session->gtk.embed = embed; if (girara_session_init(zathura->ui.session, "zathura") == false) { - goto error_out; + goto error_free; } /* girara events */ @@ -569,6 +570,12 @@ document_open(zathura_t* zathura, const char* path, const char* password) } } + /* create marks list */ + zathura->global.marks = girara_list_new2((girara_free_function_t) mark_free); + if (zathura->global.marks == NULL) { + goto error_free; + } + zathura->document = document; /* create blank pages */ @@ -634,11 +641,7 @@ document_open(zathura_t* zathura, const char* path, const char* password) /* set position */ if (file_info.position_x != 0 || file_info.position_y != 0) { - position_set_delayed_t* p = g_malloc0(sizeof(position_set_delayed_t)); - p->zathura = zathura; - p->file_info = file_info; - - gdk_threads_add_idle(position_set_delayed, p); + position_set_delayed(zathura, file_info.position_x, file_info.position_y); } else { page_set_delayed(zathura, zathura_document_get_current_page_number(document)); cb_view_vadjustment_value_changed(NULL, zathura); @@ -721,6 +724,12 @@ document_close(zathura_t* zathura, bool keep_monitor) } } + /* remove marks */ + if (zathura->global.marks != NULL) { + girara_list_free(zathura->global.marks); + zathura->global.marks = NULL; + } + /* store file information */ const char* path = zathura_document_get_path(zathura->document); @@ -907,7 +916,7 @@ gboolean purge_pages(gpointer data) } static gboolean -position_set_delayed(gpointer data) +position_set_delayed_impl(gpointer data) { position_set_delayed_t* p = (position_set_delayed_t*) data; @@ -915,8 +924,21 @@ position_set_delayed(gpointer data) GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); - gtk_adjustment_set_value(hadjustment, p->file_info.position_x); - gtk_adjustment_set_value(vadjustment, p->file_info.position_y); + gtk_adjustment_set_value(hadjustment, p->position_x); + gtk_adjustment_set_value(vadjustment, p->position_y); return FALSE; } + +bool +position_set_delayed(zathura_t* zathura, double position_x, double position_y) +{ + position_set_delayed_t* p = g_malloc0(sizeof(position_set_delayed_t)); + + p->zathura = zathura; + p->position_x = position_x; + p->position_y = position_y; + + gdk_threads_add_idle(position_set_delayed_impl, p); + +} diff --git a/zathura.h b/zathura.h index 4d980c7..837c493 100644 --- a/zathura.h +++ b/zathura.h @@ -12,11 +12,10 @@ enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT, DELETE_LAST_WORD, DELETE_LAST_CHAR, DEFAULT, ERROR, WARNING, NEXT_GROUP, PREVIOUS_GROUP, ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL, ZOOM_SPECIFIC, FORWARD, - BACKWARD, CONTINUOUS, DELETE_LAST, ADD_MARKER, EVAL_MARKER, EXPAND, - EXPAND_ALL, COLLAPSE_ALL, COLLAPSE, SELECT, GOTO_DEFAULT, GOTO_LABELS, - GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, FULL_DOWN, HALF_LEFT, HALF_RIGHT, - FULL_LEFT, FULL_RIGHT, NEXT_CHAR, PREVIOUS_CHAR, DELETE_TO_LINE_START, - APPEND_FILEPATH, ROTATE_CW, ROTATE_CCW }; + BACKWARD, CONTINUOUS, DELETE_LAST, EXPAND, EXPAND_ALL, COLLAPSE_ALL, COLLAPSE, + SELECT, GOTO_DEFAULT, GOTO_LABELS, GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, + FULL_DOWN, HALF_LEFT, HALF_RIGHT, FULL_LEFT, FULL_RIGHT, NEXT_CHAR, + PREVIOUS_CHAR, DELETE_TO_LINE_START, APPEND_FILEPATH, ROTATE_CW, ROTATE_CCW }; /* forward declaration for types form database.h */ typedef struct _ZathuraDatabase zathura_database_t; @@ -77,6 +76,7 @@ struct zathura_s { bool recolor; /**< Recoloring mode switch */ bool update_page_number; /**< Update current page number */ + girara_list_t* marks; /**< Marker */ } global; struct @@ -178,6 +178,16 @@ bool page_set(zathura_t* zathura, unsigned int page_id); */ bool page_set_delayed(zathura_t* zathura, unsigned int page_id); +/** + * Moves to the given position + * + * @param zathura Zathura session + * @param position_x X coordinate + * @param position_y Y coordinate + * @return If no error occured true, otherwise false, is returned. + */ +bool position_set_delayed(zathura_t* zathura, double position_x, double position_y); + /** * Builds the box structure to show the rendered pages *