~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to gtk/gtkprintoperation.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2009-09-23 06:36:41 UTC
  • mfrom: (1.3.2 upstream)
  • mto: (72.2.8 sid) (1.6.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 129.
  • Revision ID: james.westby@ubuntu.com-20090923063641-69c7g7h68iy4u5o3
Import upstream version 2.18.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
#include <errno.h>
24
24
#include <stdlib.h>       
 
25
#include <math.h>
25
26
 
26
27
#include <string.h>
27
28
#include "gtkprintoperation-private.h"
48
49
  CREATE_CUSTOM_WIDGET,
49
50
  CUSTOM_WIDGET_APPLY,
50
51
  PREVIEW,
 
52
  UPDATE_CUSTOM_WIDGET,
51
53
  LAST_SIGNAL
52
54
};
53
55
 
67
69
  PROP_EXPORT_FILENAME,
68
70
  PROP_STATUS,
69
71
  PROP_STATUS_STRING,
70
 
  PROP_CUSTOM_TAB_LABEL
 
72
  PROP_CUSTOM_TAB_LABEL,
 
73
  PROP_EMBED_PAGE_SETUP,
 
74
  PROP_HAS_SELECTION,
 
75
  PROP_SUPPORT_SELECTION,
 
76
  PROP_N_PAGES_TO_PRINT
71
77
};
72
78
 
73
79
static guint signals[LAST_SIGNAL] = { 0 };
153
159
  priv->default_page_setup = NULL;
154
160
  priv->print_settings = NULL;
155
161
  priv->nr_of_pages = -1;
 
162
  priv->nr_of_pages_to_print = -1;
 
163
  priv->page_position = -1;
156
164
  priv->current_page = -1;
157
165
  priv->use_full_page = FALSE;
158
166
  priv->show_progress = FALSE;
159
167
  priv->export_filename = NULL;
160
168
  priv->track_print_status = FALSE;
161
169
  priv->is_sync = FALSE;
 
170
  priv->support_selection = FALSE;
 
171
  priv->has_selection = FALSE;
 
172
  priv->embed_page_setup = FALSE;
162
173
 
163
174
  priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY;
164
175
 
219
230
  
220
231
  switch (priv->print_pages)
221
232
    {
 
233
    case GTK_PRINT_PAGES_SELECTION:
222
234
    case GTK_PRINT_PAGES_ALL:
223
235
      return (page_nr >= 0) && (page_nr < priv->nr_of_pages);
224
236
    case GTK_PRINT_PAGES_CURRENT:
313
325
    case PROP_CUSTOM_TAB_LABEL:
314
326
      gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value));
315
327
      break;
 
328
    case PROP_EMBED_PAGE_SETUP:
 
329
      gtk_print_operation_set_embed_page_setup (op, g_value_get_boolean (value));
 
330
      break;
 
331
    case PROP_HAS_SELECTION:
 
332
      gtk_print_operation_set_has_selection (op, g_value_get_boolean (value));
 
333
      break;
 
334
    case PROP_SUPPORT_SELECTION:
 
335
      gtk_print_operation_set_support_selection (op, g_value_get_boolean (value));
 
336
      break;
316
337
    default:
317
338
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
318
339
      break;
372
393
    case PROP_CUSTOM_TAB_LABEL:
373
394
      g_value_set_string (value, priv->custom_tab_label);
374
395
      break;
 
396
    case PROP_EMBED_PAGE_SETUP:
 
397
      g_value_set_boolean (value, priv->embed_page_setup);
 
398
      break;
 
399
    case PROP_HAS_SELECTION:
 
400
      g_value_set_boolean (value, priv->has_selection);
 
401
      break;
 
402
    case PROP_SUPPORT_SELECTION:
 
403
      g_value_set_boolean (value, priv->support_selection);
 
404
      break;
 
405
    case PROP_N_PAGES_TO_PRINT:
 
406
      g_value_set_int (value, priv->nr_of_pages_to_print);
 
407
      break;
375
408
    default:
376
409
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
377
410
      break;
820
853
                  G_TYPE_OBJECT, 0);
821
854
 
822
855
  /**
 
856
   * GtkPrintOperation::update-custom-widget:
 
857
   * @operation: the #GtkPrintOperation on which the signal was emitted
 
858
   * @widget: the custom widget added in create-custom-widget
 
859
   * @setup: actual page setup
 
860
   * @settings: actual print settings
 
861
   *
 
862
   * Emitted after change of selected printer. The actual page setup and
 
863
   * print settings are passed to the custom widget, which can actualize
 
864
   * itself according to this change.
 
865
   *
 
866
   * Since: 2.18
 
867
   */
 
868
  signals[UPDATE_CUSTOM_WIDGET] =
 
