Code

copyedit
[inkscape.git] / src / ui / widget / page-sizer.cpp
index d657b909640f8383b099dbb91f94c1bf1833b8d5..f193f04d20fa44aa9bc65e783e7023cb6bc8eb16 100644 (file)
@@ -7,7 +7,7 @@
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   Jon Phillips <jon@rejon.org>
  *   Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
- *   Bob Jamison <ishmal@users.sf.net> 
+ *   Bob Jamison <ishmal@users.sf.net>
  *
  * Copyright (C) 2000 - 2006 Authors
  *
@@ -18,6 +18,8 @@
 # include <config.h>
 #endif
 
+#include <string.h>
+
 #include <cmath>
 #include <gtkmm.h>
 #include "ui/widget/button.h"
@@ -52,7 +54,7 @@ namespace Widget {
      * this table and in ghostscript.
      *
      * The versions here, in mm, are the official sizes according to
-     * <a href="http://en.wikipedia.org/wiki/Paper_sizes">http://en.wikipedia.org/wiki/Paper_sizes</a> 
+     * <a href="http://en.wikipedia.org/wiki/Paper_sizes">http://en.wikipedia.org/wiki/Paper_sizes</a>
      * at 2005-01-25.  (The ISO entries in the below table
      * were produced mechanically from the table on that page.)
      *
@@ -72,7 +74,7 @@ namespace Widget {
      * inconsistent rounding rules when converting from mm to pt.
      */
     /** \todo
-     * Should we include the JIS B series (used in Japan)  
+     * Should we include the JIS B series (used in Japan)
      * (JIS B0 is sometimes called JB0, and similarly for JB1 etc)?
      * Should we exclude B7--B10 and A7--10 to make the list smaller ?
      * Should we include any of the ISO C, D and E series (see below) ?
@@ -112,11 +114,16 @@ static PaperSizeRec const inkscape_papers[] = {
     { "B9",                 44,   62, SP_UNIT_MM },
     { "B10",                31,   44, SP_UNIT_MM },
 
-#if 0 /* 
+
+
+//#if 0
+         /*
          Whether to include or exclude these depends on how
          big we mind our page size menu
          becoming.  C series is used for envelopes;
-                don't know what D and E series are used for. */
+         don't know what D and E series are used for.
+         */
+
     { "C0",                917, 1297, SP_UNIT_MM },
     { "C1",                648,  917, SP_UNIT_MM },
     { "C2",                458,  648, SP_UNIT_MM },
@@ -139,15 +146,17 @@ static PaperSizeRec const inkscape_papers[] = {
     { "E4",                280,  400, SP_UNIT_MM },
     { "E5",                200,  280, SP_UNIT_MM },
     { "E6",                140,  200, SP_UNIT_MM },
-#endif
+//#endif
+
+
 
     { "CSE",               462,  649, SP_UNIT_PT },
     { "US #10 Envelope", 4.125,  9.5, SP_UNIT_IN },
-        // TODO: Select landscape by default.
+    // TODO: Select landscape by default.
     /* See http://www.hbp.com/content/PCR_envelopes.cfm for a much larger list of US envelope
        sizes. */
     { "DL Envelope",       110,  220, SP_UNIT_MM },
-        // TODO: Select landscape by default.
+    // TODO: Select landscape by default.
     { "Ledger/Tabloid",     11,   17, SP_UNIT_IN },
     /* Note that `Folio' (used in QPrinter/KPrinter) is deliberately absent from this list, as it
        means different sizes to different people: different people may expect the width to be
@@ -156,7 +165,7 @@ static PaperSizeRec const inkscape_papers[] = {
        page size to the list, then please consider using a name more specific than just `Folio' or
        `Foolscap Folio'. */
     { "Banner 468x60",      60,  468, SP_UNIT_PX },
-         // TODO: Select landscape by default.
+    // TODO: Select landscape by default.
     { "Icon 16x16",         16,   16, SP_UNIT_PX },
     { "Icon 32x32",         32,   32, SP_UNIT_PX },
     { "Icon 48x48",         48,   48, SP_UNIT_PX },
@@ -175,33 +184,99 @@ static const SPUnit _px_unit = sp_unit_get_by_id (SP_UNIT_PX);
 
 /**
  * Constructor
- */ 
-PageSizer::PageSizer() : Gtk::VBox(false,4)
+ */
+PageSizer::PageSizer(Registry & _wr)
+    : Gtk::VBox(false,4),
+      _dimensionUnits( _("U_nits:"), "units", _wr ),
+      _dimensionWidth( _("_Width:"), _("Width of paper"), "width", _dimensionUnits, _wr ),
+      _dimensionHeight( _("_Height:"), _("Height of paper"), "height", _dimensionUnits, _wr ),
+      _widgetRegistry(&_wr)
 {
-    Gtk::HBox *hbox_size = manage (new Gtk::HBox (false, 4));
-    pack_start (*hbox_size, false, false, 0);
-    Gtk::Label *label_size = manage (new Gtk::Label (_("P_age size:"), 1.0, 0.5)); 
-    label_size->set_use_underline();
-    hbox_size->pack_start (*label_size, false, false, 0);
-    label_size->set_mnemonic_widget (_paperSizeList);
-    hbox_size->pack_start (_paperSizeList, true, true, 0);
-
     //# Set up the Paper Size combo box
-    
+    _paperSizeListStore = Gtk::ListStore::create(_paperSizeListColumns);
+    _paperSizeList.set_model(_paperSizeListStore);
+    _paperSizeList.append_column(_("Name"),
+                                 _paperSizeListColumns.nameColumn);
+    _paperSizeList.append_column(_("Description"),
+                                 _paperSizeListColumns.descColumn);
+    _paperSizeList.set_headers_visible(false);
+    _paperSizeListSelection = _paperSizeList.get_selection();
+    _paper_size_list_connection =
+        _paperSizeListSelection->signal_changed().connect (
+            sigc::mem_fun (*this, &PageSizer::on_paper_size_list_changed));
+    _paperSizeListScroller.add(_paperSizeList);
+    _paperSizeListScroller.set_shadow_type(Gtk::SHADOW_IN);
+    _paperSizeListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
+    _paperSizeListScroller.set_size_request(-1, 90);
+
     for (PaperSizeRec const *p = inkscape_papers; p->name; p++)
-           {
+    {
         Glib::ustring name = p->name;
+        char formatBuf[80];
+        snprintf(formatBuf, 79, "%0.1f x %0.1f", p->smaller, p->larger);
+        Glib::ustring desc = formatBuf;
+        if (p->unit == SP_UNIT_IN)
+            desc.append(" in");
+        else if (p->unit == SP_UNIT_MM)
+             desc.append(" mm");
+        else if (p->unit == SP_UNIT_PX)
+            desc.append(" px");
         PaperSize paper(name, p->smaller, p->larger, p->unit);
-        paperSizeTable[name] = paper;
-        _paperSizeList.append_text(name);
+        _paperSizeTable[name] = paper;
+        Gtk::TreeModel::Row row = *(_paperSizeListStore->append());
+        row[_paperSizeListColumns.nameColumn] = name;
+        row[_paperSizeListColumns.descColumn] = desc;
         }
+    //Gtk::TreeModel::iterator iter = _paperSizeListStore->children().begin();
+    //if (iter)
+    //    _paperSizeListSelection->select(iter);
+
+
+    pack_start (_paperSizeListBox, false, false, 0);
+    _paperSizeListLabel.set_label(_("P_age size:"));
+    _paperSizeListLabel.set_use_underline();
+    _paperSizeListBox.pack_start (_paperSizeListLabel, false, false, 0);
+    _paperSizeListLabel.set_mnemonic_widget (_paperSizeList);
+    _paperSizeListBox.pack_start (_paperSizeListScroller, true, true, 0);
+
+    //## Set up orientation radio buttons
+    pack_start (_orientationBox, false, false, 0);
+    _orientationLabel.set_label(_("Page orientation:"));
+    _orientationBox.pack_start(_orientationLabel, false, false, 0);
+    _landscapeButton.set_use_underline();
+    _landscapeButton.set_label(_("_Landscape"));
+    _landscapeButton.set_active(true);
+    Gtk::RadioButton::Group group = _landscapeButton.get_group();
+    _orientationBox.pack_end (_landscapeButton, false, false, 5);
+    _portraitButton.set_use_underline();
+    _portraitButton.set_label(_("_Portrait"));
+    _portraitButton.set_active(true);
+    _orientationBox.pack_end (_portraitButton, false, false, 5);
+    _portraitButton.set_group (group);
+    _portraitButton.set_active (true);
 
+    //## Set up custom size frame
+    _customFrame.set_label(_("Custom size"));
+    pack_start (_customFrame, false, false, 0);
+    _customTable.resize(2, 2);
+    _customTable.set_border_width (4);
+    _customTable.set_row_spacings (4);
+    _customTable.set_col_spacings (4);
+    _customTable.attach(_dimensionWidth, 0,1,0,1);
+    _customTable.attach(_dimensionUnits, 1,2,0,1);
+    _customTable.attach(_dimensionHeight, 0,1,1,2);
+    _customTable.attach(_fitPageButton,              1,2,1,2);
+    _customFrame.add(_customTable);
+
+    _fitPageButton.set_use_underline();
+    _fitPageButton.set_label(_("_Fit page to selection"));
+    _tips.set_tip(_fitPageButton, _("Resize the page to fit the current selection, or the entire drawing if there is no selection"));
 }
 
 
 /**
  * Destructor
- */ 
+ */
 PageSizer::~PageSizer()
 {
 }
@@ -210,77 +285,16 @@ PageSizer::~PageSizer()
 
 /**
  * Initialize or reset this widget
- */ 
+ */
 void
-PageSizer::init (Registry& reg)
+PageSizer::init ()
 {
-    Gtk::HBox *hbox_ori = manage (new Gtk::HBox);
-    pack_start (*hbox_ori, false, false, 0);
-    Gtk::Label *label_ori = manage (new Gtk::Label (_("Page orientation:"), 0.0, 0.5)); 
-    hbox_ori->pack_start (*label_ori, false, false, 0);
-    
-    _landscapeButton.set_label(_("_Landscape"));
-       _landscapeButton.set_active(true);
-    Gtk::RadioButton::Group group = _landscapeButton.get_group();
-    hbox_ori->pack_end (_landscapeButton, false, false, 5);
-    _portraitButton.set_label(_("_Portrait"));
-       _portraitButton.set_active(true);
-    hbox_ori->pack_end (_portraitButton, false, false, 5);
-    _portraitButton.set_group (group);
-    _portraitButton.set_active (true);
-    
-    /* Custom paper frame */
-    Gtk::Frame *frame = manage (new Gtk::Frame(_("Custom size")));
-    pack_start (*frame, false, false, 0);
-    Gtk::Table *table = manage (new Gtk::Table (5, 2, false));
-    table->set_border_width (4);
-    table->set_row_spacings (4);
-    table->set_col_spacings (4);
-    
-    Inkscape::UI::Widget::Button* fit_canv =
-            manage(new Inkscape::UI::Widget::Button(_("_Fit page to selection"),
-    _("Resize the page to fit the current selection, or the entire drawing if there is no selection")));
-
-    // prevent fit_canv from expanding
-    Gtk::Alignment *fit_canv_cont = manage(new Gtk::Alignment(1.0,0.5,0.0,0.0));
-    fit_canv_cont->add(*fit_canv);
-
-    frame->add (*table);
-    
-    _widgetRegistry = &reg;
-
-    _dimensionUnits.init (_("U_nits:"), "units",
-                        *_widgetRegistry);
-    _dimensionWidth.init (_("_Width:"), _("Width of paper"), "width",
-                        _dimensionUnits, *_widgetRegistry);
-    _dimensionHeight.init (_("_Height:"), _("Height of paper"), "height",
-                        _dimensionUnits, *_widgetRegistry);
-
-    table->attach (*_dimensionUnits._label, 0,1,0,1, Gtk::FILL|Gtk::EXPAND,
-                   (Gtk::AttachOptions)0,0,0);
-    table->attach (*_dimensionUnits._sel, 1,2,0,1, Gtk::FILL|Gtk::EXPAND,
-                   (Gtk::AttachOptions)0,0,0);
-    table->attach (*_dimensionWidth.getSU(), 0,2,1,2, Gtk::FILL|Gtk::EXPAND,
-                   (Gtk::AttachOptions)0,0,0);
-    table->attach (*_dimensionHeight.getSU(), 0,2,2,3, Gtk::FILL|Gtk::EXPAND,
-                  (Gtk::AttachOptions)0,0,0);
-    table->attach (*fit_canv_cont, 0,2,3,4, Gtk::FILL|Gtk::EXPAND,
-                  (Gtk::AttachOptions)0,0,0);
-
-    _paper_size_list_connection = _paperSizeList.signal_changed().connect (
-               sigc::mem_fun (*this, &PageSizer::on_paper_size_list_changed));
-               
-    _landscape_connection = _landscapeButton.signal_toggled().connect (
-               sigc::mem_fun (*this, &PageSizer::on_landscape));
-    _portrait_connection = _portraitButton.signal_toggled().connect (
-               sigc::mem_fun (*this, &PageSizer::on_portrait));
-    _changedw_connection = _dimensionWidth.getSU()->signal_value_changed().connect (
-               sigc::mem_fun (*this, &PageSizer::on_value_changed));
-    _changedh_connection = _dimensionHeight.getSU()->signal_value_changed().connect (
-               sigc::mem_fun (*this, &PageSizer::on_value_changed));
-    fit_canv->signal_clicked().connect(
-            sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
-    
+    _landscape_connection = _landscapeButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_landscape));
+    _portrait_connection = _portraitButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_portrait));
+    _changedw_connection = _dimensionWidth.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
+    _changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
+    _fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
+
     show_all_children();
 }
 
@@ -289,23 +303,24 @@ PageSizer::init (Registry& reg)
  * Set document dimensions (if not called by Doc prop's update()) and
  * set the PageSizer's widgets and text entries accordingly. If
  * 'chageList' is true, then adjust the paperSizeList to show the closest
- * standard page size.  
+ * standard page size.
  *
  * \param w, h given in px
- * \param changeList whether to modify the paper size list 
+ * \param changeList whether to modify the paper size list
  */
 void
 PageSizer::setDim (double w, double h, bool changeList)
 {
     static bool _called = false;
-    if (_called)
-           return;
+    if (_called) {
+        return;
+    }
 
     _called = true;
-    
+
     _paper_size_list_connection.block();
-       _landscape_connection.block();
-    _portrait_connection.block(); 
+    _landscape_connection.block();
+    _portrait_connection.block();
     _changedw_connection.block();
     _changedh_connection.block();
 
@@ -313,36 +328,40 @@ PageSizer::setDim (double w, double h, bool changeList)
         SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
         sp_document_set_width (doc, w, &_px_unit);
         sp_document_set_height (doc, h, &_px_unit);
-        sp_document_done (doc, SP_VERB_NONE, 
-        /* TODO: annotate */ "page-sizer.cpp:301");
-    } 
-    
+        sp_document_done (doc, SP_VERB_NONE, _("Set page size"));
+    }
+
     _landscape = ( w > h );
     _landscapeButton.set_active(_landscape ? true : false);
     _portraitButton.set_active (_landscape ? false : true);
-    
+
     if (changeList)
-           _paperSizeList.set_active (find_paper_size (w, h));
-    
-    Unit const& unit = _dimensionUnits._sel->getUnit();
+        {
+        Gtk::TreeModel::Row row = (*find_paper_size(w, h));
+        if (row)
+            _paperSizeListSelection->select(row);
+        }
+
+    Unit const& unit = _dimensionUnits.getUnit();
     _dimensionWidth.setValue (w / unit.factor);
     _dimensionHeight.setValue (h / unit.factor);
 
     _paper_size_list_connection.unblock();
-       _landscape_connection.unblock();
+    _landscape_connection.unblock();
     _portrait_connection.unblock();
     _changedw_connection.unblock();
     _changedh_connection.unblock();
-    
+
     _called = false;
 }
 
 
