Implemented jumplist bound to ^o ^i

zathura records jumps through searches, index, links, etc. and enables to go
back and forth via ^o ^i.

Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
Abdó Roig-Maranges 2012-08-17 14:14:57 +02:00 committed by Sebastian Ramacher
parent 7d001ec071
commit eb67d97180
9 changed files with 256 additions and 4 deletions

View file

@ -177,7 +177,10 @@ cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
} }
sc_toggle_index(zathura->ui.session, NULL, NULL, 0); sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
/* zathura_jumplist_save is called when entering index mode */
zathura_link_evaluate(zathura, index_element->link); zathura_link_evaluate(zathura, index_element->link);
zathura_jumplist_add(zathura);
} }
g_object_unref(model); g_object_unref(model);
@ -221,9 +224,12 @@ cb_sc_follow(GtkEntry* entry, girara_session_t* session)
if (eval == true) { if (eval == true) {
zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index); zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
if (link != NULL) { if (link != NULL) {
zathura_jumplist_save(zathura);
zathura_link_evaluate(zathura, link); zathura_link_evaluate(zathura, link);
invalid_index = false; invalid_index = false;
zathura_jumplist_add(zathura);
} }
} }
} }
@ -404,7 +410,9 @@ cb_unknown_command(girara_session_t* session, const char* input)
} }
} }
zathura_jumplist_save(zathura);
page_set(zathura, atoi(input) - 1); page_set(zathura, atoi(input) - 1);
zathura_jumplist_add(zathura);
return true; return true;
} }

View file

@ -18,6 +18,21 @@
#include <girara/gtk2-compat.h> #include <girara/gtk2-compat.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
static void
cb_jumplist_change(girara_session_t* session, const char* 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);
g_return_if_fail(name != NULL);
zathura_t* zathura = session->global.data;
if (g_strcmp0(name, "jumplist-size") == 0) {
size_t *max_size = (size_t*) value;
zathura->jumplist.max_size = *max_size;
}
}
static void static void
cb_color_change(girara_session_t* session, const char* name, cb_color_change(girara_session_t* session, const char* name,
girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data)) girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
@ -122,6 +137,8 @@ config_load_default(zathura_t* zathura)
int_value = 20; int_value = 20;
girara_setting_add(gsession, "page-store-threshold", &int_value, INT, false, _("Life time (in seconds) of a hidden page"), NULL, NULL); girara_setting_add(gsession, "page-store-threshold", &int_value, INT, false, _("Life time (in seconds) of a hidden page"), NULL, NULL);
girara_setting_add(gsession, "page-store-interval", &int_value, INT, true, _("Amount of seconds between each cache purge"), NULL, NULL); girara_setting_add(gsession, "page-store-interval", &int_value, INT, true, _("Amount of seconds between each cache purge"), NULL, NULL);
int_value = 20;
girara_setting_add(gsession, "jumplist-size", &int_value, INT, false, _("Number of positions to remember in the jumplist"), cb_jumplist_change, NULL);
girara_setting_add(gsession, "recolor-darkcolor", NULL, STRING, false, _("Recoloring (dark color)"), cb_color_change, NULL); girara_setting_add(gsession, "recolor-darkcolor", NULL, STRING, false, _("Recoloring (dark color)"), cb_color_change, NULL);
girara_setting_set(gsession, "recolor-darkcolor", "#FFFFFF"); girara_setting_set(gsession, "recolor-darkcolor", "#FFFFFF");
@ -242,6 +259,8 @@ config_load_default(zathura_t* zathura)
girara_shortcut_add(gsession, 0, GDK_KEY_y, NULL, sc_scroll, NORMAL, FULL_RIGHT, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_y, NULL, sc_scroll, NORMAL, FULL_RIGHT, NULL);
girara_shortcut_add(gsession, 0, GDK_KEY_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_space, NULL, sc_scroll, NORMAL, FULL_DOWN, NULL);
girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_space, NULL, sc_scroll, NORMAL, FULL_UP, NULL); girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_space, NULL, sc_scroll, NORMAL, FULL_UP, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_o, NULL, sc_jumplist, NORMAL, BACKWARD, NULL);
girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_i, NULL, sc_jumplist, NORMAL, FORWARD, NULL);
girara_shortcut_add(gsession, 0, GDK_KEY_n, NULL, sc_search, NORMAL, FORWARD, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_n, NULL, sc_search, NORMAL, FORWARD, NULL);
girara_shortcut_add(gsession, 0, GDK_KEY_N, NULL, sc_search, NORMAL, BACKWARD, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_N, NULL, sc_search, NORMAL, BACKWARD, NULL);

View file

