From 982600bbceb76a22d5c7b3e0cbe6e20421105ad6 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Fri, 31 Aug 2007 20:37:24 +0000 Subject: [PATCH] Add support for double and triple click selections. 2007-08-31 Carlos Garcia Campos * backend/dvi/dvi-document.c: (dvi_document_document_iface_init): * backend/impress/impress-document.c: (impress_document_document_iface_init): * backend/ps/ps-document.c: (ps_document_document_iface_init): * backend/djvu/djvu-document.c: (djvu_document_document_iface_init), (djvu_selection_get_selected_text), (djvu_selection_iface_init): * backend/tiff/tiff-document.c: (tiff_document_document_iface_init): * backend/pixbuf/pixbuf-document.c: (pixbuf_document_document_iface_init): * backend/comics/comics-document.c: (comics_document_document_iface_init): * backend/pdf/ev-poppler.cc: (pdf_document_document_iface_init), (pdf_selection_render_selection), (pdf_selection_get_selected_text), (pdf_selection_get_selection_region), (pdf_selection_get_selection_map), (pdf_selection_iface_init): * libdocument/ev-selection.[ch]: (ev_selection_get_selected_text), (ev_selection_get_selection_region), (ev_selection_get_selection_map): * libdocument/ev-document.[ch]: * shell/ev-pixbuf-cache.[ch]: (add_job), (ev_pixbuf_cache_get_selection_surface), (update_job_selection): * shell/ev-view-private.h: * shell/ev-jobs.[ch]: (ev_job_render_new), (ev_job_render_new), (ev_job_render_run): * shell/ev-window.c: (ev_window_setup_action_sensitivity): * shell/ev-view.c: (start_selection_for_event), (ev_view_button_press_event), (ev_view_drag_data_get), (ev_view_drag_data_received), (ev_view_button_release_event), (compute_new_selection_text), (compute_selections), (ev_view_select_all), (get_selected_text), (ev_view_copy), (ev_view_primary_get_cb): Add support for double and triple click selections. svn path=/trunk/; revision=2648 --- ChangeLog | 39 ++++++++++ backend/comics/comics-document.c | 7 -- backend/djvu/djvu-document.c | 66 ++++++++-------- backend/dvi/dvi-document.c | 7 -- backend/impress/impress-document.c | 7 -- backend/pdf/ev-poppler.cc | 75 ++++++++++--------- backend/pixbuf/pixbuf-document.c | 7 -- backend/ps/ps-document.c | 7 -- backend/tiff/tiff-document.c | 7 -- libdocument/ev-document.c | 22 ------ libdocument/ev-document.h | 8 -- libdocument/ev-selection.c | 29 +++++++- libdocument/ev-selection.h | 22 +++++- shell/ev-jobs.c | 5 +- shell/ev-jobs.h | 3 + shell/ev-pixbuf-cache.c | 12 ++- shell/ev-pixbuf-cache.h | 2 + shell/ev-view-private.h | 2 + shell/ev-view.c | 116 ++++++++++++++++++++--------- shell/ev-window.c | 2 +- 20 files changed, 257 insertions(+), 188 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4adca52..874e43a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2007-08-31 Carlos Garcia Campos + + * backend/dvi/dvi-document.c: (dvi_document_document_iface_init): + * backend/impress/impress-document.c: + (impress_document_document_iface_init): + * backend/ps/ps-document.c: (ps_document_document_iface_init): + * backend/djvu/djvu-document.c: + (djvu_document_document_iface_init), + (djvu_selection_get_selected_text), (djvu_selection_iface_init): + * backend/tiff/tiff-document.c: + (tiff_document_document_iface_init): + * backend/pixbuf/pixbuf-document.c: + (pixbuf_document_document_iface_init): + * backend/comics/comics-document.c: + (comics_document_document_iface_init): + * backend/pdf/ev-poppler.cc: (pdf_document_document_iface_init), + (pdf_selection_render_selection), + (pdf_selection_get_selected_text), + (pdf_selection_get_selection_region), + (pdf_selection_get_selection_map), (pdf_selection_iface_init): + * libdocument/ev-selection.[ch]: (ev_selection_get_selected_text), + (ev_selection_get_selection_region), + (ev_selection_get_selection_map): + * libdocument/ev-document.[ch]: + * shell/ev-pixbuf-cache.[ch]: (add_job), + (ev_pixbuf_cache_get_selection_surface), (update_job_selection): + * shell/ev-view-private.h: + * shell/ev-jobs.[ch]: (ev_job_render_new), (ev_job_render_new), + (ev_job_render_run): + * shell/ev-window.c: (ev_window_setup_action_sensitivity): + * shell/ev-view.c: (start_selection_for_event), + (ev_view_button_press_event), (ev_view_drag_data_get), + (ev_view_drag_data_received), (ev_view_button_release_event), + (compute_new_selection_text), (compute_selections), + (ev_view_select_all), (get_selected_text), (ev_view_copy), + (ev_view_primary_get_cb): + + Add support for double and triple click selections. + 2007-08-28 Nickolay V. Shmyrev * NEWS: diff --git a/backend/comics/comics-document.c b/backend/comics/comics-document.c index 092d8c2b..77e6fabd 100644 --- a/backend/comics/comics-document.c +++ b/backend/comics/comics-document.c @@ -367,12 +367,6 @@ comics_document_class_init (ComicsDocumentClass *klass) gobject_class->finalize = comics_document_finalize; } -static gboolean -comics_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - static EvDocumentInfo * comics_document_get_info (EvDocument *document) { @@ -386,7 +380,6 @@ comics_document_document_iface_init (EvDocumentIface *iface) { iface->load = comics_document_load; iface->save = comics_document_save; - iface->can_get_text = comics_document_can_get_text; iface->get_n_pages = comics_document_get_n_pages; iface->get_page_size = comics_document_get_page_size; iface->render = comics_document_render; diff --git a/backend/djvu/djvu-document.c b/backend/djvu/djvu-document.c index 4a7aecc0..2b9dee72 100644 --- a/backend/djvu/djvu-document.c +++ b/backend/djvu/djvu-document.c @@ -26,6 +26,7 @@ #include "ev-document-misc.h" #include "ev-document-find.h" #include "ev-document-links.h" +#include "ev-selection.h" #include #include @@ -51,6 +52,7 @@ static void djvu_document_document_thumbnails_iface_init (EvDocumentThumbnailsIf static void djvu_document_file_exporter_iface_init (EvFileExporterIface *iface); static void djvu_document_find_iface_init (EvDocumentFindIface *iface); static void djvu_document_document_links_iface_init (EvDocumentLinksIface *iface); +static void djvu_selection_iface_init (EvSelectionIface *iface); G_DEFINE_TYPE_WITH_CODE (DjvuDocument, djvu_document, G_TYPE_OBJECT, @@ -60,6 +62,7 @@ G_DEFINE_TYPE_WITH_CODE G_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER, djvu_document_file_exporter_iface_init); G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND, djvu_document_find_iface_init); G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_LINKS, djvu_document_document_links_iface_init); + G_IMPLEMENT_INTERFACE (EV_TYPE_SELECTION, djvu_selection_iface_init); }); @@ -317,35 +320,6 @@ djvu_document_class_init (DjvuDocumentClass *klass) gobject_class->finalize = djvu_document_finalize; } -static gboolean -djvu_document_can_get_text (EvDocument *document) -{ - return TRUE; -} - - -static char * -djvu_document_get_text (EvDocument *document, int page, EvRectangle *rect) -{ - DjvuDocument *djvu_document = DJVU_DOCUMENT (document); - double width, height; - EvRectangle rectangle; - char* text; - - djvu_document_get_page_size (document, page, &width, &height); - rectangle.x1 = rect->x1 / SCALE_FACTOR; - rectangle.y1 = (height - rect->y2) / SCALE_FACTOR; - rectangle.x2 = rect->x2 / SCALE_FACTOR; - rectangle.y2 = (height - rect->y1) / SCALE_FACTOR; - - text = djvu_text_copy (djvu_document, page, &rectangle); - - if (text == NULL) - text = g_strdup (""); - - return text; -} - static EvDocumentInfo * djvu_document_get_info (EvDocument *document) { @@ -361,14 +335,44 @@ djvu_document_document_iface_init (EvDocumentIface *iface) { iface->load = djvu_document_load; iface->save = djvu_document_save; - iface->can_get_text = djvu_document_can_get_text; - iface->get_text = djvu_document_get_text; iface->get_n_pages = djvu_document_get_n_pages; iface->get_page_size = djvu_document_get_page_size; iface->render = djvu_document_render; iface->get_info = djvu_document_get_info; } +static gchar * +djvu_selection_get_selected_text (EvSelection *selection, + EvRenderContext *rc, + EvSelectionStyle style, + EvRectangle *points) +{ + DjvuDocument *djvu_document = DJVU_DOCUMENT (selection); + double width, height; + EvRectangle rectangle; + gchar *text; + + djvu_document_get_page_size (EV_DOCUMENT (djvu_document), + rc->page, &width, &height); + rectangle.x1 = points->x1 / SCALE_FACTOR; + rectangle.y1 = (height - points->y2) / SCALE_FACTOR; + rectangle.x2 = points->x2 / SCALE_FACTOR; + rectangle.y2 = (height - points->y1) / SCALE_FACTOR; + + text = djvu_text_copy (djvu_document, rc->page, &rectangle); + + if (text == NULL) + text = g_strdup (""); + + return text; +} + +static void +djvu_selection_iface_init (EvSelectionIface *iface) +{ + iface->get_selected_text = djvu_selection_get_selected_text; +} + static void djvu_document_thumbnails_get_dimensions (EvDocumentThumbnails *document, EvRenderContext *rc, diff --git a/backend/dvi/dvi-document.c b/backend/dvi/dvi-document.c index b6f83258..73b148b3 100644 --- a/backend/dvi/dvi-document.c +++ b/backend/dvi/dvi-document.c @@ -250,12 +250,6 @@ dvi_document_class_init (DviDocumentClass *klass) dvi_context_mutex = g_mutex_new (); } -static gboolean -dvi_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - static EvDocumentInfo * dvi_document_get_info (EvDocument *document) { @@ -271,7 +265,6 @@ dvi_document_document_iface_init (EvDocumentIface *iface) { iface->load = dvi_document_load; iface->save = dvi_document_save; - iface->can_get_text = dvi_document_can_get_text; iface->get_n_pages = dvi_document_get_n_pages; iface->get_page_size = dvi_document_get_page_size; iface->render = dvi_document_render; diff --git a/backend/impress/impress-document.c b/backend/impress/impress-document.c index 6251fbd2..74d335a6 100644 --- a/backend/impress/impress-document.c +++ b/backend/impress/impress-document.c @@ -458,12 +458,6 @@ impress_document_class_init (ImpressDocumentClass *klass) gobject_class->finalize = impress_document_finalize; } -static gboolean -impress_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - static EvDocumentInfo * impress_document_get_info (EvDocument *document) { @@ -480,7 +474,6 @@ impress_document_document_iface_init (EvDocumentIface *iface) { iface->load = impress_document_load; iface->save = impress_document_save; - iface->can_get_text = impress_document_can_get_text; iface->get_n_pages = impress_document_get_n_pages; iface->get_page_size = impress_document_get_page_size; iface->render = impress_document_render; diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index 815862cb..09edfb41 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -568,12 +568,6 @@ pdf_document_set_password (EvDocumentSecurity *document_security, document->password = g_strdup (password); } -static gboolean -pdf_document_can_get_text (EvDocument *document) -{ - return TRUE; -} - static EvDocumentInfo * pdf_document_get_info (EvDocument *document) { @@ -719,31 +713,6 @@ pdf_document_get_info (EvDocument *document) return info; } -static char * -pdf_document_get_text (EvDocument *document, int page, EvRectangle *rect) -{ - PdfDocument *pdf_document = PDF_DOCUMENT (document); - PopplerPage *poppler_page; - PopplerRectangle r; - double height; - char *text; - - poppler_page = poppler_document_get_page (pdf_document->document, page); - g_return_val_if_fail (poppler_page != NULL, NULL); - - poppler_page_get_size (poppler_page, NULL, &height); - r.x1 = rect->x1; - r.y1 = height - rect->y2; - r.x2 = rect->x2; - r.y2 = height - rect->y1; - - text = poppler_page_get_text (poppler_page, &r); - - g_object_unref (poppler_page); - - return text; -} - static void pdf_document_document_iface_init (EvDocumentIface *iface) { @@ -755,8 +724,6 @@ pdf_document_document_iface_init (EvDocumentIface *iface) iface->has_attachments = pdf_document_has_attachments; iface->get_attachments = pdf_document_get_attachments; iface->render = pdf_document_render; - iface->get_text = pdf_document_get_text; - iface->can_get_text = pdf_document_can_get_text; iface->get_info = pdf_document_get_info; }; @@ -1792,6 +1759,7 @@ pdf_selection_render_selection (EvSelection *selection, cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, + EvSelectionStyle style, GdkColor *text, GdkColor *base) { @@ -1807,7 +1775,6 @@ pdf_selection_render_selection (EvSelection *selection, width = (int) ((width_points * rc->scale) + 0.5); height = (int) ((height_points * rc->scale) + 0.5); - #ifdef HAVE_POPPLER_PAGE_RENDER cairo_t *cr; @@ -1827,7 +1794,7 @@ pdf_selection_render_selection (EvSelection *selection, cr, (PopplerRectangle *)points, (PopplerRectangle *)old_points, - POPPLER_SELECTION_NORMAL, /* SelectionStyle */ + (PopplerSelectionStyle)style, text, base); cairo_destroy (cr); @@ -1842,7 +1809,7 @@ pdf_selection_render_selection (EvSelection *selection, rc->scale, rc->rotation, pixbuf, (PopplerRectangle *)points, (PopplerRectangle *)old_points, - POPPLER_SELECTION_NORMAL, /* SelectionStyle */ + (PopplerSelectionStyle)style, text, base); if (*surface) @@ -1852,10 +1819,40 @@ pdf_selection_render_selection (EvSelection *selection, #endif /* HAVE_POPPLER_PAGE_RENDER */ } +static gchar * +pdf_selection_get_selected_text (EvSelection *selection, + EvRenderContext *rc, + EvSelectionStyle style, + EvRectangle *points) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (selection); + PopplerPage *poppler_page; + PopplerRectangle r; + double height; + char *retval; + + poppler_page = poppler_document_get_page (pdf_document->document, rc->page); + g_return_val_if_fail (poppler_page != NULL, NULL); + + poppler_page_get_size (poppler_page, NULL, &height); + r.x1 = points->x1; + r.y1 = height - points->y2; + r.x2 = points->x2; + r.y2 = height - points->y1; + + retval = poppler_page_get_text (poppler_page, + (PopplerSelectionStyle)style, + &r); + + g_object_unref (poppler_page); + + return retval; +} static GdkRegion * pdf_selection_get_selection_region (EvSelection *selection, EvRenderContext *rc, + EvSelectionStyle style, EvRectangle *points) { PdfDocument *pdf_document; @@ -1867,6 +1864,7 @@ pdf_selection_get_selection_region (EvSelection *selection, retval = poppler_page_get_selection_region ((PopplerPage *)rc->data, rc->scale, + (PopplerSelectionStyle)style, (PopplerRectangle *) points); return retval; } @@ -1887,7 +1885,9 @@ pdf_selection_get_selection_map (EvSelection *selection, points.x1 = 0.0; points.y1 = 0.0; poppler_page_get_size (poppler_page, &(points.x2), &(points.y2)); - retval = poppler_page_get_selection_region (poppler_page, 1.0, &points); + retval = poppler_page_get_selection_region (poppler_page, 1.0, + POPPLER_SELECTION_GLYPH, + &points); g_object_unref (poppler_page); return retval; @@ -1897,6 +1897,7 @@ static void pdf_selection_iface_init (EvSelectionIface *iface) { iface->render_selection = pdf_selection_render_selection; + iface->get_selected_text = pdf_selection_get_selected_text; iface->get_selection_region = pdf_selection_get_selection_region; iface->get_selection_map = pdf_selection_get_selection_map; } diff --git a/backend/pixbuf/pixbuf-document.c b/backend/pixbuf/pixbuf-document.c index 83d2b8ae..b9b98a66 100644 --- a/backend/pixbuf/pixbuf-document.c +++ b/backend/pixbuf/pixbuf-document.c @@ -143,12 +143,6 @@ pixbuf_document_class_init (PixbufDocumentClass *klass) gobject_class->finalize = pixbuf_document_finalize; } -static gboolean -pixbuf_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - static EvDocumentInfo * pixbuf_document_get_info (EvDocument *document) { @@ -165,7 +159,6 @@ pixbuf_document_document_iface_init (EvDocumentIface *iface) { iface->load = pixbuf_document_load; iface->save = pixbuf_document_save; - iface->can_get_text = pixbuf_document_can_get_text; iface->get_n_pages = pixbuf_document_get_n_pages; iface->get_page_size = pixbuf_document_get_page_size; iface->render = pixbuf_document_render; diff --git a/backend/ps/ps-document.c b/backend/ps/ps-document.c index 5e636871..61f07ab7 100644 --- a/backend/ps/ps-document.c +++ b/backend/ps/ps-document.c @@ -415,12 +415,6 @@ ps_document_get_page_size (EvDocument *document, } } -static gboolean -ps_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - static EvDocumentInfo * ps_document_get_info (EvDocument *document) { @@ -454,7 +448,6 @@ ps_document_document_iface_init (EvDocumentIface *iface) { iface->load = ps_document_load; iface->save = ps_document_save; - iface->can_get_text = ps_document_can_get_text; iface->get_n_pages = ps_document_get_n_pages; iface->get_page_size = ps_document_get_page_size; iface->get_info = ps_document_get_info; diff --git a/backend/tiff/tiff-document.c b/backend/tiff/tiff-document.c index c6f4db2b..f813c474 100644 --- a/backend/tiff/tiff-document.c +++ b/backend/tiff/tiff-document.c @@ -373,12 +373,6 @@ tiff_document_class_init (TiffDocumentClass *klass) gobject_class->finalize = tiff_document_finalize; } -static gboolean -tiff_document_can_get_text (EvDocument *document) -{ - return FALSE; -} - static EvDocumentInfo * tiff_document_get_info (EvDocument *document) { @@ -395,7 +389,6 @@ tiff_document_document_iface_init (EvDocumentIface *iface) { iface->load = tiff_document_load; iface->save = tiff_document_save; - iface->can_get_text = tiff_document_can_get_text; iface->get_n_pages = tiff_document_get_n_pages; iface->get_page_size = tiff_document_get_page_size; iface->render = tiff_document_render; diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c index e0ce69fd..2c6db95a 100644 --- a/libdocument/ev-document.c +++ b/libdocument/ev-document.c @@ -175,14 +175,6 @@ ev_document_get_page_label(EvDocument *document, return iface->get_page_label (document, page); } -gboolean -ev_document_can_get_text (EvDocument *document) -{ - EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document); - - return iface->can_get_text (document); -} - EvDocumentInfo * ev_document_get_info (EvDocument *document) { @@ -191,20 +183,6 @@ ev_document_get_info (EvDocument *document) return iface->get_info (document); } -char * -ev_document_get_text (EvDocument *document, - int page, - EvRectangle *rect) -{ - EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document); - char *retval; - - LOG ("ev_document_get_text"); - retval = iface->get_text (document, page, rect); - - return retval; -} - gboolean ev_document_has_attachments (EvDocument *document) { diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h index 833491e2..4f83553e 100644 --- a/libdocument/ev-document.h +++ b/libdocument/ev-document.h @@ -84,10 +84,6 @@ struct _EvDocumentIface double *height); char * (* get_page_label) (EvDocument *document, int page); - gboolean (* can_get_text) (EvDocument *document); - char * (* get_text) (EvDocument *document, - int page, - EvRectangle *rect); gboolean (* has_attachments) (EvDocument *document); GList * (* get_attachments) (EvDocument *document); cairo_surface_t * (* render) (EvDocument *document, @@ -122,10 +118,6 @@ void ev_document_get_page_size (EvDocument *document, double *height); char *ev_document_get_page_label (EvDocument *document, int page); -gboolean ev_document_can_get_text (EvDocument *document); -char *ev_document_get_text (EvDocument *document, - int page, - EvRectangle *rect); gboolean ev_document_has_attachments (EvDocument *document); GList *ev_document_get_attachments (EvDocument *document); cairo_surface_t *ev_document_render (EvDocument *document, diff --git a/libdocument/ev-selection.c b/libdocument/ev-selection.c index f7aee2f7..9a7336c6 100644 --- a/libdocument/ev-selection.c +++ b/libdocument/ev-selection.c @@ -62,25 +62,45 @@ ev_selection_render_selection (EvSelection *selection, cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, - GdkColor *text, - GdkColor *base) + EvSelectionStyle style, + GdkColor *text, + GdkColor *base) { EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); + if (!iface->render_selection) + return; + iface->render_selection (selection, rc, surface, points, old_points, + style, text, base); } +gchar * +ev_selection_get_selected_text (EvSelection *selection, + EvRenderContext *rc, + EvSelectionStyle style, + EvRectangle *points) +{ + EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); + + return iface->get_selected_text (selection, rc, style, points); +} + GdkRegion * ev_selection_get_selection_region (EvSelection *selection, EvRenderContext *rc, + EvSelectionStyle style, EvRectangle *points) { EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); - return iface->get_selection_region (selection, rc, points); + if (!iface->get_selection_region) + return NULL; + + return iface->get_selection_region (selection, rc, style, points); } GdkRegion * @@ -89,5 +109,8 @@ ev_selection_get_selection_map (EvSelection *selection, { EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); + if (!iface->get_selection_map) + return NULL; + return iface->get_selection_map (selection, rc); } diff --git a/libdocument/ev-selection.h b/libdocument/ev-selection.h index 5ba9776d..0b2f41be 100644 --- a/libdocument/ev-selection.h +++ b/libdocument/ev-selection.h @@ -36,6 +36,12 @@ G_BEGIN_DECLS #define EV_IS_SELECTION_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_SELECTION)) #define EV_SELECTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_SELECTION, EvSelectionIface)) +typedef enum { + EV_SELECTION_STYLE_GLYPH, + EV_SELECTION_STYLE_WORD, + EV_SELECTION_STYLE_LINE +} EvSelectionStyle; + typedef struct _EvSelection EvSelection; typedef struct _EvSelectionIface EvSelectionIface; @@ -48,12 +54,18 @@ struct _EvSelectionIface cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, - GdkColor *text, - GdkColor *base); + EvSelectionStyle style, + GdkColor *text, + GdkColor *base); + gchar * (* get_selected_text) (EvSelection *selection, + EvRenderContext *rc, + EvSelectionStyle style, + EvRectangle *points); GdkRegion * (* get_selection_map) (EvSelection *selection, EvRenderContext *rc); GdkRegion * (* get_selection_region) (EvSelection *selection, EvRenderContext *rc, + EvSelectionStyle style, EvRectangle *points); }; @@ -63,12 +75,18 @@ void ev_selection_render_selection (EvSelection *selection, cairo_surface_t **surface, EvRectangle *points, EvRectangle *old_points, + EvSelectionStyle style, GdkColor *text, GdkColor *base); +gchar *ev_selection_get_selected_text (EvSelection *selection, + EvRenderContext *rc, + EvSelectionStyle style, + EvRectangle *points); GdkRegion *ev_selection_get_selection_map (EvSelection *selection, EvRenderContext *rc); GdkRegion *ev_selection_get_selection_region (EvSelection *selection, EvRenderContext *rc, + EvSelectionStyle style, EvRectangle *points); G_END_DECLS diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index 6934f60f..99bfc87a 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -8,7 +8,6 @@ #include "ev-document-misc.h" #include "ev-file-helpers.h" #include "ev-document-fonts.h" -#include "ev-selection.h" #include "ev-async-renderer.h" #include @@ -276,6 +275,7 @@ ev_job_render_new (EvDocument *document, gint width, gint height, EvRectangle *selection_points, + EvSelectionStyle selection_style, GdkColor *text, GdkColor *base, gboolean include_forms, @@ -296,6 +296,7 @@ ev_job_render_new (EvDocument *document, job->rc = g_object_ref (rc); job->target_width = width; job->target_height = height; + job->selection_style = selection_style; job->text = *text; job->base = *base; job->include_forms = include_forms; @@ -371,10 +372,12 @@ ev_job_render_run (EvJobRender *job) &(job->selection), &(job->selection_points), NULL, + job->selection_style, &(job->text), &(job->base)); job->selection_region = ev_selection_get_selection_region (EV_SELECTION (EV_JOB (job)->document), job->rc, + job->selection_style, &(job->selection_points)); } diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index b15f260f..6d7e95bf 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -24,6 +24,7 @@ #include "ev-document.h" #include "ev-window.h" #include "ev-file-exporter.h" +#include "ev-selection.h" G_BEGIN_DECLS @@ -133,6 +134,7 @@ struct _EvJobRender cairo_surface_t *selection; GdkRegion *selection_region; EvRectangle selection_points; + EvSelectionStyle selection_style; GdkColor base; GdkColor text; @@ -229,6 +231,7 @@ EvJob *ev_job_render_new (EvDocument *document, gint width, gint height, EvRectangle *selection_points, + EvSelectionStyle selection_style, GdkColor *text, GdkColor *base, gboolean include_forms, diff --git a/shell/ev-pixbuf-cache.c b/shell/ev-pixbuf-cache.c index 951decb2..46054914 100644 --- a/shell/ev-pixbuf-cache.c +++ b/shell/ev-pixbuf-cache.c @@ -1,7 +1,6 @@ #include "ev-pixbuf-cache.h" #include "ev-job-queue.h" #include "ev-page-cache.h" -#include "ev-selection.h" #include "ev-document-images.h" #include "ev-document-forms.h" #include "ev-image.h" @@ -26,9 +25,10 @@ typedef struct _CacheJobInfo /* Selection data. * Selection_points are the coordinates encapsulated in selection. * target_points is the target selection size. */ - EvRectangle selection_points; - EvRectangle target_points; - gboolean points_set; + EvRectangle selection_points; + EvRectangle target_points; + EvSelectionStyle selection_style; + gboolean points_set; cairo_surface_t *selection; GdkRegion *selection_region; @@ -646,6 +646,7 @@ add_job (EvPixbufCache *pixbuf_cache, job_info->rc, width, height, &(job_info->target_points), + job_info->selection_style, text, base, include_forms, include_links, @@ -1021,6 +1022,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache, job_info->selection_region = ev_selection_get_selection_region (EV_SELECTION (pixbuf_cache->document), job_info->rc, + job_info->selection_style, &(job_info->target_points)); gtk_widget_ensure_style (pixbuf_cache->view); @@ -1031,6 +1033,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache, job_info->rc, &(job_info->selection), &(job_info->target_points), old_points, + job_info->selection_style, text, base); job_info->selection_points = job_info->target_points; ev_document_doc_mutex_unlock (); @@ -1046,6 +1049,7 @@ update_job_selection (CacheJobInfo *job_info, { job_info->points_set = TRUE; job_info->target_points = selection->rect; + job_info->selection_style = selection->style; } static void diff --git a/shell/ev-pixbuf-cache.h b/shell/ev-pixbuf-cache.h index d2116cdb..ed1c1ec9 100644 --- a/shell/ev-pixbuf-cache.h +++ b/shell/ev-pixbuf-cache.h @@ -26,6 +26,7 @@ #include #include "ev-document.h" +#include "ev-selection.h" #include "ev-job-queue.h" G_BEGIN_DECLS @@ -43,6 +44,7 @@ typedef struct { int page; EvRectangle rect; GdkRegion *covered_region; + EvSelectionStyle style; } EvViewSelection; typedef struct _EvPixbufCache EvPixbufCache; diff --git a/shell/ev-view-private.h b/shell/ev-view-private.h index d1edfa66..e839a315 100644 --- a/shell/ev-view-private.h +++ b/shell/ev-view-private.h @@ -26,6 +26,7 @@ #include "ev-page-cache.h" #include "ev-image.h" #include "ev-form-field.h" +#include "ev-selection.h" /* Information for middle clicking and moving around the doc */ typedef struct { @@ -41,6 +42,7 @@ typedef struct { GdkPoint start; gboolean in_selection; GList *selections; + EvSelectionStyle style; } SelectionInfo; /* Information for handling images DND */ diff --git a/shell/ev-view.c b/shell/ev-view.c index b3bd531f..cbdffd80 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -32,7 +32,6 @@ #include "ev-view.h" #include "ev-view-private.h" #include "ev-utils.h" -#include "ev-selection.h" #include "ev-document-links.h" #include "ev-document-images.h" #include "ev-document-find.h" @@ -315,6 +314,7 @@ static void jump_to_find_page (EvView /*** Selection ***/ static void compute_selections (EvView *view, + EvSelectionStyle style, GdkPoint *start, GdkPoint *stop); static void clear_selection (EvView *view); @@ -2594,6 +2594,32 @@ ev_view_query_tooltip (GtkWidget *widget, } #endif /* GTK_CHECK_VERSION (2, 11, 7) */ +static void +start_selection_for_event (EvView *view, + GdkEventButton *event) +{ + EvSelectionStyle style; + + clear_selection (view); + + view->selection_info.start.x = event->x + view->scroll_x; + view->selection_info.start.y = event->y + view->scroll_y; + + switch (event->type) { + case GDK_2BUTTON_PRESS: + style = EV_SELECTION_STYLE_WORD; + break; + case GDK_3BUTTON_PRESS: + style = EV_SELECTION_STYLE_LINE; + break; + default: + style = EV_SELECTION_STYLE_GLYPH; + break; + } + + view->selection_info.style = style; +} + static gboolean ev_view_button_press_event (GtkWidget *widget, GdkEventButton *event) @@ -2615,18 +2641,17 @@ ev_view_button_press_event (GtkWidget *widget, EvImage *image; EvFormField *field; - if (view->selection_info.selections) { - if (location_in_selected_text (view, + if (EV_IS_SELECTION (view->document) && view->selection_info.selections) { + if (event->type == GDK_3BUTTON_PRESS) { + start_selection_for_event (view, event); + } else if (location_in_selected_text (view, event->x + view->scroll_x, event->y + view->scroll_y)) { view->selection_info.in_drag = TRUE; } else { - clear_selection (view); - - view->selection_info.start.x = event->x + view->scroll_x; - view->selection_info.start.y = event->y + view->scroll_y; + start_selection_for_event (view, event); } - + gtk_widget_queue_draw (widget); } else if (!location_in_text (view, event->x + view->scroll_x, event->y + view->scroll_y) && (image = ev_view_get_image_at_location (view, event->x, event->y))) { @@ -2642,8 +2667,9 @@ ev_view_button_press_event (GtkWidget *widget, ev_view_handle_form_field (view, field, event->x, event->y); } else { ev_view_remove_all (view); - view->selection_info.start.x = event->x + view->scroll_x; - view->selection_info.start.y = event->y + view->scroll_y; + + if (EV_IS_SELECTION (view->document)) + start_selection_for_event (view, event); } } return TRUE; @@ -2690,16 +2716,14 @@ ev_view_drag_data_get (GtkWidget *widget, switch (info) { case TARGET_DND_TEXT: - if (view->selection_info.selections && - ev_document_can_get_text (view->document)) { + if (EV_IS_SELECTION (view->document) && + view->selection_info.selections) { gchar *text; text = get_selected_text (view); - gtk_selection_data_set_text (selection_data, text, strlen (text)); - g_free (text); } break; @@ -2780,7 +2804,10 @@ ev_view_drag_data_received (GtkWidget *widget, static gboolean selection_update_idle_cb (EvView *view) { - compute_selections (view, &view->selection_info.start, &view->motion); + compute_selections (view, + view->selection_info.style, + &view->selection_info.start, + &view->motion); view->selection_update_id = 0; return FALSE; } @@ -2979,6 +3006,14 @@ ev_view_button_release_event (GtkWidget *widget, view->selection_update_id = 0; } + if (!view->selection_info.in_selection && + view->selection_info.style != EV_SELECTION_STYLE_GLYPH) { + compute_selections (view, + view->selection_info.style, + &(view->selection_info.start), + &(view->selection_info.start)); + } + if (view->selection_info.selections) { ev_view_update_primary_selection (view); @@ -5061,9 +5096,10 @@ gdk_rectangle_point_in (GdkRectangle *rectangle, } static GList * -compute_new_selection_text (EvView *view, - GdkPoint *start, - GdkPoint *stop) +compute_new_selection_text (EvView *view, + EvSelectionStyle style, + GdkPoint *start, + GdkPoint *stop) { int n_pages, i, first, last; GList *list = NULL; @@ -5118,6 +5154,7 @@ compute_new_selection_text (EvView *view, selection = g_new0 (EvViewSelection, 1); selection->page = i; + selection->style = style; selection->rect.x1 = selection->rect.y1 = 0; selection->rect.x2 = width; selection->rect.y2 = height; @@ -5275,16 +5312,17 @@ merge_selection_region (EvView *view, } static void -compute_selections (EvView *view, - GdkPoint *start, - GdkPoint *stop) +compute_selections (EvView *view, + EvSelectionStyle style, + GdkPoint *start, + GdkPoint *stop) { GList *list; if (view->selection_mode == EV_VIEW_SELECTION_RECTANGLE) list = compute_new_selection_rect (view, start, stop); else - list = compute_new_selection_text (view, start, stop); + list = compute_new_selection_text (view, style, start, stop); merge_selection_region (view, list); } @@ -5309,10 +5347,10 @@ clear_selection (EvView *view) g_object_notify (G_OBJECT (view), "has-selection"); } - void ev_view_select_all (EvView *view) { + GList *selections = NULL; int n_pages, i; /* Disable selection on rotated pages for the 0.4.0 series */ @@ -5320,7 +5358,7 @@ ev_view_select_all (EvView *view) return; clear_selection (view); - + n_pages = ev_page_cache_get_n_pages (view->page_cache); for (i = 0; i < n_pages; i++) { int width, height; @@ -5333,15 +5371,15 @@ ev_view_select_all (EvView *view) selection = g_new0 (EvViewSelection, 1); selection->page = i; + selection->style = EV_SELECTION_STYLE_GLYPH; selection->rect.x1 = selection->rect.y1 = 0; selection->rect.x2 = width; selection->rect.y2 = height; - view->selection_info.selections = g_list_append (view->selection_info.selections, selection); + selections = g_list_append (selections, selection); } - ev_pixbuf_cache_set_selection_list (view->pixbuf_cache, view->selection_info.selections); - g_object_notify (G_OBJECT (view), "has-selection"); + merge_selection_region (view, selections); gtk_widget_queue_draw (GTK_WIDGET (view)); } @@ -5352,29 +5390,35 @@ ev_view_get_has_selection (EvView *view) } static char * -get_selected_text (EvView *ev_view) +get_selected_text (EvView *view) { GString *text; GList *l; gchar *normalized_text; + EvRenderContext *rc; text = g_string_new (NULL); + rc = ev_render_context_new (view->rotation, 1, view->scale); ev_document_doc_mutex_lock (); - for (l = ev_view->selection_info.selections; l != NULL; l = l->next) { + for (l = view->selection_info.selections; l != NULL; l = l->next) { EvViewSelection *selection = (EvViewSelection *)l->data; - char *tmp; + gchar *tmp; + + ev_render_context_set_page (rc, selection->page); + tmp = ev_selection_get_selected_text (EV_SELECTION (view->document), + rc, selection->style, + &(selection->rect)); - tmp = ev_document_get_text (ev_view->document, - selection->page, - &selection->rect); g_string_append (text, tmp); g_free (tmp); } ev_document_doc_mutex_unlock (); + g_object_unref (rc); + normalized_text = g_utf8_normalize (text->str, text->len, G_NORMALIZE_NFKC); g_string_free (text, TRUE); return normalized_text; @@ -5386,9 +5430,8 @@ ev_view_copy (EvView *ev_view) GtkClipboard *clipboard; char *text; - if (!ev_document_can_get_text (ev_view->document)) { + if (!EV_IS_SELECTION (ev_view->document)) return; - } text = get_selected_text (ev_view); clipboard = gtk_widget_get_clipboard (GTK_WIDGET (ev_view), @@ -5406,9 +5449,8 @@ ev_view_primary_get_cb (GtkClipboard *clipboard, EvView *ev_view = EV_VIEW (data); char *text; - if (!ev_document_can_get_text (ev_view->document)) { + if (!EV_IS_SELECTION (ev_view->document)) return; - } text = get_selected_text (ev_view); if (text) { diff --git a/shell/ev-window.c b/shell/ev-window.c index 9081b855..81b303f3 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -316,7 +316,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) has_properties = FALSE; } - if (has_document && ev_document_can_get_text (document)) { + if (has_document && EV_IS_SELECTION (document)) { can_get_text = TRUE; } -- 2.43.5