Code

A simple layout document as to what, why and how is cppification.
[inkscape.git] / src / ui / widget / page-sizer.cpp
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)");
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),
237       
238       _widgetRegistry(&_wr)
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);
313     
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);
326     
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);
337     
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);
346     
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"));
356 /**
357  * Destructor
358  */
359 PageSizer::~PageSizer()
361     g_list_free(_dimTabOrderGList);
366 /**
367  * Initialize or reset this widget
368  */
369 void
370 PageSizer::init ()
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();
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)
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 = doc->getHeight();
410         doc->setWidth (w, &_px_unit);
411         doc->setHeight (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         SPDocumentUndo::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;
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)
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     }
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
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();
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()
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     }
549 /**
550  * Paper Size list callback for when a user changes the selection
551  */
552 void
553 PageSizer::on_paper_size_list_changed()
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);
594 /**
595  * Portrait button callback
596  */
597 void
598 PageSizer::on_portrait()
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     }
610 /**
611  * Landscape button callback
612  */
613 void
614 PageSizer::on_landscape()
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     }
625 /**
626  * Callback for the dimension widgets
627  */
628 void
629 PageSizer::on_value_changed()
631     if (_widgetRegistry->isUpdating()) return;
633     setDim (_dimensionWidth.getValue("px"),
634             _dimensionHeight.getValue("px"));
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 :