@ -293,6 +293,7 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t*
g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false); g_return_val_if_fail(zathura->document != NULL, false);
zathura_jumplist_save(zathura);
if (t != 0) { if (t != 0) {
/* add offset */ /* add offset */
unsigned int page_offset = zathura_document_get_page_offset(zathura->document); unsigned int page_offset = zathura_document_get_page_offset(zathura->document);
@ -300,13 +301,15 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t*
t += page_offset; t += page_offset;
} }
page_set(zathura, t - 1); page_set(zathura, t-1);
} else if (argument->n == TOP) { } else if (argument->n == TOP) {
page_set(zathura, 0); page_set(zathura, 0);
} else if (argument->n == BOTTOM) { } else if (argument->n == BOTTOM) {
page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1); page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1);
} }
zathura_jumplist_add(zathura);
return false; return false;
} }
@ -609,6 +612,38 @@ sc_scroll(girara_session_t* session, girara_argument_t* argument,
return false; return false;
} }
bool
sc_jumplist(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false);
zathura_jump_t* jump = NULL;
switch(argument->n) {
case FORWARD:
zathura_jumplist_save(zathura);
zathura_jumplist_forward(zathura);
jump = zathura_jumplist_current(zathura);
break;
case BACKWARD:
zathura_jumplist_save(zathura);
zathura_jumplist_backward(zathura);
jump = zathura_jumplist_current(zathura);
break;
}
page_set(zathura, jump->page);
position_set_delayed(zathura, jump->x, jump->y);
return false;
}
bool bool
sc_search(girara_session_t* session, girara_argument_t* argument, sc_search(girara_session_t* session, girara_argument_t* argument,
girara_event_t* UNUSED(event), unsigned int UNUSED(t)) girara_event_t* UNUSED(event), unsigned int UNUSED(t))
@ -651,6 +686,8 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
target_idx = current - 1; target_idx = current - 1;
} else { } else {
/* the next result is on a different page */ /* the next result is on a different page */
zathura_jumplist_save(zathura);
g_object_set(page_widget, "search-current", -1, NULL); g_object_set(page_widget, "search-current", -1, NULL);
for (int npage_id = 1; page_id < num_pages; ++npage_id) { for (int npage_id = 1; page_id < num_pages; ++npage_id) {
@ -665,6 +702,8 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
break; break;
} }
} }
zathura_jumplist_add(zathura);
} }
break; break;
@ -779,6 +818,7 @@ sc_navigate_index(girara_session_t* session, girara_argument_t* argument,
break; break;
case SELECT: case SELECT:
cb_index_row_activated(tree_view, path, NULL, zathura); cb_index_row_activated(tree_view, path, NULL, zathura);
return false; return false;
} }
@ -884,6 +924,9 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
vvalue = gtk_adjustment_get_value(vadjustment); vvalue = gtk_adjustment_get_value(vadjustment);
hvalue = gtk_adjustment_get_value(hadjustment); hvalue = gtk_adjustment_get_value(hadjustment);
/* save current position to the jumplist */
zathura_jumplist_save(zathura);
girara_set_view(session, zathura->ui.index); girara_set_view(session, zathura->ui.index);
gtk_widget_show(GTK_WIDGET(zathura->ui.index)); gtk_widget_show(GTK_WIDGET(zathura->ui.index));
girara_mode_set(zathura->ui.session, zathura->modes.index); girara_mode_set(zathura->ui.session, zathura->modes.index);

View file

