]> www.fi.muni.cz Git - evince.git/blobdiff - libview/ev-view-presentation.c
Add support for external links to EvViewPresentation
[evince.git] / libview / ev-view-presentation.c
index fa79f1042bbc5e0d648453659c8f0cd832c33e48..914868a2b9692b384e3a8a3392582aee2a4b4cb2 100644 (file)
@@ -42,6 +42,7 @@ enum {
 enum {
        CHANGE_PAGE,
        FINISHED,
 enum {
        CHANGE_PAGE,
        FINISHED,
+        SIGNAL_EXTERNAL_LINK,
        N_SIGNALS
 };
 
        N_SIGNALS
 };
 
@@ -94,9 +95,11 @@ struct _EvViewPresentationClass
        GtkWidgetClass base_class;
 
        /* signals */
        GtkWidgetClass base_class;
 
        /* signals */
-       void (* change_page) (EvViewPresentation *pview,
-                             GtkScrollType       scroll);
-       void (* finished)    (EvViewPresentation *pview);
+       void (* change_page)   (EvViewPresentation *pview,
+                                GtkScrollType       scroll);
+       void (* finished)      (EvViewPresentation *pview);
+        void (* external_link) (EvViewPresentation *pview,
+                                EvLinkAction       *action);
 };
 
 static guint signals[N_SIGNALS] = { 0 };
 };
 
 static guint signals[N_SIGNALS] = { 0 };
@@ -111,18 +114,19 @@ static void ev_view_presentation_set_cursor_for_location (EvViewPresentation *pv
 
 G_DEFINE_TYPE (EvViewPresentation, ev_view_presentation, GTK_TYPE_WIDGET)
 
 
 G_DEFINE_TYPE (EvViewPresentation, ev_view_presentation, GTK_TYPE_WIDGET)
 
+static GdkRGBA black = { 0., 0., 0., 1. };
+static GdkRGBA white = { 1., 1., 1., 1. };
+
 static void
 ev_view_presentation_set_normal (EvViewPresentation *pview)
 {
        GtkWidget *widget = GTK_WIDGET (pview);
 static void
 ev_view_presentation_set_normal (EvViewPresentation *pview)
 {
        GtkWidget *widget = GTK_WIDGET (pview);
-       GtkStyle  *style;
 
        if (pview->state == EV_PRESENTATION_NORMAL)
                return;
 
        pview->state = EV_PRESENTATION_NORMAL;
 
        if (pview->state == EV_PRESENTATION_NORMAL)
                return;
 
        pview->state = EV_PRESENTATION_NORMAL;
-       style = gtk_widget_get_style (widget);
-       gdk_window_set_background (gtk_widget_get_window (widget), &style->black);
+       gdk_window_set_background_rgba (gtk_widget_get_window (widget), &black);
        gtk_widget_queue_draw (widget);
 }
 
        gtk_widget_queue_draw (widget);
 }
 
@@ -130,14 +134,12 @@ static void
 ev_view_presentation_set_black (EvViewPresentation *pview)
 {
        GtkWidget *widget = GTK_WIDGET (pview);
 ev_view_presentation_set_black (EvViewPresentation *pview)
 {
        GtkWidget *widget = GTK_WIDGET (pview);
-       GtkStyle  *style;
 
        if (pview->state == EV_PRESENTATION_BLACK)
                return;
 
        pview->state = EV_PRESENTATION_BLACK;
 
        if (pview->state == EV_PRESENTATION_BLACK)
                return;
 
        pview->state = EV_PRESENTATION_BLACK;
-       style = gtk_widget_get_style (widget);
-       gdk_window_set_background (gtk_widget_get_window (widget), &style->black);
+       gdk_window_set_background_rgba (gtk_widget_get_window (widget), &black);
        gtk_widget_queue_draw (widget);
 }
 
        gtk_widget_queue_draw (widget);
 }
 
@@ -145,14 +147,12 @@ static void
 ev_view_presentation_set_white (EvViewPresentation *pview)
 {
        GtkWidget *widget = GTK_WIDGET (pview);
 ev_view_presentation_set_white (EvViewPresentation *pview)
 {
        GtkWidget *widget = GTK_WIDGET (pview);
-       GtkStyle  *style;
 
        if (pview->state == EV_PRESENTATION_WHITE)
                return;
 
        pview->state = EV_PRESENTATION_WHITE;
 
        if (pview->state == EV_PRESENTATION_WHITE)
                return;
 
        pview->state = EV_PRESENTATION_WHITE;
-       style = gtk_widget_get_style (widget);
-       gdk_window_set_background (gtk_widget_get_window (widget), &style->white);
+       gdk_window_set_background_rgba (gtk_widget_get_window (widget), &white);
        gtk_widget_queue_draw (widget);
 }
 
        gtk_widget_queue_draw (widget);
 }
 
@@ -735,6 +735,9 @@ ev_view_presentation_link_is_supported (EvViewPresentation *pview,
        case EV_LINK_ACTION_TYPE_GOTO_DEST:
                return ev_link_action_get_dest (action) != NULL;
        case EV_LINK_ACTION_TYPE_NAMED:
        case EV_LINK_ACTION_TYPE_GOTO_DEST:
                return ev_link_action_get_dest (action) != NULL;
        case EV_LINK_ACTION_TYPE_NAMED:
+        case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
+        case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+        case EV_LINK_ACTION_TYPE_LAUNCH:
                return TRUE;
        default:
                return FALSE;
                return TRUE;
        default:
                return FALSE;
@@ -793,14 +796,15 @@ ev_view_presentation_get_link_at_location (EvViewPresentation *pview,
 }
 
 static void
 }
 
 static void
-ev_vew_presentation_goto_link_dest (EvViewPresentation *pview,
-                                   EvLink             *link)
+ev_vew_presentation_handle_link (EvViewPresentation *pview,
+                                 EvLink             *link)
 {
        EvLinkAction *action;
 
        action = ev_link_get_action (link);
 
 {
        EvLinkAction *action;
 
        action = ev_link_get_action (link);
 
-       if (ev_link_action_get_action_type (action) == EV_LINK_ACTION_TYPE_NAMED) {
+        switch (ev_link_action_get_action_type (action)) {
+       case EV_LINK_ACTION_TYPE_NAMED: {
                const gchar *name = ev_link_action_get_name (action);
 
                if (g_ascii_strcasecmp (name, "FirstPage") == 0) {
                const gchar *name = ev_link_action_get_name (action);
 
                if (g_ascii_strcasecmp (name, "FirstPage") == 0) {
@@ -815,13 +819,25 @@ ev_vew_presentation_goto_link_dest (EvViewPresentation *pview,
                        n_pages = ev_document_get_n_pages (pview->document);
                        ev_view_presentation_update_current_page (pview, n_pages - 1);
                }
                        n_pages = ev_document_get_n_pages (pview->document);
                        ev_view_presentation_update_current_page (pview, n_pages - 1);
                }
-       } else {
+        }
+                break;
+
+       case EV_LINK_ACTION_TYPE_GOTO_DEST: {
                EvLinkDest *dest;
                gint        page;
 
                dest = ev_link_action_get_dest (action);
                page = ev_document_links_get_dest_page (EV_DOCUMENT_LINKS (pview->document), dest);
                ev_view_presentation_update_current_page (pview, page);
                EvLinkDest *dest;
                gint        page;
 
                dest = ev_link_action_get_dest (action);
                page = ev_document_links_get_dest_page (EV_DOCUMENT_LINKS (pview->document), dest);
                ev_view_presentation_update_current_page (pview, page);
+        }
+                break;
+        case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
+        case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+        case EV_LINK_ACTION_TYPE_LAUNCH:
+                g_signal_emit (pview, signals[SIGNAL_EXTERNAL_LINK], 0, action);
+                break;
+        default:
+                break;
        }
 }
 
        }
 }
 
@@ -846,7 +862,7 @@ ev_view_presentation_set_cursor (EvViewPresentation *pview,
        gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
        gdk_flush ();
        if (cursor)
        gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
        gdk_flush ();
        if (cursor)
-               gdk_cursor_unref (cursor);
+               g_object_unref (cursor);
 }
 
 static void
 }
 
 static void
@@ -949,11 +965,19 @@ ev_view_presentation_dispose (GObject *object)
 }
 
 static void
 }
 
 static void
-ev_view_presentation_size_request (GtkWidget      *widget,
-                                  GtkRequisition *requisition)
+ev_view_presentation_get_preferred_width (GtkWidget *widget,
+                                          gint      *minimum,
+                                          gint      *natural)
+{
+        *minimum = *natural = 0;
+}
+
+static void
+ev_view_presentation_get_preferred_height (GtkWidget *widget,
+                                           gint      *minimum,
+                                           gint      *natural)
 {
 {
-       requisition->width = 0;
-       requisition->height = 0;
+        *minimum = *natural = 0;
 }
 
 static void
 }
 
 static void
