#include "ev-print-operation.h"
+#if GTKUNIXPRINT_ENABLED
#include <gtk/gtkunixprint.h>
+#endif
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <unistd.h>
return op->progress;
}
+#if GTK_CHECK_VERSION (2, 17, 1) | GTKUNIXPRINT_ENABLED
static void
ev_print_operation_update_status (EvPrintOperation *op,
gint page,
g_signal_emit (op, signals[STATUS_CHANGED], 0);
}
+#endif
+
+#if GTKUNIXPRINT_ENABLED
/* Export interface */
#define EV_TYPE_PRINT_OPERATION_EXPORT (ev_print_operation_export_get_type())
gint n_pages_to_print;
gint uncollated_copies;
gint collated_copies;
- gint uncollated, collated, total, blank;
+ gint uncollated, collated, total;
+
+ gint sheet, page_count;
gint range, n_ranges;
GtkPageRange *ranges;
{
do {
export->page += export->inc;
+
+ /* note: when NOT collating, page_count is increased in export_print_page */
+ if (export->collate) {
+ export->page_count++;
+ export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
+ }
+
if (export->page == export->end) {
export->range += export->inc;
if (export->range == -1 || export->range == export->n_ranges) {
export->uncollated++;
+
+ /* when printing multiple collated copies & multiple pages per sheet we want to
+ * prevent the next copy bleeding into the last sheet of the previous one
+ * we've reached the last range to be printed now, so this is the time to do it */
+ if (export->pages_per_sheet > 1 && export->collate == 1 &&
+ (export->page_count - 1) % export->pages_per_sheet != 0) {
+
+ EvPrintOperation *op = EV_PRINT_OPERATION (export);
+ ev_document_doc_mutex_lock ();
+
+ /* keep track of all blanks but only actualise those
+ * which are in the current odd / even sheet set */
+
+ export->page_count += export->pages_per_sheet - (export->page_count - 1) % export->pages_per_sheet;
+ if (export->page_set == GTK_PAGE_SET_ALL ||
+ (export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
+ (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1) ) {
+ ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
+ }
+ ev_document_doc_mutex_unlock ();
+ export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
+ }
+
if (export->uncollated == export->uncollated_copies)
return FALSE;
find_range (export);
export->page = export->start;
}
- } while ((export->page_set == GTK_PAGE_SET_EVEN && (export->page / export->pages_per_sheet) % 2 == 0) ||
- (export->page_set == GTK_PAGE_SET_ODD && (export->page / export->pages_per_sheet) % 2 == 1));
+
+ /* in/decrement the page number until we reach the first page on the next EVEN or ODD sheet
+ * if we're not collating, we have to make sure that this is done only once! */
+ } while ( export->collate == 1 &&
+ ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 1) ||
+ (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 0)));
return TRUE;
}
{
EvPrintOperation *op = EV_PRINT_OPERATION (export);
- if (export->pages_per_sheet == 1 || (export->total + export->blank) % export->pages_per_sheet == 0 ) {
+ if (export->pages_per_sheet == 1 ||
+ ( export->page_count % export->pages_per_sheet == 0 &&
+ ( export->page_set == GTK_PAGE_SET_ALL ||
+ ( export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0 ) ||
+ ( export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1 ) ) ) ) {
+
ev_document_doc_mutex_lock ();
ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
ev_document_doc_mutex_unlock ();
if (!export->temp_file)
return FALSE; /* cancelled */
-
+
export->total++;
export->collated++;
- /* when printing multiple collated copies & multiple pages per sheet we want to
- prevent the next copy bleeding into the last sheet of the previous one
- we therefore check whether we've reached the last page in a document
- if that is the case and the given sheet is not filled with pages,
- we introduce a few blank pages to finish off the sheet
- to make sure nothing goes wrong, the final condition ensures that
- we're not at the end of a sheet, otherwise we'd introduce a blank sheet! */
-
- if (export->collate == 1 && export->total > 1 && export->pages_per_sheet > 1 &&
- (export->page + 1) % export->n_pages == 0 && (export->total - 1 + export->blank) % export->pages_per_sheet != 0) {
- ev_document_doc_mutex_lock ();
- ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
- /* keep track of how many blank pages have been added */
- export->blank += export->pages_per_sheet - (export->total - 1 + export->blank) % export->pages_per_sheet;
- ev_document_doc_mutex_unlock ();
+ /* note: when collating, page_count is increased in export_print_inc_page */
+ if (!export->collate) {
+ export->page_count++;
+ export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
}
-
if (export->collated == export->collated_copies) {
export->collated = 0;
if (!export_print_inc_page (export)) {
}
}
- if (export->pages_per_sheet == 1 || (export->total + export->blank) % export->pages_per_sheet == 1) {
+ /* we're not collating and we've reached a sheet from the wrong sheet set */
+ if (!export->collate &&
+ ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
+ (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1))) {
+
+ do {
+ export->page_count++;
+ export->collated++;
+ export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
+
+ if (export->collated == export->collated_copies) {
+ export->collated = 0;
+
+ if (!export_print_inc_page (export)) {
+ ev_document_doc_mutex_lock ();
+ ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
+ ev_document_doc_mutex_unlock ();
+
+ close (export->fd);
+ export->fd = -1;
+
+ update_progress (export);
+
+ export_print_done (export);
+ return FALSE;
+ }
+ }
+
+ } while ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
+ (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1));
+
+ }
+
+ if (export->pages_per_sheet == 1 ||
+ (export->page_count % export->pages_per_sheet == 1 &&
+ (export->page_set == GTK_PAGE_SET_ALL ||
+ (export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
+ (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1)))) {
ev_document_doc_mutex_lock ();
ev_file_exporter_begin_page (EV_FILE_EXPORTER (op->document));
ev_document_doc_mutex_unlock ();
}
-
+
if (!export->job_export) {
export->job_export = ev_job_export_new (op->document);
g_signal_connect (export->job_export, "finished",
file_format = gtk_print_settings_get (print_settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
- filename = g_strdup_printf ("evince_print.%s.XXXXXX", file_format);
+ filename = g_strdup_printf ("evince_print.%s.XXXXXX", file_format != NULL ? file_format : "");
export->fd = g_file_open_tmp (filename, &export->temp_file, &error);
g_free (filename);
if (export->fd <= -1) {
export->ranges[i].end = export->n_pages - 1;
}
break;
+ default:
+ g_warning ("Unsupported print pages setting\n");
case GTK_PRINT_PAGES_ALL:
export->ranges = &export->one_range;
break;
}
+
if (export->n_ranges < 1 || !clamp_ranges (export)) {
GtkWidget *message_dialog;
get_first_and_last_page (export, &first_page, &last_page);
- export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
- EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
+ if (file_format) {
+ export->fc.format = g_ascii_strcasecmp (file_format, "pdf") == 0 ?
+ EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
+ } else {
+ export->fc.format = gtk_printer_accepts_pdf (printer) ?
+ EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
+ }
export->fc.filename = export->temp_file;
export->fc.first_page = MIN (first_page, last_page);
export->fc.last_page = MAX (first_page, last_page);
static void
ev_print_operation_export_init (EvPrintOperationExport *export)
{
+ /* sheets are counted from 1 to be physical */
+ export->sheet = 1;
}
static GObject *
g_object_class->finalize = ev_print_operation_export_finalize;
}
+#endif /* GTKUNIXPRINT_ENABLED */
+
#if GTK_CHECK_VERSION (2, 17, 1)
/* Print to cairo interface */
#define EV_TYPE_PRINT_OPERATION_PRINT (ev_print_operation_print_get_type())
EvPrintOperation parent;
GtkPrintOperation *op;
+ gint n_pages_to_print;
+ gint total;
EvJob *job_print;
gchar *job_name;
};
n_pages = ev_page_cache_get_n_pages (ev_page_cache_get (op->document));
gtk_print_operation_set_n_pages (print->op, n_pages);
-
- /* FIXME: gtk_print should provide the progress */
ev_print_operation_update_status (op, -1, n_pages, 0);
g_signal_emit (op, signals[BEGIN_PRINT], 0);
{
EvPrintOperation *op = EV_PRINT_OPERATION (print);
- /* FIXME: gtk_print should provide the progress */
- ev_print_operation_update_status (op, 0, 1, 1.0);
+ ev_print_operation_update_status (op, 0, print->n_pages_to_print, 1.0);
g_signal_emit (op, signals[DONE], 0, result);
}
+static void
+ev_print_operation_print_status_changed (EvPrintOperationPrint *print)
+{
+#ifdef HAVE_GTK_PRINT_OPERATION_GET_N_PAGES_TO_PRINT
+ GtkPrintStatus status;
+
+ status = gtk_print_operation_get_status (print->op);
+ if (status == GTK_PRINT_STATUS_GENERATING_DATA)
+ print->n_pages_to_print = gtk_print_operation_get_n_pages_to_print (print->op);
+#endif
+}
+
static void
print_job_finished (EvJobPrint *job,
EvPrintOperationPrint *print)
{
+ EvPrintOperation *op = EV_PRINT_OPERATION (print);
+
gtk_print_operation_draw_page_finish (print->op);
+#ifdef HAVE_GTK_PRINT_OPERATION_GET_N_PAGES_TO_PRINT
+ print->total++;
+ ev_print_operation_update_status (op, print->total,
+ print->n_pages_to_print,
+ print->total / (gdouble)print->n_pages_to_print);
+#endif
ev_job_print_set_cairo (job, NULL);
}
g_signal_connect_swapped (print->op, "draw_page",
G_CALLBACK (ev_print_operation_print_draw_page),
print);
+ g_signal_connect_swapped (print->op, "status_changed",
+ G_CALLBACK (ev_print_operation_print_status_changed),
+ print);
gtk_print_operation_set_allow_async (print->op, TRUE);
}
}
#endif /* GTK_CHECK_VERSION (2, 17, 1) */
+gboolean ev_print_operation_exists_for_document (EvDocument *document)
+{
+#if GTKUNIXPRINT_ENABLED
+#if GTK_CHECK_VERSION (2, 17, 1)
+ return (EV_IS_FILE_EXPORTER(document) || EV_IS_DOCUMENT_PRINT(document));
+#else
+ return EV_IS_FILE_EXPORTER(document);
+#endif
+#else /* ! GTKUNIXPRINT_ENABLED */
+#if GTK_CHECK_VERSION (2, 17, 1)
+ return EV_IS_DOCUMENT_PRINT(document);
+#else
+ return FALSE;
+#endif
+#endif /* GTKUNIXPRINT_ENABLED */
+}
+
/* Factory method */
EvPrintOperation *
ev_print_operation_new (EvDocument *document)
{
- EvPrintOperation *op;
+ EvPrintOperation *op = NULL;
+
+ g_return_val_if_fail (ev_print_operation_exists_for_document (document), NULL);
#if GTK_CHECK_VERSION (2, 17, 1)
if (EV_IS_DOCUMENT_PRINT (document))
"document", document, NULL));
else
#endif
+#if GTKUNIXPRINT_ENABLED
op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_EXPORT,
"document", document, NULL));
-
+#endif
return op;
}