]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-print-operation.c
Bump poppler requirement to 0.11.0
[evince.git] / shell / ev-print-operation.c
index af9cb677654a83d3fe38ae8ad2809688849e250f..3b9aa3a1cad15f51b50d29b5b345f659861af2db 100644 (file)
 
 #include "ev-print-operation.h"
 
-#if GTK_CHECK_VERSION (2, 14, 0)
 #include <gtk/gtkunixprint.h>
-#else
-#include <gtk/gtkprintunixdialog.h>
-#endif
-
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 #include <unistd.h>
@@ -341,6 +336,7 @@ GType           ev_print_operation_export_get_type (void) G_GNUC_CONST;
 
 static void     ev_print_operation_export_begin    (EvPrintOperationExport *export);
 static gboolean export_print_page                  (EvPrintOperationExport *export);
+static void     export_cancel                      (EvPrintOperationExport *export);
 
 struct _EvPrintOperationExport {
        EvPrintOperation parent;
@@ -575,12 +571,13 @@ find_range (EvPrintOperationExport *export)
        }
 }
 
-static void
+static gboolean
 clamp_ranges (EvPrintOperationExport *export)
 {
        gint num_of_correct_ranges = 0;
        gint n_pages_to_print = 0;
        gint i;
+       gboolean null_flag = FALSE;
 
        for (i = 0; i < export->n_ranges; i++) {
                gint n_pages;
@@ -611,16 +608,27 @@ clamp_ranges (EvPrintOperationExport *export)
                } else if (n_pages % 2 == 0) {
                        n_pages_to_print += n_pages / 2;
                } else if (export->page_set == GTK_PAGE_SET_EVEN) {
-                       n_pages_to_print += export->ranges[i].start % 2 == 0 ?
+                       if (n_pages==1 && export->ranges[i].start % 2 == 0)
+                               null_flag = TRUE;
+                       else 
+                               n_pages_to_print += export->ranges[i].start % 2 == 0 ?
                                n_pages / 2 : (n_pages / 2) + 1;
                } else if (export->page_set == GTK_PAGE_SET_ODD) {
-                       n_pages_to_print += export->ranges[i].start % 2 == 0 ?
+                       if (n_pages==1 && export->ranges[i].start % 2 != 0) 
+                               null_flag = TRUE;
+                       else 
+                               n_pages_to_print += export->ranges[i].start % 2 == 0 ?
                                (n_pages / 2) + 1 : n_pages / 2;
                }
        }
 
-       export->n_ranges = num_of_correct_ranges;
-       export->n_pages_to_print = n_pages_to_print;
+       if (null_flag && !n_pages_to_print) {
+               return FALSE;
+       } else {
+               export->n_ranges = num_of_correct_ranges;
+               export->n_pages_to_print = n_pages_to_print;
+               return TRUE;
+       }
 }
 
 static void
@@ -730,6 +738,7 @@ export_print_done (EvPrintOperationExport *export)
        EvPrintOperation *op = EV_PRINT_OPERATION (export);
        GtkPrintSettings *settings;
        EvFileExporterCapabilities capabilities;
+       GError *error = NULL;
 
        g_assert (export->temp_file != NULL);
        
