Code

Patch by Alex Leone to add margins to resize page options in Document Properties
authorJosh Andler <scislac@gmail.com>
Fri, 8 Jan 2010 05:43:33 +0000 (21:43 -0800)
committerJosh Andler <scislac@gmail.com>
Fri, 8 Jan 2010 05:43:33 +0000 (21:43 -0800)
src/attributes.cpp
src/attributes.h
src/document.cpp
src/document.h
src/selection-chemistry.cpp
src/selection-chemistry.h
src/ui/dialog/document-properties.cpp
src/ui/widget/page-sizer.cpp
src/ui/widget/page-sizer.h

index d03c3be3e5b785990cab7a57b52acb041e1086c6..f4a2a879a8541d205feca9114778b2f3c7932c29 100644 (file)
@@ -77,6 +77,10 @@ static SPStyleProp const props[] = {
     {SP_ATTR_BORDERCOLOR, "bordercolor"},
     {SP_ATTR_BORDEROPACITY, "borderopacity"},
     {SP_ATTR_PAGECOLOR, "pagecolor"},
+    {SP_ATTR_FIT_MARGIN_TOP, "fit-margin-top"},
+    {SP_ATTR_FIT_MARGIN_LEFT, "fit-margin-left"},
+    {SP_ATTR_FIT_MARGIN_RIGHT, "fit-margin-right"},
+    {SP_ATTR_FIT_MARGIN_BOTTOM, "fit-margin-bottom"},
     {SP_ATTR_INKSCAPE_PAGEOPACITY, "inkscape:pageopacity"},
     {SP_ATTR_INKSCAPE_PAGESHADOW, "inkscape:pageshadow"},
     {SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"},
@@ -98,8 +102,8 @@ static SPStyleProp const props[] = {
     {SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS, "inkscape:snap-midpoints"},
     {SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS, "inkscape:snap-object-midpoints"},
     {SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS, "inkscape:snap-bbox-edge-midpoints"},
-       {SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS, "inkscape:snap-bbox-midpoints"},
-       {SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS, "inkscape:snap-intersection-paths"},
+    {SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS, "inkscape:snap-bbox-midpoints"},
+    {SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS, "inkscape:snap-intersection-paths"},
     {SP_ATTR_INKSCAPE_OBJECT_PATHS, "inkscape:object-paths"},
     {SP_ATTR_INKSCAPE_OBJECT_NODES, "inkscape:object-nodes"},
     {SP_ATTR_INKSCAPE_BBOX_PATHS, "inkscape:bbox-paths"},
index af60b75be4d5782dff445cf7b4722cf6dfd77f1e..e3399bc58602687306712bac0d9198c79856748b 100644 (file)
@@ -77,6 +77,10 @@ enum SPAttributeEnum {
     SP_ATTR_BORDERCOLOR,
     SP_ATTR_BORDEROPACITY,
     SP_ATTR_PAGECOLOR,
+    SP_ATTR_FIT_MARGIN_TOP,
+    SP_ATTR_FIT_MARGIN_LEFT,
+    SP_ATTR_FIT_MARGIN_RIGHT,
+    SP_ATTR_FIT_MARGIN_BOTTOM,
     SP_ATTR_INKSCAPE_PAGEOPACITY,
     SP_ATTR_INKSCAPE_PAGESHADOW,
     SP_ATTR_INKSCAPE_ZOOM,
@@ -98,7 +102,7 @@ enum SPAttributeEnum {
     SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS,
     SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS,
     SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS,
-       SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS,
+    SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS,
     //SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE,
     SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS,
     SP_ATTR_INKSCAPE_OBJECT_PATHS,
index 3104ade288663e40d9b79b41266dceb9ca224419..101c54e30b687d38160ac0d9e2c55d4d0227e93a 100644 (file)
@@ -614,27 +614,102 @@ Geom::Point sp_document_dimensions(SPDocument *doc)
     return Geom::Point(sp_document_width(doc), sp_document_height(doc));
 }
 
+/**
+ * Gets page fitting margin information from the namedview node in the XML.
+ * \param nv_repr reference to this document's namedview
+ * \param key the same key used by the RegisteredScalarUnit in
+ *        ui/widget/page-sizer.cpp
+ * \param margin_units units for the margin
+ * \param return_units units to return the result in
+ * \param width width in px (for percentage margins)
+ * \param height height in px (for percentage margins)
+ * \param use_width true if the this key is left or right margins, false
+ *        otherwise.  Used for percentage margins.
+ * \return the margin size in px, else 0.0 if anything is invalid.
+ */
+static double getMarginLength(Inkscape::XML::Node * const nv_repr,
+                             gchar const * const key,
+                             SPUnit const * const margin_units,
+                             SPUnit const * const return_units,
+                             double const width,
+                             double const height,
+                             bool const use_width)
+{
+    double value;
+    if (!sp_repr_get_double (nv_repr, key, &value)) {
+        return 0.0;
+    }
+    if (margin_units == &sp_unit_get_by_id (SP_UNIT_PERCENT)) {
+        return (use_width)? width * value : height * value; 
+    }
+    if (!sp_convert_distance (&value, margin_units, return_units)) {
+        return 0.0;
+    }
+    return value;
+}
+
 /**
  * Given a Geom::Rect that may, for example, correspond to the bbox of an object,
  * this function fits the canvas to that rect by resizing the canvas
  * and translating the document root into position.
+ * \param rect fit document size to this
+ * \param with_margins add margins to rect, by taking margins from this
+ *        document's namedview (<sodipodi:namedview> "fit-margin-..."
+ *        attributes, and "units")
  */
-void SPDocument::fitToRect(Geom::Rect const &rect)
+void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins)
 {
     double const w = rect.width();
     double const h = rect.height();
 
     double const old_height = sp_document_height(this);
     SPUnit const &px(sp_unit_get_by_id(SP_UNIT_PX));
-    sp_document_set_width(this, w, &px);
-    sp_document_set_height(this, h, &px);
+    
+    /* in px */
+    double margin_top = 0.0;
+    double margin_left = 0.0;
+    double margin_right = 0.0;
+    double margin_bottom = 0.0;
+    
+    SPNamedView *nv = sp_document_namedview(this, 0);
+    
+    if (with_margins && nv) {
+        Inkscape::XML::Node *nv_repr = SP_OBJECT_REPR (nv);
+        if (nv_repr != NULL) {
+            gchar const * const units_abbr = nv_repr->attribute("units");
+            SPUnit const *margin_units = NULL;
+            if (units_abbr != NULL) {
+                margin_units = sp_unit_get_by_abbreviation(units_abbr);
+            }
+            if (margin_units == NULL) {
+                margin_units = &sp_unit_get_by_id(SP_UNIT_PX);
+            }
+            margin_top = getMarginLength(nv_repr, "fit-margin-top",
+                                         margin_units, &px, w, h, false);
+            margin_left = getMarginLength(nv_repr, "fit-margin-left",
+                                          margin_units, &px, w, h, true);
+            margin_right = getMarginLength(nv_repr, "fit-margin-right",
+                                           margin_units, &px, w, h, true);
+            margin_bottom = getMarginLength(nv_repr, "fit-margin-bottom",
+                                            margin_units, &px, w, h, false);
+        }
+    }
+    
+    Geom::Rect const rect_with_margins(
+            rect.min() - Geom::Point(margin_left, margin_bottom),
+            rect.max() + Geom::Point(margin_right, margin_top));
+    
+    
+    sp_document_set_width(this, rect_with_margins.width(), &px);
+    sp_document_set_height(this, rect_with_margins.height(), &px);
 
-    Geom::Translate const tr(Geom::Point(0, (old_height - h))
-                             - to_2geom(rect.min()));
+    Geom::Translate const tr(
+            Geom::Point(0, old_height - rect_with_margins.height())
+            - to_2geom(rect_with_margins.min()));
     SP_GROUP(root)->translateChildItems(tr);
-    SPNamedView *nv = sp_document_namedview(this, 0);
+
     if(nv) {
-        Geom::Translate tr2(-rect.min());
+        Geom::Translate tr2(-rect_with_margins.min());
         nv->translateGuides(tr2);
 
         // update the viewport so the drawing appears to stay where it was
index e83c37a968a2d4584cd020ed5173d70752aa7207..e70582006f92ac3d2327d69ab4a19284923b0c49 100644 (file)
@@ -179,7 +179,7 @@ public:
     sigc::connection _selection_changed_connection;
     sigc::connection _desktop_activated_connection;
 
-    void fitToRect(Geom::Rect const &rect);
+    void fitToRect(Geom::Rect const &rect, bool with_margins = false);
 };
 
 SPDocument *sp_document_new(const gchar *uri, unsigned int keepalive, bool make_new = false);
index 31e899d8a34c703866ae9dbc40c6b51244fdb8dc..d976872676f12645675af4c3bd3dbdbc163e99e4 100644 (file)
@@ -2932,10 +2932,12 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) {
 }
 
 /**
- * Returns true if an undoable change should be recorded.
+ * \param with_margins margins defined in the xml under <sodipodi:namedview>
+ *                     "fit-margin-..." attributes.  See SPDocument::fitToRect.
+ * \return true if an undoable change should be recorded.
  */
 bool
-fit_canvas_to_selection(SPDesktop *desktop)
+fit_canvas_to_selection(SPDesktop *desktop, bool with_margins)
 {
     g_return_val_if_fail(desktop != NULL, false);
     SPDocument *doc = sp_desktop_document(desktop);
@@ -2949,7 +2951,7 @@ fit_canvas_to_selection(SPDesktop *desktop)
     }
     Geom::OptRect const bbox(desktop->selection->bounds());
     if (bbox) {
-        doc->fitToRect(*bbox);
+        doc->fitToRect(*bbox, with_margins);
         return true;
     } else {
         return false;
@@ -2968,8 +2970,12 @@ verb_fit_canvas_to_selection(SPDesktop *const desktop)
     }
 }
 
+/**
+ * \param with_margins margins defined in the xml under <sodipodi:namedview>
+ *                     "fit-margin-..." attributes.  See SPDocument::fitToRect.
+ */
 bool
-fit_canvas_to_drawing(SPDocument *doc)
+fit_canvas_to_drawing(SPDocument *doc, bool with_margins)
 {
     g_return_val_if_fail(doc != NULL, false);
 
@@ -2977,7 +2983,7 @@ fit_canvas_to_drawing(SPDocument *doc)
     SPItem const *const root = SP_ITEM(doc->root);
     Geom::OptRect const bbox(root->getBounds(sp_item_i2d_affine(root)));
     if (bbox) {
-        doc->fitToRect(*bbox);
+        doc->fitToRect(*bbox, with_margins);
         return true;
     } else {
         return false;
@@ -2993,6 +2999,11 @@ verb_fit_canvas_to_drawing(SPDesktop *desktop)
     }
 }
 
+/**
+ * Fits canvas to selection or drawing with margins from <sodipodi:namedview>
+ * "fit-margin-..." attributes.  See SPDocument::fitToRect and
+ * ui/dialog/page-sizer.
+ */
 void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) {
     g_return_if_fail(desktop != NULL);
     SPDocument *doc = sp_desktop_document(desktop);
@@ -3001,8 +3012,8 @@ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) {
     g_return_if_fail(desktop->selection != NULL);
 
     bool const changed = ( desktop->selection->isEmpty()
-                           ? fit_canvas_to_drawing(doc)
-                           : fit_canvas_to_selection(desktop) );
+                           ? fit_canvas_to_drawing(doc, true)
+                           : fit_canvas_to_selection(desktop, true) );
     if (changed) {
         sp_document_done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING,
                          _("Fit Page to Selection or Drawing"));
index 67e772a00999a39043b891b53e538e28d6caead4..7cc5f8d9f55992d824b81ca289e03ad181825537 100644 (file)
@@ -115,9 +115,9 @@ void sp_selection_create_bitmap_copy (SPDesktop *desktop);
 void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_layer);
 void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path);
 
-bool fit_canvas_to_selection(SPDesktop *);
+bool fit_canvas_to_selection(SPDesktop *, bool with_margins = false);
 void verb_fit_canvas_to_selection(SPDesktop *);
-bool fit_canvas_to_drawing(SPDocument *);
+bool fit_canvas_to_drawing(SPDocument *, bool with_margins = false);
 void verb_fit_canvas_to_drawing(SPDesktop *);
 void fit_canvas_to_selection_or_drawing(SPDesktop *);
 
index a7241ea405831e342b06dba912a205cb3382b350..86baa85cd973489a5a8dd8251327114e15c4c97f 100644 (file)
@@ -222,7 +222,7 @@ DocumentProperties::build_page()
     Gtk::Label* label_bor = manage (new Gtk::Label);
     label_bor->set_markup (_("<b>Border</b>"));
     Gtk::Label *label_for = manage (new Gtk::Label);
-    label_for->set_markup (_("<b>Format</b>"));
+    label_for->set_markup (_("<b>Page Size</b>"));
     _page_sizer.init();
 
     Gtk::Widget *const widget_array[] =
index 68f26792a98eaea4de40f0b486fa339e81f53e7b..e604a24ecc387cca3c7c2f952871ead081d8ffc0 100644 (file)
@@ -229,6 +229,11 @@ PageSizer::PageSizer(Registry & _wr)
       _dimensionUnits( _("U_nits:"), "units", _wr ),
       _dimensionWidth( _("_Width:"), _("Width of paper"), "width", _dimensionUnits, _wr ),
       _dimensionHeight( _("_Height:"), _("Height of paper"), "height", _dimensionUnits, _wr ),
