zathura/shortcuts.c

1412 lines
43 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
/* Setting the mode back here has not worked for ages. We need another way to
* do this. Let's disable this for now.
*/
/* 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
zathura_document_set_adjust_mode(zathura->document, argument->n);
adjust_view(zathura);
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);
}
GdkAtom* selection = get_selection(zathura);
/* we save the X clipboard that will be clear by "grab_focus" */
2013-10-07 09:02:38 +02:00
gchar* x_clipboard_text = NULL;
if (selection != NULL) {
x_clipboard_text = gtk_clipboard_wait_for_text(gtk_clipboard_get(*selection));
}
gtk_editable_set_position(GTK_EDITABLE(session->gtk.inputbar_entry), -1);
if (x_clipboard_text != NULL && selection != NULL) {
/* we reset the X clipboard with saved text */
gtk_clipboard_set_text(gtk_clipboard_get(*selection), x_clipboard_text, -1);
g_free(x_clipboard_text);
}
g_free(selection);
}
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:
case GIRARA_EVENT_SCROLL_BIDIRECTIONAL:
return sc_scroll(session, argument, event, t);
2012-02-15 11:48:28 +01:00
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));
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;
case GIRARA_EVENT_SCROLL_BIDIRECTIONAL:
argument->n = ZOOM_SMOOTH;
break;
2012-02-15 00:21:51 +01:00
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 (!scroll_wrap) {
if (new_page <= 0) {
new_page = 0;
} else if (new_page >= number_of_pages) {
new_page = number_of_pages - 1;
}
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(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* 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
2013-11-29 17:08:01 +01:00
/* if TOP or BOTTOM, go there and we are done */
if (argument->n == TOP) {
position_set(zathura, -1, 0);
return false;
} else if (argument->n == BOTTOM) {
position_set(zathura, -1, 1.0);
return false;
}
/* Retrieve current page and position */
const unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
double pos_x = zathura_document_get_position_x(zathura->document);
double pos_y = zathura_document_get_position_y(zathura->document);
/* If PAGE_TOP or PAGE_BOTTOM, go there and we are done */
if (argument->n == PAGE_TOP) {
double dontcare = 0.5;
page_number_to_position(zathura->document, page_id, dontcare, 0.0, &dontcare, &pos_y);
position_set(zathura, pos_x, pos_y);
return false;
} else if (argument->n == PAGE_BOTTOM) {
double dontcare = 0.5;
page_number_to_position(zathura->document, page_id, dontcare, 1.0, &dontcare, &pos_y);
position_set(zathura, pos_x, pos_y);
return false;
}
if (t == 0) {
t = 1;
}
unsigned int view_width = 0;
unsigned int view_height = 0;
zathura_document_get_viewport_size(zathura->document, &view_height, &view_width);
2011-01-24 12:54:20 +01:00
unsigned int doc_width = 0;
unsigned int doc_height = 0;
zathura_document_get_document_size(zathura->document, &doc_height, &doc_width);
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);
/* compute the direction of scrolling */
2013-11-29 17:08:01 +01:00
double direction = 1.0;
if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
(argument->n == UP) || (argument->n == FULL_UP) || (argument->n == HALF_UP)) {
direction = -1.0;
}
const double vstep = (double)view_height / (double)doc_height;
const double hstep = (double)view_width / (double)doc_width;
/* compute new position */
2013-11-29 17:08:01 +01:00
switch (argument->n) {
2011-01-24 12:54:20 +01:00
case FULL_UP:
case FULL_DOWN:
pos_y += direction * (1.0 - scroll_full_overlap) * vstep;
break;
case FULL_LEFT:
case FULL_RIGHT:
pos_x += direction * (1.0 - scroll_full_overlap) * hstep;
2011-01-24 12:54:20 +01:00
break;
2011-01-24 12:54:20 +01:00
case HALF_UP:
case HALF_DOWN:
pos_y += direction * 0.5 * vstep;
2011-01-24 12:54:20 +01:00
break;
case HALF_LEFT:
case HALF_RIGHT:
pos_x += direction * 0.5 * hstep;
break;
2011-01-24 12:54:20 +01:00
case UP:
case DOWN:
pos_y += direction * t * scroll_step / (double)doc_height;
2011-01-24 12:54:20 +01:00
break;
case LEFT:
case RIGHT:
pos_x += direction * t * scroll_hstep / (double)doc_width;
2011-01-24 12:54:20 +01:00
break;
case BIDIRECTIONAL: {
pos_x += event->x * t * scroll_hstep / (double)doc_width;
pos_y += event->y * t * scroll_step / (double)doc_height;
break;
}
2011-01-24 12:54:20 +01:00
}
/* handle boundaries */
const double end_x = 0.5 * (double)view_width / (double)doc_width;
const double end_y = 0.5 * (double)view_height / (double)doc_height;
const double new_x = scroll_wrap ? 1.0 - end_x : end_x;
const double new_y = scroll_wrap ? 1.0 - end_y : end_y;
if (pos_x < end_x) {
pos_x = new_x;
} else if (pos_x > 1.0 - end_x) {
pos_x = 1 - new_x;
}
if (pos_y < end_y) {
pos_y = new_y;
} else if (pos_y > 1.0 - end_y) {
pos_y = 1 - new_y;
}
2012-09-17 16:56:43 +02:00
/* snap to the border if we change page */
2013-11-29 17:08:01 +01:00
const unsigned int new_page_id = position_to_page_number(zathura->document, pos_x, pos_y);
if (scroll_page_aware == true && page_id != new_page_id) {
2013-11-29 17:08:01 +01:00
double dummy = 0.0;
switch(argument->n) {
case FULL_LEFT:
case HALF_LEFT:
page_number_to_position(zathura->document, new_page_id, 1.0, 0.0, &pos_x, &dummy);
break;
case FULL_RIGHT:
case HALF_RIGHT:
page_number_to_position(zathura->document, new_page_id, 0.0, 0.0, &pos_x, &dummy);
break;
case FULL_UP:
case HALF_UP:
page_number_to_position(zathura->document, new_page_id, 0.0, 1.0, &dummy, &pos_y);
break;
case FULL_DOWN:
case HALF_DOWN:
page_number_to_position(zathura->document, new_page_id, 0.0, 0.0, &dummy, &pos_y);
break;
2012-09-17 16:56:43 +02:00
}
}
position_set(zathura, pos_x, pos_y);
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;
}
double x = zathura_document_get_position_x(zathura->document);
double y = zathura_document_get_position_y(zathura->document);
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) {
page_set(zathura, jump->page);
position_set(zathura, jump->x, jump->y);
}
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;
g_object_get(page_widget, "search-current", &current, "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 || (tmp + num_pages) % num_pages != cur_page) {
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
/* Need to adjust rectangle to page scale and orientation */
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);
bool search_hadjust = true;
girara_setting_get(session, "search-hadjust", &search_hadjust);
/* compute the position of the center of the page */
double pos_x = 0;
double pos_y = 0;
page_number_to_position(zathura->document, zathura_page_get_index(target_page),
0.5, 0.5, &pos_x, &pos_y);
/* correction to center the current result */
/* NOTE: rectangle is in viewport units, already scaled and rotated */
unsigned int cell_height = 0;
unsigned int cell_width = 0;
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
unsigned int doc_height = 0;
unsigned int doc_width = 0;
zathura_document_get_document_size(zathura->document, &doc_height, &doc_width);
/* compute the center of the rectangle, which will be aligned to the center
of the viewport */
double center_x = (rectangle.x1 + rectangle.x2) / 2;
double center_y = (rectangle.y1 + rectangle.y2) / 2;
pos_y += (center_y - (double)cell_height/2) / (double)doc_height;
if (search_hadjust == true) {
pos_x += (center_x - (double)cell_width/2) / (double)doc_width;
}
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
/* move to position */
zathura_jumplist_add(zathura);
position_set(zathura, pos_x, pos_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_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 TOP:
/* go to the first node */
gtk_tree_path_free(path);
path = gtk_tree_path_new_first();
break;
case BOTTOM:
/* go to the last visiible node */
gtk_tree_path_free(path);
path = gtk_tree_path_new_from_indices(gtk_tree_model_iter_n_children(model, NULL) - 1, -1);
gtk_tree_model_get_iter(model, &iter, path);
while (gtk_tree_model_iter_has_child(model, &iter) == TRUE &&
gtk_tree_view_row_expanded(tree_view, path) == TRUE) {
gtk_tree_path_append_index(path, gtk_tree_model_iter_n_children(model, &iter) - 1);
}
break;
2011-09-29 18:17:03 +02:00
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)) {
2011-09-29 18:17:03 +02:00
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;
case TOGGLE:
gtk_tree_model_get_iter(model, &iter, path);
if (gtk_tree_model_iter_has_child(model, &iter) == TRUE) {
if (gtk_tree_view_row_expanded(tree_view, path) == TRUE) {
gtk_tree_view_collapse_row(tree_view, path);
} else {
gtk_tree_view_expand_row(tree_view, path, 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 == TRUE) {
2011-09-29 18:17:03 +02:00
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;
}
gtk_style_context_add_class(gtk_widget_get_style_context(treeview),
"indexmode");
2011-02-10 04:33:28 +01:00
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);
}
if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) {
girara_set_view(session, zathura->ui.page_widget);
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
/* refresh view */
refresh_view(zathura);
2011-02-10 04:33:28 +01:00
} else {
/* 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;
}
const girara_mode_t old_mode = girara_mode_get(session);
if (old_mode == zathura->modes.fullscreen) {
gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));
refresh_view(zathura);
girara_mode_set(session, zathura->modes.normal);
} else if (old_mode == zathura->modes.normal) {
gtk_window_fullscreen(GTK_WINDOW(session->gtk.window));
refresh_view(zathura);
girara_mode_set(session, zathura->modes.fullscreen);
}
return false;
}
bool
sc_toggle_presentation(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) {
girara_notify(session, GIRARA_WARNING, _("No document opened."));
return 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
const girara_mode_t old_mode = girara_mode_get(session);
if (old_mode == zathura->modes.presentation) {
2011-10-26 20:46:59 +02:00
/* 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);
refresh_view(zathura);
/* setm ode */
girara_mode_set(session, zathura->modes.normal);
} else if (old_mode == zathura->modes.normal) {
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));
refresh_view(zathura);
/* setm ode */
girara_mode_set(session, zathura->modes.presentation);
2011-02-10 03:06:13 +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_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*
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
/* retrieve 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
const int nt = (t == 0) ? 1 : t;
const double zoom_step = value / 100.0 * nt;
const double 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.0);
} else {
zathura_document_set_scale(zathura->document, t / 100.0);
}
} else if (argument->n == ZOOM_SMOOTH) {
const double dy = event->y;
zathura_document_set_scale(zathura->document, old_zoom + zoom_step * dy);
2011-02-09 21:28:36 +01:00
} else {
zathura_document_set_scale(zathura->document, 1.0);
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);
const double zoom_min = zoom_min_int * 0.01;
const double zoom_max = zoom_max_int * 0.01;
2012-02-09 18:30:36 +01:00
const double 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);
refresh_view(zathura);
2011-02-09 21:28:36 +01:00
2010-11-13 10:05:28 +01:00
return false;
}