zathura/shortcuts.c

1413 lines
44 KiB
C
Raw Normal View History

/* See LICENSE file for license and copyright information */
#include <girara/session.h>
#include <girara/settings.h>
#include <girara/datastructures.h>
#include <girara/shortcuts.h>
#include <girara/utils.h>
2010-11-12 13:48:18 +01:00
#include <gtk/gtk.h>
#include <glib/gi18n.h>
2010-11-12 13:48:18 +01:00
#include "callbacks.h"
#include "shortcuts.h"
#include "document.h"
2010-11-13 12:40:48 +01:00
#include "zathura.h"
2011-02-09 21:28:36 +01:00
#include "render.h"
2011-02-10 04:33:28 +01:00
#include "utils.h"
2012-03-26 14:44:56 +02:00
#include "page.h"
2012-05-08 16:47:34 +02:00
#include "print.h"
2012-03-16 14:37:54 +01:00
#include "page-widget.h"
#include "adjustment.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
/* Helper function; see sc_display_link and sc_follow. */
static bool
draw_links(zathura_t* zathura)
{
/* set pages to draw links */
bool show_links = false;
unsigned int page_offset = 0;
unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
if (page == NULL) {
continue;
}
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
g_object_set(page_widget, "draw-search-results", FALSE, NULL);
if (zathura_page_get_visibility(page) == true) {
g_object_set(page_widget, "draw-links", TRUE, NULL);
int number_of_links = 0;
g_object_get(page_widget, "number-of-links", &number_of_links, NULL);
if (number_of_links != 0) {
show_links = true;
}
g_object_set(page_widget, "offset-links", page_offset, NULL);
page_offset += number_of_links;
} else {
g_object_set(page_widget, "draw-links", FALSE, NULL);
}
}
return show_links;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-21 00:46:03 +02:00
sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2010-11-13 12:40:48 +01:00
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
bool clear_search = true;
girara_setting_get(session, "abort-clear-search", &clear_search);
2012-02-08 23:42:09 +01:00
if (zathura->document != NULL) {
2012-03-30 18:24:00 +02:00
unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
2012-02-08 23:42:09 +01:00
if (page == NULL) {
continue;
}
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
g_object_set(page_widget, "draw-links", FALSE, NULL);
2012-09-03 10:30:25 +02:00
if (clear_search == true) {
g_object_set(page_widget, "draw-search-results", FALSE, NULL);
}
}
}
2010-11-13 12:40:48 +01:00
2011-05-07 22:00:52 +02:00
girara_mode_set(session, session->modes.normal);
2012-02-07 19:36:49 +01:00
girara_sc_abort(session, NULL, NULL, 0);
2010-11-13 12:40:48 +01:00
2010-11-13 10:05:28 +01:00
return false;
}
bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument,
2012-10-09 01:12:18 +02:00
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);
2011-10-01 09:40:44 +02:00
2012-02-03 22:15:29 +01:00
unsigned int pages_per_row = 1;
girara_setting_get(session, "pages-per-row", &pages_per_row);
2011-10-01 09:40:44 +02:00
unsigned int first_page_column = 1;
girara_setting_get(session, "first-page-column", &first_page_column);
int padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &padding);
2012-02-07 18:30:46 +01:00
if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
2011-10-01 09:40:44 +02:00
goto error_ret;
}
zathura_document_set_adjust_mode(zathura->document, argument->n);
if (argument->n == ZATHURA_ADJUST_NONE) {
/* there is nothing todo */
goto error_ret;
}
2012-02-09 01:46:51 +01:00
2011-10-01 09:40:44 +02:00
/* get window size */
GtkAllocation allocation;
gtk_widget_get_allocation(session->gtk.view, &allocation);
unsigned int width = allocation.width;
unsigned int height = allocation.height;
2011-10-01 09:40:44 +02:00
/* scrollbar spacing */
gint spacing;
gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL);
width -= spacing;
/* correct view size */
if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) {
gtk_widget_get_allocation(session->gtk.inputbar, &allocation);
height += allocation.height;
}
double scale = 1.0;
unsigned int cell_height = 0, cell_width = 0;
unsigned int document_height = 0, document_width = 0;
zathura_document_set_scale(zathura->document, scale);
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
zathura_get_document_size(zathura, cell_height, cell_width,
&document_height, &document_width);
double page_ratio = (double)cell_height / (double)document_width;
double window_ratio = (double)height / (double)width;
if (argument->n == ZATHURA_ADJUST_WIDTH ||
(argument->n == ZATHURA_ADJUST_BESTFIT && page_ratio < window_ratio)) {
scale = (double)(width - (pages_per_row - 1) * padding) /
(double)(pages_per_row * cell_width);
zathura_document_set_scale(zathura->document, scale);
bool show_vscrollbar = false;
girara_setting_get(session, "show-v-scrollbar", &show_vscrollbar);
if (show_vscrollbar) {
/* If the document is taller than the view, there's a vertical
* scrollbar; we need to substract its width from the view's width. */
zathura_get_document_size(zathura, cell_height, cell_width,
&document_height, &document_width);
if (height < document_height) {
GtkWidget* vscrollbar = gtk_scrolled_window_get_vscrollbar(
GTK_SCROLLED_WINDOW(session->gtk.view));
if (vscrollbar != NULL) {
GtkRequisition requisition;
gtk_widget_get_requisition(vscrollbar, &requisition);
if (0 < requisition.width && (unsigned)requisition.width < width) {
width -= requisition.width;
scale = (double)(width - (pages_per_row - 1) * padding) /
(double)(pages_per_row * cell_width);
zathura_document_set_scale(zathura->document, scale);
}
}
}
2011-10-01 09:40:44 +02:00
}
}
else if (argument->n == ZATHURA_ADJUST_BESTFIT) {
scale = (double)height / (double)cell_height;
zathura_document_set_scale(zathura->document, scale);
2012-06-16 00:21:18 +02:00
}
else {
goto error_ret;
2011-10-01 09:40:44 +02:00
}
/* re-render all pages */
render_all(zathura);
error_ret:
2011-04-18 17:55:50 +02:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_change_mode(girara_session_t* session, girara_argument_t* argument,
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2010-11-13 12:40:48 +01:00
g_return_val_if_fail(session != NULL, false);
girara_mode_set(session, argument->n);
2010-11-13 10:05:28 +01:00
return false;
}
bool
sc_display_link(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->global.data != NULL, false);
zathura_t* zathura = session->global.data;
if (zathura->document == NULL || zathura->ui.session == NULL) {
return false;
}
bool show_links = draw_links(zathura);
/* ask for input */
if (show_links) {
zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_INPUTBAR);
girara_dialog(zathura->ui.session, "Display link:", FALSE, NULL,
(girara_callback_inputbar_activate_t) cb_sc_display_link,
zathura->ui.session);
}
return false;
}
bool
sc_focus_inputbar(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->gtk.inputbar_entry != 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);
zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_INPUTBAR);
if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == false) {
gtk_widget_show(GTK_WIDGET(session->gtk.inputbar));
}
if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.notification_area)) == true) {
gtk_widget_hide(GTK_WIDGET(session->gtk.notification_area));
}
gtk_widget_grab_focus(GTK_WIDGET(session->gtk.inputbar_entry));
if (argument->data != NULL) {
gtk_entry_set_text(session->gtk.inputbar_entry, (char*) argument->data);
/* append filepath */
if (argument->n == APPEND_FILEPATH && zathura->document != NULL) {
2012-03-30 18:24:00 +02:00
const char* file_path = zathura_document_get_path(zathura->document);
if (file_path == NULL) {
return false;
}
char* path = g_path_get_dirname(file_path);
char* escaped = girara_escape_string(path);
char* tmp = g_strdup_printf("%s%s/", (char*) argument->data, (g_strcmp0(path, "/") == 0) ? "" : escaped);
g_free(path);
g_free(escaped);
gtk_entry_set_text(session->gtk.inputbar_entry, tmp);
g_free(tmp);
}
/* we save the X clipboard that will be clear by "grab_focus" */
gchar* x_clipboard_text = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY));
gtk_editable_set_position(GTK_EDITABLE(session->gtk.inputbar_entry), -1);
if (x_clipboard_text != NULL) {
/* we reset the X clipboard with saved text */
gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), x_clipboard_text, -1);
g_free(x_clipboard_text);
}
}
return true;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-21 00:46:03 +02:00
sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
g_return_val_if_fail(session != NULL, false);
2012-01-19 00:49:08 +01:00
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
2012-02-12 11:16:10 +01:00
if (zathura->document == NULL || zathura->ui.session == NULL) {
2012-01-19 00:49:08 +01:00
return false;
}
bool show_links = draw_links(zathura);
2012-01-19 00:49:08 +01:00
2012-02-07 16:39:02 +01:00
/* ask for input */
2012-02-08 00:19:35 +01:00
if (show_links == true) {
zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_INPUTBAR);
2012-02-12 11:16:10 +01:00
girara_dialog(zathura->ui.session, "Follow link:", FALSE, NULL, (girara_callback_inputbar_activate_t) cb_sc_follow, zathura->ui.session);
2012-02-08 00:19:35 +01:00
}
2012-02-07 16:39:02 +01:00
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int t)
2010-11-13 10:05:28 +01:00
{
2011-04-18 17:55:50 +02:00
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);
2011-02-09 17:12:09 +01:00
Enhancements/Cleanups for the jumplist mechansim - Don't delete the elements on the right of the current one, when appending a new jump to the jumplist, because this makes no sense at all; the point of the jumplist in the first place is to remember previously jumped-to positions in the document, so there is no need to delete anythings except to trim the oldest entries from the beginning to maintain the maximum size. This also makes us compatible with the Vim way of doing things. - Make the jumplist mechanism functional on the same page; if we followed a link to a target on the same page, remember the adjustments before and after following the link. The same holds for navigating search results on the same page. - Implement position_set and use it instead of position_set_delayed when following links in order to give zathura_jumplist_save a chance to record the exact adjustments of the link target. Otherwise, it will always record the adjustments after going to the target page, but before going to the exact position within it. - Don't consider movements with ^i and ^o as jumps :) - Don't use page_set followed by setting the adjustments in sc_jumplist, because this is redundant and causes clutter when using ^i and ^o, as the adjustments is set twice this way (once in page_set and again in position_set_delayed). It's enough to only update the page number on the statusbar and then set the adjustments. - Hide implementation details (zathura_jumplist_save and zathura_jumplist_append), and make things more consistent by exporting and using only zathura_jumplist_add for adding new entries. The end result: A more slick jumping experience :-) Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-09 05:53:31 +02:00
zathura_jumplist_add(zathura);
2012-03-24 17:45:25 +01:00
if (t != 0) {
/* add offset */
2013-05-08 18:28:32 +02:00
t += zathura_document_get_page_offset(zathura->document);
2013-05-08 18:28:32 +02:00
page_set(zathura, t - 1);
2012-03-24 17:45:25 +01:00
} else if (argument->n == TOP) {
2011-10-13 12:15:21 +02:00
page_set(zathura, 0);
2012-03-24 17:45:25 +01:00
} else if (argument->n == BOTTOM) {
page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1);
2011-02-09 17:12:09 +01:00
}
zathura_jumplist_add(zathura);
2012-02-07 15:13:36 +01:00
return false;
}
bool
sc_mouse_scroll(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int 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(event != NULL, false);
if (zathura->document == NULL) {
return false;
}
2012-02-15 11:48:28 +01:00
static int x = 0;
static int y = 0;
GtkAdjustment* x_adj = NULL;
GtkAdjustment* y_adj = NULL;
switch (event->type) {
2012-10-09 01:12:18 +02:00
/* scroll */
2012-02-15 11:48:28 +01:00
case GIRARA_EVENT_SCROLL_UP:
case GIRARA_EVENT_SCROLL_DOWN:
case GIRARA_EVENT_SCROLL_LEFT:
case GIRARA_EVENT_SCROLL_RIGHT:
return sc_scroll(session, argument, NULL, t);
2012-10-09 01:12:18 +02:00
/* drag */
2012-02-15 11:48:28 +01:00
case GIRARA_EVENT_BUTTON_PRESS:
x = event->x;
y = event->y;
break;
case GIRARA_EVENT_BUTTON_RELEASE:
x = 0;
y = 0;
break;
case GIRARA_EVENT_MOTION_NOTIFY:
x_adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
2012-08-05 02:30:03 +02:00
y_adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
2012-02-15 11:48:28 +01:00
if (x_adj == NULL || y_adj == NULL) {
return false;
}
2012-02-09 01:07:25 +01:00
zathura_adjustment_set_value(x_adj,
gtk_adjustment_get_value(x_adj) - (event->x - x));
zathura_adjustment_set_value(y_adj,
gtk_adjustment_get_value(y_adj) - (event->y - y));
zathura->global.update_page_number = true;
2012-02-15 11:48:28 +01:00
break;
2012-10-09 01:12:18 +02:00
/* unhandled events */
2012-02-15 11:48:28 +01:00
default:
break;
2012-02-07 15:13:36 +01:00
}
2010-11-13 10:05:28 +01:00
return false;
}
2012-02-07 18:34:39 +01:00
bool
sc_mouse_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int 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(event != NULL, false);
if (zathura->document == NULL) {
return false;
}
/* scroll event */
2012-02-15 00:21:51 +01:00
switch (event->type) {
case GIRARA_EVENT_SCROLL_UP:
argument->n = ZOOM_IN;
break;
case GIRARA_EVENT_SCROLL_DOWN:
argument->n = ZOOM_OUT;
break;
default:
return false;
2012-02-07 18:34:39 +01:00
}
2012-02-15 00:21:51 +01:00
return sc_zoom(session, argument, NULL, t);
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_navigate(girara_session_t* session, girara_argument_t* argument,
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int t)
{
2011-04-18 17:55:50 +02:00
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);
2010-12-12 22:04:42 +01:00
int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
int new_page = zathura_document_get_current_page_number(zathura->document);
2010-12-12 22:04:42 +01:00
2012-03-14 17:44:36 +01:00
bool scroll_wrap = false;
girara_setting_get(session, "scroll-wrap", &scroll_wrap);
bool columns_per_row_offset = false;
girara_setting_get(session, "advance-pages-per-row", &columns_per_row_offset);
int offset = 1;
if (columns_per_row_offset == true) {
girara_setting_get(session, "pages-per-row", &offset);
}
2012-04-21 10:40:29 +02:00
t = (t == 0) ? (unsigned int) offset : t;
2011-02-09 12:29:09 +01:00
if (argument->n == NEXT) {
if (scroll_wrap == false) {
2012-03-14 17:44:36 +01:00
new_page = new_page + t;
} else {
new_page = (new_page + t) % number_of_pages;
}
2011-02-09 12:29:09 +01:00
} else if (argument->n == PREVIOUS) {
if (scroll_wrap == false) {
2012-03-14 17:44:36 +01:00
new_page = new_page - t;
} else {
new_page = (new_page + number_of_pages - t) % number_of_pages;
}
}
if ((new_page < 0 || new_page >= number_of_pages) && !scroll_wrap) {
2012-03-14 17:44:36 +01:00
return false;
2010-12-12 22:04:42 +01:00
}
page_set(zathura, new_page);
2010-12-12 22:04:42 +01:00
2010-11-13 10:05:28 +01:00
return false;
}
2012-05-08 16:47:34 +02:00
bool
sc_print(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
2012-05-08 16:47:34 +02:00
{
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;
}
print(zathura);
return true;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-21 00:46:03 +02:00
sc_recolor(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
g_return_val_if_fail(session != NULL, false);
2011-04-30 13:27:27 +02:00
2012-03-14 17:33:35 +01:00
bool value = false;
girara_setting_get(session, "recolor", &value);
value = !value;
girara_setting_set(session, "recolor", &value);
2011-04-18 17:55:50 +02:00
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-21 00:46:03 +02:00
sc_reload(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
g_return_val_if_fail(session != NULL, false);
2011-10-01 17:47:51 +02:00
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
2012-02-20 20:07:24 +01:00
if (zathura->file_monitor.file_path == NULL) {
2011-10-01 17:47:51 +02:00
return false;
}
/* close current document */
2012-02-20 20:07:24 +01:00
document_close(zathura, true);
2011-10-01 17:47:51 +02:00
/* reopen document */
document_open(zathura, zathura->file_monitor.file_path,
zathura->file_monitor.password,
ZATHURA_PAGE_NUMBER_UNSPECIFIED);
2011-04-18 17:55:50 +02:00
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
sc_rotate(girara_session_t* session, girara_argument_t* argument,
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int t)
{
2011-04-18 17:55:50 +02:00
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(zathura->document != NULL, false);
2011-03-06 14:49:44 +01:00
unsigned int page_number = zathura_document_get_current_page_number(zathura->document);
int angle = 90;
if (argument != NULL && argument->n == ROTATE_CCW) {
angle = 270;
}
2011-03-06 14:49:44 +01:00
/* update rotate value */
2012-04-22 23:59:30 +02:00
t = (t == 0) ? 1 : t;
2012-03-30 18:24:00 +02:00
unsigned int rotation = zathura_document_get_rotation(zathura->document);
2012-04-22 23:59:30 +02:00
zathura_document_set_rotation(zathura->document, (rotation + angle * t) % 360);
2011-03-06 14:49:44 +01:00
/* update scale */
girara_argument_t new_argument = { zathura_document_get_adjust_mode(zathura->document), NULL };
sc_adjust_window(zathura->ui.session, &new_argument, NULL, 0);
2011-03-06 14:49:44 +01:00
/* render all pages again */
render_all(zathura);
2011-03-06 14:49:44 +01:00
page_set_delayed(zathura, page_number);
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_scroll(girara_session_t* session, girara_argument_t* argument,
girara_event_t* UNUSED(event), unsigned int t)
{
2011-04-18 17:55:50 +02:00
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);
2011-09-01 11:51:49 +02:00
if (zathura->document == NULL) {
return false;
}
2011-04-18 17:55:50 +02:00
if (t == 0) {
t = 1;
}
2011-01-24 12:54:20 +01:00
GtkAdjustment* adjustment = NULL;
if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
2012-10-09 01:12:18 +02:00
(argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
2011-10-01 17:47:51 +02:00
adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
2011-10-12 16:18:40 +02:00
} else {
2011-10-01 17:47:51 +02:00
adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
2011-10-12 16:18:40 +02:00
}
2011-01-24 12:54:20 +01:00
2012-03-14 17:44:36 +01:00
gdouble view_size = gtk_adjustment_get_page_size(adjustment);
gdouble value = gtk_adjustment_get_value(adjustment);
gdouble max = gtk_adjustment_get_upper(adjustment) - view_size;
zathura->global.update_page_number = true;
2012-02-20 09:33:18 +01:00
2012-02-03 22:15:29 +01:00
float scroll_step = 40;
girara_setting_get(session, "scroll-step", &scroll_step);
float scroll_hstep = -1;
girara_setting_get(session, "scroll-hstep", &scroll_hstep);
if (scroll_hstep < 0) {
scroll_hstep = scroll_step;
}
float scroll_full_overlap = 0.0;
girara_setting_get(session, "scroll-full-overlap", &scroll_full_overlap);
bool scroll_page_aware = false;
girara_setting_get(session, "scroll-page-aware", &scroll_page_aware);
bool scroll_wrap = false;
girara_setting_get(session, "scroll-wrap", &scroll_wrap);
2012-03-16 15:47:30 +01:00
int padding = 1;
girara_setting_get(session, "page-padding", &padding);
gdouble new_value;
2011-01-24 12:54:20 +01:00
2011-10-12 16:18:40 +02:00
switch(argument->n) {
2011-01-24 12:54:20 +01:00
case FULL_UP:
case FULL_LEFT:
new_value = value - (1.0 - scroll_full_overlap) * view_size - padding;
2011-01-24 12:54:20 +01:00
break;
case FULL_DOWN:
case FULL_RIGHT:
new_value = value + (1.0 - scroll_full_overlap) * view_size + padding;
2011-01-24 12:54:20 +01:00
break;
case HALF_UP:
case HALF_LEFT:
2012-02-20 09:33:18 +01:00
new_value = value - ((view_size + padding) / 2);
2011-01-24 12:54:20 +01:00
break;
case HALF_DOWN:
case HALF_RIGHT:
2012-02-20 09:33:18 +01:00
new_value = value + ((view_size + padding) / 2);
2011-01-24 12:54:20 +01:00
break;
case LEFT:
new_value = value - scroll_hstep * t;
break;
2011-01-24 12:54:20 +01:00
case UP:
new_value = value - scroll_step * t;
2011-01-24 12:54:20 +01:00
break;
case RIGHT:
new_value = value + scroll_hstep * t;
break;
2011-01-24 12:54:20 +01:00
case DOWN:
new_value = value + scroll_step * t;
2011-01-24 12:54:20 +01:00
break;
case TOP:
new_value = 0;
break;
case BOTTOM:
new_value = max;
break;
default:
2011-10-12 16:18:40 +02:00
new_value = value;
2011-01-24 12:54:20 +01:00
}
if (scroll_wrap == true) {
if (new_value < 0)
new_value = max;
else if (new_value > max)
new_value = 0;
}
2012-09-17 16:56:43 +02:00
if (scroll_page_aware == true) {
int page_offset;
double page_size;
{
unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
page_offset_t offset;
page_calculate_offset(zathura, page, &offset);
double scale = zathura_document_get_scale(zathura->document);
2012-09-17 16:56:43 +02:00
if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
(argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
page_offset = offset.x;
page_size = zathura_page_get_width(page) * scale;
} else {
page_offset = offset.y;
page_size = zathura_page_get_height(page) * scale;
}
page_offset -= padding / 2;
page_size += padding;
}
2012-09-17 16:56:43 +02:00
if ((argument->n == FULL_DOWN) || (argument->n == HALF_DOWN) ||
(argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
if ((page_offset > value) &&
(page_offset < value + view_size)) {
new_value = page_offset;
2012-09-17 16:56:43 +02:00
} else if ((page_offset <= value) &&
(page_offset + page_size < value + view_size)) {
new_value = page_offset + page_size + 1;
2012-09-17 16:56:43 +02:00
} else if ((page_offset <= value) &&
(page_offset + page_size < new_value + view_size)) {
new_value = page_offset + page_size - view_size + 1;
}
2012-09-17 16:56:43 +02:00
} else if ((argument->n == FULL_UP) || (argument->n == HALF_UP) ||
(argument->n == FULL_LEFT) || (argument->n == HALF_LEFT)) {
if ((page_offset + 1 >= value) &&
(page_offset < value + view_size)) {
new_value = page_offset - view_size;
2012-09-17 16:56:43 +02:00
} else if ((page_offset <= value) &&
(page_offset + page_size + 1 < value + view_size)) {
new_value = page_offset + page_size - view_size;
2012-09-17 16:56:43 +02:00
} else if ((page_offset <= value) &&
(page_offset > new_value)) {
new_value = page_offset;
}
2012-09-17 16:56:43 +02:00
}
}
zathura_adjustment_set_value(adjustment, new_value);
2011-01-24 12:54:20 +01:00
2010-11-13 10:05:28 +01:00
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);
/* if no jumps in the jumplist */
if (zathura->jumplist.size == 0) {
2013-07-26 09:04:08 +02:00
return true;
}
GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
double x = zathura_adjustment_get_ratio(hadj);
double y = zathura_adjustment_get_ratio(vadj);
zathura_jump_t* jump = NULL;
zathura_jump_t* prev_jump = zathura_jumplist_current(zathura);
bool go_to_current = false;
if (zathura_jumplist_has_next(zathura) == false || zathura_jumplist_has_previous(zathura) == false) {
if (x == prev_jump->x && y == prev_jump->y) {
go_to_current = false;
} else {
go_to_current = true;
}
}
switch(argument->n) {
case FORWARD:
if (go_to_current == true && zathura_jumplist_has_previous(zathura) == false) {
jump = zathura_jumplist_current(zathura);
} else {
zathura_jumplist_forward(zathura);
jump = zathura_jumplist_current(zathura);
}
break;
case BACKWARD:
if (go_to_current == true && zathura_jumplist_has_next(zathura) == false) {
jump = zathura_jumplist_current(zathura);
} else {
zathura_jumplist_backward(zathura);
jump = zathura_jumplist_current(zathura);
}
break;
}
if (jump == prev_jump) {
if ((zathura_jumplist_has_previous(zathura) == false && argument->n == BACKWARD) ||
(zathura_jumplist_has_next(zathura) == false && argument->n == FORWARD)) {
jump = NULL;
}
}
if (jump != NULL) {
zathura_adjustment_set_value_from_ratio(hadj, jump->x);
zathura_adjustment_set_value_from_ratio(vadj, jump->y);
Enhancements/Cleanups for the jumplist mechansim - Don't delete the elements on the right of the current one, when appending a new jump to the jumplist, because this makes no sense at all; the point of the jumplist in the first place is to remember previously jumped-to positions in the document, so there is no need to delete anythings except to trim the oldest entries from the beginning to maintain the maximum size. This also makes us compatible with the Vim way of doing things. - Make the jumplist mechanism functional on the same page; if we followed a link to a target on the same page, remember the adjustments before and after following the link. The same holds for navigating search results on the same page. - Implement position_set and use it instead of position_set_delayed when following links in order to give zathura_jumplist_save a chance to record the exact adjustments of the link target. Otherwise, it will always record the adjustments after going to the target page, but before going to the exact position within it. - Don't consider movements with ^i and ^o as jumps :) - Don't use page_set followed by setting the adjustments in sc_jumplist, because this is redundant and causes clutter when using ^i and ^o, as the adjustments is set twice this way (once in page_set and again in position_set_delayed). It's enough to only update the page number on the statusbar and then set the adjustments. - Hide implementation details (zathura_jumplist_save and zathura_jumplist_append), and make things more consistent by exporting and using only zathura_jumplist_add for adding new entries. The end result: A more slick jumping experience :-) Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-09 05:53:31 +02:00
zathura_document_set_current_page_number(zathura->document, jump->page);
statusbar_page_number_update(zathura);
}
return false;
}
bool
sc_bisect(girara_session_t* session, girara_argument_t* argument,
girara_event_t* UNUSED(event), unsigned int 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);
const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document);
const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document);
/* process arguments */
int direction;
if (t > 0 && t <= num_pages) {
/* bisect between cur_page and t */
t -= 1;
if (t == cur_page) {
/* nothing to do */
return false;
}
else if (t > cur_page) {
zathura->bisect.start = cur_page;
zathura->bisect.end = t;
direction = BACKWARD;
} else {
zathura->bisect.start = t;
zathura->bisect.end = cur_page;
direction = FORWARD;
}
} else if (argument != NULL) {
direction = argument->n;
/* setup initial bisect range */
zathura_jump_t* jump = zathura_jumplist_current(zathura);
if (jump == NULL) {
girara_debug("bisecting between first and last page because there are no jumps");
zathura->bisect.start = 0;
zathura->bisect.end = num_pages - 1;
2013-07-07 00:40:32 +02:00
} else if (jump->page != cur_page || jump->page != zathura->bisect.last_jump) {
girara_debug("last jump doesn't match up, starting new bisecting");
zathura->bisect.start = 0;
zathura->bisect.end = num_pages - 1;
unsigned int prev_page;
if (direction == FORWARD) {
prev_page = num_pages - 1;
} else {
prev_page = 0;
}
/* check if we have previous jumps */
if (zathura_jumplist_has_previous(zathura) == true) {
zathura_jumplist_backward(zathura);
jump = zathura_jumplist_current(zathura);
if (jump != NULL) {
prev_page = jump->page;
}
zathura_jumplist_forward(zathura);
}
zathura->bisect.start = MIN(prev_page, cur_page);
zathura->bisect.end = MAX(prev_page, cur_page);
zathura->bisect.last_jump = cur_page;
}
} else {
return false;
}
girara_debug("bisecting between %d and %d, at %d", zathura->bisect.start, zathura->bisect.end, cur_page);
if (zathura->bisect.start == zathura->bisect.end) {
/* nothing to do */
return false;
}
unsigned int next_page = cur_page;
unsigned int next_start = zathura->bisect.start;
unsigned int next_end = zathura->bisect.end;
/* here we have next_start <= next_page <= next_end */
/* bisect step */
switch(direction) {
case FORWARD:
if (cur_page != zathura->bisect.end) {
next_page = (cur_page + zathura->bisect.end) / 2;
if (next_page == cur_page) {
++next_page;
}
next_start = cur_page;
}
break;
case BACKWARD:
if (cur_page != zathura->bisect.start) {
next_page = (cur_page + zathura->bisect.start) / 2;
if (next_page == cur_page) {
--next_page;
}
next_end = cur_page;
}
break;
}
if (next_page == cur_page) {
/* nothing to do */
return false;
}
girara_debug("bisecting between %d and %d, jumping to %d", zathura->bisect.start, zathura->bisect.end, next_page);
zathura->bisect.last_jump = next_page;
zathura->bisect.start = next_start;
zathura->bisect.end = next_end;
zathura_jumplist_add(zathura);
page_set(zathura, next_page);
zathura_jumplist_add(zathura);
return false;
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_search(girara_session_t* session, girara_argument_t* argument,
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
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);
2012-02-07 16:39:02 +01:00
const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document);
const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document);
GtkWidget *cur_page_widget = zathura_page_get_widget(zathura, zathura_document_get_page(zathura->document, cur_page));
bool nohlsearch, first_time_after_abort, draw;
nohlsearch = first_time_after_abort = draw = false;
girara_setting_get(session, "nohlsearch", &nohlsearch);
if (nohlsearch == false) {
g_object_get(cur_page_widget, "draw-search-results", &draw, NULL);
if (draw == false) {
first_time_after_abort = true;
}
document_draw_search_results(zathura, true);
}
2012-02-07 19:15:01 +01:00
int diff = argument->n == FORWARD ? 1 : -1;
if (zathura->global.search_direction == BACKWARD)
diff = -diff;
2012-02-07 19:15:01 +01:00
2012-02-07 20:29:29 +01:00
zathura_page_t* target_page = NULL;
int target_idx = 0;
for (unsigned int page_id = 0; page_id < num_pages; ++page_id) {
2012-02-07 19:15:01 +01:00
int tmp = cur_page + diff * page_id;
zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages);
2012-02-07 19:15:01 +01:00
if (page == NULL) {
continue;
}
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
2012-03-26 14:44:56 +02:00
2012-02-07 19:15:01 +01:00
int num_search_results = 0, current = -1;
2012-03-26 14:44:56 +02:00
g_object_get(page_widget, "search-current", &current,
2012-10-09 01:12:18 +02:00
"search-length", &num_search_results, NULL);
2012-02-07 19:15:01 +01:00
if (num_search_results == 0 || current == -1) {
continue;
}
if (first_time_after_abort == true && num_search_results > 0) {
target_page = page;
target_idx = diff == 1 ? 0 : num_search_results - 1;
break;
}
2012-02-07 19:15:01 +01:00
if (diff == 1 && current < num_search_results - 1) {
/* the next result is on the same page */
2012-02-07 20:29:29 +01:00
target_page = page;
target_idx = current + 1;
} else if (diff == -1 && current > 0) {
2012-02-07 20:29:29 +01:00
target_page = page;
target_idx = current - 1;
2012-02-07 19:15:01 +01:00
} else {
/* the next result is on a different page */
2012-03-26 14:44:56 +02:00
g_object_set(page_widget, "search-current", -1, NULL);
2012-02-07 19:15:01 +01:00
for (int npage_id = 1; page_id < num_pages; ++npage_id) {
int ntmp = cur_page + diff * (page_id + npage_id);
zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages);
GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage);
2012-03-26 14:44:56 +02:00
g_object_get(npage_page_widget, "search-length", &num_search_results, NULL);
2012-02-07 19:15:01 +01:00
if (num_search_results != 0) {
2012-02-07 20:29:29 +01:00
target_page = npage;
target_idx = diff == 1 ? 0 : num_search_results - 1;
2012-02-07 19:15:01 +01:00
break;
}
}
}
2012-02-07 19:15:01 +01:00
break;
}
2012-02-07 16:39:02 +01:00
2012-02-07 20:29:29 +01:00
if (target_page != NULL) {
girara_list_t* results = NULL;
GtkWidget* page_widget = zathura_page_get_widget(zathura, target_page);
2012-03-26 14:44:56 +02:00
g_object_set(page_widget, "search-current", target_idx, NULL);
g_object_get(page_widget, "search-results", &results, NULL);
2012-02-07 20:29:29 +01:00
zathura_rectangle_t* rect = girara_list_nth(results, target_idx);
zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect);
page_offset_t offset;
page_calculate_offset(zathura, target_page, &offset);
Enhancements/Cleanups for the jumplist mechansim - Don't delete the elements on the right of the current one, when appending a new jump to the jumplist, because this makes no sense at all; the point of the jumplist in the first place is to remember previously jumped-to positions in the document, so there is no need to delete anythings except to trim the oldest entries from the beginning to maintain the maximum size. This also makes us compatible with the Vim way of doing things. - Make the jumplist mechanism functional on the same page; if we followed a link to a target on the same page, remember the adjustments before and after following the link. The same holds for navigating search results on the same page. - Implement position_set and use it instead of position_set_delayed when following links in order to give zathura_jumplist_save a chance to record the exact adjustments of the link target. Otherwise, it will always record the adjustments after going to the target page, but before going to the exact position within it. - Don't consider movements with ^i and ^o as jumps :) - Don't use page_set followed by setting the adjustments in sc_jumplist, because this is redundant and causes clutter when using ^i and ^o, as the adjustments is set twice this way (once in page_set and again in position_set_delayed). It's enough to only update the page number on the statusbar and then set the adjustments. - Hide implementation details (zathura_jumplist_save and zathura_jumplist_append), and make things more consistent by exporting and using only zathura_jumplist_add for adding new entries. The end result: A more slick jumping experience :-) Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-09 05:53:31 +02:00
zathura_jumplist_add(zathura);
2012-02-07 20:29:29 +01:00
if (zathura_page_get_index(target_page) != cur_page) {
page_set(zathura, zathura_page_get_index(target_page));
}
2012-02-07 20:29:29 +01:00
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
zathura_adjustment_set_value(view_vadjustment, y);
bool search_hadjust = true;
girara_setting_get(session, "search-hadjust", &search_hadjust);
if (search_hadjust == true) {
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1;
zathura_adjustment_set_value(view_hadjustment, x);
}
Enhancements/Cleanups for the jumplist mechansim - Don't delete the elements on the right of the current one, when appending a new jump to the jumplist, because this makes no sense at all; the point of the jumplist in the first place is to remember previously jumped-to positions in the document, so there is no need to delete anythings except to trim the oldest entries from the beginning to maintain the maximum size. This also makes us compatible with the Vim way of doing things. - Make the jumplist mechanism functional on the same page; if we followed a link to a target on the same page, remember the adjustments before and after following the link. The same holds for navigating search results on the same page. - Implement position_set and use it instead of position_set_delayed when following links in order to give zathura_jumplist_save a chance to record the exact adjustments of the link target. Otherwise, it will always record the adjustments after going to the target page, but before going to the exact position within it. - Don't consider movements with ^i and ^o as jumps :) - Don't use page_set followed by setting the adjustments in sc_jumplist, because this is redundant and causes clutter when using ^i and ^o, as the adjustments is set twice this way (once in page_set and again in position_set_delayed). It's enough to only update the page number on the statusbar and then set the adjustments. - Hide implementation details (zathura_jumplist_save and zathura_jumplist_append), and make things more consistent by exporting and using only zathura_jumplist_add for adding new entries. The end result: A more slick jumping experience :-) Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-09 05:53:31 +02:00
zathura_jumplist_add(zathura);
2012-02-07 20:29:29 +01:00
}
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-21 00:46:03 +02:00
sc_navigate_index(girara_session_t* session, girara_argument_t* argument,
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
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);
2011-09-29 18:17:03 +02:00
if(zathura->ui.index == NULL) {
return false;
}
GtkTreeView *tree_view = gtk_container_get_children(GTK_CONTAINER(zathura->ui.index))->data;
GtkTreePath *path;
gtk_tree_view_get_cursor(tree_view, &path, NULL);
2011-10-12 16:18:40 +02:00
if (path == NULL) {
2011-09-29 18:17:03 +02:00
return false;
}
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
GtkTreeIter iter;
GtkTreeIter child_iter;
gboolean is_valid_path = TRUE;
switch(argument->n) {
case UP:
if (gtk_tree_path_prev(path) == FALSE) {
/* For some reason gtk_tree_path_up returns TRUE although we're not
* moving anywhere. */
is_valid_path = gtk_tree_path_up(path) && (gtk_tree_path_get_depth(path) > 0);
2011-09-29 18:17:03 +02:00
} else { /* row above */
while(gtk_tree_view_row_expanded(tree_view, path)) {
gtk_tree_model_get_iter(model, &iter, path);
/* select last child */
gtk_tree_model_iter_nth_child(model, &child_iter, &iter,
2012-10-09 01:12:18 +02:00
gtk_tree_model_iter_n_children(model, &iter)-1);
2011-09-29 18:17:03 +02:00
gtk_tree_path_free(path);
path = gtk_tree_model_get_path(model, &child_iter);
}
}
break;
case COLLAPSE:
if (gtk_tree_view_collapse_row(tree_view, path) == FALSE
2012-10-09 01:12:18 +02:00
&& gtk_tree_path_get_depth(path) > 1) {
2011-09-29 18:17:03 +02:00
gtk_tree_path_up(path);
gtk_tree_view_collapse_row(tree_view, path);
}
break;
case DOWN:
if (gtk_tree_view_row_expanded(tree_view, path) == TRUE) {
2011-09-29 18:17:03 +02:00
gtk_tree_path_down(path);
} else {
do {
gtk_tree_model_get_iter(model, &iter, path);
if (gtk_tree_model_iter_next(model, &iter)) {
gtk_tree_path_free(path);
2011-09-29 18:17:03 +02:00
path = gtk_tree_model_get_path(model, &iter);
break;
}
} while((is_valid_path = (gtk_tree_path_get_depth(path) > 1))
2012-10-09 01:12:18 +02:00
&& gtk_tree_path_up(path));
2011-09-29 18:17:03 +02:00
}
break;
case EXPAND:
if (gtk_tree_view_expand_row(tree_view, path, FALSE)) {
2011-09-29 18:17:03 +02:00
gtk_tree_path_down(path);
}
break;
case EXPAND_ALL:
gtk_tree_view_expand_all(tree_view);
break;
case COLLAPSE_ALL:
gtk_tree_view_collapse_all(tree_view);
gtk_tree_path_free(path);
path = gtk_tree_path_new_first();
gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);
break;
2011-09-29 18:17:03 +02:00
case SELECT:
cb_index_row_activated(tree_view, path, NULL, zathura);
gtk_tree_path_free(path);
2011-09-29 18:17:03 +02:00
return false;
}
if (is_valid_path) {
gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);
}
gtk_tree_path_free(path);
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-29 17:05:54 +02:00
sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
2011-10-03 17:13:33 +02:00
if (zathura->document == NULL) {
return false;
}
2011-02-10 04:33:28 +01:00
girara_tree_node_t* document_index = NULL;
GtkWidget* treeview = NULL;
GtkTreeModel* model = NULL;
GtkCellRenderer* renderer = NULL;
2011-09-29 17:35:00 +02:00
GtkCellRenderer* renderer2 = NULL;
2011-02-10 04:33:28 +01:00
if (zathura->ui.index == NULL) {
2011-02-10 04:33:28 +01:00
/* create new index widget */
zathura->ui.index = gtk_scrolled_window_new(NULL, NULL);
2011-02-10 04:33:28 +01:00
if (zathura->ui.index == NULL) {
2011-02-10 04:33:28 +01:00
goto error_ret;
}
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index),
2012-10-09 01:12:18 +02:00
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2011-02-10 04:33:28 +01:00
/* create index */
2012-02-07 21:01:54 +01:00
document_index = zathura_document_index_generate(zathura->document, NULL);
2011-02-10 04:33:28 +01:00
if (document_index == NULL) {
2012-03-08 18:37:51 +01:00
girara_notify(session, GIRARA_WARNING, _("This document does not contain any index"));
2011-02-10 04:33:28 +01:00
goto error_free;
}
2011-09-29 17:28:09 +02:00
model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
2011-02-10 04:33:28 +01:00
if (model == NULL) {
goto error_free;
}
treeview = gtk_tree_view_new_with_model(model);
if (treeview == NULL) {
goto error_free;
}
g_object_unref(model);
renderer = gtk_cell_renderer_text_new();
if (renderer == NULL) {
goto error_free;
}
2011-09-29 17:35:00 +02:00
renderer2 = gtk_cell_renderer_text_new();
if (renderer2 == NULL) {
goto error_free;
}
2011-02-10 04:33:28 +01:00
document_index_build(model, NULL, document_index);
girara_node_free(document_index);
/* setup widget */
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 0, "Title", renderer, "markup", 0, NULL);
2011-09-29 17:35:00 +02:00
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 1, "Target", renderer2, "text", 1, NULL);
2011-09-29 17:28:09 +02:00
2011-02-10 04:33:28 +01:00
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
g_object_set(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)), "expand", TRUE, NULL);
2011-09-29 17:35:00 +02:00
gtk_tree_view_column_set_alignment(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), 1.0f);
2011-02-10 04:33:28 +01:00
gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE);
2011-09-29 17:05:54 +02:00
g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), zathura);
2011-02-10 04:33:28 +01:00
gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview);
2011-02-10 04:33:28 +01:00
gtk_widget_show(treeview);
}
2012-03-27 11:19:39 +02:00
static double vvalue = 0;
static double hvalue = 0;
if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) {
2012-02-07 18:30:46 +01:00
girara_set_view(session, zathura->ui.page_widget_alignment);
gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
2011-09-29 17:05:54 +02:00
girara_mode_set(zathura->ui.session, zathura->modes.normal);
2012-03-27 11:19:39 +02:00
/* reset adjustment */
position_set_delayed(zathura, hvalue, vvalue);
2011-02-10 04:33:28 +01:00
} else {
2012-03-27 11:19:39 +02:00
/* save adjustment */
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
2012-03-27 11:19:39 +02:00
vvalue = gtk_adjustment_get_value(vadjustment);
hvalue = gtk_adjustment_get_value(hadjustment);
/* save current position to the jumplist */
Enhancements/Cleanups for the jumplist mechansim - Don't delete the elements on the right of the current one, when appending a new jump to the jumplist, because this makes no sense at all; the point of the jumplist in the first place is to remember previously jumped-to positions in the document, so there is no need to delete anythings except to trim the oldest entries from the beginning to maintain the maximum size. This also makes us compatible with the Vim way of doing things. - Make the jumplist mechanism functional on the same page; if we followed a link to a target on the same page, remember the adjustments before and after following the link. The same holds for navigating search results on the same page. - Implement position_set and use it instead of position_set_delayed when following links in order to give zathura_jumplist_save a chance to record the exact adjustments of the link target. Otherwise, it will always record the adjustments after going to the target page, but before going to the exact position within it. - Don't consider movements with ^i and ^o as jumps :) - Don't use page_set followed by setting the adjustments in sc_jumplist, because this is redundant and causes clutter when using ^i and ^o, as the adjustments is set twice this way (once in page_set and again in position_set_delayed). It's enough to only update the page number on the statusbar and then set the adjustments. - Hide implementation details (zathura_jumplist_save and zathura_jumplist_append), and make things more consistent by exporting and using only zathura_jumplist_add for adding new entries. The end result: A more slick jumping experience :-) Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
2013-06-09 05:53:31 +02:00
zathura_jumplist_add(zathura);
girara_set_view(session, zathura->ui.index);
gtk_widget_show(GTK_WIDGET(zathura->ui.index));
2011-09-29 17:05:54 +02:00
girara_mode_set(zathura->ui.session, zathura->modes.index);
2011-02-10 04:33:28 +01:00
}
return false;
error_free:
if (zathura->ui.index != NULL) {
g_object_ref_sink(zathura->ui.index);
zathura->ui.index = NULL;
2011-02-10 04:33:28 +01:00
}
if (document_index != NULL) {
girara_node_free(document_index);
}
2011-04-18 17:55:50 +02:00
2011-02-10 04:33:28 +01:00
error_ret:
2010-11-13 10:05:28 +01:00
return false;
}
2012-10-06 14:58:07 +02:00
bool
sc_toggle_page_mode(girara_session_t* session, girara_argument_t*
2012-10-09 01:12:18 +02:00
UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t))
2012-10-06 14:58:07 +02:00
{
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_WARNING, _("No document opened."));
return false;
}
int pages_per_row = 1;
girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row);
static int tmp = 2;
int value = 1;
if (pages_per_row == 1) {
value = tmp;
} else {
tmp = pages_per_row;
}
girara_setting_set(zathura->ui.session, "pages-per-row", &value);
return true;
}
2010-11-13 10:05:28 +01:00
bool
2011-09-21 00:46:03 +02:00
sc_toggle_fullscreen(girara_session_t* session, girara_argument_t*
2012-10-09 01:12:18 +02:00
UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
2011-02-10 03:06:13 +01:00
if (zathura->document == NULL) {
girara_notify(session, GIRARA_WARNING, _("No document opened."));
return false;
}
static bool fullscreen = false;
2011-10-26 20:46:59 +02:00
static int pages_per_row = 1;
static int first_page_column = 1;
static double zoom = 1.0;
2011-10-26 20:46:59 +02:00
if (fullscreen == true) {
/* reset pages per row */
girara_setting_set(session, "pages-per-row", &pages_per_row);
/* reset first page column */
girara_setting_set(session, "first-page-column", &first_page_column);
2011-10-26 20:46:59 +02:00
/* show status bar */
gtk_widget_show(GTK_WIDGET(session->gtk.statusbar));
/* set full screen */
2011-02-10 03:06:13 +01:00
gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));
/* reset scale */
zathura_document_set_scale(zathura->document, zoom);
render_all(zathura);
page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));
/* setm ode */
girara_mode_set(session, zathura->modes.normal);
2011-02-10 03:06:13 +01:00
} else {
2011-10-26 20:46:59 +02:00
/* backup pages per row */
2012-02-03 22:15:29 +01:00
girara_setting_get(session, "pages-per-row", &pages_per_row);
2011-10-26 20:46:59 +02:00
/* backup first page column */
girara_setting_get(session, "first-page-column", &first_page_column);
2011-10-26 20:46:59 +02:00
/* set single view */
int int_value = 1;
girara_setting_set(session, "pages-per-row", &int_value);
/* back up zoom */
zoom = zathura_document_get_scale(zathura->document);
2011-10-26 20:46:59 +02:00
/* adjust window */
girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL };
2012-01-24 01:34:09 +01:00
sc_adjust_window(session, &argument, NULL, 0);
2011-10-26 20:46:59 +02:00
/* hide status and inputbar */
gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar));
gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar));
/* set full screen */
2011-02-10 03:06:13 +01:00
gtk_window_fullscreen(GTK_WINDOW(session->gtk.window));
page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));
/* setm ode */
girara_mode_set(session, zathura->modes.fullscreen);
2011-02-10 03:06:13 +01:00
}
fullscreen = fullscreen ? false : true;
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_quit(girara_session_t* session, girara_argument_t* UNUSED(argument),
2012-10-09 01:12:18 +02:00
girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
2011-04-18 17:55:50 +02:00
g_return_val_if_fail(session != NULL, false);
2010-11-12 13:48:18 +01:00
girara_argument_t arg = { GIRARA_HIDE, NULL };
2012-01-24 01:34:09 +01:00
girara_isc_completion(session, &arg, NULL, 0);
2010-11-12 13:48:18 +01:00
cb_destroy(NULL, NULL);
2010-11-13 10:05:28 +01:00
return false;
}
2010-11-13 10:05:28 +01:00
bool
2012-01-24 01:34:09 +01:00
sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t*
2012-10-09 01:12:18 +02:00
UNUSED(event), unsigned int t)
{
2011-04-18 17:55:50 +02:00
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);
2011-02-09 21:28:36 +01:00
zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_NONE);
2012-02-09 01:46:51 +01:00
2011-02-09 21:28:36 +01:00
/* retreive zoom step value */
2012-02-03 22:15:29 +01:00
int value = 1;
girara_setting_get(zathura->ui.session, "zoom-step", &value);
2011-02-09 21:28:36 +01:00
int nt = (t == 0) ? 1 : t;
float zoom_step = value / 100.0f * nt;
float old_zoom = zathura_document_get_scale(zathura->document);
2011-02-09 21:28:36 +01:00
/* specify new zoom value */
2011-02-09 21:28:36 +01:00
if (argument->n == ZOOM_IN) {
zathura_document_set_scale(zathura->document, old_zoom + zoom_step);
2011-02-09 21:28:36 +01:00
} else if (argument->n == ZOOM_OUT) {
zathura_document_set_scale(zathura->document, old_zoom - zoom_step);
} else if (argument->n == ZOOM_SPECIFIC) {
if (t == 0) {
zathura_document_set_scale(zathura->document, 1.0f);
} else {
zathura_document_set_scale(zathura->document, t / 100.0f);
}
2011-02-09 21:28:36 +01:00
} else {
zathura_document_set_scale(zathura->document, 1.0f);
2011-02-09 21:28:36 +01:00
}
/* zoom limitations */
2012-02-09 18:30:36 +01:00
int zoom_min_int = 10;
int zoom_max_int = 1000;
girara_setting_get(session, "zoom-min", &zoom_min_int);
girara_setting_get(session, "zoom-max", &zoom_max_int);
float zoom_min = zoom_min_int * 0.01f;
float zoom_max = zoom_max_int * 0.01f;
float scale = zathura_document_get_scale(zathura->document);
if (scale < zoom_min) {
2012-03-30 18:24:00 +02:00
zathura_document_set_scale(zathura->document, zoom_min);
} else if (scale > zoom_max) {
2012-03-30 18:24:00 +02:00
zathura_document_set_scale(zathura->document, zoom_max);
}
render_all(zathura);
2011-02-09 21:28:36 +01:00
2010-11-13 10:05:28 +01:00
return false;
}