ev-window.c 176 KB
Newer Older
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
2 3
/* this file is part of evince, a gnome document viewer
 *
4
 *  Copyright (C) 2008 Carlos Garcia Campos
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
5
 *  Copyright (C) 2004 Martin Kretzschmar
6
 *  Copyright (C) 2004 Red Hat, Inc.
7
 *  Copyright (C) 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti
8
 *  Copyright (C) 2003, 2004, 2005 Christian Persch
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *
 *  Author:
 *    Martin Kretzschmar <martink@gnome.org>
 *
 * Evince is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Evince is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

32 33 34 35 36 37 38 39 40
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <glib/gstdio.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
41
#if GTK_CHECK_VERSION (2, 14, 0)
42
#include <gtk/gtkunixprint.h>
43 44 45
#else
#include <gtk/gtkprintunixdialog.h>
#endif
46
#ifdef WITH_GCONF
47
#include <gconf/gconf-client.h>
48
#endif
49

50
#include "egg-editable-toolbar.h"
51
#include "egg-toolbar-editor.h"
52
#include "egg-toolbars-model.h"
53 54 55

#include "eggfindbar.h"

56
#include "ephy-zoom-action.h"
57 58
#include "ephy-zoom.h"

59
#include "ev-application.h"
60 61 62 63 64 65
#include "ev-document-factory.h"
#include "ev-document-find.h"
#include "ev-document-fonts.h"
#include "ev-document-images.h"
#include "ev-document-links.h"
#include "ev-document-thumbnails.h"
66
#include "ev-document-type-builtins.h"
67
#include "ev-file-exporter.h"
68
#include "ev-file-helpers.h"
69
#include "ev-file-monitor.h"
70
#include "ev-history.h"
71
#include "ev-image.h"
72 73
#include "ev-job-scheduler.h"
#include "ev-jobs.h"
74
#include "ev-message-area.h"
75
#include "ev-metadata-manager.h"
76
#include "ev-mount-operation.h"
77 78 79 80 81 82 83 84 85 86
#include "ev-navigation-action.h"
#include "ev-open-recent-action.h"
#include "ev-page-action.h"
#include "ev-password-view.h"
#include "ev-properties-dialog.h"
#include "ev-sidebar-attachments.h"
#include "ev-sidebar.h"
#include "ev-sidebar-links.h"
#include "ev-sidebar-page.h"
#include "ev-sidebar-thumbnails.h"
87
#include "ev-sidebar-layers.h"
88 89
#include "ev-stock-icons.h"
#include "ev-utils.h"
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
90
#include "ev-keyring.h"
91
#include "ev-view.h"
92
#include "ev-view-type-builtins.h"
93 94
#include "ev-window.h"
#include "ev-window-title.h"
95
#include "ev-print-operation.h"
96
#include "ev-progress-message-area.h"
97

98 99 100
#ifdef ENABLE_DBUS
#include "ev-media-player-keys.h"
#endif /* ENABLE_DBUS */
101

102
#ifdef ENABLE_PDF
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
103
#include <poppler.h>
104
#endif
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
105

106
typedef enum {
107 108
	PAGE_MODE_DOCUMENT,
	PAGE_MODE_PASSWORD
109
} EvWindowPageMode;
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
110

111 112 113
typedef enum {
	EV_CHROME_MENUBAR	= 1 << 0,
	EV_CHROME_TOOLBAR	= 1 << 1,
114
	EV_CHROME_FINDBAR	= 1 << 2,
115
	EV_CHROME_RAISE_TOOLBAR	= 1 << 3,
116 117 118
	EV_CHROME_FULLSCREEN_TOOLBAR	= 1 << 4,
	EV_CHROME_SIDEBAR	= 1 << 5,
	EV_CHROME_NORMAL	= EV_CHROME_MENUBAR | EV_CHROME_TOOLBAR | EV_CHROME_SIDEBAR
119 120
} EvChrome;

121 122 123 124 125 126
typedef enum {
	EV_SAVE_DOCUMENT,
	EV_SAVE_ATTACHMENT,
	EV_SAVE_IMAGE
} EvSaveType;

Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
127
struct _EvWindowPrivate {
128 129 130
	/* UI */
	EvChrome chrome;

Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
131
	GtkWidget *main_box;
132 133
	GtkWidget *menubar;
	GtkWidget *toolbar;
134
	GtkWidget *hpaned;
135
	GtkWidget *view_box;
136
	GtkWidget *sidebar;
137
	GtkWidget *find_bar;
138
	GtkWidget *scrolled_window;
139
	GtkWidget *view;
140
	GtkWidget *message_area;
141
	GtkWidget *password_view;
142
	GtkWidget *sidebar_thumbs;
143
	GtkWidget *sidebar_links;
144
	GtkWidget *sidebar_attachments;
145
	GtkWidget *sidebar_layers;
146

147 148 149 150
	/* Progress Messages */
	guint progress_idle;
	GCancellable *progress_cancellable;

151
	/* Dialogs */
152
	GtkWidget *properties;
153
	GtkWidget *print_dialog;
154

155
	/* UI Builders */
156 157 158 159 160 161 162
	GtkActionGroup   *action_group;
	GtkActionGroup   *view_popup_action_group;
	GtkActionGroup   *attachment_popup_action_group;
	GtkRecentManager *recent_manager;
	GtkActionGroup   *recent_action_group;
	guint             recent_ui_id;
	GtkUIManager     *ui_manager;
163

164
	/* Fullscreen mode */
165
	GtkWidget *fullscreen_toolbar;
166 167 168 169

