[evince/BUG_tooltip_annots_aacid: 11/11] pdf: support 'de facto' tooltip feature



commit e2ad8611a4c58f09d78def78500a2c10a21ac48b
Author: Nelson Benítez León <nbenitezl gmail com>
Date:   Sat Mar 14 17:57:41 2020 -0400

    pdf: support 'de facto' tooltip feature
    
    Most pdf readers implement a tooltip feature by
    showing the string content of 'TU' field of a
    widget annotation that is not linked to any
    form field.
    
    Normally, widget annotations carry a reference to a
    form field which are used together to implement the
    different form widgets. But, the PDF spec does not
    forbid standalone (i.e. not linked to any form field)
    widget annotations, and the fact is they're been used
    by most pdf readers to show a tooltip when the area
    of that AnnotWidget is hovered.
    
    According to issue reported files, 'pdfTeX' seems to
    be one of the pdf producers incorporating this tooltip
    feature.
    
    The support for this feature has been recently been
    added to poppler-glib with following api:
    
    gchar*
    poppler_form_field_get_alternate_ui_name (PopplerFormField *field)
    
    so this commit uses that api to show tooltips on pdf's
    that carry them. For that we add a new 'alt_ui_name'
    field to EvFormField and show it as a tooltip when
    the field's area is hovered.
    
    Evince issue #842
    
    Poppler issue:
    https://gitlab.freedesktop.org/poppler/poppler/issues/34

 backend/pdf/ev-poppler.cc   |  5 +++++
 libdocument/ev-form-field.c |  2 ++
 libdocument/ev-form-field.h |  1 +
 libview/ev-view.c           | 34 +++++++++++++++++++++++++++++++++-
 4 files changed, 41 insertions(+), 1 deletion(-)
---
diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc
index a6383a15..f5ab3e5e 100644
--- a/backend/pdf/ev-poppler.cc
+++ b/backend/pdf/ev-poppler.cc
@@ -2665,11 +2665,15 @@ ev_form_field_from_poppler_field (PdfDocument      *pdf_document,
        gdouble      font_size;
        gboolean     is_read_only;
        PopplerAction *action;
+       gchar       *alt_ui_name = NULL;
 
        id = poppler_form_field_get_id (poppler_field);
        font_size = poppler_form_field_get_font_size (poppler_field);
        is_read_only = poppler_form_field_is_read_only (poppler_field);
        action = poppler_form_field_get_action (poppler_field);
+#if POPPLER_CHECK_VERSION(0, 88, 0)
+       alt_ui_name = poppler_form_field_get_alternate_ui_name (poppler_field);
+#endif
 
        switch (poppler_form_field_get_field_type (poppler_field)) {
                case POPPLER_FORM_FIELD_TEXT: {
@@ -2759,6 +2763,7 @@ ev_form_field_from_poppler_field (PdfDocument      *pdf_document,
 
        ev_field->font_size = font_size;
        ev_field->is_read_only = is_read_only;
+       ev_field->alt_ui_name = alt_ui_name;
 
        if (action)
                ev_field->activation_link = ev_link_from_action (pdf_document, action);
diff --git a/libdocument/ev-form-field.c b/libdocument/ev-form-field.c
index c234e967..7e0169ad 100644
--- a/libdocument/ev-form-field.c
+++ b/libdocument/ev-form-field.c
@@ -45,6 +45,7 @@ ev_form_field_init (EvFormField *field)
        field->page = NULL;
        field->changed = FALSE;
        field->is_read_only = FALSE;
+       field->alt_ui_name = NULL;
 }
 
 static void
@@ -56,6 +57,7 @@ ev_form_field_finalize (GObject *object)
        field->page = NULL;
 
        g_clear_object (&field->activation_link);
+       g_clear_pointer (&field->alt_ui_name, g_free);
 
        (* G_OBJECT_CLASS (ev_form_field_parent_class)->finalize) (object);
 }
diff --git a/libdocument/ev-form-field.h b/libdocument/ev-form-field.h
index d0571a2a..84344504 100644
--- a/libdocument/ev-form-field.h
+++ b/libdocument/ev-form-field.h
@@ -113,6 +113,7 @@ struct _EvFormField
 
        EvPage  *page;
        gboolean changed;
+       gchar   *alt_ui_name;
 };
 
 struct _EvFormFieldClass
diff --git a/libview/ev-view.c b/libview/ev-view.c
index ffbe1704..f73f0ce9 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -2205,7 +2205,7 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
        }
 
-       if (link || annot)
+       if (link || annot || (field && field->alt_ui_name))
                g_object_set (view, "has-tooltip", TRUE, NULL);
 }
 
@@ -4911,6 +4911,26 @@ get_annot_area (EvView       *view,
                                       annot, area);
 }
 
+static void
+get_field_area (EvView       *view,
+               gint          x,
+               gint          y,
+               EvFormField  *field,
+               GdkRectangle *area)
+{
+       EvMappingList *field_mapping;
+       gint           page;
+       gint           x_offset = 0, y_offset = 0;
+
+       x += view->scroll_x;
+       y += view->scroll_y;
+
+       find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
+
+       field_mapping = ev_page_cache_get_form_field_mapping (view->page_cache, page);
+       ev_view_get_area_from_mapping (view, page, field_mapping, field, area);
+}
+
 static gboolean
 ev_view_query_tooltip (GtkWidget  *widget,
                       gint        x,
@@ -4919,6 +4939,7 @@ ev_view_query_tooltip (GtkWidget  *widget,
                       GtkTooltip *tooltip)
 {
        EvView       *view = EV_VIEW (widget);
+       EvFormField  *field;
        EvLink       *link;
        EvAnnotation *annot;
        gchar        *text;
@@ -4939,6 +4960,17 @@ ev_view_query_tooltip (GtkWidget  *widget,
                }
        }
 
+       field = ev_view_get_form_field_at_location (view, x, y);
+       if (field && field->alt_ui_name && *(field->alt_ui_name) != '\0') {
+               GdkRectangle field_area;
+
+               get_field_area (view, x, y, field, &field_area);
+               gtk_tooltip_set_text (tooltip, field->alt_ui_name);
+               gtk_tooltip_set_tip_area (tooltip, &field_area);
+
+               return TRUE;
+       }
+
        link = ev_view_get_link_at_location (view, x, y);
        if (!link)
                return FALSE;


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