]> www.fi.muni.cz Git - evince.git/commitdiff
Beginnings of clipboard support. Incomplete but primary sort of work.
authorMarco Pesenti Gritti <marco@gnome.org>
Wed, 5 Jan 2005 15:10:04 +0000 (15:10 +0000)
committerMarco Pesenti Gritti <marco@src.gnome.org>
Wed, 5 Jan 2005 15:10:04 +0000 (15:10 +0000)
2005-01-05  Marco Pesenti Gritti  <marco@gnome.org>

        * backend/ev-document.c: (ev_document_get_text):
        * backend/ev-document.h:
        * pdf/xpdf/pdf-document.cc:
        * shell/ev-view.c: (ev_view_realize), (expose_bin_window),
        (ev_view_primary_get_cb), (ev_view_primary_clear_cb),
        (ev_view_update_primary_selection), (ev_view_button_press_event),
        (ev_view_motion_notify_event), (ev_view_button_release_event):

        Beginnings of clipboard support. Incomplete but primary sort
        of work.

ChangeLog
backend/ev-document.c
backend/ev-document.h
pdf/xpdf/pdf-document.cc
shell/ev-view.c

index 8f4074c3245c11dd4ce4fef5071dd140e4e62571..5ea38fb90018368f0cd2d76cb31706e90db92528 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-01-05  Marco Pesenti Gritti  <marco@gnome.org>
+
+       * backend/ev-document.c: (ev_document_get_text):
+       * backend/ev-document.h:
+       * pdf/xpdf/pdf-document.cc:
+       * shell/ev-view.c: (ev_view_realize), (expose_bin_window),
+       (ev_view_primary_get_cb), (ev_view_primary_clear_cb),
+       (ev_view_update_primary_selection), (ev_view_button_press_event),
+       (ev_view_motion_notify_event), (ev_view_button_release_event):
+
+       Beginnings of clipboard support. Incomplete but primary sort
+       of work.
+
 2005-01-05  Marco Pesenti Gritti  <marco@gnome.org>
 
        * shell/ev-view.c: (ev_gdk_color_to_rgb), (draw_rubberband),
index 2306a21a1b24796aa2bfb27e680205320276d2e1..f0075466bbfd84c783bbeb2d8b8db042cc4ea246 100644 (file)
@@ -161,6 +161,14 @@ ev_document_get_page_size   (EvDocument   *document,
        iface->get_page_size (document, width, height);
 }
 
+char *
+ev_document_get_text (EvDocument   *document,
+                     GdkRectangle *rect)
+{
+       EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
+       return iface->get_text (document, rect);
+}
+
 void
 ev_document_render (EvDocument  *document,
                    int          clip_x,
index c0a4b46c09c40c6dca94ed8ec5983a50f5dcbbc9..ebf60af636d13b0c9bb7d5a7060343f28ced84a5 100644 (file)
@@ -46,31 +46,33 @@ struct _EvDocumentIface
        void        (* changed)         (EvDocument *document);
 
        /* Methods  */
-       gboolean    (* load)            (EvDocument *document,
-                                        const char *uri,
-                                        GError    **error);
-       gboolean    (* save)            (EvDocument *document,
-                                        const char *uri,
-                                        GError    **error);
-       int         (* get_n_pages)     (EvDocument *document);
-       void        (* set_page)        (EvDocument  *document,
-                                        int          page);
-       int         (* get_page)        (EvDocument  *document);
-       void        (* set_target)      (EvDocument  *document,
-                                        GdkDrawable *target);
-       void        (* set_scale)       (EvDocument  *document,
-                                        double       scale);
-       void        (* set_page_offset) (EvDocument  *document,
-                                        int          x,
-                                        int          y);
-       void        (* get_page_size)   (EvDocument  *document,
-                                        int         *width,
-                                        int         *height);
-       void        (* render)          (EvDocument  *document,
-                                        int          clip_x,
-                                        int          clip_y,
-                                        int          clip_width,
-                                        int          clip_height);
+       gboolean    (* load)            (EvDocument   *document,
+                                        const char   *uri,
+                                        GError      **error);
+       gboolean    (* save)            (EvDocument   *document,
+                                        const char   *uri,
+                                        GError      **error);
+       int         (* get_n_pages)     (EvDocument   *document);
+       void        (* set_page)        (EvDocument   *document,
+                                        int           page);
+       int         (* get_page)        (EvDocument   *document);
+       void        (* set_target)      (EvDocument   *document,
+                                        GdkDrawable  *target);
+       void        (* set_scale)       (EvDocument   *document,
+                                        double        scale);
+       void        (* set_page_offset) (EvDocument   *document,
+                                        int           x,
+                                        int           y);
+       void        (* get_page_size)   (EvDocument   *document,
+                                        int          *width,
+                                        int          *height);
+       char      * (* get_text)        (EvDocument   *document,
+                                        GdkRectangle *rect);
+       void        (* render)          (EvDocument   *document,
+                                        int           clip_x,
+                                        int           clip_y,
+                                        int           clip_width,
+                                        int           clip_height);
 };
 
 GType ev_document_get_type (void);