@@ -984,15 +1008,8 @@ ev_view_presentation_draw_end_page (EvViewPresentation *pview,
        area.width = allocation.width;
        area.height = allocation.height;
 
        area.width = allocation.width;
        area.height = allocation.height;
 
-        gtk_paint_layout (gtk_widget_get_style (widget),
-                          cr,
-                          gtk_widget_get_state (widget),
-                          FALSE,
-                          widget,
-                          NULL,
-                          15,
-                          15,
-                          layout);
+        gtk_render_layout (gtk_widget_get_style_context (widget),
+                           cr, 15, 15, layout);
 
        pango_font_description_free (font_desc);
        g_object_unref (layout);
 
        pango_font_description_free (font_desc);
        g_object_unref (layout);
@@ -1156,7 +1173,7 @@ ev_view_presentation_button_release_event (GtkWidget      *widget,
                                                                  event->x,
                                                                  event->y);
                if (link)
                                                                  event->x,
                                                                  event->y);
                if (link)
-                       ev_vew_presentation_goto_link_dest (pview, link);
+                       ev_vew_presentation_handle_link (pview, link);
                else
                        ev_view_presentation_next_page (pview);
        }
                else
                        ev_view_presentation_next_page (pview);
        }
@@ -1217,10 +1234,9 @@ init_presentation (GtkWidget *widget)
 static void
 ev_view_presentation_realize (GtkWidget *widget)
 {
 static void
 ev_view_presentation_realize (GtkWidget *widget)
 {
-       GdkWindow    *window;
-       GtkStyle     *style;
-       GdkWindowAttr attributes;
-       GtkAllocation allocation;
+       GdkWindow     *window;
+       GdkWindowAttr  attributes;
+       GtkAllocation  allocation;
 
        gtk_widget_set_realized (widget, TRUE);
 
 
        gtk_widget_set_realized (widget, TRUE);
 
@@ -1251,9 +1267,7 @@ ev_view_presentation_realize (GtkWidget *widget)
        gdk_window_set_user_data (window, widget);
        gtk_widget_set_window (widget, window);
 
        gdk_window_set_user_data (window, widget);
        gtk_widget_set_window (widget, window);
 
-       gtk_widget_style_attach (widget);
-       style = gtk_widget_get_style (widget);
-       gdk_window_set_background (window, &style->black);
+        gdk_window_set_background_rgba (window, &black);
 
        g_idle_add ((GSourceFunc)init_presentation, widget);
 }
 
        g_idle_add ((GSourceFunc)init_presentation, widget);
 }
@@ -1375,7 +1389,8 @@ ev_view_presentation_class_init (EvViewPresentationClass *klass)
 
         gobject_class->dispose = ev_view_presentation_dispose;
 
 
         gobject_class->dispose = ev_view_presentation_dispose;
 
-       widget_class->size_request = ev_view_presentation_size_request;
+       widget_class->get_preferred_width = ev_view_presentation_get_preferred_width;
+       widget_class->get_preferred_height = ev_view_presentation_get_preferred_height;
        widget_class->realize = ev_view_presentation_realize;
         widget_class->draw = ev_view_presentation_draw;
        widget_class->key_press_event = ev_view_presentation_key_press_event;
        widget_class->realize = ev_view_presentation_realize;
         widget_class->draw = ev_view_presentation_draw;
        widget_class->key_press_event = ev_view_presentation_key_press_event;
@@ -1438,6 +1453,15 @@ ev_view_presentation_class_init (EvViewPresentationClass *klass)
                              g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0,
                              G_TYPE_NONE);
                              g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0,
                              G_TYPE_NONE);
+        signals[SIGNAL_EXTERNAL_LINK] =
+                g_signal_new ("external-link",
+                              G_TYPE_FROM_CLASS (gobject_class),
+                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                              G_STRUCT_OFFSET (EvViewPresentationClass, external_link),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__OBJECT,
+                              G_TYPE_NONE, 1,
+                              G_TYPE_OBJECT);
 
        binding_set = gtk_binding_set_by_class (klass);
        add_change_page_binding_keypad (binding_set, GDK_KEY_Left,  0, GTK_SCROLL_PAGE_BACKWARD);
 
        binding_set = gtk_binding_set_by_class (klass);
        add_change_page_binding_keypad (binding_set, GDK_KEY_Left,  0, GTK_SCROLL_PAGE_BACKWARD);