-/** 
- * Returns an index into paperSizeTable of a paper of the specified 
- * size (specified in px), or -1 if there's no such paper.
+/**
+ * Returns an iterator pointing to a row in paperSizeListStore which
+ * contains a paper of the specified size (specified in px), or
+ * paperSizeListStore->children().end() if no such paper exists.
  */
-int
+Gtk::ListStore::iterator
 PageSizer::find_paper_size (double w, double h) const
 {
     double smaller = w;
@@ -351,43 +370,51 @@ PageSizer::find_paper_size (double w, double h) const
         smaller = h; larger = w;
     }
 
-    g_return_val_if_fail(smaller <= larger, -1);
-    
-    int index = 0;
+    g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end());
+
     std::map<Glib::ustring, PaperSize>::const_iterator iter;
-    for (iter = paperSizeTable.begin() ; iter != paperSizeTable.end() ; iter++) {
+    for (iter = _paperSizeTable.begin() ;
+         iter != _paperSizeTable.end() ; iter++) {
         PaperSize paper = iter->second;
         SPUnit const &i_unit = sp_unit_get_by_id(paper.unit);
         double smallX = sp_units_get_pixels(paper.smaller, i_unit);
         double largeX = sp_units_get_pixels(paper.larger,  i_unit);
-        
-        g_return_val_if_fail(smallX <= largeX, -1);
-        
+
+        g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end());
+
         if ((std::abs(smaller - smallX) <= 0.1) &&
-            (std::abs(larger  - largeX) <= 0.1)   )
-            return index;
-            
-        index++;
+            (std::abs(larger  - largeX) <= 0.1)   ) {
+            Gtk::ListStore::iterator p;
+            // We need to search paperSizeListStore explicitly for the
+            // specified paper size because it is sorted in a different
+            // way than paperSizeTable (which is sorted alphabetically)
+            for (p = _paperSizeListStore->children().begin(); p != _paperSizeListStore->children().end(); p++) {
+                if ((*p)[_paperSizeListColumns.nameColumn] == paper.name) {
+                    return p;
+                }
+            }
+        }
     }