+      _marginTop( _("T_op margin:"), _("Top margin"), "fit-margin-top", _wr ),
+      _marginLeft( _("L_eft:"), _("Left margin"), "fit-margin-left", _wr),
+      _marginRight( _("Ri_ght:"), _("Right margin"), "fit-margin-right", _wr),
+      _marginBottom( _("Botto_m:"), _("Bottom margin"), "fit-margin-bottom", _wr),
+      
       _widgetRegistry(&_wr)
 {
     //# Set up the Paper Size combo box
@@ -273,16 +278,11 @@ PageSizer::PageSizer(Registry & _wr)
     //    _paperSizeListSelection->select(iter);
 
 
-    pack_start (_paperSizeListBox, true, true, 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);
+    pack_start (_paperSizeListScroller, true, true, 0);
 
     //## Set up orientation radio buttons
     pack_start (_orientationBox, false, false, 0);
-    _orientationLabel.set_label(_("Page orientation:"));
+    _orientationLabel.set_label(_("Orientation:"));
     _orientationBox.pack_start(_orientationLabel, false, false, 0);
     _landscapeButton.set_use_underline();
     _landscapeButton.set_label(_("_Landscape"));
@@ -299,19 +299,48 @@ PageSizer::PageSizer(Registry & _wr)
     //## 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);
-
+    _customFrame.add(_customDimTable);
+
+    _customDimTable.resize(3, 2);
+    _customDimTable.set_border_width(4);
+    _customDimTable.set_row_spacings(4);
+    _customDimTable.set_col_spacings(4);
+    _customDimTable.attach(_dimensionWidth,        0,1, 0,1);
+    _customDimTable.attach(_dimensionUnits,        1,2, 0,1);
+    _customDimTable.attach(_dimensionHeight,       0,1, 1,2);
+    _customDimTable.attach(_fitPageMarginExpander, 0,2, 2,3);
+    
+    //## Set up fit page expander
+    _fitPageMarginExpander.set_label(_("Resi_ze page to content..."));
+    _fitPageMarginExpander.set_use_underline();
+    _fitPageMarginExpander.add(_marginTable);
+    
+    //## Set up margin settings
+    _marginTable.resize(4, 2);
+    _marginTable.set_border_width(4);
+    _marginTable.set_row_spacings(4);
+    _marginTable.set_col_spacings(4);
+    _marginTable.attach(_fitPageButtonAlign, 0,2, 0,1);
+    _marginTable.attach(_marginTopAlign,     0,2, 1,2);
+    _marginTable.attach(_marginLeftAlign,    0,1, 2,3);
+    _marginTable.attach(_marginRightAlign,   1,2, 2,3);
+    _marginTable.attach(_marginBottomAlign,  0,2, 3,4);
+    
+    _marginTopAlign.set(0.5, 0.5, 0.0, 1.0);
+    _marginTopAlign.add(_marginTop);
+    _marginLeftAlign.set(0.0, 0.5, 0.0, 1.0);
+    _marginLeftAlign.add(_marginLeft);
+    _marginRightAlign.set(1.0, 0.5, 0.0, 1.0);
+    _marginRightAlign.add(_marginRight);
+    _marginBottomAlign.set(0.5, 0.5, 0.0, 1.0);
+    _marginBottomAlign.add(_marginBottom);
+    
+    _fitPageButtonAlign.set(0.5, 0.5, 0.0, 1.0);
+    _fitPageButtonAlign.add(_fitPageButton);
     _fitPageButton.set_use_underline();
-    _fitPageButton.set_label(_("_Fit page to selection"));
+    _fitPageButton.set_label(_("_Resize page to drawing or selection"));
     _tips.set_tip(_fitPageButton, _("Resize the page to fit the current selection, or the entire drawing if there is no selection"));
+
 }
 
 
@@ -343,7 +372,7 @@ PageSizer::init ()
 /**
  * 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
+ * 'changeList' is true, then adjust the paperSizeList to show the closest
  * standard page size.
  *
  * \param w, h given in px
@@ -454,7 +483,7 @@ PageSizer::find_paper_size (double w, double h) const
 
 
 /**
- * Tell the desktop to change the page size
+ * Tell the desktop to fit the page size to the selection or drawing.
  */
 void
 PageSizer::fire_fit_canvas_to_selection_or_drawing()
index f970afe44cf55fa1f4614ceb6475dfbabf030c0e..718eb95b592449898c134643514f0a50fcd32034 100644 (file)
@@ -183,24 +183,38 @@ protected:
     Gtk::HBox           _orientationBox;
     Gtk::Label          _orientationLabel;
     Gtk::RadioButton    _portraitButton;
-       Gtk::RadioButton    _landscapeButton;
+    Gtk::RadioButton    _landscapeButton;
     //callbacks
     void on_portrait();
     void on_landscape();
     sigc::connection    _portrait_connection;
-       sigc::connection    _landscape_connection;
+    sigc::connection    _landscape_connection;
 
     //### Custom size frame
     Gtk::Frame           _customFrame;
-    Gtk::Table           _customTable;
+    Gtk::Table           _customDimTable;
     RegisteredUnitMenu   _dimensionUnits;
     RegisteredScalarUnit _dimensionWidth;
-       RegisteredScalarUnit _dimensionHeight;
-       Gtk::Button          _fitPageButton;
+    RegisteredScalarUnit _dimensionHeight;
+
+    //### Fit Page options
+    Gtk::Expander        _fitPageMarginExpander;
+    Gtk::Table           _marginTable;
+    Gtk::Alignment       _marginTopAlign;
+    Gtk::Alignment       _marginLeftAlign;
+    Gtk::Alignment       _marginRightAlign;
+    Gtk::Alignment       _marginBottomAlign;
+    RegisteredScalar     _marginTop;
+    RegisteredScalar     _marginLeft;
+    RegisteredScalar     _marginRight;
+    RegisteredScalar     _marginBottom;
+    Gtk::Alignment       _fitPageButtonAlign;
+    Gtk::Button          _fitPageButton;
+
     //callback
     void on_value_changed();
     sigc::connection    _changedw_connection;
-       sigc::connection    _changedh_connection;
+    sigc::connection    _changedh_connection;
 
     Registry            *_widgetRegistry;