Code

Merge and cleanup of GSoC C++-ification project.
[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  *   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)");
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),
238       
239       _widgetRegistry(&_wr)
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     }
309     
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);
323     
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);
336     
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);
347     
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);
356     
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"));
366 /**
367  * Destructor
368  */
369 PageSizer::~PageSizer()
371     g_list_free(_dimTabOrderGList);
376 /**
377  * Initialize or reset this widget
378  */
379 void
380 PageSizer::init ()
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();
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)
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;
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)
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     }
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
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();
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()
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     }
559 /**
560  * Paper Size list callback for when a user changes the selection
561  */
562 void
563 PageSizer::on_paper_size_list_changed()
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);
604 /**
605  * Portrait button callback
606  */
607 void
608 PageSizer::on_portrait()
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     }
620 /**
621  * Landscape button callback
622  */
623 void
624 PageSizer::on_landscape()
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     }
635 /**
636  * Callback for the dimension widgets
637  */
638 void
639 PageSizer::on_value_changed()
641     if (_widgetRegistry->isUpdating()) return;
643     setDim (_dimensionWidth.getValue("px"),
644             _dimensionHeight.getValue("px"));
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 :