	/* Presentation mode */
	guint      presentation_timeout_id;

170
	/* Popup view */
171
	GtkWidget *view_popup;
172
	EvLink    *link;
173
	EvImage   *image;
174

175 176
	/* Popup attachment */
	GtkWidget    *attachment_popup;
177
	GList        *attach_list;
178

179 180
	/* Document */
	char *uri;
181
	glong uri_mtime;
182
	char *local_uri;
183
	gboolean in_reload;
184
	EvFileMonitor *monitor;
185
	guint setup_document_idle;
186
	
187
	EvDocument *document;
188
	EvHistory *history;
189
	EvPageCache *page_cache;
190
	EvWindowPageMode page_mode;
191
	EvWindowTitle *title;
192

193 194 195 196 197
	/* Load params */
	EvLinkDest       *dest;
	gchar            *search_string;
	EvWindowRunMode   window_mode;

198
	EvJob            *load_job;
199
	EvJob            *reload_job;
200 201
	EvJob            *thumbnail_job;
	EvJob            *save_job;
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
202
	EvJob            *find_job;
203 204

	/* Printing */
205
	GQueue           *print_queue;
206 207 208
	GtkPrinter       *printer;
	GtkPrintSettings *print_settings;
	GtkPageSetup     *print_page_setup;
209
	gboolean          close_after_print;
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
210
};
211

212 213 214
#define EV_WINDOW_GET_PRIVATE(object) \
	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_WINDOW, EvWindowPrivate))

215
#define PAGE_SELECTOR_ACTION	"PageSelector"
216
#define ZOOM_CONTROL_ACTION	"ViewZoom"
217
#define NAVIGATION_ACTION	"Navigation"
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
218

219 220 221
#define GCONF_OVERRIDE_RESTRICTIONS "/apps/evince/override_restrictions"
#define GCONF_LOCKDOWN_SAVE         "/desktop/gnome/lockdown/disable_save_to_disk"
#define GCONF_LOCKDOWN_PRINT        "/desktop/gnome/lockdown/disable_printing"
222

223
#define PRESENTATION_TIMEOUT 5
224

225
#define SIDEBAR_DEFAULT_SIZE    132
226 227
#define LINKS_SIDEBAR_ID "links"
#define THUMBNAILS_SIDEBAR_ID "thumbnails"
228
#define ATTACHMENTS_SIDEBAR_ID "attachments"
229
#define LAYERS_SIDEBAR_ID "layers"
230

231 232 233 234 235 236 237 238
static const gchar *document_print_settings[] = {
	GTK_PRINT_SETTINGS_N_COPIES,
	GTK_PRINT_SETTINGS_COLLATE,
	GTK_PRINT_SETTINGS_REVERSE,
	GTK_PRINT_SETTINGS_NUMBER_UP,
	GTK_PRINT_SETTINGS_SCALE,
	GTK_PRINT_SETTINGS_PRINT_PAGES,
	GTK_PRINT_SETTINGS_PAGE_RANGES,
239 240
	GTK_PRINT_SETTINGS_PAGE_SET,
	GTK_PRINT_SETTINGS_OUTPUT_URI
241 242
};

243
static void	ev_window_update_actions	 	(EvWindow         *ev_window);
244 245 246 247 248
static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_sidebar,
							 GParamSpec       *pspec,
							 EvWindow         *ev_window);
static void     ev_window_set_page_mode                 (EvWindow         *window,
							 EvWindowPageMode  page_mode);
249
static void	ev_window_load_job_cb  			(EvJob            *job,
250
							 gpointer          data);
251
static void     ev_window_reload_document               (EvWindow         *window);
252
static void     ev_window_reload_job_cb                 (EvJob            *job,
253
							 EvWindow         *window);
254 255
static void     ev_window_set_icon_from_thumbnail       (EvJobThumbnail   *job,
							 EvWindow         *ev_window);
256
static void     ev_window_save_job_cb                   (EvJob            *save,
257
							 EvWindow         *window);
258 259 260
static void     ev_window_sizing_mode_changed_cb        (EvView           *view,
							 GParamSpec       *pspec,
							 EvWindow         *ev_window);
261 262 263
static void     ev_window_zoom_changed_cb 	        (EvView           *view,
							 GParamSpec       *pspec,
							 EvWindow         *ev_window);
264 265
static void     ev_window_add_recent                    (EvWindow         *window,
							 const char       *filename);
266
static void     ev_window_run_fullscreen                (EvWindow         *window);
267 268
static void     ev_window_stop_fullscreen               (EvWindow         *window,
							 gboolean          unfullscreen_window);
269 270 271
static void     ev_window_cmd_view_fullscreen           (GtkAction        *action,
							 EvWindow         *window);
static void     ev_window_run_presentation              (EvWindow         *window);
272 273
static void     ev_window_stop_presentation             (EvWindow         *window,
							 gboolean          unfullscreen_window);
274 275
static void     ev_window_cmd_view_presentation         (GtkAction        *action,
							 EvWindow         *window);
