Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@gnome.org>2005-01-05 15:10:04 (GMT)
committer Marco Pesenti Gritti <marco@src.gnome.org>2005-01-05 15:10:04 (GMT)
commit9c1e6ba4d99cb7f937b2b3998814a7486b88c4ce (patch)
tree8ffa6e82aa7437c6c777a75bdc950b199b28cb27
parentc65e82ff717a6abb0474ab13e282a3ed6dafc5f7 (diff)
Beginnings of clipboard support. Incomplete but primary sort of work.
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.
-rw-r--r--ChangeLog13
-rw-r--r--backend/ev-document.c8
-rw-r--r--backend/ev-document.h54
-rw-r--r--pdf/xpdf/pdf-document.cc20
-rw-r--r--shell/ev-view.c107
5 files changed, 168 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f4074c..5ea38fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
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),
(expose_bin_window):
diff --git a/backend/ev-document.c b/backend/ev-document.c
index 2306a21..f007546 100644
--- a/backend/ev-document.c
+++ b/backend/ev-document.c
@@ -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,
diff --git a/backend/ev-document.h b/backend/ev-document.h
index c0a4b46..ebf60af 100644
--- a/backend/ev-document.h
+++ b/backend/ev-document.h
@@ -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,
diff --git a/pdf/xpdf/pdf-document.cc b/pdf/xpdf/pdf-document.cc
index ed3b505..2293841 100644
--- a/pdf/xpdf/pdf-document.cc
+++ b/pdf/xpdf/pdf-document.cc
@@ -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;
diff --git a/shell/ev-view.c b/shell/ev-view.c
index 8616fea..bd50b38 100644
--- a/shell/ev-view.c
+++ b/shell/ev-view.c
@@ -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"
@@ -31,6 +33,21 @@
#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;
}