869
    g_signal_new (I_("update-custom-widget"),
 
870
                  G_TYPE_FROM_CLASS (class),
 
871
                  G_SIGNAL_RUN_LAST,
 
872
                  G_STRUCT_OFFSET (GtkPrintOperationClass, update_custom_widget),
 
873
                  NULL, NULL,
 
874
                  _gtk_marshal_VOID__OBJECT_OBJECT_OBJECT,
 
875
                  G_TYPE_NONE, 3, GTK_TYPE_WIDGET, GTK_TYPE_PAGE_SETUP, GTK_TYPE_PRINT_SETTINGS);
 
876
 
 
877
  /**
823
878
   * GtkPrintOperation::custom-widget-apply:
824
879
   * @operation: the #GtkPrintOperation on which the signal was emitted
825
880
   * @widget: the custom widget added in create-custom-widget
826
881
   *
827
882
   * Emitted right before #GtkPrintOperation::begin-print if you added
828
 
   * a custom widget in the #GtkPrintOperation:;create-custom-widget handler. 
 
883
   * a custom widget in the #GtkPrintOperation::create-custom-widget handler. 
829
884
   * When you get this signal you should read the information from the 
830
885
   * custom widgets, as the widgets are not guaraneed to be around at a 
831
886
   * later time.
1167
1222
                                                        NULL,
1168
1223
                                                        GTK_PARAM_READWRITE));
1169
1224
 
 
1225
  /**
 
1226
   * GtkPrintOperation:support-selection:
 
1227
   *
 
1228
   * If %TRUE, the print operation will support print of selection.
 
1229
   * This allows the print dialog to show a "Selection" button.
 
1230
   * 
 
1231
   * Since: 2.18
 
1232
   */
 
1233
  g_object_class_install_property (gobject_class,
 
1234
                                   PROP_SUPPORT_SELECTION,
 
1235
                                   g_param_spec_boolean ("support-selection",
 
1236
                                                         P_("Support Selection"),
 
1237
                                                         P_("TRUE if the print operation will support print of selection."),
 
1238
                                                         FALSE,
 
1239
                                                         GTK_PARAM_READWRITE));
 
1240
 
 
1241
  /**
 
1242
   * GtkPrintOperation:has-selection:
 
1243
   *
 
1244
   * Determines whether there is a selection in your application.
 
1245
   * This can allow your application to print the selection.
 
1246
   * This is typically used to make a "Selection" button sensitive.
 
1247
   * 
 
1248
   * Since: 2.18
 
1249
   */
 
1250
  g_object_class_install_property (gobject_class,
 
1251
                                   PROP_HAS_SELECTION,
 
1252
                                   g_param_spec_boolean ("has-selection",
 
1253
                                                         P_("Has Selection"),
 
1254
                                                         P_("TRUE if a selecion exists."),
 
1255
                                                         FALSE,
 
1256
                                                         GTK_PARAM_READWRITE));
 
1257
 
 
1258
 
 
1259
  /**
 
1260
   * GtkPrintOperation:embed-page-setup:
 
1261
   *
 
1262
   * If %TRUE, page size combo box and orientation combo box are embedded into page setup page.
 
1263
   * 
 
1264
   * Since: 2.18
 
1265
   */
 
1266
  g_object_class_install_property (gobject_class,
 
1267
                                   PROP_EMBED_PAGE_SETUP,
 
1268
                                   g_param_spec_boolean ("embed-page-setup",
 
1269
                                                         P_("Embed Page Setup"),
 
1270
                                                         P_("TRUE if page setup combos are embedded in GtkPrintDialog"),
 
1271
                                                         FALSE,
 
1272
                                                         GTK_PARAM_READWRITE));
 
1273
  /**
 
1274
   * GtkPrintOperation:n-pages-to-print:
 
1275
   *
 
1276
   * The number of pages that will be printed.
 
1277
   *
 
1278
   * Note that this value is set during print preparation phase
 
1279
   * (%GTK_PRINT_STATUS_PREPARING), so this value should never be
 
1280
   * get before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA).
 
1281
   * You can connect to the #GtkPrintOperation::status-changed signal
 
1282
   * and call gtk_print_operation_get_n_pages_to_print() when
 
1283
   * print status is %GTK_PRINT_STATUS_GENERATING_DATA.
 
1284
   * This is typically used to track the progress of print operation.
 
1285
   *
 
1286
   * Since: 2.18
 
1287
   */
 
1288
  g_object_class_install_property (gobject_class,
 
1289
                                   PROP_N_PAGES_TO_PRINT,
 
1290
                                   g_param_spec_int ("n-pages-to-print",
 
1291
                                                     P_("Number of Pages To Print"),
 
1292
                                                     P_("The number of pages that will be printed."),
 
1293
                                                     -1,
 
1294
                                                     G_MAXINT,
 
1295
                                                     -1,
 
1296
                                                     GTK_PARAM_READABLE));