276
static void     ev_view_popup_cmd_open_link             (GtkAction        *action,
277
							 EvWindow         *window);
278 279
static void     ev_view_popup_cmd_open_link_new_window  (GtkAction        *action,
							 EvWindow         *window);
280
static void     ev_view_popup_cmd_copy_link_address     (GtkAction        *action,
281
							 EvWindow         *window);
282 283 284 285
static void     ev_view_popup_cmd_save_image_as         (GtkAction        *action,
							 EvWindow         *window);
static void     ev_view_popup_cmd_copy_image            (GtkAction        *action,
							 EvWindow         *window);
286
static void	ev_attachment_popup_cmd_open_attachment (GtkAction        *action,
287 288 289
							 EvWindow         *window);
static void	ev_attachment_popup_cmd_save_attachment_as (GtkAction     *action, 
							 EvWindow         *window);
290 291 292 293
static void	ev_window_cmd_view_best_fit 		(GtkAction 	  *action, 
							 EvWindow 	  *ev_window);
static void	ev_window_cmd_view_page_width 		(GtkAction 	  *action, 
							 EvWindow 	  *ev_window);
294 295 296
static void	view_handle_link_cb 			(EvView           *view, 
							 EvLink           *link, 
							 EvWindow         *window);
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
297
static void     ev_window_update_find_status_message    (EvWindow         *ev_window);
298 299
static void     ev_window_cmd_edit_find                 (GtkAction        *action,
							 EvWindow         *ev_window);
300 301 302
static void     find_bar_search_changed_cb              (EggFindBar       *find_bar,
							 GParamSpec       *param,
							 EvWindow         *ev_window);
303 304
static void     ev_window_load_file_remote              (EvWindow         *ev_window,
							 GFile            *source_file);
305 306 307
static void     ev_window_media_player_key_pressed      (EvWindow         *window,
							 const gchar      *key,
							 gpointer          user_data);
308
static void     ev_window_save_print_page_setup         (EvWindow         *window);
309

Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
310 311
G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)

312
static void
313 314 315
ev_window_set_action_sensitive (EvWindow   *ev_window,
		    	        const char *name,
		  	        gboolean    sensitive)
316 317 318 319 320 321
{
	GtkAction *action = gtk_action_group_get_action (ev_window->priv->action_group,
							 name);
	gtk_action_set_sensitive (action, sensitive);
}

322

323
static void
324
ev_window_setup_action_sensitivity (EvWindow *ev_window)
325
{
326
	EvDocument *document = ev_window->priv->document;
327
	const EvDocumentInfo *info = NULL;
328 329

	gboolean has_document = FALSE;
330 331
	gboolean ok_to_print = TRUE;
	gboolean ok_to_copy = TRUE;
332
	gboolean has_properties = TRUE;
333
	gboolean override_restrictions = TRUE;
334
	gboolean can_get_text = FALSE;
335 336
	gboolean has_pages = FALSE;
	gboolean can_find = FALSE;
337
#ifdef WITH_GCONF
338
	GConfClient *client;
339
#endif
340

341 342
	if (document) {
		has_document = TRUE;
343
		info = ev_page_cache_get_info (ev_window->priv->page_cache);
344
	}
345

346
	if (has_document && ev_window->priv->page_cache) {
347 348 349 350 351 352 353
		has_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0;
	}

	if (!info || info->fields_mask == 0) {
		has_properties = FALSE;
	}

354
	if (has_document && EV_IS_SELECTION (document)) {
355 356 357
		can_get_text = TRUE;
	}
	
358
	if (has_pages && EV_IS_DOCUMENT_FIND (document)) {
359
		can_find = TRUE;
360
	}
361

362
#ifdef WITH_GCONF
363 364 365 366
	client = gconf_client_get_default ();
	override_restrictions = gconf_client_get_bool (client, 
						       GCONF_OVERRIDE_RESTRICTIONS, 
						       NULL);
367
#endif
368
	if (!override_restrictions && info && info->fields_mask & EV_DOCUMENT_INFO_PERMISSIONS) {
369 370 371 372
		ok_to_print = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT);
		ok_to_copy = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_COPY);
	}

373
	if (has_document && !EV_IS_FILE_EXPORTER(document))
374 375
		ok_to_print = FALSE;

376
#ifdef WITH_GCONF
377 378 379 380 381 382 383
	if (gconf_client_get_bool (client, GCONF_LOCKDOWN_SAVE, NULL)) {
		ok_to_copy = FALSE;
	}

	if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) {
		ok_to_print = FALSE;
	}
384

385
	g_object_unref (client);
386
#endif
387

388
	/* File menu */
389
	ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document);
390
	ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy);
391
	ev_window_set_action_sensitive (ev_window, "FilePrintSetup", has_pages && ok_to_print);
392 393
	ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print);
	ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties);
394

395
        /* Edit menu */
396
	ev_window_set_action_sensitive (ev_window, "EditSelectAll", has_pages && can_get_text);
397 398
	ev_window_set_action_sensitive (ev_window, "EditFind", can_find);
	ev_window_set_action_sensitive (ev_window, "Slash", can_find);
399 400
	ev_window_set_action_sensitive (ev_window, "EditRotateLeft", has_pages);
	ev_window_set_action_sensitive (ev_window, "EditRotateRight", has_pages);
