summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMarek Kasik <mkasik@redhat.com>2009-05-13 18:28:42 +0200
committerMarek Kasik <mkasik@redhat.com>2009-05-13 18:28:42 +0200
commit91190ce281b562d0f37d8181d9766e09e3c57558 (patch)
treef526535d4239732c1f2a231740bc81f72b4e79d5 /gtk
parent26c10075f95268ed2d8dbfacadeb1cdc0f559da6 (diff)
downloadgtk+-91190ce281b562d0f37d8181d9766e09e3c57558.tar.gz
Add ability to print in number-up mode for file backend and lpr backend
GtkPrintOperation is now able to render multiple pages per sheet by its own. The most important changes are in these functions: * increment_page_sequence * prepare_data * common_render_page * print_pages_idle Patch also changes set of choices for 2 pages per sheet mode when landscape orientation is used to "Top to bottom" and "Bottom to top".
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkprintjob.c2
-rw-r--r--gtk/gtkprintjob.h2
-rw-r--r--gtk/gtkprintoperation-private.h5
-rw-r--r--gtk/gtkprintoperation-unix.c24
-rw-r--r--gtk/gtkprintoperation-win32.c4
-rw-r--r--gtk/gtkprintoperation.c415
-rw-r--r--gtk/gtkprintunixdialog.c72
7 files changed, 443 insertions, 81 deletions
diff --git a/gtk/gtkprintjob.c b/gtk/gtkprintjob.c
index c59a27a741..51d41d1e08 100644
--- a/gtk/gtkprintjob.c
+++ b/gtk/gtkprintjob.c
@@ -205,6 +205,8 @@ gtk_print_job_init (GtkPrintJob *job)
job->scale = 1.0;
job->page_set = GTK_PAGE_SET_ALL;
job->rotate_to_orientation = FALSE;
+ job->number_up = 1;
+ job->number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
}
diff --git a/gtk/gtkprintjob.h b/gtk/gtkprintjob.h
index 71ddfdc5ab..fd821840f9 100644
--- a/gtk/gtkprintjob.h
+++ b/gtk/gtkprintjob.h
@@ -66,6 +66,8 @@ struct _GtkPrintJob
guint GSEAL (rotate_to_orientation) : 1;
guint GSEAL (collate) : 1;
guint GSEAL (reverse) : 1;
+ guint GSEAL (number_up);
+ GtkNumberUpLayout GSEAL (number_up_layout);
};
struct _GtkPrintJobClass
diff --git a/gtk/gtkprintoperation-private.h b/gtk/gtkprintoperation-private.h
index 0e5f606c80..718f16df6f 100644
--- a/gtk/gtkprintoperation-private.h
+++ b/gtk/gtkprintoperation-private.h
@@ -43,6 +43,8 @@ struct _GtkPrintOperationPrivate
GtkPrintSettings *print_settings;
gchar *job_name;
gint nr_of_pages;
+ gint nr_of_pages_to_print;
+ gint page_position;
gint current_page;
GtkUnit unit;
gchar *export_filename;
@@ -70,6 +72,9 @@ struct _GtkPrintOperationPrivate
guint manual_orientation : 1;
double manual_scale;
GtkPageSet manual_page_set;
+ guint manual_number_up;
+ GtkNumberUpLayout manual_number_up_layout;
+
GtkWidget *custom_widget;
gchar *custom_tab_label;
diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c
index bec565c01f..ad8bc126f8 100644
--- a/gtk/gtkprintoperation-unix.c
+++ b/gtk/gtkprintoperation-unix.c
@@ -87,10 +87,14 @@ unix_start_page (GtkPrintOperation *op,
type = cairo_surface_get_type (op_unix->surface);
- if (type == CAIRO_SURFACE_TYPE_PS)
- cairo_ps_surface_set_size (op_unix->surface, w, h);
- else if (type == CAIRO_SURFACE_TYPE_PDF)
- cairo_pdf_surface_set_size (op_unix->surface, w, h);
+ if ((op->priv->manual_number_up < 2) ||
+ (op->priv->page_position % op->priv->manual_number_up == 0))
+ {
+ if (type == CAIRO_SURFACE_TYPE_PS)
+ cairo_ps_surface_set_size (op_unix->surface, w, h);
+ else if (type == CAIRO_SURFACE_TYPE_PDF)
+ cairo_pdf_surface_set_size (op_unix->surface, w, h);
+ }
}
static void
@@ -100,7 +104,11 @@ unix_end_page (GtkPrintOperation *op,
cairo_t *cr;
cr = gtk_print_context_get_cairo_context (print_context);
- cairo_show_page (cr);
+
+ if ((op->priv->manual_number_up < 2) ||
+ ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
+ (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
+ cairo_show_page (cr);
}
static void
@@ -399,7 +407,9 @@ get_print_dialog (GtkPrintOperation *op,
GTK_PRINT_CAPABILITY_COLLATE |
GTK_PRINT_CAPABILITY_REVERSE |
GTK_PRINT_CAPABILITY_SCALE |
- GTK_PRINT_CAPABILITY_PREVIEW);
+ GTK_PRINT_CAPABILITY_PREVIEW |
+ GTK_PRINT_CAPABILITY_NUMBER_UP |
+ GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT);
if (priv->print_settings)
gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd),
@@ -523,6 +533,8 @@ finish_print (PrintResponseData *rdata,
priv->manual_page_set = job->page_set;
priv->manual_scale = job->scale;
priv->manual_orientation = job->rotate_to_orientation;
+ priv->manual_number_up = job->number_up;
+ priv->manual_number_up_layout = job->number_up_layout;
}
}
out:
diff --git a/gtk/gtkprintoperation-win32.c b/gtk/gtkprintoperation-win32.c
index 7a9b559a93..3da48cb708 100644
--- a/gtk/gtkprintoperation-win32.c
+++ b/gtk/gtkprintoperation-win32.c
@@ -1598,6 +1598,8 @@ gtk_print_operation_run_without_dialog (GtkPrintOperation *op,
op->priv->manual_orientation = FALSE;
op->priv->manual_scale = 1.0;
op->priv->manual_page_set = GTK_PAGE_SET_ALL;
+ op->priv->manual_number_up = 1;
+ op->priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
op->priv->start_page = win32_start_page;
op->priv->end_page = win32_end_page;
@@ -1821,6 +1823,8 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
op->priv->manual_orientation = FALSE;
op->priv->manual_scale = 1.0;
op->priv->manual_page_set = GTK_PAGE_SET_ALL;
+ op->priv->manual_number_up = 1;
+ op->priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
}
op->priv->start_page = win32_start_page;
diff --git a/gtk/gtkprintoperation.c b/gtk/gtkprintoperation.c
index 424054601f..bc0a5e519d 100644
--- a/gtk/gtkprintoperation.c
+++ b/gtk/gtkprintoperation.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <stdlib.h>
+#include <math.h>
#include <string.h>
#include "gtkprintoperation-private.h"
@@ -154,6 +155,8 @@ gtk_print_operation_init (GtkPrintOperation *operation)
priv->default_page_setup = NULL;
priv->print_settings = NULL;
priv->nr_of_pages = -1;
+ priv->nr_of_pages_to_print = -1;
+ priv->page_position = -1;
priv->current_page = -1;
priv->use_full_page = FALSE;
priv->show_progress = FALSE;
@@ -1832,7 +1835,11 @@ pdf_end_page (GtkPrintOperation *op,
cairo_t *cr;
cr = gtk_print_context_get_cairo_context (print_context);
- cairo_show_page (cr);
+
+ if ((op->priv->manual_number_up < 2) ||
+ ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
+ (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
+ cairo_show_page (cr);
}
static void
@@ -1906,6 +1913,8 @@ run_pdf (GtkPrintOperation *op,
priv->manual_page_set = GTK_PAGE_SET_ALL;
priv->manual_scale = 1.0;
priv->manual_orientation = TRUE;
+ priv->manual_number_up = 1;
+ priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
*do_print = TRUE;
@@ -1927,7 +1936,12 @@ typedef struct
GtkPageRange *ranges;
GtkPageRange one_range;
- gint page, start, end, inc;
+ gint page;
+ gint sheet;
+ gint first_position, last_position;
+ gint first_sheet;
+ gint num_of_sheets;
+ gint *pages;
GtkWidget *progress;
@@ -1936,25 +1950,6 @@ typedef struct
} PrintPagesData;
static void
-find_range (PrintPagesData *data)
-{
- GtkPageRange *range;
-
- range = &data->ranges[data->range];
-
- if (data->inc < 0)
- {
- data->start = range->end;
- data->end = range->start - 1;
- }
- else
- {
- data->start = range->start;
- data->end = range->end + 1;
- }
-}
-
-static void
clamp_page_ranges (PrintPagesData *data)
{
GtkPrintOperationPrivate *priv;
@@ -1998,26 +1993,78 @@ static gboolean
increment_page_sequence (PrintPagesData *data)
{
GtkPrintOperationPrivate *priv = data->op->priv;
+ gint inc;
- do {
- data->page += data->inc;
- if (data->page == data->end)
- {
- data->range += data->inc;
- if (data->range == -1 || data->range == data->num_ranges)
- {
- data->uncollated++;
- if (data->uncollated == data->uncollated_copies)
- return FALSE;
-
- data->range = data->inc < 0 ? data->num_ranges - 1 : 0;
- }
- find_range (data);
- data->page = data->start;
- }
- }
- while ((priv->manual_page_set == GTK_PAGE_SET_EVEN && data->page % 2 == 0) ||
- (priv->manual_page_set == GTK_PAGE_SET_ODD && data->page % 2 == 1));
+ /* check whether we reached last position */
+ if (priv->page_position == data->last_position &&
+ !(data->collated_copies > 1 && data->collated < (data->collated_copies - 1)))
+ {
+ if (data->uncollated_copies > 1 && data->uncollated < (data->uncollated_copies - 1))
+ {
+ priv->page_position = data->first_position;
+ data->sheet = data->first_sheet;
+ data->uncollated++;
+ }
+ else
+ return FALSE;
+ }
+ else
+ {
+ if (priv->manual_reverse)
+ inc = -1;
+ else
+ inc = 1;
+
+ /* changing sheet */
+ if ((priv->page_position + 1) % priv->manual_number_up == 0 ||
+ priv->page_position == data->last_position ||
+ priv->page_position == priv->nr_of_pages_to_print - 1)
+ {
+ /* check whether to print the same sheet again */
+ if (data->collated_copies > 1)
+ {
+ if (data->collated < (data->collated_copies - 1))
+ {
+ data->collated++;
+ data->total++;
+ priv->page_position = data->sheet * priv->manual_number_up;
+
+ if (priv->page_position < 0 ||
+ priv->page_position >= priv->nr_of_pages_to_print ||
+ data->sheet < 0 ||
+ data->sheet >= data->num_of_sheets)
+ return FALSE;
+ else
+ data->page = data->pages[priv->page_position];
+
+ return TRUE;
+ }
+ else
+ data->collated = 0;
+ }
+
+ if (priv->manual_page_set == GTK_PAGE_SET_ODD ||
+ priv->manual_page_set == GTK_PAGE_SET_EVEN)
+ data->sheet += 2 * inc;
+ else
+ data->sheet += inc;
+
+ priv->page_position = data->sheet * priv->manual_number_up;
+ }
+ else
+ priv->page_position += 1;
+ }
+
+ /* general check */
+ if (priv->page_position < 0 ||
+ priv->page_position >= priv->nr_of_pages_to_print ||
+ data->sheet < 0 ||
+ data->sheet >= data->num_of_sheets)
+ return FALSE;
+ else
+ data->page = data->pages[priv->page_position];
+
+ data->total++;
return TRUE;
}
@@ -2052,6 +2099,7 @@ print_pages_idle_done (gpointer user_data)
GTK_PRINT_OPERATION_RESULT_APPLY);
g_object_unref (data->op);
+ g_free (data->pages);
g_free (data);
}
@@ -2073,7 +2121,7 @@ update_progress (PrintPagesData *data)
text = g_strdup (_("Preparing"));
}
else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
- text = g_strdup_printf (_("Printing %d"), data->total);
+ text = g_strdup_printf (_("Printing %d"), data->total - 1);
if (text)
{
@@ -2164,16 +2212,193 @@ common_render_page (GtkPrintOperation *op,
cr = gtk_print_context_get_cairo_context (print_context);
cairo_save (cr);
- if (priv->manual_scale != 1.0)
+ if (priv->manual_scale != 1.0 && priv->manual_number_up <= 1)
cairo_scale (cr,
priv->manual_scale,
priv->manual_scale);
if (priv->manual_orientation)
_gtk_print_context_rotate_according_to_orientation (print_context);
-
- if (!priv->use_full_page)
- _gtk_print_context_translate_into_margin (print_context);
+
+ if (priv->manual_number_up > 1)
+ {
+ GtkPageOrientation orientation;
+ GtkPageSetup *page_setup;
+ gdouble paper_width, paper_height;
+ gdouble page_width, page_height;
+ gdouble context_width, context_height;
+ gdouble bottom_margin, top_margin, left_margin, right_margin;
+ gdouble x_step, y_step;
+ gdouble x_scale, y_scale, scale;
+ gdouble horizontal_offset = 0.0, vertical_offset = 0.0;
+ gint columns, rows, x, y, tmp_length;
+
+ page_setup = gtk_print_context_get_page_setup (print_context);
+ orientation = gtk_page_setup_get_orientation (page_setup);
+
+ top_margin = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_POINTS);
+ bottom_margin = gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_POINTS);
+ left_margin = gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_POINTS);
+ right_margin = gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_POINTS);
+
+ paper_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
+ paper_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
+
+ context_width = gtk_print_context_get_width (print_context);
+ context_height = gtk_print_context_get_height (print_context);
+
+ if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
+ orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
+ {
+ page_width = paper_width - (left_margin + right_margin);
+ page_height = paper_height - (top_margin + bottom_margin);
+ }
+ else
+ {
+ page_width = paper_width - (top_margin + bottom_margin);
+ page_height = paper_height - (left_margin + right_margin);
+ }
+
+ if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
+ orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
+ cairo_translate (cr, left_margin, top_margin);
+ else
+ cairo_translate (cr, top_margin, left_margin);
+
+ switch (priv->manual_number_up)
+ {
+ default:
+ columns = 1;
+ rows = 1;
+ break;
+ case 2:
+ columns = 2;
+ rows = 1;
+ break;
+ case 4:
+ columns = 2;
+ rows = 2;
+ break;
+ case 6:
+ columns = 3;
+ rows = 2;
+ break;
+ case 9:
+ columns = 3;
+ rows = 3;
+ break;
+ case 16:
+ columns = 4;
+ rows = 4;
+ break;
+ }
+
+ if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
+ orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
+ {
+ tmp_length = columns;
+ columns = rows;
+ rows = tmp_length;
+ }
+
+ switch (priv->manual_number_up_layout)
+ {
+ case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM:
+ x = priv->page_position % columns;
+ y = (priv->page_position / columns) % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP:
+ x = priv->page_position % columns;
+ y = rows - 1 - (priv->page_position / columns) % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM:
+ x = columns - 1 - priv->page_position % columns;
+ y = (priv->page_position / columns) % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP:
+ x = columns - 1 - priv->page_position % columns;
+ y = rows - 1 - (priv->page_position / columns) % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT:
+ x = (priv->page_position / rows) % columns;
+ y = priv->page_position % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT:
+ x = columns - 1 - (priv->page_position / rows) % columns;
+ y = priv->page_position % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT:
+ x = (priv->page_position / rows) % columns;
+ y = rows - 1 - priv->page_position % rows;
+ break;
+ case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT:
+ x = columns - 1 - (priv->page_position / rows) % columns;
+ y = rows - 1 - priv->page_position % rows;
+ break;
+ }
+
+ if (priv->manual_number_up == 4 || priv->manual_number_up == 9 || priv->manual_number_up == 16)
+ {
+ x_scale = page_width / (columns * paper_width);
+ y_scale = page_height / (rows * paper_height);
+
+ scale = x_scale < y_scale ? x_scale : y_scale;
+
+ x_step = paper_width * (x_scale / scale);
+ y_step = paper_height * (y_scale / scale);
+
+ if ((left_margin + right_margin) > 0)
+ {
+ horizontal_offset = left_margin * (x_step - context_width) / (left_margin + right_margin);
+ vertical_offset = top_margin * (y_step - context_height) / (top_margin + bottom_margin);
+ }
+ else
+ {
+ horizontal_offset = (x_step - context_width) / 2.0;
+ vertical_offset = (y_step - context_height) / 2.0;
+ }
+
+ cairo_scale (cr, scale, scale);
+
+ cairo_translate (cr,
+ x * x_step + horizontal_offset,
+ y * y_step + vertical_offset);
+
+ if (priv->manual_scale != 1.0)
+ cairo_scale (cr, priv->manual_scale, priv->manual_scale);
+ }
+
+ if (priv->manual_number_up == 2 || priv->manual_number_up == 6)
+ {
+ x_scale = page_height / (columns * paper_width);
+ y_scale = page_width / (rows * paper_height);
+
+ scale = x_scale < y_scale ? x_scale : y_scale;
+
+ horizontal_offset = (paper_width * (x_scale / scale) - paper_width) / 2.0 * columns;
+ vertical_offset = (paper_height * (y_scale / scale) - paper_height) / 2.0 * rows;
+
+ if (!priv->use_full_page)
+ {
+ horizontal_offset -= right_margin;
+ vertical_offset += top_margin;
+ }
+
+ cairo_scale (cr, scale, scale);
+
+ cairo_translate (cr,
+ y * paper_height + vertical_offset,
+ (columns - x) * paper_width + horizontal_offset);
+
+ if (priv->manual_scale != 1.0)
+ cairo_scale (cr, priv->manual_scale, priv->manual_scale);
+
+ cairo_rotate (cr, - M_PI / 2);
+ }
+ }
+ else
+ if (!priv->use_full_page)
+ _gtk_print_context_translate_into_margin (print_context);
priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DRAWING;
@@ -2189,7 +2414,7 @@ prepare_data (PrintPagesData *data)
{
GtkPrintOperationPrivate *priv;
GtkPageSetup *page_setup;
- gint i;
+ gint i, j, counter;
priv = data->op->priv;
@@ -2267,21 +2492,85 @@ prepare_data (PrintPagesData *data)
return;
}
+ priv->nr_of_pages_to_print = 0;
+ for (i = 0; i < data->num_ranges; i++)
+ priv->nr_of_pages_to_print += data->ranges[i].end - data->ranges[i].start + 1;
+
+ data->pages = g_new (gint, priv->nr_of_pages_to_print);
+ counter = 0;
+ for (i = 0; i < data->num_ranges; i++)
+ for (j = data->ranges[i].start; j <= data->ranges[i].end; j++)
+ {
+ data->pages[counter] = j;
+ counter++;
+ }
+
+ data->total = 0;
+ data->collated = 0;
+ data->uncollated = 0;
+
+ if (priv->nr_of_pages_to_print % priv->manual_number_up == 0)
+ data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up;
+ else
+ data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up + 1;
+
if (priv->manual_reverse)
{
- data->range = data->num_ranges - 1;
- data->inc = -1;
+ /* data->sheet is 0-based */
+ if (priv->manual_page_set == GTK_PAGE_SET_ODD)
+ data->sheet = (data->num_of_sheets - 1) - (data->num_of_sheets - 1) % 2;
+ else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
+ data->sheet = (data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2);
+ else
+ data->sheet = data->num_of_sheets - 1;
}
else
{
- data->range = 0;
- data->inc = 1;
+ /* data->sheet is 0-based */
+ if (priv->manual_page_set == GTK_PAGE_SET_ODD)
+ data->sheet = 0;
+ else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
+ {
+ if (data->num_of_sheets > 1)
+ data->sheet = 1;
+ else
+ data->sheet = -1;
+ }
+ else
+ data->sheet = 0;
+ }
+
+ priv->page_position = data->sheet * priv->manual_number_up;
+
+ if (priv->page_position < 0 || priv->page_position >= priv->nr_of_pages_to_print)
+ {
+ priv->cancelled = TRUE;
+ return;
+ }
+
+ data->page = data->pages[priv->page_position];
+ data->first_position = priv->page_position;
+ data->first_sheet = data->sheet;
+
+ if (priv->manual_reverse)
+ {
+ if (priv->manual_page_set == GTK_PAGE_SET_ODD)
+ data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
+ else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
+ data->last_position = MIN (2 * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
+ else
+ data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
+ }
+ else
+ {
+ if (priv->manual_page_set == GTK_PAGE_SET_ODD)
+ data->last_position = MIN (((data->num_of_sheets - 1) - ((data->num_of_sheets - 1) % 2)) * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
+ else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
+ data->last_position = MIN (((data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2)) * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
+ else
+ data->last_position = priv->nr_of_pages_to_print - 1;
}
- find_range (data);
- /* go back one page, since we preincrement below */
- data->page = data->start - data->inc;
- data->collated = data->collated_copies - 1;
_gtk_print_operation_set_status (data->op,
GTK_PRINT_STATUS_GENERATING_DATA,
@@ -2306,19 +2595,6 @@ print_pages_idle (gpointer user_data)
goto out;
}
- data->total++;
- data->collated++;
- if (data->collated == data->collated_copies)
- {
- data->collated = 0;
- if (!increment_page_sequence (data))
- {
- done = TRUE;
-
- goto out;
- }
- }
-
if (data->is_preview && !priv->cancelled)
{
done = TRUE;
@@ -2329,6 +2605,9 @@ print_pages_idle (gpointer user_data)
common_render_page (data->op, data->page);
+ if (!increment_page_sequence (data))
+ done = TRUE;
+
out:
if (priv->cancelled)
@@ -2468,6 +2747,8 @@ print_pages (GtkPrintOperation *op,
priv->manual_page_set = GTK_PAGE_SET_ALL;
priv->manual_scale = 1.0;
priv->manual_orientation = TRUE;
+ priv->manual_number_up = 1;
+ priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
}
priv->print_pages_idle_id = gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c
index fbb2d40583..92c93e9300 100644
--- a/gtk/gtkprintunixdialog.c
+++ b/gtk/gtkprintunixdialog.c
@@ -2428,6 +2428,7 @@ update_number_up_layout (GtkPrintUnixDialog *dialog)
GtkNumberUpLayout layout;
GtkPrinterOption *option;
GtkPrinterOption *old_option;
+ GtkPageOrientation page_orientation;
set = priv->options;
@@ -2438,17 +2439,64 @@ update_number_up_layout (GtkPrintUnixDialog *dialog)
if (priv->number_up_layout_n_option == NULL)
{
priv->number_up_layout_n_option = gtk_printer_option_set_lookup (set, "gtk-n-up-layout");
+ if (priv->number_up_layout_n_option == NULL)
+ {
+ char *n_up_layout[] = { "lrtb", "lrbt", "rltb", "rlbt", "tblr", "tbrl", "btlr", "btrl" };
+ /* Translators: These strings name the possible arrangements of
+ * multiple pages on a sheet when printing (same as in gtkprintbackendcups.c)
+ */
+ char *n_up_layout_display[] = { N_("Left to right, top to bottom"), N_("Left to right, bottom to top"),
+ N_("Right to left, top to bottom"), N_("Right to left, bottom to top"),
+ N_("Top to bottom, left to right"), N_("Top to bottom, right to left"),
+ N_("Bottom to top, left to right"), N_("Bottom to top, right to left") };
+ int i;
+
+ priv->number_up_layout_n_option = gtk_printer_option_new ("gtk-n-up-layout",
+ _("Page Ordering"),
+ GTK_PRINTER_OPTION_TYPE_PICKONE);
+ gtk_printer_option_allocate_choices (priv->number_up_layout_n_option, 8);
+
+ for (i = 0; i < G_N_ELEMENTS (n_up_layout_display); i++)
+ {
+ priv->number_up_layout_n_option->choices[i] = g_strdup (n_up_layout[i]);
+ priv->number_up_layout_n_option->choices_display[i] = g_strdup (_(n_up_layout_display[i]));
+ }
+ }
g_object_ref (priv->number_up_layout_n_option);
priv->number_up_layout_2_option = gtk_printer_option_new ("gtk-n-up-layout",
_("Page Ordering"),
GTK_PRINTER_OPTION_TYPE_PICKONE);
gtk_printer_option_allocate_choices (priv->number_up_layout_2_option, 2);
+ }
- priv->number_up_layout_2_option->choices[0] = priv->number_up_layout_n_option->choices[0];
- priv->number_up_layout_2_option->choices[1] = priv->number_up_layout_n_option->choices[2];
- priv->number_up_layout_2_option->choices_display[0] = g_strdup ( _("Left to right"));
- priv->number_up_layout_2_option->choices_display[1] = g_strdup ( _("Right to left"));
+ page_orientation = gtk_page_setup_get_orientation (priv->page_setup);
+ if (page_orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
+ page_orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
+ {
+ if (! (priv->number_up_layout_2_option->choices[0] == priv->number_up_layout_n_option->choices[0] &&
+ priv->number_up_layout_2_option->choices[1] == priv->number_up_layout_n_option->choices[2]))
+ {
+ g_free (priv->number_up_layout_2_option->choices_display[0]);
+ g_free (priv->number_up_layout_2_option->choices_display[1]);
+ priv->number_up_layout_2_option->choices[0] = priv->number_up_layout_n_option->choices[0];
+ priv->number_up_layout_2_option->choices[1] = priv->number_up_layout_n_option->choices[2];
+ priv->number_up_layout_2_option->choices_display[0] = g_strdup ( _("Left to right"));
+ priv->number_up_layout_2_option->choices_display[1] = g_strdup ( _("Right to left"));
+ }
+ }
+ else
+ {
+ if (! (priv->number_up_layout_2_option->choices[0] == priv->number_up_layout_n_option->choices[0] &&
+ priv->number_up_layout_2_option->choices[1] == priv->number_up_layout_n_option->choices[1]))
+ {
+ g_free (priv->number_up_layout_2_option->choices_display[0]);
+ g_free (priv->number_up_layout_2_option->choices_display[1]);
+ priv->number_up_layout_2_option->choices[0] = priv->number_up_layout_n_option->choices[0];
+ priv->number_up_layout_2_option->choices[1] = priv->number_up_layout_n_option->choices[1];
+ priv->number_up_layout_2_option->choices_display[0] = g_strdup ( _("Top to bottom"));
+ priv->number_up_layout_2_option->choices_display[1] = g_strdup ( _("Bottom to top"));
+ }
}
layout = dialog_get_number_up_layout (dialog);
@@ -2468,12 +2516,20 @@ update_number_up_layout (GtkPrintUnixDialog *dialog)
option = priv->number_up_layout_2_option;
if (layout == GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM ||
- layout == GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP ||
- layout == GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT ||
- layout == GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT)
+ layout == GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT)
enum_value = g_enum_get_value (enum_class, GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM);
- else
+
+ if (layout == GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP ||
+ layout == GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT)
+ enum_value = g_enum_get_value (enum_class, GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP);
+
+ if (layout == GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM ||
+ layout == GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT)
enum_value = g_enum_get_value (enum_class, GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM);
+
+ if (layout == GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP ||
+ layout == GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT)
+ enum_value = g_enum_get_value (enum_class, GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP);
}
else
{