1170
1297
}
1171
1298
 
1172
1299
/**
1809
1936
  cairo_t *cr;
1810
1937
 
1811
1938
  cr = gtk_print_context_get_cairo_context (print_context);
1812
 
  cairo_show_page (cr);
 
1939
 
 
1940
  if ((op->priv->manual_number_up < 2) ||
 
1941
      ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
 
1942
      (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
 
1943
    cairo_show_page (cr);
1813
1944
}
1814
1945
 
1815
1946
static void
1883
2014
  priv->manual_page_set = GTK_PAGE_SET_ALL;
1884
2015
  priv->manual_scale = 1.0;
1885
2016
  priv->manual_orientation = TRUE;
 
2017
  priv->manual_number_up = 1;
 
2018
  priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
1886
2019
  
1887
2020
  *do_print = TRUE;
1888
2021
  
1904
2037
  GtkPageRange *ranges;
1905
2038
  GtkPageRange one_range;
1906
2039
 
1907
 
  gint page, start, end, inc;
 
2040
  gint page;
 
2041
  gint sheet;
 
2042
  gint first_position, last_position;
 
2043
  gint first_sheet;
 
2044
  gint num_of_sheets;
 
2045
  gint *pages;
1908
2046
 
1909
2047
  GtkWidget *progress;
1910
2048
 
1911
2049
  gboolean initialized;
1912
 
  gboolean is_preview; 
 
2050
  gboolean is_preview;
 
2051
  gboolean done;
1913
2052
} PrintPagesData;
1914
2053
 
1915
2054
static void
1916
 
find_range (PrintPagesData *data)
1917
 
{
1918
 
  GtkPageRange *range;
1919
 
 
1920
 
  range = &data->ranges[data->range];
1921
 
 
1922
 
  if (data->inc < 0)
1923
 
    {
1924
 
      data->start = range->end;
1925
 
      data->end = range->start - 1;
1926
 
    }
1927
 
  else
1928
 
    {
1929
 
      data->start = range->start;
1930
 
      data->end = range->end + 1;
1931
 
    }
1932
 
}
1933
 
 
1934
 
static void
1935
2055
clamp_page_ranges (PrintPagesData *data)
1936
2056
{
1937
2057
  GtkPrintOperationPrivate *priv; 
1971
2091
  data->num_ranges = num_of_correct_ranges;
1972
2092
}
1973
2093
 
1974
 
static gboolean 
 
2094
static void
1975
2095
increment_page_sequence (PrintPagesData *data)
1976
2096
{
1977
2097
  GtkPrintOperationPrivate *priv = data->op->priv;
1978
 
 
1979
 
  do {
1980
 
    data->page += data->inc;
1981
 
    if (data->page == data->end)
1982
 
      {
1983
 
        data->range += data->inc;
1984
 
        if (data->range == -1 || data->range == data->num_ranges)
1985
 
          {
1986
 
            data->uncollated++;
1987
 
            if (data->uncollated == data->uncollated_copies)
1988
 
              return FALSE;
1989
 
 
1990
 
            data->range = data->inc < 0 ? data->num_ranges - 1 : 0;
1991
 
          }
1992
 
        find_range (data);
1993
 
        data->page = data->start;
1994
 
      }
1995
 
  }
1996
 
  while ((priv->manual_page_set == GTK_PAGE_SET_EVEN && data->page % 2 == 0) ||
1997
 
         (priv->manual_page_set == GTK_PAGE_SET_ODD && data->page % 2 == 1));
1998
 
 
1999
 
  return TRUE;
 
2098
  gint inc;
 
2099
 
 
2100
  if (data->total == -1)
 
2101
    {
 
2102
      data->total = 0;
 
2103
      return;
 
2104
    }
 
2105
 
 
2106
  /* check whether we reached last position */
 
2107
  if (priv->page_position == data->last_position &&
 
2108
      !(data->collated_copies > 1 && data->collated < (data->collated_copies - 1)))
 
2109
    {
 
2110
      if (data->uncollated_copies > 1 && data->uncollated < (data->uncollated_copies - 1))
 
2111
        {
 
2112
          priv->page_position = data->first_position;
 
2113
          data->sheet = data->first_sheet;
 
2114
          data->uncollated++;
 
2115
        }
 
2116
      else
 
2117
        {
 
2118
          data->done = TRUE;
 
2119
          return;
 
2120
        }
 
2121
    }
 
2122
  else
 