401

402
        /* View menu */
403 404 405 406 407
	ev_window_set_action_sensitive (ev_window, "ViewContinuous", has_pages);
	ev_window_set_action_sensitive (ev_window, "ViewDual", has_pages);
	ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages);
	ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages);
	ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages);
408
	ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages);
409 410 411 412

	/* Toolbar-specific actions: */
	ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages);
	ev_window_set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION,  has_pages);
413
	ev_window_set_action_sensitive (ev_window, NAVIGATION_ACTION,  FALSE);
414 415 416 417 418 419 420 421 422 423

        ev_window_update_actions (ev_window);
}

static void
ev_window_update_actions (EvWindow *ev_window)
{
	EvView *view = EV_VIEW (ev_window->priv->view);
	int n_pages = 0, page = -1;
	gboolean has_pages = FALSE;
424
	gboolean presentation_mode;
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
425
	gboolean can_find_in_page = FALSE;
426 427 428 429 430 431 432

	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);
		has_pages = n_pages > 0;
	}

Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
433 434 435
	can_find_in_page = (ev_window->priv->find_job &&
			    ev_job_find_has_results (EV_JOB_FIND (ev_window->priv->find_job)));

436 437 438
	ev_window_set_action_sensitive (ev_window, "EditCopy",
					has_pages &&
					ev_view_get_has_selection (view));
439
	ev_window_set_action_sensitive (ev_window, "EditFindNext",
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
440
					has_pages && can_find_in_page);
441
	ev_window_set_action_sensitive (ev_window, "EditFindPrevious",
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
442
					has_pages && can_find_in_page);
443

444 445
	presentation_mode = ev_view_get_presentation (view);
	
446
	ev_window_set_action_sensitive (ev_window, "ViewZoomIn",
447 448 449
					has_pages &&
					ev_view_can_zoom_in (view) &&
					!presentation_mode);
450
	ev_window_set_action_sensitive (ev_window, "ViewZoomOut",
451 452 453 454
					has_pages &&
					ev_view_can_zoom_out (view) &&
					!presentation_mode);
	
455
        /* Go menu */
456 457 458 459 460
	if (has_pages) {
		ev_window_set_action_sensitive (ev_window, "GoPreviousPage", page > 0);
		ev_window_set_action_sensitive (ev_window, "GoNextPage", page < n_pages - 1);
		ev_window_set_action_sensitive (ev_window, "GoFirstPage", page > 0);
		ev_window_set_action_sensitive (ev_window, "GoLastPage", page < n_pages - 1);
461
	} else {
462 463 464 465
  		ev_window_set_action_sensitive (ev_window, "GoFirstPage", FALSE);
		ev_window_set_action_sensitive (ev_window, "GoPreviousPage", FALSE);
		ev_window_set_action_sensitive (ev_window, "GoNextPage", FALSE);
		ev_window_set_action_sensitive (ev_window, "GoLastPage", FALSE);
466
	}
467

468 469 470
	if (has_pages &&
	    ev_view_get_sizing_mode (view) != EV_SIZING_FIT_WIDTH &&
	    ev_view_get_sizing_mode (view) != EV_SIZING_BEST_FIT) {
471 472 473 474 475 476 477 478
		GtkAction *action;
		float      zoom;
		float      real_zoom;

		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));
479
		real_zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window));
480 481 482 483
		zoom = ephy_zoom_get_nearest_zoom_level (real_zoom);

		ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), zoom);
	}
484 485
}

486 487 488
static void
ev_window_set_view_accels_sensitivity (EvWindow *window, gboolean sensitive)
{
489
	gboolean can_find;
490

491 492 493
	can_find = window->priv->document && 
	    EV_IS_DOCUMENT_FIND (window->priv->document);

494 495 496 497 498 499 500 501 502 503 504 505 506 507
	if (window->priv->action_group) {
		ev_window_set_action_sensitive (window, "PageDown", sensitive);
		ev_window_set_action_sensitive (window, "PageUp", sensitive);
		ev_window_set_action_sensitive (window, "Space", sensitive);
		ev_window_set_action_sensitive (window, "ShiftSpace", sensitive);
		ev_window_set_action_sensitive (window, "BackSpace", sensitive);
		ev_window_set_action_sensitive (window, "ShiftBackSpace", sensitive);
		ev_window_set_action_sensitive (window, "Return", sensitive);
		ev_window_set_action_sensitive (window, "ShiftReturn", sensitive);
		ev_window_set_action_sensitive (window, "Plus", sensitive);
		ev_window_set_action_sensitive (window, "Minus", sensitive);
		ev_window_set_action_sensitive (window, "KpPlus", sensitive);
		ev_window_set_action_sensitive (window, "KpMinus", sensitive);
		ev_window_set_action_sensitive (window, "Equal", sensitive);
508 509

		ev_window_set_action_sensitive (window, "Slash", sensitive && can_find);
510 511 512
	}
}

513 514 515
static void
set_widget_visibility (GtkWidget *widget, gboolean visible)
{
516
	g_assert (GTK_IS_WIDGET (widget));
517
	
518 519 520 521 522 523
	if (visible)
		gtk_widget_show (widget);
	else
		gtk_widget_hide (widget);
}

