summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libview/ev-document-model.c72
-rw-r--r--libview/ev-document-model.h20
-rw-r--r--libview/ev-view-private.h2
-rw-r--r--libview/ev-view.c164
4 files changed, 201 insertions, 57 deletions
diff --git a/libview/ev-document-model.c b/libview/ev-document-model.c
index 856ee36e..d5d97f62 100644
--- a/libview/ev-document-model.c
+++ b/libview/ev-document-model.c
@@ -35,6 +35,7 @@ struct _EvDocumentModel
gint rotation;
gdouble scale;
EvSizingMode sizing_mode;
+ EvPageLayout page_layout;
guint continuous : 1;
guint dual_page : 1;
guint dual_page_odd_left : 1;
@@ -66,7 +67,8 @@ enum {
PROP_CONTINUOUS,
PROP_DUAL_PAGE,
PROP_DUAL_PAGE_ODD_LEFT,
- PROP_FULLSCREEN
+ PROP_FULLSCREEN,
+ PROP_PAGE_LAYOUT
};
enum
@@ -122,6 +124,9 @@ ev_document_model_set_property (GObject *object,
case PROP_CONTINUOUS:
ev_document_model_set_continuous (model, g_value_get_boolean (value));
break;
+ case PROP_PAGE_LAYOUT:
+ ev_document_model_set_page_layout (model, g_value_get_enum (value));
+ break;
case PROP_DUAL_PAGE:
ev_document_model_set_dual_page (model, g_value_get_boolean (value));
break;
@@ -166,6 +171,9 @@ ev_document_model_get_property (GObject *object,
case PROP_CONTINUOUS:
g_value_set_boolean (value, ev_document_model_get_continuous (model));
break;
+ case PROP_PAGE_LAYOUT:
+ g_value_set_enum (value, model->page_layout);
+ break;
case PROP_DUAL_PAGE:
g_value_set_boolean (value, ev_document_model_get_dual_page (model));
break;
@@ -234,6 +242,15 @@ ev_document_model_class_init (EvDocumentModelClass *klass)
EV_SIZING_FIT_WIDTH,
G_PARAM_READWRITE));
g_object_class_install_property (g_object_class,
+ PROP_PAGE_LAYOUT,
+ g_param_spec_enum ("page-layout",
+ "Page Layout",
+ "Current page layout",
+ EV_TYPE_PAGE_LAYOUT,
+ EV_PAGE_LAYOUT_SINGLE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (g_object_class,
PROP_CONTINUOUS,
g_param_spec_boolean ("continuous",
"Continuous",
@@ -472,6 +489,47 @@ ev_document_model_get_sizing_mode (EvDocumentModel *model)
return model->sizing_mode;
}
+static void
+_ev_document_model_set_dual_page_internal (EvDocumentModel *model,
+ gboolean dual_page)
+{
+ g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+
+ dual_page = dual_page != FALSE;
+
+ if (dual_page == model->dual_page)
+ return;
+
+ model->dual_page = dual_page;
+
+ g_object_notify (G_OBJECT (model), "dual-page");
+}
+
+void
+ev_document_model_set_page_layout (EvDocumentModel *model,
+ EvPageLayout layout)
+{
+ g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+
+ if (layout == model->page_layout)
+ return;
+
+ model->page_layout = layout;
+
+ g_object_notify (G_OBJECT (model), "page-layout");
+
+ /* set deprecated property as well */
+ _ev_document_model_set_dual_page_internal (model, layout == EV_PAGE_LAYOUT_DUAL);
+}
+
+EvPageLayout
+ev_document_model_get_page_layout (EvDocumentModel *model)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), EV_PAGE_LAYOUT_SINGLE);
+
+ return model->page_layout;
+}
+
void
ev_document_model_set_rotation (EvDocumentModel *model,
gint rotation)
@@ -549,16 +607,12 @@ void
ev_document_model_set_dual_page (EvDocumentModel *model,
gboolean dual_page)
{
- g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
-
- dual_page = dual_page != FALSE;
-
- if (dual_page == model->dual_page)
- return;
+ EvPageLayout layout;
- model->dual_page = dual_page;
+ g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
- g_object_notify (G_OBJECT (model), "dual-page");
+ layout = dual_page ? EV_PAGE_LAYOUT_DUAL : EV_PAGE_LAYOUT_SINGLE;
+ ev_document_model_set_page_layout (model, layout);
}
gboolean
diff --git a/libview/ev-document-model.h b/libview/ev-document-model.h
index fdec1433..4dda24cb 100644
--- a/libview/ev-document-model.h
+++ b/libview/ev-document-model.h
@@ -41,6 +41,12 @@ typedef enum {
EV_SIZING_AUTOMATIC,
} EvSizingMode;
+typedef enum {
+ EV_PAGE_LAYOUT_SINGLE,
+ EV_PAGE_LAYOUT_DUAL,
+ EV_PAGE_LAYOUT_AUTOMATIC,
+} EvPageLayout;
+
typedef struct _EvDocumentModel EvDocumentModel;
typedef struct _EvDocumentModelClass EvDocumentModelClass;
@@ -68,6 +74,9 @@ gdouble ev_document_model_get_min_scale (EvDocumentModel *model);
void ev_document_model_set_sizing_mode (EvDocumentModel *model,
EvSizingMode mode);
EvSizingMode ev_document_model_get_sizing_mode (EvDocumentModel *model);
+void ev_document_model_set_page_layout (EvDocumentModel *model,
+ EvPageLayout layout);
+EvPageLayout ev_document_model_get_page_layout (EvDocumentModel *model);
void ev_document_model_set_rotation (EvDocumentModel *model,
gint rotation);
gint ev_document_model_get_rotation (EvDocumentModel *model);
@@ -79,9 +88,6 @@ gboolean ev_document_model_get_inverted_colors (EvDocumentModel *model);
void ev_document_model_set_continuous (EvDocumentModel *model,
gboolean continuous);
gboolean ev_document_model_get_continuous (EvDocumentModel *model);
-void ev_document_model_set_dual_page (EvDocumentModel *model,
- gboolean dual_page);
-gboolean ev_document_model_get_dual_page (EvDocumentModel *model);
void ev_document_model_set_dual_page_odd_pages_left (EvDocumentModel *model,
gboolean odd_left);
gboolean ev_document_model_get_dual_page_odd_pages_left (EvDocumentModel *model);
@@ -89,6 +95,14 @@ void ev_document_model_set_fullscreen (EvDocumentModel *model,
gboolean fullscreen);
gboolean ev_document_model_get_fullscreen (EvDocumentModel *model);
+/* deprecated */
+
+EV_DEPRECATED_FOR(ev_document_model_set_page_layout)
+void ev_document_model_set_dual_page (EvDocumentModel *model,
+ gboolean dual_page);
+EV_DEPRECATED_FOR(ev_document_model_get_page_layout)
+gboolean ev_document_model_get_dual_page (EvDocumentModel *model);
+
G_END_DECLS
#endif /* __EV_DOCUMENT_MODEL_H__ */
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 02219641..c93b0f90 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -168,10 +168,10 @@ struct _EvView {
gboolean loading;
gboolean continuous;
- gboolean dual_page;
gboolean dual_even_left;
gboolean fullscreen;
EvSizingMode sizing_mode;
+ EvPageLayout page_layout;
GtkWidget *loading_window;
guint loading_timeout;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 0b05b4a9..9125e361 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -480,6 +480,65 @@ ev_view_get_scrollbar_size (EvView *view,
return (orientation == GTK_ORIENTATION_VERTICAL ? req.width : req.height) + spacing;
}
+static gboolean
+is_dual_page (EvView *view,
+ gboolean *odd_left_out)
+{
+ gboolean dual = FALSE;
+ gboolean odd_left = FALSE;
+
+ switch (view->page_layout) {
+ case EV_PAGE_LAYOUT_AUTOMATIC: {
+ GdkScreen *screen;
+#if GTK_CHECK_VERSION (3, 22, 0)
+ GdkMonitor *monitor;
+ GdkDisplay *display;
+#else
+ gint monitor;
+#endif
+ double scale;
+ double doc_width;
+ double doc_height;
+ GtkAllocation allocation;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (view));
+#if GTK_CHECK_VERSION (3, 22, 0)
+ display = gdk_screen_get_display (screen);
+ monitor = gdk_display_get_primary_monitor (display);
+#else
+ monitor = gdk_screen_get_primary_monitor (screen);
+#endif
+ scale = ev_document_misc_get_screen_dpi (screen, monitor) / 72.0;
+
+ ev_document_get_max_page_size (view->document, &doc_width, &doc_height);
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+
+ /* If the width is ok and the height is pretty close, try to fit it in */
+ if (ev_document_get_n_pages (view->document) > 1 &&
+ doc_width < doc_height &&
+ allocation.width > (2 * doc_width * scale) &&
+ allocation.height > (doc_height * scale * 0.9)) {
+ odd_left = !view->dual_even_left;
+ dual = TRUE;
+ }
+ }
+ break;
+ case EV_PAGE_LAYOUT_DUAL:
+ odd_left = !view->dual_even_left;
+ dual = TRUE;
+ break;
+ case EV_PAGE_LAYOUT_SINGLE:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (odd_left_out)
+ *odd_left_out = odd_left;
+
+ return dual;
+}
+
static void
scroll_to_point (EvView *view,
gdouble x,
@@ -507,7 +566,7 @@ scroll_to_point (EvView *view,
upper = gtk_adjustment_get_upper (view->hadjustment);
lower = gtk_adjustment_get_lower (view->hadjustment);
- if (view->dual_page) {
+ if (is_dual_page (view, NULL)) {
gtk_adjustment_clamp_page (view->hadjustment, x,
x + page_size);
} else {
@@ -638,6 +697,7 @@ view_update_range_and_current_page (EvView *view)
{
gint start = view->start_page;
gint end = view->end_page;
+ gboolean odd_left;
if (ev_document_get_n_pages (view->document) <= 0 ||
!ev_document_check_dimensions (view->document))
@@ -680,7 +740,7 @@ view_update_range_and_current_page (EvView *view)
view->end_page = i;
j = 0;
} else if (found && view->current_page <= view->end_page) {
- if (view->dual_page && j < 1) {
+ if (is_dual_page (view, NULL) && j < 1) {
/* In dual mode we stop searching
* after two consecutive non-visible pages.
*/
@@ -700,8 +760,8 @@ view_update_range_and_current_page (EvView *view)
ev_document_model_set_page (view->model, best_current_page);
}
}
- } else if (view->dual_page) {
- if (view->current_page % 2 == view->dual_even_left) {
+ } else if (is_dual_page (view, &odd_left)) {
+ if (view->current_page % 2 == !odd_left) {
view->start_page = view->current_page;
if (view->current_page + 1 < ev_document_get_n_pages (view->document))
view->end_page = view->start_page + 1;
@@ -1081,16 +1141,17 @@ get_page_y_offset (EvView *view, int page, int *y_offset)
{
int max_width, offset = 0;
GtkBorder border;
+ gboolean odd_left;
g_return_if_fail (y_offset != NULL);
ev_view_get_max_page_size (view, &max_width, NULL);
compute_border (view, max_width, max_width, &border);
- if (view->dual_page) {
+ if (is_dual_page (view, &odd_left)) {
ev_view_get_height_to_page (view, page, NULL, &offset);
- offset += ((page + view->dual_even_left) / 2 + 1) * view->spacing +
- ((page + view->dual_even_left) / 2 ) * (border.top + border.bottom);
+ offset += ((page + !odd_left) / 2 + 1) * view->spacing +
+ ((page + !odd_left) / 2 ) * (border.top + border.bottom);
} else {
ev_view_get_height_to_page (view, page, &offset, NULL);
offset += (page + 1) * view->spacing + page * (border.top + border.bottom);
@@ -1122,14 +1183,15 @@ ev_view_get_page_extents (EvView *view,
if (view->continuous) {
gint max_width;
gint x, y;
+ gboolean odd_left;
ev_view_get_max_page_size (view, &max_width, NULL);
max_width = max_width + border->left + border->right;
/* Get the location of the bounding box */
- if (view->dual_page) {
- x = view->spacing + ((page % 2 == view->dual_even_left) ? 0 : 1) * (max_width + view->spacing);
+ if (is_dual_page (view, &odd_left)) {
+ x = view->spacing + ((page % 2 == !odd_left) ? 0 : 1) * (max_width + view->spacing);
x = x + MAX (0, allocation.width - (max_width * 2 + view->spacing * 3)) / 2;
- if (page % 2 == view->dual_even_left)
+ if (page % 2 == !odd_left)
x = x + (max_width - width - border->left - border->right);
} else {
x = view->spacing;
@@ -1142,14 +1204,16 @@ ev_view_get_page_extents (EvView *view,
page_area->y = y;
} else {
gint x, y;
- if (view->dual_page) {
+ gboolean odd_left;
+
+ if (is_dual_page (view, &odd_left)) {
gint width_2, height_2;
gint max_width = width;
gint max_height = height;
GtkBorder overall_border;
gint other_page;
- other_page = (page % 2 == view->dual_even_left) ? page + 1: page - 1;
+ other_page = (page % 2 == !odd_left) ? page + 1: page - 1;
/* First, we get the bounding box of the two pages */
if (other_page < ev_document_get_n_pages (view->document)
@@ -1168,7 +1232,7 @@ ev_view_get_page_extents (EvView *view,
y = view->spacing;
/* Adjust for being the left or right page */
- if (page % 2 == view->dual_even_left)
+ if (page % 2 == !odd_left)
x = x + max_width - width;
else
x = x + (max_width + overall_border.left + overall_border.right) + view->spacing;
@@ -3288,6 +3352,7 @@ ev_view_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
EvView *view = EV_VIEW (widget);
+ gboolean dual_page;
if (view->document == NULL) {
view->requisition.width = 1;
@@ -3313,11 +3378,12 @@ ev_view_size_request (GtkWidget *widget,
allocation.height);
}
- if (view->continuous && view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (view->continuous && dual_page)
ev_view_size_request_continuous_dual_page (view, &view->requisition);
else if (view->continuous)
ev_view_size_request_continuous (view, &view->requisition);
- else if (view->dual_page)
+ else if (dual_page)
ev_view_size_request_dual_page (view, &view->requisition);
else
ev_view_size_request_single_page (view, &view->requisition);
@@ -5318,10 +5384,10 @@ ev_view_init (EvView *view)
view->selection_info.in_drag = FALSE;
view->selection_mode = EV_VIEW_SELECTION_TEXT;
view->continuous = TRUE;
- view->dual_page = FALSE;
view->dual_even_left = TRUE;
view->fullscreen = FALSE;
view->sizing_mode = EV_SIZING_FIT_WIDTH;
+ view->page_layout = EV_PAGE_LAYOUT_SINGLE;
view->pending_scroll = SCROLL_TO_KEEP_POSITION;
view->jump_to_find_result = TRUE;
view->highlight_find_results = FALSE;
@@ -5682,6 +5748,23 @@ ev_view_sizing_mode_changed_cb (EvDocumentModel *model,
gtk_widget_queue_resize (GTK_WIDGET (view));
}
+static void
+ev_view_page_layout_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvView *view)
+{
+ EvPageLayout layout = ev_document_model_get_page_layout (model);
+
+ view->page_layout = layout;
+
+ view->pending_scroll = SCROLL_TO_PAGE_POSITION;
+ gtk_widget_queue_resize (GTK_WIDGET (view));
+
+ /* FIXME: if we're keeping the pixbuf cache around, we should extend the
+ * preload_cache_size to be 2 if dual_page is set.
+ */
+}
+
#define EPSILON 0.0000001
static void
ev_view_scale_changed_cb (EvDocumentModel *model,
@@ -5713,25 +5796,11 @@ ev_view_continuous_changed_cb (EvDocumentModel *model,
}
static void
-ev_view_dual_page_changed_cb (EvDocumentModel *model,
- GParamSpec *pspec,
- EvView *view)
-{
- view->dual_page = ev_document_model_get_dual_page (model);
- view->pending_scroll = SCROLL_TO_PAGE_POSITION;
- /* FIXME: if we're keeping the pixbuf cache around, we should extend the
- * preload_cache_size to be 2 if dual_page is set.
- */
- gtk_widget_queue_resize (GTK_WIDGET (view));
-}
-
-static void
ev_view_dual_odd_left_changed_cb (EvDocumentModel *model,
GParamSpec *pspec,
EvView *view)
{
view->dual_even_left = !ev_document_model_get_dual_page_odd_pages_left (model);
-
view->pending_scroll = SCROLL_TO_PAGE_POSITION;
gtk_widget_queue_resize (GTK_WIDGET (view));
}
@@ -5773,7 +5842,7 @@ ev_view_set_model (EvView *view,
view->sizing_mode = ev_document_model_get_sizing_mode (view->model);
view->scale = ev_document_model_get_scale (view->model);
view->continuous = ev_document_model_get_continuous (view->model);
- view->dual_page = ev_document_model_get_dual_page (view->model);
+ view->page_layout = ev_document_model_get_page_layout (view->model);
view->fullscreen = ev_document_model_get_fullscreen (view->model);
ev_view_document_changed_cb (view->model, NULL, view);
@@ -5789,15 +5858,15 @@ ev_view_set_model (EvView *view,
g_signal_connect (view->model, "notify::sizing-mode",
G_CALLBACK (ev_view_sizing_mode_changed_cb),
view);
+ g_signal_connect (view->model, "notify::page-layout",
+ G_CALLBACK (ev_view_page_layout_changed_cb),
+ view);
g_signal_connect (view->model, "notify::scale",
G_CALLBACK (ev_view_scale_changed_cb),
view);
g_signal_connect (view->model, "notify::continuous",
G_CALLBACK (ev_view_continuous_changed_cb),
view);
- g_signal_connect (view->model, "notify::dual-page",
- G_CALLBACK (ev_view_dual_page_changed_cb),
- view);
g_signal_connect (view->model, "notify::dual-odd-left",
G_CALLBACK (ev_view_dual_odd_left_changed_cb),
view);
@@ -6120,6 +6189,8 @@ ev_view_zoom_for_size (EvView *view,
int width,
int height)
{
+ gboolean dual_page;
+
g_return_if_fail (EV_IS_VIEW (view));
g_return_if_fail (view->sizing_mode == EV_SIZING_FIT_WIDTH ||
view->sizing_mode == EV_SIZING_FIT_PAGE ||
@@ -6130,11 +6201,12 @@ ev_view_zoom_for_size (EvView *view,
if (view->document == NULL)
return;
- if (view->continuous && view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (view->continuous && dual_page)
ev_view_zoom_for_size_continuous_and_dual_page (view, width, height);
else if (view->continuous)
ev_view_zoom_for_size_continuous (view, width, height);
- else if (view->dual_page)
+ else if (dual_page)
ev_view_zoom_for_size_dual_page (view, width, height);
else
ev_view_zoom_for_size_single_page (view, width, height);
@@ -6432,7 +6504,7 @@ compute_new_selection_text (EvView *view,
if (view->continuous) {
start_page = 0;
end_page = n_pages;
- } else if (view->dual_page) {
+ } else if (is_dual_page (view, NULL)) {
start_page = view->start_page;
end_page = view->end_page + 1;
} else {
@@ -6897,6 +6969,7 @@ gboolean
ev_view_next_page (EvView *view)
{
int page, n_pages;
+ gboolean dual_page;
g_return_val_if_fail (EV_IS_VIEW (view), FALSE);
@@ -6906,7 +6979,8 @@ ev_view_next_page (EvView *view)
page = ev_document_model_get_page (view->model);
n_pages = ev_document_get_n_pages (view->document);
- if (view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (dual_page)
page = page + 2;
else
page = page + 1;
@@ -6914,7 +6988,7 @@ ev_view_next_page (EvView *view)
if (page < n_pages) {
ev_document_model_set_page (view->model, page);
return TRUE;
- } else if (view->dual_page && page == n_pages) {
+ } else if (dual_page && page == n_pages) {
ev_document_model_set_page (view->model, page - 1);
return TRUE;
} else {
@@ -6926,6 +7000,7 @@ gboolean
ev_view_previous_page (EvView *view)
{
int page;
+ gboolean dual_page;
g_return_val_if_fail (EV_IS_VIEW (view), FALSE);
@@ -6934,7 +7009,8 @@ ev_view_previous_page (EvView *view)
page = ev_document_model_get_page (view->model);
- if (view->dual_page)
+ dual_page = is_dual_page (view, NULL);
+ if (dual_page)
page = page - 2;
else
page = page - 1;
@@ -6942,7 +7018,7 @@ ev_view_previous_page (EvView *view)
if (page >= 0) {
ev_document_model_set_page (view->model, page);
return TRUE;
- } else if (view->dual_page && page == -1) {
+ } else if (dual_page && page == -1) {
ev_document_model_set_page (view->model, 0);
return TRUE;
} else {
@@ -6970,13 +7046,13 @@ ev_view_disconnect_handlers(EvView *view)
G_CALLBACK (ev_view_sizing_mode_changed_cb),
view);
g_signal_handlers_disconnect_by_func(view->model,
- G_CALLBACK (ev_view_scale_changed_cb),
+ G_CALLBACK (ev_view_page_layout_changed_cb),
view);
g_signal_handlers_disconnect_by_func(view->model,
- G_CALLBACK (ev_view_continuous_changed_cb),
+ G_CALLBACK (ev_view_scale_changed_cb),
view);
g_signal_handlers_disconnect_by_func(view->model,
- G_CALLBACK (ev_view_dual_page_changed_cb),
+ G_CALLBACK (ev_view_continuous_changed_cb),
view);
g_signal_handlers_disconnect_by_func(view->model,
G_CALLBACK (ev_view_fullscreen_changed_cb),