-    return -1;
+    return _paperSizeListStore->children().end();
 }
 
 
 
 /**
  * Tell the desktop to change the page size
- */ 
+ */
 void
 PageSizer::fire_fit_canvas_to_selection_or_drawing()
 {
     SPDesktop *dt = SP_ACTIVE_DESKTOP;
-    if (!dt)
-           return;
+    if (!dt) {
+        return;
+    }
     Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING );
     if (verb) {
         SPAction *action = verb->get_action(dt);
         if (action)
-            sp_action_perform(action, NULL);        
+            sp_action_perform(action, NULL);
     }
 }
 
@@ -395,18 +422,26 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing()
 
 /**
  * Paper Size list callback for when a user changes the selection
- */ 
+ */
 void
 PageSizer::on_paper_size_list_changed()
 {
-    Glib::ustring name = _paperSizeList.get_active_text();
-    std::map<Glib::ustring, PaperSize>::const_iterator iter =
-        paperSizeTable.find(name);
-    if (iter == paperSizeTable.end()) {
+    //Glib::ustring name = _paperSizeList.get_active_text();
+    Gtk::TreeModel::iterator miter = _paperSizeListSelection->get_selected();
+    if(!miter)
+        {
+        //error?
+        return;
+        }
+    Gtk::TreeModel::Row row = *miter;
+    Glib::ustring name = row[_paperSizeListColumns.nameColumn];
+    std::map<Glib::ustring, PaperSize>::const_iterator piter =
+                    _paperSizeTable.find(name);
+    if (piter == _paperSizeTable.end()) {
         g_warning("paper size '%s' not found in table", name.c_str());
         return;
     }
-    PaperSize paper = iter->second;
+    PaperSize paper = piter->second;
     double w = paper.smaller;
     double h = paper.larger;
     SPUnit const &src_unit = sp_unit_get_by_id (paper.unit);
@@ -429,37 +464,39 @@ PageSizer::on_portrait()
 {
     if (!_portraitButton.get_active())
         return;
-    double w = _dimensionWidth.getSU()->getValue ("px");
-    double h = _dimensionHeight.getSU()->getValue ("px");
-    if (h < w)
-           setDim (h, w);
+    double w = _dimensionWidth.getValue ("px");
+    double h = _dimensionHeight.getValue ("px");
+    if (h < w) {
+        setDim (h, w);
+    }
 }
 
 
 /**
  * Landscape button callback
- */ 
+ */
 void
 PageSizer::on_landscape()
 {
     if (!_landscapeButton.get_active())
         return;
-    double w = _dimensionWidth.getSU()->getValue ("px");
-    double h = _dimensionHeight.getSU()->getValue ("px");
-    if (w < h)
-           setDim (h, w);
+    double w = _dimensionWidth.getValue ("px");
+    double h = _dimensionHeight.getValue ("px");
+    if (w < h) {
+        setDim (h, w);
+    }
 }
 
 /**
  * Callback for the dimension widgets
- */ 
+ */
 void
 PageSizer::on_value_changed()
 {
     if (_widgetRegistry->isUpdating()) return;
 
-    setDim (_dimensionWidth.getSU()->getValue("px"),
-               _dimensionHeight.getSU()->getValue("px"));
+    setDim (_dimensionWidth.getValue("px"),
+            _dimensionHeight.getValue("px"));
 }