+static gboolean
+window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer dummy)
+{
+ if (!(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
+ gboolean maximized;
+
+ maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
+ if (!ev_window_is_empty (window))
+ ev_metadata_manager_set_boolean (window->priv->uri, "window_maximized", maximized);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer dummy)
+{
+ char *uri = window->priv->uri;
+ GdkWindowState state;
+ int x, y, width, height;
+
+ state = gdk_window_get_state (GTK_WIDGET (window)->window);
+
+ if (!(state & GDK_WINDOW_STATE_FULLSCREEN)) {
+ gtk_window_get_position (GTK_WINDOW (window), &x, &y);
+ gtk_window_get_size (GTK_WINDOW (window), &width, &height);
+
+ if (!ev_window_is_empty (window)) {
+ ev_metadata_manager_set_int (uri, "window_x", x);
+ ev_metadata_manager_set_int (uri, "window_y", y);
+ ev_metadata_manager_set_int (uri, "window_width", width);
+ ev_metadata_manager_set_int (uri, "window_height", height);
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, EvWindow *window)
+{
+ ev_view_goto_link (EV_VIEW (window->priv->view), link);
+}
+
+static void
+launch_link (EvWindow *window, EvLink *link)
+{
+ const char *filename = ev_link_get_filename (link);
+ char *uri = NULL;
+
+ if (filename && g_path_is_absolute (filename)) {
+ uri = gnome_vfs_get_uri_from_local_path (filename);
+ } else {
+ GnomeVFSURI *base_uri, *resolved_uri;
+
+ base_uri = gnome_vfs_uri_new (window->priv->uri);
+ if (base_uri && filename) {
+ resolved_uri = gnome_vfs_uri_resolve_relative (base_uri, filename);
+ if (resolved_uri) {
+ uri = gnome_vfs_uri_to_string (resolved_uri, GNOME_VFS_URI_HIDE_NONE);
+ gnome_vfs_uri_unref (resolved_uri);
+ }
+ gnome_vfs_uri_unref (base_uri);
+ }
+ }
+
+ if (uri) {
+ gnome_vfs_url_show (uri);
+ } else {
+ gnome_vfs_url_show (filename);
+ }
+
+ g_free (uri);
+
+ /* According to the PDF spec filename can be an executable. I'm not sure
+ allowing to launch executables is a good idea though. -- marco */
+}
+
+static void
+launch_external_uri (EvWindow *window, EvLink *link)
+{
+ const char *uri;
+ char *escaped;
+
+ uri = ev_link_get_uri (link);
+ escaped = gnome_vfs_escape_host_and_path_string (uri);
+
+ gnome_vfs_url_show (escaped);
+ g_free (escaped);
+}
+
+static void
+view_external_link_cb (EvView *view, EvLink *link, EvWindow *window)
+{
+ switch (ev_link_get_link_type (link)) {
+ case EV_LINK_TYPE_EXTERNAL_URI:
+ launch_external_uri (window, link);
+ break;
+ case EV_LINK_TYPE_LAUNCH:
+ launch_link (window, link);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+ev_view_popup_cmd_open_link (GtkAction *action, EvWindow *window)
+{
+ ev_view_goto_link (EV_VIEW (window->priv->view), window->priv->link);
+}
+
+static void
+ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
+{
+ GtkClipboard *clipboard;
+ const gchar *uri;
+
+ uri = ev_link_get_uri (window->priv->link);
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, uri, -1);
+}
+
+static void
+ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window)
+{
+ GError *error = NULL;
+
+ if (!window->priv->attachment)
+ return;
+
+ ev_attachment_open (window->priv->attachment, &error);
+
+ if (error) {
+ ev_window_error_dialog (GTK_WINDOW (window),
+ _("Unable to open attachment"),
+ error);
+ g_error_free (error);
+ }
+}
+
+static void
+attachment_save_dialog_response_cb (GtkWidget *fc,
+ gint response_id,
+ EvWindow *ev_window)
+{
+ if (response_id == GTK_RESPONSE_OK) {
+ const char *uri;
+ GError *error = NULL;
+
+ uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
+
+ ev_attachment_save (ev_window->priv->attachment, uri, &error);
+
+ if (error) {
+ ev_window_error_dialog (GTK_WINDOW (fc),
+ _("The attachment could not be saved."),
+ error);
+ g_error_free (error);
+ }
+ }
+
+ gtk_widget_destroy (fc);
+}
+
+static void
+ev_attachment_popup_cmd_save_attachment_as (GtkAction *action, EvWindow *window)
+{
+ GtkWidget *fc;
+
+ fc = gtk_file_chooser_dialog_new (_("Save a Copy"),
+ GTK_WINDOW (window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
+
+#ifdef HAVE_GTK_FILE_CHOOSER_SET_DO_OVERWRITE_CONFIRMATION
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
+#endif
+
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc),
+ ev_attachment_get_name (window->priv->attachment));
+
+ g_signal_connect (fc, "response",
+ G_CALLBACK (attachment_save_dialog_response_cb),
+ window);
+
+ gtk_widget_show (fc);
+}
+