524 525 526 527
static void
update_chrome_visibility (EvWindow *window)
{
	EvWindowPrivate *priv = window->priv;
528
	gboolean menubar, toolbar, findbar, fullscreen_toolbar, sidebar;
529 530 531 532 533
	gboolean fullscreen_mode, presentation, fullscreen;

	presentation = ev_view_get_presentation (EV_VIEW (priv->view));
	fullscreen = ev_view_get_fullscreen (EV_VIEW (priv->view));
	fullscreen_mode = fullscreen || presentation;
534

535
	menubar = (priv->chrome & EV_CHROME_MENUBAR) != 0 && !fullscreen_mode;
536 537
	toolbar = ((priv->chrome & EV_CHROME_TOOLBAR) != 0  || 
		   (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && !fullscreen_mode;
538 539
	fullscreen_toolbar = ((priv->chrome & EV_CHROME_FULLSCREEN_TOOLBAR) != 0 || 
			      (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && fullscreen;
540
	findbar = (priv->chrome & EV_CHROME_FINDBAR) != 0;
541
	sidebar = (priv->chrome & EV_CHROME_SIDEBAR) != 0 && !presentation;
542

543
	set_widget_visibility (priv->menubar, menubar);	
544
	set_widget_visibility (priv->toolbar, toolbar);
545
	set_widget_visibility (priv->find_bar, findbar);
546
	set_widget_visibility (priv->sidebar, sidebar);
547
	
548 549 550
	ev_window_set_action_sensitive (window, "EditToolbar", toolbar);
	gtk_widget_set_sensitive (priv->menubar, menubar);

551
	if (priv->fullscreen_toolbar != NULL) {
552
		set_widget_visibility (priv->fullscreen_toolbar, fullscreen_toolbar);
553
	}
554 555 556
}

static void
557
update_chrome_flag (EvWindow *window, EvChrome flag, gboolean active)
558 559 560 561 562
{
	EvWindowPrivate *priv = window->priv;
	
	if (active) {
		priv->chrome |= flag;
563
	} else {
564 565 566 567
		priv->chrome &= ~flag;
	}
}

568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
static void
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) {
584 585 586 587 588 589 590 591 592 593 594
	        case EV_SIZING_BEST_FIT:
			best_fit = TRUE;
			page_width = FALSE;
			break;
	        case EV_SIZING_FIT_WIDTH:
			best_fit = FALSE;
			page_width = TRUE;
			break;
	        default:
			best_fit = page_width = FALSE;
			break;
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
	}

	action = gtk_action_group_get_action (action_group, "ViewBestFit");
	g_signal_handlers_block_by_func
		(action, G_CALLBACK (ev_window_cmd_view_best_fit), window);
	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), best_fit);
	g_signal_handlers_unblock_by_func
		(action, G_CALLBACK (ev_window_cmd_view_best_fit), window);

	action = gtk_action_group_get_action (action_group, "ViewPageWidth");	
	g_signal_handlers_block_by_func
		(action, G_CALLBACK (ev_window_cmd_view_page_width), window);
	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), page_width);
	g_signal_handlers_unblock_by_func
		(action, G_CALLBACK (ev_window_cmd_view_page_width), window);

	action = gtk_action_group_get_action (window->priv->action_group, 
					      ZOOM_CONTROL_ACTION);	
	if (best_fit) {
		ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), 
						 EPHY_ZOOM_BEST_FIT);
	} else if (page_width) {
		ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), 
						 EPHY_ZOOM_FIT_WIDTH);
	}
}

622 623 624 625 626 627 628 629 630 631
/**
 * ev_window_is_empty:
 * @ev_window: The instance of the #EvWindow.
 *
 * It does look if there is any document loaded or if there is any job to load
 * a document.
 *
 * Returns: %TRUE if there isn't any document loaded or any any documente to be
 *          loaded, %FALSE in other case.
 */
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
632 633 634 635
gboolean
ev_window_is_empty (const EvWindow *ev_window)
{
	g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
636

637
	return (ev_window->priv->document == NULL) && 
638
		(ev_window->priv->load_job == NULL);
639 640
}

641
static void
642 643
ev_window_set_message_area (EvWindow  *window,
			    GtkWidget *area)
644
{
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
	if (window->priv->message_area == area)
		return;

	if (window->priv->message_area)
		gtk_widget_destroy (window->priv->message_area);
	window->priv->message_area = area;

	if (!area)
		return;

	gtk_box_pack_start (GTK_BOX (window->priv->view_box),
			    window->priv->message_area,
			    FALSE, FALSE, 0);
	gtk_box_reorder_child (GTK_BOX (window->priv->view_box),
			       window->priv->message_area, 0);
	g_object_add_weak_pointer (G_OBJECT (window->priv->message_area),
				   (gpointer) &(window->priv->message_area));
662 663
}

664
static void
665 666 667
ev_window_message_area_response_cb (EvMessageArea *area,
				    gint           response_id,
				    EvWindow      *window)
668
{
669 670
	ev_window_set_message_area (window, NULL);
}
671

672
static void
673 674 675 676
ev_window_error_message (EvWindow    *window,
			 GError      *error,
			 const gchar *format,
			 ...)