2123
    {
 
2124
      if (priv->manual_reverse)
 
2125
        inc = -1;
 
2126
      else
 
2127
        inc = 1;
 
2128
 
 
2129
      /* changing sheet */
 
2130
      if ((priv->page_position + 1) % priv->manual_number_up == 0 ||
 
2131
          priv->page_position == data->last_position ||
 
2132
          priv->page_position == priv->nr_of_pages_to_print - 1)
 
2133
        {
 
2134
          /* check whether to print the same sheet again */
 
2135
          if (data->collated_copies > 1)
 
2136
            {
 
2137
              if (data->collated < (data->collated_copies - 1))
 
2138
                {
 
2139
                  data->collated++;
 
2140
                  data->total++;
 
2141
                  priv->page_position = data->sheet * priv->manual_number_up;
 
2142
 
 
2143
                  if (priv->page_position < 0 ||
 
2144
                      priv->page_position >= priv->nr_of_pages_to_print ||
 
2145
                      data->sheet < 0 ||
 
2146
                      data->sheet >= data->num_of_sheets)
 
2147
                    {
 
2148
                      data->done = TRUE;
 
2149
                      return;
 
2150
                    }
 
2151
                  else
 
2152
                    data->page = data->pages[priv->page_position];
 
2153
 
 
2154
                  return;
 
2155
                }
 
2156
              else
 
2157
                data->collated = 0;
 
2158
            }
 
2159
 
 
2160
          if (priv->manual_page_set == GTK_PAGE_SET_ODD ||
 
2161
              priv->manual_page_set == GTK_PAGE_SET_EVEN)
 
2162
            data->sheet += 2 * inc;
 
2163
          else
 
2164
            data->sheet += inc;
 
2165
 
 
2166
          priv->page_position = data->sheet * priv->manual_number_up;
 
2167
        }
 
2168
      else
 
2169
        priv->page_position += 1;
 
2170
    }
 
2171
 
 
2172
  /* general check */
 
2173
  if (priv->page_position < 0 ||
 
2174
      priv->page_position >= priv->nr_of_pages_to_print ||
 
2175
      data->sheet < 0 ||
 
2176
      data->sheet >= data->num_of_sheets)
 
2177
    {
 
2178
      data->done = TRUE;
 
2179
      return;
 
2180
    }
 
2181
  else
 
2182
    data->page = data->pages[priv->page_position];
 
2183
 
 
2184
  data->total++;
2000
2185
}
2001
2186
 
2002
2187
static void
2029
2214
                   GTK_PRINT_OPERATION_RESULT_APPLY);
2030
2215
  
2031
2216
  g_object_unref (data->op);
 
2217
  g_free (data->pages);
2032
2218
  g_free (data);
2033
2219
}
2034
2220
 
2044
2230
    {
2045
2231
      if (priv->status == GTK_PRINT_STATUS_PREPARING)
2046
2232
        {
2047
 
          if (priv->nr_of_pages > 0)
2048
 
            text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages);
 
2233
          if (priv->nr_of_pages_to_print > 0)
 
2234
            text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages_to_print);
2049
2235
          else
2050
2236
            text = g_strdup (_("Preparing"));
2051
2237
        }
2083
2269
}
2084
2270
 
2085
2271
/**
 
2272
 * gtk_print_operation_set_embed_page_setup:
 
2273
 * @op: a #GtkPrintOperation
 
2274
 * @embed: %TRUE to embed page setup selection in the #GtkPrintDialog
 
2275
 *
 
2276
 * Embed page size combo box and orientation combo box into page setup page.
 
2277
 * Selected page setup is stored as default page setup in #GtkPrintOperation.
 
2278
 *
 
2279
 * Since: 2.18
 
2280
 **/
 
2281
void
 
2282
gtk_print_operation_set_embed_page_setup (GtkPrintOperation  *op,
 
2283
                                          gboolean            embed)
 
2284
{
 
2285
  GtkPrintOperationPrivate *priv;
 
2286
 
 
2287
  g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
 
2288
 
 
2289
  priv = op->priv;
 
2290
 
 
2291
  embed = embed != FALSE;
 
2292
  if (priv->embed_page_setup != embed)
 
2293
    {
 
2294
      priv->embed_page_setup = embed;
 
2295
      g_object_notify (G_OBJECT (op), "embed-page-setup");
 
2296
    }
 
2297
}
 
2298
 
 
2299
/**
 
2300
 * gtk_print_operation_get_embed_page_setup:
 
2301
 * @op: a #GtkPrintOperation
 
2302
 *
 
2303
 * Gets the value of #GtkPrintOperation::embed-page-setup property.
 
2304
 * 
 
2305
 * Returns: whether page setup selection combos are embedded
 
2306
 *
 
2307
 * Since: 2.18
 
2308
 */
 
2309
gboolean
 
2310
gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op)
 
2311
{
 
2312
  g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
 
2313
 
 
2314
  return op->priv->embed_page_setup;
 
2315
}
 
