X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=shell%2Fev-window.c;h=528226b3ba1325903312e01846626f76d289c85f;hb=5f554d8e362a35e05840068e1b3ea935be5d3c47;hp=ded233d856375bc2e94316863e5088643f44bd68;hpb=d0d7034bc1d16ad1cc2c3320d5333d472803ba5f;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index ded233d8..528226b3 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -5,7 +5,7 @@ * Copyright (C) 2004 Martin Kretzschmar * Copyright (C) 2004 Red Hat, Inc. * Copyright (C) 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti - * Copyright (C) 2003, 2004, 2005 Christian Persch + * Copyright © 2003, 2004, 2005, 2009 Christian Persch * * Author: * Martin Kretzschmar @@ -68,7 +68,7 @@ #include "ev-job-scheduler.h" #include "ev-jobs.h" #include "ev-message-area.h" -#include "ev-metadata-manager.h" +#include "ev-metadata.h" #include "ev-navigation-action.h" #include "ev-open-recent-action.h" #include "ev-page-action.h" @@ -139,6 +139,10 @@ struct _EvWindowPrivate { GtkWidget *sidebar_attachments; GtkWidget *sidebar_layers; + /* Menubar accels */ + guint menubar_accel_keyval; + GdkModifierType menubar_accel_modifier; + /* Progress Messages */ guint progress_idle; GCancellable *progress_cancellable; @@ -172,6 +176,7 @@ struct _EvWindowPrivate { GList *attach_list; /* Document */ + EvDocumentModel *model; char *uri; glong uri_mtime; char *local_uri; @@ -181,9 +186,9 @@ struct _EvWindowPrivate { EvDocument *document; EvHistory *history; - EvPageCache *page_cache; EvWindowPageMode page_mode; EvWindowTitle *title; + EvMetadata *metadata; /* Load params */ EvLinkDest *dest; @@ -222,6 +227,15 @@ struct _EvWindowPrivate { #define ATTACHMENTS_SIDEBAR_ID "attachments" #define LAYERS_SIDEBAR_ID "layers" +#define EV_PRINT_SETTINGS_FILE "print-settings" +#define EV_PRINT_SETTINGS_GROUP "Print Settings" +#define EV_PAGE_SETUP_GROUP "Page Setup" + +#define EV_TOOLBARS_FILENAME "evince-toolbar.xml" + +#define MIN_SCALE 0.05409 +#define MAX_SCALE 4.0 + static const gchar *document_print_settings[] = { GTK_PRINT_SETTINGS_N_COPIES, GTK_PRINT_SETTINGS_COLLATE, @@ -242,17 +256,18 @@ static void ev_window_set_page_mode (EvWindow *windo EvWindowPageMode page_mode); static void ev_window_load_job_cb (EvJob *job, gpointer data); -static void ev_window_reload_document (EvWindow *window); +static void ev_window_reload_document (EvWindow *window, + EvLinkDest *dest); static void ev_window_reload_job_cb (EvJob *job, EvWindow *window); static void ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, EvWindow *ev_window); static void ev_window_save_job_cb (EvJob *save, EvWindow *window); -static void ev_window_sizing_mode_changed_cb (EvView *view, +static void ev_window_sizing_mode_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window); -static void ev_window_zoom_changed_cb (EvView *view, +static void ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window); static void ev_window_add_recent (EvWindow *window, @@ -299,7 +314,8 @@ static void ev_window_load_file_remote (EvWindow *ev_wi static void ev_window_media_player_key_pressed (EvWindow *window, const gchar *key, gpointer user_data); -static void ev_window_save_print_page_setup (EvWindow *window); + +static guint ev_window_n_copies = 0; G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW) @@ -334,11 +350,8 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) if (document) { has_document = TRUE; - info = ev_page_cache_get_info (ev_window->priv->page_cache); - } - - if (has_document && ev_window->priv->page_cache) { - has_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0; + has_pages = ev_document_get_n_pages (document) > 0; + info = ev_document_get_info (document); } if (!info || info->fields_mask == 0) { @@ -364,7 +377,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ok_to_copy = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_COPY); } - if (has_document && !EV_IS_FILE_EXPORTER(document)) + if (has_document && !ev_print_operation_exists_for_document(document)) ok_to_print = FALSE; #ifdef WITH_GCONF @@ -417,10 +430,11 @@ ev_window_update_actions (EvWindow *ev_window) gboolean has_pages = FALSE; gboolean presentation_mode; gboolean can_find_in_page = FALSE; + EvSizingMode sizing_mode; - if (ev_window->priv->document && ev_window->priv->page_cache) { - page = ev_page_cache_get_current_page (ev_window->priv->page_cache); - n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache); + if (ev_window->priv->document) { + page = ev_document_model_get_page (ev_window->priv->model); + n_pages = ev_document_get_n_pages (ev_window->priv->document); has_pages = n_pages > 0; } @@ -461,17 +475,16 @@ ev_window_update_actions (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "GoLastPage", FALSE); } - if (has_pages && - ev_view_get_sizing_mode (view) != EV_SIZING_FIT_WIDTH && - ev_view_get_sizing_mode (view) != EV_SIZING_BEST_FIT) { + sizing_mode = ev_document_model_get_sizing_mode (ev_window->priv->model); + if (has_pages && sizing_mode != EV_SIZING_FIT_WIDTH && sizing_mode != EV_SIZING_BEST_FIT) { GtkAction *action; float zoom; float real_zoom; - action = gtk_action_group_get_action (ev_window->priv->action_group, + action = gtk_action_group_get_action (ev_window->priv->action_group, ZOOM_CONTROL_ACTION); - real_zoom = ev_view_get_zoom (EV_VIEW (ev_window->priv->view)); + real_zoom = ev_document_model_get_scale (ev_window->priv->model); real_zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window)); zoom = ephy_zoom_get_nearest_zoom_level (real_zoom); @@ -525,7 +538,7 @@ update_chrome_visibility (EvWindow *window) gboolean fullscreen_mode, presentation, fullscreen; presentation = ev_view_get_presentation (EV_VIEW (priv->view)); - fullscreen = ev_view_get_fullscreen (EV_VIEW (priv->view)); + fullscreen = ev_document_model_get_fullscreen (priv->model); fullscreen_mode = fullscreen || presentation; menubar = (priv->chrome & EV_CHROME_MENUBAR) != 0 && !fullscreen_mode; @@ -542,7 +555,6 @@ update_chrome_visibility (EvWindow *window) set_widget_visibility (priv->sidebar, sidebar); ev_window_set_action_sensitive (window, "EditToolbar", toolbar); - gtk_widget_set_sensitive (priv->menubar, menubar); if (priv->fullscreen_toolbar != NULL) { set_widget_visibility (priv->fullscreen_toolbar, fullscreen_toolbar); @@ -567,16 +579,8 @@ update_sizing_buttons (EvWindow *window) GtkActionGroup *action_group = window->priv->action_group; GtkAction *action; gboolean best_fit, page_width; - EvSizingMode sizing_mode; - - if (window->priv->view == NULL) - return; - g_object_get (window->priv->view, - "sizing_mode", &sizing_mode, - NULL); - - switch (sizing_mode) { + switch (ev_document_model_get_sizing_mode (window->priv->model)) { case EV_SIZING_BEST_FIT: best_fit = TRUE; page_width = FALSE; @@ -728,19 +732,6 @@ ev_window_warning_message (EvWindow *window, ev_window_set_message_area (window, area); } -static void -page_changed_cb (EvPageCache *page_cache, - gint page, - EvWindow *ev_window) -{ - ev_window_update_actions (ev_window); - - ev_window_update_find_status_message (ev_window); - - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_int (ev_window->priv->uri, "page", page); -} - typedef struct _FindTask { const gchar *page_label; gchar *chapter; @@ -798,7 +789,7 @@ ev_window_add_history (EvWindow *window, gint page, EvLink *link) } else { dest = ev_link_dest_new_page (page); action = ev_link_action_new_dest (dest); - page_label = ev_page_cache_get_page_label (window->priv->page_cache, page); + page_label = ev_document_get_page_label (window->priv->document, page); } if (!page_label) @@ -839,23 +830,29 @@ ev_window_add_history (EvWindow *window, gint page, EvLink *link) static void view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window) { - int current_page = ev_page_cache_get_current_page (window->priv->page_cache); + int current_page = ev_document_model_get_page (window->priv->model); ev_window_add_history (window, 0, link); ev_window_add_history (window, current_page, NULL); } static void -history_changed_cb (EvPageCache *page_cache, - gint page, - EvWindow *window) +ev_window_page_changed_cb (EvWindow *ev_window, + gint old_page, + gint new_page, + EvDocumentModel *model) { - int current_page = ev_page_cache_get_current_page (window->priv->page_cache); + ev_window_update_actions (ev_window); - ev_window_add_history (window, page, NULL); - ev_window_add_history (window, current_page, NULL); + ev_window_update_find_status_message (ev_window); + + if (abs (new_page - old_page) > 1) { + ev_window_add_history (ev_window, new_page, NULL); + ev_window_add_history (ev_window, old_page, NULL); + } - return; + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_int (ev_window->priv->metadata, "page", new_page); } static void @@ -873,12 +870,12 @@ static void setup_chrome_from_metadata (EvWindow *window) { EvChrome chrome = EV_CHROME_NORMAL; - GValue show_toolbar = { 0, }; + gboolean show_toolbar; - if (ev_metadata_manager_get (NULL, "show_toolbar", &show_toolbar, FALSE)) { - if (!g_value_get_boolean (&show_toolbar)) + if (window->priv->metadata && + ev_metadata_get_boolean (window->priv->metadata, "show_toolbar", &show_toolbar)) { + if (!show_toolbar) chrome &= ~EV_CHROME_TOOLBAR; - g_value_unset (&show_toolbar); } window->priv->chrome = chrome; } @@ -886,26 +883,24 @@ setup_chrome_from_metadata (EvWindow *window) static void setup_sidebar_from_metadata (EvWindow *window) { - gchar *uri = window->priv->uri; EvDocument *document = window->priv->document; GtkWidget *sidebar = window->priv->sidebar; GtkWidget *links = window->priv->sidebar_links; GtkWidget *thumbs = window->priv->sidebar_thumbs; GtkWidget *attachments = window->priv->sidebar_attachments; GtkWidget *layers = window->priv->sidebar_layers; - GValue sidebar_size = { 0, }; - GValue sidebar_page = { 0, }; - GValue sidebar_visibility = { 0, }; + gchar *page_id; + gint sidebar_size; + gboolean sidebar_visibility; - if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size, FALSE)) { - gtk_paned_set_position (GTK_PANED (window->priv->hpaned), - g_value_get_int (&sidebar_size)); - g_value_unset(&sidebar_size); + if (!window->priv->metadata) + return; + + if (ev_metadata_get_int (window->priv->metadata, "sidebar_size", &sidebar_size)) { + gtk_paned_set_position (GTK_PANED (window->priv->hpaned), sidebar_size); } - - if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, TRUE)) { - const char *page_id = g_value_get_string (&sidebar_page); + if (document && ev_metadata_get_string (window->priv->metadata, "sidebar_page", &page_id)) { if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { @@ -915,7 +910,6 @@ setup_sidebar_from_metadata (EvWindow *window) } else if (strcmp (page_id, LAYERS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) { ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers); } - g_value_unset (&sidebar_page); } else if (document) { if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); @@ -928,197 +922,185 @@ setup_sidebar_from_metadata (EvWindow *window) } } - if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) { - update_chrome_flag (window, EV_CHROME_SIDEBAR, g_value_get_boolean (&sidebar_visibility)); - g_value_unset (&sidebar_visibility); + if (ev_metadata_get_boolean (window->priv->metadata, "sidebar_visibility", &sidebar_visibility)) { + update_chrome_flag (window, EV_CHROME_SIDEBAR, sidebar_visibility); update_chrome_visibility (window); } } +static void +setup_model_from_metadata (EvWindow *window) +{ + gint page; + gchar *sizing_mode; + gdouble zoom; + gint rotation; + gboolean continuous = { 0, }; + gboolean dual_page = { 0, }; + gboolean fullscreen = { 0, }; + + if (!window->priv->metadata) + return; + + /* Current page */ + if (!window->priv->dest && + ev_metadata_get_int (window->priv->metadata, "page", &page)) { + ev_document_model_set_page (window->priv->model, page); + } + + /* Sizing mode */ + if (ev_metadata_get_string (window->priv->metadata, "sizing_mode", &sizing_mode)) { + GEnumValue *enum_value; + + enum_value = g_enum_get_value_by_nick + (g_type_class_peek (EV_TYPE_SIZING_MODE), sizing_mode); + ev_document_model_set_sizing_mode (window->priv->model, enum_value->value); + } + + /* Zoom */ + if (ev_document_model_get_sizing_mode (window->priv->model) == EV_SIZING_FREE && + ev_metadata_get_double (window->priv->metadata, "zoom", &zoom)) { + zoom *= get_screen_dpi (GTK_WINDOW (window)) / 72.0; + ev_document_model_set_scale (window->priv->model, zoom); + } + + /* Rotation */ + if (ev_metadata_get_int (window->priv->metadata, "rotation", &rotation)) { + switch (rotation) { + case 90: + rotation = 90; + break; + case 180: + rotation = 180; + break; + case 270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + ev_document_model_set_rotation (window->priv->model, rotation); + } + + /* Continuous */ + if (ev_metadata_get_boolean (window->priv->metadata, "continuous", &continuous)) { + ev_document_model_set_continuous (window->priv->model, continuous); + } + + /* Dual page */ + if (ev_metadata_get_boolean (window->priv->metadata, "dual-page", &dual_page)) { + ev_document_model_set_dual_page (window->priv->model, dual_page); + } + + /* Fullscreen */ + if (ev_metadata_get_boolean (window->priv->metadata, "fullscreen", &fullscreen)) { + if (fullscreen) { + ev_window_run_fullscreen (window); + } + } +} + static void setup_document_from_metadata (EvWindow *window) { - gchar *uri = window->priv->uri; - GValue page = { 0, }; - GValue width = { 0, }; - GValue height = { 0, }; - GValue width_ratio = { 0, }; - GValue height_ratio = { 0, }; + gint page, n_pages; + gint width; + gint height; + gdouble width_ratio; + gdouble height_ratio; + + if (!window->priv->metadata) + return; - /* View the previously shown page, but make sure to not open a document on - * the last page, since closing it on the last page most likely means the + /* Make sure to not open a document on the last page, + * since closing it on the last page most likely means the * user was finished reading the document. In that case, reopening should * show the first page. */ - if (uri && ev_metadata_manager_get (uri, "page", &page, TRUE)) { - gint n_pages; - gint new_page; - - n_pages = ev_page_cache_get_n_pages (window->priv->page_cache); - new_page = CLAMP (g_value_get_int (&page), 0, n_pages - 1); - ev_page_cache_set_current_page (window->priv->page_cache, - new_page); - g_value_unset (&page); - } + page = ev_document_model_get_page (window->priv->model); + n_pages = ev_document_get_n_pages (window->priv->document); + if (page == n_pages - 1) + ev_document_model_set_page (window->priv->model, 0); setup_sidebar_from_metadata (window); - if (ev_metadata_manager_get (uri, "window_width", &width, TRUE) && - ev_metadata_manager_get (uri, "window_height", &height, TRUE)) + if (ev_metadata_get_int (window->priv->metadata, "window_width", &width) && + ev_metadata_get_int (window->priv->metadata, "window_height", &height)) return; /* size was already set in setup_size_from_metadata */ - if (ev_metadata_manager_get (uri, "window_width_ratio", &width_ratio, FALSE) && - ev_metadata_manager_get (uri, "window_height_ratio", &height_ratio, FALSE)) { - gint document_width; - gint document_height; + if (ev_metadata_get_double (window->priv->metadata, "window_width_ratio", &width_ratio) && + ev_metadata_get_double (window->priv->metadata, "window_height_ratio", &height_ratio)) { + gdouble document_width; + gdouble document_height; GdkScreen *screen; gint request_width; gint request_height; - ev_page_cache_get_max_width (window->priv->page_cache, - 0, 1.0, - &document_width); - ev_page_cache_get_max_height (window->priv->page_cache, - 0, 1.0, - &document_height); - - request_width = g_value_get_double (&width_ratio) * document_width; - request_height = g_value_get_double (&height_ratio) * document_height; - + ev_document_get_max_page_size (window->priv->document, + &document_width, &document_height); + + request_width = (gint)(width_ratio * document_width + 0.5); + request_height = (gint)(height_ratio * document_height + 0.5); + screen = gtk_window_get_screen (GTK_WINDOW (window)); - if (screen) { request_width = MIN (request_width, gdk_screen_get_width (screen)); request_height = MIN (request_width, gdk_screen_get_height (screen)); } - + if (request_width > 0 && request_height > 0) { gtk_window_resize (GTK_WINDOW (window), request_width, request_height); } - g_value_unset (&width_ratio); - g_value_unset (&height_ratio); } } static void setup_size_from_metadata (EvWindow *window) { - char *uri = window->priv->uri; - GValue width = { 0, }; - GValue height = { 0, }; - GValue maximized = { 0, }; - GValue x = { 0, }; - GValue y = { 0, }; + gint width; + gint height; + gboolean maximized; + gint x; + gint y; + + if (!window->priv->metadata) + return; - if (ev_metadata_manager_get (uri, "window_maximized", &maximized, FALSE)) { - if (g_value_get_boolean (&maximized)) { + if (ev_metadata_get_boolean (window->priv->metadata, "window_maximized", &maximized)) { + if (maximized) { gtk_window_maximize (GTK_WINDOW (window)); - g_value_unset (&maximized); return; } else { gtk_window_unmaximize (GTK_WINDOW (window)); } - g_value_unset (&maximized); } - if (ev_metadata_manager_get (uri, "window_x", &x, TRUE) && - ev_metadata_manager_get (uri, "window_y", &y, TRUE)) { - gtk_window_move (GTK_WINDOW (window), g_value_get_int (&x), - g_value_get_int (&y)); - g_value_unset (&x); - g_value_unset (&y); + if (ev_metadata_get_int (window->priv->metadata, "window_x", &x) && + ev_metadata_get_int (window->priv->metadata, "window_y", &y)) { + gtk_window_move (GTK_WINDOW (window), x, y); } - if (ev_metadata_manager_get (uri, "window_width", &width, TRUE) && - ev_metadata_manager_get (uri, "window_height", &height, TRUE)) { - gtk_window_resize (GTK_WINDOW (window), - g_value_get_int (&width), - g_value_get_int (&height)); - g_value_unset (&width); - g_value_unset (&height); + if (ev_metadata_get_int (window->priv->metadata, "window_width", &width) && + ev_metadata_get_int (window->priv->metadata, "window_height", &height)) { + gtk_window_resize (GTK_WINDOW (window), width, height); } } static void setup_view_from_metadata (EvWindow *window) { - EvView *view = EV_VIEW (window->priv->view); - gchar *uri = window->priv->uri; - GEnumValue *enum_value; - GValue sizing_mode = { 0, }; - GValue zoom = { 0, }; - GValue continuous = { 0, }; - GValue dual_page = { 0, }; - GValue presentation = { 0, }; - GValue fullscreen = { 0, }; - GValue rotation = { 0, }; - - /* Sizing mode */ - if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) { - enum_value = g_enum_get_value_by_nick - (g_type_class_peek (EV_TYPE_SIZING_MODE), g_value_get_string (&sizing_mode)); - g_value_unset (&sizing_mode); - ev_view_set_sizing_mode (view, enum_value->value); - } - - /* Zoom */ - if (ev_metadata_manager_get (uri, "zoom", &zoom, FALSE) && - ev_view_get_sizing_mode (view) == EV_SIZING_FREE) { - gdouble zoom_value; - - zoom_value = g_value_get_double (&zoom); - zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0; - ev_view_set_zoom (view, zoom_value, FALSE); - g_value_unset (&zoom); - } - - /* Continuous */ - if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) { - ev_view_set_continuous (view, g_value_get_boolean (&continuous)); - g_value_unset (&continuous); - } + gboolean presentation; - /* Dual page */ - if (ev_metadata_manager_get (uri, "dual-page", &dual_page, FALSE)) { - ev_view_set_dual_page (view, g_value_get_boolean (&dual_page)); - g_value_unset (&dual_page); - } + if (!window->priv->metadata) + return; /* Presentation */ - if (ev_metadata_manager_get (uri, "presentation", &presentation, FALSE)) { - if (g_value_get_boolean (&presentation) && uri) { + if (ev_metadata_get_boolean (window->priv->metadata, "presentation", &presentation)) { + if (presentation) { ev_window_run_presentation (window); } - g_value_unset (&presentation); - } - - /* Fullscreen */ - if (ev_metadata_manager_get (uri, "fullscreen", &fullscreen, FALSE)) { - if (g_value_get_boolean (&fullscreen) && uri) { - ev_window_run_fullscreen (window); - } - g_value_unset (&fullscreen); - } - - /* Rotation */ - if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) { - if (g_value_get_int (&rotation)) { - switch (g_value_get_int (&rotation)) { - case 90: - ev_view_set_rotation (view, 90); - break; - case 180: - ev_view_set_rotation (view, 180); - break; - case 270: - ev_view_set_rotation (view, 270); - break; - default: - break; - } - } - g_value_unset (&rotation); } } @@ -1152,23 +1134,21 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, static void ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) { - gint page_width, page_height; + gdouble page_width; gdouble scale; EvDocument *document = ev_window->priv->document; - + if (!EV_IS_DOCUMENT_THUMBNAILS (document) || - ev_page_cache_get_n_pages (ev_window->priv->page_cache) <= 0 || - ev_page_cache_check_dimensions (ev_window->priv->page_cache)) { + ev_document_get_n_pages (document) <= 0 || + !ev_document_check_dimensions (document)) { return; } - + ev_window_clear_thumbnail_job (ev_window); - - ev_page_cache_get_size (ev_window->priv->page_cache, - 0, 0, 1.0, - &page_width, &page_height); - scale = (gdouble)128 / (gdouble)page_width; - + + ev_document_get_page_size (document, 0, &page_width, NULL); + scale = 128. / page_width; + ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale); g_signal_connect (ev_window->priv->thumbnail_job, "finished", G_CALLBACK (ev_window_set_icon_from_thumbnail), @@ -1181,7 +1161,6 @@ ev_window_setup_document (EvWindow *ev_window) { const EvDocumentInfo *info; EvDocument *document = ev_window->priv->document; - EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar); GtkAction *action; ev_window->priv->setup_document_idle = 0; @@ -1192,10 +1171,6 @@ ev_window_setup_document (EvWindow *ev_window) ev_window_title_set_document (ev_window->priv->title, document); ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri); - ev_sidebar_set_document (sidebar, document); - - action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION); - ev_page_action_set_document (EV_PAGE_ACTION (action), document); ev_window_setup_action_sensitivity (ev_window); if (ev_window->priv->history) @@ -1210,28 +1185,25 @@ ev_window_setup_document (EvWindow *ev_window) ev_window->priv->document); } - info = ev_page_cache_get_info (ev_window->priv->page_cache); + info = ev_document_get_info (document); update_document_mode (ev_window, info->mode); + gtk_widget_grab_focus (ev_window->priv->view); + return FALSE; } static void ev_window_set_document (EvWindow *ev_window, EvDocument *document) { - EvView *view = EV_VIEW (ev_window->priv->view); + if (ev_window->priv->document == document) + return; if (ev_window->priv->document) g_object_unref (ev_window->priv->document); ev_window->priv->document = g_object_ref (document); ev_window_set_message_area (ev_window, NULL); - - ev_window->priv->page_cache = ev_page_cache_get (ev_window->priv->document); - g_signal_connect (ev_window->priv->page_cache, "page-changed", - G_CALLBACK (page_changed_cb), ev_window); - g_signal_connect (ev_window->priv->page_cache, "history-changed", - G_CALLBACK (history_changed_cb), ev_window); if (ev_window->priv->in_reload && ev_window->priv->dest) { gint page; @@ -1239,20 +1211,18 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) /* Restart the current page */ page = CLAMP (ev_link_dest_get_page (ev_window->priv->dest), 0, - ev_page_cache_get_n_pages (ev_window->priv->page_cache) - 1); - ev_page_cache_set_current_page (ev_window->priv->page_cache, page); + ev_document_get_n_pages (document) - 1); + ev_document_model_set_page (ev_window->priv->model, page); g_object_unref (ev_window->priv->dest); ev_window->priv->dest = NULL; } - if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) <= 0) { + if (ev_document_get_n_pages (document) <= 0) { ev_window_warning_message (ev_window, "%s", _("The document contains no pages")); - } else if (ev_page_cache_check_dimensions (ev_window->priv->page_cache)) { + } else if (!ev_document_check_dimensions (document)) { ev_window_warning_message (ev_window, "%s", _("The document contains only empty pages")); - } else { - ev_view_set_document (view, document); } if (ev_window->priv->setup_document_idle > 0) @@ -1265,7 +1235,7 @@ static void ev_window_document_changed (EvWindow *ev_window, gpointer user_data) { - ev_window_reload_document (ev_window); + ev_window_reload_document (ev_window, NULL); } static void @@ -1317,36 +1287,18 @@ ev_window_clear_local_uri (EvWindow *ev_window) } static void -ev_window_clear_temp_symlink (EvWindow *ev_window) +ev_window_handle_link (EvWindow *ev_window, + EvLinkDest *dest) { - GFile *file, *tempdir; + if (dest) { + EvLink *link; + EvLinkAction *link_action; - if (!ev_window->priv->uri) - return; - - file = g_file_new_for_uri (ev_window->priv->uri); - tempdir = g_file_new_for_path (ev_tmp_dir ()); - - if (g_file_has_prefix (file, tempdir)) { - GFileInfo *file_info; - GError *error = NULL; - - file_info = g_file_query_info (file, - G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, &error); - if (file_info) { - if (g_file_info_get_is_symlink (file_info)) - g_file_delete (file, NULL, NULL); - g_object_unref (file_info); - } else { - g_warning ("Error deleting temp symlink: %s\n", error->message); - g_error_free (error); - } + link_action = ev_link_action_new_dest (dest); + link = ev_link_new (NULL, link_action); + ev_view_handle_link (EV_VIEW (ev_window->priv->view), link); + g_object_unref (link); } - - g_object_unref (file); - g_object_unref (tempdir); } /* This callback will executed when load job will be finished. @@ -1371,7 +1323,7 @@ ev_window_load_job_cb (EvJob *job, /* Success! */ if (!ev_job_is_failed (job)) { - ev_window_set_document (ev_window, document); + ev_document_model_set_document (ev_window->priv->model, document); setup_document_from_metadata (ev_window); setup_view_from_metadata (ev_window); @@ -1390,21 +1342,12 @@ ev_window_load_job_cb (EvJob *job, flags); } - if (ev_window->priv->dest) { - EvLink *link; - EvLinkAction *link_action; - - link_action = ev_link_action_new_dest (ev_window->priv->dest); - link = ev_link_new (NULL, link_action); - ev_view_handle_link (EV_VIEW (ev_window->priv->view), link); - g_object_unref (link); - - /* Already unrefed by ev_link_action - * FIXME: link action should inc dest ref counting - * or not unref it at all - */ - ev_window->priv->dest = NULL; - } + ev_window_handle_link (ev_window, ev_window->priv->dest); + /* Already unrefed by ev_link_action + * FIXME: link action should inc dest ref counting + * or not unref it at all + */ + ev_window->priv->dest = NULL; switch (ev_window->priv->window_mode) { case EV_WINDOW_MODE_FULLSCREEN: @@ -1483,6 +1426,7 @@ ev_window_reload_job_cb (EvJob *job, EvWindow *ev_window) { GtkWidget *widget; + EvLinkDest *dest = NULL; if (ev_job_is_failed (job)) { ev_window_clear_reload_job (ev_window); @@ -1492,9 +1436,14 @@ ev_window_reload_job_cb (EvJob *job, return; } - - ev_window_set_document (ev_window, job->document); - + + if (ev_window->priv->dest) { + dest = g_object_ref (ev_window->priv->dest); + } + ev_document_model_set_document (ev_window->priv->model, + job->document); + ev_window_handle_link (ev_window, dest); + /* Restart the search after reloading */ widget = gtk_window_get_focus (GTK_WINDOW (ev_window)); if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) { @@ -1596,7 +1545,9 @@ show_loading_progress (EvWindow *ev_window) if (ev_window->priv->message_area) return FALSE; - display_name = escape_uri_for_display (ev_window->priv->uri); + text = g_uri_unescape_string (ev_window->priv->uri, NULL); + display_name = g_markup_escape_text (text, -1); + g_free (text); text = g_strdup_printf (_("Loading document from “%s”"), display_name); @@ -1684,7 +1635,8 @@ window_open_file_copy_ready_cb (GFile *source, GError *error = NULL; ev_window_clear_progress_idle (ev_window); - + ev_window_set_message_area (ev_window, NULL); + g_file_copy_finish (source, async_result, &error); if (!error) { ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE); @@ -1734,6 +1686,9 @@ window_open_file_copy_progress_cb (goffset n_bytes, if (!ev_window->priv->message_area) return; + if (total_bytes <= 0) + return; + fraction = n_bytes / (gdouble)total_bytes; status = g_strdup_printf (_("Downloading document (%d%%)"), (gint)(fraction * 100)); @@ -1753,19 +1708,30 @@ ev_window_load_file_remote (EvWindow *ev_window, GFile *target_file; if (!ev_window->priv->local_uri) { - gchar *tmp_name; - gchar *base_name; + char *base_name, *template; + GFile *tmp_file; + GError *err = NULL; /* We'd like to keep extension of source uri since - * it helps to resolve some mime types, say cbz */ - tmp_name = ev_tmp_filename (NULL); + * it helps to resolve some mime types, say cbz. + */ base_name = g_file_get_basename (source_file); - ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-", - base_name, NULL); + template = g_build_filename ("document.XXXXXX-%s", base_name, NULL); + g_free (base_name); + + tmp_file = ev_mkstemp_file (template, &err); + if (tmp_file == NULL) { + ev_window_error_message (ev_window, err, + "%s", _("Failed to load remote file.")); + g_error_free (err); + return; + } + + ev_window->priv->local_uri = g_file_get_uri (tmp_file); + g_object_unref (tmp_file); + ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job), ev_window->priv->local_uri); - g_free (base_name); - g_free (tmp_name); } ev_window_reset_progress_cancellable (ev_window); @@ -1797,7 +1763,7 @@ ev_window_open_uri (EvWindow *ev_window, if (ev_window->priv->uri && g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) { - ev_window_reload_document (ev_window); + ev_window_reload_document (ev_window, dest); return; } @@ -1817,6 +1783,15 @@ ev_window_open_uri (EvWindow *ev_window, g_free (ev_window->priv->uri); ev_window->priv->uri = g_strdup (uri); + if (ev_window->priv->metadata) + g_object_unref (ev_window->priv->metadata); + + source_file = g_file_new_for_uri (uri); + if (ev_is_metadata_supported_for_file (source_file)) + ev_window->priv->metadata = ev_metadata_new (source_file); + else + ev_window->priv->metadata = NULL; + if (ev_window->priv->search_string) g_free (ev_window->priv->search_string); ev_window->priv->search_string = search_string ? @@ -1827,6 +1802,7 @@ ev_window_open_uri (EvWindow *ev_window, ev_window->priv->dest = dest ? g_object_ref (dest) : NULL; setup_size_from_metadata (ev_window); + setup_model_from_metadata (ev_window); ev_window->priv->load_job = ev_job_load_new (uri); g_signal_connect (ev_window->priv->load_job, @@ -1834,7 +1810,6 @@ ev_window_open_uri (EvWindow *ev_window, G_CALLBACK (ev_window_load_job_cb), ev_window); - source_file = g_file_new_for_uri (uri); if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) { ev_window_load_file_remote (ev_window, source_file); } else { @@ -1843,6 +1818,75 @@ ev_window_open_uri (EvWindow *ev_window, } } +void +ev_window_open_document (EvWindow *ev_window, + EvDocument *document, + EvLinkDest *dest, + EvWindowRunMode mode, + const gchar *search_string) +{ + if (document == ev_window->priv->document) + return; + + ev_window_close_dialogs (ev_window); + ev_window_clear_load_job (ev_window); + ev_window_clear_local_uri (ev_window); + + if (ev_window->priv->monitor) { + g_object_unref (ev_window->priv->monitor); + ev_window->priv->monitor = NULL; + } + + if (ev_window->priv->uri) + g_free (ev_window->priv->uri); + ev_window->priv->uri = g_strdup (ev_document_get_uri (document)); + + setup_size_from_metadata (ev_window); + setup_model_from_metadata (ev_window); + + ev_document_model_set_document (ev_window->priv->model, document); + + setup_document_from_metadata (ev_window); + setup_view_from_metadata (ev_window); + + if (dest) { + EvLink *link; + EvLinkAction *link_action; + + link_action = ev_link_action_new_dest (dest); + link = ev_link_new (NULL, link_action); + ev_view_handle_link (EV_VIEW (ev_window->priv->view), link); + /* FIXME: link action should inc dest ref counting + * or not unref it at all + */ + g_object_ref (dest); + g_object_unref (link); + } + + switch (mode) { + case EV_WINDOW_MODE_FULLSCREEN: + ev_window_run_fullscreen (ev_window); + break; + case EV_WINDOW_MODE_PRESENTATION: + ev_window_run_presentation (ev_window); + break; + default: + break; + } + + if (search_string && EV_IS_DOCUMENT_FIND (document)) { + ev_window_cmd_edit_find (NULL, ev_window); + egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar), + search_string); + } + + /* Create a monitor for the document */ + ev_window->priv->monitor = ev_file_monitor_new (ev_window->priv->uri); + g_signal_connect_swapped (ev_window->priv->monitor, "changed", + G_CALLBACK (ev_window_document_changed), + ev_window); +} + static void ev_window_reload_local (EvWindow *ev_window) { @@ -1916,7 +1960,10 @@ reload_remote_copy_progress_cb (goffset n_bytes, if (!ev_window->priv->message_area) return; - + + if (total_bytes <= 0) + return; + fraction = n_bytes / (gdouble)total_bytes; status = g_strdup_printf (_("Downloading document (%d%%)"), (gint)(fraction * 100)); @@ -1992,7 +2039,8 @@ ev_window_reload_remote (EvWindow *ev_window) } static void -ev_window_reload_document (EvWindow *ev_window) +ev_window_reload_document (EvWindow *ev_window, + EvLinkDest *dest) { gint page; @@ -2000,12 +2048,12 @@ ev_window_reload_document (EvWindow *ev_window) ev_window_clear_reload_job (ev_window); ev_window->priv->in_reload = TRUE; - page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + page = ev_document_model_get_page (ev_window->priv->model); if (ev_window->priv->dest) g_object_unref (ev_window->priv->dest); /* FIXME: save the scroll position too (xyz dest) */ - ev_window->priv->dest = ev_link_dest_new_page (page); + ev_window->priv->dest = dest ? g_object_ref (dest) : ev_link_dest_new_page (page); if (ev_window->priv->local_uri) { ev_window_reload_remote (ev_window); @@ -2027,7 +2075,7 @@ file_open_dialog_response_cb (GtkWidget *chooser, ev_application_open_uri_list (EV_APP, uris, gtk_window_get_screen (GTK_WINDOW (ev_window)), - GDK_CURRENT_TIME); + gtk_get_current_event_time ()); g_slist_foreach (uris, (GFunc)g_free, NULL); g_slist_free (uris); @@ -2093,104 +2141,26 @@ ev_window_cmd_file_open (GtkAction *action, EvWindow *window) gtk_widget_show (chooser); } -static gchar * -ev_window_create_tmp_symlink (const gchar *filename, GError **error) -{ - gchar *tmp_filename = NULL; - gchar *name; - guint i = 0; - GError *link_error = NULL; - GFile *tmp_file = NULL; - - name = g_path_get_basename (filename); - - do { - gchar *basename; - - if (tmp_filename) - g_free (tmp_filename); - if (tmp_file) - g_object_unref (tmp_file); - g_clear_error (&link_error); - - basename = g_strdup_printf ("%s-%d", name, i++); - tmp_filename = g_build_filename (ev_tmp_dir (), - basename, NULL); - - g_free (basename); - tmp_file = g_file_new_for_path (tmp_filename); - } while (!g_file_make_symbolic_link (tmp_file, filename, NULL, &link_error) && - g_error_matches (link_error, G_IO_ERROR, G_IO_ERROR_EXISTS)); - - g_free (name); - g_object_unref (tmp_file); - - if (link_error) { - g_propagate_prefixed_error (error, - link_error, - _("Couldn't create symlink “%s”: "), - tmp_filename); - g_free (tmp_filename); - - return NULL; - } - - return tmp_filename; -} - static void -ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) +ev_window_open_copy_at_dest (EvWindow *window, + EvLinkDest *dest) { - GError *error = NULL; - gchar *symlink_uri; - gchar *old_filename; - gchar *new_filename; - const gchar *uri_unc; - - uri_unc = g_object_get_data (G_OBJECT (window->priv->document), - "uri-uncompressed"); - old_filename = g_filename_from_uri (uri_unc ? uri_unc : window->priv->uri, - NULL, NULL); - new_filename = ev_window_create_tmp_symlink (old_filename, &error); - - if (error) { - ev_window_error_message (window, error, - "%s", _("Cannot open a copy.")); - g_error_free (error); - g_free (old_filename); - g_free (new_filename); + EvWindow *new_window = EV_WINDOW (ev_window_new ()); - return; - } - - g_free (old_filename); + ev_window_n_copies++; - symlink_uri = g_filename_to_uri (new_filename, NULL, NULL); - g_free (new_filename); - - ev_application_open_uri_at_dest (EV_APP, - symlink_uri, - gtk_window_get_screen (GTK_WINDOW (window)), - dest, - 0, - NULL, - GDK_CURRENT_TIME); - g_free (symlink_uri); + 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) { - EvPageCache *page_cache; - EvLinkDest *dest; - gint current_page; - - page_cache = ev_page_cache_get (window->priv->document); - current_page = ev_page_cache_get_current_page (page_cache); - - dest = ev_link_dest_new_page (current_page); - ev_window_cmd_file_open_copy_at_dest (window, dest); - g_object_unref (dest); + ev_window_open_copy_at_dest (window, NULL); } static void @@ -2207,7 +2177,7 @@ ev_window_cmd_recent_file_activate (GtkAction *action, ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (window)), - NULL, 0, NULL, GDK_CURRENT_TIME); + NULL, 0, NULL, gtk_get_current_event_time ()); } static void @@ -2217,7 +2187,7 @@ ev_window_open_recent_action_item_activated (EvOpenRecentAction *action, { ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (window)), - NULL, 0, NULL, GDK_CURRENT_TIME); + NULL, 0, NULL, gtk_get_current_event_time ()); } static void @@ -2463,7 +2433,10 @@ window_save_file_copy_progress_cb (goffset n_bytes, if (!ev_window->priv->message_area) return; - + + if (total_bytes <= 0) + return; + fraction = n_bytes / (gdouble)total_bytes; save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type")); @@ -2639,114 +2612,203 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) gtk_widget_show (fc); } +static GKeyFile * +get_print_settings_file (void) +{ + GKeyFile *print_settings_file; + gchar *filename; + GError *error = NULL; + + print_settings_file = g_key_file_new (); + + filename = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE), + EV_PRINT_SETTINGS_FILE, NULL); + if (!g_key_file_load_from_file (print_settings_file, + filename, + G_KEY_FILE_KEEP_COMMENTS | + G_KEY_FILE_KEEP_TRANSLATIONS, + &error)) { + + /* Don't warn if the file simply doesn't exist */ + if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_warning ("%s", error->message); + + g_error_free (error); + } + + g_free (filename); + + return print_settings_file; +} + static void -ev_window_load_print_settings_from_metadata (EvWindow *window) +save_print_setting_file (GKeyFile *key_file) { - gchar *uri = window->priv->uri; - gint i; - - /* Load print setting that are specific to the document */ - for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { - GValue value = { 0, }; - gboolean success; + gchar *filename; + gchar *data; + gsize data_length; + GError *error = NULL; - success = ev_metadata_manager_get (uri, document_print_settings[i], &value, TRUE); - gtk_print_settings_set (window->priv->print_settings, - document_print_settings[i], - success ? g_value_get_string (&value) : NULL); - if (success) - g_value_unset (&value); + filename = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE), + EV_PRINT_SETTINGS_FILE, NULL); + data = g_key_file_to_data (key_file, &data_length, NULL); + g_file_set_contents (filename, data, data_length, &error); + if (error) { + g_warning ("Failed to save print settings: %s", error->message); + g_error_free (error); } + g_free (data); + g_free (filename); } static void -ev_window_save_print_settings (EvWindow *window) +ev_window_save_print_settings (EvWindow *window, + GtkPrintSettings *print_settings) { - gchar *uri = window->priv->uri; - gint i; - + GKeyFile *key_file; + gint i; + + key_file = get_print_settings_file (); + gtk_print_settings_to_key_file (print_settings, key_file, EV_PRINT_SETTINGS_GROUP); + save_print_setting_file (key_file); + g_key_file_free (key_file); + + if (!window->priv->metadata) + return; + /* Save print settings that are specific to the document */ for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { const gchar *value; - value = gtk_print_settings_get (window->priv->print_settings, + value = gtk_print_settings_get (print_settings, document_print_settings[i]); - ev_metadata_manager_set_string (uri, document_print_settings[i], value); + ev_metadata_set_string (window->priv->metadata, + document_print_settings[i], value); } } static void -ev_window_save_print_page_setup (EvWindow *window) +ev_window_save_print_page_setup (EvWindow *window, + GtkPageSetup *page_setup) { - gchar *uri = window->priv->uri; - GtkPageSetup *page_setup = window->priv->print_page_setup; + GKeyFile *key_file; + + key_file = get_print_settings_file (); + gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP); + save_print_setting_file (key_file); + g_key_file_free (key_file); + + if (!window->priv->metadata) + return; /* Save page setup options that are specific to the document */ - ev_metadata_manager_set_int (uri, "page-setup-orientation", - gtk_page_setup_get_orientation (page_setup)); - ev_metadata_manager_set_double (uri, "page-setup-margin-top", - gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); - ev_metadata_manager_set_double (uri, "page-setup-margin-bottom", - gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); - ev_metadata_manager_set_double (uri, "page-setup-margin-left", - gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); - ev_metadata_manager_set_double (uri, "page-setup-margin-right", - gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_int (window->priv->metadata, "page-setup-orientation", + gtk_page_setup_get_orientation (page_setup)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-top", + gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-bottom", + gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-left", + gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-right", + gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); } static void -ev_window_load_print_page_setup_from_metadata (EvWindow *window) +ev_window_load_print_settings_from_metadata (EvWindow *window, + GtkPrintSettings *print_settings) { - gchar *uri = window->priv->uri; - GtkPageSetup *page_setup = window->priv->print_page_setup; - GtkPaperSize *paper_size; - GValue value = { 0, }; + gint i; + + if (!window->priv->metadata) + return; + + /* Load print setting that are specific to the document */ + for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { + gchar *value = NULL; + + ev_metadata_get_string (window->priv->metadata, + document_print_settings[i], &value); + gtk_print_settings_set (print_settings, + document_print_settings[i], value); + } +} + +static void +ev_window_load_print_page_setup_from_metadata (EvWindow *window, + GtkPageSetup *page_setup) +{ + gint int_value; + gdouble double_value; + GtkPaperSize *paper_size = gtk_page_setup_get_paper_size (page_setup); - paper_size = gtk_page_setup_get_paper_size (page_setup); - /* Load page setup options that are specific to the document */ - if (ev_metadata_manager_get (uri, "page-setup-orientation", &value, TRUE)) { - gtk_page_setup_set_orientation (page_setup, g_value_get_int (&value)); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_int (window->priv->metadata, "page-setup-orientation", &int_value)) { + gtk_page_setup_set_orientation (page_setup, int_value); } else { gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_PORTRAIT); } - - if (ev_metadata_manager_get (uri, "page-setup-margin-top", &value, TRUE)) { - gtk_page_setup_set_top_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-top", &double_value)) { + gtk_page_setup_set_top_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_top_margin (page_setup, gtk_paper_size_get_default_top_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); } - if (ev_metadata_manager_get (uri, "page-setup-margin-bottom", &value, TRUE)) { - gtk_page_setup_set_bottom_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-bottom", &double_value)) { + gtk_page_setup_set_bottom_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_bottom_margin (page_setup, gtk_paper_size_get_default_bottom_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); } - if (ev_metadata_manager_get (uri, "page-setup-margin-left", &value, TRUE)) { - gtk_page_setup_set_left_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-left", &double_value)) { + gtk_page_setup_set_left_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_left_margin (page_setup, gtk_paper_size_get_default_left_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); - } + } - if (ev_metadata_manager_get (uri, "page-setup-margin-right", &value, TRUE)) { - gtk_page_setup_set_right_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-right", &double_value)) { + gtk_page_setup_set_right_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_right_margin (page_setup, gtk_paper_size_get_default_right_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); - } + } +} + +static GtkPrintSettings * +get_print_settings (GKeyFile *key_file) +{ + GtkPrintSettings *print_settings; + + print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ? + gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) : + gtk_print_settings_new (); + + return print_settings ? print_settings : gtk_print_settings_new (); +} + +static GtkPageSetup * +get_print_page_setup (GKeyFile *key_file) +{ + GtkPageSetup *page_setup; + + page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ? + gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) : + gtk_page_setup_new (); + + return page_setup ? page_setup : gtk_page_setup_new (); } static void @@ -2757,31 +2819,33 @@ ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup, if (!page_setup) return; - if (window->priv->print_page_setup != page_setup) { - if (window->priv->print_page_setup) - g_object_unref (window->priv->print_page_setup); - window->priv->print_page_setup = g_object_ref (page_setup); - } - - ev_application_set_page_setup (EV_APP, page_setup); - ev_window_save_print_page_setup (window); + ev_window_save_print_page_setup (window, page_setup); } static void -ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window) +ev_window_cmd_file_print_setup (GtkAction *action, + EvWindow *ev_window) { - if (!ev_window->priv->print_page_setup) { - ev_window->priv->print_page_setup = gtk_page_setup_copy ( - ev_application_get_page_setup (EV_APP)); - ev_window_load_print_page_setup_from_metadata (ev_window); - } - - gtk_print_run_page_setup_dialog_async ( - GTK_WINDOW (ev_window), - ev_window->priv->print_page_setup, - ev_window->priv->print_settings, - (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb, - ev_window); + GKeyFile *print_settings_file; + GtkPrintSettings *print_settings; + GtkPageSetup *print_page_setup; + + print_settings_file = get_print_settings_file (); + + print_settings = get_print_settings (print_settings_file); + ev_window_load_print_settings_from_metadata (ev_window, print_settings); + + print_page_setup = get_print_page_setup (print_settings_file); + ev_window_load_print_page_setup_from_metadata (ev_window, print_page_setup); + + gtk_print_run_page_setup_dialog_async (GTK_WINDOW (ev_window), + print_page_setup, + print_settings, + (GtkPageSetupDoneFunc)ev_window_print_page_setup_done_cb, + ev_window); + g_object_unref (print_settings); + g_object_unref (print_page_setup); + g_key_file_free (print_settings_file); } static void @@ -2837,20 +2901,13 @@ ev_window_print_operation_done (EvPrintOperation *op, EvWindow *ev_window) { gint n_jobs; - + switch (result) { case GTK_PRINT_OPERATION_RESULT_APPLY: { GtkPrintSettings *print_settings; - + print_settings = ev_print_operation_get_print_settings (op); - if (ev_window->priv->print_settings != print_settings) { - if (ev_window->priv->print_settings) - g_object_unref (ev_window->priv->print_settings); - ev_window->priv->print_settings = g_object_ref (print_settings); - } - - ev_application_set_print_settings (EV_APP, print_settings); - ev_window_save_print_settings (ev_window); + ev_window_save_print_settings (ev_window, print_settings); } break; @@ -2954,19 +3011,12 @@ static void ev_window_print_operation_begin_print (EvPrintOperation *op, EvWindow *ev_window) { - GtkPrintSettings *print_settings; - if (!ev_window->priv->print_queue) ev_window->priv->print_queue = g_queue_new (); g_queue_push_head (ev_window->priv->print_queue, op); ev_window_print_update_pending_jobs_message (ev_window, g_queue_get_length (ev_window->priv->print_queue)); - - if (ev_window->priv->print_settings) - g_object_unref (ev_window->priv->print_settings); - print_settings = ev_print_operation_get_print_settings (op); - ev_window->priv->print_settings = g_object_ref (print_settings); } void @@ -2975,7 +3025,9 @@ ev_window_print_range (EvWindow *ev_window, gint last_page) { EvPrintOperation *op; - EvPageCache *page_cache; + GKeyFile *print_settings_file; + GtkPrintSettings *print_settings; + GtkPageSetup *print_page_setup; gint current_page; gint document_last_page; @@ -2986,6 +3038,11 @@ ev_window_print_range (EvWindow *ev_window, ev_window->priv->print_queue = g_queue_new (); op = ev_print_operation_new (ev_window->priv->document); + if (!op) { + g_warning ("%s", "Printing is not supported for document\n"); + return; + } + g_signal_connect (op, "begin_print", G_CALLBACK (ev_window_print_operation_begin_print), (gpointer)ev_window); @@ -2996,15 +3053,16 @@ ev_window_print_range (EvWindow *ev_window, G_CALLBACK (ev_window_print_operation_done), (gpointer)ev_window); - page_cache = ev_page_cache_get (ev_window->priv->document); - current_page = ev_page_cache_get_current_page (page_cache); - document_last_page = ev_page_cache_get_n_pages (page_cache); + current_page = ev_document_model_get_page (ev_window->priv->model); + document_last_page = ev_document_get_n_pages (ev_window->priv->document); - if (!ev_window->priv->print_settings) { - ev_window->priv->print_settings = gtk_print_settings_copy ( - ev_application_get_print_settings (EV_APP)); - ev_window_load_print_settings_from_metadata (ev_window); - } + print_settings_file = get_print_settings_file (); + + print_settings = get_print_settings (print_settings_file); + ev_window_load_print_settings_from_metadata (ev_window, print_settings); + + print_page_setup = get_print_page_setup (print_settings_file); + ev_window_load_print_page_setup_from_metadata (ev_window, print_page_setup); if (first_page != 1 || last_page != document_last_page) { GtkPageRange range; @@ -3012,18 +3070,21 @@ ev_window_print_range (EvWindow *ev_window, /* Ranges in GtkPrint are 0 - N */ range.start = first_page - 1; range.end = last_page - 1; - - gtk_print_settings_set_print_pages (ev_window->priv->print_settings, + + gtk_print_settings_set_print_pages (print_settings, GTK_PRINT_PAGES_RANGES); - gtk_print_settings_set_page_ranges (ev_window->priv->print_settings, + gtk_print_settings_set_page_ranges (print_settings, &range, 1); } ev_print_operation_set_job_name (op, gtk_window_get_title (GTK_WINDOW (ev_window))); ev_print_operation_set_current_page (op, current_page); - ev_print_operation_set_print_settings (op, ev_window->priv->print_settings); - if (ev_window->priv->print_page_setup) - ev_print_operation_set_default_page_setup (op, ev_window->priv->print_page_setup); + ev_print_operation_set_print_settings (op, print_settings); + ev_print_operation_set_default_page_setup (op, print_page_setup); + + g_object_unref (print_settings); + g_object_unref (print_page_setup); + g_key_file_free (print_settings_file); ev_print_operation_run (op, GTK_WINDOW (ev_window)); } @@ -3031,13 +3092,8 @@ ev_window_print_range (EvWindow *ev_window, static void ev_window_print (EvWindow *window) { - EvPageCache *page_cache; - gint last_page; - - page_cache = ev_page_cache_get (window->priv->document); - last_page = ev_page_cache_get_n_pages (page_cache); - - ev_window_print_range (window, 1, last_page); + ev_window_print_range (window, 1, + ev_document_get_n_pages (window->priv->document)); } static void @@ -3195,10 +3251,7 @@ ev_window_cmd_continuous (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - g_object_set (G_OBJECT (ev_window->priv->view), - "continuous", continuous, - NULL); - ev_window_update_actions (ev_window); + ev_document_model_set_continuous (ev_window->priv->model, continuous); } static void @@ -3208,10 +3261,7 @@ ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - g_object_set (G_OBJECT (ev_window->priv->view), - "dual-page", dual_page, - NULL); - ev_window_update_actions (ev_window); + ev_document_model_set_dual_page (ev_window->priv->model, dual_page); } static void @@ -3220,9 +3270,9 @@ ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_BEST_FIT); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_BEST_FIT); } else { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); } ev_window_update_actions (ev_window); } @@ -3233,9 +3283,9 @@ ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FIT_WIDTH); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FIT_WIDTH); } else { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); } ev_window_update_actions (ev_window); } @@ -3295,12 +3345,13 @@ ev_window_cmd_edit_copy (GtkAction *action, EvWindow *ev_window) } static void -ev_window_sidebar_position_change_cb (GObject *object, GParamSpec *pspec, - EvWindow *ev_window) +ev_window_sidebar_position_change_cb (GObject *object, + GParamSpec *pspec, + EvWindow *ev_window) { - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_int (ev_window->priv->uri, "sidebar_size", - gtk_paned_get_position (GTK_PANED (object))); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_int (ev_window->priv->metadata, "sidebar_size", + gtk_paned_get_position (GTK_PANED (object))); } static void @@ -3312,7 +3363,7 @@ ev_window_update_fullscreen_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_fullscreen (EV_VIEW (window->priv->view))); + ev_document_model_get_fullscreen (window->priv->model)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window); } @@ -3362,7 +3413,7 @@ ev_window_run_fullscreen (EvWindow *window) EvView *view = EV_VIEW (window->priv->view); gboolean fullscreen_window = TRUE; - if (ev_view_get_fullscreen (view)) + if (ev_document_model_get_fullscreen (window->priv->model)) return; if (!window->priv->fullscreen_toolbar) { @@ -3391,7 +3442,7 @@ ev_window_run_fullscreen (EvWindow *window) "shadow-type", GTK_SHADOW_NONE, NULL); - ev_view_set_fullscreen (view, TRUE); + ev_document_model_set_fullscreen (window->priv->model, TRUE); ev_window_update_fullscreen_action (window); /* If the user doesn't have the main toolbar he/she won't probably want @@ -3405,32 +3456,30 @@ ev_window_run_fullscreen (EvWindow *window) gtk_window_fullscreen (GTK_WINDOW (window)); gtk_widget_grab_focus (window->priv->view); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", TRUE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "fullscreen", TRUE); } static void ev_window_stop_fullscreen (EvWindow *window, gboolean unfullscreen_window) { - EvView *view = EV_VIEW (window->priv->view); - - if (!ev_view_get_fullscreen (view)) + if (!ev_document_model_get_fullscreen (window->priv->model)) return; g_object_set (G_OBJECT (window->priv->scrolled_window), "shadow-type", GTK_SHADOW_IN, NULL); - ev_view_set_fullscreen (view, FALSE); + ev_document_model_set_fullscreen (window->priv->model, FALSE); ev_window_update_fullscreen_action (window); update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE); update_chrome_visibility (window); if (unfullscreen_window) gtk_window_unfullscreen (GTK_WINDOW (window)); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", FALSE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "fullscreen", FALSE); } static void @@ -3533,7 +3582,7 @@ ev_window_run_presentation (EvWindow *window) if (ev_view_get_presentation (view)) return; - if (ev_view_get_fullscreen (view)) { + if (ev_document_model_get_fullscreen (window->priv->model)) { ev_window_stop_fullscreen (window, FALSE); fullscreen_window = FALSE; } @@ -3563,8 +3612,8 @@ ev_window_run_presentation (EvWindow *window) ev_application_screensaver_disable (EV_APP); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "presentation", TRUE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "presentation", TRUE); } static void @@ -3596,8 +3645,8 @@ ev_window_stop_presentation (EvWindow *window, ev_application_screensaver_enable (EV_APP); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "presentation", FALSE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "presentation", FALSE); } static void @@ -3611,6 +3660,35 @@ ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window) } } +static void +ev_window_setup_gtk_settings (EvWindow *window) +{ + GtkSettings *settings; + GdkScreen *screen; + gchar *menubar_accel_accel; + + screen = gtk_window_get_screen (GTK_WINDOW (window)); + settings = gtk_settings_get_for_screen (screen); + + g_object_get (settings, + "gtk-menu-bar-accel", &menubar_accel_accel, + NULL); + if (menubar_accel_accel != NULL && menubar_accel_accel[0] != '\0') { + gtk_accelerator_parse (menubar_accel_accel, + &window->priv->menubar_accel_keyval, + &window->priv->menubar_accel_modifier); + if (window->priv->menubar_accel_keyval == 0) { + g_warning ("Failed to parse menu bar accelerator '%s'\n", + menubar_accel_accel); + } + } else { + window->priv->menubar_accel_keyval = 0; + window->priv->menubar_accel_modifier = 0; + } + + g_free (menubar_accel_accel); +} + static void ev_window_screen_changed (GtkWidget *widget, GdkScreen *old_screen) @@ -3618,14 +3696,17 @@ ev_window_screen_changed (GtkWidget *widget, EvWindow *window = EV_WINDOW (widget); EvWindowPrivate *priv = window->priv; GdkScreen *screen; + gdouble dpi; screen = gtk_widget_get_screen (widget); if (screen == old_screen) return; - ev_view_set_screen_dpi (EV_VIEW (priv->view), - get_screen_dpi (GTK_WINDOW (window))); - + ev_window_setup_gtk_settings (window); + dpi = get_screen_dpi (GTK_WINDOW (window)); + ev_document_model_set_min_scale (priv->model, MIN_SCALE * dpi / 72.0); + ev_document_model_set_max_scale (priv->model, MAX_SCALE * dpi / 72.0); + if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) { GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen); } @@ -3646,12 +3727,12 @@ ev_window_state_event (GtkWidget *widget, return FALSE; if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) { - if (ev_view_get_fullscreen (view) || ev_view_get_presentation (view)) + if (ev_document_model_get_fullscreen (window->priv->model) || ev_view_get_presentation (view)) return FALSE; ev_window_run_fullscreen (window); } else { - if (ev_view_get_fullscreen (view)) + if (ev_document_model_get_fullscreen (window->priv->model)) ev_window_stop_fullscreen (window, FALSE); else if (ev_view_get_presentation (view)) ev_window_stop_presentation (window, FALSE); @@ -3697,52 +3778,68 @@ ev_window_set_page_mode (EvWindow *window, static void ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window) { - ev_view_rotate_left (EV_VIEW (ev_window->priv->view)); + gint rotation = ev_document_model_get_rotation (ev_window->priv->model); + + ev_document_model_set_rotation (ev_window->priv->model, rotation - 90); } static void ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window) { - ev_view_rotate_right (EV_VIEW (ev_window->priv->view)); + gint rotation = ev_document_model_get_rotation (ev_window->priv->model); + + ev_document_model_set_rotation (ev_window->priv->model, rotation + 90); } static void -ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, gint response, gpointer data) +ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, + gint response, + EvWindow *ev_window) { - EvWindow *ev_window = EV_WINDOW (data); - egg_editable_toolbar_set_edit_mode - (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), FALSE); - ev_application_save_toolbars_model (EV_APP); + EggEditableToolbar *toolbar; + gchar *toolbars_file; + + toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar); + egg_editable_toolbar_set_edit_mode (toolbar, FALSE); + + toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE), + "evince_toolbar.xml", NULL); + egg_toolbars_model_save_toolbars (egg_editable_toolbar_get_model (toolbar), + toolbars_file, "1.0"); + g_free (toolbars_file); + gtk_widget_destroy (GTK_WIDGET (dialog)); } static void ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window) { - GtkWidget *dialog; - GtkWidget *editor; + GtkWidget *dialog; + GtkWidget *editor; + EggEditableToolbar *toolbar; dialog = gtk_dialog_new_with_buttons (_("Toolbar Editor"), - GTK_WINDOW (ev_window), - GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_WINDOW (ev_window), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, - GTK_RESPONSE_CLOSE, + GTK_RESPONSE_CLOSE, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5); gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400); - + + toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar); editor = egg_toolbar_editor_new (ev_window->priv->ui_manager, - ev_application_get_toolbars_model (EV_APP)); + egg_editable_toolbar_get_model (toolbar)); + gtk_container_set_border_width (GTK_CONTAINER (editor), 5); gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5); - + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), editor); - egg_editable_toolbar_set_edit_mode - (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), TRUE); + egg_editable_toolbar_set_edit_mode (toolbar, TRUE); g_signal_connect (dialog, "response", G_CALLBACK (ev_window_cmd_edit_toolbar_cb), @@ -3755,7 +3852,7 @@ ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); ev_view_zoom_in (EV_VIEW (ev_window->priv->view)); } @@ -3764,7 +3861,7 @@ ev_window_cmd_view_zoom_out (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); ev_view_zoom_out (EV_VIEW (ev_window->priv->view)); } @@ -3789,18 +3886,16 @@ ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_page_cache_set_current_page (ev_window->priv->page_cache, 0); + ev_document_model_set_page (ev_window->priv->model, 0); } static void ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window) { - int n_pages; - g_return_if_fail (EV_IS_WINDOW (ev_window)); - n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache); - ev_page_cache_set_current_page (ev_window->priv->page_cache, n_pages - 1); + ev_document_model_set_page (ev_window->priv->model, + ev_document_get_n_pages (ev_window->priv->document) - 1); } static void @@ -3810,11 +3905,12 @@ ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window) g_return_if_fail (EV_IS_WINDOW (ev_window)); - n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache); - current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + n_pages = ev_document_get_n_pages (ev_window->priv->document); + current_page = ev_document_model_get_page (ev_window->priv->model); - if (current_page + 10 < n_pages) - ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page + 10); + if (current_page + 10 < n_pages) { + ev_document_model_set_page (ev_window->priv->model, current_page + 10); + } } static void @@ -3824,16 +3920,17 @@ ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window) g_return_if_fail (EV_IS_WINDOW (ev_window)); - current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + current_page = ev_document_model_get_page (ev_window->priv->model); - if (current_page - 10 >= 0) - ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page - 10); + if (current_page - 10 >= 0) { + ev_document_model_set_page (ev_window->priv->model, current_page - 10); + } } static void ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) { - ev_window_reload_document (ev_window); + ev_window_reload_document (ev_window, NULL); } static void @@ -3849,7 +3946,7 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (ev_window)), "ghelp:evince", - GDK_CURRENT_TIME, + gtk_get_current_event_time (), &error); if (error) { ev_window_error_message (ev_window, error, @@ -3886,8 +3983,8 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) gboolean fullscreen; gboolean presentation; + fullscreen = ev_document_model_get_fullscreen (window->priv->model); g_object_get (window->priv->view, - "fullscreen", &fullscreen, "presentation", &presentation, NULL); @@ -3911,60 +4008,30 @@ save_sizing_mode (EvWindow *window) EvSizingMode mode; GEnumValue *enum_value; - mode = ev_view_get_sizing_mode (EV_VIEW (window->priv->view)); - enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode); + if (!window->priv->metadata || ev_window_is_empty (window)) + return; - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_string (window->priv->uri, "sizing_mode", - enum_value->value_nick); + mode = ev_document_model_get_sizing_mode (window->priv->model); + enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode); + ev_metadata_set_string (window->priv->metadata, "sizing_mode", + enum_value->value_nick); } static void -ev_window_set_view_size (EvWindow *window) +ev_window_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { - gint width, height; - GtkRequisition vsb_requisition; - GtkRequisition hsb_requisition; - gint scrollbar_spacing; - GtkWidget *scrolled_window = window->priv->scrolled_window; - - if (!window->priv->view) - return; - - /* Calculate the width available for the content */ - width = scrolled_window->allocation.width; - height = scrolled_window->allocation.height; - - if (gtk_scrolled_window_get_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window)) == GTK_SHADOW_IN) { - width -= 2 * window->priv->view->style->xthickness; - height -= 2 * window->priv->view->style->ythickness; - } - - gtk_widget_size_request (GTK_SCROLLED_WINDOW (scrolled_window)->vscrollbar, - &vsb_requisition); - gtk_widget_size_request (GTK_SCROLLED_WINDOW (scrolled_window)->hscrollbar, - &hsb_requisition); - gtk_widget_style_get (scrolled_window, - "scrollbar_spacing", - &scrollbar_spacing, - NULL); - - ev_view_set_zoom_for_size (EV_VIEW (window->priv->view), - MAX (1, width), - MAX (1, height), - vsb_requisition.width + scrollbar_spacing, - hsb_requisition.height + scrollbar_spacing); + ev_window_set_document (ev_window, + ev_document_model_get_document (model)); } -static void -ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, - EvWindow *ev_window) +static void +ev_window_sizing_mode_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { - EvSizingMode sizing_mode; - - g_object_get (ev_window->priv->view, - "sizing-mode", &sizing_mode, - NULL); + EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model); g_object_set (ev_window->priv->scrolled_window, "hscrollbar-policy", @@ -3977,17 +4044,20 @@ ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, save_sizing_mode (ev_window); } -static void -ev_window_zoom_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) +static void +ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window) { ev_window_update_actions (ev_window); - if (ev_view_get_sizing_mode (view) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) { + if (!ev_window->priv->metadata) + return; + + if (ev_document_model_get_sizing_mode (model) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) { gdouble zoom; - zoom = ev_view_get_zoom (view); - zoom *= 72.0 / get_screen_dpi (GTK_WINDOW(ev_window)); - ev_metadata_manager_set_double (ev_window->priv->uri, "zoom", zoom); + zoom = ev_document_model_get_scale (model); + zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window)); + ev_metadata_set_double (ev_window->priv->metadata, "zoom", zoom); } } @@ -4000,7 +4070,7 @@ ev_window_update_continuous_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_continuous), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_continuous (EV_VIEW (window->priv->view))); + ev_document_model_get_continuous (window->priv->model)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_continuous), window); } @@ -4014,34 +4084,34 @@ ev_window_update_dual_page_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_dual), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_dual_page (EV_VIEW (window->priv->view))); + ev_document_model_get_dual_page (window->priv->model)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_dual), window); } -static void -ev_window_continuous_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) +static void +ev_window_continuous_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { ev_window_update_continuous_action (ev_window); - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_boolean (ev_window->priv->uri, "continuous", - ev_view_get_continuous (EV_VIEW (ev_window->priv->view))); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_boolean (ev_window->priv->metadata, "continuous", + ev_document_model_get_continuous (model)); } -static void -ev_window_rotation_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window) +static void +ev_window_rotation_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *window) { - int rotation; - - rotation = ev_view_get_rotation (EV_VIEW (window->priv->view)); + gint rotation = ev_document_model_get_rotation (model); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_int (window->priv->uri, "rotation", - rotation); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_int (window->priv->metadata, "rotation", + rotation); - ev_sidebar_thumbnails_refresh (EV_SIDEBAR_THUMBNAILS (window->priv->sidebar_thumbs), - rotation); ev_window_refresh_window_thumbnail (window, rotation); } @@ -4051,14 +4121,16 @@ ev_window_has_selection_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *w ev_window_update_actions (window); } -static void -ev_window_dual_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) +static void +ev_window_dual_mode_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { ev_window_update_dual_page_action (ev_window); - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_boolean (ev_window->priv->uri, "dual-page", - ev_view_get_dual_page (EV_VIEW (ev_window->priv->view))); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_boolean (ev_window->priv->metadata, "dual-page", + ev_document_model_get_dual_page (model)); } static char * @@ -4102,6 +4174,7 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) "Bryan Clark ", "Carlos Garcia Campos ", "Wouter Bolsterlee ", + "Christian Persch ", NULL }; @@ -4146,7 +4219,7 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) "name", _("Evince"), "version", VERSION, "copyright", - _("\xc2\xa9 1996-2007 The Evince authors"), + _("© 1996–2009 The Evince authors"), "license", license_trans, "website", "http://www.gnome.org/projects/evince", "comments", comments, @@ -4169,7 +4242,8 @@ ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window) active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, active); update_chrome_visibility (ev_window); - ev_metadata_manager_set_boolean (NULL, "show_toolbar", active); + if (ev_window->priv->metadata) + ev_metadata_set_boolean (ev_window->priv->metadata, "show_toolbar", active); } static void @@ -4207,8 +4281,8 @@ ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar, g_object_unref (current_page); - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_string (ev_window->priv->uri, "sidebar_page", id); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_string (ev_window->priv->metadata, "sidebar_page", id); } static void @@ -4225,8 +4299,9 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), GTK_WIDGET_VISIBLE (ev_sidebar)); - ev_metadata_manager_set_boolean (ev_window->priv->uri, "sidebar_visibility", - GTK_WIDGET_VISIBLE (ev_sidebar)); + if (ev_window->priv->metadata) + ev_metadata_set_boolean (ev_window->priv->metadata, "sidebar_visibility", + GTK_WIDGET_VISIBLE (ev_sidebar)); } } @@ -4366,7 +4441,7 @@ ev_window_update_find_status_message (EvWindow *ev_window) gint n_results; n_results = ev_job_find_get_n_results (EV_JOB_FIND (ev_window->priv->find_job), - ev_page_cache_get_current_page (ev_window->priv->page_cache)); + ev_document_model_get_page (ev_window->priv->model)); /* TRANS: Sometimes this could be better translated as "%d hit(s) on this page". Therefore this string contains plural cases. */ @@ -4469,8 +4544,8 @@ find_bar_search_changed_cb (EggFindBar *find_bar, if (search_string && search_string[0]) { ev_window->priv->find_job = ev_job_find_new (ev_window->priv->document, - ev_page_cache_get_current_page (ev_window->priv->page_cache), - ev_page_cache_get_n_pages (ev_window->priv->page_cache), + ev_document_model_get_page (ev_window->priv->model), + ev_document_get_n_pages (ev_window->priv->document), search_string, case_sensitive); g_signal_connect (ev_window->priv->find_job, "finished", @@ -4524,8 +4599,6 @@ zoom_control_changed_cb (EphyZoomAction *action, EvWindow *ev_window) { EvSizingMode mode; - - g_return_if_fail (EV_IS_WINDOW (ev_window)); if (zoom == EPHY_ZOOM_BEST_FIT) { mode = EV_SIZING_BEST_FIT; @@ -4535,12 +4608,11 @@ zoom_control_changed_cb (EphyZoomAction *action, mode = EV_SIZING_FREE; } - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), mode); - + ev_document_model_set_sizing_mode (ev_window->priv->model, mode); + if (mode == EV_SIZING_FREE) { - ev_view_set_zoom (EV_VIEW (ev_window->priv->view), - zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0, - FALSE); + ev_document_model_set_scale (ev_window->priv->model, + zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0); } } @@ -4588,15 +4660,13 @@ ev_window_drag_data_received (GtkWidget *widget, static void ev_window_finalize (GObject *object) { - GList *windows = ev_application_get_windows (EV_APP); + G_OBJECT_CLASS (ev_window_parent_class)->finalize (object); - if (windows == NULL) { + if (ev_window_n_copies == 0) { ev_application_shutdown (EV_APP); } else { - g_list_free (windows); + ev_window_n_copies--; } - - G_OBJECT_CLASS (ev_window_parent_class)->finalize (object); } static void @@ -4611,7 +4681,12 @@ ev_window_dispose (GObject *object) ev_window_media_player_key_pressed, window); } - + + if (priv->metadata) { + g_object_unref (priv->metadata); + priv->metadata = NULL; + } + if (priv->setup_document_idle > 0) { g_source_remove (priv->setup_document_idle); priv->setup_document_idle = 0; @@ -4661,9 +4736,12 @@ ev_window_dispose (GObject *object) priv->recent_ui_id = 0; - if (priv->page_cache) { - g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window); - priv->page_cache = NULL; + if (priv->model) { + g_signal_handlers_disconnect_by_func (priv->model, + ev_window_page_changed_cb, + window); + g_object_unref (priv->model); + priv->model = NULL; } if (priv->document) { @@ -4714,16 +4792,6 @@ ev_window_dispose (GObject *object) ev_window_close_dialogs (window); - if (window->priv->print_settings) { - g_object_unref (window->priv->print_settings); - window->priv->print_settings = NULL; - } - - if (window->priv->print_page_setup) { - g_object_unref (window->priv->print_page_setup); - window->priv->print_page_setup = NULL; - } - if (priv->link) { g_object_unref (priv->link); priv->link = NULL; @@ -4751,8 +4819,6 @@ ev_window_dispose (GObject *object) } if (priv->uri) { - /* Delete the uri if it's a temp symlink (open a copy) */ - ev_window_clear_temp_symlink (window); g_free (priv->uri); priv->uri = NULL; } @@ -4785,22 +4851,56 @@ ev_window_dispose (GObject *object) G_OBJECT_CLASS (ev_window_parent_class)->dispose (object); } +static void +menubar_deactivate_cb (GtkWidget *menubar, + EvWindow *window) +{ + g_signal_handlers_disconnect_by_func (menubar, + G_CALLBACK (menubar_deactivate_cb), + window); + + gtk_menu_shell_deselect (GTK_MENU_SHELL (menubar)); + + update_chrome_visibility (window); +} + static gboolean ev_window_key_press_event (GtkWidget *widget, GdkEventKey *event) { - EvWindow *ev_window = EV_WINDOW (widget); - gboolean handled = FALSE; + EvWindow *ev_window = EV_WINDOW (widget); + EvWindowPrivate *priv = ev_window->priv; + gboolean handled = FALSE; /* Propagate the event to the view first * It's needed to be able to type in * annot popups windows */ - if (ev_window->priv->view) { - g_object_ref (ev_window->priv->view); - if (GTK_WIDGET_IS_SENSITIVE (ev_window->priv->view)) - handled = gtk_widget_event (ev_window->priv->view, (GdkEvent*) event); - g_object_unref (ev_window->priv->view); + if (priv->view) { + g_object_ref (priv->view); + if (GTK_WIDGET_IS_SENSITIVE (priv->view)) + handled = gtk_widget_event (priv->view, (GdkEvent*) event); + g_object_unref (priv->view); + } + + if (!handled && !ev_view_get_presentation (EV_VIEW (priv->view))) { + guint modifier = event->state & gtk_accelerator_get_default_mod_mask (); + + if (priv->menubar_accel_keyval != 0 && + event->keyval == priv->menubar_accel_keyval && + modifier == priv->menubar_accel_modifier) { + if (!GTK_WIDGET_VISIBLE (priv->menubar)) { + g_signal_connect (priv->menubar, "deactivate", + G_CALLBACK (menubar_deactivate_cb), + ev_window); + + gtk_widget_show (priv->menubar); + gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menubar), + FALSE); + + handled = TRUE; + } + } } if (!handled) @@ -5059,6 +5159,8 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group) "icon_name", "text-x-generic", "visible_overflown", FALSE, NULL); + ev_page_action_set_model (EV_PAGE_ACTION (action), + window->priv->model); g_signal_connect (action, "activate_link", G_CALLBACK (activate_link_cb), window); gtk_action_group_add_action (group, action); @@ -5169,7 +5271,7 @@ sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links, NULL); action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION); - ev_page_action_set_model (EV_PAGE_ACTION (action), model); + ev_page_action_set_links_model (EV_PAGE_ACTION (action), model); g_object_unref (model); } @@ -5228,8 +5330,8 @@ window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer du 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); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "window_maximized", maximized); } return FALSE; @@ -5238,32 +5340,26 @@ window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer du static gboolean window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer dummy) { - char *uri = window->priv->uri; GdkWindowState state; - int x, y, width, height, document_width, document_height; + gdouble document_width, document_height; + + if (!window->priv->metadata) + return FALSE; 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) && window->priv->page_cache) { - ev_page_cache_get_max_width (window->priv->page_cache, - 0, 1.0, - &document_width); - ev_page_cache_get_max_height (window->priv->page_cache, - 0, 1.0, - &document_height); - ev_metadata_manager_set_double (uri, "window_width_ratio", - (double)width / document_width); - ev_metadata_manager_set_double (uri, "window_height_ratio", - (double)height / document_height); - - 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); + if (!ev_window_is_empty (window) && window->priv->document) { + ev_document_get_max_page_size (window->priv->document, + &document_width, &document_height); + ev_metadata_set_double (window->priv->metadata, "window_width_ratio", + (double)event->width / document_width); + ev_metadata_set_double (window->priv->metadata, "window_height_ratio", + (double)event->height / document_height); + ev_metadata_set_int (window->priv->metadata, "window_x", event->x); + ev_metadata_set_int (window->priv->metadata, "window_y", event->y); + ev_metadata_set_int (window->priv->metadata, "window_width", event->width); + ev_metadata_set_int (window->priv->metadata, "window_height", event->height); } } @@ -5311,7 +5407,8 @@ launch_action (EvWindow *window, EvLinkAction *action) context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ()); gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context), gtk_window_get_screen (GTK_WINDOW (window))); - gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), GDK_CURRENT_TIME); + gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), + gtk_get_current_event_time ()); file_list.data = file; if (!g_app_info_launch (app_info, &file_list, context, &error)) { @@ -5323,6 +5420,7 @@ launch_action (EvWindow *window, EvLinkAction *action) g_object_unref (app_info); g_object_unref (file); + /* FIXMEchpe: unref launch context? */ /* According to the PDF spec filename can be an executable. I'm not sure allowing to launch executables is a good idea though. -- marco */ @@ -5340,7 +5438,7 @@ launch_external_uri (EvWindow *window, EvLinkAction *action) gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context), gtk_window_get_screen (GTK_WINDOW (window))); gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), - GDK_CURRENT_TIME); + gtk_get_current_event_time ()); if (!g_strstr_len (uri, strlen (uri), "://") && !g_str_has_prefix (uri, "mailto:")) { @@ -5348,10 +5446,10 @@ launch_external_uri (EvWindow *window, EvLinkAction *action) /* Not a valid uri, assuming it's http */ http = g_strdup_printf ("http://%s", uri); - ret = g_app_info_launch_default_for_uri (http, NULL, &error); + ret = g_app_info_launch_default_for_uri (http, context, &error); g_free (http); } else { - ret = g_app_info_launch_default_for_uri (uri, NULL, &error); + ret = g_app_info_launch_default_for_uri (uri, context, &error); } if (ret == FALSE) { @@ -5359,6 +5457,8 @@ launch_external_uri (EvWindow *window, EvLinkAction *action) "%s", _("Unable to open external link")); g_error_free (error); } + + /* FIXMEchpe: unref launch context? */ } static void @@ -5378,7 +5478,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action) ev_link_action_get_dest (action), 0, NULL, - GDK_CURRENT_TIME); + gtk_get_current_event_time ()); g_free (uri); } @@ -5423,7 +5523,7 @@ view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window) if (!dest) return; - ev_window_cmd_file_open_copy_at_dest (window, dest); + ev_window_open_copy_at_dest (window, dest); } break; case EV_LINK_ACTION_TYPE_EXTERNAL_URI: @@ -5463,7 +5563,7 @@ ev_view_popup_cmd_open_link_new_window (GtkAction *action, EvWindow *window) if (!dest) return; - ev_window_cmd_file_open_copy_at_dest (window, dest); + ev_window_open_copy_at_dest (window, dest); } static void @@ -5509,6 +5609,15 @@ image_save_dialog_response_cb (GtkWidget *fc, format = get_gdk_pixbuf_format_by_extension (uri); } + if (format == NULL && g_strrstr (uri, ".") == NULL) { + /* no extension found and no extension provided within uri */ + format = get_gdk_pixbuf_format_by_extension (".png"); + if (format == NULL) { + /* no .png support, try .jpeg */ + format = get_gdk_pixbuf_format_by_extension (".jpeg"); + } + } + if (format == NULL) { ev_window_error_message (ev_window, NULL, "%s", @@ -5536,7 +5645,9 @@ image_save_dialog_response_cb (GtkWidget *fc, if (is_native) { filename = g_file_get_path (target_file); } else { - filename = ev_tmp_filename ("saveimage"); + /* Create a temporary local file to save to */ + if (ev_mkstemp ("saveimage.XXXXXX", &filename, &error) == -1) + goto has_error; } ev_document_doc_mutex_lock (); @@ -5549,6 +5660,7 @@ image_save_dialog_response_cb (GtkWidget *fc, g_free (file_format); g_object_unref (pixbuf); + has_error: if (error) { ev_window_error_message (ev_window, error, "%s", _("The image could not be saved.")); @@ -5646,7 +5758,7 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window) attachment = (EvAttachment *) l->data; - ev_attachment_open (attachment, screen, GDK_CURRENT_TIME, &error); + ev_attachment_open (attachment, screen, gtk_get_current_event_time (), &error); if (error) { ev_window_error_message (window, error, @@ -5681,7 +5793,7 @@ attachment_save_dialog_response_cb (GtkWidget *fc, for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) { EvAttachment *attachment; - GFile *save_to; + GFile *save_to = NULL; GError *error = NULL; attachment = (EvAttachment *) l->data; @@ -5689,15 +5801,17 @@ attachment_save_dialog_response_cb (GtkWidget *fc, if (is_native) { if (is_dir) { save_to = g_file_get_child (target_file, + /* FIXMEchpe: file name encoding! */ ev_attachment_get_name (attachment)); } else { save_to = g_object_ref (target_file); } } else { - save_to = ev_tmp_file_get ("saveattachment"); + save_to = ev_mkstemp_file ("saveattachment.XXXXXX", &error); } - ev_attachment_save (attachment, save_to, &error); + if (save_to) + ev_attachment_save (attachment, save_to, &error); if (error) { ev_window_error_message (ev_window, error, @@ -5803,6 +5917,52 @@ ev_window_media_player_key_pressed (EvWindow *window, } } +static EggToolbarsModel * +get_toolbars_model (void) +{ + EggToolbarsModel *toolbars_model; + gchar *toolbars_file; + gchar *toolbars_path; + gint i; + + toolbars_model = egg_toolbars_model_new (); + + toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE), + "evince_toolbar.xml", NULL); + toolbars_path = g_build_filename (ev_application_get_data_dir (EV_APP), + "evince-toolbar.xml", NULL); + egg_toolbars_model_load_names (toolbars_model, toolbars_path); + + if (!egg_toolbars_model_load_toolbars (toolbars_model, toolbars_file)) { + egg_toolbars_model_load_toolbars (toolbars_model, toolbars_path); + goto skip_conversion; + } + + /* Open item doesn't exist anymore, + * convert it to OpenRecent for compatibility + */ + for (i = 0; i < egg_toolbars_model_n_items (toolbars_model, 0); i++) { + const gchar *item; + + item = egg_toolbars_model_item_nth (toolbars_model, 0, i); + if (g_ascii_strcasecmp (item, "FileOpen") == 0) { + egg_toolbars_model_remove_item (toolbars_model, 0, i); + egg_toolbars_model_add_item (toolbars_model, 0, i, + "FileOpenRecent"); + egg_toolbars_model_save_toolbars (toolbars_model, toolbars_file, "1.0"); + break; + } + } + + skip_conversion: + g_free (toolbars_file); + g_free (toolbars_path); + + egg_toolbars_model_set_flags (toolbars_model, 0, EGG_TB_MODEL_NOT_REMOVABLE); + + return toolbars_model; +} + static void ev_window_init (EvWindow *ev_window) { @@ -5810,7 +5970,10 @@ ev_window_init (EvWindow *ev_window) GtkAccelGroup *accel_group; GError *error = NULL; GtkWidget *sidebar_widget; + EggToolbarsModel *toolbars_model; GObject *mpkeys; + gchar *ui_path; + gdouble dpi; g_signal_connect (ev_window, "configure_event", G_CALLBACK (window_configure_event_cb), NULL); @@ -5819,6 +5982,8 @@ ev_window_init (EvWindow *ev_window) ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window); + ev_window->priv->model = ev_document_model_new (); + ev_window->priv->page_mode = PAGE_MODE_DOCUMENT; ev_window->priv->title = ev_window_title_new (ev_window); @@ -5865,12 +6030,15 @@ ev_window_init (EvWindow *ev_window) gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager, action_group, 0); - if (!gtk_ui_manager_add_ui_from_file (ev_window->priv->ui_manager, - DATADIR"/evince-ui.xml", - &error)) { + ui_path = g_build_filename (ev_application_get_data_dir (EV_APP), + "evince-ui.xml", NULL); + if (!gtk_ui_manager_add_ui_from_file ( + ev_window->priv->ui_manager, ui_path, &error)) + { g_warning ("building menus failed: %s", error->message); g_error_free (error); } + g_free (ui_path); ev_window->priv->recent_manager = gtk_recent_manager_get_default (); ev_window->priv->recent_action_group = NULL; @@ -5887,12 +6055,14 @@ ev_window_init (EvWindow *ev_window) ev_window->priv->menubar, FALSE, FALSE, 0); - ev_window->priv->toolbar = GTK_WIDGET - (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR, - "ui-manager", ev_window->priv->ui_manager, - "popup-path", "/ToolbarPopup", - "model", ev_application_get_toolbars_model (EV_APP), - NULL)); + toolbars_model = get_toolbars_model (); + ev_window->priv->toolbar = GTK_WIDGET + (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR, + "ui-manager", ev_window->priv->ui_manager, + "popup-path", "/ToolbarPopup", + "model", toolbars_model, + NULL)); + g_object_unref (toolbars_model); egg_editable_toolbar_show (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), "DefaultToolBar"); @@ -5914,6 +6084,8 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->hpaned); ev_window->priv->sidebar = ev_sidebar_new (); + ev_sidebar_set_model (EV_SIDEBAR (ev_window->priv->sidebar), + ev_window->priv->model); gtk_paned_pack1 (GTK_PANED (ev_window->priv->hpaned), ev_window->priv->sidebar, FALSE, FALSE); gtk_widget_show (ev_window->priv->sidebar); @@ -5981,8 +6153,10 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->view_box); ev_window->priv->view = ev_view_new (); - ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view), - get_screen_dpi (GTK_WINDOW (ev_window))); + ev_view_set_model (EV_VIEW (ev_window->priv->view), ev_window->priv->model); + dpi = get_screen_dpi (GTK_WINDOW (ev_window)); + ev_document_model_set_min_scale (ev_window->priv->model, MIN_SCALE * dpi / 72.0); + ev_document_model_set_max_scale (ev_window->priv->model, MAX_SCALE * dpi / 72.0); ev_window->priv->password_view = ev_password_view_new (GTK_WINDOW (ev_window)); g_signal_connect_swapped (ev_window->priv->password_view, "unlock", @@ -6000,9 +6174,6 @@ ev_window_init (EvWindow *ev_window) g_signal_connect_object (ev_window->priv->view, "handle-link", G_CALLBACK (view_handle_link_cb), ev_window, 0); - g_signal_connect_swapped (ev_window->priv->view, "zoom_invalid", - G_CALLBACK (ev_window_set_view_size), - ev_window); g_signal_connect_object (ev_window->priv->view, "popup", G_CALLBACK (view_menu_popup_cb), @@ -6023,26 +6194,37 @@ ev_window_init (EvWindow *ev_window) gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), ev_window->priv->view); - g_signal_connect (ev_window->priv->view, - "notify::sizing-mode", - G_CALLBACK (ev_window_sizing_mode_changed_cb), + /* Connect to model signals */ + g_signal_connect_swapped (ev_window->priv->model, + "page-changed", + G_CALLBACK (ev_window_page_changed_cb), + ev_window); + g_signal_connect (ev_window->priv->model, + "notify::document", + G_CALLBACK (ev_window_document_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, - "notify::zoom", + g_signal_connect (ev_window->priv->model, + "notify::scale", G_CALLBACK (ev_window_zoom_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, - "notify::dual-page", - G_CALLBACK (ev_window_dual_mode_changed_cb), + g_signal_connect (ev_window->priv->model, + "notify::sizing-mode", + G_CALLBACK (ev_window_sizing_mode_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, + g_signal_connect (ev_window->priv->model, + "notify::rotation", + G_CALLBACK (ev_window_rotation_changed_cb), + ev_window); + g_signal_connect (ev_window->priv->model, "notify::continuous", G_CALLBACK (ev_window_continuous_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, - "notify::rotation", - G_CALLBACK (ev_window_rotation_changed_cb), + g_signal_connect (ev_window->priv->model, + "notify::dual-page", + G_CALLBACK (ev_window_dual_mode_changed_cb), ev_window); + + /* Connect to view signals */ g_signal_connect (ev_window->priv->view, "notify::has-selection", G_CALLBACK (ev_window_has_selection_changed_cb), @@ -6104,13 +6286,15 @@ ev_window_init (EvWindow *ev_window) G_CALLBACK (ev_window_media_player_key_pressed), ev_window); } - + /* Give focus to the document view */ gtk_widget_grab_focus (ev_window->priv->view); /* Set it user interface params */ ev_window_setup_recent (ev_window); + ev_window_setup_gtk_settings (ev_window); + setup_chrome_from_metadata (ev_window); set_chrome_actions (ev_window); update_chrome_visibility (ev_window); @@ -6120,7 +6304,7 @@ ev_window_init (EvWindow *ev_window) setup_view_from_metadata (ev_window); setup_sidebar_from_metadata (ev_window); - ev_window_sizing_mode_changed_cb (EV_VIEW (ev_window->priv->view), NULL, ev_window); + ev_window_sizing_mode_changed_cb (ev_window->priv->model, NULL, ev_window); ev_window_setup_action_sensitivity (ev_window); /* Drag and Drop */