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