2316
 
 
2317
/**
2086
2318
 * gtk_print_operation_draw_page_finish:
2087
2319
 * @op: a #GtkPrintOperation
2088
2320
 * 
2141
2373
  cr = gtk_print_context_get_cairo_context (print_context);
2142
2374
  
2143
2375
  cairo_save (cr);
2144
 
  if (priv->manual_scale != 1.0)
 
2376
  if (priv->manual_scale != 1.0 && priv->manual_number_up <= 1)
2145
2377
    cairo_scale (cr,
2146
2378
                 priv->manual_scale,
2147
2379
                 priv->manual_scale);
2148
2380
  
2149
2381
  if (priv->manual_orientation)
2150
2382
    _gtk_print_context_rotate_according_to_orientation (print_context);
2151
 
  
2152
 
  if (!priv->use_full_page)
2153
 
    _gtk_print_context_translate_into_margin (print_context);
 
2383
 
 
2384
  if (priv->manual_number_up > 1)
 
2385
    {
 
2386
      GtkPageOrientation  orientation;
 
2387
      GtkPageSetup       *page_setup;
 
2388
      gdouble             paper_width, paper_height;
 
2389
      gdouble             page_width, page_height;
 
2390
      gdouble             context_width, context_height;
 
2391
      gdouble             bottom_margin, top_margin, left_margin, right_margin;
 
2392
      gdouble             x_step, y_step;
 
2393
      gdouble             x_scale, y_scale, scale;
 
2394
      gdouble             horizontal_offset = 0.0, vertical_offset = 0.0;
 
2395
      gint                columns, rows, x, y, tmp_length;
 
2396
 
 
2397
      page_setup = gtk_print_context_get_page_setup (print_context);
 
2398
      orientation = gtk_page_setup_get_orientation (page_setup);
 
2399
 
 
2400
      top_margin = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_POINTS);
 
2401
      bottom_margin = gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_POINTS);
 
2402
      left_margin = gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_POINTS);
 
2403
      right_margin = gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_POINTS);
 
2404
 
 
2405
      paper_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
 
2406
      paper_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
 
2407
 
 
2408
      context_width = gtk_print_context_get_width (print_context);
 
2409
      context_height = gtk_print_context_get_height (print_context);
 
2410
 
 
2411
      if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
 
2412
          orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
 
2413
        {
 
2414
          page_width = paper_width - (left_margin + right_margin);
 
2415
          page_height = paper_height - (top_margin + bottom_margin);
 
2416
        }
 
2417
      else
 
2418
        {
 
2419
          page_width = paper_width - (top_margin + bottom_margin);
 
2420
          page_height = paper_height - (left_margin + right_margin);
 
2421
        }
 
2422
 
 
2423
      if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
 
2424
          orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
 
2425
        cairo_translate (cr, left_margin, top_margin);
 
2426
      else
 
2427
        cairo_translate (cr, top_margin, left_margin);
 
2428
 
 
2429
      switch (priv->manual_number_up)
 
2430
        {
 
2431
          default:
 
2432
            columns = 1;
 
2433
            rows = 1;
 
2434
            break;
 
2435
          case 2:
 
2436
            columns = 2;
 
2437
            rows = 1;
 
2438
            break;
 
2439
          case 4:
 
2440
            columns = 2;
 
2441
            rows = 2;
 
2442
            break;
 
2443
          case 6:
 
2444
            columns = 3;
 
2445
            rows = 2;
 
2446
            break;
 
2447
          case 9:
 
2448
            columns = 3;
 
2449
            rows = 3;
 
2450
            break;
 
2451
          case 16:
 
2452
            columns = 4;
 
2453
            rows = 4;
 
2454
            break;
 
2455
        }
 
2456
 
 
2457
      if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
 
2458
          orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
 
2459
        {
 
2460
          tmp_length = columns;
 
2461
          columns = rows;
 
2462
          rows = tmp_length;
 
2463
        }
 
2464
 
 
2465
      switch (priv->manual_number_up_layout)
 
2466
        {
 
2467
          case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM:
 
2468
            x = priv->page_position % columns;
 
2469
            y = (priv->page_position / columns) % rows;
 
2470
            break;
 
2471
          case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP:
 
2472
            x = priv->page_position % columns;
 
2473
            y = rows - 1 - (priv->page_position / columns) % rows;
 
2474
            break;
 
2475
          case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM:
 
2476
            x = columns - 1 - priv->page_position % columns;
 
2477
            y = (priv->page_position / columns) % rows;
 
2478
            break;
 
2479
          case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP:
 
2480
            x = columns - 1 - priv->page_position % columns;
 
2481
            y = rows - 1 - (priv->page_position / columns) % rows;
 
2482
            break;
 
2483
          case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT:
 
2484
            x = (priv->page_position / rows) % columns;
 
2485
            y = priv->page_position % rows;
 
2486
            break;
 
2487
          case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT:
 
2488
            x = columns - 1 - (priv->page_position / rows) % columns;
 
2489
            y = priv->page_position % rows;
 
2490
            break;
 
2491
          case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT:
 
2492
            x = (priv->page_position / rows) % columns;
 
2493
            y = rows - 1 - priv->page_position % rows;
 
2494
            break;
 
2495
          case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT:
 
2496
            x = columns - 1 - (priv->page_position / rows) % columns;
 
2497
            y = rows - 1 - priv->page_position % rows;
 
2498
            break;
 
2499
        }
 
2500
 
 
2501
      if (priv->manual_number_up == 4 || priv->manual_number_up == 9 || priv->manual_number_up == 16)
 
2502
        {
 
2503
          x_scale = page_width / (columns * paper_width);
 
2504
          y_scale = page_height / (rows * paper_height);
 
2505
 
 
2506
          scale = x_scale < y_scale ? x_scale : y_scale;
 
2507
 
 
2508
          x_step = paper_width * (x_scale / scale);
 
2509
          y_step = paper_height * (y_scale / scale);
 
2510
 
 
2511
          if ((left_margin + right_margin) > 0)
 
2512
            {
 
2513
              horizontal_offset = left_margin * (x_step - context_width) / (left_margin + right_margin);
 
2514
              vertical_offset = top_margin * (y_step - context_height) / (top_margin + bottom_margin);
 
2515
            }
 
2516
          else
 
2517
            {
 
2518
              horizontal_offset = (x_step - context_width) / 2.0;
 
2519
              vertical_offset = (y_step - context_height) / 2.0;
 
2520
            }
 
2521
 
 
2522
          cairo_scale (cr, scale, scale);
 
2523
 
 
2524
          cairo_translate (cr,
 
2525
                           x * x_step + horizontal_offset,
 
2526
                           y * y_step + vertical_offset);
 
2527
 
 
2528
          if (priv->manual_scale != 1.0)
 
2529
            cairo_scale (cr, priv->manual_scale, priv->manual_scale);
 
2530
        }
 
2531
 
 
2532
      if (priv->manual_number_up == 2 || priv->manual_number_up == 6)
 
2533
        {
 
2534
          x_scale = page_height / (columns * paper_width);
 
2535
          y_scale = page_width / (rows * paper_height);
 
2536
 
 
2537
          scale = x_scale < y_scale ? x_scale : y_scale;
 
2538
 
 
2539
          horizontal_offset = (paper_width * (x_scale / scale) - paper_width) / 2.0 * columns;
 
2540
          vertical_offset = (paper_height * (y_scale / scale) - paper_height) / 2.0 * rows;
 
2541
 
 
2542
          if (!priv->use_full_page)
 
2543
            {
 
2544
              horizontal_offset -= right_margin;
 
2545
              vertical_offset += top_margin;
 
2546
            }
 
2547
 
 
2548
          cairo_scale (cr, scale, scale);
 
2549
 
 
2550
          cairo_translate (cr,
 
2551
                           y * paper_height + vertical_offset,
 
2552
                           (columns - x) * paper_width + horizontal_offset);
 
2553
 
 
2554
          if (priv->manual_scale != 1.0)
 
2555
            cairo_scale (cr, priv->manual_scale, priv->manual_scale);
 
2556
 
 
2557
          cairo_rotate (cr, - G_PI / 2);
 
2558
        }
 
2559
    }
 
2560
  else
 
2561
    if (!priv->use_full_page)
 
2562
      _gtk_print_context_translate_into_margin (print_context);
2154
2563
  
2155
2564
  priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DRAWING;
2156
2565
 
2166
2575
{
2167
2576
  GtkPrintOperationPrivate *priv;
2168
2577
  GtkPageSetup             *page_setup;
2169
 
  gint                      i;
 
2578
  gint                      i, j, counter;
2170
2579
 
2171
2580
  priv = data->op->priv;
2172
2581
 
2244
2653
      return;
2245
2654
    }
2246
2655
 
2247
 
  if (priv->manual_reverse)
2248
 
    {
2249
 
      data->range = data->num_ranges - 1;
2250
 
      data->inc = -1;      
2251
 
    }
2252
 
  else
2253
 
    {
2254
 
      data->range = 0;
2255
 
      data->inc = 1;      
2256
 
    }
2257
 
  find_range (data);
2258
 
 
2259
 
  /* go back one page, since we preincrement below */
2260
 
  data->page = data->start - data->inc;
2261
 
  data->collated = data->collated_copies - 1;
 
2656
  priv->nr_of_pages_to_print = 0;
 
2657
  for (i = 0; i < data->num_ranges; i++)
 
2658
    priv->nr_of_pages_to_print += data->ranges[i].end - data->ranges[i].start + 1;
 
2659
 
 
2660
  data->pages = g_new (gint, priv->nr_of_pages_to_print);
 
2661
  counter = 0;
 
2662
  for (i = 0; i < data->num_ranges; i++)
 
2663
    for (j = data->ranges[i].start; j <= data->ranges[i].end; j++)
 
2664
      {
 
2665
        data->pages[counter] = j;
 
2666
        counter++;
 
2667
      }
 
2668
 
 
2669
  data->total = -1;
 
2670
  data->collated = 0;
 
2671
  data->uncollated = 0;
 
2672
 
 
2673
  if (priv->nr_of_pages_to_print % priv->manual_number_up == 0)
 
2674
    data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up;
 
2675
  else
 
2676
    data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up + 1;
 
2677
 
 
2678
  if (priv->manual_reverse)
 
2679
    {
 
2680
      /* data->sheet is 0-based */
 
2681
      if (priv->manual_page_set == GTK_PAGE_SET_ODD)
 
2682
        data->sheet = (data->num_of_sheets - 1) - (data->num_of_sheets - 1) % 2;
 
2683
      else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
 
2684
        data->sheet = (data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2);
 
2685
      else
 
2686
        data->sheet = data->num_of_sheets - 1;
 
2687
    }
 
2688
  else
 
2689
    {
 
2690
      /* data->sheet is 0-based */
 
2691
      if (priv->manual_page_set == GTK_PAGE_SET_ODD)
 
2692
        data->sheet = 0;
 
2693
      else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
 
2694
        {
 
2695
          if (data->num_of_sheets > 1)
 
2696
            data->sheet = 1;
 
2697
          else
 
2698
            data->sheet = -1;
 
2699
        }
 
2700
      else
 
2701
        data->sheet = 0;
 
2702
    }
 
2703
 
 
2704
  priv->page_position = data->sheet * priv->manual_number_up;
 
2705
 
 
2706
  if (priv->page_position < 0 || priv->page_position >= priv->nr_of_pages_to_print)
 
2707
    {
 
2708
      priv->cancelled = TRUE;
 
2709
      return;
 
2710
    }
 
2711
 
 
2712
  data->page = data->pages[priv->page_position];
 
2713
  data->first_position = priv->page_position;
 
2714
  data->first_sheet = data->sheet;
 
2715
 
 
2716
  if (priv->manual_reverse)
 
2717
    {
 
2718
      if (priv->manual_page_set == GTK_PAGE_SET_ODD)
 
2719
        data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
 
2720
      else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
 
2721
        data->last_position = MIN (2 * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
 
2722
      else
 
2723
        data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
 
2724
    }
 
2725
  else
 
2726
    {
 
2727
      if (priv->manual_page_set == GTK_PAGE_SET_ODD)
 
2728
        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);
 
2729
      else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
 
2730
        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);
 
2731
      else
 
2732
        data->last_position = priv->nr_of_pages_to_print - 1;
 
2733
    }
 
2734
 
2262
2735
 
2263
2736
  _gtk_print_operation_set_status (data->op, 
2264
2737
                                   GTK_PRINT_STATUS_GENERATING_DATA, 
2269
2742
print_pages_idle (gpointer user_data)
2270
2743
{
2271
2744
  PrintPagesData *data; 
2272
 
  GtkPrintOperationPrivate *priv; 
 
2745
  GtkPrintOperationPrivate *priv;
2273
2746
  gboolean done = FALSE;
2274
2747
 
2275
2748
  data = (PrintPagesData*)user_data;
2283
2756
          goto out;
2284
2757
        }
2285
2758
 
2286
 
      data->total++;
2287
 
      data->collated++;
2288
 
      if (data->collated == data->collated_copies)
2289
 
        {
2290
 
          data->collated = 0;
2291
 
          if (!increment_page_sequence (data))
2292
 
            {
2293
 
              done = TRUE;
2294
 
 
2295
 
              goto out;
2296
 
            }
2297
 
        }
2298
 
 
2299
2759
      if (data->is_preview && !priv->cancelled)
2300
2760
        {
2301
2761
          done = TRUE;
2304
2764
          goto out;
2305
2765
        }
2306
2766
 
2307
 
      common_render_page (data->op, data->page);
 
2767
      increment_page_sequence (data);
 
2768
 
 
2769
      if (!data->done)
 
2770
        common_render_page (data->op, data->page);
 
2771
      else
 
2772
        done = priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY;
2308
2773
 
2309
2774
 out:
2310
2775
 
2445
2910
      priv->manual_page_set = GTK_PAGE_SET_ALL;
2446
2911
      priv->manual_scale = 1.0;
2447
2912
      priv->manual_orientation = TRUE;
 
2913
      priv->manual_number_up = 1;
 
2914
      priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
2448
2915
    }
2449
2916
  
2450
2917
  priv->print_pages_idle_id = gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
2661
3128
  op->priv->cancelled = TRUE;
2662
3129
}
2663
3130
 
2664
 
 
 
