+ case EV_LINK_ACTION_TYPE_LAUNCH:
+ msg = g_strdup_printf (_("Launch %s"),
+ ev_link_action_get_filename (action));
+ break;
+ case EV_LINK_ACTION_TYPE_NAMED:
+ msg = tip_from_action_named (action);
+ break;
+ default:
+ if (title)
+ msg = g_strdup (title);
+ break;
+ }
+
+ return msg;
+}
+
+static void
+ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
+{
+ EvLink *link;
+ EvFormField *field;
+
+ if (view->cursor == EV_VIEW_CURSOR_HIDDEN)
+ return;
+
+ if (view->drag_info.in_drag) {
+ if (view->cursor != EV_VIEW_CURSOR_DRAG)
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG);
+ return;
+ }
+
+ if (view->scroll_info.autoscrolling) {
+ if (view->cursor != EV_VIEW_CURSOR_AUTOSCROLL)
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_AUTOSCROLL);
+ return;
+ }
+
+ link = ev_view_get_link_at_location (view, x, y);
+
+#if !GTK_CHECK_VERSION (2, 11, 7)
+ if (view->link_tooltip == NULL) {
+ view->link_tooltip = ev_tooltip_new (GTK_WIDGET (view));
+ }
+
+ if (view->hovered_link != link) {
+ view->hovered_link = link;
+ ev_tooltip_deactivate (EV_TOOLTIP (view->link_tooltip));
+ }
+#endif
+
+ if (link) {
+#if GTK_CHECK_VERSION (2, 11, 7)
+ g_object_set (view, "has-tooltip", TRUE, NULL);
+#else
+ char *msg = tip_from_link (view, link);
+
+ if (msg && g_utf8_validate (msg, -1, NULL)) {
+ EvTooltip *tooltip = EV_TOOLTIP (view->link_tooltip);
+
+ ev_tooltip_set_position (tooltip, x, y);
+ ev_tooltip_set_text (tooltip, msg);
+ ev_tooltip_activate (tooltip);
+ }
+ g_free (msg);
+#endif
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+ } else if ((field = ev_view_get_form_field_at_location (view, x, y))) {
+ if (field->is_read_only) {
+ if (view->cursor == EV_VIEW_CURSOR_LINK ||
+ view->cursor == EV_VIEW_CURSOR_IBEAM ||
+ view->cursor == EV_VIEW_CURSOR_DRAG)
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
+ } else if (EV_IS_FORM_FIELD_TEXT (field)) {
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM);
+ } else {
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+ }
+ } else if (location_in_text (view, x + view->scroll_x, y + view->scroll_y)) {
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM);
+ } else {
+ if (view->cursor == EV_VIEW_CURSOR_LINK ||
+ view->cursor == EV_VIEW_CURSOR_IBEAM ||
+ view->cursor == EV_VIEW_CURSOR_DRAG ||
+ view->cursor == EV_VIEW_CURSOR_AUTOSCROLL)
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
+ }
+}
+
+/*** Images ***/
+static EvImage *
+ev_view_get_image_at_location (EvView *view,
+ gdouble x,
+ gdouble y)
+{
+ gint page = -1;
+ gint x_offset = 0, y_offset = 0;
+ gint x_new = 0, y_new = 0;
+ GList *image_mapping;
+
+ if (!EV_IS_DOCUMENT_IMAGES (view->document))
+ return NULL;
+
+ x += view->scroll_x;
+ y += view->scroll_y;
+
+ find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
+
+ if (page == -1)
+ return NULL;
+
+ if (get_doc_point_from_offset (view, page, x_offset,
+ y_offset, &x_new, &y_new) == FALSE)
+ return NULL;
+
+ image_mapping = ev_pixbuf_cache_get_image_mapping (view->pixbuf_cache, page);
+
+ if (image_mapping)
+ return ev_image_mapping_find (image_mapping, x_new, y_new);
+ else
+ return NULL;
+}
+
+/*** Forms ***/
+static EvFormField *
+ev_view_get_form_field_at_location (EvView *view,
+ gdouble x,
+ gdouble y)
+{
+ gint page = -1;
+ gint x_offset = 0, y_offset = 0;
+ gint x_new = 0, y_new = 0;
+ GList *forms_mapping;
+
+ if (!EV_IS_DOCUMENT_FORMS (view->document))
+ return NULL;
+
+ x += view->scroll_x;
+ y += view->scroll_y;
+
+ find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
+
+ if (page == -1)
+ return NULL;
+
+ if (get_doc_point_from_offset (view, page, x_offset,
+ y_offset, &x_new, &y_new) == FALSE)
+ return NULL;
+
+ forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache, page);
+
+ if (forms_mapping)
+ return ev_form_field_mapping_find (forms_mapping, x_new, y_new);
+ else
+ return NULL;
+}
+
+static GdkRegion *
+ev_view_form_field_get_region (EvView *view,
+ EvFormField *field)
+{
+ EvRectangle field_area;
+ GdkRectangle view_area;
+ GList *forms_mapping;
+
+ forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
+ field->page);
+ ev_form_field_mapping_get_area (forms_mapping, field, &field_area);
+ doc_rect_to_view_rect (view, field->page, &field_area, &view_area);
+ view_area.x -= view->scroll_x;
+ view_area.y -= view->scroll_y;
+
+ return gdk_region_rectangle (&view_area);
+}
+
+static gboolean
+ev_view_forms_remove_widgets (EvView *view)
+{
+ ev_view_remove_all (view);
+
+ return FALSE;
+}
+
+static void
+ev_view_form_field_destroy (GtkWidget *widget,
+ EvView *view)
+{
+ g_idle_add ((GSourceFunc)ev_view_forms_remove_widgets, view);
+}
+
+static GtkWidget *
+ev_view_form_field_button_create_widget (EvView *view,
+ EvFormField *field)
+{
+ EvFormFieldButton *field_button = EV_FORM_FIELD_BUTTON (field);
+ GdkRegion *field_region = NULL;
+
+ switch (field_button->type) {
+ case EV_FORM_FIELD_BUTTON_PUSH:
+ return NULL;
+ case EV_FORM_FIELD_BUTTON_CHECK:
+ case EV_FORM_FIELD_BUTTON_RADIO: {
+ gboolean state;
+ GList *forms_mapping, *l;
+
+ state = ev_document_forms_form_field_button_get_state (EV_DOCUMENT_FORMS (view->document),
+ field);
+
+ /* FIXME: it actually depends on NoToggleToOff flags */
+ if (field_button->type == EV_FORM_FIELD_BUTTON_RADIO &&
+ state && field_button->state)
+ return NULL;
+
+ field_region = ev_view_form_field_get_region (view, field);
+
+ /* For radio buttons and checkbox buttons that are in a set
+ * we need to update also the region for the current selected item
+ */
+ forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
+ field->page);
+ for (l = forms_mapping; l; l = g_list_next (l)) {
+ EvFormField *button = ((EvFormFieldMapping *)(l->data))->field;
+ GdkRegion *button_region;
+
+ if (button->id == field->id)
+ continue;
+
+ /* FIXME: only buttons in the same group should be updated */
+ if (!EV_IS_FORM_FIELD_BUTTON (button) ||
+ EV_FORM_FIELD_BUTTON (button)->type != field_button->type ||
+ EV_FORM_FIELD_BUTTON (button)->state != TRUE)
+ continue;
+
+ button_region = ev_view_form_field_get_region (view, button);
+ gdk_region_union (field_region, button_region);
+ gdk_region_destroy (button_region);
+ }
+
+ ev_document_forms_form_field_button_set_state (EV_DOCUMENT_FORMS (view->document),
+ field, !state);
+ field_button->state = !state;
+ }