@@ -760,49 +769,79 @@ export_print_done (EvPrintOperationExport *export)
        }
 
        if (export->print_preview) {
-               gchar *uri;
-               gchar *print_settings_file = NULL;
-
-               print_settings_file = ev_tmp_filename ("print-settings");
-               gtk_print_settings_to_file (settings, print_settings_file, NULL);
-
-               uri = g_filename_to_uri (export->temp_file, NULL, NULL);
-               ev_application_open_uri_at_dest (EV_APP,
-                                                uri,
-                                                gtk_window_get_screen (export->parent_window),
-                                                NULL,
-                                                EV_WINDOW_MODE_PREVIEW,
-                                                NULL,
-                                                TRUE,
-                                                print_settings_file,
-                                                GDK_CURRENT_TIME);
-               g_free (print_settings_file);
-               g_free (uri);
+               GKeyFile *key_file;
+               gchar    *data = NULL;
+               gsize     data_len;
+               gchar    *print_settings_file = NULL;
 
-               g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
-               /* temp_file will be deleted by the previewer */
+               key_file = g_key_file_new ();
 
-               ev_print_operation_export_run_next (export);
+               gtk_print_settings_to_key_file (settings, key_file, NULL);
+               gtk_page_setup_to_key_file (export->page_setup, key_file, NULL);
+               g_key_file_set_string (key_file, "Print Job", "title", export->job_name);
+
+               data = g_key_file_to_data (key_file, &data_len, &error);
+               if (data) {
+                       gint fd;
+                       
+                       fd = g_file_open_tmp ("print-settingsXXXXXX", &print_settings_file, &error);
+                       if (!error)
+                               g_file_set_contents (print_settings_file, data, data_len, &error);
+                       close (fd);
+                       
+                       g_free (data);
+               }
+
+               g_key_file_free (key_file);
+
+               if (!error) {
+                       gint    argc;
+                       gchar **argv;
+                       gchar  *cmd;
+                       gchar  *quoted_filename;
+                       gchar  *quoted_settings_filename;
+
+                       quoted_filename = g_shell_quote (export->temp_file);
+                       quoted_settings_filename = g_shell_quote (print_settings_file);
+                       cmd = g_strdup_printf ("evince-previewer --unlink-tempfile --print-settings %s %s",
+                                              quoted_settings_filename, quoted_filename);
+
+                       g_shell_parse_argv (cmd, &argc, &argv, &error);
+
+                       g_free (quoted_filename);
+                       g_free (quoted_settings_filename);
+                       g_free (cmd);
+
+                       if (!error) {
+                               gdk_spawn_on_screen (gtk_window_get_screen (export->parent_window),
+                                                    NULL, argv, NULL,
+                                                    G_SPAWN_SEARCH_PATH,
+                                                    NULL, NULL, NULL,
+                                                    &error);
+                       }
+
+                       g_strfreev (argv);
+               }
+
+               if (error) {
+                       if (print_settings_file)
+                               g_unlink (print_settings_file);
+                       g_free (print_settings_file);
+               } else {
+                       g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
+                       /* temp_file will be deleted by the previewer */
+
+                       ev_print_operation_export_run_next (export);
+               }
        } else {
                GtkPrintJob *job;
-               GError      *error = NULL;
                
                job = gtk_print_job_new (export->job_name,
                                         export->printer,
                                         settings,
                                         export->page_setup);
                gtk_print_job_set_source_file (job, export->temp_file, &error);
-               if (error) {
-                       g_set_error_literal (&export->error,
-                                            GTK_PRINT_ERROR,
-                                            GTK_PRINT_ERROR_GENERAL,
-                                            error->message);
-                       g_error_free (error);
-                       ev_print_operation_export_clear_temp_file (export);
-                       g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
-
-                       ev_print_operation_export_run_next (export);
-               } else {
+               if (!error){
                        gtk_print_job_send (job,
                                            (GtkPrintJobCompleteFunc)print_job_finished,
                                            g_object_ref (export),
@@ -810,6 +849,18 @@ export_print_done (EvPrintOperationExport *export)
                }
        }
        g_object_unref (settings);
+
+       if (error) {
+               g_set_error_literal (&export->error,
+                                    GTK_PRINT_ERROR,
+                                    GTK_PRINT_ERROR_GENERAL,
+                                    error->message);
+               g_error_free (error);
+               ev_print_operation_export_clear_temp_file (export);
+               g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
+
+               ev_print_operation_export_run_next (export);
+       }
 }
 
 static void
@@ -840,6 +891,12 @@ export_job_finished (EvJobExport            *job,
 static void
 export_job_cancelled (EvJobExport            *job,
                      EvPrintOperationExport *export)
+{
+       export_cancel (export);
+}
+
+static void
+export_cancel (EvPrintOperationExport *export)
 {
        EvPrintOperation *op = EV_PRINT_OPERATION (export);
 
@@ -847,15 +904,17 @@ export_job_cancelled (EvJobExport            *job,
                g_source_remove (export->idle_id);
        export->idle_id = 0;
 
-       g_signal_handlers_disconnect_by_func (export->job_export,
-                                             export_job_finished,
-                                             export);
-       g_signal_handlers_disconnect_by_func (export->job_export,
-                                             export_job_cancelled,
-                                             export);
-       g_object_unref (export->job_export);
-       export->job_export = NULL;
-
+       if (export->job_export) {
+               g_signal_handlers_disconnect_by_func (export->job_export,
+                                                     export_job_finished,
+                                                     export);
+               g_signal_handlers_disconnect_by_func (export->job_export,
+                                                     export_job_cancelled,
+                                                     export);
+               g_object_unref (export->job_export);
+               export->job_export = NULL;
+       }
+       
        if (export->fd != -1) {
                close (export->fd);
                export->fd = -1;
@@ -864,7 +923,7 @@ export_job_cancelled (EvJobExport            *job,
        ev_print_operation_export_clear_temp_file (export);
 
        g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
-       
+
        ev_print_operation_export_run_next (export);
 }
 
@@ -918,10 +977,10 @@ export_print_page (EvPrintOperationExport *export)
        
        if (!export->job_export) {
                export->job_export = ev_job_export_new (op->document);
-               g_signal_connect (G_OBJECT (export->job_export), "finished",
+               g_signal_connect (export->job_export, "finished",
                                  G_CALLBACK (export_job_finished),
                                  (gpointer)export);
-               g_signal_connect (G_OBJECT (export->job_export), "cancelled",
+               g_signal_connect (export->job_export, "cancelled",
                                  G_CALLBACK (export_job_cancelled),
                                  (gpointer)export);
        }
@@ -938,6 +997,9 @@ static void
 ev_print_operation_export_begin (EvPrintOperationExport *export)
 {
        EvPrintOperation *op = EV_PRINT_OPERATION (export);
+
+       if (!export->temp_file)
+               return; /* cancelled */
        
        ev_document_doc_mutex_lock ();
        ev_file_exporter_begin (EV_FILE_EXPORTER (op->document), &export->fc);
@@ -976,8 +1038,6 @@ ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dial
                return;
        }
 
-       ev_print_operation_update_status (op, -1, -1, 0.0);
-       
        export->print_preview = (response == GTK_RESPONSE_APPLY);
        
        printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog));
@@ -992,10 +1052,10 @@ ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dial
        if (!gtk_printer_accepts_ps (export->printer)) {
                gtk_widget_destroy (GTK_WIDGET (dialog));
                
-               g_set_error (&export->error,
-                            GTK_PRINT_ERROR,
-                            GTK_PRINT_ERROR_GENERAL,
-                            "%s", _("Printing is not supported on this printer."));
+               g_set_error_literal (&export->error,
+                                     GTK_PRINT_ERROR,
+                                     GTK_PRINT_ERROR_GENERAL,
+                                     _("Printing is not supported on this printer."));
                g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
                
                return;
@@ -1050,8 +1110,25 @@ ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dial
                
                break;
        }
-       clamp_ranges (export);
+       if (!clamp_ranges (export)) {
+               GtkWidget *message_dialog;
+
+               message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
+                                                GTK_DIALOG_MODAL,
+                                                GTK_MESSAGE_WARNING,
+                                                GTK_BUTTONS_CLOSE,
+                                                "%s", _("Invalid page selection"));
+               gtk_window_set_title (GTK_WINDOW (message_dialog), _("Warning"));
+               gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
+                                                         "%s", _("Your print range selection does not include any page"));
+               g_signal_connect (message_dialog, "response",
+                                 G_CALLBACK (gtk_widget_destroy),
+                                 NULL);
+               gtk_widget_show (message_dialog);
 
+               return;
+       } else  ev_print_operation_update_status (op, -1, -1, 0.0);
        width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
        height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
        scale = gtk_print_settings_get_scale (print_settings) * 0.01;
@@ -1060,7 +1137,7 @@ ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dial
                height *= scale;
        }
 
-       export->pages_per_sheet = gtk_print_settings_get_number_up (print_settings);
+       export->pages_per_sheet = MAX (1, gtk_print_settings_get_number_up (print_settings));
        
        export->copies = gtk_print_settings_get_n_copies (print_settings);
        export->collate = gtk_print_settings_get_collate (print_settings);
@@ -1088,7 +1165,7 @@ ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dial
 
        get_first_and_last_page (export, &first_page, &last_page);
 
-       export->fc.format = g_ascii_strcasecmp (file_format, "pdf") == 0 ?
+       export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
                EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
        export->fc.filename = export->temp_file;
        export->fc.first_page = MIN (first_page, last_page);
@@ -1096,7 +1173,7 @@ ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dial
        export->fc.paper_width = width;
        export->fc.paper_height = height;
        export->fc.duplex = FALSE;
-       export->fc.pages_per_sheet = MAX (1, export->pages_per_sheet);
+       export->fc.pages_per_sheet = export->pages_per_sheet;
 
        if (ev_print_queue_is_empty (op->document))
                ev_print_operation_export_begin (export);
@@ -1139,7 +1216,7 @@ ev_print_operation_export_run (EvPrintOperation *op,
                gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
                                                      export->page_setup);
        
-       g_signal_connect (G_OBJECT (dialog), "response",
+       g_signal_connect (dialog, "response",
                          G_CALLBACK (ev_print_operation_export_print_dialog_response_cb),
                          export);
 
@@ -1151,13 +1228,11 @@ ev_print_operation_export_cancel (EvPrintOperation *op)
 {
        EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
 
-       if (export->job_export) {
-               if (!ev_job_is_finished (export->job_export)) {
-                       ev_job_cancel (export->job_export);
-               } else {
-                       export_job_cancelled (EV_JOB_EXPORT (export->job_export),
-                                             export);
-               }
+       if (export->job_export &&
+           !ev_job_is_finished (export->job_export)) {
+               ev_job_cancel (export->job_export);
+       } else {
+               export_cancel (export);
        }
 }