677 678
{
	GtkWidget *area;
679 680
	va_list    args;
	gchar     *msg = NULL;
681

682
	if (window->priv->message_area)
683 684
		return;

685 686 687 688
	va_start (args, format);
	msg = g_strdup_vprintf (format, args);
	va_end (args);
	
689 690 691
	area = ev_message_area_new (GTK_MESSAGE_ERROR,
				    msg,
				    GTK_STOCK_CLOSE,
692
				    GTK_RESPONSE_CLOSE,
693
				    NULL);
694 695
	g_free (msg);
	
696 697
	if (error)
		ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message);
698
	g_signal_connect (area, "response",
699 700 701
			  G_CALLBACK (ev_window_message_area_response_cb),
			  window);
	gtk_widget_show (area);
702
	ev_window_set_message_area (window, area);
703 704 705
}

static void
706 707 708
ev_window_warning_message (EvWindow    *window,
			   const gchar *format,
			   ...)
709 710
{
	GtkWidget *area;
711 712
	va_list    args;
	gchar     *msg = NULL;
713

714
	if (window->priv->message_area)
715 716
		return;

717 718 719 720
	va_start (args, format);
	msg = g_strdup_vprintf (format, args);
	va_end (args);

721 722 723
	area = ev_message_area_new (GTK_MESSAGE_WARNING,
				    msg,
				    GTK_STOCK_CLOSE,
724
				    GTK_RESPONSE_CLOSE,
725
				    NULL);
726
	g_free (msg);
727 728 729
	
	g_signal_connect (area, "response",
			  G_CALLBACK (ev_window_message_area_response_cb),
730 731
			  window);
	gtk_widget_show (area);
732
	ev_window_set_message_area (window, area);
Marco Pesenti Gritti's avatar
Marco Pesenti Gritti committed
733 734
}

735 736 737 738 739
static void
page_changed_cb (EvPageCache *page_cache,
		 gint         page,
		 EvWindow    *ev_window)
{
740
	ev_window_update_actions (ev_window);
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
741 742 743

	ev_window_update_find_status_message (ev_window);

744 745
	if (!ev_window_is_empty (ev_window))
		ev_metadata_manager_set_int (ev_window->priv->uri, "page", page);
746
}
747 748

typedef struct _FindTask {
749 750
	const gchar *page_label;
	gchar *chapter;
751 752 753 754 755 756 757 758
} FindTask;

static gboolean
ev_window_find_chapter (GtkTreeModel *tree_model,
		        GtkTreePath  *path,
		        GtkTreeIter  *iter,
		        gpointer      data)
{
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
	FindTask *task = (FindTask *)data;
	gchar *page_string;
	
	gtk_tree_model_get (tree_model, iter,
			    EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, &page_string, 
			    -1);
	
	if (!page_string)
		return FALSE;
	
	if (!strcmp (page_string, task->page_label)) {
		gtk_tree_model_get (tree_model, iter,
				    EV_DOCUMENT_LINKS_COLUMN_MARKUP, &task->chapter, 
				    -1);
		g_free (page_string);
		return TRUE;
	}
	
	g_free (page_string);
	return FALSE;
779 780 781 782 783
}

static void
ev_window_add_history (EvWindow *window, gint page, EvLink *link)
{
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
784
	gchar *page_label = NULL;
785 786 787 788 789 790
	gchar *link_title;
	FindTask find_task;
	EvLink *real_link;
	EvLinkAction *action;
	EvLinkDest *dest;
	
791 792
	if (window->priv->history == NULL)
		return;
793 794 795

	if (!EV_IS_DOCUMENT_LINKS (window->priv->document))
		return;
796
	
797 798 799 800
	if (link) {
		action = g_object_ref (ev_link_get_action (link));
		dest = ev_link_action_get_dest (action);
		page = ev_link_dest_get_page (dest);
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
801
		page_label = ev_view_page_label_from_dest (EV_VIEW (window->priv->view), dest);
802 803 804
	} else {
		dest = ev_link_dest_new_page (page);
		action = ev_link_action_new_dest (dest);
805
		page_label = ev_page_cache_get_page_label (window->priv->page_cache, page);
806 807
	}

808
	if (!page_label)
809 810 811 812 813
		return;
	
	find_task.page_label = page_label;
	find_task.chapter = NULL;
	
814
	if (ev_document_links_has_document_links (EV_DOCUMENT_LINKS (window->priv->document))) {
815 816 817 818
		GtkTreeModel *model;
	
		g_object_get (G_OBJECT (window->priv->sidebar_links), "model", &model, NULL);
		
819 820 821 822
		if (model) {
			gtk_tree_model_foreach (model,
						ev_window_find_chapter,
						&find_task);
823
	
824 825
			g_object_unref (model);
		}
826 827 828 829 830 831 832 833 834 835
	}

	if (find_task.chapter)
		link_title = g_strdup_printf (_("Page %s - %s"), page_label, find_task.chapter);
	else
		link_title = g_strdup_printf (_("Page %s"), page_label);
	
	real_link = ev_link_new (link_title, action);
	
	ev_history_add_link (window->priv->history, real_link);
Carlos Garcia Campos's avatar
Carlos Garcia Campos committed
836 837

	g_free (find_task.chapter);
838
	g_free (link_title);
839
	g_free (page_label);
840 841 842 843 844 845 846 847 848 849 850 851
	g_object_unref (real_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);
	
	ev_window_add_history (window, 0, link);
	ev_window_add_history (window, current_page, NULL);
}

852 853 854
static void
history_changed_cb (EvPageCache *page_cache,
		    gint         page,
855
		    EvWindow 	*window)
856
{
857 858 859 860 861
	int current_page = ev_page_cache_get_current_page (window->priv->page_cache);

	ev_window_add_history (window, page, NULL);
	ev_window_add_history (window, current_page, NULL);

862 863
	return;
}
864

865 866 867
static void
update_document_mode (EvWindow *window, EvDocumentMode mode)
{
868
	if (mode == EV_DOCUMENT_MODE_PRESENTATION) {
869
		ev_window_run_presentation (window);
870
	}
871
	else if (mode == EV_DOCUMENT_MODE_FULL_SCREEN) {
872
		ev_window_run_fullscreen (window);
873
	}
874 875
}

876 877 878 879 880 881 882
static void
setup_chrome_from_metadata (EvWindow *window)
{
	EvChrome chrome = EV_CHROME_NORMAL;
	GValue show_toolbar = { 0, };

	if (ev_metadata_manager_get (NULL, "show_toolbar", &show_toolbar, FALSE)) {
883
		if (!g_value_get_boolean (&show_toolbar))
884
			chrome &= ~EV_CHROME_TOOLBAR;
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
885
		g_value_unset (&show_toolbar);
886 887 888 889
	}
	window->priv->chrome = chrome;
}

890
static void
891
setup_sidebar_from_metadata (EvWindow *window)
892
{
893 894 895 896 897 898 899 900 901 902
	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, };
903

904
	if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size, FALSE)) {
905 906
		gtk_paned_set_position (GTK_PANED (window->priv->hpaned),
					g_value_get_int (&sidebar_size));
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
907
		g_value_unset(&sidebar_size);
908
	}
909
	
910
	if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, TRUE)) {
911
		const char *page_id = g_value_get_string (&sidebar_page);
912

913
		if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
914
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
915
		} else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
916
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs);
917
		} else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
918
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments);
919 920
		} 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);
921
		}
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
922
		g_value_unset (&sidebar_page);
923 924 925 926 927 928 929 930 931 932
	} else if (document) {
		if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
		} else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs);
		} else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments);
		} else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) {
			ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers);
		}
933 934
	}

935 936
	if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) {
		update_chrome_flag (window, EV_CHROME_SIDEBAR, g_value_get_boolean (&sidebar_visibility));
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
937
		g_value_unset (&sidebar_visibility);
938
		update_chrome_visibility (window);
939
	}
940 941
}

942
static void
943
setup_document_from_metadata (EvWindow *window)
944
{
945 946
	gchar *uri = window->priv->uri;
	GValue page = { 0, };
947 948
	GValue width = { 0, };
	GValue height = { 0, };
949 950
	GValue width_ratio = { 0, };
	GValue height_ratio = { 0, };
951

952 953 954 955 956 957 958 959 960 961 962 963 964
	/* 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
	 * 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);
965 966
	}

967
	setup_sidebar_from_metadata (window);
968

969 970 971
	if (ev_metadata_manager_get (uri, "window_width", &width, TRUE) &&
	    ev_metadata_manager_get (uri, "window_height", &height, TRUE))
		return; /* size was already set in setup_size_from_metadata */
972

973
	if (ev_metadata_manager_get (uri, "window_width_ratio", &width_ratio, FALSE) &&
974
	    ev_metadata_manager_get (uri, "window_height_ratio", &height_ratio, FALSE)) {
975 976
		gint       document_width;
		gint       document_height;
977
		GdkScreen *screen;
978 979
		gint       request_width;
		gint       request_height;
980 981 982 983 984 985 986 987

		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);			
		
988 989 990 991 992 993 994 995 996 997
		request_width = g_value_get_double (&width_ratio) * document_width;
		request_height = g_value_get_double (&height_ratio) * document_height;
		
		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));
		}
			        
998
		gtk_window_resize (GTK_WINDOW (window),
999 1000
				   request_width,
				   request_height);
1001 1002 1003 1004 1005 1006
	    	g_value_unset (&width_ratio);
		g_value_unset (&height_ratio);
	}
}

static void
1007
setup_size_from_metadata (EvWindow *window)
1008 1009
{
	char *uri = window->priv->uri;
1010 1011
	GValue width = { 0, };
	GValue height = { 0, };
1012
	GValue maximized = { 0, };
1013 1014
	GValue x = { 0, };
	GValue y = { 0, };
1015 1016 1017 1018

	if (ev_metadata_manager_get (uri, "window_maximized", &maximized, FALSE)) {
		if (g_value_get_boolean (&maximized)) {
			gtk_window_maximize (GTK_WINDOW (window));
1019 1020
			g_value_unset (&maximized);
			return;
1021 1022 1023 1024 1025 1026
		} else {
			gtk_window_unmaximize (GTK_WINDOW (window));
		}
		g_value_unset (&maximized);
	}

1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
	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_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);
	}
}

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, };

1059 1060 1061
	/* Sizing mode */
	if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) {
		enum_value = g_enum_get_value_by_nick
1062
			(g_type_class_peek (EV_TYPE_SIZING_MODE), g_value_get_string (&sizing_mode));
1063 1064 1065 1066 1067 1068 1069
		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) {
1070 1071 1072
		gdouble zoom_value;

		zoom_value = g_value_get_double (&zoom);
1073
		zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0;
1074
		ev_view_set_zoom (view, zoom_value, FALSE);
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
1075
		g_value_unset (&zoom);
1076 1077 1078 1079 1080
	}

	/* Continuous */
	if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) {
		ev_view_set_continuous (view, g_value_get_boolean (&continuous));
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
1081
		g_value_unset (&continuous);
1082 1083 1084 1085 1086
	}

	/* 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));
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
1087
		g_value_unset (&dual_page);
1088 1089 1090 1091
	}

	/* Presentation */
	if (ev_metadata_manager_get (uri, "presentation", &presentation, FALSE)) {
1092
		if (g_value_get_boolean (&presentation) && uri) {
1093 1094
			ev_window_run_presentation (window);
		}
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
1095
		g_value_unset (&presentation);
1096 1097 1098 1099
	}

	/* Fullscreen */
	if (ev_metadata_manager_get (uri, "fullscreen", &fullscreen, FALSE)) {
1100
		if (g_value_get_boolean (&fullscreen) && uri) {
1101 1102
			ev_window_run_fullscreen (window);
		}
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
1103
		g_value_unset (&fullscreen);
1104 1105 1106 1107 1108 1109
	}

	/* Rotation */
	if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) {
		if (g_value_get_int (&rotation)) {
			switch (g_value_get_int (&rotation)) {
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
			        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;
1121 1122
			}
		}
Ricardo Markiewicz's avatar
Ricardo Markiewicz committed
1123
		g_value_unset (&rotation);
1124 1125 1126
	}
}

1127 1128 1129 1130
static void
ev_window_clear_thumbnail_job (EvWindow *ev_window)
{
	if (ev_window->priv->thumbnail_job != NULL) {
1131 1132 1133
		if (!ev_job_is_finished (ev_window->priv->thumbnail_job))
			ev_job_cancel (ev_window->priv->thumbnail_job);
		
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
		g_signal_handlers_disconnect_by_func (ev_window->priv->thumbnail_job,
						      ev_window_set_icon_from_thumbnail,
						      ev_window);
		g_object_unref (ev_window->priv->thumbnail_job);
		ev_window->priv->thumbnail_job = NULL;
	}
}

static void
ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
				   EvWindow       *ev_window)
{
	if (job->thumbnail) {
		gtk_window_set_icon (GTK_WINDOW (ev_window),
				     job->thumbnail);
	}

	ev_window_clear_thumbnail_job (ev_window);
}

1154 1155 1156 1157 1158 1159 1160
static void
ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation)
{
	gint page_width, page_height;
	gdouble scale;
	EvDocument *document = ev_window->priv->document;
	
1161 1162
	if (!EV_IS_DOCUMENT_THUMBNAILS (document) ||
	    ev_page_cache_get_n_pages (ev_window->priv->page_cache) <= 0) {
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
		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;
	
1173
	ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale);
1174 1175 1176
	g_signal_connect (ev_window->priv->thumbnail_job, "finished",
			  G_CALLBACK (ev_window_set_icon_from_thumbnail),
			  ev_window);
1177
	ev_job_scheduler_push_job (ev_window->priv->thumbnail_job, EV_JOB_PRIORITY_NONE);
1178 1179
}

1180
static gboolean
1181 1182
ev_window_setup_document (EvWindow *ev_window)
{
1183
	const EvDocumentInfo *info;
1184
	EvDocument *document = ev_window->priv->document;
1185
	EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar);
1186
	GtkAction *action;
1187 1188

	ev_window->priv->setup_document_idle = 0;
1189
	
1190
	ev_window_refresh_window_thumbnail (ev_window, 0);
1191

1192
	ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT);
1193
	ev_window_title_set_document (ev_window->priv->title, document);
1194
	ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
1195

1196 1197
	ev_sidebar_set_document (sidebar, document);

1198 1199
	action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
	ev_page_action_set_document (EV_PAGE_ACTION (action), document);
1200
	ev_window_setup_action_sensitivity (ev_window);
1201

1202 1203 1204 1205 1206 1207
	if (ev_window->priv->history)
		g_object_unref (ev_window->priv->history);
	ev_window->priv->history = ev_history_new ();
	action = gtk_action_group_get_action (ev_window->priv->action_group, NAVIGATION_ACTION);
        ev_navigation_action_set_history (EV_NAVIGATION_ACTION (action), ev_window->priv->history);
	
1208
	if (ev_window->priv->properties) {
1209
		ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
1210
						   ev_window->priv->uri,
1211
					           ev_window->priv->document);
1212
	}
1213
	
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
	info = ev_page_cache_get_info (ev_window->priv->page_cache);
	update_document_mode (ev_window, info->mode);

	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)
		g_object_unref (ev_window->priv->document);
	ev_window->priv->document = g_object_ref (document);
1228 1229

	ev_window_set_message_area (ev_window, NULL);
1230 1231 1232 1233 1234 1235 1236
	
	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);

1237 1238 1239 1240 1241 1242 1243 1244 1245