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);
/* zathura_jumplist_save is called when entering index mode */
zathura_link_evaluate(zathura, index_element->link);
zathura_jumplist_add(zathura);
}
g_object_unref(model);
@ -221,9 +224,12 @@ cb_sc_follow(GtkEntry* entry, girara_session_t* session)
if (eval == true) {
zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
if (link != NULL) {
zathura_jumplist_save(zathura);
zathura_link_evaluate(zathura, link);
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);
zathura_jumplist_add(zathura);
return true;
}

View file

@ -18,6 +18,21 @@
#include <girara/gtk2-compat.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
cb_color_change(girara_session_t* session, const char* name,
girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
@ -122,6 +137,8 @@ config_load_default(zathura_t* zathura)
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-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_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_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_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, 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(zathura->document != NULL, false);
zathura_jumplist_save(zathura);
if (t != 0) {
/* add offset */
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;
}
page_set(zathura, t - 1);
page_set(zathura, t-1);
} else if (argument->n == TOP) {
page_set(zathura, 0);
} else if (argument->n == BOTTOM) {
page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1);
}
zathura_jumplist_add(zathura);
return false;
}
@ -609,6 +612,38 @@ sc_scroll(girara_session_t* session, girara_argument_t* argument,
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
sc_search(girara_session_t* session, girara_argument_t* argument,
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;
} else {
/* the next result is on a different page */
zathura_jumplist_save(zathura);
g_object_set(page_widget, "search-current", -1, NULL);
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;
}
}
zathura_jumplist_add(zathura);
}
break;
@ -779,6 +818,7 @@ sc_navigate_index(girara_session_t* session, girara_argument_t* argument,
break;
case SELECT:
cb_index_row_activated(tree_view, path, NULL, zathura);
return false;
}
@ -884,6 +924,9 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
vvalue = gtk_adjustment_get_value(vadjustment);
hvalue = gtk_adjustment_get_value(hadjustment);
/* save current position to the jumplist */
zathura_jumplist_save(zathura);
girara_set_view(session, zathura->ui.index);
gtk_widget_show(GTK_WIDGET(zathura->ui.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);
/**
* 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
*

View file

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

View file

@ -68,6 +68,8 @@ t, ^f, ^b, space, <S-space>, y
Scroll a full page left, down, up or right
gg, G, nG
Goto to the first, the last or to the nth page
^o, ^i
Move backward and forward through the jump list
^c, Escape
Abort
a, s
@ -84,7 +86,7 @@ f
Enter command
r
Rotate by 90 degrees
^i
^r
Recolor
R
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);
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;
error_free:
@ -291,6 +301,15 @@ zathura_free(zathura_t* zathura)
g_free(zathura->config.config_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);
}
@ -1026,3 +1045,92 @@ position_set_delayed(zathura_t* zathura, double position_x, double position_y)
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 */
} bookmarks;
struct
{
girara_list_t* list;
girara_list_iterator_t *cur;
unsigned int size;
unsigned int max_size;
} jumplist;
struct
{
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);
/**
* 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