@@ -96,6 +98,8 @@ void     ev_document_set_page_offset (EvDocument   *document,
 void     ev_document_get_page_size   (EvDocument   *document,
                                      int          *width,
                                      int          *height);
+char    *ev_document_get_text       (EvDocument   *document,
+                                     GdkRectangle *rect);
 void     ev_document_render          (EvDocument   *document,
                                      int           clip_x,
                                      int           clip_y,
index ed3b5054b06a501174331aed7d02c064eba98c92..2293841fd2e6709433f906311eb27126c5400687 100644 (file)
@@ -959,6 +959,25 @@ pdf_document_get_title (PdfDocument *pdf_document)
        return title;
 }
 
+static char *
+pdf_document_get_text (EvDocument *document, GdkRectangle *rect)
+{
+       PdfDocument *pdf_document = PDF_DOCUMENT (document);
+       GString *sel_text = new GString;
+       const char *text;
+       int x1, y1, x2, y2;
+
+       x1 = rect->x;
+       y1 = rect->y;
+       x2 = x1 + rect->width;
+       y2 = y1 + rect->height;
+
+       sel_text = pdf_document->out->getText (x1, y1, x2, y2);
+       text = sel_text->getCString ();
+
+       return text ? g_strdup (text) : NULL;
+}
+
 static void
 pdf_document_get_property (GObject *object,
                           guint prop_id,
@@ -995,6 +1014,7 @@ pdf_document_document_iface_init (EvDocumentIface *iface)
 {
        iface->load = pdf_document_load;
        iface->save = pdf_document_save;
+       iface->get_text = pdf_document_get_text;
        iface->get_n_pages = pdf_document_get_n_pages;
        iface->set_page = pdf_document_set_page;
        iface->get_page = pdf_document_get_page;
index 8616fea96ae4d4646f2fdcdf6d30c93ee7a02f87..bd50b38b6c0209e428d31b159ef3ea2ead5461ac 100644 (file)
@@ -21,6 +21,8 @@
 #include <gtk/gtkalignment.h>
 #include <glib/gi18n.h>
 #include <gtk/gtkbindings.h>
+#include <gtk/gtkselection.h>
+#include <gtk/gtkclipboard.h>
 #include <gdk/gdkkeysyms.h>
 
 #include "ev-marshal.h"
 #define EV_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_VIEW))
 #define EV_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_VIEW, EvViewClass))
 
+enum {
+  TARGET_STRING,
+  TARGET_TEXT,
+  TARGET_COMPOUND_TEXT,
+  TARGET_UTF8_STRING,
+  TARGET_TEXT_BUFFER_CONTENTS
+};
+
+static const GtkTargetEntry targets[] = {
+       { "STRING", 0, TARGET_STRING },
+       { "TEXT",   0, TARGET_TEXT },
+       { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
+       { "UTF8_STRING", 0, TARGET_UTF8_STRING },
+};
+
 struct _EvView {
        GtkWidget parent_instance;
 
@@ -41,6 +58,9 @@ struct _EvView {
        int scroll_x;
        int scroll_y;
 
+       gboolean has_selection;
+       GdkRectangle selection;
+
        GtkAdjustment *hadjustment;
        GtkAdjustment *vadjustment;
 
@@ -247,8 +267,10 @@ ev_view_realize (GtkWidget *widget)
        attributes.height = MAX (widget->allocation.height, widget->requisition.height);
        attributes.event_mask = GDK_EXPOSURE_MASK |
                                GDK_BUTTON_PRESS_MASK |
+                               GDK_BUTTON_RELEASE_MASK |
                                GDK_SCROLL_MASK |
-                               GDK_KEY_PRESS_MASK;
+                               GDK_KEY_PRESS_MASK |
+                               GDK_BUTTON1_MOTION_MASK;
   
        view->bin_window = gdk_window_new (widget->window,
                                           &attributes,
@@ -379,6 +401,10 @@ expose_bin_window (GtkWidget      *widget,
                                         &results[i].highlight_area);
                 ++i;
         }
+
+       if (view->has_selection) {
+               draw_rubberband (widget, view->bin_window, &view->selection);
+       }
 }
 
 static gboolean
@@ -395,14 +421,67 @@ ev_view_expose_event (GtkWidget      *widget,
        return FALSE;
 }
 
+static void
+ev_view_primary_get_cb (GtkClipboard     *clipboard,
+                       GtkSelectionData *selection_data,
+                       guint             info,
+                       gpointer          data)
+{
+       EvView *ev_view = EV_VIEW (data);
+       char *text;
+
+       text = ev_document_get_text (ev_view->document, &ev_view->selection);
+       gtk_selection_data_set_text (selection_data, text, -1);
+}
+
+static void
+ev_view_primary_clear_cb (GtkClipboard *clipboard,
+                         gpointer      data)
+{
+       EvView *ev_view = EV_VIEW (data);
+
+       ev_view->has_selection = FALSE;
+}
+
+static void
+ev_view_update_primary_selection (EvView *ev_view)
+{
+       GtkClipboard *clipboard;
+
+       clipboard = gtk_widget_get_clipboard (GTK_WIDGET (ev_view),
+                                              GDK_SELECTION_PRIMARY);
+
+       if (ev_view->has_selection) {
+               if (!gtk_clipboard_set_with_owner (clipboard,
+                                                  targets,
+                                                  G_N_ELEMENTS (targets),
+                                                  ev_view_primary_get_cb,
+                                                  ev_view_primary_clear_cb,
+                                                  G_OBJECT (ev_view)))
+                       ev_view_primary_clear_cb (clipboard, ev_view);
+       } else {
+               if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (ev_view))
+                       gtk_clipboard_clear (clipboard);
+       }
+}
+
 static gboolean
 ev_view_button_press_event (GtkWidget      *widget,
                            GdkEventButton *event)
 {
-       if (event->type == GDK_BUTTON_PRESS) {
-               if (!GTK_WIDGET_HAS_FOCUS (widget)) {
-                       gtk_widget_grab_focus (widget);
-               }
+       EvView *view = EV_VIEW (widget);
+
+       if (!GTK_WIDGET_HAS_FOCUS (widget)) {
+               gtk_widget_grab_focus (widget);
+       }
+
+       switch (event->button) {
+               case 1:
+                       view->selection.x = event->x;
+                       view->selection.y = event->y;
+                       view->selection.width = 0;
+                       view->selection.height = 0;
+                       break;
        }
 
        return TRUE;
@@ -412,16 +491,26 @@ static gboolean
 ev_view_motion_notify_event (GtkWidget      *widget,
                             GdkEventMotion *event)
 {
-       /* EvView *view = EV_VIEW (widget); */
-  
-       return FALSE;
+       EvView *view = EV_VIEW (widget);
+
+       view->has_selection = TRUE;
+       view->selection.x = MIN (view->selection.x, event->x);
+       view->selection.y = MIN (view->selection.y, event->y);
+       view->selection.width = ABS (view->selection.x - event->x) + 1;
+       view->selection.height = ABS (view->selection.y - event->y) + 1;
+
+       gtk_widget_queue_draw (widget);
+
+       return TRUE;
 }
 
 static gboolean
 ev_view_button_release_event (GtkWidget      *widget,
                              GdkEventButton *event)
 {
-       /* EvView *view = EV_VIEW (widget); */
+       EvView *view = EV_VIEW (widget);
+
+       ev_view_update_primary_selection (view);
 
        return FALSE;
 }