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 //## Set up fit page expander
315 _fitPageMarginExpander.set_label(_("Resi_ze page to content..."));
316 _fitPageMarginExpander.set_use_underline();
317 _fitPageMarginExpander.add(_marginTable);
319 //## Set up margin settings
320 _marginTable.resize(4, 2);
321 _marginTable.set_border_width(4);
322 _marginTable.set_row_spacings(4);
323 _marginTable.set_col_spacings(4);
324 _marginTable.attach(_marginTopAlign, 0,2, 0,1);
325 _marginTable.attach(_marginLeftAlign, 0,1, 1,2);
326 _marginTable.attach(_marginRightAlign, 1,2, 1,2);
327 _marginTable.attach(_marginBottomAlign, 0,2, 2,3);
328 _marginTable.attach(_fitPageButtonAlign, 0,2, 3,4);
330 _marginTopAlign.set(0.5, 0.5, 0.0, 1.0);
331 _marginTopAlign.add(_marginTop);
332 _marginLeftAlign.set(0.0, 0.5, 0.0, 1.0);
333 _marginLeftAlign.add(_marginLeft);
334 _marginRightAlign.set(1.0, 0.5, 0.0, 1.0);
335 _marginRightAlign.add(_marginRight);
336 _marginBottomAlign.set(0.5, 0.5, 0.0, 1.0);
337 _marginBottomAlign.add(_marginBottom);
339 _fitPageButtonAlign.set(0.5, 0.5, 0.0, 1.0);
340 _fitPageButtonAlign.add(_fitPageButton);
341 _fitPageButton.set_use_underline();
342 _fitPageButton.set_label(_("_Resize page to drawing or selection"));
343 _tips.set_tip(_fitPageButton, _("Resize the page to fit the current selection, or the entire drawing if there is no selection"));
345 }
348 /**
349 * Destructor
350 */
351 PageSizer::~PageSizer()
352 {
353 }
357 /**
358 * Initialize or reset this widget
359 */
360 void
361 PageSizer::init ()
362 {
363 _landscape_connection = _landscapeButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_landscape));
364 _portrait_connection = _portraitButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_portrait));
365 _changedw_connection = _dimensionWidth.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
366 _changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
367 _fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
369 show_all_children();
370 }
373 /**
374 * Set document dimensions (if not called by Doc prop's update()) and
375 * set the PageSizer's widgets and text entries accordingly. If
376 * 'changeList' is true, then adjust the paperSizeList to show the closest
377 * standard page size.
378 *
379 * \param w, h given in px
380 * \param changeList whether to modify the paper size list
381 */
382 void
383 PageSizer::setDim (double w, double h, bool changeList)
384 {
385 static bool _called = false;
386 if (_called) {
387 return;
388 }
390 _called = true;
392 _paper_size_list_connection.block();
393 _landscape_connection.block();
394 _portrait_connection.block();
395 _changedw_connection.block();
396 _changedh_connection.block();
398 if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) {
399 SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
400 double const old_height = sp_document_height(doc);
401 sp_document_set_width (doc, w, &_px_unit);
402 sp_document_set_height (doc, h, &_px_unit);
403 // The origin for the user is in the lower left corner; this point should remain stationary when
404 // changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this
405 Geom::Translate const vert_offset(Geom::Point(0, (old_height - h)));
406 SP_GROUP(SP_ROOT(doc->root))->translateChildItems(vert_offset);
407 sp_document_done (doc, SP_VERB_NONE, _("Set page size"));
408 }
410 if ( w != h ) {
411 _landscapeButton.set_sensitive(true);
412 _portraitButton.set_sensitive (true);
413 _landscape = ( w > h );
414 _landscapeButton.set_active(_landscape ? true : false);
415 _portraitButton.set_active (_landscape ? false : true);
416 } else {
417 _landscapeButton.set_sensitive(false);
418 _portraitButton.set_sensitive (false);
419 }
421 if (changeList)
422 {
423 Gtk::TreeModel::Row row = (*find_paper_size(w, h));
424 if (row)
425 _paperSizeListSelection->select(row);
426 }
428 Unit const& unit = _dimensionUnits.getUnit();
429 _dimensionWidth.setValue (w / unit.factor);
430 _dimensionHeight.setValue (h / unit.factor);
432 _paper_size_list_connection.unblock();
433 _landscape_connection.unblock();
434 _portrait_connection.unblock();
435 _changedw_connection.unblock();
436 _changedh_connection.unblock();
438 _called = false;
439 }
441 /**
442 * Updates the scalar widgets for the fit margins. (Just changes the value
443 * of the ui widgets to match the xml).
444 */
445 void
446 PageSizer::updateFitMarginsUI(Inkscape::XML::Node *nv_repr)
447 {
448 double value = 0.0;
449 if (sp_repr_get_double(nv_repr, "fit-margin-top", &value)) {
450 _marginTop.setValue(value);
451 }
452 if (sp_repr_get_double(nv_repr, "fit-margin-left", &value)) {
453 _marginLeft.setValue(value);
454 }
455 if (sp_repr_get_double(nv_repr, "fit-margin-right", &value)) {
456 _marginRight.setValue(value);
457 }
458 if (sp_repr_get_double(nv_repr, "fit-margin-bottom", &value)) {
459 _marginBottom.setValue(value);
460 }
461 }
464 /**
465 * Returns an iterator pointing to a row in paperSizeListStore which
466 * contains a paper of the specified size (specified in px), or
467 * paperSizeListStore->children().end() if no such paper exists.
468 */
469 Gtk::ListStore::iterator
470 PageSizer::find_paper_size (double w, double h) const
471 {
472 double smaller = w;
473 double larger = h;
474 if ( h < w ) {
475 smaller = h; larger = w;
476 }
478 g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end());
480 std::map<Glib::ustring, PaperSize>::const_iterator iter;
481 for (iter = _paperSizeTable.begin() ;
482 iter != _paperSizeTable.end() ; iter++) {
483 PaperSize paper = iter->second;
484 SPUnit const &i_unit = sp_unit_get_by_id(paper.unit);
485 double smallX = sp_units_get_pixels(paper.smaller, i_unit);
486 double largeX = sp_units_get_pixels(paper.larger, i_unit);
488 g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end());
490 if ((std::abs(smaller - smallX) <= 0.1) &&
491 (std::abs(larger - largeX) <= 0.1) ) {
492 Gtk::ListStore::iterator p;
493 // We need to search paperSizeListStore explicitly for the
494 // specified paper size because it is sorted in a different
495 // way than paperSizeTable (which is sorted alphabetically)
496 for (p = _paperSizeListStore->children().begin(); p != _paperSizeListStore->children().end(); p++) {
497 if ((*p)[_paperSizeListColumns.nameColumn] == paper.name) {
498 return p;
499 }
500 }
501 }
502 }
503 return _paperSizeListStore->children().end();
504 }
508 /**
509 * Tell the desktop to fit the page size to the selection or drawing.
510 */
511 void
512 PageSizer::fire_fit_canvas_to_selection_or_drawing()
513 {
514 SPDesktop *dt = SP_ACTIVE_DESKTOP;
515 if (!dt) {
516 return;
517 }
518 SPDocument *doc;
519 SPNamedView *nv;
520 Inkscape::XML::Node *nv_repr;
521 if ((doc = sp_desktop_document(SP_ACTIVE_DESKTOP))
522 && (nv = sp_document_namedview(doc, 0))
523 && (nv_repr = SP_OBJECT_REPR(nv))) {
524 sp_repr_set_svg_double(nv_repr, "fit-margin-top", _marginTop.getValue());
525 sp_repr_set_svg_double(nv_repr, "fit-margin-left", _marginLeft.getValue());
526 sp_repr_set_svg_double(nv_repr, "fit-margin-right", _marginRight.getValue());
527 sp_repr_set_svg_double(nv_repr, "fit-margin-bottom", _marginBottom.getValue());
528 }
529 Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING );
530 if (verb) {
531 SPAction *action = verb->get_action(dt);
532 if (action) {
533 sp_action_perform(action, NULL);
534 }
535 }
536 }
540 /**
541 * Paper Size list callback for when a user changes the selection
542 */
543 void
544 PageSizer::on_paper_size_list_changed()
545 {
546 //Glib::ustring name = _paperSizeList.get_active_text();
547 Gtk::TreeModel::iterator miter = _paperSizeListSelection->get_selected();
548 if(!miter)
549 {
550 //error?
551 return;
552 }
553 Gtk::TreeModel::Row row = *miter;
554 Glib::ustring name = row[_paperSizeListColumns.nameColumn];
555 std::map<Glib::ustring, PaperSize>::const_iterator piter =
556 _paperSizeTable.find(name);
557 if (piter == _paperSizeTable.end()) {
558 g_warning("paper size '%s' not found in table", name.c_str());
559 return;
560 }
561 PaperSize paper = piter->second;
562 double w = paper.smaller;
563 double h = paper.larger;
565 if (std::find(lscape_papers.begin(), lscape_papers.end(), paper.name.c_str()) != lscape_papers.end()) {
566 // enforce landscape mode if this is desired for the given page format
567 _landscape = true;
568 } else {
569 // otherwise we keep the current mode
570 _landscape = _landscapeButton.get_active();
571 }
573 SPUnit const &src_unit = sp_unit_get_by_id (paper.unit);
574 sp_convert_distance (&w, &src_unit, &_px_unit);
575 sp_convert_distance (&h, &src_unit, &_px_unit);
577 if (_landscape)
578 setDim (h, w, false);
579 else
580 setDim (w, h, false);
582 }
585 /**
586 * Portrait button callback
587 */
588 void
589 PageSizer::on_portrait()
590 {
591 if (!_portraitButton.get_active())
592 return;
593 double w = _dimensionWidth.getValue ("px");
594 double h = _dimensionHeight.getValue ("px");
595 if (h < w) {
596 setDim (h, w);
597 }
598 }
601 /**
602 * Landscape button callback
603 */
604 void
605 PageSizer::on_landscape()
606 {
607 if (!_landscapeButton.get_active())
608 return;
609 double w = _dimensionWidth.getValue ("px");
610 double h = _dimensionHeight.getValue ("px");
611 if (w < h) {
612 setDim (h, w);
613 }
614 }
616 /**
617 * Callback for the dimension widgets
618 */
619 void
620 PageSizer::on_value_changed()
621 {
622 if (_widgetRegistry->isUpdating()) return;
624 setDim (_dimensionWidth.getValue("px"),
625 _dimensionHeight.getValue("px"));
626 }
629 } // namespace Widget
630 } // namespace UI
631 } // namespace Inkscape
633 /*
634 Local Variables:
635 mode:c++
636 c-file-style:"stroustrup"
637 c-file-offsets:((innamespace . 0)(inline-open . 0))
638 indent-tabs-mode:nil
639 fill-column:99
640 End:
641 */
642 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :