summaryrefslogtreecommitdiff
path: root/previewer
diff options
context:
space:
mode:
Diffstat (limited to 'previewer')
-rw-r--r--previewer/Makefile.am37
-rw-r--r--previewer/ev-previewer-window.c723
-rw-r--r--previewer/ev-previewer-window.h51
-rw-r--r--previewer/ev-previewer.c205
4 files changed, 1016 insertions, 0 deletions
diff --git a/previewer/Makefile.am b/previewer/Makefile.am
new file mode 100644
index 00000000..ab8f95d7
--- /dev/null
+++ b/previewer/Makefile.am
@@ -0,0 +1,37 @@
+
+bin_PROGRAMS = evince-previewer
+
+evince_previewer_SOURCES = \
+ ev-previewer.c \
+ ev-previewer-window.h \
+ ev-previewer-window.c
+
+evince_previewer_CPPFLAGS = \
+ -DEVINCEDATADIR=\"$(pkgdatadir)\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/libdocument \
+ -I$(top_srcdir)/libview \
+ -I$(top_srcdir)/libmisc \
+ $(AM_CPPFLAGS)
+
+evince_previewer_CFLAGS = \
+ $(PREVIEWER_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED) \
+ $(AM_CFLAGS)
+
+evince_previewer_LDFLAGS = $(AM_LDFLAGS)
+
+if PLATFORM_WIN32
+evince_previewer_LDFLAGS += -mwindows
+endif
+
+evince_previewer_LDADD = \
+ $(top_builddir)/libdocument/libevdocument.la \
+ $(top_builddir)/libview/libevview.la \
+ $(top_builddir)/libmisc/libevmisc.la \
+ $(PREVIEWER_LIBS)
+
+
+-include $(top_srcdir)/git.mk
diff --git a/previewer/ev-previewer-window.c b/previewer/ev-previewer-window.c
new file mode 100644
index 00000000..bfef10dc
--- /dev/null
+++ b/previewer/ev-previewer-window.c
@@ -0,0 +1,723 @@
+/* ev-previewer-window.c:
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#if GTKUNIXPRINT_ENABLED
+#include <gtk/gtkunixprint.h>
+#endif
+#include <glib/gi18n.h>
+#include <evince-view.h>
+#include "ev-page-action.h"
+
+#include "ev-previewer-window.h"
+
+struct _EvPreviewerWindow {
+ GtkWindow base_instance;
+
+ EvDocumentModel *model;
+ EvDocument *document;
+
+ GtkActionGroup *action_group;
+ GtkActionGroup *accels_group;
+ GtkUIManager *ui_manager;
+
+ GtkWidget *swindow;
+ EvView *view;
+ gdouble dpi;
+
+ /* Printing */
+ GtkPrintSettings *print_settings;
+ GtkPageSetup *print_page_setup;
+#if GTKUNIXPRINT_ENABLED
+ GtkPrinter *printer;
+#endif
+ gchar *print_job_title;
+ gchar *source_file;
+};
+
+struct _EvPreviewerWindowClass {
+ GtkWindowClass base_class;
+};
+
+enum {
+ PROP_0,
+ PROP_MODEL
+};
+
+#define MIN_SCALE 0.05409
+#define MAX_SCALE 4.0
+
+G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_WINDOW)
+
+static gdouble
+get_screen_dpi (EvPreviewerWindow *window)
+{
+ GdkScreen *screen;
+
+ screen = gtk_window_get_screen (GTK_WINDOW (window));
+ return ev_document_misc_get_screen_dpi (screen);
+}
+
+#if GTKUNIXPRINT_ENABLED
+static void
+ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
+ GError *error)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "%s", _("Failed to print document"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "%s", error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+#endif
+
+static void
+ev_previewer_window_close (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+static void
+ev_previewer_window_previous_page (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_view_previous_page (window->view);
+}
+
+static void
+ev_previewer_window_next_page (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_view_next_page (window->view);
+}
+
+static void
+ev_previewer_window_zoom_in (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE);
+ ev_view_zoom_in (window->view);
+}
+
+static void
+ev_previewer_window_zoom_out (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE);
+ ev_view_zoom_out (window->view);
+}
+
+static void
+ev_previewer_window_zoom_best_fit (GtkToggleAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_document_model_set_sizing_mode (window->model,
+ gtk_toggle_action_get_active (action) ?
+ EV_SIZING_BEST_FIT : EV_SIZING_FREE);
+}
+
+static void
+ev_previewer_window_zoom_page_width (GtkToggleAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_document_model_set_sizing_mode (window->model,
+ gtk_toggle_action_get_active (action) ?
+ EV_SIZING_FIT_WIDTH : EV_SIZING_FREE);
+}
+
+static void
+ev_previewer_window_action_page_activated (GtkAction *action,
+ EvLink *link,
+ EvPreviewerWindow *window)
+{
+ ev_view_handle_link (window->view, link);
+ gtk_widget_grab_focus (GTK_WIDGET (window->view));
+}
+
+static void
+ev_previewer_window_focus_page_selector (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ GtkAction *page_action;
+
+ page_action = gtk_action_group_get_action (window->action_group,
+ "PageSelector");
+ ev_page_action_grab_focus (EV_PAGE_ACTION (page_action));
+}
+
+static void
+ev_previewer_window_scroll_forward (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_view_scroll (window->view, GTK_SCROLL_PAGE_FORWARD, FALSE);
+}
+
+static void
+ev_previewer_window_scroll_backward (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ ev_view_scroll (window->view, GTK_SCROLL_PAGE_BACKWARD, FALSE);
+}
+
+#if GTKUNIXPRINT_ENABLED
+static void
+ev_previewer_window_print_finished (GtkPrintJob *print_job,
+ EvPreviewerWindow *window,
+ GError *error)
+{
+ if (error) {
+ ev_previewer_window_error_dialog_run (window, error);
+ }
+
+ g_object_unref (print_job);
+ gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+static void
+ev_previewer_window_do_print (EvPreviewerWindow *window)
+{
+ GtkPrintJob *job;
+ GError *error = NULL;
+
+ job = gtk_print_job_new (window->print_job_title ?
+ window->print_job_title :
+ window->source_file,
+ window->printer,
+ window->print_settings,
+ window->print_page_setup);
+ if (gtk_print_job_set_source_file (job, window->source_file, &error)) {
+ gtk_print_job_send (job,
+ (GtkPrintJobCompleteFunc)ev_previewer_window_print_finished,
+ window, NULL);
+ } else {
+ ev_previewer_window_error_dialog_run (window, error);
+ g_error_free (error);
+ }
+
+ gtk_widget_hide (GTK_WIDGET (window));
+}
+
+static void
+ev_previewer_window_enumerate_finished (EvPreviewerWindow *window)
+{
+ if (window->printer) {
+ ev_previewer_window_do_print (window);
+ } else {
+ GError *error = NULL;
+
+ g_set_error (&error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_GENERAL,
+ _("The selected printer '%s' could not be found"),
+ gtk_print_settings_get_printer (window->print_settings));
+
+ ev_previewer_window_error_dialog_run (window, error);
+ g_error_free (error);
+ }
+}
+
+static gboolean
+ev_previewer_window_enumerate_printers (GtkPrinter *printer,
+ EvPreviewerWindow *window)
+{
+ const gchar *printer_name;
+
+ printer_name = gtk_print_settings_get_printer (window->print_settings);
+ if ((printer_name
+ && strcmp (printer_name, gtk_printer_get_name (printer)) == 0) ||
+ (!printer_name && gtk_printer_is_default (printer))) {
+ if (window->printer)
+ g_object_unref (window->printer);
+ window->printer = g_object_ref (printer);
+
+ return TRUE; /* we're done */
+ }
+
+ return FALSE; /* continue the enumeration */
+}
+
+static void
+ev_previewer_window_print (GtkAction *action,
+ EvPreviewerWindow *window)
+{
+ if (!window->print_settings)
+ window->print_settings = gtk_print_settings_new ();
+ if (!window->print_page_setup)
+ window->print_page_setup = gtk_page_setup_new ();
+ gtk_enumerate_printers ((GtkPrinterFunc)ev_previewer_window_enumerate_printers,
+ window,
+ (GDestroyNotify)ev_previewer_window_enumerate_finished,
+ FALSE);
+}
+#endif
+
+static const GtkActionEntry action_entries[] = {
+ { "FileCloseWindow", GTK_STOCK_CLOSE, NULL, "<control>W",
+ NULL,
+ G_CALLBACK (ev_previewer_window_close) },
+ { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
+ N_("Go to the previous page"),
+ G_CALLBACK (ev_previewer_window_previous_page) },
+ { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
+ N_("Go to the next page"),
+ G_CALLBACK (ev_previewer_window_next_page) },
+ { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
+ N_("Enlarge the document"),
+ G_CALLBACK (ev_previewer_window_zoom_in) },
+ { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
+ N_("Shrink the document"),
+ G_CALLBACK (ev_previewer_window_zoom_out) },
+#if GTKUNIXPRINT_ENABLED
+ { "PreviewPrint", GTK_STOCK_PRINT, N_("Print"), NULL,
+ N_("Print this document"),
+ G_CALLBACK (ev_previewer_window_print) }
+#endif
+};
+
+static const GtkActionEntry accel_entries[] = {
+ { "Space", NULL, "", "space", NULL,
+ G_CALLBACK (ev_previewer_window_scroll_forward) },
+ { "ShiftSpace", NULL, "", "<shift>space", NULL,
+ G_CALLBACK (ev_previewer_window_scroll_backward) },
+ { "BackSpace", NULL, "", "BackSpace", NULL,
+ G_CALLBACK (ev_previewer_window_scroll_backward) },
+ { "ShiftBackSpace", NULL, "", "<shift>BackSpace", NULL,
+ G_CALLBACK (ev_previewer_window_scroll_forward) },
+ { "Return", NULL, "", "Return", NULL,
+ G_CALLBACK (ev_previewer_window_scroll_forward) },
+ { "ShiftReturn", NULL, "", "<shift>Return", NULL,
+ G_CALLBACK (ev_previewer_window_scroll_backward) },
+ { "p", GTK_STOCK_GO_UP, "", "p", NULL,
+ G_CALLBACK (ev_previewer_window_previous_page) },
+ { "n", GTK_STOCK_GO_DOWN, "", "n", NULL,
+ G_CALLBACK (ev_previewer_window_next_page) },
+ { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_in) },
+ { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "<control>equal", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_in) },
+ { "Equal", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_in) },
+ { "Minus", GTK_STOCK_ZOOM_OUT, NULL, "minus", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_out) },
+ { "KpPlus", GTK_STOCK_ZOOM_IN, NULL, "KP_Add", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_in) },
+ { "KpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_out) },
+ { "CtrlKpPlus", GTK_STOCK_ZOOM_IN, NULL, "<control>KP_Add", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_in) },
+ { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "<control>KP_Subtract", NULL,
+ G_CALLBACK (ev_previewer_window_zoom_out) },
+ { "FocusPageSelector", NULL, "", "<control>l", NULL,
+ G_CALLBACK (ev_previewer_window_focus_page_selector) }
+
+};
+
+static const GtkToggleActionEntry toggle_action_entries[] = {
+ { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
+ N_("Make the current document fill the window"),
+ G_CALLBACK (ev_previewer_window_zoom_best_fit) },
+ { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL,
+ N_("Make the current document fill the window width"),
+ G_CALLBACK (ev_previewer_window_zoom_page_width) }
+};
+
+static gboolean
+view_focus_changed (GtkWidget *widget,
+ GdkEventFocus *event,
+ EvPreviewerWindow *window)
+{
+ if (window->accels_group)
+ gtk_action_group_set_sensitive (window->accels_group, event->in);
+
+ return FALSE;
+}
+
+static void
+view_sizing_mode_changed (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvPreviewerWindow *window)
+{
+ EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model);
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (window->action_group, "ViewBestFit");
+ g_signal_handlers_block_by_func (action,
+ G_CALLBACK (ev_previewer_window_zoom_best_fit),
+ window);
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+ sizing_mode == EV_SIZING_BEST_FIT);
+ g_signal_handlers_unblock_by_func (action,
+ G_CALLBACK (ev_previewer_window_zoom_best_fit),
+ window);
+
+ action = gtk_action_group_get_action (window->action_group, "ViewPageWidth");
+ g_signal_handlers_block_by_func (action,
+ G_CALLBACK (ev_previewer_window_zoom_page_width),
+ window);
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+ sizing_mode == EV_SIZING_FIT_WIDTH);
+ g_signal_handlers_unblock_by_func (action,
+ G_CALLBACK (ev_previewer_window_zoom_page_width),
+ window);
+}
+
+static void
+ev_previewer_window_set_document (EvPreviewerWindow *window,
+ GParamSpec *pspec,
+ EvDocumentModel *model)
+{
+ EvDocument *document = ev_document_model_get_document (model);
+
+ window->document = g_object_ref (document);
+
+ g_signal_connect (model, "notify::sizing-mode",
+ G_CALLBACK (view_sizing_mode_changed),
+ window);
+ ev_view_set_loading (window->view, FALSE);
+ gtk_action_group_set_sensitive (window->action_group, TRUE);
+ gtk_action_group_set_sensitive (window->accels_group, TRUE);
+}
+
+static void
+ev_previewer_window_connect_action_accelerators (EvPreviewerWindow *window)
+{
+ GList *actions;
+
+ gtk_ui_manager_ensure_update (window->ui_manager);
+
+ actions = gtk_action_group_list_actions (window->action_group);
+ g_list_foreach (actions, (GFunc)gtk_action_connect_accelerator, NULL);
+ g_list_free (actions);
+}
+
+static void
+ev_previewer_window_dispose (GObject *object)
+{
+ EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
+
+ if (window->model) {
+ g_object_unref (window->model);
+ window->model = NULL;
+ }
+
+ if (window->document) {
+ g_object_unref (window->document);
+ window->document = NULL;
+ }
+
+ if (window->action_group) {
+ g_object_unref (window->action_group);
+ window->action_group = NULL;
+ }
+
+ if (window->accels_group) {
+ g_object_unref (window->accels_group);
+ window->accels_group = NULL;
+ }
+
+ if (window->ui_manager) {
+ g_object_unref (window->ui_manager);
+ window->ui_manager = NULL;
+ }
+
+ if (window->print_settings) {
+ g_object_unref (window->print_settings);
+ window->print_settings = NULL;
+ }
+
+ if (window->print_page_setup) {
+ g_object_unref (window->print_page_setup);
+ window->print_page_setup = NULL;
+ }
+
+#if GTKUNIXPRINT_ENABLED
+ if (window->printer) {
+ g_object_unref (window->printer);
+ window->printer = NULL;
+ }
+#endif
+
+ if (window->print_job_title) {
+ g_free (window->print_job_title);
+ window->print_job_title = NULL;
+ }
+
+ if (window->source_file) {
+ g_free (window->source_file);
+ window->source_file = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_previewer_window_parent_class)->dispose (object);
+}
+
+static gchar*
+data_dir (void)
+{
+ gchar *datadir;
+#ifdef G_OS_WIN32
+ gchar *dir;
+
+ dir = g_win32_get_package_installation_directory_of_module (NULL);
+ datadir = g_build_filename (dir, "share", "evince", NULL);
+ g_free (dir);
+#else
+ datadir = g_strdup (EVINCEDATADIR);
+#endif
+
+ return datadir;
+}
+
+static void
+ev_previewer_window_init (EvPreviewerWindow *window)
+{
+ gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
+}
+
+static void
+ev_previewer_window_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
+
+ switch (prop_id) {
+ case PROP_MODEL:
+ window->model = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GObject *
+ev_previewer_window_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ EvPreviewerWindow *window;
+ GtkWidget *vbox;
+ GtkWidget *toolbar;
+ GtkAction *action;
+ GError *error = NULL;
+ gchar *datadir, *ui_path;
+ gdouble dpi;
+
+ object = G_OBJECT_CLASS (ev_previewer_window_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_params);
+ window = EV_PREVIEWER_WINDOW (object);
+
+ dpi = get_screen_dpi (window);
+ ev_document_model_set_min_scale (window->model, MIN_SCALE * dpi / 72.0);
+ ev_document_model_set_max_scale (window->model, MAX_SCALE * dpi / 72.0);
+ ev_document_model_set_sizing_mode (window->model, EV_SIZING_FIT_WIDTH);
+ g_signal_connect_swapped (window->model, "notify::document",
+ G_CALLBACK (ev_previewer_window_set_document),
+ window);
+
+ window->action_group = gtk_action_group_new ("PreviewerActions");
+ gtk_action_group_set_translation_domain (window->action_group, NULL);
+ gtk_action_group_add_actions (window->action_group, action_entries,
+ G_N_ELEMENTS (action_entries),
+ window);
+ gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries,
+ G_N_ELEMENTS (toggle_action_entries),
+ window);
+ gtk_action_group_set_sensitive (window->action_group, FALSE);
+
+ action = g_object_new (EV_TYPE_PAGE_ACTION,
+ "name", "PageSelector",
+ "label", _("Page"),
+ "tooltip", _("Select Page"),
+ "icon_name", "text-x-generic",
+ "visible_overflown", FALSE,
+ NULL);
+ ev_page_action_set_model (EV_PAGE_ACTION (action), window->model);
+ g_signal_connect (action, "activate_link",
+ G_CALLBACK (ev_previewer_window_action_page_activated),
+ window);
+ gtk_action_group_add_action (window->action_group, action);
+ g_object_unref (action);
+
+ window->accels_group = gtk_action_group_new ("PreviewerAccelerators");
+ gtk_action_group_add_actions (window->accels_group, accel_entries,
+ G_N_ELEMENTS (accel_entries),
+ window);
+ gtk_action_group_set_sensitive (window->accels_group, FALSE);
+
+ window->ui_manager = gtk_ui_manager_new ();
+ gtk_ui_manager_insert_action_group (window->ui_manager,
+ window->action_group, 0);
+ gtk_ui_manager_insert_action_group (window->ui_manager,
+ window->accels_group, 1);
+ gtk_window_add_accel_group (GTK_WINDOW (window),
+ gtk_ui_manager_get_accel_group (window->ui_manager));
+ datadir = data_dir ();
+ ui_path = g_build_filename (datadir, "evince-previewer-ui.xml", NULL);
+ if (!gtk_ui_manager_add_ui_from_file (window->ui_manager, ui_path, &error)) {
+ g_warning ("Failed to load ui from evince-previewer-ui.xml: %s", error->message);
+ g_error_free (error);
+ }
+ g_free (ui_path);
+ g_free (datadir);
+
+ /* GTKUIManager connects actions accels only for menu items,
+ * but not for tool items. See bug #612972.
+ */
+ ev_previewer_window_connect_action_accelerators (window);
+
+ view_sizing_mode_changed (window->model, NULL, window);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+
+ toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/PreviewToolbar");
+ gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
+ gtk_widget_show (toolbar);
+
+ window->swindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window->swindow),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ window->view = EV_VIEW (ev_view_new ());
+ g_signal_connect_object (window->view, "focus_in_event",
+ G_CALLBACK (view_focus_changed),
+ window, 0);
+ g_signal_connect_object (window->view, "focus_out_event",
+ G_CALLBACK (view_focus_changed),
+ window, 0);
+ ev_view_set_model (window->view, window->model);
+ ev_document_model_set_continuous (window->model, FALSE);
+ ev_view_set_loading (window->view, TRUE);
+
+ gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view));
+ gtk_widget_show (GTK_WIDGET (window->view));
+
+ gtk_box_pack_start (GTK_BOX (vbox), window->swindow, TRUE, TRUE, 0);
+ gtk_widget_show (window->swindow);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+ gtk_widget_show (vbox);
+
+ return object;
+}
+
+
+static void
+ev_previewer_window_class_init (EvPreviewerWindowClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructor = ev_previewer_window_constructor;
+ gobject_class->set_property = ev_previewer_window_set_property;
+ gobject_class->dispose = ev_previewer_window_dispose;
+
+ g_object_class_install_property (gobject_class,
+ PROP_MODEL,
+ g_param_spec_object ("model",
+ "Model",
+ "The document model",
+ EV_TYPE_DOCUMENT_MODEL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+/* Public methods */
+GtkWidget *
+ev_previewer_window_new (EvDocumentModel *model)
+{
+ return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, "model", model, NULL));
+}
+
+void
+ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
+ const gchar *print_settings)
+{
+ if (window->print_settings)
+ g_object_unref (window->print_settings);
+ if (window->print_page_setup)
+ g_object_unref (window->print_page_setup);
+ if (window->print_job_title)
+ g_free (window->print_job_title);
+
+ if (print_settings && g_file_test (print_settings, G_FILE_TEST_IS_REGULAR)) {
+ GKeyFile *key_file;
+ GError *error = NULL;
+
+ key_file = g_key_file_new ();
+ g_key_file_load_from_file (key_file,
+ print_settings,
+ G_KEY_FILE_KEEP_COMMENTS |
+ G_KEY_FILE_KEEP_TRANSLATIONS,
+ &error);
+ if (!error) {
+ GtkPrintSettings *psettings;
+ GtkPageSetup *psetup;
+ gchar *job_name;
+
+ psettings = gtk_print_settings_new_from_key_file (key_file,
+ "Print Settings",
+ NULL);
+ window->print_settings = psettings ? psettings : gtk_print_settings_new ();
+
+ psetup = gtk_page_setup_new_from_key_file (key_file,
+ "Page Setup",
+ NULL);
+ window->print_page_setup = psetup ? psetup : gtk_page_setup_new ();
+
+ job_name = g_key_file_get_string (key_file,
+ "Print Job", "title",
+ NULL);
+ if (job_name) {
+ window->print_job_title = job_name;
+ gtk_window_set_title (GTK_WINDOW (window), job_name);
+ }
+ } else {
+ window->print_settings = gtk_print_settings_new ();
+ window->print_page_setup = gtk_page_setup_new ();
+ g_error_free (error);
+ }
+
+ g_key_file_free (key_file);
+ } else {
+ window->print_settings = gtk_print_settings_new ();
+ window->print_page_setup = gtk_page_setup_new ();
+ }
+}
+
+void
+ev_previewer_window_set_source_file (EvPreviewerWindow *window,
+ const gchar *source_file)
+{
+ if (window->source_file)
+ g_free (window->source_file);
+ window->source_file = g_strdup (source_file);
+}
diff --git a/previewer/ev-previewer-window.h b/previewer/ev-previewer-window.h
new file mode 100644
index 00000000..483d0245
--- /dev/null
+++ b/previewer/ev-previewer-window.h
@@ -0,0 +1,51 @@
+/* ev-previewer-window.h:
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef EV_PREVIEWER_WINDOW_H
+#define EV_PREVIEWER_WINDOW_H
+
+#include <gtk/gtk.h>
+
+#include <evince-document.h>
+#include <evince-view.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_PREVIEWER_WINDOW (ev_previewer_window_get_type())
+#define EV_PREVIEWER_WINDOW(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PREVIEWER_WINDOW, EvPreviewerWindow))
+#define EV_PREVIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PREVIEWER_WINDOW, EvPreviewerWindowClass))
+#define EV_IS_PREVIEWER_WINDOW(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PREVIEWER_WINDOW))
+#define EV_IS_PREVIEWER_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_PREVIEWER_WINDOW))
+#define EV_PREVIEWER_WINDOW_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_PREVIEWER_WINDOW, EvPreviewerWindowClass))
+
+typedef struct _EvPreviewerWindow EvPreviewerWindow;
+typedef struct _EvPreviewerWindowClass EvPreviewerWindowClass;
+
+GType ev_previewer_window_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_previewer_window_new (EvDocumentModel *model);
+
+void ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
+ const gchar *print_settings);
+void ev_previewer_window_set_source_file (EvPreviewerWindow *window,
+ const gchar *source_file);
+
+G_END_DECLS
+
+#endif /* EV_PREVIEWER_WINDOW_H */
diff --git a/previewer/ev-previewer.c b/previewer/ev-previewer.c
new file mode 100644
index 00000000..a836cf39
--- /dev/null
+++ b/previewer/ev-previewer.c
@@ -0,0 +1,205 @@
+/* ev-previewer.c:
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <evince-document.h>
+#include <evince-view.h>
+
+#include "ev-previewer-window.h"
+
+#ifdef G_OS_WIN32
+#include <io.h>
+#include <conio.h>
+#if !(_WIN32_WINNT >= 0x0500)
+#error "_WIN32_WINNT must be defined >= 0x0500"
+#endif
+#include <windows.h>
+#endif
+
+static gboolean unlink_temp_file = FALSE;
+static const gchar *print_settings;
+static const gchar **filenames;
+
+static const GOptionEntry goption_options[] = {
+ { "unlink-tempfile", 'u', 0, G_OPTION_ARG_NONE, &unlink_temp_file, N_("Delete the temporary file"), NULL },
+ { "print-settings", 'p', 0, G_OPTION_ARG_FILENAME, &print_settings, N_("Print settings file"), N_("FILE") },
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") },
+ { NULL }
+};
+
+static void
+ev_previewer_unlink_tempfile (const gchar *filename)
+{
+ GFile *file, *tempdir;
+
+ file = g_file_new_for_path (filename);
+ tempdir = g_file_new_for_path (g_get_tmp_dir ());
+
+ if (g_file_has_prefix (file, tempdir)) {
+ g_file_delete (file, NULL, NULL);
+ }
+
+ g_object_unref (file);
+ g_object_unref (tempdir);
+}
+
+static void
+ev_previewer_load_job_finished (EvJob *job,
+ EvDocumentModel *model)
+{
+ if (ev_job_is_failed (job)) {
+ g_warning ("%s", job->error->message);
+ g_object_unref (job);
+
+ return;
+ }
+ ev_document_model_set_document (model, job->document);
+ g_object_unref (job);
+}
+
+static void
+ev_previewer_load_document (const gchar *filename,
+ EvDocumentModel *model)
+{
+ EvJob *job;
+ gchar *uri;
+ GFile *file;
+
+ file = g_file_new_for_commandline_arg (filename);
+ uri = g_file_get_uri (file);
+ g_object_unref (file);
+
+ job = ev_job_load_new (uri);
+ g_signal_connect (job, "finished",
+ G_CALLBACK (ev_previewer_load_job_finished),
+ model);
+ ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
+ g_free (uri);
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+ GtkWidget *window;
+ GOptionContext *context;
+ const gchar *filename;
+ EvDocumentModel *model;
+ GError *error = NULL;
+
+#ifdef G_OS_WIN32
+ if (fileno (stdout) != -1 &&
+ _get_osfhandle (fileno (stdout)) != -1)
+ {
+ /* stdout is fine, presumably redirected to a file or pipe */
+ }
+ else
+ {
+ typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
+
+ AttachConsole_t p_AttachConsole =
+ (AttachConsole_t) GetProcAddress (GetModuleHandle ("kernel32.dll"), "AttachConsole");
+
+ if (p_AttachConsole != NULL && p_AttachConsole (ATTACH_PARENT_PROCESS))
+ {
+ freopen ("CONOUT$", "w", stdout);
+ dup2 (fileno (stdout), 1);
+ freopen ("CONOUT$", "w", stderr);
+ dup2 (fileno (stderr), 2);
+
+ }
+ }
+#endif
+
+ /* Init glib threads asap */
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+
+#ifdef ENABLE_NLS
+ /* Initialize the i18n stuff */
+ bindtextdomain (GETTEXT_PACKAGE, ev_get_locale_dir());
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+#endif
+
+ context = g_option_context_new (_("MATE Document Previewer"));
+ g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
+ g_option_context_add_main_entries (context, goption_options, GETTEXT_PACKAGE);
+
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_warning ("Error parsing command line arguments: %s", error->message);
+ g_error_free (error);
+ g_option_context_free (context);
+
+ return 1;
+ }
+ g_option_context_free (context);
+
+ if (!filenames) {
+ g_warning ("File argument is required");
+
+ return 1;
+ }
+
+ filename = filenames[0];
+
+ if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
+ g_warning ("Filename \"%s\" does not exist or is not a regular file", filename);
+
+ return 1;
+ }
+
+ if (!ev_init ())
+ return 1;
+
+ ev_stock_icons_init ();
+
+ g_set_application_name (_("MATE Document Previewer"));
+ gtk_window_set_default_icon_name ("evince");
+
+ model = ev_document_model_new ();
+ window = ev_previewer_window_new (model);
+ ev_previewer_window_set_source_file (EV_PREVIEWER_WINDOW (window), filename);
+ ev_previewer_window_set_print_settings (EV_PREVIEWER_WINDOW (window), print_settings);
+ g_signal_connect (window, "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_show (window);
+
+ ev_previewer_load_document (filename, model);
+
+ gtk_main ();
+
+ if (unlink_temp_file)
+ ev_previewer_unlink_tempfile (filename);
+ if (print_settings)
+ ev_previewer_unlink_tempfile (print_settings);
+
+ ev_shutdown ();
+ ev_stock_icons_shutdown ();
+ g_object_unref (model);
+
+ return 0;
+}