@ -160,6 +160,17 @@ bool sc_rotate(girara_session_t* session, girara_argument_t* argument, girara_ev
*/ */
bool sc_scroll(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t); bool sc_scroll(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t);
/**
* Scroll through the pages
*
* @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_jumplist(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t);
/** /**
* Search through the document for the latest search item * Search through the document for the latest search item
* *

View file

@ -19,6 +19,15 @@ typedef struct zathura_page_s zathura_page_t;
* Zathura * Zathura
*/ */
typedef struct zathura_s zathura_t; typedef struct zathura_s zathura_t;
/**
* Jump
*/
typedef struct zathura_jump_s
{
unsigned int page;
double x;
double y;
} zathura_jump_t;
/** /**
* Plugin manager * Plugin manager

View file

@ -68,6 +68,8 @@ t, ^f, ^b, space, <S-space>, y
Scroll a full page left, down, up or right Scroll a full page left, down, up or right
gg, G, nG gg, G, nG
Goto to the first, the last or to the nth page Goto to the first, the last or to the nth page
^o, ^i
Move backward and forward through the jump list
^c, Escape ^c, Escape
Abort Abort
a, s a, s
@ -84,7 +86,7 @@ f
Enter command Enter command
r r
Rotate by 90 degrees Rotate by 90 degrees
^i ^r
Recolor Recolor
R R
Reload document Reload document

108
zathura.c
View file

@ -235,6 +235,16 @@ zathura_init(zathura_t* zathura)
girara_setting_get(zathura->ui.session, "page-store-interval", &interval); girara_setting_get(zathura->ui.session, "page-store-interval", &interval);
g_timeout_add_seconds(interval, purge_pages, zathura); g_timeout_add_seconds(interval, purge_pages, zathura);
/* jumplist */
zathura->jumplist.max_size = 20;
girara_setting_get(zathura->ui.session, "jumplist-size", &(zathura->jumplist.max_size));
zathura->jumplist.list = girara_list_new2(g_free);
zathura->jumplist.size = 0;
zathura->jumplist.cur = NULL;
zathura_jumplist_append_jump(zathura);
zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list);
return true; return true;
error_free: error_free:
@ -291,6 +301,15 @@ zathura_free(zathura_t* zathura)
g_free(zathura->config.config_dir); g_free(zathura->config.config_dir);
g_free(zathura->config.data_dir); g_free(zathura->config.data_dir);
/* free jumplist */
if (zathura->jumplist.list != NULL) {
girara_list_free(zathura->jumplist.list);
}
if (zathura->jumplist.cur != NULL) {
girara_list_iterator_free(zathura->jumplist.cur);
}
g_free(zathura); g_free(zathura);
} }
@ -1026,3 +1045,92 @@ position_set_delayed(zathura_t* zathura, double position_x, double position_y)
return FALSE; return FALSE;
} }
zathura_jump_t*
zathura_jumplist_current(zathura_t* zathura) {
if (zathura->jumplist.cur != NULL) {
return girara_list_iterator_data(zathura->jumplist.cur);
} else {
return NULL;
}
}
void
zathura_jumplist_forward(zathura_t* zathura) {
if (girara_list_iterator_has_next(zathura->jumplist.cur)) {
girara_list_iterator_next(zathura->jumplist.cur);
}
}
void
zathura_jumplist_backward(zathura_t* zathura) {
if (girara_list_iterator_has_previous(zathura->jumplist.cur)) {
girara_list_iterator_previous(zathura->jumplist.cur);
}
}
void
zathura_jumplist_append_jump(zathura_t* zathura) {
zathura_jump_t *jump = g_malloc(sizeof(zathura_jump_t));
if (jump != NULL) {
jump->page = 0;
jump->x = 0;
jump->y = 0;
/* remove right tail after current */
if (zathura->jumplist.cur != NULL) {
girara_list_iterator_t *it = girara_list_iterator_copy(zathura->jumplist.cur);
girara_list_iterator_next(it);
while (girara_list_iterator_is_valid(it)) {
girara_list_iterator_remove(it);
zathura->jumplist.size = zathura->jumplist.size - 1;
}
g_free(it);
}
/* trim from beginning until max_size */
girara_list_iterator_t *it = girara_list_iterator(zathura->jumplist.list);
while (zathura->jumplist.size >= zathura->jumplist.max_size && girara_list_iterator_is_valid(it)) {
girara_list_iterator_remove(it);
zathura->jumplist.size = zathura->jumplist.size - 1;
}
g_free(it);
girara_list_append(zathura->jumplist.list, jump);
zathura->jumplist.size = zathura->jumplist.size + 1;
}
}
void
zathura_jumplist_add(zathura_t* zathura) {
if (zathura->jumplist.list != NULL) {
unsigned int pagenum = zathura_document_get_current_page_number(zathura->document);
zathura_jump_t* cur = zathura_jumplist_current(zathura);
if (cur && cur->page == pagenum) {
return;
}
zathura_jumplist_append_jump(zathura);
girara_list_iterator_next(zathura->jumplist.cur);
zathura_jumplist_save(zathura);
}
}
void
zathura_jumplist_save(zathura_t* zathura) {
zathura_jump_t* cur = zathura_jumplist_current(zathura);
unsigned int pagenum = zathura_document_get_current_page_number(zathura->document);
if (cur) {
/* get position */
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));
cur->page = pagenum;
cur->x = gtk_adjustment_get_value(view_hadjustment);
cur->y = gtk_adjustment_get_value(view_vadjustment);
}
}

View file

@ -105,6 +105,14 @@ struct zathura_s
girara_list_t* bookmarks; /**< bookmarks */ girara_list_t* bookmarks; /**< bookmarks */
} bookmarks; } bookmarks;
struct
{
girara_list_t* list;
girara_list_iterator_t *cur;
unsigned int size;
unsigned int max_size;
} jumplist;
struct struct
{ {
gchar* file; gchar* file;
@ -292,4 +300,48 @@ void page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsign
*/ */
void statusbar_page_number_update(zathura_t* zathura); void statusbar_page_number_update(zathura_t* zathura);
/**
* Return current jump in the jumplist
*
* @param zathura The zathura session
* @return current jump
*/
zathura_jump_t* zathura_jumplist_current(zathura_t* zathura);
/**
* Move forward in the jumplist
*
* @param zathura The zathura session
*/
void zathura_jumplist_forward(zathura_t* zathura);
/**
* Move backward in the jumplist
*
* @param zathura The zathura session
*/
void zathura_jumplist_backward(zathura_t* zathura);
/**
* Save current page to the jumplist at current position
*
* @param zathura The zathura session
*/
void zathura_jumplist_save(zathura_t* zathura);
/**
* Add current page as a new item to the jumplist after current position
*
* @param zathura The zathura session
*/
void zathura_jumplist_add(zathura_t* zathura);
/**
* Add a page to the jumplist after current position
*
* @param zathura The zathura session
*/
void zathura_jumplist_append_jump(zathura_t* zathura);
#endif // ZATHURA_H #endif // ZATHURA_H