- if (event->window == view->bin_window)
- ev_view_bin_expose (view, event);
- else
- return GTK_WIDGET_CLASS (ev_view_parent_class)->expose_event (widget, event);
-
- return FALSE;
-}
-
-void
-ev_view_select_all (EvView *ev_view)
-{
- GtkWidget *widget = GTK_WIDGET (ev_view);
- GdkRectangle selection;
- int width, height;
- int x_offset, y_offset;
-
- g_return_if_fail (EV_IS_VIEW (ev_view));
-
-
- ev_view_get_offsets (ev_view, &x_offset, &y_offset);
- ev_page_cache_get_size (ev_view->page_cache,
- ev_view->current_page,
- ev_view->scale,
- &width, &height);
-
- ev_view->has_selection = TRUE;
- selection.x = x_offset + ev_view->border.left;
- selection.y = y_offset + ev_view->border.top;
- selection.width = width;
- selection.height = height;
- view_rect_to_doc_rect (ev_view, &selection, &ev_view->selection);
-
- gtk_widget_queue_draw (widget);
-}
-
-void
-ev_view_copy (EvView *ev_view)
-{
- GtkClipboard *clipboard;
- char *text;
-
- if (!ev_document_can_get_text (ev_view->document)) {
- return;
- }
-
- ev_document_doc_mutex_lock ();
- text = ev_document_get_text (ev_view->document,
- ev_view->current_page,
- &ev_view->selection);
- ev_document_doc_mutex_unlock ();
-
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET (ev_view),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, text, -1);
- g_free (text);
-}
-
-static void
-ev_view_primary_get_cb (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer data)
-{
- EvView *ev_view = EV_VIEW (data);
- char *text;
-
- if (!ev_document_can_get_text (ev_view->document)) {
- return;
- }
-
- ev_document_doc_mutex_lock ();
- text = ev_document_get_text (ev_view->document,
- ev_view->current_page,
- &ev_view->selection);
- ev_document_doc_mutex_unlock ();
- 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)
-{
- EvView *view = EV_VIEW (widget);
-
- if (!GTK_WIDGET_HAS_FOCUS (widget)) {
- gtk_widget_grab_focus (widget);
- }
-
- view->pressed_button = event->button;
-
- switch (event->button) {
- case 1:
- if (view->has_selection) {
- view->has_selection = FALSE;
- gtk_widget_queue_draw (widget);
- }
-
- view->selection_start.x = event->x;
- view->selection_start.y = event->y;
- break;
- }
-
- return TRUE;
-}
-
-static char *
-status_message_from_link (EvView *view, EvLink *link)
-{
- EvLinkType type;
- char *msg = NULL;
- char *page_label;
-
- type = ev_link_get_link_type (link);
-
- switch (type) {
- case EV_LINK_TYPE_TITLE:
- if (ev_link_get_title (link))
- msg = g_strdup (ev_link_get_title (link));
- break;
- case EV_LINK_TYPE_PAGE:
- page_label = ev_page_cache_get_page_label (view->page_cache, ev_link_get_page (link));
- msg = g_strdup_printf (_("Go to page %s"), page_label);
- g_free (page_label);
- break;
- case EV_LINK_TYPE_EXTERNAL_URI:
- msg = g_strdup (ev_link_get_uri (link));
- break;
- default:
- break;
- }
-
- return msg;
-}
-
-static void
-ev_view_set_status (EvView *view, const char *message)
-{
- g_return_if_fail (EV_IS_VIEW (view));
-
- if (message != view->status) {
- g_free (view->status);
- view->status = g_strdup (message);
- g_object_notify (G_OBJECT (view), "status");
- }
-}
-
-static void
-ev_view_set_find_status (EvView *view, const char *message)
-{
- g_return_if_fail (EV_IS_VIEW (view));
-
- g_free (view->find_status);
- view->find_status = g_strdup (message);
- g_object_notify (G_OBJECT (view), "find-status");
-}
-
-static GdkCursor *
-ev_view_create_invisible_cursor(void)
-{
- GdkBitmap *empty;
- GdkColor black = { 0, 0, 0, 0 };
- static char bits[] = { 0x00 };
-
- empty = gdk_bitmap_create_from_data (NULL, bits, 1, 1);
-
- return gdk_cursor_new_from_pixmap (empty, empty, &black, &black, 0, 0);
-}
-
-static void
-ev_view_set_cursor (EvView *view, EvViewCursor new_cursor)
-{
- GdkCursor *cursor = NULL;
- GdkDisplay *display;
- GtkWidget *widget;
-
- if (view->cursor == new_cursor) {
- return;
- }
-
- widget = gtk_widget_get_toplevel (GTK_WIDGET (view));
- display = gtk_widget_get_display (widget);
- view->cursor = new_cursor;
-
- switch (new_cursor) {
- case EV_VIEW_CURSOR_NORMAL:
- gdk_window_set_cursor (widget->window, NULL);
- break;
- case EV_VIEW_CURSOR_LINK:
- cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
- break;
- case EV_VIEW_CURSOR_WAIT:
- cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
- break;
- case EV_VIEW_CURSOR_HIDDEN:
- cursor = ev_view_create_invisible_cursor ();
- break;
-
- }
-
- if (cursor) {
- gdk_window_set_cursor (widget->window, cursor);
- gdk_cursor_unref (cursor);
- gdk_flush();
- }
-}
-
-
-static void
-find_page_at_location (EvView *view,
- gdouble x,
- gdouble y,
- gint *page,
- gint *x_offset,
- gint *y_offset)
-{
- int i;
-
- if (view->document == NULL)
- return;
-
- g_assert (page);
- g_assert (x_offset);
- g_assert (y_offset);
-
- for (i = view->start_page; i <= view->end_page; i++) {
- GdkRectangle page_area;
- GtkBorder border;
-
- if (! get_page_extents (view, i, &page_area, &border))
- continue;
-
- if ((x >= page_area.x + border.left) &&
- (x < page_area.x + page_area.width - border.right) &&
- (y >= page_area.y + border.top) &&
- (y < page_area.y + page_area.height - border.bottom)) {
- *page = i;
- *x_offset = x - (page_area.x + border.left);
- *y_offset = y - (page_area.y + border.top);
- return;
- }
- }
-
- *page = -1;
-}
-
-static EvLink *
-get_link_at_location (EvView *view,
- gdouble x,
- gdouble y)
-{
- gint page = -1;
- gint x_offset = 0, y_offset = 0;
- GList *link_mapping;
-
- find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
-
- if (page == -1)
- return NULL;
-
- link_mapping = ev_pixbuf_cache_get_link_mapping (view->pixbuf_cache, page);
-
- if (link_mapping)
- return ev_link_mapping_find (link_mapping, x_offset / view->scale, y_offset / view->scale);
- else
- return NULL;
-}
-
-
-static gboolean
-ev_view_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event)
-{
- EvView *view = EV_VIEW (widget);
-
- if (view->pressed_button > 0) {
- GdkRectangle selection;
-
- view->has_selection = TRUE;
- selection.x = MIN (view->selection_start.x, event->x);
- selection.y = MIN (view->selection_start.y, event->y);
- selection.width = ABS (view->selection_start.x - event->x) + 1;
- selection.height = ABS (view->selection_start.y - event->y) + 1;
- view_rect_to_doc_rect (view, &selection, &view->selection);
-
- gtk_widget_queue_draw (widget);
- } else if (view->document) {
- EvLink *link;
-
- link = get_link_at_location (view, event->x, event->y);
- if (link) {
- char *msg;
-
- msg = status_message_from_link (view, link);
- ev_view_set_status (view, msg);
- ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
- g_free (msg);
- } else {
- ev_view_set_status (view, NULL);
- if (view->cursor == EV_VIEW_CURSOR_LINK) {
- ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
- }
- }
- }
-
- return TRUE;
-}
-
-/* FIXME: standardize this sometime */
-static void
-go_to_link (EvView *view, EvLink *link)
-{
- EvLinkType type;
- const char *uri;
- int page;
-
- type = ev_link_get_link_type (link);
-
- switch (type) {
- case EV_LINK_TYPE_TITLE:
- break;
- case EV_LINK_TYPE_PAGE:
- page = ev_link_get_page (link);
- ev_page_cache_set_current_page (view->page_cache, page);
- break;
- case EV_LINK_TYPE_EXTERNAL_URI:
- uri = ev_link_get_uri (link);
- gnome_vfs_url_show (uri);
- break;
- }
-}
-
-
-static gboolean
-ev_view_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
-{
- EvView *view = EV_VIEW (widget);
-
- view->pressed_button = -1;
-
- if (view->has_selection) {
- ev_view_update_primary_selection (view);
- } else if (view->document) {
- EvLink *link;
-
- link = get_link_at_location (view, event->x, event->y);
- if (link) {
- go_to_link (view, link);
- }
- }
-
- return FALSE;
-}
-
-static void
-on_adjustment_value_changed (GtkAdjustment *adjustment,
- EvView *view)
-{
- view_update_adjustments (view);
-}
-
-static void
-set_scroll_adjustment (EvView *view,
- GtkOrientation orientation,
- GtkAdjustment *adjustment)
-{
- GtkAdjustment **to_set;
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- to_set = &view->hadjustment;
- else
- to_set = &view->vadjustment;
-
- if (*to_set != adjustment) {
- if (*to_set) {
- g_signal_handlers_disconnect_by_func (*to_set,
- (gpointer) on_adjustment_value_changed,
- view);
- g_object_unref (*to_set);
- }
-
- *to_set = adjustment;
- view_set_adjustment_values (view, orientation);
-
- if (*to_set) {
- g_object_ref (*to_set);
- g_signal_connect (*to_set, "value_changed",
- G_CALLBACK (on_adjustment_value_changed), view);
- }
- }
-}
-
-static void
-ev_view_set_scroll_adjustments (EvView *view,
- GtkAdjustment *hadjustment,
- GtkAdjustment *vadjustment)
-{
- set_scroll_adjustment (view, GTK_ORIENTATION_HORIZONTAL, hadjustment);
- set_scroll_adjustment (view, GTK_ORIENTATION_VERTICAL, vadjustment);
-
- view_update_adjustments (view);
-}