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);
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,
#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;
int scroll_x;
int scroll_y;
+ gboolean has_selection;
+ GdkRectangle selection;
+
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
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,
&results[i].highlight_area);
++i;
}
+
+ if (view->has_selection) {
+ draw_rubberband (widget, view->bin_window, &view->selection);
+ }
}
static gboolean
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;
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;
}