diff options
author | Marek Kasik <mkasik@redhat.com> | 2009-05-13 18:28:42 +0200 |
---|---|---|
committer | Marek Kasik <mkasik@redhat.com> | 2009-05-13 18:28:42 +0200 |
commit | 91190ce281b562d0f37d8181d9766e09e3c57558 (patch) | |
tree | f526535d4239732c1f2a231740bc81f72b4e79d5 /gtk | |
parent | 26c10075f95268ed2d8dbfacadeb1cdc0f559da6 (diff) | |
download | gtk+-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.c | 2 | ||||
-rw-r--r-- | gtk/gtkprintjob.h | 2 | ||||
-rw-r--r-- | gtk/gtkprintoperation-private.h | 5 | ||||
-rw-r--r-- | gtk/gtkprintoperation-unix.c | 24 | ||||
-rw-r--r-- | gtk/gtkprintoperation-win32.c | 4 | ||||
-rw-r--r-- | gtk/gtkprintoperation.c | 415 | ||||
-rw-r--r-- | gtk/gtkprintunixdialog.c | 72 |
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 { |