2010-11-10 20:31:15 +01:00
|
|
|
/* See LICENSE file for license and copyright information */
|
2010-11-12 13:48:18 +01:00
|
|
|
|
2011-10-23 17:01:15 +02:00
|
|
|
#include <girara/statusbar.h>
|
|
|
|
#include <girara/session.h>
|
|
|
|
#include <girara/settings.h>
|
2012-01-21 22:03:08 +01:00
|
|
|
#include <girara/utils.h>
|
2010-11-13 12:40:48 +01:00
|
|
|
#include <stdlib.h>
|
2010-12-29 11:46:13 +01:00
|
|
|
#include <gtk/gtk.h>
|
2012-02-07 17:31:47 +01:00
|
|
|
#include <string.h>
|
2012-03-04 18:45:58 +01:00
|
|
|
#include <glib/gi18n.h>
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
#include <math.h>
|
2010-11-12 13:48:18 +01:00
|
|
|
|
2011-08-31 14:35:53 +02:00
|
|
|
#include "callbacks.h"
|
2012-05-28 12:43:22 +02:00
|
|
|
#include "links.h"
|
2010-11-12 13:48:18 +01:00
|
|
|
#include "zathura.h"
|
2011-01-07 09:07:02 +01:00
|
|
|
#include "render.h"
|
2011-03-05 19:46:05 +01:00
|
|
|
#include "document.h"
|
2011-04-19 20:23:58 +02:00
|
|
|
#include "utils.h"
|
2011-09-29 18:08:37 +02:00
|
|
|
#include "shortcuts.h"
|
2012-03-16 14:37:54 +01:00
|
|
|
#include "page-widget.h"
|
2012-03-26 14:44:56 +02:00
|
|
|
#include "page.h"
|
2013-03-23 15:59:27 +01:00
|
|
|
#include "adjustment.h"
|
2010-11-12 13:48:18 +01:00
|
|
|
|
|
|
|
gboolean
|
2012-03-07 01:11:18 +01:00
|
|
|
cb_destroy(GtkWidget* UNUSED(widget), zathura_t* zathura)
|
2010-11-12 13:48:18 +01:00
|
|
|
{
|
2012-03-07 01:11:18 +01:00
|
|
|
if (zathura != NULL && zathura->document != NULL) {
|
2012-05-01 12:03:14 +02:00
|
|
|
document_close(zathura, false);
|
2012-03-07 01:11:18 +01:00
|
|
|
}
|
|
|
|
|
2011-10-16 20:59:25 +02:00
|
|
|
gtk_main_quit();
|
2010-11-12 13:48:18 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
2010-11-13 12:40:48 +01:00
|
|
|
|
|
|
|
void
|
2012-02-08 15:19:51 +01:00
|
|
|
cb_buffer_changed(girara_session_t* session)
|
2010-11-13 12:40:48 +01:00
|
|
|
{
|
|
|
|
g_return_if_fail(session != NULL);
|
2011-04-18 17:37:03 +02:00
|
|
|
g_return_if_fail(session->global.data != NULL);
|
|
|
|
|
|
|
|
zathura_t* zathura = session->global.data;
|
2010-11-13 12:40:48 +01:00
|
|
|
|
|
|
|
char* buffer = girara_buffer_get(session);
|
2012-03-04 01:30:27 +01:00
|
|
|
if (buffer != NULL) {
|
2011-04-18 17:37:03 +02:00
|
|
|
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
|
2010-11-13 12:40:48 +01:00
|
|
|
free(buffer);
|
2010-12-26 01:12:20 +01:00
|
|
|
} else {
|
2011-04-18 17:37:03 +02:00
|
|
|
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
|
2010-11-29 14:58:56 +01:00
|
|
|
}
|
2010-11-13 12:40:48 +01:00
|
|
|
}
|
2010-12-29 11:46:13 +01:00
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
static void
|
|
|
|
update_visible_pages(zathura_t* zathura) {
|
2013-10-19 17:45:12 +02:00
|
|
|
const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
|
2012-03-27 21:59:35 +02:00
|
|
|
|
|
|
|
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-04-03 09:02:45 +02:00
|
|
|
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
|
2013-08-30 18:56:15 +02:00
|
|
|
ZathuraPage* zathura_page_widget = ZATHURA_PAGE(page_widget);
|
2011-04-19 20:41:16 +02:00
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
if (page_is_visible(zathura->document, page_id) == true) {
|
|
|
|
/* make page visible */
|
2013-03-27 10:28:47 +01:00
|
|
|
if (zathura_page_get_visibility(page) == false) {
|
2013-07-26 16:13:41 +02:00
|
|
|
zathura_page_set_visibility(page, true);
|
2013-08-30 18:56:15 +02:00
|
|
|
zathura_page_widget_update_view_time(zathura_page_widget);
|
2013-10-20 16:06:15 +02:00
|
|
|
zathura_renderer_page_cache_add(zathura->sync.render_thread, zathura_page_get_index(page));
|
2013-03-27 10:28:47 +01:00
|
|
|
}
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
|
2011-04-19 20:46:33 +02:00
|
|
|
} else {
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
/* make page invisible */
|
2013-10-19 17:45:12 +02:00
|
|
|
if (zathura_page_get_visibility(page) == true) {
|
|
|
|
zathura_page_set_visibility(page, false);
|
|
|
|
/* If a page becomes invisible, abort the render request. */
|
|
|
|
zathura_page_widget_abort_render_request(zathura_page_widget);
|
2013-07-27 16:25:20 +02:00
|
|
|
}
|
2013-06-08 02:46:58 +02:00
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
/* reset current search result */
|
2013-06-08 02:46:58 +02:00
|
|
|
girara_list_t* results = NULL;
|
|
|
|
g_object_get(page_widget, "search-results", &results, NULL);
|
|
|
|
if (results != NULL) {
|
2013-07-26 16:13:41 +02:00
|
|
|
g_object_set(page_widget, "search-current", 0, NULL);
|
2013-06-08 02:46:58 +02:00
|
|
|
}
|
2010-12-29 11:46:13 +01:00
|
|
|
}
|
|
|
|
}
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cb_view_hadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
|
|
|
|
{
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
if (zathura == NULL || zathura->document == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-10-23 16:09:50 +02:00
|
|
|
/* Do nothing in index mode */
|
|
|
|
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
update_visible_pages(zathura);
|
|
|
|
|
|
|
|
double position_x = zathura_adjustment_get_ratio(adjustment);
|
|
|
|
double position_y = zathura_document_get_position_y(zathura->document);
|
|
|
|
unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);
|
|
|
|
|
|
|
|
zathura_document_set_position_x(zathura->document, position_x);
|
|
|
|
zathura_document_set_position_y(zathura->document, position_y);
|
|
|
|
zathura_document_set_current_page_number(zathura->document, page_id);
|
|
|
|
|
|
|
|
statusbar_page_number_update(zathura);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cb_view_vadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
|
|
|
|
{
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
if (zathura == NULL || zathura->document == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-10-23 16:09:50 +02:00
|
|
|
/* Do nothing in index mode */
|
|
|
|
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
update_visible_pages(zathura);
|
|
|
|
|
|
|
|
double position_x = zathura_document_get_position_x(zathura->document);
|
|
|
|
double position_y = zathura_adjustment_get_ratio(adjustment);
|
|
|
|
unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);
|
|
|
|
|
|
|
|
zathura_document_set_position_x(zathura->document, position_x);
|
|
|
|
zathura_document_set_position_y(zathura->document, position_y);
|
|
|
|
zathura_document_set_current_page_number(zathura->document, page_id);
|
2012-02-07 14:56:58 +01:00
|
|
|
|
|
|
|
statusbar_page_number_update(zathura);
|
2010-12-29 11:46:13 +01:00
|
|
|
}
|
2011-07-21 14:47:24 +02:00
|
|
|
|
2013-03-23 15:59:27 +01:00
|
|
|
void
|
|
|
|
cb_view_hadjustment_changed(GtkAdjustment* adjustment, gpointer data)
|
|
|
|
{
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
g_return_if_fail(zathura != NULL);
|
|
|
|
|
|
|
|
zathura_adjust_mode_t adjust_mode =
|
|
|
|
zathura_document_get_adjust_mode(zathura->document);
|
|
|
|
|
2013-10-23 16:09:50 +02:00
|
|
|
/* Do nothing in index mode */
|
|
|
|
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
/* Don't scroll we're focusing the inputbar. */
|
|
|
|
if (adjust_mode == ZATHURA_ADJUST_INPUTBAR) {
|
|
|
|
return;
|
2013-03-23 15:59:27 +01:00
|
|
|
}
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
|
|
|
|
/* save the viewport size */
|
|
|
|
unsigned int view_width = (unsigned int)floor(gtk_adjustment_get_page_size(adjustment));
|
|
|
|
zathura_document_set_viewport_width(zathura->document, view_width);
|
|
|
|
|
|
|
|
/* reset the adjustment, in case bounds have changed */
|
|
|
|
double ratio = zathura_document_get_position_x(zathura->document);
|
|
|
|
zathura_adjustment_set_value_from_ratio(adjustment, ratio);
|
2013-03-23 15:59:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cb_view_vadjustment_changed(GtkAdjustment* adjustment, gpointer data)
|
|
|
|
{
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
g_return_if_fail(zathura != NULL);
|
|
|
|
|
2013-03-23 11:07:17 +01:00
|
|
|
zathura_adjust_mode_t adjust_mode =
|
|
|
|
zathura_document_get_adjust_mode(zathura->document);
|
|
|
|
|
2013-10-23 16:09:50 +02:00
|
|
|
/* Do nothing in index mode */
|
|
|
|
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-03-23 11:07:17 +01:00
|
|
|
/* Don't scroll we're focusing the inputbar. */
|
2013-03-23 16:12:38 +01:00
|
|
|
if (adjust_mode == ZATHURA_ADJUST_INPUTBAR) {
|
2013-03-23 11:07:17 +01:00
|
|
|
return;
|
2013-03-23 16:12:38 +01:00
|
|
|
}
|
2013-03-23 11:07:17 +01:00
|
|
|
|
adapt view_adjustment callbacks to new document/view separation
The adjustment callbacks act as an interface between position data in
the document object, and the adjustments.
We remove the horizontal centering code, as now it is done by
position_set. Those callbacks should not change the position read from
the document object in any way.
Also, we split the adjustment_value_changed callback into a vertical and
an horizontal version. Previously a single callback was reused for both,
horizontal and vertical. That lead to a subtle problem when coming out
of index mode. What happened was the following:
1. horizontal adjustment bounds change coming out of index mode. This
triggers an hadjustment changed signal.
2. the hadjustment_changed callback handles it, and resets the
hadjustment value, as the bound may have changed. This triggers a
value_changed event.
3. the value_changed callback handles the event, and captures the
position for *BOTH*, horizontal and vertical adjustments, saving
them to the document object.
1..3 is repeated for the vertical adjustment.
Now, if in 3. the horizontal adjustment bounds were not yet updated
after the index mode, we got ourselves at the wrong vertical position.
This race condition is avoided now because both value_changed callbacks
*ONLY* handle their own direction, either vertical or horizontal, not
both.
2013-10-22 23:00:21 +02:00
|
|
|
/* save the viewport size */
|
|
|
|
unsigned int view_height = (unsigned int)floor(gtk_adjustment_get_page_size(adjustment));
|
|
|
|
zathura_document_set_viewport_height(zathura->document, view_height);
|
|
|
|
|
|
|
|
/* reset the adjustment, in case bounds have changed */
|
|
|
|
double ratio = zathura_document_get_position_y(zathura->document);
|
2013-03-23 15:59:27 +01:00
|
|
|
zathura_adjustment_set_value_from_ratio(adjustment, ratio);
|
|
|
|
}
|
|
|
|
|
2013-10-22 21:24:26 +02:00
|
|
|
void
|
|
|
|
cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data)
|
|
|
|
{
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
if (zathura == NULL || zathura->document == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
|
|
|
|
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
|
|
|
|
if (page == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
|
|
|
GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
|
|
|
|
|
|
|
double position_x = zathura_document_get_position_x(zathura->document);
|
|
|
|
double position_y = zathura_document_get_position_y(zathura->document);
|
|
|
|
|
|
|
|
zathura_adjustment_set_value_from_ratio(vadj, position_y);
|
|
|
|
zathura_adjustment_set_value_from_ratio(hadj, position_x);
|
|
|
|
|
|
|
|
statusbar_page_number_update(zathura);
|
|
|
|
}
|
|
|
|
|
2011-07-21 14:47:24 +02:00
|
|
|
void
|
2013-10-20 16:20:08 +02:00
|
|
|
cb_page_layout_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
|
2011-07-21 14:47:24 +02:00
|
|
|
{
|
2011-11-20 11:32:34 +01:00
|
|
|
g_return_if_fail(value != NULL);
|
2012-02-10 14:13:08 +01:00
|
|
|
g_return_if_fail(session != NULL);
|
|
|
|
g_return_if_fail(session->global.data != NULL);
|
|
|
|
zathura_t* zathura = session->global.data;
|
2011-11-20 11:32:34 +01:00
|
|
|
|
2013-11-17 18:36:22 +01:00
|
|
|
if (zathura->document == NULL) {
|
|
|
|
/* no document has been openend yet */
|
|
|
|
return;
|
|
|
|
}
|
2011-07-21 14:47:24 +02:00
|
|
|
|
2013-10-20 16:20:08 +02:00
|
|
|
unsigned int pages_per_row = 1;
|
|
|
|
girara_setting_get(session, "pages-per-row", &pages_per_row);
|
2011-07-21 14:47:24 +02:00
|
|
|
|
2012-06-27 22:34:16 +02:00
|
|
|
unsigned int first_page_column = 1;
|
|
|
|
girara_setting_get(session, "first-page-column", &first_page_column);
|
|
|
|
|
2013-10-20 16:07:07 +02:00
|
|
|
unsigned int page_padding = 1;
|
2013-10-20 16:20:08 +02:00
|
|
|
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
|
2013-10-20 16:07:07 +02:00
|
|
|
|
|
|
|
page_widget_set_mode(zathura, page_padding, pages_per_row, first_page_column);
|
|
|
|
zathura_document_set_page_layout(zathura->document, page_padding, pages_per_row, first_page_column);
|
2011-07-21 14:47:24 +02:00
|
|
|
}
|
2011-09-29 17:05:54 +02:00
|
|
|
|
|
|
|
void
|
2011-09-29 18:17:03 +02:00
|
|
|
cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
|
2012-10-09 01:12:18 +02:00
|
|
|
GtkTreeViewColumn* UNUSED(column), void* data)
|
2011-09-29 17:05:54 +02:00
|
|
|
{
|
2011-12-09 14:50:35 +01:00
|
|
|
zathura_t* zathura = data;
|
2011-09-29 17:05:54 +02:00
|
|
|
if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
g_object_get(tree_view, "model", &model, NULL);
|
|
|
|
|
2012-03-04 01:30:27 +01:00
|
|
|
if(gtk_tree_model_get_iter(model, &iter, path)) {
|
2011-09-29 17:05:54 +02:00
|
|
|
zathura_index_element_t* index_element;
|
2011-09-29 17:28:09 +02:00
|
|
|
gtk_tree_model_get(model, &iter, 2, &index_element, -1);
|
2011-09-29 17:05:54 +02:00
|
|
|
|
|
|
|
if (index_element == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-22 10:04:46 +02:00
|
|
|
sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
|
2012-05-12 17:04:25 +02:00
|
|
|
zathura_link_evaluate(zathura, index_element->link);
|
2011-09-29 17:05:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
g_object_unref(model);
|
|
|
|
}
|
2012-02-07 16:39:02 +01:00
|
|
|
|
2012-12-07 16:03:43 +01:00
|
|
|
typedef enum zathura_link_action_e
|
|
|
|
{
|
|
|
|
ZATHURA_LINK_ACTION_FOLLOW,
|
|
|
|
ZATHURA_LINK_ACTION_DISPLAY
|
|
|
|
} zathura_link_action_t;
|
|
|
|
|
|
|
|
static bool
|
|
|
|
handle_link(GtkEntry* entry, girara_session_t* session,
|
|
|
|
zathura_link_action_t action)
|
2012-02-07 17:31:47 +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;
|
2012-02-08 00:19:35 +01:00
|
|
|
bool eval = true;
|
2012-02-07 17:31:47 +01:00
|
|
|
|
|
|
|
char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
|
2012-02-08 00:19:35 +01:00
|
|
|
if (input == NULL || strlen(input) == 0) {
|
|
|
|
eval = false;
|
2012-02-07 17:31:47 +01:00
|
|
|
}
|
|
|
|
|
2012-02-08 00:19:35 +01:00
|
|
|
int index = 0;
|
|
|
|
if (eval == true) {
|
|
|
|
index = atoi(input);
|
|
|
|
if (index == 0 && g_strcmp0(input, "0") != 0) {
|
2012-03-04 18:45:58 +01:00
|
|
|
girara_notify(session, GIRARA_WARNING, _("Invalid input '%s' given."), input);
|
2012-02-08 00:19:35 +01:00
|
|
|
eval = false;
|
|
|
|
}
|
|
|
|
index = index - 1;
|
2012-02-07 17:31:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* set pages to draw links */
|
|
|
|
bool invalid_index = true;
|
2012-03-27 21:59:35 +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-03-26 14:44:56 +02:00
|
|
|
if (page == NULL || zathura_page_get_visibility(page) == false) {
|
2012-02-07 17:31:47 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-04-03 09:02:45 +02:00
|
|
|
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
|
2012-03-26 14:44:56 +02:00
|
|
|
g_object_set(page_widget, "draw-links", FALSE, NULL);
|
2012-02-07 18:00:47 +01:00
|
|
|
|
2012-02-08 00:19:35 +01:00
|
|
|
if (eval == true) {
|
2012-03-26 14:44:56 +02:00
|
|
|
zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
|
2012-08-17 14:14:57 +02:00
|
|
|
|
2012-02-08 00:19:35 +01:00
|
|
|
if (link != NULL) {
|
|
|
|
invalid_index = false;
|
2012-12-07 16:03:43 +01:00
|
|
|
switch (action) {
|
|
|
|
case ZATHURA_LINK_ACTION_FOLLOW:
|
|
|
|
zathura_link_evaluate(zathura, link);
|
|
|
|
break;
|
|
|
|
case ZATHURA_LINK_ACTION_DISPLAY:
|
|
|
|
zathura_link_display(zathura, link);
|
|
|
|
break;
|
|
|
|
}
|
2012-02-07 17:31:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-08 00:19:35 +01:00
|
|
|
if (eval == true && invalid_index == true) {
|
2012-03-04 18:45:58 +01:00
|
|
|
girara_notify(session, GIRARA_WARNING, _("Invalid index '%s' given."), input);
|
2012-02-07 17:31:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
g_free(input);
|
|
|
|
|
2012-02-08 00:19:35 +01:00
|
|
|
return (eval == TRUE) ? TRUE : FALSE;
|
2012-02-07 17:31:47 +01:00
|
|
|
}
|
2012-02-07 19:25:47 +01:00
|
|
|
|
2012-12-07 16:03:43 +01:00
|
|
|
bool
|
|
|
|
cb_sc_follow(GtkEntry* entry, girara_session_t* session)
|
|
|
|
{
|
|
|
|
return handle_link(entry, session, ZATHURA_LINK_ACTION_FOLLOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
cb_sc_display_link(GtkEntry* entry, girara_session_t* session)
|
|
|
|
{
|
|
|
|
return handle_link(entry, session, ZATHURA_LINK_ACTION_DISPLAY);
|
|
|
|
}
|
|
|
|
|
2013-08-30 19:25:24 +02:00
|
|
|
static gboolean
|
|
|
|
file_monitor_reload(void* data)
|
|
|
|
{
|
|
|
|
sc_reload((girara_session_t*) data, NULL, NULL, 0);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-02-07 19:25:47 +01:00
|
|
|
void
|
|
|
|
cb_file_monitor(GFileMonitor* monitor, GFile* file, GFile* UNUSED(other_file), GFileMonitorEvent event, girara_session_t* session)
|
|
|
|
{
|
|
|
|
g_return_if_fail(monitor != NULL);
|
|
|
|
g_return_if_fail(file != NULL);
|
|
|
|
g_return_if_fail(session != NULL);
|
|
|
|
|
2012-02-20 20:07:24 +01:00
|
|
|
switch (event) {
|
|
|
|
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
|
|
|
case G_FILE_MONITOR_EVENT_CREATED:
|
2013-08-30 19:25:24 +02:00
|
|
|
g_main_context_invoke(NULL, file_monitor_reload, session);
|
2012-02-20 20:07:24 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
2012-02-07 19:25:47 +01:00
|
|
|
}
|
|
|
|
}
|
2012-02-08 23:21:27 +01:00
|
|
|
|
2012-02-08 23:50:55 +01:00
|
|
|
static gboolean
|
|
|
|
password_dialog(gpointer data)
|
|
|
|
{
|
|
|
|
zathura_password_dialog_info_t* dialog = data;
|
2012-03-04 01:30:27 +01:00
|
|
|
|
2012-02-08 23:50:55 +01:00
|
|
|
if (dialog != NULL) {
|
2012-03-04 01:30:27 +01:00
|
|
|
girara_dialog(
|
2012-10-09 01:12:18 +02:00
|
|
|
dialog->zathura->ui.session,
|
|
|
|
"Incorrect password. Enter password:",
|
|
|
|
true,
|
|
|
|
NULL,
|
|
|
|
(girara_callback_inputbar_activate_t) cb_password_dialog,
|
|
|
|
dialog
|
|
|
|
);
|
2012-02-08 23:50:55 +01:00
|
|
|
}
|
2012-03-04 01:30:27 +01:00
|
|
|
|
2012-02-08 23:50:55 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-02-08 23:21:27 +01:00
|
|
|
bool
|
|
|
|
cb_password_dialog(GtkEntry* entry, zathura_password_dialog_info_t* dialog)
|
|
|
|
{
|
|
|
|
if (entry == NULL || dialog == NULL) {
|
|
|
|
goto error_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dialog->path == NULL) {
|
|
|
|
free(dialog);
|
|
|
|
goto error_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dialog->zathura == NULL) {
|
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
|
|
|
|
|
|
|
|
/* no or empty password: ask again */
|
|
|
|
if (input == NULL || strlen(input) == 0) {
|
|
|
|
if (input != NULL) {
|
|
|
|
g_free(input);
|
|
|
|
}
|
|
|
|
|
2012-02-16 16:18:12 +01:00
|
|
|
gdk_threads_add_idle(password_dialog, dialog);
|
2012-02-08 23:21:27 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to open document again */
|
2013-03-17 10:56:43 +01:00
|
|
|
if (document_open(dialog->zathura, dialog->path, input,
|
|
|
|
ZATHURA_PAGE_NUMBER_UNSPECIFIED) == false) {
|
2012-02-16 16:18:12 +01:00
|
|
|
gdk_threads_add_idle(password_dialog, dialog);
|
2012-02-08 23:50:55 +01:00
|
|
|
} else {
|
|
|
|
g_free(dialog->path);
|
|
|
|
free(dialog);
|
|
|
|
}
|
2012-02-08 23:21:27 +01:00
|
|
|
|
|
|
|
g_free(input);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
error_free:
|
|
|
|
|
2012-10-09 01:12:18 +02:00
|
|
|
g_free(dialog->path);
|
|
|
|
free(dialog);
|
2012-02-08 23:21:27 +01:00
|
|
|
|
|
|
|
error_ret:
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2012-02-09 01:46:51 +01:00
|
|
|
|
|
|
|
bool
|
2013-10-24 22:11:52 +02:00
|
|
|
cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* UNUSED(allocation), zathura_t* zathura)
|
2012-02-09 01:46:51 +01:00
|
|
|
{
|
|
|
|
if (zathura == NULL || zathura->document == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-10-24 22:11:52 +02:00
|
|
|
/* adjust the scale according to settings. If nothing needs to be resized,
|
|
|
|
it does not trigger the resize event.
|
2012-02-09 01:46:51 +01:00
|
|
|
|
2013-10-24 22:11:52 +02:00
|
|
|
The right viewport size is already in the document object, due to a
|
|
|
|
previous call to adjustment_changed. We don't want to use the allocation in
|
|
|
|
here, because we would have to subtract scrollbars, etc. */
|
|
|
|
adjust_view(zathura);
|
2012-02-14 15:53:04 +01:00
|
|
|
|
|
|
|
return false;
|
2012-02-09 01:46:51 +01:00
|
|
|
}
|
2012-03-14 17:33:35 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
cb_setting_recolor_change(girara_session_t* session, const char* name,
|
2012-10-09 01:12:18 +02:00
|
|
|
girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
|
2012-03-14 17:33:35 +01:00
|
|
|
{
|
|
|
|
g_return_if_fail(value != NULL);
|
|
|
|
g_return_if_fail(session != NULL);
|
|
|
|
g_return_if_fail(session->global.data != NULL);
|
|
|
|
g_return_if_fail(name != NULL);
|
|
|
|
zathura_t* zathura = session->global.data;
|
|
|
|
|
2013-08-24 00:07:32 +02:00
|
|
|
const bool bool_value = *((bool*) value);
|
2012-03-14 17:33:35 +01:00
|
|
|
|
2013-08-24 00:07:32 +02:00
|
|
|
if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_enabled(zathura->sync.render_thread) != bool_value) {
|
|
|
|
zathura_renderer_enable_recolor(zathura->sync.render_thread, bool_value);
|
|
|
|
render_all(zathura);
|
2012-03-14 17:33:35 +01:00
|
|
|
}
|
|
|
|
}
|
2012-05-01 19:09:33 +02:00
|
|
|
|
2012-07-31 16:43:20 +02:00
|
|
|
void
|
|
|
|
cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
|
2012-10-09 01:12:18 +02:00
|
|
|
girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
|
2012-07-31 16:43:20 +02:00
|
|
|
{
|
|
|
|
g_return_if_fail(value != NULL);
|
|
|
|
g_return_if_fail(session != NULL);
|
|
|
|
g_return_if_fail(session->global.data != NULL);
|
|
|
|
g_return_if_fail(name != NULL);
|
|
|
|
zathura_t* zathura = session->global.data;
|
|
|
|
|
2013-08-24 00:07:32 +02:00
|
|
|
const bool bool_value = *((bool*) value);
|
2012-07-31 16:43:20 +02:00
|
|
|
|
2013-08-24 00:07:32 +02:00
|
|
|
if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_hue_enabled(zathura->sync.render_thread) != bool_value) {
|
|
|
|
zathura_renderer_enable_recolor_hue(zathura->sync.render_thread, bool_value);
|
|
|
|
render_all(zathura);
|
2012-07-31 16:43:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-01 19:09:33 +02:00
|
|
|
bool
|
|
|
|
cb_unknown_command(girara_session_t* session, const char* input)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail(session != NULL, false);
|
|
|
|
g_return_val_if_fail(session->global.data != NULL, false);
|
|
|
|
g_return_val_if_fail(input != NULL, false);
|
|
|
|
|
|
|
|
zathura_t* zathura = session->global.data;
|
|
|
|
|
|
|
|
if (zathura->document == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check for number */
|
2013-08-30 18:56:15 +02:00
|
|
|
const size_t size = strlen(input);
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
2012-05-01 19:09:33 +02:00
|
|
|
if (g_ascii_isdigit(input[i]) == FALSE) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-09 05:53:31 +02:00
|
|
|
zathura_jumplist_add(zathura);
|
2012-05-01 19:09:33 +02:00
|
|
|
page_set(zathura, atoi(input) - 1);
|
2012-08-17 14:14:57 +02:00
|
|
|
zathura_jumplist_add(zathura);
|
2012-05-01 19:09:33 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-31 13:12:41 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
cb_page_widget_text_selected(ZathuraPage* page, const char* text, void* data)
|
|
|
|
{
|
|
|
|
g_return_if_fail(page != NULL);
|
|
|
|
g_return_if_fail(text != NULL);
|
|
|
|
g_return_if_fail(data != NULL);
|
|
|
|
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
GdkAtom* selection = get_selection(zathura);
|
|
|
|
|
|
|
|
/* copy to clipboard */
|
|
|
|
if (selection != NULL) {
|
|
|
|
gtk_clipboard_set_text(gtk_clipboard_get(*selection), text, -1);
|
|
|
|
|
|
|
|
char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' ');
|
2013-10-21 14:16:38 +02:00
|
|
|
char* escaped_text = g_markup_printf_escaped(
|
|
|
|
_("Copied selected text to clipboard: %s"), stripped_text);
|
2013-08-31 13:12:41 +02:00
|
|
|
g_free(stripped_text);
|
2013-10-21 14:16:38 +02:00
|
|
|
|
2013-10-21 14:19:28 +02:00
|
|
|
girara_notify(zathura->ui.session, GIRARA_INFO, "%s", escaped_text);
|
2013-10-21 14:16:38 +02:00
|
|
|
g_free(escaped_text);
|
2013-08-31 13:12:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
g_free(selection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cb_page_widget_image_selected(ZathuraPage* page, GdkPixbuf* pixbuf, void* data)
|
|
|
|
{
|
|
|
|
g_return_if_fail(page != NULL);
|
|
|
|
g_return_if_fail(pixbuf != NULL);
|
|
|
|
g_return_if_fail(data != NULL);
|
|
|
|
|
|
|
|
zathura_t* zathura = data;
|
|
|
|
GdkAtom* selection = get_selection(zathura);
|
|
|
|
|
|
|
|
if (selection != NULL) {
|
|
|
|
gtk_clipboard_set_image(gtk_clipboard_get(*selection), pixbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(selection);
|
|
|
|
}
|