+
+ default_uri = ev_application_get_filechooser_uri (EV_APP, GTK_FILE_CHOOSER_ACTION_OPEN);
+ if (!default_uri && window->priv->uri) {
+ GFile *file, *parent;
+
+ file = g_file_new_for_uri (window->priv->uri);
+ parent = g_file_get_parent (file);
+ if (parent) {
+ parent_uri = g_file_get_uri (parent);
+ default_uri = parent_uri;
+ g_object_unref (parent);
+ }
+ g_object_unref (file);
+ }
+
+ if (default_uri) {
+ gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (chooser), default_uri);
+ } else {
+ const gchar *folder;
+
+ folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
+ folder ? folder : g_get_home_dir ());
+ }
+ g_free (parent_uri);
+
+ g_signal_connect (chooser, "response",
+ G_CALLBACK (file_open_dialog_response_cb),
+ window);
+
+ gtk_widget_show (chooser);
+}
+
+static void
+ev_window_open_copy_at_dest (EvWindow *window,
+ EvLinkDest *dest)
+{
+ EvWindow *new_window = EV_WINDOW (ev_window_new ());
+
+ ev_window_n_copies++;
+
+ if (window->priv->metadata)
+ new_window->priv->metadata = g_object_ref (window->priv->metadata);
+ ev_window_open_document (new_window,
+ window->priv->document,
+ dest, 0, NULL);
+ gtk_window_present (GTK_WINDOW (new_window));
+}
+
+static void
+ev_window_cmd_file_open_copy (GtkAction *action, EvWindow *window)
+{
+ ev_window_open_copy_at_dest (window, NULL);
+}
+
+static void
+ev_window_cmd_recent_file_activate (GtkAction *action,
+ EvWindow *window)
+{
+ GtkRecentInfo *info;
+ const gchar *uri;
+
+ info = g_object_get_data (G_OBJECT (action), "gtk-recent-info");
+ g_assert (info != NULL);
+
+ uri = gtk_recent_info_get_uri (info);
+
+ ev_application_open_uri_at_dest (EV_APP, uri,
+ gtk_window_get_screen (GTK_WINDOW (window)),
+ NULL, 0, NULL, gtk_get_current_event_time ());
+}
+
+static void
+ev_window_open_recent_action_item_activated (EvOpenRecentAction *action,
+ const gchar *uri,
+ EvWindow *window)
+{
+ ev_application_open_uri_at_dest (EV_APP, uri,
+ gtk_window_get_screen (GTK_WINDOW (window)),
+ NULL, 0, NULL, gtk_get_current_event_time ());
+}
+
+static void
+ev_window_add_recent (EvWindow *window, const char *filename)
+{
+ gtk_recent_manager_add_item (window->priv->recent_manager, filename);
+}
+
+static gint
+compare_recent_items (GtkRecentInfo *a, GtkRecentInfo *b)
+{
+ gboolean has_ev_a, has_ev_b;
+ const gchar *evince = g_get_application_name ();
+
+ has_ev_a = gtk_recent_info_has_application (a, evince);
+ has_ev_b = gtk_recent_info_has_application (b, evince);
+
+ if (has_ev_a && has_ev_b) {
+ time_t time_a, time_b;
+
+ time_a = gtk_recent_info_get_modified (a);
+ time_b = gtk_recent_info_get_modified (b);
+
+ return (time_b - time_a);
+ } else if (has_ev_a) {
+ return -1;
+ } else if (has_ev_b) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Doubles underscore to avoid spurious menu accels.
+ */
+static gchar *
+ev_window_get_recent_file_label (gint index, const gchar *filename)
+{
+ GString *str;
+ gint length;
+ const gchar *p;
+ const gchar *end;
+ gboolean is_rtl;
+
+ is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ length = strlen (filename);
+ str = g_string_sized_new (length + 10);
+ g_string_printf (str, "%s_%d. ", is_rtl ? "\xE2\x80\x8F" : "", index);
+
+ p = filename;
+ end = filename + length;
+
+ while (p != end) {
+ const gchar *next;
+ next = g_utf8_next_char (p);
+
+ switch (*p) {
+ case '_':
+ g_string_append (str, "__");
+ break;
+ default:
+ g_string_append_len (str, p, next - p);
+ break;
+ }
+
+ p = next;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+static void
+ev_window_setup_recent (EvWindow *ev_window)
+{
+ GList *items, *l;
+ guint n_items = 0;
+ const gchar *evince = g_get_application_name ();
+ static guint i = 0;
+
+ if (ev_window->priv->recent_ui_id > 0) {
+ gtk_ui_manager_remove_ui (ev_window->priv->ui_manager,
+ ev_window->priv->recent_ui_id);
+ gtk_ui_manager_ensure_update (ev_window->priv->ui_manager);
+ }
+ ev_window->priv->recent_ui_id = gtk_ui_manager_new_merge_id (ev_window->priv->ui_manager);
+
+ if (ev_window->priv->recent_action_group) {
+ gtk_ui_manager_remove_action_group (ev_window->priv->ui_manager,
+ ev_window->priv->recent_action_group);
+ g_object_unref (ev_window->priv->recent_action_group);
+ }
+ ev_window->priv->recent_action_group = gtk_action_group_new ("RecentFilesActions");
+ gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
+ ev_window->priv->recent_action_group, 0);
+
+ items = gtk_recent_manager_get_items (ev_window->priv->recent_manager);
+ items = g_list_sort (items, (GCompareFunc) compare_recent_items);
+
+ for (l = items; l && l->data; l = g_list_next (l)) {
+ GtkRecentInfo *info;
+ GtkAction *action;
+ gchar *action_name;
+ gchar *label;
+
+ info = (GtkRecentInfo *) l->data;
+
+ if (!gtk_recent_info_has_application (info, evince) ||
+ (gtk_recent_info_is_local (info) && !gtk_recent_info_exists (info)))
+ continue;
+
+ action_name = g_strdup_printf ("RecentFile%u", i++);
+ label = ev_window_get_recent_file_label (
+ n_items + 1, gtk_recent_info_get_display_name (info));
+
+ action = g_object_new (GTK_TYPE_ACTION,
+ "name", action_name,
+ "label", label,
+ NULL);
+
+ g_object_set_data_full (G_OBJECT (action),
+ "gtk-recent-info",
+ gtk_recent_info_ref (info),
+ (GDestroyNotify) gtk_recent_info_unref);
+
+ g_signal_connect (action, "activate",
+ G_CALLBACK (ev_window_cmd_recent_file_activate),
+ (gpointer) ev_window);
+
+ gtk_action_group_add_action (ev_window->priv->recent_action_group,
+ action);
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (ev_window->priv->ui_manager,
+ ev_window->priv->recent_ui_id,
+ "/MainMenu/FileMenu/RecentFilesMenu",
+ label,
+ action_name,
+ GTK_UI_MANAGER_MENUITEM,
+ FALSE);
+ g_free (action_name);
+ g_free (label);
+
+ if (++n_items == 5)
+ break;
+ }
+
+ g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL);
+ g_list_free (items);
+}
+
+static gboolean
+show_saving_progress (GFile *dst)
+{
+ EvWindow *ev_window;
+ GtkWidget *area;
+ gchar *text;
+ gchar *uri;
+ EvSaveType save_type;
+
+ ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
+ ev_window->priv->progress_idle = 0;
+
+ if (ev_window->priv->message_area)
+ return FALSE;
+
+ save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type"));
+ uri = g_file_get_uri (dst);
+ switch (save_type) {
+ case EV_SAVE_DOCUMENT:
+ text = g_strdup_printf (_("Saving document to %s"), uri);
+ break;
+ case EV_SAVE_ATTACHMENT:
+ text = g_strdup_printf (_("Saving attachment to %s"), uri);
+ break;
+ case EV_SAVE_IMAGE:
+ text = g_strdup_printf (_("Saving image to %s"), uri);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ g_free (uri);
+ area = ev_progress_message_area_new (GTK_STOCK_SAVE,
+ text,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ g_signal_connect (area, "response",
+ G_CALLBACK (ev_window_progress_response_cb),
+ ev_window);
+ gtk_widget_show (area);
+ ev_window_set_message_area (ev_window, area);
+ g_free (text);
+
+ return FALSE;
+}
+
+static void
+window_save_file_copy_ready_cb (GFile *src,
+ GAsyncResult *async_result,
+ GFile *dst)
+{
+ EvWindow *ev_window;
+ GError *error = NULL;
+
+ ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
+ ev_window_clear_progress_idle (ev_window);