[evince/abderrahim/dual-rtl: 95/95] ev-view: Make document direction independent of UI direction



commit 7b2433b719607d87b71e4022473c49e809167bfa
Author: Abderrahim Kitouni <akitouni gnome org>
Date:   Mon Mar 4 14:22:20 2019 +0100

    ev-view: Make document direction independent of UI direction
    
    Based on a patch by Tomo Kazahaya <tomonacci gmail com>
    
    Fix #830

 libview/ev-document-model.c | 40 ++++++++++++++++++++++++++++++++++++
 libview/ev-document-model.h |  3 +++
 libview/ev-view.c           | 15 ++++++++++++++
 shell/ev-window.c           | 50 +++++++++++++++++++++++++++++++++++++++++++++
 shell/evince-menus.ui       |  4 ++++
 5 files changed, 112 insertions(+)
---
diff --git a/libview/ev-document-model.c b/libview/ev-document-model.c
index a90b6ff7..db537a5a 100644
--- a/libview/ev-document-model.c
+++ b/libview/ev-document-model.c
@@ -39,6 +39,7 @@ struct _EvDocumentModel
        guint continuous : 1;
        guint dual_page  : 1;
        guint dual_page_odd_left : 1;
+       guint rtl : 1;
        guint fullscreen : 1;
        guint inverted_colors : 1;
 
@@ -57,6 +58,7 @@ enum {
        PROP_CONTINUOUS,
        PROP_DUAL_PAGE,
        PROP_DUAL_PAGE_ODD_LEFT,
+       PROP_RTL,
        PROP_FULLSCREEN,
        PROP_MIN_SCALE,
        PROP_MAX_SCALE,
@@ -134,6 +136,9 @@ ev_document_model_set_property (GObject      *object,
        case PROP_DUAL_PAGE_ODD_LEFT:
                ev_document_model_set_dual_page_odd_pages_left (model, g_value_get_boolean (value));
                break;
+       case PROP_RTL:
+               ev_document_model_set_rtl (model, g_value_get_boolean (value));
+               break;
        case PROP_FULLSCREEN:
                ev_document_model_set_fullscreen (model, g_value_get_boolean (value));
                break;
@@ -187,6 +192,9 @@ ev_document_model_get_property (GObject    *object,
        case PROP_DUAL_PAGE_ODD_LEFT:
                g_value_set_boolean (value, ev_document_model_get_dual_page_odd_pages_left (model));
                break;
+       case PROP_RTL:
+               g_value_set_boolean (value, ev_document_model_get_rtl (model));
+               break;
        case PROP_FULLSCREEN:
                g_value_set_boolean (value, ev_document_model_get_fullscreen (model));
                break;
@@ -303,6 +311,14 @@ ev_document_model_class_init (EvDocumentModelClass *klass)
                                                               FALSE,
                                                               G_PARAM_READWRITE |
                                                                G_PARAM_STATIC_STRINGS));
+       g_object_class_install_property (g_object_class,
+                                        PROP_RTL,
+                                        g_param_spec_boolean ("rtl",
+                                                              "Right to Left",
+                                                              "Whether the document is written from right to 
left",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE |
+                                                               G_PARAM_STATIC_STRINGS));
        g_object_class_install_property (g_object_class,
                                         PROP_FULLSCREEN,
                                         g_param_spec_boolean ("fullscreen",
@@ -720,6 +736,30 @@ ev_document_model_get_dual_page_odd_pages_left (EvDocumentModel *model)
        return model->dual_page_odd_left;
 }
 
+void
+ev_document_model_set_rtl (EvDocumentModel *model,
+                           gboolean         rtl)
+{
+       g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+
+       rtl = rtl != FALSE;
+
+       if (rtl == model->rtl)
+               return;
+
+       model->rtl = rtl;
+
+       g_object_notify (G_OBJECT (model), "rtl");
+}
+
+gboolean
+ev_document_model_get_rtl (EvDocumentModel *model)
+{
+       g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), FALSE);
+
+       return model->rtl;
+}
+
 void
 ev_document_model_set_fullscreen (EvDocumentModel *model,
                                  gboolean         fullscreen)
