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