3131
/**
 
3132
 * gtk_print_operation_set_support_selection:
 
3133
 * @op: a #GtkPrintOperation
 
3134
 * @support_selection: %TRUE to support selection
 
3135
 *
 
3136
 * Sets whether selection is supported by #GtkPrintOperation.
 
3137
 *
 
3138
 * Since: 2.18
 
3139
 */
 
3140
void
 
3141
gtk_print_operation_set_support_selection (GtkPrintOperation  *op,
 
3142
                                           gboolean            support_selection)
 
3143
{
 
3144
  GtkPrintOperationPrivate *priv;
 
3145
 
 
3146
  g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
 
3147
 
 
3148
  priv = op->priv;
 
3149
 
 
3150
  support_selection = support_selection != FALSE;
 
3151
  if (priv->support_selection != support_selection)
 
3152
    {
 
3153
      priv->support_selection = support_selection;
 
3154
      g_object_notify (G_OBJECT (op), "support-selection");
 
3155
    }
 
3156
}
 
3157
 
 
3158
/**
 
3159
 * gtk_print_operation_get_support_selection:
 
3160
 * @op: a #GtkPrintOperation
 
3161
 *
 
3162
 * Gets the value of #GtkPrintOperation::support-selection property.
 
3163
 * 
 
3164
 * Returns: whether the application supports print of selection
 
3165
 *
 
3166
 * Since: 2.18
 
3167
 */
 
3168
gboolean
 
3169
gtk_print_operation_get_support_selection (GtkPrintOperation *op)
 
3170
{
 
3171
  g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
 
3172
 
 
3173
  return op->priv->support_selection;
 
3174
}
 
3175
 
 
3176
/**
 
3177
 * gtk_print_operation_set_has_selection:
 
3178
 * @op: a #GtkPrintOperation
 
3179
 * @has_selection: %TRUE indicates that a selection exists
 
3180
 *
 
3181
 * Sets whether there is a selection to print.
 
3182
 *
 
3183
 * Application has to set number of pages to which the selection
 
3184
 * will draw by gtk_print_operation_set_n_pages() in a callback of
 
3185
 * #GtkPrintOperation::begin-print.
 
3186
 *
 
3187
 * Since: 2.18
 
3188
 */
 
3189
void
 
3190
gtk_print_operation_set_has_selection (GtkPrintOperation  *op,
 
3191
                                       gboolean            has_selection)
 
3192
{
 
3193
  GtkPrintOperationPrivate *priv;
 
3194
 
 
3195
  g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
 
3196
 
 
3197
  priv = op->priv;
 
3198
 
 
3199
  has_selection = has_selection != FALSE;
 
3200
  if (priv->has_selection != has_selection)
 
3201
    {
 
3202
      priv->has_selection = has_selection;
 
3203
      g_object_notify (G_OBJECT (op), "has-selection");
 
3204
    }
 
3205
}
 
3206
 
 
3207
/**
 
3208
 * gtk_print_operation_get_has_selection:
 
3209
 * @op: a #GtkPrintOperation
 
3210
 *
 
3211
 * Gets the value of #GtkPrintOperation::has-selection property.
 
3212
 * 
 
3213
 * Returns: whether there is a selection
 
3214
 *
 
3215
 * Since: 2.18
 
3216
 */
 
3217
gboolean
 
3218
gtk_print_operation_get_has_selection (GtkPrintOperation *op)
 
3219
{
 
3220
  g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
 
3221
 
 
3222
  return op->priv->has_selection;
 
3223
}
 
3224
 
 
3225
/**
 
3226
 * gtk_print_operation_get_n_pages_to_print:
 
3227
 * @op: a #GtkPrintOperation
 
3228
 *
 
3229
 * Returns the number of pages that will be printed.
 
3230
 *
 
3231
 * Note that this value is set during print preparation phase
 
3232
 * (%GTK_PRINT_STATUS_PREPARING), so this function should never be
 
3233
 * called before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA).
 
3234
 * You can connect to the #GtkPrintOperation::status-changed signal
 
3235
 * and call gtk_print_operation_get_n_pages_to_print() when
 
3236
 * print status is %GTK_PRINT_STATUS_GENERATING_DATA.
 
3237
 * This is typically used to track the progress of print operation.
 
3238
 *
 
3239
 * Returns: the number of pages that will be printed
 
3240
 *
 
3241
 * Since: 2.18
 
3242
 **/
 
3243
gint
 
3244
gtk_print_operation_get_n_pages_to_print (GtkPrintOperation *op)
 
3245
{
 
3246
  g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), -1);
 
3247
 
 
3248
  return op->priv->nr_of_pages_to_print;
 
3249
}
2665
3250
 
2666
3251
#define __GTK_PRINT_OPERATION_C__
2667
3252
#include "gtkaliasdef.c"