26763cc77e1a6aa41d2142971d6c9c29bbd91821
1 /** \file
2 *
3 * Paper-size widget and helper functions
4 *
5 * Authors:
6 * bulia byak <buliabyak@users.sf.net>
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * Jon Phillips <jon@rejon.org>
9 * Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
10 * Bob Jamison <ishmal@users.sf.net>
11 *
12 * Copyright (C) 2000 - 2006 Authors
13 *
14 * Released under GNU GPL. Read the file 'COPYING' for more information
15 */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
21 #include <cmath>
22 #include <gtkmm.h>
23 #include <string>
24 #include <string.h>
25 #include <vector>
27 #include "desktop-handles.h"
28 #include "document.h"
29 #include "desktop.h"
30 #include "helper/action.h"
31 #include "helper/units.h"
32 #include "inkscape.h"
33 #include "page-sizer.h"
34 #include "sp-namedview.h"
35 #include "sp-root.h"
36 #include "ui/widget/button.h"
37 #include "ui/widget/scalar-unit.h"
38 #include "verbs.h"
39 #include "xml/node.h"
40 #include "xml/repr.h"
42 using std::pair;
44 namespace Inkscape {
45 namespace UI {
46 namespace Widget {
48 /** \note
49 * The ISO page sizes in the table below differ from ghostscript's idea of page sizes (by
50 * less than 1pt). Being off by <1pt should be OK for most purposes, but may cause fuzziness
51 * (antialiasing) problems when printing to 72dpi or 144dpi printers or bitmap files due to
52 * postscript's different coordinate system (y=0 meaning bottom of page in postscript and top
53 * of page in SVG). I haven't looked into whether this does in fact cause fuzziness, I merely
54 * note the possibility. Rounding done by extension/internal/ps.cpp (e.g. floor/ceil calls)
55 * will also affect whether fuzziness occurs.
56 *
57 * The remainder of this comment discusses the origin of the numbers used for ISO page sizes in
58 * this table and in ghostscript.
59 *
60 * The versions here, in mm, are the official sizes according to
61 * <a href="http://en.wikipedia.org/wiki/Paper_sizes">http://en.wikipedia.org/wiki/Paper_sizes</a>
62 * at 2005-01-25. (The ISO entries in the below table
63 * were produced mechanically from the table on that page.)
64 *
65 * (The rule seems to be that A0, B0, ..., D0. sizes are rounded to the nearest number of mm
66 * from the "theoretical size" (i.e. 1000 * sqrt(2) or pow(2.0, .25) or the like), whereas
67 * going from e.g. A0 to A1 always take the floor of halving -- which by chance coincides
68 * exactly with flooring the "theoretical size" for n != 0 instead of the rounding to nearest
69 * done for n==0.)
70 *
71 * Ghostscript paper sizes are given in gs_statd.ps according to gs(1). gs_statd.ps always
72 * uses an integer number of pt: sometimes gs_statd.ps rounds to nearest (e.g. a1), sometimes
73 * floors (e.g. a10), sometimes ceils (e.g. a8).
74 *
75 * I'm not sure how ghostscript's gs_statd.ps was calculated: it isn't just rounding the
76 * "theoretical size" of each page to pt (see a0), nor is it rounding the a0 size times an
77 * appropriate power of two (see a1). Possibly it was prepared manually, with a human applying
78 * inconsistent rounding rules when converting from mm to pt.
79 */
80 /** \todo
81 * Should we include the JIS B series (used in Japan)
82 * (JIS B0 is sometimes called JB0, and similarly for JB1 etc)?
83 * Should we exclude B7--B10 and A7--10 to make the list smaller ?
84 * Should we include any of the ISO C, D and E series (see below) ?
85 */
87 struct PaperSizeRec {
88 char const * const name; //name
89 double const smaller; //lesser dimension
90 double const larger; //greater dimension
91 SPUnitId const unit; //units
92 };
94 // list of page formats that should be in landscape automatically
95 static std::vector<std::string> lscape_papers;
97 static void
98 fill_landscape_papers() {
99 lscape_papers.push_back("US #10 Envelope");
100 lscape_papers.push_back("DL Envelope");
101 lscape_papers.push_back("Banner 468x60");
102 lscape_papers.push_back("Business Card (ISO 7810)");
103 lscape_papers.push_back("Business Card (US)");
104 lscape_papers.push_back("Business Card (Europe)");
105 lscape_papers.push_back("Business Card (Aus/NZ)");
106 }
108 static PaperSizeRec const inkscape_papers[] = {
109 { "A4", 210, 297, SP_UNIT_MM },
110 { "US Letter", 8.5, 11, SP_UNIT_IN },
111 { "US Legal", 8.5, 14, SP_UNIT_IN },
112 { "US Executive", 7.25, 10.5, SP_UNIT_IN },
113 { "A0", 841, 1189, SP_UNIT_MM },
114 { "A1", 594, 841, SP_UNIT_MM },
115 { "A2", 420, 594, SP_UNIT_MM },
116 { "A3", 297, 420, SP_UNIT_MM },
117 { "A5", 148, 210, SP_UNIT_MM },
118 { "A6", 105, 148, SP_UNIT_MM },
119 { "A7", 74, 105, SP_UNIT_MM },
120 { "A8", 52, 74, SP_UNIT_MM },
121 { "A9", 37, 52, SP_UNIT_MM },
122 { "A10", 26, 37, SP_UNIT_MM },
123 { "B0", 1000, 1414, SP_UNIT_MM },
124 { "B1", 707, 1000, SP_UNIT_MM },
125 { "B2", 500, 707, SP_UNIT_MM },
126 { "B3", 353, 500, SP_UNIT_MM },
127 { "B4", 250, 353, SP_UNIT_MM },
128 { "B5", 176, 250, SP_UNIT_MM },
129 { "B6", 125, 176, SP_UNIT_MM },
130 { "B7", 88, 125, SP_UNIT_MM },
131 { "B8", 62, 88, SP_UNIT_MM },
132 { "B9", 44, 62, SP_UNIT_MM },
133 { "B10", 31, 44, SP_UNIT_MM },
137 //#if 0
138 /*
139 Whether to include or exclude these depends on how
140 big we mind our page size menu
141 becoming. C series is used for envelopes;
142 don't know what D and E series are used for.
143 */
145 { "C0", 917, 1297, SP_UNIT_MM },
146 { "C1", 648, 917, SP_UNIT_MM },
147 { "C2", 458, 648, SP_UNIT_MM },
148 { "C3", 324, 458, SP_UNIT_MM },
149 { "C4", 229, 324, SP_UNIT_MM },
150 { "C5", 162, 229, SP_UNIT_MM },
151 { "C6", 114, 162, SP_UNIT_MM },
152 { "C7", 81, 114, SP_UNIT_MM },
153 { "C8", 57, 81, SP_UNIT_MM },
154 { "C9", 40, 57, SP_UNIT_MM },
155 { "C10", 28, 40, SP_UNIT_MM },
156 { "D1", 545, 771, SP_UNIT_MM },
157 { "D2", 385, 545, SP_UNIT_MM },
158 { "D3", 272, 385, SP_UNIT_MM },
159 { "D4", 192, 272, SP_UNIT_MM },
160 { "D5", 136, 192, SP_UNIT_MM },
161 { "D6", 96, 136, SP_UNIT_MM },
162 { "D7", 68, 96, SP_UNIT_MM },
163 { "E3", 400, 560, SP_UNIT_MM },
164 { "E4", 280, 400, SP_UNIT_MM },
165 { "E5", 200, 280, SP_UNIT_MM },
166 { "E6", 140, 200, SP_UNIT_MM },
167 //#endif
171 { "CSE", 462, 649, SP_UNIT_PT },
172 { "US #10 Envelope", 4.125, 9.5, SP_UNIT_IN },
173 /* See http://www.hbp.com/content/PCR_envelopes.cfm for a much larger list of US envelope
174 sizes. */
175 { "DL Envelope", 110, 220, SP_UNIT_MM },
176 { "Ledger/Tabloid", 11, 17, SP_UNIT_IN },
177 /* Note that `Folio' (used in QPrinter/KPrinter) is deliberately absent from this list, as it
178 means different sizes to different people: different people may expect the width to be
179 either 8, 8.25 or 8.5 inches, and the height to be either 13 or 13.5 inches, even
180 restricting our interpretation to foolscap folio. If you wish to introduce a folio-like
181 page size to the list, then please consider using a name more specific than just `Folio' or
182 `Foolscap Folio'. */
183 { "Banner 468x60", 60, 468, SP_UNIT_PX },
184 { "Icon 16x16", 16, 16, SP_UNIT_PX },
185 { "Icon 32x32", 32, 32, SP_UNIT_PX },
186 { "Icon 48x48", 48, 48, SP_UNIT_PX },
187 /* business cards */
188 { "Business Card (ISO 7810)", 53.98, 85.60, SP_UNIT_MM },
189 { "Business Card (US)", 2, 3.5, SP_UNIT_IN },
190 { "Business Card (Europe)", 55, 85, SP_UNIT_MM },
191 { "Business Card (Aus/NZ)", 55, 90, SP_UNIT_MM },
193 // Start Arch Series List
196 { "Arch A", 9, 12, SP_UNIT_IN }, // 229 x 305 mm
197 { "Arch B", 12, 18, SP_UNIT_IN }, // 305 x 457 mm
198 { "Arch C", 18, 24, SP_UNIT_IN }, // 457 x 610 mm
199 { "Arch D", 24, 36, SP_UNIT_IN }, // 610 x 914 mm
200 { "Arch E", 36, 48, SP_UNIT_IN }, // 914 x 1219 mm
201 { "Arch E1", 30, 42, SP_UNIT_IN }, // 762 x 1067 mm
203 /*
204 * The above list of Arch sizes were taken from the following site:
205 * http://en.wikipedia.org/wiki/Paper_size
206 * Further detail can be found at http://www.ansi.org
207 * Sizes are assumed to be arbitrary rounding to MM unless shown to be otherwise
208 * No conflicting information was found regarding sizes in MM
209 * September 2009 - DAK
210 */
212 { NULL, 0, 0, SP_UNIT_PX },
213 };
217 //########################################################################
218 //# P A G E S I Z E R
219 //########################################################################
221 //The default unit for this widget and its calculations
222 static const SPUnit _px_unit = sp_unit_get_by_id (SP_UNIT_PX);
225 /**
226 * Constructor
227 */
228 PageSizer::PageSizer(Registry & _wr)
229 : Gtk::VBox(false,4),
230 _dimensionUnits( _("U_nits:"), "units", _wr ),
231 _dimensionWidth( _("_Width:"), _("Width of paper"), "width", _dimensionUnits, _wr ),
232 _dimensionHeight( _("_Height:"), _("Height of paper"), "height", _dimensionUnits, _wr ),
233 _marginTop( _("T_op margin:"), _("Top margin"), "fit-margin-top", _wr ),
234 _marginLeft( _("L_eft:"), _("Left margin"), "fit-margin-left", _wr),
235 _marginRight( _("Ri_ght:"), _("Right margin"), "fit-margin-right", _wr),
236 _marginBottom( _("Botto_m:"), _("Bottom margin"), "fit-margin-bottom", _wr),
238 _widgetRegistry(&_wr)
239 {
240 //# Set up the Paper Size combo box
241 _paperSizeListStore = Gtk::ListStore::create(_paperSizeListColumns);
242 _paperSizeList.set_model(_paperSizeListStore);
243 _paperSizeList.append_column(_("Name"),
244 _paperSizeListColumns.nameColumn);
245 _paperSizeList.append_column(_("Description"),
246 _paperSizeListColumns.descColumn);
247 _paperSizeList.set_headers_visible(false);
248 _paperSizeListSelection = _paperSizeList.get_selection();
249 _paper_size_list_connection =
250 _paperSizeListSelection->signal_changed().connect (
251 sigc::mem_fun (*this, &PageSizer::on_paper_size_list_changed));
252 _paperSizeListScroller.add(_paperSizeList);
253 _paperSizeListScroller.set_shadow_type(Gtk::SHADOW_IN);
254 _paperSizeListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
255 _paperSizeListScroller.set_size_request(-1, 90);
257 fill_landscape_papers();
259 for (PaperSizeRec const *p = inkscape_papers; p->name; p++)
260 {
261 Glib::ustring name = p->name;
262 char formatBuf[80];
263 snprintf(formatBuf, 79, "%0.1f x %0.1f", p->smaller, p->larger);
264 Glib::ustring desc = formatBuf;
265 if (p->unit == SP_UNIT_IN)
266 desc.append(" in");
267 else if (p->unit == SP_UNIT_MM)
268 desc.append(" mm");
269 else if (p->unit == SP_UNIT_PX)
270 desc.append(" px");
271 PaperSize paper(name, p->smaller, p->larger, p->unit);
272 _paperSizeTable[name] = paper;
273 Gtk::TreeModel::Row row = *(_paperSizeListStore->append());
274 row[_paperSizeListColumns.nameColumn] = name;
275 row[_paperSizeListColumns.descColumn] = desc;
276 }
277 //Gtk::TreeModel::iterator iter = _paperSizeListStore->children().begin();
278 //if (iter)
279 // _paperSizeListSelection->select(iter);
282 pack_start (_paperSizeListScroller, true, true, 0);
284 //## Set up orientation radio buttons
285 pack_start (_orientationBox, false, false, 0);
286 _orientationLabel.set_label(_("Orientation:"));
287 _orientationBox.pack_start(_orientationLabel, false, false, 0);
288 _landscapeButton.set_use_underline();
289 _landscapeButton.set_label(_("_Landscape"));
290 _landscapeButton.set_active(true);
291 Gtk::RadioButton::Group group = _landscapeButton.get_group();
292 _orientationBox.pack_end (_landscapeButton, false, false, 5);
293 _portraitButton.set_use_underline();
294 _portraitButton.set_label(_("_Portrait"));
295 _portraitButton.set_active(true);
296 _orientationBox.pack_end (_portraitButton, false, false, 5);
297 _portraitButton.set_group (group);
298 _portraitButton.set_active (true);
300 //## Set up custom size frame
301 _customFrame.set_label(_("Custom size"));
302 pack_start (_customFrame, false, false, 0);
303 _customFrame.add(_customDimTable);
305 _customDimTable.resize(3, 2);
306 _customDimTable.set_border_width(4);
307 _customDimTable.set_row_spacings(4);
308 _customDimTable.set_col_spacings(4);
309 _customDimTable.attach(_dimensionWidth, 0,1, 0,1);
310 _customDimTable.attach(_dimensionUnits, 1,2, 0,1);
311 _customDimTable.attach(_dimensionHeight, 0,1, 1,2);
312 _customDimTable.attach(_fitPageMarginExpander, 0,2, 2,3);
314 _dimTabOrderGList = NULL;
315 _dimTabOrderGList = g_list_append(_dimTabOrderGList, _dimensionWidth.gobj());
316 _dimTabOrderGList = g_list_append(_dimTabOrderGList, _dimensionHeight.gobj());
317 _dimTabOrderGList = g_list_append(_dimTabOrderGList, _dimensionUnits.gobj());
318 _dimTabOrderGList = g_list_append(_dimTabOrderGList, _fitPageMarginExpander.gobj());
319 Glib::ListHandle<Widget *> dimFocusChain(_dimTabOrderGList, Glib::OWNERSHIP_NONE);
320 _customDimTable.set_focus_chain(dimFocusChain);
322 //## Set up fit page expander
323 _fitPageMarginExpander.set_use_underline();
324 _fitPageMarginExpander.set_label(_("Resi_ze page to content..."));
325 _fitPageMarginExpander.add(_marginTable);
327 //## Set up margin settings
328 _marginTable.resize(4, 2);
329 _marginTable.set_border_width(4);
330 _marginTable.set_row_spacings(4);
331 _marginTable.set_col_spacings(4);
332 _marginTable.attach(_marginTopAlign, 0,2, 0,1);
333 _marginTable.attach(_marginLeftAlign, 0,1, 1,2);
334 _marginTable.attach(_marginRightAlign, 1,2, 1,2);
335 _marginTable.attach(_marginBottomAlign, 0,2, 2,3);
336 _marginTable.attach(_fitPageButtonAlign, 0,2, 3,4);
338 _marginTopAlign.set(0.5, 0.5, 0.0, 1.0);
339 _marginTopAlign.add(_marginTop);
340 _marginLeftAlign.set(0.0, 0.5, 0.0, 1.0);
341 _marginLeftAlign.add(_marginLeft);
342 _marginRightAlign.set(1.0, 0.5, 0.0, 1.0);
343 _marginRightAlign.add(_marginRight);
344 _marginBottomAlign.set(0.5, 0.5, 0.0, 1.0);
345 _marginBottomAlign.add(_marginBottom);
347 _fitPageButtonAlign.set(0.5, 0.5, 0.0, 1.0);
348 _fitPageButtonAlign.add(_fitPageButton);
349 _fitPageButton.set_use_underline();
350 _fitPageButton.set_label(_("_Resize page to drawing or selection"));
351 _tips.set_tip(_fitPageButton, _("Resize the page to fit the current selection, or the entire drawing if there is no selection"));
353 }
356 /**
357 * Destructor
358 */
359 PageSizer::~PageSizer()
360 {
361 g_list_free(_dimTabOrderGList);
362 }
366 /**
367 * Initialize or reset this widget
368 */
369 void
370 PageSizer::init ()
371 {
372 _landscape_connection = _landscapeButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_landscape));
373 _portrait_connection = _portraitButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_portrait));
374 _changedw_connection = _dimensionWidth.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
375 _changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
376 _fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
378 show_all_children();
379 }
382 /**
383 * Set document dimensions (if not called by Doc prop's update()) and
384 * set the PageSizer's widgets and text entries accordingly. If
385 * 'changeList' is true, then adjust the paperSizeList to show the closest
386 * standard page size.
387 *
388 * \param w, h given in px
389 * \param changeList whether to modify the paper size list
390 */
391 void
392 PageSizer::setDim (double w, double h, bool changeList)
393 {
394 static bool _called = false;
395 if (_called) {
396 return;
397 }
399 _called = true;
401 _paper_size_list_connection.block();
402 _landscape_connection.block();
403 _portrait_connection.block();
404 _changedw_connection.block();
405 _changedh_connection.block();
407 if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) {
408 SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
409 double const old_height = sp_document_height(doc);
410 sp_document_set_width (doc, w, &_px_unit);
411 sp_document_set_height (doc, h, &_px_unit);
412 // The origin for the user is in the lower left corner; this point should remain stationary when
413 // changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this
414 Geom::Translate const vert_offset(Geom::Point(0, (old_height - h)));
415 SP_GROUP(SP_ROOT(doc->root))->translateChildItems(vert_offset);
416 sp_document_done (doc, SP_VERB_NONE, _("Set page size"));
417 }
419 if ( w != h ) {
420 _landscapeButton.set_sensitive(true);
421 _portraitButton.set_sensitive (true);
422 _landscape = ( w > h );
423 _landscapeButton.set_active(_landscape ? true : false);
424 _portraitButton.set_active (_landscape ? false : true);
425 } else {
426 _landscapeButton.set_sensitive(false);
427 _portraitButton.set_sensitive (false);
428 }
430 if (changeList)
431 {
432 Gtk::TreeModel::Row row = (*find_paper_size(w, h));
433 if (row)
434 _paperSizeListSelection->select(row);
435 }
437 Unit const& unit = _dimensionUnits.getUnit();
438 _dimensionWidth.setValue (w / unit.factor);
439 _dimensionHeight.setValue (h / unit.factor);
441 _paper_size_list_connection.unblock();
442 _landscape_connection.unblock();
443 _portrait_connection.unblock();
444 _changedw_connection.unblock();
445 _changedh_connection.unblock();
447 _called = false;
448 }
450 /**
451 * Updates the scalar widgets for the fit margins. (Just changes the value
452 * of the ui widgets to match the xml).
453 */
454 void
455 PageSizer::updateFitMarginsUI(Inkscape::XML::Node *nv_repr)
456 {
457 double value = 0.0;
458 if (sp_repr_get_double(nv_repr, "fit-margin-top", &value)) {
459 _marginTop.setValue(value);
460 }
461 if (sp_repr_get_double(nv_repr, "fit-margin-left", &value)) {
462 _marginLeft.setValue(value);
463 }
464 if (sp_repr_get_double(nv_repr, "fit-margin-right", &value)) {
465 _marginRight.setValue(value);
466 }
467 if (sp_repr_get_double(nv_repr, "fit-margin-bottom", &value)) {
468 _marginBottom.setValue(value);
469 }
470 }
473 /**
474 * Returns an iterator pointing to a row in paperSizeListStore which
475 * contains a paper of the specified size (specified in px), or
476 * paperSizeListStore->children().end() if no such paper exists.
477 */
478 Gtk::ListStore::iterator
479 PageSizer::find_paper_size (double w, double h) const
480 {
481 double smaller = w;
482 double larger = h;
483 if ( h < w ) {
484 smaller = h; larger = w;
485 }
487 g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end());
489 std::map<Glib::ustring, PaperSize>::const_iterator iter;
490 for (iter = _paperSizeTable.begin() ;
491 iter != _paperSizeTable.end() ; iter++) {
492 PaperSize paper = iter->second;
493 SPUnit const &i_unit = sp_unit_get_by_id(paper.unit);
494 double smallX = sp_units_get_pixels(paper.smaller, i_unit);
495 double largeX = sp_units_get_pixels(paper.larger, i_unit);
497 g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end());
499 if ((std::abs(smaller - smallX) <= 0.1) &&
500 (std::abs(larger - largeX) <= 0.1) ) {
501 Gtk::ListStore::iterator p;
502 // We need to search paperSizeListStore explicitly for the
503 // specified paper size because it is sorted in a different
504 // way than paperSizeTable (which is sorted alphabetically)
505 for (p = _paperSizeListStore->children().begin(); p != _paperSizeListStore->children().end(); p++) {
506 if ((*p)[_paperSizeListColumns.nameColumn] == paper.name) {
507 return p;
508 }
509 }
510 }
511 }
512 return _paperSizeListStore->children().end();
513 }
517 /**
518 * Tell the desktop to fit the page size to the selection or drawing.
519 */
520 void
521 PageSizer::fire_fit_canvas_to_selection_or_drawing()
522 {
523 SPDesktop *dt = SP_ACTIVE_DESKTOP;
524 if (!dt) {
525 return;
526 }
527 SPDocument *doc;
528 SPNamedView *nv;
529 Inkscape::XML::Node *nv_repr;
530 if ((doc = sp_desktop_document(SP_ACTIVE_DESKTOP))
531 && (nv = sp_document_namedview(doc, 0))
532 && (nv_repr = SP_OBJECT_REPR(nv))) {
533 sp_repr_set_svg_double(nv_repr, "fit-margin-top", _marginTop.getValue());
534 sp_repr_set_svg_double(nv_repr, "fit-margin-left", _marginLeft.getValue());
535 sp_repr_set_svg_double(nv_repr, "fit-margin-right", _marginRight.getValue());
536 sp_repr_set_svg_double(nv_repr, "fit-margin-bottom", _marginBottom.getValue());
537 }
538 Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING );
539 if (verb) {
540 SPAction *action = verb->get_action(dt);
541 if (action) {
542 sp_action_perform(action, NULL);
543 }
544 }
545 }
549 /**
550 * Paper Size list callback for when a user changes the selection
551 */
552 void
553 PageSizer::on_paper_size_list_changed()
554 {
555 //Glib::ustring name = _paperSizeList.get_active_text();
556 Gtk::TreeModel::iterator miter = _paperSizeListSelection->get_selected();
557 if(!miter)
558 {
559 //error?
560 return;
561 }
562 Gtk::TreeModel::Row row = *miter;
563 Glib::ustring name = row[_paperSizeListColumns.nameColumn];
564 std::map<Glib::ustring, PaperSize>::const_iterator piter =
565 _paperSizeTable.find(name);
566 if (piter == _paperSizeTable.end()) {
567 g_warning("paper size '%s' not found in table", name.c_str());
568 return;
569 }
570 PaperSize paper = piter->second;
571 double w = paper.smaller;
572 double h = paper.larger;
574 if (std::find(lscape_papers.begin(), lscape_papers.end(), paper.name.c_str()) != lscape_papers.end()) {
575 // enforce landscape mode if this is desired for the given page format
576 _landscape = true;
577 } else {
578 // otherwise we keep the current mode
579 _landscape = _landscapeButton.get_active();
580 }
582 SPUnit const &src_unit = sp_unit_get_by_id (paper.unit);
583 sp_convert_distance (&w, &src_unit, &_px_unit);
584 sp_convert_distance (&h, &src_unit, &_px_unit);
586 if (_landscape)
587 setDim (h, w, false);
588 else
589 setDim (w, h, false);
591 }
594 /**
595 * Portrait button callback
596 */
597 void
598 PageSizer::on_portrait()
599 {
600 if (!_portraitButton.get_active())
601 return;
602 double w = _dimensionWidth.getValue ("px");
603 double h = _dimensionHeight.getValue ("px");
604 if (h < w) {
605 setDim (h, w);
606 }
607 }
610 /**
611 * Landscape button callback
612 */
613 void
614 PageSizer::on_landscape()
615 {
616 if (!_landscapeButton.get_active())
617 return;
618 double w = _dimensionWidth.getValue ("px");
619 double h = _dimensionHeight.getValue ("px");
620 if (w < h) {
621 setDim (h, w);
622 }
623 }
625 /**
626 * Callback for the dimension widgets
627 */
628 void
629 PageSizer::on_value_changed()
630 {
631 if (_widgetRegistry->isUpdating()) return;
633 setDim (_dimensionWidth.getValue("px"),
634 _dimensionHeight.getValue("px"));
635 }
638 } // namespace Widget
639 } // namespace UI
640 } // namespace Inkscape
642 /*
643 Local Variables:
644 mode:c++
645 c-file-style:"stroustrup"
646 c-file-offsets:((innamespace . 0)(inline-open . 0))
647 indent-tabs-mode:nil
648 fill-column:99
649 End:
650 */
651 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :