Code

RegisteredScalar subclassed from RegisteredWidget<Scalar> instead of old RegisteredWdg
[inkscape.git] / src / ui / widget / page-sizer.cpp
index bf16effb6ec2e0a3caf9c11ff2218f811a203857..7b0fea5f558fd8b91d0397b444762ec8c24a8841 100644 (file)
@@ -7,6 +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> 
  *
  * Copyright (C) 2000 - 2006 Authors
  *
@@ -17,6 +18,8 @@
 # include <config.h>
 #endif
 
+#include <string.h>
+
 #include <cmath>
 #include <gtkmm.h>
 #include "ui/widget/button.h"
@@ -78,81 +81,95 @@ namespace Widget {
      */
 
 struct PaperSizeRec {
-    char const * const name;
-    double const smaller;
-    double const larger;
-    SPUnitId const unit;
+    char const * const name;  //name
+    double const smaller;     //lesser dimension
+    double const larger;      //greater dimension
+    SPUnitId const unit;      //units
 };
 
 static PaperSizeRec const inkscape_papers[] = {
-    { "A4", 210, 297, SP_UNIT_MM },
-    { "US Letter", 8.5, 11, SP_UNIT_IN },
-    { "US Legal", 8.5, 14, SP_UNIT_IN },
-    { "US Executive", 7.25, 10.5, SP_UNIT_IN },
-    { "A0", 841, 1189, SP_UNIT_MM },
-    { "A1", 594, 841, SP_UNIT_MM },
-    { "A2", 420, 594, SP_UNIT_MM },
-    { "A3", 297, 420, SP_UNIT_MM },
-    { "A5", 148, 210, SP_UNIT_MM },
-    { "A6", 105, 148, SP_UNIT_MM },
-    { "A7", 74, 105, SP_UNIT_MM },
-    { "A8", 52, 74, SP_UNIT_MM },
-    { "A9", 37, 52, SP_UNIT_MM },
-    { "A10", 26, 37, SP_UNIT_MM },
-    { "B0", 1000, 1414, SP_UNIT_MM },
-    { "B1", 707, 1000, SP_UNIT_MM },
-    { "B2", 500, 707, SP_UNIT_MM },
-    { "B3", 353, 500, SP_UNIT_MM },
-    { "B4", 250, 353, SP_UNIT_MM },
-    { "B5", 176, 250, SP_UNIT_MM },
-    { "B6", 125, 176, SP_UNIT_MM },
-    { "B7", 88, 125, SP_UNIT_MM },
-    { "B8", 62, 88, SP_UNIT_MM },
-    { "B9", 44, 62, SP_UNIT_MM },
-    { "B10", 31, 44, SP_UNIT_MM },
-
-#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. */
-    { "C0", 917, 1297, SP_UNIT_MM },
-    { "C1", 648, 917, SP_UNIT_MM },
-    { "C2", 458, 648, SP_UNIT_MM },
-    { "C3", 324, 458, SP_UNIT_MM },
-    { "C4", 229, 324, SP_UNIT_MM },
-    { "C5", 162, 229, SP_UNIT_MM },
-    { "C6", 114, 162, SP_UNIT_MM },
-    { "C7", 81, 114, SP_UNIT_MM },
-    { "C8", 57, 81, SP_UNIT_MM },
-    { "C9", 40, 57, SP_UNIT_MM },
-    { "C10", 28, 40, SP_UNIT_MM },
-    { "D1", 545, 771, SP_UNIT_MM },
-    { "D2", 385, 545, SP_UNIT_MM },
-    { "D3", 272, 385, SP_UNIT_MM },
-    { "D4", 192, 272, SP_UNIT_MM },
-    { "D5", 136, 192, SP_UNIT_MM },
-    { "D6", 96, 136, SP_UNIT_MM },
-    { "D7", 68, 96, SP_UNIT_MM },
-    { "E3", 400, 560, SP_UNIT_MM },
-    { "E4", 280, 400, SP_UNIT_MM },
-    { "E5", 200, 280, SP_UNIT_MM },
-    { "E6", 140, 200, SP_UNIT_MM },
-#endif
-
-    { "CSE", 462, 649, SP_UNIT_PT },
-    { "US #10 Envelope", 4.125, 9.5, SP_UNIT_IN }, // TODO: Select landscape by default.
+    { "A4",                210,  297, SP_UNIT_MM },
+    { "US Letter",         8.5,   11, SP_UNIT_IN },
+    { "US Legal",          8.5,   14, SP_UNIT_IN },
+    { "US Executive",     7.25, 10.5, SP_UNIT_IN },
+    { "A0",                841, 1189, SP_UNIT_MM },
+    { "A1",                594,  841, SP_UNIT_MM },
+    { "A2",                420,  594, SP_UNIT_MM },
+    { "A3",                297,  420, SP_UNIT_MM },
+    { "A5",                148,  210, SP_UNIT_MM },
+    { "A6",                105,  148, SP_UNIT_MM },
+    { "A7",                 74,  105, SP_UNIT_MM },
+    { "A8",                 52,   74, SP_UNIT_MM },
+    { "A9",                 37,   52, SP_UNIT_MM },
+    { "A10",                26,   37, SP_UNIT_MM },
+    { "B0",               1000, 1414, SP_UNIT_MM },
+    { "B1",                707, 1000, SP_UNIT_MM },
+    { "B2",                500,  707, SP_UNIT_MM },
+    { "B3",                353,  500, SP_UNIT_MM },
+    { "B4",                250,  353, SP_UNIT_MM },
+    { "B5",                176,  250, SP_UNIT_MM },
+    { "B6",                125,  176, SP_UNIT_MM },
+    { "B7",                 88,  125, SP_UNIT_MM },
+    { "B8",                 62,   88, SP_UNIT_MM },
+    { "B9",                 44,   62, SP_UNIT_MM },
+    { "B10",                31,   44, SP_UNIT_MM },
+
+
+
+//#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.
+                */
+
+    { "C0",                917, 1297, SP_UNIT_MM },
+    { "C1",                648,  917, SP_UNIT_MM },
+    { "C2",                458,  648, SP_UNIT_MM },
+    { "C3",                324,  458, SP_UNIT_MM },
+    { "C4",                229,  324, SP_UNIT_MM },
+    { "C5",                162,  229, SP_UNIT_MM },
+    { "C6",                114,  162, SP_UNIT_MM },
+    { "C7",                 81,  114, SP_UNIT_MM },
+    { "C8",                 57,   81, SP_UNIT_MM },
+    { "C9",                 40,   57, SP_UNIT_MM },
+    { "C10",                28,   40, SP_UNIT_MM },
+    { "D1",                545,  771, SP_UNIT_MM },
+    { "D2",                385,  545, SP_UNIT_MM },
+    { "D3",                272,  385, SP_UNIT_MM },
+    { "D4",                192,  272, SP_UNIT_MM },
+    { "D5",                136,  192, SP_UNIT_MM },
+    { "D6",                 96,  136, SP_UNIT_MM },
+    { "D7",                 68,   96, SP_UNIT_MM },
+    { "E3",                400,  560, SP_UNIT_MM },
+    { "E4",                280,  400, SP_UNIT_MM },
+    { "E5",                200,  280, SP_UNIT_MM },
+    { "E6",                140,  200, SP_UNIT_MM },
+//#endif
+
+
+
+    { "CSE",               462,  649, SP_UNIT_PT },
+    { "US #10 Envelope", 4.125,  9.5, SP_UNIT_IN },
+        // 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.
-    { "Ledger/Tabloid", 11, 17, SP_UNIT_IN },
+    { "DL Envelope",       110,  220, SP_UNIT_MM },
+        // 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
        either 8, 8.25 or 8.5 inches, and the height to be either 13 or 13.5 inches, even
        restricting our interpretation to foolscap folio.  If you wish to introduce a folio-like
        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.
-    { "Icon 16x16", 16, 16, SP_UNIT_PX },
-    { "Icon 32x32", 32, 32, SP_UNIT_PX },
-    { NULL, 0, 0, SP_UNIT_PX },
+    { "Banner 468x60",      60,  468, SP_UNIT_PX },
+         // 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 },
+    { NULL,                  0,    0, SP_UNIT_PX },
 };
 
 
@@ -170,23 +187,86 @@ static const SPUnit _px_unit = sp_unit_get_by_id (SP_UNIT_PX);
  */ 
 PageSizer::PageSizer() : Gtk::VBox(false,4)
 {
-    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
-    
+
+
+    //# 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);
+    _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"));
+
+
 
 }
 
@@ -206,38 +286,13 @@ PageSizer::~PageSizer()
 void
 PageSizer::init (Registry& reg)
 {
-    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);
+    /*
+    Note that the registered widgets can only be placed onto a
+    container after they have been init()-ed.  That is why some
+    of the widget creation is in the constructor, and the rest is
+    here.
+    */
     
     _widgetRegistry = &reg;
 
@@ -248,20 +303,11 @@ PageSizer::init (Registry& reg)
     _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));
-               
+    _customTable.attach(*(_dimensionWidth.getSU()),  0,1,0,1);
+    _customTable.attach(*(_dimensionUnits._sel),     1,2,0,1);
+    _customTable.attach(*(_dimensionHeight.getSU()), 0,1,1,2);
+    _customTable.attach(_fitPageButton,              1,2,1,2);
+
     _landscape_connection = _landscapeButton.signal_toggled().connect (
                sigc::mem_fun (*this, &PageSizer::on_landscape));
     _portrait_connection = _portraitButton.signal_toggled().connect (
@@ -270,10 +316,11 @@ PageSizer::init (Registry& reg)
                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(
+    _fitPageButton.signal_clicked().connect(
             sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
     
     show_all_children();
+
 }
 
 
@@ -305,8 +352,7 @@ 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 );
@@ -314,7 +360,11 @@ PageSizer::setDim (double w, double h, bool changeList)
     _portraitButton.set_active (_landscape ? false : true);
     
     if (changeList)
-           _paperSizeList.set_active (find_paper_size (w, h));
+        {
+        Gtk::TreeModel::Row row = (*find_paper_size(w, h));
+        if (row)
+            _paperSizeListSelection->select(row);
+        }
     
     Unit const& unit = _dimensionUnits._sel->getUnit();
     _dimensionWidth.setValue (w / unit.factor);
@@ -331,10 +381,11 @@ PageSizer::setDim (double w, double h, bool changeList)
 
 
 /** 
- * 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;
@@ -343,25 +394,32 @@ PageSizer::find_paper_size (double w, double h) const
         smaller = h; larger = w;
     }
 
-    g_return_val_if_fail(smaller <= larger, -1);
+    g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end());
     
-    int index = 0;
     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();
 }
 
 
@@ -391,14 +449,22 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing()
 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);