diff --git a/libview/ev-document-model.h b/libview/ev-document-model.h
index 6a99e43a..042977ec 100644
--- a/libview/ev-document-model.h
+++ b/libview/ev-document-model.h
@@ -92,6 +92,9 @@ gboolean         ev_document_model_get_continuous    (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);
+void             ev_document_model_set_rtl (EvDocumentModel *model,
+                                            gboolean         rtl);
+gboolean         ev_document_model_get_rtl (EvDocumentModel *model);
 void             ev_document_model_set_fullscreen    (EvDocumentModel *model,
                                                      gboolean         fullscreen);
 gboolean         ev_document_model_get_fullscreen    (EvDocumentModel *model);
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 852fbfc5..8ba063e4 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -8561,6 +8561,17 @@ ev_view_dual_odd_left_changed_cb (EvDocumentModel *model,
                gtk_widget_queue_resize (GTK_WIDGET (view));
 }
 
+static void
+ev_view_direction_changed_cb (EvDocumentModel *model,
+                              GParamSpec      *pspec,
+                              EvView          *view)
+{
+       gboolean rtl = ev_document_model_get_rtl (model);
+       gtk_widget_set_direction (GTK_WIDGET (view), rtl ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+       view->pending_scroll = SCROLL_TO_PAGE_POSITION;
+       gtk_widget_queue_resize (GTK_WIDGET (view));
+}
+
 static void
 ev_view_fullscreen_changed_cb (EvDocumentModel *model,
                               GParamSpec      *pspec,
@@ -8594,6 +8605,7 @@ ev_view_set_model (EvView          *view,
        view->scale = ev_document_model_get_scale (view->model);
        view->continuous = ev_document_model_get_continuous (view->model);
        view->page_layout = ev_document_model_get_page_layout (view->model);
+       gtk_widget_set_direction (GTK_WIDGET(view), ev_document_model_get_rtl (view->model));
        view->fullscreen = ev_document_model_get_fullscreen (view->model);
        ev_view_document_changed_cb (view->model, NULL, view);
 
@@ -8627,6 +8639,9 @@ ev_view_set_model (EvView          *view,
        g_signal_connect (view->model, "notify::dual-odd-left",
                          G_CALLBACK (ev_view_dual_odd_left_changed_cb),
                          view);
+       g_signal_connect (view->model, "notify::rtl",
+                         G_CALLBACK (ev_view_direction_changed_cb),
+                         view);
        g_signal_connect (view->model, "notify::fullscreen",
                          G_CALLBACK (ev_view_fullscreen_changed_cb),
                          view);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index e46eb250..e09ddea1 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -528,6 +528,8 @@ ev_window_update_actions_sensitivity (EvWindow *ev_window)
                                      !recent_view_mode);
        ev_window_set_action_enabled (ev_window, "dual-page", has_pages &&
                                      !recent_view_mode);
+       ev_window_set_action_enabled (ev_window, "rtl", has_pages &&
+                                     !recent_view_mode);
        ev_window_set_action_enabled (ev_window, "reload", has_pages &&
                                      !recent_view_mode);
        ev_window_set_action_enabled (ev_window, "auto-scroll", has_pages &&
@@ -1134,6 +1136,10 @@ ev_window_init_metadata_with_default_values (EvWindow *window)
                ev_metadata_set_boolean (metadata, "dual-page-odd-left",
                                         g_settings_get_boolean (settings, "dual-page-odd-left"));
        }
+       if (!ev_metadata_has_key (metadata, "rtl")) {
+               ev_metadata_set_boolean (metadata, "rtl",
+                                        gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL ? TRUE : 
FALSE);
+       }
        if (!ev_metadata_has_key (metadata, "inverted-colors")) {
                ev_metadata_set_boolean (metadata, "inverted-colors",
                                         g_settings_get_boolean (settings, "inverted-colors"));
@@ -1201,6 +1207,7 @@ setup_model_from_metadata (EvWindow *window)
        gboolean continuous = FALSE;
        gboolean dual_page = FALSE;
        gboolean dual_page_odd_left = FALSE;
+       gboolean rtl = FALSE;
        gboolean fullscreen = FALSE;
        EvWindowPrivate *priv = GET_PRIVATE (window);
 
@@ -1269,6 +1276,11 @@ setup_model_from_metadata (EvWindow *window)
                ev_document_model_set_dual_page_odd_pages_left (priv->model, dual_page_odd_left);
        }
 
+       /* Right to left document */
+       if (ev_metadata_get_boolean (priv->metadata, "rtl", &rtl)) {
+               ev_document_model_set_rtl (priv->model, rtl);
+       }
+
        /* Fullscreen */
        if (ev_metadata_get_boolean (priv->metadata, "fullscreen", &fullscreen)) {
                if (fullscreen)
@@ -1482,6 +1494,7 @@ ev_window_setup_default (EvWindow *ev_window)
        ev_document_model_set_continuous (model, g_settings_get_boolean (settings, "continuous"));
        ev_document_model_set_dual_page (model, g_settings_get_boolean (settings, "dual-page"));
        ev_document_model_set_dual_page_odd_pages_left (model, g_settings_get_boolean (settings, 
"dual-page-odd-left"));
+       ev_document_model_set_rtl (model, gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL ? TRUE : 
FALSE);
        ev_document_model_set_inverted_colors (model, g_settings_get_boolean (settings, "inverted-colors"));
        ev_document_model_set_sizing_mode (model, g_settings_get_enum (settings, "sizing-mode"));
        if (ev_document_model_get_sizing_mode (model) == EV_SIZING_FREE)
@@ -4141,6 +4154,19 @@ ev_window_cmd_dual_odd_pages_left (GSimpleAction *action,
        g_simple_action_set_state (action, state);
 }
 
+static void
+ev_window_cmd_rtl (GSimpleAction *action,
+                   GVariant      *state,
+                   gpointer       user_data)
+{
+       EvWindow *window = user_data;
+       EvWindowPrivate *priv = GET_PRIVATE (window);
+
+       ev_document_model_set_rtl (priv->model,
+                                  g_variant_get_boolean (state));
+       g_simple_action_set_state (action, state);
+}
+
 static void
 ev_window_change_sizing_mode_action_state (GSimpleAction *action,
                                           GVariant      *state,
@@ -5320,6 +5346,25 @@ ev_window_dual_mode_odd_pages_left_changed_cb (EvDocumentModel *model,
                                         odd_left);
 }
 
+static void
+ev_window_direction_changed_cb (EvDocumentModel *model,
+                          GParamSpec      *pspec,
+                          EvWindow        *ev_window)
+{
+       EvWindowPrivate *priv = GET_PRIVATE (ev_window);
+       gboolean rtl;
+       GAction *action;
+
+       rtl = ev_document_model_get_rtl (model);
+
+       action = g_action_map_lookup_action (G_ACTION_MAP (ev_window), "rtl");
+       g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (rtl));
+
+       if (priv->metadata && !ev_window_is_empty (ev_window))
+               ev_metadata_set_boolean (priv->metadata, "rtl",
+                                        rtl);
+}
+
 static void
 ev_window_cmd_action_menu (GSimpleAction *action,
                           GVariant      *parameter,
@@ -6254,6 +6299,7 @@ static const GActionEntry actions[] = {
        { "continuous", NULL, NULL, "true", ev_window_cmd_continuous },
        { "dual-page", NULL, NULL, "false", ev_window_cmd_dual },
        { "dual-odd-left", NULL, NULL, "false", ev_window_cmd_dual_odd_pages_left },
+       { "rtl", NULL, NULL, "false", ev_window_cmd_rtl },
        { "show-side-pane", NULL, NULL, "false", ev_window_view_cmd_toggle_sidebar },
        { "inverted-colors", NULL, NULL, "false", ev_window_cmd_view_inverted_colors },
        { "enable-spellchecking", NULL, NULL, "false", ev_window_cmd_view_enable_spellchecking },
@@ -7677,6 +7723,10 @@ ev_window_init (EvWindow *ev_window)
                          "notify::dual-odd-left",
                          G_CALLBACK (ev_window_dual_mode_odd_pages_left_changed_cb),
                          ev_window);
+       g_signal_connect (priv->model,
+                         "notify::rtl",
+                         G_CALLBACK (ev_window_direction_changed_cb),
+                         ev_window);
        g_signal_connect (priv->model,
                          "notify::inverted-colors",
                          G_CALLBACK (ev_window_inverted_colors_changed_cb),
diff --git a/shell/evince-menus.ui b/shell/evince-menus.ui
index 72670dd7..5844d928 100644
--- a/shell/evince-menus.ui
+++ b/shell/evince-menus.ui
@@ -78,6 +78,10 @@
         <attribute name="label" translatable="yes">_Odd Pages Left</attribute>
         <attribute name="action">win.dual-odd-left</attribute>
       </item>
+      <item>
+        <attribute name="label" translatable="yes">Right to Left Document</attribute>
+        <attribute name="action">win.rtl</attribute>
+      </item>
     </section>
     <section>
       <item>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]