summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2017-05-05 16:52:19 +0000
committerjabiertxof <info@marker.es>2017-05-05 16:52:19 +0000
commitbec0359a0d5b3f7db96417f003927c282c18a9f4 (patch)
treee45fa17927826da138e233499060e3142de86899 /src
parentUpdate to trunk (diff)
parentmerge lpeUpdDefaultParams (diff)
downloadinkscape-bec0359a0d5b3f7db96417f003927c282c18a9f4.tar.gz
inkscape-bec0359a0d5b3f7db96417f003927c282c18a9f4.zip
Update to trunk
(bzr r13645.1.174)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/sbasis-to-bezier.cpp41
-rw-r--r--src/attributes.cpp1
-rw-r--r--src/attributes.h1
-rw-r--r--src/desktop-events.cpp4
-rw-r--r--src/desktop.cpp75
-rw-r--r--src/desktop.h36
-rw-r--r--src/display/CMakeLists.txt4
-rw-r--r--src/display/canvas-debug.cpp100
-rw-r--r--src/display/canvas-debug.h41
-rw-r--r--src/display/canvas-grid.cpp254
-rw-r--r--src/display/canvas-grid.h2
-rw-r--r--src/display/canvas-rotate.cpp288
-rw-r--r--src/display/canvas-rotate.h50
-rw-r--r--src/display/canvas-temporary-item-list.h1
-rw-r--r--src/display/gnome-canvas-acetate.cpp8
-rw-r--r--src/display/sodipodi-ctrlrect.cpp262
-rw-r--r--src/display/sodipodi-ctrlrect.h11
-rw-r--r--src/display/sp-canvas.cpp308
-rw-r--r--src/display/sp-canvas.h11
-rw-r--r--src/document-undo.cpp4
-rw-r--r--src/extension/extension.cpp8
-rw-r--r--src/extension/internal/bluredge.cpp4
-rw-r--r--src/extension/internal/cairo-png-out.cpp4
-rw-r--r--src/extension/internal/cairo-ps-out.cpp7
-rw-r--r--src/extension/internal/cairo-renderer-pdf-out.cpp4
-rw-r--r--src/extension/internal/cdr-input.cpp13
-rw-r--r--src/extension/internal/emf-inout.cpp21
-rw-r--r--src/extension/internal/emf-print.cpp4
-rw-r--r--src/extension/internal/javafx-out.cpp9
-rw-r--r--src/extension/internal/latex-pstricks-out.cpp2
-rw-r--r--src/extension/internal/metafile-print.cpp27
-rw-r--r--src/extension/internal/odf.cpp9
-rw-r--r--src/extension/internal/pov-out.cpp13
-rw-r--r--src/extension/internal/vsd-input.cpp15
-rw-r--r--src/extension/internal/wmf-inout.cpp23
-rw-r--r--src/extension/param/bool.cpp15
-rw-r--r--src/extension/param/bool.h8
-rw-r--r--src/extension/param/color.cpp12
-rw-r--r--src/extension/param/color.h8
-rw-r--r--src/extension/param/description.cpp74
-rw-r--r--src/extension/param/description.h11
-rw-r--r--src/extension/param/enum.cpp48
-rw-r--r--src/extension/param/enum.h12
-rw-r--r--src/extension/param/float.cpp17
-rw-r--r--src/extension/param/float.h8
-rw-r--r--src/extension/param/int.cpp18
-rw-r--r--src/extension/param/int.h8
-rw-r--r--src/extension/param/notebook.cpp87
-rw-r--r--src/extension/param/notebook.h8
-rw-r--r--src/extension/param/parameter.cpp128
-rw-r--r--src/extension/param/parameter.h42
-rw-r--r--src/extension/param/radiobutton.cpp40
-rw-r--r--src/extension/param/radiobutton.h8
-rw-r--r--src/extension/param/string.cpp14
-rw-r--r--src/extension/param/string.h8
-rw-r--r--src/extension/prefdialog.cpp2
-rw-r--r--src/file.cpp6
-rw-r--r--src/helper/geom-pathvectorsatellites.cpp2
-rw-r--r--src/io/sys.cpp76
-rw-r--r--src/livarot/PathOutline.cpp6
-rw-r--r--src/live_effects/effect.cpp255
-rw-r--r--src/live_effects/effect.h14
-rw-r--r--src/live_effects/lpe-bendpath.cpp8
-rw-r--r--src/live_effects/lpe-bounding-box.cpp4
-rw-r--r--src/live_effects/lpe-bspline.cpp10
-rw-r--r--src/live_effects/lpe-clone-original.cpp40
-rw-r--r--src/live_effects/lpe-clone-original.h3
-rw-r--r--src/live_effects/lpe-constructgrid.cpp4
-rw-r--r--src/live_effects/lpe-copy_rotate.cpp277
-rw-r--r--src/live_effects/lpe-copy_rotate.h19
-rw-r--r--src/live_effects/lpe-curvestitch.cpp16
-rw-r--r--src/live_effects/lpe-dynastroke.cpp22
-rw-r--r--src/live_effects/lpe-envelope.cpp12
-rw-r--r--src/live_effects/lpe-extrude.cpp2
-rw-r--r--src/live_effects/lpe-fill-between-many.cpp10
-rw-r--r--src/live_effects/lpe-fill-between-strokes.cpp14
-rw-r--r--src/live_effects/lpe-fillet-chamfer.cpp8
-rw-r--r--src/live_effects/lpe-interpolate.cpp6
-rw-r--r--src/live_effects/lpe-knot.cpp12
-rw-r--r--src/live_effects/lpe-lattice.cpp32
-rw-r--r--src/live_effects/lpe-line_segment.cpp2
-rw-r--r--src/live_effects/lpe-measure-line.cpp153
-rw-r--r--src/live_effects/lpe-measure-line.h1
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp39
-rw-r--r--src/live_effects/lpe-offset.cpp4
-rw-r--r--src/live_effects/lpe-parallel.cpp6
-rw-r--r--src/live_effects/lpe-path_length.cpp8
-rw-r--r--src/live_effects/lpe-patternalongpath.cpp20
-rw-r--r--src/live_effects/lpe-perp_bisector.cpp4
-rw-r--r--src/live_effects/lpe-perspective-envelope.cpp32
-rw-r--r--src/live_effects/lpe-perspective_path.cpp10
-rw-r--r--src/live_effects/lpe-powerstroke.cpp16
-rw-r--r--src/live_effects/lpe-recursiveskeleton.cpp2
-rw-r--r--src/live_effects/lpe-rough-hatches.cpp40
-rw-r--r--src/live_effects/lpe-ruler.cpp18
-rw-r--r--src/live_effects/lpe-skeleton.cpp2
-rw-r--r--src/live_effects/lpe-sketch.cpp34
-rw-r--r--src/live_effects/lpe-tangent_to_curve.cpp8
-rw-r--r--src/live_effects/lpe-test-doEffect-stack.cpp8
-rw-r--r--src/live_effects/lpe-text_label.cpp2
-rw-r--r--src/live_effects/lpe-transform_2pts.cpp18
-rw-r--r--src/live_effects/lpe-vonkoch.cpp18
-rw-r--r--src/live_effects/parameter/array.h2
-rw-r--r--src/live_effects/parameter/bool.cpp7
-rw-r--r--src/live_effects/parameter/bool.h2
-rw-r--r--src/live_effects/parameter/enum.h11
-rw-r--r--src/live_effects/parameter/fontbutton.cpp9
-rw-r--r--src/live_effects/parameter/fontbutton.h6
-rw-r--r--src/live_effects/parameter/item.cpp4
-rw-r--r--src/live_effects/parameter/item.h1
-rw-r--r--src/live_effects/parameter/originalpatharray.h3
-rw-r--r--src/live_effects/parameter/parameter.cpp16
-rw-r--r--src/live_effects/parameter/parameter.h6
-rw-r--r--src/live_effects/parameter/path.cpp4
-rw-r--r--src/live_effects/parameter/path.h1
-rw-r--r--src/live_effects/parameter/point.cpp36
-rw-r--r--src/live_effects/parameter/point.h6
-rw-r--r--src/live_effects/parameter/powerstrokepointarray.h2
-rw-r--r--src/live_effects/parameter/random.cpp14
-rw-r--r--src/live_effects/parameter/random.h4
-rw-r--r--src/live_effects/parameter/text.cpp6
-rw-r--r--src/live_effects/parameter/text.h6
-rw-r--r--src/live_effects/parameter/togglebutton.cpp18
-rw-r--r--src/live_effects/parameter/togglebutton.h2
-rw-r--r--src/live_effects/parameter/transformedpoint.cpp19
-rw-r--r--src/live_effects/parameter/transformedpoint.h4
-rw-r--r--src/live_effects/parameter/unit.cpp5
-rw-r--r--src/live_effects/parameter/unit.h5
-rw-r--r--src/live_effects/parameter/vector.cpp19
-rw-r--r--src/live_effects/parameter/vector.h3
-rw-r--r--src/main.cpp31
-rw-r--r--src/preferences.cpp29
-rw-r--r--src/print.cpp2
-rw-r--r--src/sp-lpe-item.cpp2
-rw-r--r--src/sp-namedview.cpp98
-rw-r--r--src/sp-namedview.h11
-rw-r--r--src/splivarot.cpp18
-rw-r--r--src/text-editing.cpp6
-rw-r--r--src/ui/CMakeLists.txt1
-rw-r--r--src/ui/clipboard.cpp2
-rw-r--r--src/ui/dialog/export.cpp9
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp7
-rw-r--r--src/ui/dialog/inkscape-preferences.h2
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp62
-rw-r--r--src/ui/dialog/livepatheffect-editor.h5
-rw-r--r--src/ui/dialog/symbols.cpp58
-rw-r--r--src/ui/event-debug.h132
-rw-r--r--src/ui/object-edit.cpp70
-rw-r--r--src/ui/tools/calligraphic-tool.cpp3
-rw-r--r--src/ui/tools/freehand-base.cpp8
-rw-r--r--src/ui/tools/node-tool.cpp3
-rw-r--r--src/ui/tools/tool-base.cpp953
-rw-r--r--src/ui/tools/zoom-tool.cpp20
-rw-r--r--src/ui/view/edit-widget-interface.h3
-rw-r--r--src/ui/widget/color-scales.cpp1
-rw-r--r--src/ui/widget/rotateable.cpp1
-rw-r--r--src/ui/widget/selected-style.cpp10
-rw-r--r--src/ui/widget/selected-style.h3
-rw-r--r--src/verbs.cpp131
-rw-r--r--src/verbs.h35
-rw-r--r--src/viewbox.cpp62
-rw-r--r--src/viewbox.h7
-rw-r--r--src/widgets/desktop-widget.cpp338
-rw-r--r--src/widgets/desktop-widget.h5
-rw-r--r--src/xml/repr-io.cpp7
165 files changed, 3201 insertions, 2699 deletions
diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp
index 64c07f35e..583fe9ba2 100644
--- a/src/2geom/sbasis-to-bezier.cpp
+++ b/src/2geom/sbasis-to-bezier.cpp
@@ -188,7 +188,8 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
double xprime[2], yprime[2];
double midx = 0;
double midy = 0;
- double numer;
+ double midx_0, midy_0;
+ double numer[2], numer_0[2];
double denom;
double div;
@@ -239,21 +240,23 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
midx = 8*midx - 4*bz[0][X] - 4*bz[3][X]; // re-define relative to center
midy = 8*midy - 4*bz[0][Y] - 4*bz[3][Y];
+ midx_0 = sb[X][1][0] + sb[X][1][1]; // zeroth order estimate
+ midy_0 = sb[Y][1][0] + sb[Y][1][1];
if ((std::abs(xprime[0]) < EPSILON) && (std::abs(yprime[0]) < EPSILON)
&& ((std::abs(xprime[1]) > EPSILON) || (std::abs(yprime[1]) > EPSILON))) { // degenerate handle at 0 : use distance of closest approach
- numer = midx*xprime[1] + midy*yprime[1];
+ numer[0] = midx*xprime[1] + midy*yprime[1];
denom = 3.0*(xprime[1]*xprime[1] + yprime[1]*yprime[1]);
delx[0] = 0;
dely[0] = 0;
- delx[1] = -xprime[1]*numer/denom;
- dely[1] = -yprime[1]*numer/denom;
+ delx[1] = -xprime[1]*numer[0]/denom;
+ dely[1] = -yprime[1]*numer[0]/denom;
} else if ((std::abs(xprime[1]) < EPSILON) && (std::abs(yprime[1]) < EPSILON)
&& ((std::abs(xprime[0]) > EPSILON) || (std::abs(yprime[0]) > EPSILON))) { // degenerate handle at 1 : ditto
- numer = midx*xprime[0] + midy*yprime[0];
+ numer[1] = midx*xprime[0] + midy*yprime[0];
denom = 3.0*(xprime[0]*xprime[0] + yprime[0]*yprime[0]);
- delx[0] = xprime[0]*numer/denom;
- dely[0] = yprime[0]*numer/denom;
+ delx[0] = xprime[0]*numer[1]/denom;
+ dely[0] = yprime[0]*numer[1]/denom;
delx[1] = 0;
dely[1] = 0;
} else if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > // general case : fit mid fxn value
@@ -264,15 +267,21 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
return;
denom = 3.0*(xprime[1]*yprime[0] - yprime[1]*xprime[0]);
for (int i = 0; i < 2; ++i) {
- numer = xprime[1 - i]*midy - yprime[1 - i]*midx;
- delx[i] = xprime[i]*numer/denom;
- dely[i] = yprime[i]*numer/denom;
+ numer_0[i] = xprime[1 - i]*midy_0 - yprime[1 - i]*midx_0;
+ numer[i] = xprime[1 - i]*midy - yprime[1 - i]*midx;
+ delx[i] = xprime[i]*numer[i]/denom;
+ dely[i] = yprime[i]*numer[i]/denom;
+ if (numer_0[i]*numer[i] < 0) // check for reversal of direction, LP Bug 1544680
+ return;
}
+ if (std::abs((numer[0] - numer_0[0])*numer_0[1]) > 10.0*std::abs((numer[1] - numer_0[1])*numer_0[0]) // check for asymmetry
+ || std::abs((numer[1] - numer_0[1])*numer_0[0]) > 10.0*std::abs((numer[0] - numer_0[0])*numer_0[1]))
+ return;
} else if ((xprime[0]*xprime[1] < 0) || (yprime[0]*yprime[1] < 0)) { // symmetric case : use distance of closest approach
- numer = midx*xprime[0] + midy*yprime[0];
+ numer[0] = midx*xprime[0] + midy*yprime[0];
denom = 6.0*(xprime[0]*xprime[0] + yprime[0]*yprime[0]);
- delx[0] = xprime[0]*numer/denom;
- dely[0] = yprime[0]*numer/denom;
+ delx[0] = xprime[0]*numer[0]/denom;
+ dely[0] = yprime[0]*numer[0]/denom;
delx[1] = -delx[0];
dely[1] = -dely[0];
} else { // anti-symmetric case : fit mid slope
@@ -291,10 +300,10 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
}
if (midx*yprime[0] != midy*xprime[0]) {
denom = midx*yprime[0] - midy*xprime[0];
- numer = midx*(bz[3][Y] - bz[0][Y]) - midy*(bz[3][X] - bz[0][X]);
+ numer[0] = midx*(bz[3][Y] - bz[0][Y]) - midy*(bz[3][X] - bz[0][X]);
for (int i = 0; i < 2; ++i) {
- delx[i] = xprime[0]*numer/denom;
- dely[i] = yprime[0]*numer/denom;
+ delx[i] = xprime[0]*numer[0]/denom;
+ dely[i] = yprime[0]*numer[0]/denom;
}
} else { // linear case
for (int i = 0; i < 2; ++i) {
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 5b3d35590..c375ba903 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -89,7 +89,6 @@ static SPStyleProp const props[] = {
{SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"},
{SP_ATTR_INKSCAPE_CX, "inkscape:cx"},
{SP_ATTR_INKSCAPE_CY, "inkscape:cy"},
- {SP_ATTR_INKSCAPE_DOCUMENT_ROTATION, "inkscape:document-rotation"},
{SP_ATTR_INKSCAPE_WINDOW_WIDTH, "inkscape:window-width"},
{SP_ATTR_INKSCAPE_WINDOW_HEIGHT, "inkscape:window-height"},
{SP_ATTR_INKSCAPE_WINDOW_X, "inkscape:window-x"},
diff --git a/src/attributes.h b/src/attributes.h
index 6d4ac7543..c4658b85b 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -97,7 +97,6 @@ enum SPAttributeEnum {
SP_ATTR_INKSCAPE_ZOOM,
SP_ATTR_INKSCAPE_CX,
SP_ATTR_INKSCAPE_CY,
- SP_ATTR_INKSCAPE_DOCUMENT_ROTATION,
SP_ATTR_INKSCAPE_WINDOW_WIDTH,
SP_ATTR_INKSCAPE_WINDOW_HEIGHT,
SP_ATTR_INKSCAPE_WINDOW_X,
diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp
index 9e5f1c20b..5fef8cbfc 100644
--- a/src/desktop-events.cpp
+++ b/src/desktop-events.cpp
@@ -155,10 +155,6 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge
}
}
- SPNamedView *namedview = desktop->namedview;
- //if (namedview && namedview->document_rotation) {
- // normal *= Geom::Rotate(Geom::rad_from_deg(namedview->document_rotation * -1));
- //}
guide = sp_guideline_new(desktop->guides, NULL, event_dt, normal);
sp_guideline_set_color(SP_GUIDELINE(guide), desktop->namedview->guidehicolor);
diff --git a/src/desktop.cpp b/src/desktop.cpp
index c46d6e2f6..c56c42267 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -40,7 +40,9 @@
#include "desktop-style.h"
#include "device-manager.h"
#include "display/canvas-arena.h"
+#include "display/canvas-debug.h"
#include "display/canvas-grid.h"
+#include "display/canvas-rotate.h"
#include "display/canvas-temporary-item-list.h"
#include "display/drawing-group.h"
#include "display/gnome-canvas-acetate.h"
@@ -129,7 +131,6 @@ SPDesktop::SPDesktop() :
layers->_layer_deactivated_signal.connect(sigc::bind(sigc::ptr_fun(_layer_deactivated), this));
layers->_layer_changed_signal.connect(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this));
selection = Inkscape::GC::release( new Inkscape::Selection(layers, this) );
- // _current_affine.setRotate(M_PI/4); // To test zooming with rotation
}
void
@@ -221,10 +222,10 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
// being selected? or does it intercept some of the events that should have gone to the
// node handler? see bug https://bugs.launchpad.net/inkscape/+bug/414142)
gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
- guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
- sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
tempgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
- controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+ controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
// Set the select tool as the active tool.
set_event_context2("/tools/select");
@@ -252,7 +253,8 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
_doc2dt[5] = document->getHeight().value("px");
sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
- _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
+ _modified_connection =
+ namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
Inkscape::DrawingItem *ai = document->getRoot()->invoke_show(
SP_CANVAS_ARENA (drawing)->drawing,
@@ -314,6 +316,10 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid
temporary_item_list = new Inkscape::Display::TemporaryItemList( this );
snapindicator = new Inkscape::Display::SnapIndicator ( this );
+
+ canvas_rotate = sp_canvas_item_new (root, SP_TYPE_CANVAS_ROTATE, NULL);
+ sp_canvas_item_hide( canvas_rotate );
+ // canvas_debug = sp_canvas_item_new (main, SP_TYPE_CANVAS_DEBUG, NULL);
}
@@ -838,6 +844,7 @@ SPDesktop::set_display_area (bool log)
_widget->updateRulers();
_widget->updateScrollbars(_current_affine.getZoom());
_widget->updateZoom();
+ _widget->updateRotation();
signal_zoom_changed.emit(_current_affine.getZoom());
}
@@ -1128,6 +1135,48 @@ SPDesktop::rotate_relative_center_point (Geom::Point const &c, double rotate)
/**
+ * Flip keeping the point 'c' fixed in the desktop window.
+ */
+void
+SPDesktop::flip_absolute_keep_point (Geom::Point const &c, CanvasFlip flip)
+{
+ Geom::Point w = d2w( c ); // Must be before flip.
+ _current_affine.setFlip( flip );
+ set_display_area( c, w );
+}
+
+
+void
+SPDesktop::flip_relative_keep_point (Geom::Point const &c, CanvasFlip flip)
+{
+ Geom::Point w = d2w( c ); // Must be before flip.
+ _current_affine.addFlip( flip );
+ set_display_area( c, w );
+}
+
+
+/**
+ * Flip aligning the point 'c' to the center of desktop window.
+ */
+void
+SPDesktop::flip_absolute_center_point (Geom::Point const &c, CanvasFlip flip)
+{
+ _current_affine.setFlip( flip );
+ Geom::Rect viewbox = canvas->getViewbox();
+ set_display_area( c, viewbox.midpoint() );
+}
+
+
+void
+SPDesktop::flip_relative_center_point (Geom::Point const &c, CanvasFlip flip)
+{
+ _current_affine.addFlip( flip );
+ Geom::Rect viewbox = canvas->getViewbox();
+ set_display_area( c, viewbox.midpoint() );
+}
+
+
+/**
* Scroll canvas by to a particular point (window coordinates).
*/
void
@@ -1557,12 +1606,16 @@ SPDesktop::setDocument (SPDocument *doc)
layers->setDocument(doc);
selection->setDocument(doc);
- // remove old EventLog if it exists (see also: bug #1071082)
- if (event_log) {
- doc->removeUndoObserver(*event_log);
- delete event_log;
- event_log = 0;
- }
+ if (event_log) {
+ // Remove it from the replaced document. This prevents Inkscape from
+ // crashing since we access it in the replaced document's destructor
+ // which results in an undefined behavior. (See also: bug #1670688)
+ if (this->doc()) {
+ this->doc()->removeUndoObserver(*event_log);
+ }
+ delete event_log;
+ event_log = 0;
+ }
/* setup EventLog */
event_log = new Inkscape::EventLog(doc);
diff --git a/src/desktop.h b/src/desktop.h
index 3dc11b557..330d95607 100644
--- a/src/desktop.h
+++ b/src/desktop.h
@@ -177,6 +177,8 @@ public:
SPCanvasGroup *tempgroup; ///< contains temporary canvas items
SPCanvasItem *page; ///< page background
SPCanvasItem *page_border; ///< page border
+ SPCanvasItem *canvas_rotate; ///< quickly show canvas rotation
+ SPCanvasItem *canvas_debug; ///< shows tiling
SPCSSAttr *current; ///< current style
bool _focusMode; ///< Whether we're focused working or general working
@@ -351,6 +353,18 @@ public:
void rotate_absolute_center_point (Geom::Point const &c, double const rotate);
void rotate_relative_center_point (Geom::Point const &c, double const rotate);
+ enum CanvasFlip {
+ FLIP_NONE = 0,
+ FLIP_HORIZONTAL = 1,
+ FLIP_VERTICAL = 2
+ };
+ void flip_absolute_keep_point (Geom::Point const &c, CanvasFlip flip);
+ void flip_relative_keep_point (Geom::Point const &c, CanvasFlip flip);
+ void flip_absolute_center_point (Geom::Point const &c, CanvasFlip flip);
+ void flip_relative_center_point (Geom::Point const &c, CanvasFlip flip);
+
+ double current_rotation() const { return _current_affine.getRotation(); }
+
void scroll_absolute (Geom::Point const &point, bool is_scrolling = false);
void scroll_relative (Geom::Point const &delta, bool is_scrolling = false);
void scroll_relative_in_svg_coords (double dx, double dy, bool is_scrolling = false);
@@ -474,10 +488,29 @@ private:
_update();
}
+ void setFlip( CanvasFlip flip ) {
+ _flip = Geom::Scale();
+ addFlip( flip );
+ }
+
+ void addFlip( CanvasFlip flip ) {
+ if (flip & FLIP_HORIZONTAL) {
+ _flip *= Geom::Scale(-1.0, 1.0);
+ }
+ if (flip & FLIP_VERTICAL) {
+ _flip *= Geom::Scale(1.0, -1.0);
+ }
+ _update();
+ }
+
double getZoom() const {
return _d2w.descrim();
}
+ double getRotation() const {
+ return _rotate.angle();
+ }
+
void setOffset( Geom::Point offset ) {
_offset = offset;
}
@@ -490,13 +523,14 @@ private:
private:
void _update() {
- _d2w = _rotate * _scale;
+ _d2w = _rotate * _scale * _flip;
_w2d = _d2w.inverse();
}
Geom::Affine _w2d; // Window to desktop
Geom::Affine _d2w; // Desktop to window
Geom::Rotate _rotate; // Rotate part of _w2d
Geom::Scale _scale; // Scale part of _w2d
+ Geom::Scale _flip; // Flip part of _w2d
Geom::Point _offset; // Point on canvas to align to (0,0) of window
};
diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt
index 0bf1d6e45..8eaaee99a 100644
--- a/src/display/CMakeLists.txt
+++ b/src/display/CMakeLists.txt
@@ -4,7 +4,9 @@ set(display_SRC
canvas-arena.cpp
canvas-axonomgrid.cpp
canvas-bpath.cpp
+ canvas-debug.cpp
canvas-grid.cpp
+ canvas-rotate.cpp
canvas-temporary-item-list.cpp
canvas-temporary-item.cpp
canvas-text.cpp
@@ -64,7 +66,9 @@ set(display_SRC
canvas-arena.h
canvas-axonomgrid.h
canvas-bpath.h
+ canvas-debug.h
canvas-grid.h
+ canvas-rotate.h
canvas-temporary-item-list.h
canvas-temporary-item.h
canvas-text.h
diff --git a/src/display/canvas-debug.cpp b/src/display/canvas-debug.cpp
new file mode 100644
index 000000000..1748029e9
--- /dev/null
+++ b/src/display/canvas-debug.cpp
@@ -0,0 +1,100 @@
+/*
+ * A simple surface for debugging the canvas. Shows how tiles are drawn.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "inkscape.h"
+#include "desktop.h"
+
+#include "canvas-debug.h"
+#include "sp-canvas.h"
+#include "cairo-utils.h"
+#include "ui/event-debug.h"
+
+namespace {
+
+static void sp_canvas_debug_destroy(SPCanvasItem *item);
+static void sp_canvas_debug_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
+static void sp_canvas_debug_render (SPCanvasItem *item, SPCanvasBuf *buf);
+static int sp_canvas_debug_event (SPCanvasItem *item, GdkEvent *event);
+
+} // namespace
+
+G_DEFINE_TYPE(SPCanvasDebug, sp_canvas_debug, SP_TYPE_CANVAS_ITEM);
+
+static void sp_canvas_debug_class_init (SPCanvasDebugClass *klass)
+{
+ klass->destroy = sp_canvas_debug_destroy;
+ klass->update = sp_canvas_debug_update;
+ klass->render = sp_canvas_debug_render;
+ klass->event = sp_canvas_debug_event;
+}
+
+static void sp_canvas_debug_init (SPCanvasDebug *debug)
+{
+ debug->pickable = true; // So we can receive events.
+}
+
+namespace {
+static void sp_canvas_debug_destroy (SPCanvasItem *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (SP_IS_CANVAS_DEBUG (object));
+
+ if (SP_CANVAS_ITEM_CLASS(sp_canvas_debug_parent_class)->destroy) {
+ SP_CANVAS_ITEM_CLASS(sp_canvas_debug_parent_class)->destroy(object);
+ }
+}
+
+static void sp_canvas_debug_update( SPCanvasItem *item, Geom::Affine const &/*affine*/, unsigned int /*flags*/ )
+{
+ // We cover the entire canvas
+ item->x1 = -G_MAXINT;
+ item->y1 = -G_MAXINT;
+ item->x2 = G_MAXINT;
+ item->y2 = G_MAXINT;
+}
+
+static void sp_canvas_debug_render( SPCanvasItem *item, SPCanvasBuf *buf)
+{
+ if (!buf->ct) {
+ return;
+ }
+
+ cairo_set_line_width (buf->ct, 2);
+
+ // Draw box around buffer (for debugging)
+ cairo_new_path (buf->ct);
+ cairo_move_to (buf->ct, 0, 0);
+ cairo_line_to (buf->ct, buf->rect.width(), 0);
+ cairo_line_to (buf->ct, buf->rect.width(), buf->rect.height());
+ cairo_line_to (buf->ct, 0, buf->rect.height());
+ cairo_close_path (buf->ct);
+ ink_cairo_set_source_rgba32 (buf->ct, 0xff7f7f7f);
+ cairo_stroke (buf->ct);
+}
+
+static int sp_canvas_debug_event (SPCanvasItem *item, GdkEvent *event)
+{
+ ui_dump_event (event, Glib::ustring("sp_canvas_debug_event"));
+ return false; // We don't use any events...
+}
+
+} // namespace
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/display/canvas-debug.h b/src/display/canvas-debug.h
new file mode 100644
index 000000000..d5a166da9
--- /dev/null
+++ b/src/display/canvas-debug.h
@@ -0,0 +1,41 @@
+#ifndef SEEN_SP_CANVAS_DEBUG_H
+#define SEEN_SP_CANVAS_DEBUG_H
+
+/*
+ * A simple surface for debugging the canvas. Shows how tiles are drawn.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-canvas-item.h"
+
+class SPItem;
+
+#define SP_TYPE_CANVAS_DEBUG (sp_canvas_debug_get_type ())
+#define SP_CANVAS_DEBUG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CANVAS_DEBUG, SPCanvasDebug))
+#define SP_IS_CANVAS_DEBUG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CANVAS_DEBUG))
+
+struct SPCanvasDebug : public SPCanvasItem {
+};
+
+GType sp_canvas_debug_get_type (void);
+
+struct SPCanvasDebugClass : public SPCanvasItemClass{};
+
+#endif // SEEN_SP_CANVAS_DEBUG_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp
index 2dadde336..4243d3365 100644
--- a/src/display/canvas-grid.cpp
+++ b/src/display/canvas-grid.cpp
@@ -5,6 +5,7 @@
* Copyright (C) Lauris Kaplinski 2000
* Abhishek Sharma
* Jon A. Cruz <jon@joncruz.org>
+ * Copyright (C) Tavmong Bah 2017 <tavmjong@free.fr>
*/
/* As a general comment, I am not exactly proud of how things are done.
@@ -841,21 +842,19 @@ void
CanvasXYGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/)
{
ow = origin * affine;
- // Temp hack to insure grid doesn't collapse with rotation.
- sw[0] = spacing[0] * sqrt(affine[0]*affine[0] + affine[1]*affine[1]);
- sw[1] = spacing[1] * sqrt(affine[2]*affine[2] + affine[3]*affine[3]);
- sw -= Geom::Point(affine[4], affine[5]);
+ sw[0] = Geom::Point(spacing[0], 0) * affine.withoutTranslation();
+ sw[1] = Geom::Point(0, spacing[1]) * affine.withoutTranslation();
+ // Find suitable grid spacing for display
for(int dim = 0; dim < 2; dim++) {
gint scaling_factor = empspacing;
if (scaling_factor <= 1)
scaling_factor = 5;
- scaled[dim] = FALSE;
- sw[dim] = fabs (sw[dim]);
- while (sw[dim] < 8.0) {
- scaled[dim] = TRUE;
+ scaled[dim] = false;
+ while (fabs(sw[dim].length()) < 8.0) {
+ scaled[dim] = true;
sw[dim] *= scaling_factor;
/* First pass, go up to the major line spacing, then
keep increasing by two. */
@@ -865,49 +864,45 @@ CanvasXYGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/)
}
-static void
-grid_hline (SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba)
+// Find intersections of line with rectangle. There should be zero or two.
+// If line is degenerate with rectangle side, two corner points are returned.
+static std::vector<Geom::Point>
+intersect_line_rectangle( Geom::Line const &line, Geom::Rect const &rect )
{
- if ((y < buf->rect.top()) || (y >= buf->rect.bottom()))
- return;
-
- cairo_move_to(buf->ct, 0.5 + xs, 0.5 + y);
- cairo_line_to(buf->ct, 0.5 + xe, 0.5 + y);
- ink_cairo_set_source_rgba32(buf->ct, rgba);
- cairo_stroke(buf->ct);
-}
-
-static void
-grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba)
-{
- if ((x < buf->rect.left()) || (x >= buf->rect.right()))
- return;
-
- cairo_move_to(buf->ct, 0.5 + x, 0.5 + ys);
- cairo_line_to(buf->ct, 0.5 + x, 0.5 + ye);
- ink_cairo_set_source_rgba32(buf->ct, rgba);
- cairo_stroke(buf->ct);
+ std::vector<Geom::Point> intersections;
+ for (unsigned i = 0; i < 4; ++i) {
+ Geom::LineSegment side( rect.corner(i), rect.corner((i+1)%4) );
+ try {
+ Geom::OptCrossing oc = Geom::intersection(line, side);
+ if (oc) {
+ intersections.push_back( line.pointAt((*oc).ta));
+ }
+ } catch (Geom::InfiniteSolutions) {
+ intersections.clear();
+ intersections.push_back( side.pointAt(0) );
+ intersections.push_back( side.pointAt(1) );
+ return intersections;
+ }
+ }
+ return intersections;
}
-static void
-grid_dot (SPCanvasBuf *buf, gint x, gint y, guint32 rgba)
-{
- if ( (y < buf->rect.top()) || (y >= buf->rect.bottom())
- || (x < buf->rect.left()) || (x >= buf->rect.right()) )
- return;
-
- cairo_rectangle(buf->ct, x, y, 1, 1);
- ink_cairo_set_source_rgba32(buf->ct, rgba);
- cairo_fill(buf->ct);
+// Find the signed distance of a point to a line. The distance is negative if
+// the point lies to the left of the line considering the line's versor.
+static double
+signed_distance( Geom::Point const &point, Geom::Line const &line ) {
+ Geom::Coord t = line.nearestTime( point );
+ Geom::Point p = line.pointAt(t);
+ double distance = Geom::distance( p, point );
+ if ( Geom::cross( Geom::Line( p, point ).versor(), line.versor() ) < 0.0 ) {
+ distance = -distance;
+ }
+ return distance;
}
void
CanvasXYGrid::Render (SPCanvasBuf *buf)
{
- gdouble const sxg = floor ((buf->rect.left() - ow[Geom::X]) / sw[Geom::X]) * sw[Geom::X] + ow[Geom::X];
- gint const xlinestart = round((sxg - ow[Geom::X]) / sw[Geom::X]);
- gdouble const syg = floor ((buf->rect.top() - ow[Geom::Y]) / sw[Geom::Y]) * sw[Geom::Y] + ow[Geom::Y];
- gint const ylinestart = round((syg - ow[Geom::Y]) / sw[Geom::Y]);
// no_emphasize_when_zoomedout determines color (minor or major) when only major grid lines/dots shown.
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -924,75 +919,128 @@ CanvasXYGrid::Render (SPCanvasBuf *buf)
cairo_set_line_width(buf->ct, 1.0);
cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE);
- if (!render_dotted) {
- // Line grid
- gint ylinenum;
- gdouble y;
- for (y = syg, ylinenum = ylinestart; y < buf->rect.bottom(); y += sw[Geom::Y], ylinenum++) {
- gint const y0 = round(y);
- if (!scaled[Geom::Y] && (ylinenum % empspacing) != 0) {
- grid_hline (buf, y0, buf->rect.left(), buf->rect.right() - 1, color);
- } else {
- grid_hline (buf, y0, buf->rect.left(), buf->rect.right() - 1, _empcolor);
- }
- }
+ for (unsigned dim = 0; dim < 2; ++dim) {
- gint xlinenum;
- gdouble x;
- for (x = sxg, xlinenum = xlinestart; x < buf->rect.right(); x += sw[Geom::X], xlinenum++) {
- gint const ix = round(x);
- if (!scaled[Geom::X] && (xlinenum % empspacing) != 0) {
- grid_vline (buf, ix, buf->rect.top(), buf->rect.bottom(), color);
- } else {
- grid_vline (buf, ix, buf->rect.top(), buf->rect.bottom(), _empcolor);
+ // std::cout << "\n " << (dim==0?"Horizontal":"Vertical") << " ------------" << std::endl;
+
+ // Construct an axis line through origin with direction normal to grid spacing.
+ Geom::Line axis = Geom::Line::from_origin_and_vector( ow, sw[dim] );
+ Geom::Line orth = Geom::Line::from_origin_and_vector( ow, sw[(dim+1)%2] );
+
+ double spacing = sw[(dim+1)%2].length(); // Spacing between grid lines.
+ double dash = sw[dim].length(); // Total length of dash pattern.
+
+ // std::cout << " axis: " << axis.origin() << ", " << axis.vector() << std::endl;
+ // std::cout << " spacing: " << spacing << std::endl;
+ // std::cout << " dash period: " << dash << std::endl;
+
+ // Find the minimum and maximum distances of the buffer corners from axis.
+ double min = 1000000;
+ double max = -1000000;
+ for (unsigned c = 0; c < 4; ++c) {
+
+ // We need signed distance... lib2geom offers only positive distance.
+ double distance = signed_distance( buf->rect.corner(c), axis );
+
+ // Correct it for coordinate flips (inverts handedness).
+ if (Geom::cross( axis.vector(), orth.vector() ) > 0 ) {
+ distance = -distance;
}
+
+ if (distance < min)
+ min = distance;
+ if (distance > max)
+ max = distance;
}
- } else {
- // Dotted grid
- gint ylinenum;
- gdouble y;
-
- // alpha needs to be larger than in the line case to maintain a similar visual impact but
- // setting it to the maximal value makes the dots dominant in some cases. Solution,
- // increase the alpha by a factor of 4. This then allows some user adjustment.
- guint32 _empdot = (_empcolor & 0xff) << 2;
- if (_empdot > 0xff)
- _empdot = 0xff;
- _empdot += (_empcolor & 0xffffff00);
-
- guint32 _colordot = (color & 0xff) << 2;
- if (_colordot > 0xff)
- _colordot = 0xff;
- _colordot += (color & 0xffffff00);
-
- for (y = syg, ylinenum = ylinestart; y < buf->rect.bottom(); y += sw[Geom::Y], ylinenum++) {
- gint const iy = round(y);
-
- gint xlinenum;
- gdouble x;
- for (x = sxg, xlinenum = xlinestart; x < buf->rect.right(); x += sw[Geom::X], xlinenum++) {
- gint const ix = round(x);
- if ( (!scaled[Geom::X] && (xlinenum % empspacing) != 0)
- || (!scaled[Geom::Y] && (ylinenum % empspacing) != 0)
- || ((scaled[Geom::X] || scaled[Geom::Y]) && no_emp_when_zoomed_out) )
- {
- // Minor point: dot only
- grid_dot (buf, ix, iy, _colordot); // | (guint32)0x000000FF); // put alpha to max value
+ int start = floor( min/spacing );
+ int stop = floor( max/spacing );
+
+ // std::cout << " rect: " << buf->rect << std::endl;
+ // std::cout << " min: " << min << " max: " << max << std::endl;
+ // std::cout << " start: " << start << " stop: " << stop << std::endl;
+
+ // Loop over grid lines that intersected buf rectangle.
+ for (int j = start+1; j <= stop; ++j) {
+
+ Geom::Line grid_line = Geom::make_parallel_line( ow + j * sw[(dim+1)%2], axis );
+
+ std::vector<Geom::Point> x = intersect_line_rectangle( grid_line, buf->rect );
+
+ // If we have two intersections, grid line intersects buffer rectangle.
+ if (x.size() == 2 ) {
+
+ // Make sure lines are always drawn in the same direction (or dashes misplaced).
+ Geom::Line vector( x[0], x[1]);
+ if (Geom::dot( vector.vector(), axis.vector() ) < 0.0) {
+ std::swap(x[0], x[1]);
+ }
+
+ // Set up line.
+ cairo_move_to(buf->ct, x[0][Geom::X] + 0.5, x[0][Geom::Y] + 0.5);
+ cairo_line_to(buf->ct, x[1][Geom::X] + 0.5, x[1][Geom::Y] + 0.5);
+
+ // Set dash pattern and color.
+ if (render_dotted) {
+
+ // alpha needs to be larger than in the line case to maintain a similar
+ // visual impact but setting it to the maximal value makes the dots
+ // dominant in some cases. Solution, increase the alpha by a factor of
+ // 4. This then allows some user adjustment.
+ guint32 _empdot = (_empcolor & 0xff) << 2;
+ if (_empdot > 0xff)
+ _empdot = 0xff;
+ _empdot += (_empcolor & 0xffffff00);
+
+ guint32 _colordot = (color & 0xff) << 2;
+ if (_colordot > 0xff)
+ _colordot = 0xff;
+ _colordot += (color & 0xffffff00);
+
+ // Dash pattern must use spacing from orthogonal direction.
+ // Offset is to center dash on orthogonal lines.
+ double offset = fmod( signed_distance( x[0], orth ), sw[dim].length());
+ if (Geom::cross( axis.vector(), orth.vector() ) > 0 ) {
+ offset = -offset;
+ }
+
+ double dashes[2];
+ if (!scaled[dim] && (j % empspacing) != 0) {
+ // Minor lines
+ dashes[0] = 1;
+ dashes[1] = dash -1;
+ offset -= 0.5;
+ ink_cairo_set_source_rgba32(buf->ct, _colordot);
+ } else {
+ // Major lines
+ dashes[0] = 3;
+ dashes[1] = dash - 3;
+ offset -= 1.5; // Center dash on intersection.
+ ink_cairo_set_source_rgba32(buf->ct, _empdot);
+ }
+
+ cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_BUTT);
+ cairo_set_dash(buf->ct, dashes, 2, -offset);
+
} else {
- // Major point: small cross
- gint const pitch = 1;
- grid_dot (buf, ix-pitch, iy, _empcolor);
- grid_dot (buf, ix+pitch, iy, _empcolor);
- grid_dot (buf, ix, iy, _empdot ); // | (guint32)0x000000FF); // put alpha to max value
+ // Solid lines
- grid_dot (buf, ix, iy-pitch, _empcolor);
- grid_dot (buf, ix, iy+pitch, _empcolor);
+ // Set color
+ if (!scaled[dim] && (j % empspacing) != 0) {
+ ink_cairo_set_source_rgba32(buf->ct, color );
+ } else {
+ ink_cairo_set_source_rgba32(buf->ct, _empcolor );
+ }
}
- }
+ cairo_stroke(buf->ct);
+
+ } else {
+ std::cerr << "CanvasXYGrid::render: Grid line doesn't intersect!" << std::endl;
+ }
}
}
+
cairo_restore(buf->ct);
}
@@ -1031,7 +1079,7 @@ CanvasXYGridSnapper::_getSnapLines(Geom::Point const &p) const
if (getSnapVisibleOnly()) {
// Only snapping to visible grid lines
- spacing = grid->sw[i]; // this is the spacing of the visible grid lines measured in screen pixels
+ spacing = grid->sw[i].length(); // this is the spacing of the visible grid lines measured in screen pixels
// convert screen pixels to px
// FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
SPDesktop const *dt = _snapmanager->getDesktop();
diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h
index bf520467a..91fa43e69 100644
--- a/src/display/canvas-grid.h
+++ b/src/display/canvas-grid.h
@@ -148,7 +148,7 @@ public:
be different in the X or Y direction, hence two
variables */
Geom::Point ow; /**< Transformed origin by the affine for the zoom */
- Geom::Point sw; /**< Transformed spacing by the affine for the zoom */
+ Geom::Point sw[2]; /**< Transformed spacing by the affine for the zoom */
protected:
virtual Gtk::Widget * newSpecificWidget();
diff --git a/src/display/canvas-rotate.cpp b/src/display/canvas-rotate.cpp
new file mode 100644
index 000000000..aaf6b962c
--- /dev/null
+++ b/src/display/canvas-rotate.cpp
@@ -0,0 +1,288 @@
+/*
+ * Temporary surface for previewing rotated canvas.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "inkscape.h"
+#include "desktop.h"
+
+#include "canvas-rotate.h"
+#include "sp-canvas.h"
+#include "cairo-utils.h"
+#include "ui/event-debug.h"
+
+#include "2geom/point.h"
+#include "2geom/rect.h"
+
+#include <gtk/gtk.h>
+
+namespace {
+
+static void sp_canvas_rotate_destroy(SPCanvasItem *item);
+static void sp_canvas_rotate_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
+static void sp_canvas_rotate_render (SPCanvasItem *item, SPCanvasBuf *buf);
+static int sp_canvas_rotate_event (SPCanvasItem *item, GdkEvent *event);
+
+} // namespace
+
+void sp_canvas_rotate_paint (SPCanvasRotate *canvas_rotate, cairo_surface_t *background);
+
+G_DEFINE_TYPE(SPCanvasRotate, sp_canvas_rotate, SP_TYPE_CANVAS_ITEM);
+
+static void sp_canvas_rotate_class_init (SPCanvasRotateClass *klass)
+{
+ klass->destroy = sp_canvas_rotate_destroy;
+ //klass->update = sp_canvas_rotate_update;
+ //klass->render = sp_canvas_rotate_render;
+ klass->event = sp_canvas_rotate_event;
+}
+
+static void sp_canvas_rotate_init (SPCanvasRotate *rotate)
+{
+ rotate->pickable = true; // So we can receive events.
+ rotate->angle = 0.0;
+ rotate->start_angle = -1000;
+ rotate->surface_copy = NULL;
+ rotate->surface_rotated = NULL;
+}
+
+namespace {
+static void sp_canvas_rotate_destroy (SPCanvasItem *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (SP_IS_CANVAS_ROTATE (object));
+
+ if (SP_CANVAS_ITEM_CLASS(sp_canvas_rotate_parent_class)->destroy) {
+ SP_CANVAS_ITEM_CLASS(sp_canvas_rotate_parent_class)->destroy(object);
+ }
+}
+
+// NOT USED... TOO SLOW
+static void sp_canvas_rotate_update( SPCanvasItem *item, Geom::Affine const &/*affine*/, unsigned int /*flags*/ )
+{
+ SPCanvasRotate *cr = SP_CANVAS_ROTATE(item);
+
+ if (cr->surface_copy == NULL) {
+ // std::cout << "sp_canvas_rotate_update: surface_copy is NULL" << std::endl;
+ return;
+ }
+
+ // Destroy surface_rotated if it already exists.
+ if (cr->surface_rotated != NULL) {
+ cairo_surface_destroy (cr->surface_rotated);
+ cr->surface_rotated = NULL;
+ }
+
+ // Create rotated surface
+ cr->surface_rotated = ink_cairo_surface_create_identical(cr->surface_copy);
+ double width = cairo_image_surface_get_width (cr->surface_rotated);
+ double height = cairo_image_surface_get_height (cr->surface_rotated);
+ cairo_t *context = cairo_create( cr->surface_rotated );
+ cairo_set_operator( context, CAIRO_OPERATOR_SOURCE );
+ cairo_translate( context, width/2.0, height/2.0 );
+ cairo_rotate( context, Geom::rad_from_deg(-cr->angle) );
+ cairo_translate( context, -width/2.0, -height/2.0 );
+ cairo_set_source_surface( context, cr->surface_copy, 0, 0 );
+ cairo_paint( context );
+ cairo_destroy( context);
+
+ // We cover the entire canvas
+ item->x1 = -G_MAXINT;
+ item->y1 = -G_MAXINT;
+ item->x2 = G_MAXINT;
+ item->y2 = G_MAXINT;
+
+ item->canvas->requestRedraw(item->x1, item->y1, item->x2, item->y2);
+}
+
+// NOT USED... TOO SLOW
+static void sp_canvas_rotate_render( SPCanvasItem *item, SPCanvasBuf *buf)
+{
+ // std::cout << "sp_canvas_rotate_render:" << std::endl;
+ // std::cout << " buf->rect: " << buf->rect << std::endl;
+ // std::cout << " buf->canvas_rect: " << buf->canvas_rect << std::endl;
+ SPCanvasRotate *cr = SP_CANVAS_ROTATE(item);
+
+ if (!buf->ct) {
+ return;
+ }
+
+ if (cr->surface_rotated == NULL ) {
+ // std::cout << " surface_rotated is NULL" << std::endl;
+ return;
+ }
+
+ // Draw rotated canvas
+ cairo_save (buf->ct);
+ cairo_translate (buf->ct,
+ buf->canvas_rect.left() - buf->rect.left(),
+ buf->canvas_rect.top() - buf->rect.top() );
+ cairo_set_operator (buf->ct, CAIRO_OPERATOR_SOURCE );
+ cairo_set_source_surface (buf->ct, cr->surface_rotated, 0, 0 );
+ cairo_paint (buf->ct);
+ cairo_restore (buf->ct);
+
+
+ // Draw line from center to cursor
+ cairo_save (buf->ct);
+ cairo_translate (buf->ct, -buf->rect.left(), -buf->rect.top());
+ cairo_new_path (buf->ct);
+ cairo_move_to (buf->ct, cr->center[Geom::X], cr->center[Geom::Y]);
+ cairo_rel_line_to (buf->ct, cr->cursor[Geom::X], cr->cursor[Geom::Y]);
+ cairo_set_line_width (buf->ct, 2);
+ ink_cairo_set_source_rgba32 (buf->ct, 0xff00007f);
+ cairo_stroke (buf->ct);
+ cairo_restore (buf->ct);
+
+}
+
+static int sp_canvas_rotate_event (SPCanvasItem *item, GdkEvent *event)
+{
+ SPCanvasRotate *cr = SP_CANVAS_ROTATE(item);
+
+// ui_dump_event (event, Glib::ustring("sp_canvas_rotate_event"));
+
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Geom::Rect viewbox = desktop->canvas->getViewbox(); // Not SVG viewbox!
+ cr->center = viewbox.midpoint();
+
+ switch (event->type) {
+ case GDK_MOTION_NOTIFY:
+ {
+ Geom::Point cursor( event->motion.x, event->motion.y );
+
+ // Both cursor and center are in window coordinates
+ Geom::Point rcursor( cursor - cr->center );
+ double angle = Geom::deg_from_rad( Geom::atan2(rcursor) );
+
+ // Set start angle
+ if (cr->start_angle < -360) {
+ cr->start_angle = angle;
+ }
+
+ double rotation_snap = 15;
+
+ double delta_angle = cr->start_angle - angle;
+
+ if (event->motion.state & GDK_SHIFT_MASK &&
+ event->motion.state & GDK_CONTROL_MASK) {
+ delta_angle = 0;
+ } else if (event->motion.state & GDK_SHIFT_MASK) {
+ delta_angle = round(delta_angle/rotation_snap) * rotation_snap;
+ } else if (event->motion.state & GDK_CONTROL_MASK) {
+ // ?
+ } else if (event->motion.state & GDK_MOD1_MASK) {
+ // Decimal raw angle
+ } else {
+ delta_angle = floor(delta_angle);
+ }
+
+ cr->angle = delta_angle;
+
+ // Correct line for snapping of angle
+ double distance = rcursor.length();
+ cr->cursor = Geom::Point::polar( Geom::rad_from_deg(angle), distance );
+
+ // Update screen
+ // sp_canvas_item_request_update( item );
+ sp_canvas_rotate_paint (cr, cr->canvas->_backing_store);
+ break;
+ }
+ case GDK_BUTTON_RELEASE:
+
+ // Rotate the actual canvas
+ desktop->rotate_relative_center_point (desktop->w2d(cr->center),
+ Geom::rad_from_deg(cr->angle) );
+
+ // We're done
+ sp_canvas_item_ungrab (item, event->button.time);
+ sp_canvas_item_hide (item);
+
+ cr->start_angle = -1000;
+ if (cr->surface_copy != NULL) {
+ cairo_surface_destroy( cr->surface_copy );
+ cr->surface_copy = NULL;
+ }
+ if (cr->surface_rotated != NULL) {
+ cairo_surface_destroy( cr->surface_rotated );
+ cr->surface_rotated = NULL;
+ }
+ // sp_canvas_item_show (desktop->drawing);
+
+ break;
+ case GDK_KEY_PRESS:
+ // std::cout << " Key press: " << std::endl;
+ break;
+ case GDK_KEY_RELEASE:
+ // std::cout << " Key release: " << std::endl;
+ break;
+ default:
+ // ui_dump_event (event, "sp_canvas_rotate_event: unwanted event: ");
+ break;
+ }
+
+ if (event->type == GDK_KEY_PRESS) return false;
+
+ return true;
+}
+
+} // namespace
+
+void sp_canvas_rotate_start (SPCanvasRotate *canvas_rotate, cairo_surface_t *background)
+{
+ if (background == NULL) {
+ std::cerr << "sp_canvas_rotate_start: background is NULL!" << std::endl;
+ return;
+ }
+
+ canvas_rotate->angle = 0.0;
+
+ // Copy current background
+ canvas_rotate->surface_copy = ink_cairo_surface_copy( background );
+
+ // Paint canvas with background... since we are hiding drawing.
+ sp_canvas_item_request_update( canvas_rotate );
+}
+
+// Paint the canvas ourselves for speed....
+void sp_canvas_rotate_paint (SPCanvasRotate *canvas_rotate, cairo_surface_t *background)
+{
+ if (background == NULL) {
+ std::cerr << "sp_canvas_rotate_paint: background is NULL!" << std::endl;
+ return;
+ }
+
+ double width = cairo_image_surface_get_width (background);
+ double height = cairo_image_surface_get_height (background);
+
+ // Draw rotated canvas
+ cairo_t *context = cairo_create( background );
+
+ cairo_save (context);
+ cairo_set_operator( context, CAIRO_OPERATOR_SOURCE );
+ cairo_translate( context, width/2.0, height/2.0 );
+ cairo_rotate( context, Geom::rad_from_deg(-canvas_rotate->angle) );
+ cairo_translate( context, -width/2.0, -height/2.0 );
+ cairo_set_source_surface( context, canvas_rotate->surface_copy, 0, 0 );
+ cairo_paint( context );
+ cairo_restore( context );
+ cairo_destroy( context );
+
+ gtk_widget_queue_draw (GTK_WIDGET (canvas_rotate->canvas));
+}
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/display/canvas-rotate.h b/src/display/canvas-rotate.h
new file mode 100644
index 000000000..8620dcced
--- /dev/null
+++ b/src/display/canvas-rotate.h
@@ -0,0 +1,50 @@
+#ifndef SEEN_SP_CANVAS_ROTATE_H
+#define SEEN_SP_CANVAS_ROTATE_H
+
+/*
+ * Temporary surface for previewing rotated canvas.
+ *
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2017 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-canvas-item.h"
+#include "2geom/line.h"
+
+class SPItem;
+
+#define SP_TYPE_CANVAS_ROTATE (sp_canvas_rotate_get_type ())
+#define SP_CANVAS_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CANVAS_ROTATE, SPCanvasRotate))
+#define SP_IS_CANVAS_ROTATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CANVAS_ROTATE))
+
+struct SPCanvasRotate : public SPCanvasItem {
+ Geom::Point center; // Center of screen
+ Geom::Point cursor; // Position of cursor relative to center (after angle snapping)
+ double angle; // Rotation angle in degrees
+ double start_angle; // Starting angle of cursor
+ cairo_surface_t *surface_copy; // Copy of original surface
+ cairo_surface_t *surface_rotated; // Copy of original surface, rotated
+};
+
+void sp_canvas_rotate_start( SPCanvasRotate *canvas_rotate, cairo_surface_t *background );
+
+GType sp_canvas_rotate_get_type (void);
+
+struct SPCanvasRotateClass : public SPCanvasItemClass{};
+
+#endif // SEEN_SP_CANVAS_ROTATE_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/display/canvas-temporary-item-list.h b/src/display/canvas-temporary-item-list.h
index 6b0e5796b..471bb99b9 100644
--- a/src/display/canvas-temporary-item-list.h
+++ b/src/display/canvas-temporary-item-list.h
@@ -14,7 +14,6 @@
struct SPCanvasItem;
class SPDesktop;
-class SPViewBox;
namespace Inkscape {
namespace Display {
diff --git a/src/display/gnome-canvas-acetate.cpp b/src/display/gnome-canvas-acetate.cpp
index 9147a1bbf..297d69068 100644
--- a/src/display/gnome-canvas-acetate.cpp
+++ b/src/display/gnome-canvas-acetate.cpp
@@ -14,11 +14,13 @@
*/
#include "gnome-canvas-acetate.h"
+#include "ui/event-debug.h"
static void sp_canvas_acetate_destroy(SPCanvasItem *object);
static void sp_canvas_acetate_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
static double sp_canvas_acetate_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item);
+static int sp_canvas_acetate_event( SPCanvasItem *item, GdkEvent *event);
G_DEFINE_TYPE(SPCanvasAcetate, sp_canvas_acetate, SP_TYPE_CANVAS_ITEM);
@@ -29,6 +31,7 @@ static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass)
item_class->destroy = sp_canvas_acetate_destroy;
item_class->update = sp_canvas_acetate_update;
item_class->point = sp_canvas_acetate_point;
+ // item_class->event = sp_canvas_acetate_event;
}
static void sp_canvas_acetate_init (SPCanvasAcetate */*acetate*/)
@@ -60,3 +63,8 @@ static double sp_canvas_acetate_point( SPCanvasItem *item, Geom::Point /*p*/, SP
return 0.0;
}
+// static int sp_canvas_acetate_event( SPCanvasItem *item, GdkEvent *event)
+// {
+// ui_dump_event (event, "sp_canvas_acetate_event");
+// return 0; // ?
+// }
diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp
index ecc952c48..075e04e6d 100644
--- a/src/display/sodipodi-ctrlrect.cpp
+++ b/src/display/sodipodi-ctrlrect.cpp
@@ -6,9 +6,11 @@
* bulia byak <buliabyak@users.sf.net>
* Carl Hetherington <inkscape@carlh.net>
* Jon A. Cruz <jon@joncruz.org>
+ * Tavmjong Bah <tavmjong@free.fr>
*
* Copyright (C) 1999-2001 Lauris Kaplinski
* Copyright (C) 2000-2001 Ximian, Inc.
+ * Copyright (C) 2017 Tavmjong Bah
*
* Released under GNU GPL
*
@@ -18,6 +20,7 @@
#include "sp-canvas-util.h"
#include "display/cairo-utils.h"
#include "display/sp-canvas.h"
+#include <2geom/transforms.h>
/*
* Currently we do not have point method, as it should always be painted
@@ -76,14 +79,12 @@ void CtrlRect::init()
_dashed = false;
_checkerboard = false;
- _shadow = 0;
+ _shadow_width = 0;
_area = Geom::OptIntRect();
_rect = Geom::Rect(Geom::Point(0,0),Geom::Point(0,0));
- _shadow_size = 0;
-
_border_color = 0x000000ff;
_fill_color = 0xffffffff;
_shadow_color = 0x000000ff;
@@ -98,52 +99,120 @@ void CtrlRect::render(SPCanvasBuf *buf)
if (!_area) {
return;
}
- Geom::IntRect area = *_area;
- Geom::IntRect area_w_shadow (area[X].min(), area[Y].min(),
- area[X].max() + _shadow_size, area[Y].max() + _shadow_size);
- if ( area_w_shadow.intersects(buf->rect) )
+
+ Geom::IntRect area = *_area; // _area already includes space for shadow.
+ if ( area.intersects(buf->rect) )
{
- static double const dashes[2] = {4.0, 4.0};
+
cairo_save(buf->ct);
cairo_translate(buf->ct, -buf->rect.left(), -buf->rect.top());
- cairo_set_line_width(buf->ct, 1);
- if (_dashed) cairo_set_dash(buf->ct, dashes, 2, 0);
- cairo_rectangle(buf->ct, 0.5 + area[X].min(), 0.5 + area[Y].min(),
- area[X].max() - area[X].min(), area[Y].max() - area[Y].min());
+
+ // Get canvas rotation (scale is isotropic).
+ double rotation = atan2( _affine[1], _affine[0] );
+
+ // Are we axis aligned?
+ double mod_rot = fmod(rotation * M_2_PI, 1);
+ bool axis_aligned = Geom::are_near( mod_rot, 0 ) || Geom::are_near( mod_rot, 1.0 );
+
+ // Get the points we need transformed to window coordinates.
+ Geom::Point rect_transformed[4];
+ for (unsigned i = 0; i < 4; ++i) {
+ rect_transformed[i] = _rect.corner(i) * _affine;
+ }
+
+ // Draw shadow first. Shadow extends under rectangle to reduce aliasing effects.
+ if (_shadow_width > 0 && !_dashed) {
+
+ // Offset by half stroke width (_shadow_width is in window coordinates).
+ // Need to handle change in handedness with flips.
+ Geom::Point shadow( _shadow_width/2.0, (_affine.det()>0?-1:1)*_shadow_width/2.0 );
+ shadow *= Geom::Rotate( rotation );
+
+ if (axis_aligned) {
+ // Snap to pixel grid (add 0.5 to center on pixel).
+ cairo_move_to( buf->ct,
+ floor(rect_transformed[0][X]+shadow[X]+0.5) + 0.5,
+ floor(rect_transformed[0][Y]+shadow[Y]+0.5) + 0.5 );
+ cairo_line_to( buf->ct,
+ floor(rect_transformed[1][X]+shadow[X]+0.5) + 0.5,
+ floor(rect_transformed[1][Y]+shadow[Y]+0.5) + 0.5 );
+ cairo_line_to( buf->ct,
+ floor(rect_transformed[2][X]+shadow[X]+0.5) + 0.5,
+ floor(rect_transformed[2][Y]+shadow[Y]+0.5) + 0.5 );
+ } else {
+ cairo_move_to( buf->ct,
+ rect_transformed[0][X]+shadow[X],
+ rect_transformed[0][Y]+shadow[Y] );
+ cairo_line_to( buf->ct,
+ rect_transformed[1][X]+shadow[X],
+ rect_transformed[1][Y]+shadow[Y] );
+ cairo_line_to( buf->ct,
+ rect_transformed[2][X]+shadow[X],
+ rect_transformed[2][Y]+shadow[Y] );
+ }
+
+ ink_cairo_set_source_rgba32( buf->ct, _shadow_color );
+ cairo_set_line_width( buf->ct, _shadow_width + 1 );
+ cairo_stroke( buf->ct );
+ }
+
+ // Setup rectangle path
+ if (axis_aligned) {
+
+ // Snap to pixel grid
+ Geom::Rect outline( _rect.min() * _affine, _rect.max() * _affine);
+ // Check if there is a simpler way to go from 'outline' to 'int_rect'.
+ Geom::IntRect int_rect ( (int) floor(outline.min()[X] + 0.5),
+ (int) floor(outline.min()[Y] + 0.5),
+ (int) floor(outline.max()[X] + 0.5),
+ (int) floor(outline.max()[Y] + 0.5) );
+ cairo_rectangle (buf->ct,
+ 0.5 + int_rect[X].min(),
+ 0.5 + int_rect[Y].min(),
+ int_rect[X].max() - int_rect[X].min(),
+ int_rect[Y].max() - int_rect[Y].min() );
+ } else {
+
+ // Angled
+ cairo_move_to( buf->ct, rect_transformed[0][X], rect_transformed[0][Y] );
+ cairo_line_to( buf->ct, rect_transformed[1][X], rect_transformed[1][Y] );
+ cairo_line_to( buf->ct, rect_transformed[2][X], rect_transformed[2][Y] );
+ cairo_line_to( buf->ct, rect_transformed[3][X], rect_transformed[3][Y] );
+ cairo_close_path( buf->ct );
+ }
+
+ // This doesn't seem to be used anywhere. If it is, then we should
+ // probably rotate the coordinate system and fill using a cairo_rectangle().
if (_checkerboard) {
cairo_pattern_t *cb = ink_cairo_pattern_create_checkerboard();
cairo_set_source(buf->ct, cb);
cairo_pattern_destroy(cb);
cairo_fill_preserve(buf->ct);
}
+
if (_has_fill) {
ink_cairo_set_source_rgba32(buf->ct, _fill_color);
cairo_fill_preserve(buf->ct);
}
+ // Set up stroke.
ink_cairo_set_source_rgba32(buf->ct, _border_color);
- cairo_stroke(buf->ct);
+ cairo_set_line_width(buf->ct, 1);
+ static double const dashes[2] = {4.0, 4.0};
+ if (_dashed) cairo_set_dash(buf->ct, dashes, 2, 0);
- if (_shadow_size == 1) { // highlight the border by drawing it in _shadow_color
- if (_dashed) {
- cairo_set_dash(buf->ct, dashes, 2, 4);
- cairo_rectangle(buf->ct, 0.5 + area[X].min(), 0.5 + area[Y].min(),
- area[X].max() - area[X].min(), area[Y].max() - area[Y].min());
- } else {
- cairo_rectangle(buf->ct, -0.5 + area[X].min(), -0.5 + area[Y].min(),
- area[X].max() - area[X].min(), area[Y].max() - area[Y].min());
- }
- ink_cairo_set_source_rgba32(buf->ct, _shadow_color);
- cairo_stroke(buf->ct);
- } else if (_shadow_size > 1) { // fill the shadow
+ // Stroke rectangle.
+ cairo_stroke_preserve(buf->ct);
+
+ // Highlight the border by drawing it in _shadow_color.
+ if (_shadow_width == 1 && _dashed) {
ink_cairo_set_source_rgba32(buf->ct, _shadow_color);
- cairo_rectangle(buf->ct, 1 + area[X].max(), area[Y].min() + _shadow_size,
- _shadow_size, area[Y].max() - area[Y].min() + 1); // right shadow
- cairo_rectangle(buf->ct, area[X].min() + _shadow_size, 1 + area[Y].max(),
- area[X].max() - area[X].min() - _shadow_size + 1, _shadow_size);
- cairo_fill(buf->ct);
+ cairo_set_dash(buf->ct, dashes, 2, 4); // Dash offset by dash length.
+ cairo_stroke_preserve(buf->ct);
}
+
+ cairo_new_path( buf->ct ); // Clear path or get wierd artifacts.
cairo_restore(buf->ct);
}
}
@@ -158,124 +227,33 @@ void CtrlRect::update(Geom::Affine const &affine, unsigned int flags)
(SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class))->update(this, affine, flags);
}
- sp_canvas_item_reset_bounds(this);
+ // Note: There is no harm if 'area' is too large other than a possible small slow down in
+ // rendering speed.
- Geom::Rect bbox(_rect.min() * affine, _rect.max() * affine);
+ // Calculate an axis-aligned bounding box that include all of transformed _rect.
+ Geom::Rect bbox = _rect;
+ bbox *= affine;
- Geom::OptIntRect _area_old = _area;
- Geom::IntRect area ( (int) floor(bbox.min()[Geom::X] + 0.5),
- (int) floor(bbox.min()[Geom::Y] + 0.5),
- (int) floor(bbox.max()[Geom::X] + 0.5),
- (int) floor(bbox.max()[Geom::Y] + 0.5) );
- _area = area;
- Geom::IntRect area_old(0,0,0,0);
- if (_area_old) { // this weird construction is because the code below assumes _area_old to be 'valid'
- area_old = *_area_old;
- }
+ // Enlarge bbox by twice shadow size (to allow for shadow on any side with a 45deg rotation).
+ bbox.expandBy( 2.0 *_shadow_width );
- gint _shadow_size_old = _shadow_size;
- _shadow_size = _shadow;
-
- // FIXME: we don't process a possible change in _has_fill
- if (_has_fill) {
- if (_area_old) {
- canvas->requestRedraw(area_old[X].min() - 1, area_old[Y].min() - 1,
- area_old[X].max() + _shadow_size + 1, area_old[Y].max() + _shadow_size + 1);
- }
- if (_area) {
- canvas->requestRedraw(area[X].min() - 1, area[Y].min() - 1,
- area[X].max() + _shadow_size + 1, area[Y].max() + _shadow_size + 1);
- }
- } else { // clear box, be smart about what part of the frame to redraw
-
- /* Top */
- if (area[Y].min() != area_old[Y].min()) { // different level, redraw fully old and new
- if (area_old[X].min() != area_old[X].max())
- canvas->requestRedraw(area_old[X].min() - 1, area_old[Y].min() - 1,
- area_old[X].max() + 1, area_old[Y].min() + 1);
-
- if (area[X].min() != area[X].max())
- canvas->requestRedraw(area[X].min() - 1, area[Y].min() - 1,
- area[X].max() + 1, area[Y].min() + 1);
- } else { // same level, redraw only the ends
- if (area[X].min() != area_old[X].min()) {
- canvas->requestRedraw(MIN(area_old[X].min(),area[X].min()) - 1, area[Y].min() - 1,
- MAX(area_old[X].min(),area[X].min()) + 1, area[Y].min() + 1);
- }
- if (area[X].max() != area_old[X].max()) {
- canvas->requestRedraw(MIN(area_old[X].max(),area[X].max()) - 1, area[Y].min() - 1,
- MAX(area_old[X].max(),area[X].max()) + 1, area[Y].min() + 1);
- }
- }
-
- /* Left */
- if (area[X].min() != area_old[X].min()) { // different level, redraw fully old and new
- if (area_old[Y].min() != area_old[Y].max())
- canvas->requestRedraw(area_old[X].min() - 1, area_old[Y].min() - 1,
- area_old[X].min() + 1, area_old[Y].max() + 1);
-
- if (area[Y].min() != area[Y].max())
- canvas->requestRedraw(area[X].min() - 1, area[Y].min() - 1,
- area[X].min() + 1, area[Y].max() + 1);
- } else { // same level, redraw only the ends
- if (area[Y].min() != area_old[Y].min()) {
- canvas->requestRedraw(area[X].min() - 1, MIN(area_old[Y].min(),area[Y].min()) - 1,
- area[X].min() + 1, MAX(area_old[Y].min(),area[Y].min()) + 1);
- }
- if (area[Y].max() != area_old[Y].max()) {
- canvas->requestRedraw(area[X].min() - 1, MIN(area_old[Y].max(),area[Y].max()) - 1,
- area[X].min() + 1, MAX(area_old[Y].max(),area[Y].max()) + 1);
- }
- }
-
- /* Right */
- if (area[X].max() != area_old[X].max() || _shadow_size_old != _shadow_size) {
- if (area_old[Y].min() != area_old[Y].max())
- canvas->requestRedraw(area_old[X].max() - 1, area_old[Y].min() - 1,
- area_old[X].max() + _shadow_size + 1, area_old[Y].max() + _shadow_size + 1);
-
- if (area[Y].min() != area[Y].max())
- canvas->requestRedraw(area[X].max() - 1, area[Y].min() - 1,
- area[X].max() + _shadow_size + 1, area[Y].max() + _shadow_size + 1);
- } else { // same level, redraw only the ends
- if (area[Y].min() != area_old[Y].min()) {
- canvas->requestRedraw(area[X].max() - 1, MIN(area_old[Y].min(),area[Y].min()) - 1,
- area[X].max() + _shadow_size + 1, MAX(area_old[Y].min(),area[Y].min()) + _shadow_size + 1);
- }
- if (area[Y].max() != area_old[Y].max()) {
- canvas->requestRedraw(area[X].max() - 1, MIN(area_old[Y].max(),area[Y].max()) - 1,
- area[X].max() + _shadow_size + 1, MAX(area_old[Y].max(),area[Y].max()) + _shadow_size + 1);
- }
- }
+ // Generate an integer rectangle that includes bbox.
+ Geom::OptIntRect _area_old = _area;
+ _area = bbox.roundOutwards();
- /* Bottom */
- if (area[Y].max() != area_old[Y].max() || _shadow_size_old != _shadow_size) {
- if (area_old[X].min() != area_old[X].max())
- canvas->requestRedraw(area_old[X].min() - 1, area_old[Y].max() - 1,
- area_old[X].max() + _shadow_size + 1, area_old[Y].max() + _shadow_size + 1);
-
- if (area[X].min() != area[X].max())
- canvas->requestRedraw(area[X].min() - 1, area[Y].max() - 1,
- area[X].max() + _shadow_size + 1, area[Y].max() + _shadow_size + 1);
- } else { // same level, redraw only the ends
- if (area[X].min() != area_old[X].min()) {
- canvas->requestRedraw(MIN(area_old[X].min(),area[X].min()) - 1, area[Y].max() - 1,
- MAX(area_old[X].min(),area[X].min()) + _shadow_size + 1, area[Y].max() + _shadow_size + 1);
- }
- if (area[X].max() != area_old[X].max()) {
- canvas->requestRedraw(MIN(area_old[X].max(),area[X].max()) - 1, area[Y].max() - 1,
- MAX(area_old[X].max(),area[X].max()) + _shadow_size + 1, area[Y].max() + _shadow_size + 1);
- }
- }
- }
+ // std::cout << " _rect: " << _rect << std::endl;
+ // std::cout << " bbox: " << bbox << std::endl;
+ // std::cout << " area: " << *_area << std::endl;
- // update SPCanvasItem box
if (_area) {
- x1 = area[X].min() - 1;
- y1 = area[Y].min() - 1;
- x2 = area[X].max() + _shadow_size + 1;
- y2 = area[Y].max() + _shadow_size + 1;
+ Geom::IntRect area = *_area;
+ sp_canvas_update_bbox( this, area[X].min(), area[Y].min(), area[X].max(), area[Y].max() );
+ } else {
+ std::cerr << "CtrlRect::update: No area!!" << std::endl;
}
+
+ // At rendering stage, we need to know affine:
+ _affine = affine;
}
@@ -289,7 +267,7 @@ void CtrlRect::setColor(guint32 b, bool h, guint f)
void CtrlRect::setShadow(int s, guint c)
{
- _shadow = s;
+ _shadow_width = s;
_shadow_color = c;
_requestUpdate();
}
diff --git a/src/display/sodipodi-ctrlrect.h b/src/display/sodipodi-ctrlrect.h
index 08a085649..02fc85647 100644
--- a/src/display/sodipodi-ctrlrect.h
+++ b/src/display/sodipodi-ctrlrect.h
@@ -4,14 +4,17 @@
/**
* @file
* Simple non-transformed rectangle, usable for rubberband.
+ * Modified to work with rotated canvas.
*/
/*
* Authors:
* Lauris Kaplinski <lauris@ximian.com>
* Carl Hetherington <inkscape@carlh.net>
+ * Tavmjong Bah <tavjong@free.fr>
*
* Copyright (C) 1999-2001 Lauris Kaplinski
* Copyright (C) 2000-2001 Ximian, Inc.
+ * Copyright (C) 2017 Tavmjong Bah
*
* Released under GNU GPL
*
@@ -21,6 +24,7 @@
#include "sp-canvas-item.h"
#include <2geom/rect.h>
#include <2geom/int-rect.h>
+#include <2geom/transforms.h>
struct SPCanvasBuf;
@@ -48,23 +52,24 @@ private:
void _requestUpdate();
Geom::Rect _rect;
+ Geom::Affine _affine;
+
bool _has_fill;
bool _dashed;
bool _checkerboard;
Geom::OptIntRect _area;
- gint _shadow_size;
+ gint _shadow_width;
guint32 _border_color;
guint32 _fill_color;
guint32 _shadow_color;
- int _shadow;
};
struct CtrlRectClass : public SPCanvasItemClass {};
GType sp_ctrlrect_get_type();
-#endif // SEEN_RUBBERBAND_H
+#endif // SEEN_CTRLRECT_H
/*
Local Variables:
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp
index 61602e880..d04c81ecb 100644
--- a/src/display/sp-canvas.cpp
+++ b/src/display/sp-canvas.cpp
@@ -33,11 +33,6 @@
#include "display/sp-canvas-group.h"
#include "display/rendermode.h"
#include "display/cairo-utils.h"
-#include "display/cairo-templates.h"
-#include "display/drawing-context.h"
-#include "display/drawing-item.h"
-#include "display/nr-filter-colormatrix.h"
-#include "display/canvas-arena.h"
#include "preferences.h"
#include "inkscape.h"
#include "sodipodi-ctrlrect.h"
@@ -45,8 +40,6 @@
#include "debug/gdk-event-latency-tracker.h"
#include "desktop.h"
#include "color.h"
-#include <iomanip>
-#include <glibmm/i18n.h>
#if GTK_CHECK_VERSION(3,20,0)
# include <gdkmm/seat.h>
@@ -1514,7 +1507,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect
buf.buf = NULL;
buf.buf_rowstride = 0;
buf.rect = paint_rect;
- buf.visible_rect = canvas_rect;
+ buf.canvas_rect = canvas_rect;
buf.is_empty = true;
// create temporary surface
@@ -1578,7 +1571,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect
}
struct PaintRectSetup {
- Geom::IntRect big_rect;
+ Geom::IntRect canvas_rect;
GTimeVal start_time;
int max_pixels;
Geom::Point mouse_loc;
@@ -1637,7 +1630,7 @@ int SPCanvas::paintRectInternal(PaintRectSetup const *setup, Geom::IntRect const
gdk_window_begin_paint_rect(window, &r);
*/
- paintSingleBuffer(this_rect, setup->big_rect, bw);
+ paintSingleBuffer(this_rect, setup->canvas_rect, bw);
//gdk_window_end_paint(window);
return 1;
}
@@ -1702,6 +1695,7 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1)
gtk_widget_get_allocation(GTK_WIDGET(this), &allocation);
+ // Find window rectangle in 'world coordinates'.
Geom::IntRect canvas_rect = Geom::IntRect::from_xywh(_x0, _y0,
allocation.width, allocation.height);
Geom::IntRect paint_rect(xx0, yy0, xx1, yy1);
@@ -1712,7 +1706,7 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1)
paint_rect = *area;
PaintRectSetup setup;
- setup.big_rect = paint_rect;
+ setup.canvas_rect = canvas_rect;
// Save the mouse location
gint x, y;
@@ -1733,10 +1727,16 @@ bool SPCanvas::paintRect(int xx0, int yy0, int xx1, int yy1)
setup.mouse_loc = sp_canvas_window_to_world(this, Geom::Point(x,y));
+ static unsigned tile_multiplier = 0;
+ if (tile_multiplier == 0) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ tile_multiplier = prefs->getIntLimited("/options/rendering/tile-multiplier", 1, 1, 64);
+ }
+
if (_rendermode != Inkscape::RENDERMODE_OUTLINE) {
// use 256K as a compromise to not slow down gradients
// 256K is the cached buffer and we need 4 channels
- setup.max_pixels = 65536; // 256K/4
+ setup.max_pixels = 65536 * tile_multiplier; // 256K/4
} else {
// paths only, so 1M works faster
// 1M is the cached buffer and we need 4 channels
@@ -1924,19 +1924,6 @@ SPCanvasGroup *SPCanvas::getRoot()
return SP_CANVAS_GROUP(_root);
}
-gdouble grayscale_value_matrix[20] = {
- 0.21, 0.72, 0.072, 0, 0,
- 0.21, 0.72, 0.072, 0, 0,
- 0.21, 0.72, 0.072, 0, 0,
- 0 , 0 , 0 , 1, 0
- };
-cairo_surface_t *surface_rotated;
-cairo_surface_t *surface_origin;
-cairo_surface_t *surface_measure;
-double start_angle = 0;
-bool started = false;
-bool rotated = false;
-
/**
* Scroll screen to point 'c'. 'c' is measured in screen pixels.
*/
@@ -1965,14 +1952,10 @@ void SPCanvas::scrollTo( Geom::Point const &c, unsigned int clear, bool is_scrol
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
// Paint the background
cairo_translate(cr, -ix, -iy);
- if (rotated) {
- cairo_translate(cr, dx, dy);
- rotated = false;
- }
cairo_set_source(cr, _background);
cairo_paint(cr);
+
// Copy the old backing store contents
-
cairo_set_source_surface(cr, _backing_store, _x0, _y0);
cairo_rectangle(cr, _x0, _y0, allocation.width, allocation.height);
cairo_clip(cr);
@@ -2009,271 +1992,6 @@ void SPCanvas::scrollTo( Geom::Point const &c, unsigned int clear, bool is_scrol
addIdle();
}
-void SPCanvas::startRotateTo(double angle)
-{
- if (!_backing_store || started) {
- return;
- }
- start_angle = angle;
- started = true;
- GtkAllocation allocation;
- gtk_widget_get_allocation(&_widget, &allocation);
- int half_w = allocation.width/2;
- int half_h = allocation.height/2;
- int half_min = std::min(half_w,half_h);
-
- cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height);
- cairo_t *cr = cairo_create(new_backing_store);
- cairo_arc(cr, half_w, half_h, half_min-15, 0, 2*M_PI);
- cairo_fill(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_IN);
- cairo_set_source_surface(cr, _backing_store, 0, 0);
- cairo_paint(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_arc(cr, half_w, half_h, half_min-16, 0, 2*M_PI);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.5);
- cairo_stroke(cr);
- cairo_destroy(cr);
- surface_rotated = new_backing_store;
-
- cairo_surface_t *new_backing_store_measure = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height);
- cr = cairo_create(new_backing_store_measure);
- cairo_arc(cr, half_w, half_h, half_min-15, 0, 2*M_PI);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.2);
- cairo_fill(cr);
- cairo_translate(cr, half_w, half_h);
- cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
- cairo_set_font_size(cr, 10.0);
- for (gint x = 0; x < 360 ; x++){
- gint ang = 360 - x ;//+ 90;
- if (ang > 180) {
- ang -= 360;
- }
- double rot = (-180.0 + x)*(M_PI/180.);
- double dist = half_min-9;
- gint inverse = 1;
- if((x) < 91 || (x) > 270) {
- inverse = -1;
- }
- if(x%10 == 0) {
- cairo_rotate(cr, -rot);
- cairo_text_extents_t extents;
- std::string s = std::to_string(ang) + "º";
- cairo_text_extents(cr, s.c_str(), &extents);
- //std::cout << extents.width/2 << "extents.x_bearing\n";
- cairo_translate(cr, (extents.width/2) * inverse * -1, (dist + ((extents.height/2)* inverse)));
- if((x) < 91 || (x) > 270) {
- cairo_rotate(cr, 180*(M_PI/180.0));
- }
- cairo_text_path(cr, s.c_str());
- if((x) < 91 || (x) > 270) {
- cairo_rotate(cr, -180*(M_PI/180.0));
- }
- cairo_translate(cr, (extents.width/2) * inverse , (dist + ((extents.height/2)* inverse)) * -1);
- cairo_set_source_rgba (cr, 1, 1, 1, 1);
- cairo_fill(cr);
- cairo_rotate(cr, rot);
- }
- cairo_rotate(cr, x*(M_PI/180.));
- if(x%5 == 0) {
- cairo_move_to(cr, 0, half_min-30);
- cairo_line_to(cr, 0, half_min-17);
- } else {
- cairo_move_to(cr, 0, half_min-20);
- cairo_line_to(cr, 0, half_min-15);
- }
- cairo_line_to(cr, 0, half_min-15);
- cairo_set_source_rgba (cr, 0, 0, 0, 0.4);
- cairo_set_line_width (cr,1);
- cairo_stroke(cr);
- cairo_rotate(cr, -x*(M_PI/180.));
- }
- cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
- cairo_translate(cr, -half_w, -half_h);
- cairo_arc(cr, half_w, half_h, half_min-30, 0, 2*M_PI);
- cairo_set_source_rgba (cr, 1, 1, 1, 1);
- cairo_fill(cr);
- cairo_translate(cr, half_w, half_h);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_rotate(cr, start_angle*(M_PI/180.));
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, 0, (half_min-17) * -1);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.25);
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_line_width (cr,5);
- cairo_stroke(cr);
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, 0, (half_min-17) * -1);
- cairo_set_source_rgba (cr, 1, 0, 0, 0.9);
- cairo_set_line_width (cr,1);
- cairo_stroke(cr);
- cairo_rotate(cr, -start_angle*(M_PI/180.));
- cairo_destroy(cr);
- surface_measure = new_backing_store_measure;
-
- cairo_surface_t *new_backing_store_grey = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height);
- cr = cairo_create(new_backing_store_grey);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_set_source_surface(cr, _backing_store, 0, 0);
- cairo_paint(cr);
- Inkscape::Filters::FilterColorMatrix::ColorMatrixMatrix _grayscale_colormatrix = std::vector<gdouble> (grayscale_value_matrix, grayscale_value_matrix + 20);
- cairo_surface_t *out = ink_cairo_surface_create_identical(new_backing_store_grey);
- ink_cairo_surface_filter(new_backing_store_grey, out, _grayscale_colormatrix);
- cairo_set_source_surface(cr, out, 0, 0);
- cairo_surface_destroy(out);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint(cr);
- cairo_destroy(cr);
- surface_origin = new_backing_store_grey;
-}
-
-bool SPCanvas::endRotateTo()
-{
- if (!_backing_store || !started) {
- return false;
- }
- started = false;
- surface_rotated = NULL;
- surface_origin = NULL;
- gtk_widget_queue_draw(GTK_WIDGET(this));
- dirtyAll();
- addIdle();
- rotated = true;
- return true;
-}
-
-void SPCanvas::clearRotateTo()
-{
- if (!started) {
- return;
- }
- gtk_widget_queue_draw(GTK_WIDGET(this));
- dirtyAll();
- addIdle();
-}
-
-void SPCanvas::rotateTo(double angle)
-{
- if (!_backing_store || !started) {
- return;
- }
- GtkAllocation allocation;
- gtk_widget_get_allocation(&_widget, &allocation);
- int half_w = allocation.width/2;
- int half_h = allocation.height/2;
- int half_min = std::min(half_w,half_h);
- cairo_surface_t *new_backing_store = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height);
- cairo_t *cr = cairo_create(new_backing_store);
- cairo_set_source_surface(cr, surface_origin, 0, 0);
- cairo_paint(cr);
- cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
- cairo_paint(cr);
- cairo_pattern_t *source_pattern;
- cairo_matrix_t matrix;
- source_pattern = cairo_pattern_create_for_surface (surface_rotated);
- cairo_matrix_init_identity (&matrix);
- cairo_matrix_translate (&matrix, allocation.width/2.0, allocation.height/2.0);
- cairo_matrix_rotate (&matrix, Geom::rad_from_deg(angle - start_angle) * -1);
- cairo_matrix_translate (&matrix, -allocation.width/2.0, -allocation.height/2.0);
- cairo_pattern_set_matrix (source_pattern, &matrix);
- cairo_set_source(cr, source_pattern);
- cairo_paint(cr);
- cairo_set_source_surface(cr, surface_measure, 0, 0);
- cairo_paint(cr);
- cairo_translate(cr, half_w, half_h);
- cairo_rotate(cr, angle*(M_PI/180.));
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, 0, (half_min-17) * -1);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.25);
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_line_width (cr,5);
- cairo_stroke(cr);
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, 0, (half_min-17) * -1);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.9);
- cairo_set_line_width (cr,1);
- cairo_stroke(cr);
- cairo_move_to(cr, 0, 0);
- cairo_line_to(cr, 0, (half_min-17) * -1);
- cairo_set_source_rgba (cr, 1, 0, 0, 0.9);
- const double dashed[] = {6.0, 3.0};
- int len = sizeof(dashed) / sizeof(dashed[0]);
- cairo_set_dash(cr, dashed, len, 1);
- cairo_stroke(cr);
- cairo_translate(cr, -half_w, -half_h);
- cairo_set_source_rgba (cr, 1, 1, 1, 0.25);
- cairo_arc(cr, half_w, half_h, 7, 0, 2*M_PI);
- cairo_fill(cr);
- cairo_set_source_rgba (cr, 1, 0, 0, 0.7);
- cairo_arc(cr, half_w, half_h, 5, 0, 2*M_PI);
- cairo_fill(cr);
- cairo_translate(cr, half_w, half_h);
- cairo_rotate(cr, -angle*(M_PI/180.));
- cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
- cairo_set_font_size(cr, 15.0);
- cairo_text_extents_t extents;
- std::ostringstream s;
- s << _("Original angle ") << std::fixed << std::setprecision(2) << start_angle << "º";
- cairo_text_extents(cr, s.str().c_str(), &extents);
- cairo_translate(cr, half_w - extents.width -15 ,-half_h + 25);
- cairo_set_source_rgba (cr, 1, 1, 1, 1);
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 25) *-1);
- s.str("");
- s << _("New angle ") << std::fixed << std::setprecision(2) << angle << "º";
- cairo_text_extents(cr, s.str().c_str(), &extents);
- cairo_translate(cr, half_w - extents.width -15 ,-half_h + 45);
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 45) *-1);
- s.str("");
- s << _("Gap ") << std::fixed << std::setprecision(2) << std::abs(start_angle-angle) << "º";
- cairo_text_extents(cr, s.str().c_str(), &extents);
- cairo_translate(cr, half_w - extents.width -15 ,-half_h + 65);
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (half_w - extents.width -15) *-1 ,(-half_h + 65) *-1);
- cairo_translate(cr, -half_w + 10 ,-half_h + 25);
- s.str("");
- cairo_set_font_size(cr, 12.0);
- s << _("Normal mode, 1º round step");
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (-half_w +10) * -1 ,(-half_h + 25) * -1);
- cairo_translate(cr, -half_w + 10 ,-half_h + 40);
- s.str("");
- s << _("+ALT, Fractional degrees");
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 40) * -1);
- cairo_translate(cr, -half_w + 10 ,-half_h + 55);
- s.str("");
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- s << _("+CTRL, ") << 180.0/prefs->getInt("/options/rotationsnapsperpi/value", 12) << _("º round step");
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 55) * -1);
- cairo_translate(cr, -half_w + 10 ,-half_h + 70);
- s.str("");
- s << _("+SHIFT, Reset");
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 70) * -1);
- cairo_translate(cr, -half_w + 10 ,-half_h + 85);
- s.str("");
- s << _("+CTRL+SHIFT, 0º");
- cairo_text_path(cr, s.str().c_str());
- cairo_fill(cr);
- //cairo_translate(cr, (-half_w + 10) * -1 ,(-half_h + 60) * -1);
- cairo_destroy(cr);
- cairo_surface_destroy(_backing_store);
- _backing_store = new_backing_store;
- cairo_pattern_destroy (source_pattern);
- gtk_widget_queue_draw(GTK_WIDGET(this));
- addIdle();
-}
-
void SPCanvas::updateNow()
{
if (_need_update) {
diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h
index 708653bdf..a2cbe0b27 100644
--- a/src/display/sp-canvas.h
+++ b/src/display/sp-canvas.h
@@ -51,7 +51,7 @@ enum {
struct SPCanvasBuf {
cairo_t *ct;
Geom::IntRect rect;
- Geom::IntRect visible_rect;
+ Geom::IntRect canvas_rect; // visible window in world coordinates (i.e. offset by _x0, _y0)
unsigned char *buf;
int buf_rowstride;
@@ -72,10 +72,7 @@ GType sp_canvas_get_type() G_GNUC_CONST;
struct SPCanvas {
/// Scrolls canvas to specific position (c is measured in screen pixels).
void scrollTo(Geom::Point const &c, unsigned int clear, bool is_scrolling = false);
- void startRotateTo(double angle);
- void rotateTo(double angle);
- bool endRotateTo();
- void clearRotateTo();
+
/// Synchronously updates the canvas if necessary.
void updateNow();
@@ -177,8 +174,8 @@ public:
bool _is_dragging;
double _dx0;
double _dy0;
- int _x0; ///< World coordinate of the leftmost pixels
- int _y0; ///< World coordinate of the topmost pixels
+ int _x0; ///< World coordinate of the leftmost pixels of window
+ int _y0; ///< World coordinate of the topmost pixels of window
/// Image surface storing the contents of the widget
cairo_surface_t *_backing_store;
diff --git a/src/document-undo.cpp b/src/document-undo.cpp
index fb1f47312..f36010602 100644
--- a/src/document-undo.cpp
+++ b/src/document-undo.cpp
@@ -281,10 +281,6 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc)
if (ret) INKSCAPE.external_change();
- SPObject *updated = doc->getRoot();
- if (updated && !ret) {
- updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- }
return ret;
}
diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp
index 6c6e2d71e..497f98431 100644
--- a/src/extension/extension.cpp
+++ b/src/extension/extension.cpp
@@ -701,7 +701,7 @@ public:
#endif
this->pack_start(*widg, false, false, 0);
if (tooltip) {
- widg->set_tooltip_text(_(tooltip));
+ widg->set_tooltip_text(tooltip);
} else {
widg->set_tooltip_text("");
widg->set_has_tooltip(false);
@@ -718,7 +718,7 @@ public:
a Gtk::VBox, which is then returned to the calling function.
If there are no visible parameters, this function just returns NULL.
- If all parameters are gui_visible = false NULL is returned as well.
+ If all parameters are gui_hidden = true NULL is returned as well.
*/
Gtk::Widget *
Extension::autogui (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
@@ -732,7 +732,7 @@ Extension::autogui (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<v
//go through the list of parameters to see if there are any non-hidden ones
for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
Parameter * param = reinterpret_cast<Parameter *>(list->data);
- if (param->get_gui_hidden()) continue; //Ignore hidden parameters
+ if (param->get_hidden()) continue; //Ignore hidden parameters
Gtk::Widget * widg = param->get_widget(doc, node, changeSignal);
gchar const * tip = param->get_tooltip();
int indent = param->get_indent();
@@ -837,7 +837,7 @@ unsigned int Extension::param_visible_count ( )
unsigned int _visible_count = 0;
for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
Parameter * param = reinterpret_cast<Parameter *>(list->data);
- if (!param->get_gui_hidden()) _visible_count++;
+ if (!param->get_hidden()) _visible_count++;
}
return _visible_count;
}
diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp
index 8aa982810..d1fe357da 100644
--- a/src/extension/internal/bluredge.cpp
+++ b/src/extension/internal/bluredge.cpp
@@ -131,8 +131,8 @@ BlurEdge::init (void)
"<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
"<name>" N_("Inset/Outset Halo") "</name>\n"
"<id>org.inkscape.effect.bluredge</id>\n"
- "<param name=\"blur-width\" _gui-text=\"" N_("Width:") "\" gui-description=\"" N_("Width in px of the halo") "\" scope=\"document\" type=\"float\" min=\"1.0\" max=\"50.0\">1.0</param>\n"
- "<param name=\"num-steps\" _gui-text=\"" N_("Number of steps:") "\" gui-description=\"" N_("Number of inset/outset copies of the object to make") "\" scope=\"document\" type=\"int\" min=\"5\" max=\"100\">11</param>\n"
+ "<param name=\"blur-width\" _gui-text=\"" N_("Width:") "\" gui-description=\"" N_("Width in px of the halo") "\" type=\"float\" min=\"1.0\" max=\"50.0\">1.0</param>\n"
+ "<param name=\"num-steps\" _gui-text=\"" N_("Number of steps:") "\" gui-description=\"" N_("Number of inset/outset copies of the object to make") "\" type=\"int\" min=\"5\" max=\"100\">11</param>\n"
"<effect>\n"
"<object-type>all</object-type>\n"
"<effects-menu>\n"
diff --git a/src/extension/internal/cairo-png-out.cpp b/src/extension/internal/cairo-png-out.cpp
index 5859a82da..956fcce9a 100644
--- a/src/extension/internal/cairo-png-out.cpp
+++ b/src/extension/internal/cairo-png-out.cpp
@@ -53,10 +53,11 @@ png_render_document_to_file(SPDocument *doc, gchar const *filename)
{
CairoRenderer *renderer;
CairoRenderContext *ctx;
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
+
doc->ensureUpToDate();
/* Start */
+
SPItem *base = doc->getRoot();
Inkscape::Drawing drawing;
unsigned dkey = SPItem::display_key_new(1);
@@ -76,7 +77,6 @@ png_render_document_to_file(SPDocument *doc, gchar const *filename)
renderer->destroyContext(ctx);
base->invoke_hide(dkey);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
/* end */
delete renderer;
diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp
index 809125266..e8f47e79e 100644
--- a/src/extension/internal/cairo-ps-out.cpp
+++ b/src/extension/internal/cairo-ps-out.cpp
@@ -68,7 +68,6 @@ static bool
ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext,
bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, float bleedmargin_px, bool eps = false)
{
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
doc->ensureUpToDate();
SPItem *base = NULL;
@@ -85,10 +84,9 @@ ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int l
pageBoundingBox = !exportDrawing;
}
- if (!base) {
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
+ if (!base)
return false;
- }
+
Inkscape::Drawing drawing;
unsigned dkey = SPItem::display_key_new(1);
base->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY);
@@ -117,7 +115,6 @@ ps_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int l
renderer->destroyContext(ctx);
delete renderer;
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return ret;
}
diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp
index 5558fe1ad..5576676b2 100644
--- a/src/extension/internal/cairo-renderer-pdf-out.cpp
+++ b/src/extension/internal/cairo-renderer-pdf-out.cpp
@@ -61,7 +61,6 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int
bool texttopath, bool omittext, bool filtertobitmap, int resolution,
const gchar * const exportId, bool exportDrawing, bool exportCanvas, float bleedmargin_px)
{
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
doc->ensureUpToDate();
/* Start */
@@ -81,7 +80,6 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int
}
if (!base) {
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return false;
}
@@ -114,7 +112,7 @@ pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int
renderer->destroyContext(ctx);
delete renderer;
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
+
return ret;
}
diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp
index 70bf84ef4..b94408b36 100644
--- a/src/extension/internal/cdr-input.cpp
+++ b/src/extension/internal/cdr-input.cpp
@@ -210,6 +210,19 @@ void CdrImportDialog::_setPreviewPage()
}
SPDocument *doc = SPDocument::createNewDocFromMem(_vec[_current_page-1].cstr(), strlen(_vec[_current_page-1].cstr()), 0);
+ if(!doc) {
+ g_warning("CDR import: Could not create preview for page %d", _current_page);
+ gchar const *no_preview_template =
+ "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
+ " <path style='fill:none;stroke:#ff0000;stroke-width:2px;' d='M 82,10 18,74 m 0,-64 64,64' />"
+ " <rect style='fill:none;stroke:#000000;stroke-width:1.5px;' width='64' height='64' x='18' y='10' />"
+ " <text x='50' y='92' style='font-size:10px;text-anchor:middle;font-family:sans-serif;'>%s</text>"
+ "</svg>";
+ gchar * no_preview = g_strdup_printf(no_preview_template, _("No preview"));
+ doc = SPDocument::createNewDocFromMem(no_preview, strlen(no_preview), 0);
+ g_free(no_preview);
+ }
+
Gtk::Widget * tmpPreviewArea = Glib::wrap(sp_svg_view_widget_new(doc));
std::swap(_previewArea, tmpPreviewArea);
delete tmpPreviewArea;
diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp
index 198c18ff2..92deb2e19 100644
--- a/src/extension/internal/emf-inout.cpp
+++ b/src/extension/internal/emf-inout.cpp
@@ -94,7 +94,7 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename)
const gchar *oldconst;
gchar *oldoutput;
unsigned int ret;
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
+
doc->ensureUpToDate();
mod = Inkscape::Extension::get_print(PRINT_EMF);
@@ -114,7 +114,6 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename)
/* Print document */
ret = mod->begin(doc);
if (ret) {
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
g_free(oldoutput);
throw Inkscape::Extension::Output::save_failed();
}
@@ -128,7 +127,7 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename)
mod->set_param_string("destination", oldoutput);
g_free(oldoutput);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
+
return;
}
@@ -166,8 +165,16 @@ Emf::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena
ext->set_param_bool("FixImageRot",new_FixImageRot);
ext->set_param_bool("textToPath", new_val);
+ // ensure usage of dot as decimal separator in scanf/printf functions (indepentendly of current locale)
+ char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL));
+ setlocale(LC_NUMERIC, "C");
+
print_document_to_file(doc, filename);
+ // restore decimal separator used in scanf/printf functions to initial value
+ setlocale(LC_NUMERIC, oldlocale);
+ g_free(oldlocale);
+
return;
}
@@ -3525,6 +3532,10 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
return NULL;
}
+ // ensure usage of dot as decimal separator in scanf/printf functions (indepentendly of current locale)
+ char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL));
+ setlocale(LC_NUMERIC, "C");
+
EMF_CALLBACK_DATA d;
d.n_obj = 0; //these might not be set otherwise if the input file is corrupt
@@ -3589,6 +3600,10 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
// in earlier versions no viewbox was generated and a call to setViewBoxIfMissing() was needed here.
+ // restore decimal separator used in scanf/printf functions to initial value
+ setlocale(LC_NUMERIC, oldlocale);
+ g_free(oldlocale);
+
return doc;
}
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index 826176bc0..147324b4f 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -251,11 +251,7 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1");
}
- char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL));
- setlocale(LC_NUMERIC, "C");
snprintf(buff, sizeof(buff) - 1, "Drawing=%.1fx%.1fpx, %.1fx%.1fmm", _width, _height, Inkscape::Util::Quantity::convert(dwInchesX, "in", "mm"), Inkscape::Util::Quantity::convert(dwInchesY, "in", "mm"));
- setlocale(LC_NUMERIC, oldlocale);
- g_free(oldlocale);
rec = textcomment_set(buff);
if (!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)) {
g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1");
diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp
index c95434939..d7ad7e6f7 100644
--- a/src/extension/internal/javafx-out.cpp
+++ b/src/extension/internal/javafx-out.cpp
@@ -843,8 +843,7 @@ void JavaFXOutput::reset()
bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
{
reset();
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
- doc->ensureUpToDate();
+
name = Glib::path_get_basename(filename_utf8);
int pos = name.find('.');
@@ -857,14 +856,12 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
//# Lets do the curves first, to get the stats
if (!doTree(doc)) {
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return false;
}
String curveBuf = outbuf;
outbuf.clear();
if (!doHeader()) {
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return false;
}
@@ -878,7 +875,6 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
doBody(doc, doc->getRoot());
if (!doTail()) {
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return false;
}
@@ -888,7 +884,6 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
FILE *f = Inkscape::IO::fopen_utf8name(filename_utf8, "w");
if (!f)
{
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
err("Could open JavaFX file '%s' for writing", filename_utf8);
return false;
}
@@ -899,7 +894,7 @@ bool JavaFXOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
}
fclose(f);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
+
return true;
}
diff --git a/src/extension/internal/latex-pstricks-out.cpp b/src/extension/internal/latex-pstricks-out.cpp
index aa6ea6963..3ce2c5531 100644
--- a/src/extension/internal/latex-pstricks-out.cpp
+++ b/src/extension/internal/latex-pstricks-out.cpp
@@ -49,7 +49,6 @@ bool LatexOutput::check(Inkscape::Extension::Extension * /*module*/)
void LatexOutput::save(Inkscape::Extension::Output * /*mod2*/, SPDocument *doc, gchar const *filename)
{
SPPrintContext context;
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
doc->ensureUpToDate();
Inkscape::Extension::Print *mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_LATEX);
@@ -77,7 +76,6 @@ void LatexOutput::save(Inkscape::Extension::Output * /*mod2*/, SPDocument *doc,
mod->set_param_string("destination", oldoutput);
g_free(oldoutput);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
}
#include "clear-n_.h"
diff --git a/src/extension/internal/metafile-print.cpp b/src/extension/internal/metafile-print.cpp
index 11567ceb3..68a425d85 100644
--- a/src/extension/internal/metafile-print.cpp
+++ b/src/extension/internal/metafile-print.cpp
@@ -355,27 +355,6 @@ int PrintMetafile::hold_gradient(void *gr, int mode)
return 1;
}
-/* behaves like snprintf() but makes sure decimal separators are formatted as dots
- otherwise invalid strings can be produced depending on the set locale
-*/
-int PrintMetafile::snprintf_dots(char * s, size_t n, const char * format, ...)
-{
- int nChars;
-
- char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL));
- setlocale(LC_NUMERIC, "C");
-
- va_list argptr;
- va_start(argptr, format);
- nChars = vsnprintf(s, n, format, argptr);
- va_end(argptr);
-
- setlocale(LC_NUMERIC, oldlocale);
- g_free(oldlocale);
-
- return nChars;
-}
-
/* convert from center ellipse to SVGEllipticalArc ellipse
From:
@@ -411,7 +390,7 @@ Geom::PathVector PrintMetafile::center_ellipse_as_SVG_PathV(Geom::Point ctr, dou
y2 = ctr[Y] + sin(F) * rx * cos(M_PI) + cos(F) * ry * sin(M_PI);
char text[256];
- snprintf_dots(text, 256, " M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z",
+ snprintf(text, 256, " M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z",
x1, y1, rx, ry, F * 360. / (2.*M_PI), x2, y2, rx, ry, F * 360. / (2.*M_PI), x1, y1);
Geom::PathVector outres = Geom::parse_svg_path(text);
return outres;
@@ -440,7 +419,7 @@ Geom::PathVector PrintMetafile::center_elliptical_ring_as_SVG_PathV(Geom::Point
y22 = ctr[Y] + sin(F) * rx2 * cos(M_PI) + cos(F) * ry2 * sin(M_PI);
char text[512];
- snprintf_dots(text, 512, " M %f,%f A %f %f %f 0 1 %f %f A %f %f %f 0 1 %f %f z M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z",
+ snprintf(text, 512, " M %f,%f A %f %f %f 0 1 %f %f A %f %f %f 0 1 %f %f z M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z",
x11, y11, rx1, ry1, degrot, x12, y12, rx1, ry1, degrot, x11, y11,
x21, y21, rx2, ry2, degrot, x22, y22, rx2, ry2, degrot, x21, y21);
Geom::PathVector outres = Geom::parse_svg_path(text);
@@ -462,7 +441,7 @@ Geom::PathVector PrintMetafile::center_elliptical_hole_as_SVG_PathV(Geom::Point
y2 = ctr[Y] + sin(F) * rx * cos(M_PI) + cos(F) * ry * sin(M_PI);
char text[256];
- snprintf_dots(text, 256, " M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z M 50000,50000 50000,-50000 -50000,-50000 -50000,50000 z",
+ snprintf(text, 256, " M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z M 50000,50000 50000,-50000 -50000,-50000 -50000,50000 z",
x1, y1, rx, ry, F * 360. / (2.*M_PI), x2, y2, rx, ry, F * 360. / (2.*M_PI), x1, y1);
Geom::PathVector outres = Geom::parse_svg_path(text);
return outres;
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp
index 66d370357..f885ef5e5 100644
--- a/src/extension/internal/odf.cpp
+++ b/src/extension/internal/odf.cpp
@@ -72,7 +72,6 @@
#include "sp-path.h"
#include "sp-text.h"
#include "sp-flowtext.h"
-#include "sp-root.h"
#include "svg/svg.h"
#include "text-editing.h"
#include "util/units.h"
@@ -2096,8 +2095,7 @@ void OdfOutput::reset()
void OdfOutput::save(Inkscape::Extension::Output */*mod*/, SPDocument *doc, gchar const *filename)
{
reset();
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
- doc->ensureUpToDate();
+
documentUri = Inkscape::URI(filename);
ZipFile zf;
@@ -2106,30 +2104,25 @@ void OdfOutput::save(Inkscape::Extension::Output */*mod*/, SPDocument *doc, gcha
if (!writeManifest(zf))
{
g_warning("Failed to write manifest");
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
if (!writeContent(zf, doc->rroot))
{
g_warning("Failed to write content");
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
if (!writeMeta(zf))
{
g_warning("Failed to write metafile");
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
if (!zf.writeFile(filename))
{
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
}
diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp
index 03a2ecd62..8df883069 100644
--- a/src/extension/internal/pov-out.cpp
+++ b/src/extension/internal/pov-out.cpp
@@ -616,13 +616,11 @@ void PovOutput::reset()
void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
{
reset();
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
- doc->ensureUpToDate();
+
//###### SAVE IN POV FORMAT TO BUFFER
//# Lets do the curves first, to get the stats
if (!doTree(doc))
{
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
err("Could not output curves for %s", filename_utf8);
return;
}
@@ -632,7 +630,6 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
if (!doHeader())
{
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
err("Could not write header for %s", filename_utf8);
return;
}
@@ -641,7 +638,6 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
if (!doTail())
{
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
err("Could not write footer for %s", filename_utf8);
return;
}
@@ -652,11 +648,9 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
//###### WRITE TO FILE
Inkscape::IO::dump_fopen_call(filename_utf8, "L");
FILE *f = Inkscape::IO::fopen_utf8name(filename_utf8, "w");
- if (!f){
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
+ if (!f)
return;
- }
-
+
for (String::iterator iter = outbuf.begin() ; iter!=outbuf.end(); ++iter)
{
int ch = *iter;
@@ -664,7 +658,6 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
}
fclose(f);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
}
diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp
index b7277b99e..c1cfb5cc6 100644
--- a/src/extension/internal/vsd-input.cpp
+++ b/src/extension/internal/vsd-input.cpp
@@ -146,7 +146,7 @@ VsdImportDialog::VsdImportDialog(const std::vector<RVNGString> &vec)
_page_selector_box->pack_start(*_labelTotalPages, Gtk::PACK_SHRINK);
vbox1->pack_end(*_page_selector_box, Gtk::PACK_SHRINK);
-
+
// Buttons
cancelbutton = Gtk::manage(new Gtk::Button(_("_Cancel"), true));
okbutton = Gtk::manage(new Gtk::Button(_("_OK"), true));
@@ -211,6 +211,19 @@ void VsdImportDialog::_setPreviewPage()
}
SPDocument *doc = SPDocument::createNewDocFromMem(_vec[_current_page-1].cstr(), strlen(_vec[_current_page-1].cstr()), 0);
+ if(!doc) {
+ g_warning("VSD import: Could not create preview for page %d", _current_page);
+ gchar const *no_preview_template =
+ "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
+ " <path style='fill:none;stroke:#ff0000;stroke-width:2px;' d='M 82,10 18,74 m 0,-64 64,64' />"
+ " <rect style='fill:none;stroke:#000000;stroke-width:1.5px;' width='64' height='64' x='18' y='10' />"
+ " <text x='50' y='92' style='font-size:10px;text-anchor:middle;font-family:sans-serif;'>%s</text>"
+ "</svg>";
+ gchar * no_preview = g_strdup_printf(no_preview_template, _("No preview"));
+ doc = SPDocument::createNewDocFromMem(no_preview, strlen(no_preview), 0);
+ g_free(no_preview);
+ }
+
Gtk::Widget * tmpPreviewArea = Glib::wrap(sp_svg_view_widget_new(doc));
std::swap(_previewArea, tmpPreviewArea);
delete tmpPreviewArea;
diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp
index 42ec2f2bb..e2d1433e4 100644
--- a/src/extension/internal/wmf-inout.cpp
+++ b/src/extension/internal/wmf-inout.cpp
@@ -95,7 +95,7 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename)
SPPrintContext context;
const gchar *oldconst;
gchar *oldoutput;
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
+
doc->ensureUpToDate();
mod = Inkscape::Extension::get_print(PRINT_WMF);
@@ -115,7 +115,6 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename)
/* Print document */
if (mod->begin(doc)) {
g_free(oldoutput);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
throw Inkscape::Extension::Output::save_failed();
}
mod->base->invoke_print(&context);
@@ -128,7 +127,7 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename)
mod->set_param_string("destination", oldoutput);
g_free(oldoutput);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
+
return;
}
@@ -136,8 +135,6 @@ Wmf::print_document_to_file(SPDocument *doc, const gchar *filename)
void
Wmf::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filename)
{
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
- doc->ensureUpToDate();
Inkscape::Extension::Extension * ext;
ext = Inkscape::Extension::db.get(PRINT_WMF);
@@ -164,8 +161,16 @@ Wmf::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena
ext->set_param_bool("FixPPTPatternAsHatch",new_FixPPTPatternAsHatch);
ext->set_param_bool("textToPath", new_val);
+ // ensure usage of dot as decimal separator in scanf/printf functions (indepentendly of current locale)
+ char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL));
+ setlocale(LC_NUMERIC, "C");
+
print_document_to_file(doc, filename);
+ // restore decimal separator used in scanf/printf functions to initial value
+ setlocale(LC_NUMERIC, oldlocale);
+ g_free(oldlocale);
+
return;
}
@@ -3100,6 +3105,10 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
return NULL;
}
+ // ensure usage of dot as decimal separator in scanf/printf functions (indepentendly of current locale)
+ char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL));
+ setlocale(LC_NUMERIC, "C");
+
WMF_CALLBACK_DATA d;
d.n_obj = 0; //these might not be set otherwise if the input file is corrupt
@@ -3180,6 +3189,10 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
// in earlier versions no viewbox was generated and a call to setViewBoxIfMissing() was needed here.
+ // restore decimal separator used in scanf/printf functions to initial value
+ setlocale(LC_NUMERIC, oldlocale);
+ g_free(oldlocale);
+
return doc;
}
diff --git a/src/extension/param/bool.cpp b/src/extension/param/bool.cpp
index 9f8d3dcc0..2c7e32480 100644
--- a/src/extension/param/bool.cpp
+++ b/src/extension/param/bool.cpp
@@ -14,7 +14,6 @@
#include <gtkmm/box.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/checkbutton.h>
-#include <glib/gi18n.h>
#include "xml/node.h"
#include "../extension.h"
@@ -25,15 +24,13 @@ namespace Inkscape {
namespace Extension {
ParamBool::ParamBool(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(false)
{
const char * defaultval = NULL;
@@ -129,14 +126,14 @@ void ParamBool::string(std::string &string) const
Gtk::Widget *ParamBool::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
auto hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, Parameter::GUI_PARAM_WIDGETS_SPACING));
hbox->set_homogeneous(false);
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START));
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START));
label->show();
hbox->pack_end(*label, true, true);
diff --git a/src/extension/param/bool.h b/src/extension/param/bool.h
index 0af12b105..826a98927 100644
--- a/src/extension/param/bool.h
+++ b/src/extension/param/bool.h
@@ -33,11 +33,9 @@ public:
* Use the superclass' allocator and set the \c _value.
*/
ParamBool(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml);
diff --git a/src/extension/param/color.cpp b/src/extension/param/color.cpp
index fd88e9adb..035c43ba8 100644
--- a/src/extension/param/color.cpp
+++ b/src/extension/param/color.cpp
@@ -53,15 +53,13 @@ guint32 ParamColor::set( guint32 in, SPDocument * /*doc*/, Inkscape::XML::Node *
}
ParamColor::ParamColor(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _changeSignal(0)
{
const char * defaulthex = NULL;
@@ -94,7 +92,7 @@ Gtk::Widget *ParamColor::get_widget( SPDocument * /*doc*/, Inkscape::XML::Node *
{
using Inkscape::UI::Widget::ColorNotebook;
- if (_gui_hidden) return NULL;
+ if (_hidden) return NULL;
if (changeSignal) {
_changeSignal = new sigc::signal<void>(*changeSignal);
diff --git a/src/extension/param/color.h b/src/extension/param/color.h
index d6e9d1fbe..890f5ba5f 100644
--- a/src/extension/param/color.h
+++ b/src/extension/param/color.h
@@ -32,11 +32,9 @@ private:
sigc::connection _color_changed;
public:
ParamColor(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml);
diff --git a/src/extension/param/description.cpp b/src/extension/param/description.cpp
index 3c29b7c49..cf94918f7 100644
--- a/src/extension/param/description.cpp
+++ b/src/extension/param/description.cpp
@@ -17,6 +17,7 @@
#include <gtkmm/label.h>
#include <glibmm/i18n.h>
#include <glibmm/markup.h>
+#include <glibmm/regex.h>
#include "xml/node.h"
#include "extension/extension.h"
@@ -28,30 +29,59 @@ namespace Extension {
/** \brief Initialize the object, to do that, copy the data. */
ParamDescription::ParamDescription(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
AppearanceMode mode)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(NULL)
, _mode(mode)
{
- // printf("Building Description\n");
- const char * defaultval = NULL;
- if (xml->firstChild() != NULL) {
- defaultval = xml->firstChild()->content();
+ // construct the text content by concatenating all (non-empty) text nodes,
+ // removing all other nodes (e.g. comment nodes) and replacing <extension:br> elements with "<br/>"
+ Glib::ustring value;
+ Inkscape::XML::Node * cur_child = xml->firstChild();
+ while (cur_child != NULL) {
+ if (cur_child->type() == XML::TEXT_NODE && cur_child->content() != NULL) {
+ value += cur_child->content();
+ } else if (cur_child->type() == XML::ELEMENT_NODE && !g_strcmp0(cur_child->name(), "extension:br")) {
+ value += "<br/>";
+ }
+ cur_child = cur_child->next();
}
- if (defaultval != NULL) {
- _value = g_strdup(defaultval);
+ // if there is no text content we can return immediately (the description will be invisible)
+ if (value == Glib::ustring("")) {
+ return;
}
- _context = xml->attribute("msgctxt");
+ // do replacements in the source string to account for the attribute xml:space="preserve"
+ // (those should match replacements potentially performed by xgettext to allow for proper translation)
+ if (g_strcmp0(xml->attribute("xml:space"), "preserve") == 0) {
+ // xgettext copies the source string verbatim in this case, so no changes needed
+ } else {
+ // remove all whitespace from start/end of string and replace intermediate whitespace with a single space
+ value = Glib::Regex::create("^\\s+|\\s+$")->replace_literal(value, 0, "", (Glib::RegexMatchFlags)0);
+ value = Glib::Regex::create("\\s+")->replace_literal(value, 0, " ", (Glib::RegexMatchFlags)0);
+ }
+
+ // translate if underscored version (_param) was used
+ if (g_str_has_prefix(xml->name(), "extension:_")) {
+ const gchar * context = xml->attribute("msgctxt");
+ if (context != NULL) {
+ value = g_dpgettext2(NULL, context, value.c_str());
+ } else {
+ value = _(value.c_str());
+ }
+ }
+
+ // finally replace all remaining <br/> with a real newline character
+ value = Glib::Regex::create("<br/>")->replace_literal(value, 0, "\n", (Glib::RegexMatchFlags)0);
+
+ _value = g_strdup(value.c_str());
return;
}
@@ -60,31 +90,25 @@ ParamDescription::ParamDescription(const gchar * name,
Gtk::Widget *
ParamDescription::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * /*changeSignal*/)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
if (_value == NULL) {
return NULL;
}
- Glib::ustring newguitext;
-
- if (_context != NULL) {
- newguitext = g_dpgettext2(NULL, _context, _value);
- } else {
- newguitext = _(_value);
- }
+ Glib::ustring newtext = _value;
Gtk::Label * label = Gtk::manage(new Gtk::Label());
if (_mode == HEADER) {
- label->set_markup(Glib::ustring("<b>") + Glib::Markup::escape_text(newguitext) + Glib::ustring("</b>"));
+ label->set_markup(Glib::ustring("<b>") + Glib::Markup::escape_text(newtext) + Glib::ustring("</b>"));
label->set_margin_top(5);
label->set_margin_bottom(5);
} else if (_mode == URL) {
- Glib::ustring escaped_url = Glib::Markup::escape_text(newguitext);
+ Glib::ustring escaped_url = Glib::Markup::escape_text(newtext);
label->set_markup(Glib::ustring::compose("<a href='%1'>%1</a>", escaped_url));
} else {
- label->set_text(newguitext);
+ label->set_text(newtext);
}
label->set_line_wrap();
#if (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 16)
@@ -101,7 +125,7 @@ ParamDescription::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node
// - Here we set a lower limit of GUI_MAX_LINE_LENGTH characters per line that long texts will always use
// This means texts can not shrink anymore (they can still grow, though) and it's also necessary
// to prevent https://bugzilla.gnome.org/show_bug.cgi?id=773572
- int len = newguitext.length();
+ int len = newtext.length();
label->set_width_chars(len > Parameter::GUI_MAX_LINE_LENGTH ? Parameter::GUI_MAX_LINE_LENGTH : len);
label->show();
diff --git a/src/extension/param/description.h b/src/extension/param/description.h
index c6c5f4013..599c4db78 100644
--- a/src/extension/param/description.h
+++ b/src/extension/param/description.h
@@ -27,14 +27,12 @@ namespace Extension {
class ParamDescription : public Parameter {
public:
enum AppearanceMode {
- DESC, HEADER, URL
+ DESCRIPTION, HEADER, URL
};
ParamDescription(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
@@ -45,7 +43,6 @@ private:
/** \brief Internal value. */
gchar * _value;
AppearanceMode _mode;
- const gchar* _context;
};
} /* namespace Extension */
diff --git a/src/extension/param/enum.cpp b/src/extension/param/enum.cpp
index a26458c35..7cd860465 100644
--- a/src/extension/param/enum.cpp
+++ b/src/extension/param/enum.cpp
@@ -33,29 +33,27 @@ namespace Inkscape {
namespace Extension {
/* For internal use only.
- Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
+ Note that value and text MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
class enumentry {
public:
enumentry (Glib::ustring &val, Glib::ustring &text) :
value(val),
- guitext(text)
+ text(text)
{}
Glib::ustring value;
- Glib::ustring guitext;
+ Glib::ustring text;
};
ParamComboBox::ParamComboBox(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(NULL)
, choices(NULL)
{
@@ -66,7 +64,7 @@ ParamComboBox::ParamComboBox(const gchar * name,
for (Inkscape::XML::Node *node = xml->firstChild(); node; node = node->next()) {
char const * chname = node->name();
if (!strcmp(chname, INKSCAPE_EXTENSION_NS "item") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) {
- Glib::ustring newguitext, newvalue;
+ Glib::ustring newtext, newvalue;
const char * contents = NULL;
if (node->firstChild()) {
contents = node->firstChild()->content();
@@ -77,12 +75,12 @@ ParamComboBox::ParamComboBox(const gchar * name,
// still need to include if are to be localized
if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) {
if (node->attribute("msgctxt") != NULL) {
- newguitext = g_dpgettext2(NULL, node->attribute("msgctxt"), contents);
+ newtext = g_dpgettext2(NULL, node->attribute("msgctxt"), contents);
} else {
- newguitext = _(contents);
+ newtext = _(contents);
}
} else {
- newguitext = contents;
+ newtext = contents;
}
} else
continue;
@@ -94,8 +92,8 @@ ParamComboBox::ParamComboBox(const gchar * name,
newvalue = contents;
}
- if ( (!newguitext.empty()) && (!newvalue.empty()) ) { // logical error if this is not true here
- choices = g_slist_append( choices, new enumentry(newvalue, newguitext) );
+ if ( (!newtext.empty()) && (!newvalue.empty()) ) { // logical error if this is not true here
+ choices = g_slist_append( choices, new enumentry(newvalue, newtext) );
}
}
}
@@ -155,7 +153,7 @@ const gchar *ParamComboBox::set(const gchar * in, SPDocument * /*doc*/, Inkscape
Glib::ustring settext;
for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
enumentry * entr = reinterpret_cast<enumentry *>(list->data);
- if ( !entr->guitext.compare(in) ) {
+ if ( !entr->text.compare(in) ) {
settext = entr->value;
break; // break out of for loop
}
@@ -175,20 +173,20 @@ const gchar *ParamComboBox::set(const gchar * in, SPDocument * /*doc*/, Inkscape
}
/**
- * function to test if \c guitext is selectable
+ * function to test if \c text is selectable
*/
-bool ParamComboBox::contains(const gchar * guitext, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const
+bool ParamComboBox::contains(const gchar * text, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const
{
- if (guitext == NULL) {
+ if (text == NULL) {
return false; /* Can't have NULL string */
}
for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
enumentry * entr = reinterpret_cast<enumentry *>(list->data);
- if ( !entr->guitext.compare(guitext) )
+ if ( !entr->text.compare(text) )
return true;
}
- // if we did not find the guitext in this ParamComboBox:
+ // if we did not find the text in this ParamComboBox:
return false;
}
@@ -246,12 +244,12 @@ ParamComboBoxEntry::changed (void)
*/
Gtk::Widget *ParamComboBox::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING));
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START));
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START));
label->show();
hbox->pack_start(*label, false, false);
@@ -260,11 +258,11 @@ Gtk::Widget *ParamComboBox::get_widget(SPDocument * doc, Inkscape::XML::Node * n
Glib::ustring settext;
for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
enumentry * entr = reinterpret_cast<enumentry *>(list->data);
- Glib::ustring text = entr->guitext;
+ Glib::ustring text = entr->text;
combo->append(text);
if ( _value && !entr->value.compare(_value) ) {
- settext = entr->guitext;
+ settext = entr->text;
}
}
if (!settext.empty()) {
diff --git a/src/extension/param/enum.h b/src/extension/param/enum.h
index f9d3d75f7..143a648d7 100644
--- a/src/extension/param/enum.h
+++ b/src/extension/param/enum.h
@@ -38,11 +38,9 @@ private:
public:
ParamComboBox(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml);
@@ -60,9 +58,9 @@ public:
const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
/**
- * @returns true if guitext is part of this enum
+ * @returns true if text is part of this enum
*/
- bool contains(const gchar * guitext, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const;
+ bool contains(const gchar * text, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const;
void changed (void);
}; /* class ParamComboBox */
diff --git a/src/extension/param/float.cpp b/src/extension/param/float.cpp
index e3fdba826..69283a572 100644
--- a/src/extension/param/float.cpp
+++ b/src/extension/param/float.cpp
@@ -15,7 +15,6 @@
#include <gtkmm/scale.h>
#include "ui/widget/spinbutton.h"
#include "ui/widget/spin-scale.h"
-#include <glib/gi18n.h>
#include "xml/node.h"
#include "extension/extension.h"
@@ -28,16 +27,14 @@ namespace Extension {
/** Use the superclass' allocator and set the \c _value. */
ParamFloat::ParamFloat(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
AppearanceMode mode)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(0.0)
, _mode(mode)
, _min(0.0)
@@ -170,7 +167,7 @@ void ParamFloatAdjustment::val_changed(void)
*/
Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
@@ -181,7 +178,7 @@ Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * nod
if (_mode == FULL) {
- UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_(_text), fadjust, _precision);
+ UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_text, fadjust, _precision);
scale->set_size_request(400, -1);
scale->show();
hbox->pack_start(*scale, true, true);
@@ -189,7 +186,7 @@ Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * nod
}
else if (_mode == MINIMAL) {
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START));
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START));
label->show();
hbox->pack_start(*label, true, true);
diff --git a/src/extension/param/float.h b/src/extension/param/float.h
index 7fd86cea7..d58253ccb 100644
--- a/src/extension/param/float.h
+++ b/src/extension/param/float.h
@@ -30,11 +30,9 @@ public:
FULL, MINIMAL
};
ParamFloat(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
diff --git a/src/extension/param/int.cpp b/src/extension/param/int.cpp
index 538ddc08d..357f98590 100644
--- a/src/extension/param/int.cpp
+++ b/src/extension/param/int.cpp
@@ -15,7 +15,6 @@
#include <gtkmm/scale.h>
#include "ui/widget/spinbutton.h"
#include "ui/widget/spin-scale.h"
-#include <glib/gi18n.h>
#include "xml/node.h"
#include "extension/extension.h"
@@ -28,16 +27,14 @@ namespace Extension {
/** Use the superclass' allocator and set the \c _value. */
ParamInt::ParamInt(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
AppearanceMode mode)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(0)
, _mode(mode)
, _min(0)
@@ -151,7 +148,7 @@ void ParamIntAdjustment::val_changed(void)
Gtk::Widget *
ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
@@ -162,14 +159,13 @@ ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal
if (_mode == FULL) {
- UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_(_text), fadjust, 0);
+ UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_text, fadjust, 0);
scale->set_size_request(400, -1);
scale->show();
hbox->pack_start(*scale, true, true);
}
else if (_mode == MINIMAL) {
-
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START));
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START));
label->show();
hbox->pack_start(*label, true, true);
diff --git a/src/extension/param/int.h b/src/extension/param/int.h
index 40c0395ec..fcb1ef3f1 100644
--- a/src/extension/param/int.h
+++ b/src/extension/param/int.h
@@ -30,11 +30,9 @@ public:
FULL, MINIMAL
};
ParamInt(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
diff --git a/src/extension/param/notebook.cpp b/src/extension/param/notebook.cpp
index de86d1005..4e94b5216 100644
--- a/src/extension/param/notebook.cpp
+++ b/src/extension/param/notebook.cpp
@@ -55,31 +55,27 @@ public:
static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext);
ParamNotebookPage(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml);
~ParamNotebookPage(void);
Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
void paramString (std::list <std::string> &list);
- gchar * get_guitext (void) {return _text;};
+ gchar * get_text (void) {return _text;};
Parameter * get_param (const gchar * name);
}; /* class ParamNotebookPage */
ParamNotebookPage::ParamNotebookPage(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, /*indent*/ 0, ext)
+ : Parameter(name, text, description, hidden, /*indent*/ 0, ext)
{
parameters = NULL;
@@ -151,30 +147,23 @@ ParamNotebookPage *
ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
{
const char * name;
- const char * guitext;
- const char * desc;
- const char * scope_str;
- Parameter::_scope_t scope = Parameter::SCOPE_USER;
- bool gui_hidden = false;
- const char * gui_hide;
- const char * gui_tip;
+ const char * text;
+ const char * description;
+ bool hidden = false;
+ const char * hide;
name = in_repr->attribute("name");
- guitext = in_repr->attribute("gui-text");
- if (guitext == NULL)
- guitext = in_repr->attribute("_gui-text");
- gui_tip = in_repr->attribute("gui-tip");
- if (gui_tip == NULL)
- gui_tip = in_repr->attribute("_gui-tip");
- desc = in_repr->attribute("gui-description");
- if (desc == NULL)
- desc = in_repr->attribute("_gui-description");
- scope_str = in_repr->attribute("scope");
- gui_hide = in_repr->attribute("gui-hidden");
- if (gui_hide != NULL) {
- if (strcmp(gui_hide, "1") == 0 ||
- strcmp(gui_hide, "true") == 0) {
- gui_hidden = true;
+ text = in_repr->attribute("gui-text");
+ if (text == NULL)
+ text = in_repr->attribute("_gui-text");
+ description = in_repr->attribute("gui-description");
+ if (description == NULL)
+ description = in_repr->attribute("_gui-description");
+ hide = in_repr->attribute("gui-hidden");
+ if (hide != NULL) {
+ if (strcmp(hide, "1") == 0 ||
+ strcmp(hide, "true") == 0) {
+ hidden = true;
}
/* else stays false */
}
@@ -184,17 +173,7 @@ ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension:
return NULL;
}
- if (scope_str != NULL) {
- if (!strcmp(scope_str, "user")) {
- scope = Parameter::SCOPE_USER;
- } else if (!strcmp(scope_str, "document")) {
- scope = Parameter::SCOPE_DOCUMENT;
- } else if (!strcmp(scope_str, "node")) {
- scope = Parameter::SCOPE_NODE;
- }
- }
-
- ParamNotebookPage * page = new ParamNotebookPage(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ ParamNotebookPage * page = new ParamNotebookPage(name, text, description, hidden, in_ext, in_repr);
/* Note: page could equal NULL */
return page;
@@ -209,7 +188,7 @@ ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension:
*/
Gtk::Widget * ParamNotebookPage::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
@@ -232,7 +211,7 @@ Gtk::Widget * ParamNotebookPage::get_widget(SPDocument * doc, Inkscape::XML::Nod
gchar const * tip = param->get_tooltip();
if (tip) {
- widg->set_tooltip_text(_(tip));
+ widg->set_tooltip_text(tip);
} else {
widg->set_tooltip_text("");
widg->set_has_tooltip(false);
@@ -247,15 +226,13 @@ Gtk::Widget * ParamNotebookPage::get_widget(SPDocument * doc, Inkscape::XML::Nod
ParamNotebook::ParamNotebook(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
{
pages = NULL;
@@ -446,7 +423,7 @@ Parameter *ParamNotebookPage::get_param(const gchar * name)
*/
Gtk::Widget * ParamNotebook::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
@@ -459,7 +436,7 @@ Gtk::Widget * ParamNotebook::get_widget(SPDocument * doc, Inkscape::XML::Node *
i++;
ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);
Gtk::Widget * widg = page->get_widget(doc, node, changeSignal);
- nb->append_page(*widg, _(page->get_guitext()));
+ nb->append_page(*widg, _(page->get_text()));
if (!strcmp(_value, page->name())) {
pagenr = i; // this is the page to be displayed?
}
diff --git a/src/extension/param/notebook.h b/src/extension/param/notebook.h
index 278c4de12..8475de61d 100644
--- a/src/extension/param/notebook.h
+++ b/src/extension/param/notebook.h
@@ -42,11 +42,9 @@ private:
notebook */
public:
ParamNotebook(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml);
diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp
index 0eb491078..5c4fe591f 100644
--- a/src/extension/param/parameter.cpp
+++ b/src/extension/param/parameter.cpp
@@ -62,25 +62,39 @@ Parameter *Parameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Ex
}
}
- const char *guitext = in_repr->attribute("gui-text");
- if (guitext == NULL) {
- guitext = in_repr->attribute("_gui-text");
- }
- const char *gui_tip = in_repr->attribute("gui-tip");
- if (gui_tip == NULL) {
- gui_tip = in_repr->attribute("_gui-tip");
+ const char *text = in_repr->attribute("gui-text");
+ if (text == NULL) {
+ text = in_repr->attribute("_gui-text");
+ if (text == NULL) {
+ // text = ""; // propably better to require devs to explicitly set an empty gui-text if this is what they want
+ } else {
+ const char *context = in_repr->attribute("msgctxt");
+ if (context != NULL) {
+ text = g_dpgettext2(NULL, context, text);
+ } else {
+ text = _(text);
+ }
+ }
}
- const char *desc = in_repr->attribute("gui-description");
- if (desc == NULL) {
- desc = in_repr->attribute("_gui-description");
+ const char *description = in_repr->attribute("gui-description");
+ if (description == NULL) {
+ description = in_repr->attribute("_gui-description");
+ if (description != NULL) {
+ const char *context = in_repr->attribute("msgctxt");
+ if (context != NULL) {
+ description = g_dpgettext2(NULL, context, description);
+ } else {
+ description = _(description);
+ }
+ }
}
- bool gui_hidden = false;
+ bool hidden = false;
{
const char *gui_hide = in_repr->attribute("gui-hidden");
if (gui_hide != NULL) {
if (strcmp(gui_hide, "1") == 0 ||
strcmp(gui_hide, "true") == 0) {
- gui_hidden = true;
+ hidden = true;
}
/* else stays false */
}
@@ -98,44 +112,30 @@ Parameter *Parameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Ex
}
const gchar* appearance = in_repr->attribute("appearance");
- Parameter::_scope_t scope = Parameter::SCOPE_USER;
- {
- const char *scope_str = in_repr->attribute("scope");
- if (scope_str != NULL) {
- if (!strcmp(scope_str, "user")) {
- scope = Parameter::SCOPE_USER;
- } else if (!strcmp(scope_str, "document")) {
- scope = Parameter::SCOPE_DOCUMENT;
- } else if (!strcmp(scope_str, "node")) {
- scope = Parameter::SCOPE_NODE;
- }
- }
- }
-
Parameter * param = NULL;
if (!strcmp(type, "boolean")) {
- param = new ParamBool(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr);
+ param = new ParamBool(name, text, description, hidden, indent, in_ext, in_repr);
} else if (!strcmp(type, "int")) {
if (appearance && !strcmp(appearance, "full")) {
- param = new ParamInt(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, ParamInt::FULL);
+ param = new ParamInt(name, text, description, hidden, indent, in_ext, in_repr, ParamInt::FULL);
} else {
- param = new ParamInt(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, ParamInt::MINIMAL);
+ param = new ParamInt(name, text, description, hidden, indent, in_ext, in_repr, ParamInt::MINIMAL);
}
} else if (!strcmp(type, "float")) {
if (appearance && !strcmp(appearance, "full")) {
- param = new ParamFloat(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, ParamFloat::FULL);
+ param = new ParamFloat(name, text, description, hidden, indent, in_ext, in_repr, ParamFloat::FULL);
} else {
- param = new ParamFloat(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, ParamFloat::MINIMAL);
+ param = new ParamFloat(name, text, description, hidden, indent, in_ext, in_repr, ParamFloat::MINIMAL);
}
} else if (!strcmp(type, "string")) {
- param = new ParamString(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr);
+ param = new ParamString(name, text, description, hidden, indent, in_ext, in_repr);
gchar const * max_length = in_repr->attribute("max_length");
if (max_length != NULL) {
ParamString * ps = dynamic_cast<ParamString *>(param);
ps->setMaxLength(atoi(max_length));
}
} else if (!strcmp(type, "description")) {
- ParamDescription::AppearanceMode appearance_mode = ParamDescription::DESC;
+ ParamDescription::AppearanceMode appearance_mode = ParamDescription::DESCRIPTION;
if (appearance) {
if (!strcmp(appearance, "header")) {
appearance_mode = ParamDescription::HEADER;
@@ -143,19 +143,19 @@ Parameter *Parameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Ex
appearance_mode = ParamDescription::URL;
}
}
- param = new ParamDescription(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, appearance_mode);
+ param = new ParamDescription(name, text, description, hidden, indent, in_ext, in_repr, appearance_mode);
} else if (!strcmp(type, "enum")) {
- param = new ParamComboBox(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr);
+ param = new ParamComboBox(name, text, description, hidden, indent, in_ext, in_repr);
} else if (!strcmp(type, "notebook")) {
- param = new ParamNotebook(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr);
+ param = new ParamNotebook(name, text, description, hidden, indent, in_ext, in_repr);
} else if (!strcmp(type, "optiongroup")) {
if (appearance && !strcmp(appearance, "minimal")) {
- param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, ParamRadioButton::MINIMAL);
+ param = new ParamRadioButton(name, text, description, hidden, indent, in_ext, in_repr, ParamRadioButton::MINIMAL);
} else {
- param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr, ParamRadioButton::FULL);
+ param = new ParamRadioButton(name, text, description, hidden, indent, in_ext, in_repr, ParamRadioButton::FULL);
}
} else if (!strcmp(type, "color")) {
- param = new ParamColor(name, guitext, desc, scope, gui_hidden, gui_tip, indent, in_ext, in_repr);
+ param = new ParamColor(name, text, description, hidden, indent, in_ext, in_repr);
}
// Note: param could equal NULL
@@ -302,29 +302,24 @@ Parameter::set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node)
/** Oop, now that we need a parameter, we need it's name. */
-Parameter::Parameter(gchar const * name, gchar const * guitext, gchar const * desc, const Parameter::_scope_t scope, bool gui_hidden, gchar const * gui_tip, int indent, Inkscape::Extension::Extension * ext) :
- _desc(0),
- _scope(scope),
+Parameter::Parameter(gchar const * name, gchar const * text, gchar const * description, bool hidden, int indent, Inkscape::Extension::Extension * ext) :
+ _description(0),
_text(0),
- _gui_hidden(gui_hidden),
- _gui_tip(0),
+ _hidden(hidden),
_indent(indent),
- extension(ext),
+ _extension(ext),
_name(0)
{
if (name != NULL) {
_name = g_strdup(name);
}
- if (desc != NULL) {
- _desc = g_strdup(desc);
-// printf("Adding description: '%s' on '%s'\n", _desc, _name);
- }
- if (gui_tip != NULL) {
- _gui_tip = g_strdup(gui_tip);
+
+ if (description != NULL) {
+ _description = g_strdup(description);
}
- if (guitext != NULL) {
- _text = g_strdup(guitext);
+ if (text != NULL) {
+ _text = g_strdup(text);
} else {
_text = g_strdup(name);
}
@@ -333,21 +328,19 @@ Parameter::Parameter(gchar const * name, gchar const * guitext, gchar const * de
}
/** Oop, now that we need a parameter, we need it's name. */
-Parameter::Parameter (gchar const * name, gchar const * guitext, Inkscape::Extension::Extension * ext) :
- _desc(0),
- _scope(Parameter::SCOPE_USER),
+Parameter::Parameter (gchar const * name, gchar const * text, Inkscape::Extension::Extension * ext) :
+ _description(0),
_text(0),
- _gui_hidden(false),
- _gui_tip(0),
+ _hidden(false),
_indent(0),
- extension(ext),
+ _extension(ext),
_name(0)
{
if (name != NULL) {
_name = g_strdup(name);
}
- if (guitext != NULL) {
- _text = g_strdup(guitext);
+ if (text != NULL) {
+ _text = g_strdup(text);
} else {
_text = g_strdup(name);
}
@@ -363,16 +356,13 @@ Parameter::~Parameter(void)
g_free(_text);
_text = 0;
- g_free(_gui_tip);
- _gui_tip = 0;
-
- g_free(_desc);
- _desc = 0;
+ g_free(_description);
+ _description = 0;
}
gchar *Parameter::pref_name(void) const
{
- return g_strdup_printf("%s.%s", extension->get_id(), _name);
+ return g_strdup_printf("%s.%s", _extension->get_id(), _name);
}
Inkscape::XML::Node *
@@ -405,7 +395,7 @@ Inkscape::XML::Node *Parameter::document_param_node(SPDocument * doc)
child != NULL;
child = child->next()) {
if ((GQuark)child->code() == name_quark &&
- !strcmp(child->attribute("extension"), extension->get_id())) {
+ !strcmp(child->attribute("extension"), _extension->get_id())) {
params = child;
break;
}
@@ -413,7 +403,7 @@ Inkscape::XML::Node *Parameter::document_param_node(SPDocument * doc)
if (params == NULL) {
params = xml_doc->createElement("inkscape:extension-param");
- params->setAttribute("extension", extension->get_id());
+ params->setAttribute("extension", _extension->get_id());
defs->appendChild(params);
Inkscape::GC::release(params);
}
diff --git a/src/extension/param/parameter.h b/src/extension/param/parameter.h
index c107f24f9..96cc055d8 100644
--- a/src/extension/param/parameter.h
+++ b/src/extension/param/parameter.h
@@ -47,26 +47,16 @@ extern Glib::ustring const extension_pref_root;
*/
class Parameter {
-protected:
- /** List of possible scopes. */
- typedef enum {
- SCOPE_USER, /**< Parameter value is saved in the user's configuration file. (default) */
- SCOPE_DOCUMENT, /**< Parameter value is saved in the document. */
- SCOPE_NODE /**< Parameter value is attached to the node. */
- } _scope_t;
-
public:
Parameter(gchar const *name,
- gchar const *guitext,
- gchar const *desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- gchar const *gui_tip,
+ gchar const *text,
+ gchar const *description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext);
Parameter(gchar const *name,
- gchar const *guitext,
+ gchar const *text,
Inkscape::Extension::Extension * ext);
virtual ~Parameter(void);
@@ -140,10 +130,10 @@ public:
virtual Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
- gchar const * get_tooltip(void) const { return _desc; }
+ gchar const * get_tooltip(void) const { return _description; }
/** Indicates if the GUI for this parameter is hidden or not */
- bool get_gui_hidden() const { return _gui_hidden; }
+ bool get_hidden() const { return _hidden; }
/** Indentation level of the parameter */
int get_indent() const { return _indent; }
@@ -173,20 +163,14 @@ public:
protected:
- /** Description of the parameter. */
- gchar * _desc;
-
- /** Scope of the parameter. */
- _scope_t _scope;
-
- /** Text for the GUI selection of this. */
- gchar * _text;
+ /** Parameter text to show as the GUI label. */
+ gchar * _text;
- /** Whether the GUI is visible. */
- bool _gui_hidden;
+ /** Extended description of the parameter (crrently shown as tooltip on hover). */
+ gchar * _description;
- /** A tip for the GUI if there is one. */
- gchar * _gui_tip;
+ /** Whether the parameter is visible. */
+ bool _hidden;
/** Indentation level of the parameter. */
int _indent;
@@ -207,7 +191,7 @@ protected:
private:
/** Which extension is this parameter attached to. */
- Inkscape::Extension::Extension *extension;
+ Inkscape::Extension::Extension *_extension;
/** The name of this parameter. */
gchar *_name;
diff --git a/src/extension/param/radiobutton.cpp b/src/extension/param/radiobutton.cpp
index 178dc20e8..a08ba6860 100644
--- a/src/extension/param/radiobutton.cpp
+++ b/src/extension/param/radiobutton.cpp
@@ -41,33 +41,31 @@ namespace Inkscape {
namespace Extension {
/* For internal use only.
- Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
+ Note that value and text MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
class optionentry {
public:
- optionentry (Glib::ustring * val, Glib::ustring * text) {
+ optionentry (Glib::ustring * val, Glib::ustring * txt) {
value = val;
- guitext = text;
+ text = txt;
}
~optionentry() {
delete value;
- delete guitext;
+ delete text;
}
Glib::ustring * value;
- Glib::ustring * guitext;
+ Glib::ustring * text;
};
ParamRadioButton::ParamRadioButton(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
AppearanceMode mode)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(0)
, _mode(mode)
, choices(0)
@@ -79,7 +77,7 @@ ParamRadioButton::ParamRadioButton(const gchar * name,
while (child_repr != NULL) {
char const * chname = child_repr->name();
if (!strcmp(chname, INKSCAPE_EXTENSION_NS "option") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) {
- Glib::ustring * newguitext = NULL;
+ Glib::ustring * newtext = NULL;
Glib::ustring * newvalue = NULL;
const char * contents = child_repr->firstChild()->content();
@@ -87,12 +85,12 @@ ParamRadioButton::ParamRadioButton(const gchar * name,
// don't translate when 'item' but do translate when '_option'
if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) {
if (child_repr->attribute("msgctxt") != NULL) {
- newguitext = new Glib::ustring(g_dpgettext2(NULL, child_repr->attribute("msgctxt"), contents));
+ newtext = new Glib::ustring(g_dpgettext2(NULL, child_repr->attribute("msgctxt"), contents));
} else {
- newguitext = new Glib::ustring(_(contents));
+ newtext = new Glib::ustring(_(contents));
}
} else {
- newguitext = new Glib::ustring(contents);
+ newtext = new Glib::ustring(contents);
}
} else {
continue;
@@ -106,8 +104,8 @@ ParamRadioButton::ParamRadioButton(const gchar * name,
newvalue = new Glib::ustring(contents);
}
- if ( (newguitext) && (newvalue) ) { // logical error if this is not true here
- choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
+ if ( (newtext) && (newvalue) ) { // logical error if this is not true here
+ choices = g_slist_append( choices, new optionentry(newvalue, newtext) );
}
}
child_repr = child_repr->next();
@@ -282,7 +280,7 @@ Glib::ustring ParamRadioButton::value_from_label(const Glib::ustring label)
for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
optionentry * entr = reinterpret_cast<optionentry *>(list->data);
- if ( !entr->guitext->compare(label) ) {
+ if ( !entr->text->compare(label) ) {
value = *(entr->value);
break;
}
@@ -297,7 +295,7 @@ Glib::ustring ParamRadioButton::value_from_label(const Glib::ustring label)
*/
Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
@@ -306,7 +304,7 @@ Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node
auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0));
vbox->set_homogeneous(false);
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START, Gtk::ALIGN_START));
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START, Gtk::ALIGN_START));
label->show();
hbox->pack_start(*label, false, false);
@@ -323,7 +321,7 @@ Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node
Gtk::RadioButtonGroup group;
for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
optionentry * entr = reinterpret_cast<optionentry *>(list->data);
- Glib::ustring * text = entr->guitext;
+ Glib::ustring * text = entr->text;
switch ( _mode ) {
case MINIMAL:
{
diff --git a/src/extension/param/radiobutton.h b/src/extension/param/radiobutton.h
index 5e15dcb57..b91b11ea3 100644
--- a/src/extension/param/radiobutton.h
+++ b/src/extension/param/radiobutton.h
@@ -35,11 +35,9 @@ public:
};
ParamRadioButton(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml,
diff --git a/src/extension/param/string.cpp b/src/extension/param/string.cpp
index 0c5238f99..51b5dfdf3 100644
--- a/src/extension/param/string.cpp
+++ b/src/extension/param/string.cpp
@@ -77,15 +77,13 @@ void ParamString::string(std::string &string) const
/** Initialize the object, to do that, copy the data. */
ParamString::ParamString(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, indent, ext)
+ : Parameter(name, text, description, hidden, indent, ext)
, _value(NULL)
{
const char * defaultval = NULL;
@@ -164,12 +162,12 @@ void ParamStringEntry::changed_text(void)
*/
Gtk::Widget * ParamString::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
{
- if (_gui_hidden) {
+ if (_hidden) {
return NULL;
}
Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING));
- Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START));
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START));
label->show();
hbox->pack_start(*label, false, false);
diff --git a/src/extension/param/string.h b/src/extension/param/string.h
index f5412ebcc..d338f83b9 100644
--- a/src/extension/param/string.h
+++ b/src/extension/param/string.h
@@ -24,11 +24,9 @@ private:
gint _max_length;
public:
ParamString(const gchar * name,
- const gchar * guitext,
- const gchar * desc,
- const Parameter::_scope_t scope,
- bool gui_hidden,
- const gchar * gui_tip,
+ const gchar * text,
+ const gchar * description,
+ bool hidden,
int indent,
Inkscape::Extension::Extension * ext,
Inkscape::XML::Node * xml);
diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp
index 2bdbb081e..92ddd3050 100644
--- a/src/extension/prefdialog.cpp
+++ b/src/extension/prefdialog.cpp
@@ -246,7 +246,7 @@ PrefDialog::on_response (int signal) {
#include "internal/clear-n_.h"
-const char * PrefDialog::live_param_xml = "<param name=\"__live_effect__\" type=\"boolean\" _gui-text=\"" N_("Live preview") "\" gui-description=\"" N_("Is the effect previewed live on canvas?") "\" scope=\"user\">false</param>";
+const char * PrefDialog::live_param_xml = "<param name=\"__live_effect__\" type=\"boolean\" _gui-text=\"" N_("Live preview") "\" gui-description=\"" N_("Is the effect previewed live on canvas?") "\">false</param>";
}; }; /* namespace Inkscape, Extension */
diff --git a/src/file.cpp b/src/file.cpp
index fc9ce6b19..795df433d 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -293,12 +293,10 @@ bool sp_file_open(const Glib::ustring &uri,
bool replace_empty)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- Inkscape::Display::TemporaryItem *page_border_rotated = NULL;
if (desktop) {
desktop->setWaitingCursor();
- page_border_rotated = sp_document_namedview(desktop->getDocument(), NULL)->page_border_rotated;
}
-
+
SPDocument *doc = NULL;
bool cancelled = false;
try {
@@ -317,6 +315,7 @@ bool sp_file_open(const Glib::ustring &uri,
}
if (doc) {
+
SPDocument *existing = desktop ? desktop->getDocument() : NULL;
if (existing && existing->virgin && replace_empty) {
@@ -324,7 +323,6 @@ bool sp_file_open(const Glib::ustring &uri,
doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc.
desktop->change_document(doc);
doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px"));
- desktop->remove_temporary_canvasitem(page_border_rotated);
} else {
// create a whole new desktop and window
SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc.
diff --git a/src/helper/geom-pathvectorsatellites.cpp b/src/helper/geom-pathvectorsatellites.cpp
index 79055af8d..dd231d78f 100644
--- a/src/helper/geom-pathvectorsatellites.cpp
+++ b/src/helper/geom-pathvectorsatellites.cpp
@@ -67,7 +67,9 @@ void PathVectorSatellites::setSelected(std::vector<size_t> selected)
size_t counter = 0;
for (size_t i = 0; i < _satellites.size(); ++i) {
for (size_t j = 0; j < _satellites[i].size(); ++j) {
+ std::cout << j;
if (find (selected.begin(), selected.end(), counter) != selected.end()) {
+
_satellites[i][j].setSelected(true);
} else {
_satellites[i][j].setSelected(false);
diff --git a/src/io/sys.cpp b/src/io/sys.cpp
index 61a6a96f4..b06b550dd 100644
--- a/src/io/sys.cpp
+++ b/src/io/sys.cpp
@@ -37,36 +37,6 @@ void dump_ustr(Glib::ustring const &ustr);
extern guint update_in_progress;
-#define DEBUG_MESSAGE(key, ...) \
-{\
- Inkscape::Preferences *prefs = Inkscape::Preferences::get(); \
- gint dump = prefs->getBool("/options/bulia/" #key) ? 1 : 0;\
- gint dumpD = prefs->getBool("/options/bulia/" #key"D") ? 1 : 0;\
- gint dumpD2 = prefs->getBool("/options/bulia/" #key"D2") ? 1 : 0;\
- dumpD &= ( (update_in_progress == 0) || dumpD2 );\
- if ( dump )\
- {\
- g_message( __VA_ARGS__ );\
-\
- }\
- if ( dumpD )\
- {\
- GtkWidget *dialog = gtk_message_dialog_new(NULL,\
- GTK_DIALOG_DESTROY_WITH_PARENT, \
- GTK_MESSAGE_INFO, \
- GTK_BUTTONS_OK, \
- __VA_ARGS__ \
- );\
- g_signal_connect_swapped(dialog, "response",\
- G_CALLBACK(gtk_widget_destroy), \
- dialog); \
- gtk_widget_show_all( dialog );\
- }\
-}
-
-
-
-
void Inkscape::IO::dump_fopen_call( char const *utf8name, char const *id )
{
#ifdef INK_DUMP_FOPEN
@@ -97,65 +67,33 @@ void Inkscape::IO::dump_fopen_call( char const *utf8name, char const *id )
FILE *Inkscape::IO::fopen_utf8name( char const *utf8name, char const *mode )
{
- static gint counter = 0;
FILE* fp = NULL;
-
- DEBUG_MESSAGE( dumpOne, "entering fopen_utf8name( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
-
-#ifndef WIN32
- DEBUG_MESSAGE( dumpOne, " STEP 0 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL );
if ( filename )
{
- DEBUG_MESSAGE( dumpOne, " STEP 1 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
- fp = std::fopen(filename, mode);
- DEBUG_MESSAGE( dumpOne, " STEP 2 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
+ Glib::ustring how( mode );
+ if ( how.find("b") == Glib::ustring::npos )
+ {
+ how.append("b"); // not needed in POSIX but doesn't hurt either
+ }
+ fp = g_fopen(filename, how.c_str());
g_free(filename);
- DEBUG_MESSAGE( dumpOne, " STEP 3 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
filename = 0;
}
-#else
- Glib::ustring how( mode );
- how.append("b");
- DEBUG_MESSAGE( dumpOne, " calling is_os_wide() ( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
-
- fp = g_fopen(utf8name, how.c_str());
-#endif
-
- DEBUG_MESSAGE( dumpOne, "leaving fopen_utf8name( '%s', '%s' )[%d]", utf8name, mode, (counter++) );
-
return fp;
}
int Inkscape::IO::mkdir_utf8name( char const *utf8name )
{
- static gint counter = 0;
int retval = -1;
-
- DEBUG_MESSAGE( dumpMk, "entering mkdir_utf8name( '%s' )[%d]", utf8name, (counter++) );
-
-#ifndef WIN32
- DEBUG_MESSAGE( dumpMk, " STEP 0 ( '%s' )[%d]", utf8name, (counter++) );
gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL );
if ( filename )
{
- DEBUG_MESSAGE( dumpMk, " STEP 1 ( '%s' )[%d]", utf8name, (counter++) );
- retval = ::mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP);
- DEBUG_MESSAGE( dumpMk, " STEP 2 ( '%s' )[%d]", utf8name, (counter++) );
+ retval = g_mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); // The mode argument is ignored on Windows.
g_free(filename);
- DEBUG_MESSAGE( dumpMk, " STEP 3 ( '%s' )[%d]", utf8name, (counter++) );
filename = 0;
}
-#else
- DEBUG_MESSAGE( dumpMk, " calling is_os_wide() ( '%s' )[%d]", utf8name, (counter++) );
-
- // Mode should be ingnored inside of glib on the way in
- retval = g_mkdir( utf8name, 0 );
-#endif
-
- DEBUG_MESSAGE( dumpMk, "leaving mkdir_utf8name( '%s' )[%d]", utf8name, (counter++) );
-
return retval;
}
diff --git a/src/livarot/PathOutline.cpp b/src/livarot/PathOutline.cpp
index 7043469d2..c1a48d41f 100644
--- a/src/livarot/PathOutline.cpp
+++ b/src/livarot/PathOutline.cpp
@@ -158,7 +158,8 @@ void Path::Outline(Path *dest, double width, JoinType join, ButtType butt, doubl
join, butt, miter, false, false, endPos, endButt);
Geom::Point endNor=endButt.ccw();
if (butt == butt_round) {
- dest->ArcTo (endPos+width*endNor, 1.0001 * width, 1.0001 * width, 0.0, true, true);
+ dest->ArcTo (endPos+width*endButt, width, width, 0.0, false, true);
+ dest->ArcTo (endPos+width*endNor, width, width, 0.0, false, true);
} else if (butt == butt_square) {
dest->LineTo (endPos-width*endNor+width*endButt);
dest->LineTo (endPos+width*endNor+width*endButt);
@@ -175,7 +176,8 @@ void Path::Outline(Path *dest, double width, JoinType join, ButtType butt, doubl
endNor=endButt.ccw();
if (butt == butt_round) {
- dest->ArcTo (endPos+width*endNor, 1.0001 * width, 1.0001 * width, 0.0, true, true);
+ dest->ArcTo (endPos+width*endButt, width, width, 0.0, false, true);
+ dest->ArcTo (endPos+width*endNor, width, width, 0.0, false, true);
} else if (butt == butt_square) {
dest->LineTo (endPos-width*endNor+width*endButt);
dest->LineTo (endPos+width*endNor+width*endButt);
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 5ef9487ab..467a65c7c 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -73,8 +73,10 @@
#include "path-chemistry.h"
#include "xml/sp-css-attr.h"
#include "live_effects/lpeobject.h"
+#include <pangomm/layout.h>
#include "display/curve.h"
-
+#include <stdio.h>
+#include <string.h>
namespace Inkscape {
@@ -83,63 +85,63 @@ namespace LivePathEffect {
const Util::EnumData<EffectType> LPETypeData[] = {
// {constant defined in effect-enum.h, N_("name of your effect"), "name of your effect in SVG"}
#ifdef LPE_ENABLE_TEST_EFFECTS
- {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"},
- {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"},
+ {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"},
+ {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"},
{CIRCLE_WITH_RADIUS, N_("Circle (by center and radius)"), "circle_with_radius"},
- {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"},
- {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"},
- {EXTRUDE, N_("Extrude"), "extrude"},
- {LATTICE, N_("Lattice Deformation"), "lattice"},
- {LINE_SEGMENT, N_("Line Segment"), "line_segment"},
- {OFFSET, N_("Offset"), "offset"},
- {PARALLEL, N_("Parallel"), "parallel"},
- {PATH_LENGTH, N_("Path length"), "path_length"},
- {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
- {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"},
- {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"},
- {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"},
- {TEXT_LABEL, N_("Text label"), "text_label"},
+ {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"},
+ {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"},
+ {EXTRUDE, N_("Extrude"), "extrude"},
+ {LATTICE, N_("Lattice Deformation"), "lattice"},
+ {LINE_SEGMENT, N_("Line Segment"), "line_segment"},
+ {OFFSET, N_("Offset"), "offset"},
+ {PARALLEL, N_("Parallel"), "parallel"},
+ {PATH_LENGTH, N_("Path length"), "path_length"},
+ {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
+ {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"},
+ {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"},
+ {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"},
+ {TEXT_LABEL, N_("Text label"), "text_label"},
#endif
/* 0.46 */
- {BEND_PATH, N_("Bend"), "bend_path"},
- {GEARS, N_("Gears"), "gears"},
- {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
- {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"},
+ {BEND_PATH, N_("Bend"), "bend_path"},
+ {GEARS, N_("Gears"), "gears"},
+ {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
+ {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"},
/* 0.47 */
- {VONKOCH, N_("VonKoch"), "vonkoch"},
- {KNOT, N_("Knot"), "knot"},
- {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"},
- {SPIRO, N_("Spiro spline"), "spiro"},
- {ENVELOPE, N_("Envelope Deformation"), "envelope"},
- {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"},
- {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"},
- {SKETCH, N_("Sketch"), "sketch"},
- {RULER, N_("Ruler"), "ruler"},
+ {VONKOCH, N_("VonKoch"), "vonkoch"},
+ {KNOT, N_("Knot"), "knot"},
+ {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"},
+ {SPIRO, N_("Spiro spline"), "spiro"},
+ {ENVELOPE, N_("Envelope Deformation"), "envelope"},
+ {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"},
+ {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"},
+ {SKETCH, N_("Sketch"), "sketch"},
+ {RULER, N_("Ruler"), "ruler"},
/* 0.91 */
- {POWERSTROKE, N_("Power stroke"), "powerstroke"},
- {CLONE_ORIGINAL, N_("Clone original"), "clone_original"},
+ {POWERSTROKE, N_("Power stroke"), "powerstroke"},
+ {CLONE_ORIGINAL, N_("Clone original"), "clone_original"},
/* 0.92 */
- {SIMPLIFY, N_("Simplify"), "simplify"},
- {LATTICE2, N_("Lattice Deformation 2"), "lattice2"},
- {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective_envelope"},
- {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"},
- {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"},
- {SHOW_HANDLES, N_("Show handles"), "show_handles"},
- {ROUGHEN, N_("Roughen"), "roughen"},
- {BSPLINE, N_("BSpline"), "bspline"},
- {JOIN_TYPE, N_("Join type"), "join_type"},
- {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"},
- {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
- {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
+ {SIMPLIFY, N_("Simplify"), "simplify"},
+ {LATTICE2, N_("Lattice Deformation 2"), "lattice2"},
+ {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, //TODO:Wrong name with "-"
+ {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"},
+ {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"},
+ {SHOW_HANDLES, N_("Show handles"), "show_handles"},
+ {ROUGHEN, N_("Roughen"), "roughen"},
+ {BSPLINE, N_("BSpline"), "bspline"},
+ {JOIN_TYPE, N_("Join type"), "join_type"},
+ {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"},
+ {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
+ {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
/* Ponyscape -> Inkscape 0.92*/
- {ATTACH_PATH, N_("Attach path"), "attach_path"},
- {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"},
- {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"},
- {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"},
- {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"},
+ {ATTACH_PATH, N_("Attach path"), "attach_path"},
+ {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"},
+ {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"},
+ {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"},
+ {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"},
/* 9.93 */
- {MEASURE_LINE, N_("Measure Line"), "measure_line"},
- {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"},
+ {MEASURE_LINE, N_("Measure Line"), "measure_line"},
+ {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet_chamfer"},
};
const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
@@ -401,58 +403,19 @@ Effect::setCurrentZoom(double cZ)
}
void
-Effect::setSelectedNodePos(std::vector<Geom::Point> selected_nodes_pos_data)
+Effect::setSelectedNodePoints(std::vector<Geom::Point> sNP)
{
- selected_nodes_pos = selected_nodes_pos_data;
-}
-
-void
-
-Effect::setSelectedNodeIndex(Geom::PathVector pv)
-{
- selected_nodes_index.clear();
- for (Geom::PathVector::const_iterator path_it = pv.begin();
- path_it != pv.end(); ++path_it) {
-
- if (path_it->empty()) {
- continue;
- }
- Geom::Path::const_iterator curve_it1 = path_it->begin();
- Geom::Path::const_iterator curve_endit = path_it->end_default();
- if (path_it->closed()) {
- const Geom::Curve &closingline = path_it->back_closed();
- // the closing line segment is always of type
- // Geom::LineSegment.
- if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
- // closingline.isDegenerate() did not work, because it only checks for
- // *exact* zero length, which goes wrong for relative coordinates and
- // rounding errors...
- // the closing line segment has zero-length. So stop before that one!
- curve_endit = path_it->end_open();
- }
- }
- size_t i = 0;
- while (curve_it1 != curve_endit) {
- if (isNodeSelected(curve_it1->initialPoint())) {
- selected_nodes_index.push_back(i);
- }
- ++i;
- ++curve_it1;
- }
- if (isNodeSelected(path_it->finalPoint())) {
- selected_nodes_index.push_back(i);
- }
- }
+ selectedNodesPoints = sNP;
}
bool
-Effect::isNodeSelected(Geom::Point const &nodePoint) const
+Effect::isNodePointSelected(Geom::Point const &nodePoint) const
{
- if (selected_nodes_pos.size() > 0) {
+ if (selectedNodesPoints.size() > 0) {
using Geom::X;
using Geom::Y;
- for (std::vector<Geom::Point>::const_iterator i = selected_nodes_pos.begin();
- i != selected_nodes_pos.end(); ++i) {
+ for (std::vector<Geom::Point>::const_iterator i = selectedNodesPoints.begin();
+ i != selectedNodesPoints.end(); ++i) {
Geom::Point p = *i;
Geom::Affine transformCoordinate = sp_lpe_item->i2dt_affine();
Geom::Point p2(nodePoint[X],nodePoint[Y]);
@@ -683,6 +646,7 @@ void
Effect::readallParameters(Inkscape::XML::Node const* repr)
{
std::vector<Parameter *>::iterator it = param_vector.begin();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
while (it != param_vector.end()) {
Parameter * param = *it;
const gchar * key = param->param_key.c_str();
@@ -693,10 +657,17 @@ Effect::readallParameters(Inkscape::XML::Node const* repr)
g_warning("Effect::readallParameters - '%s' not accepted for %s", value, key);
}
} else {
- // set default value
- param->param_set_default();
+ Glib::ustring pref_path = (Glib::ustring)"/live_effects/" +
+ (Glib::ustring)LPETypeConverter.get_key(effectType()).c_str() +
+ (Glib::ustring)"/" +
+ (Glib::ustring)key;
+ bool valid = prefs->getEntry(pref_path).isValid();
+ if(valid){
+ param->param_update_default(prefs->getString(pref_path).c_str());
+ } else {
+ param->param_set_default();
+ }
}
-
++it;
}
}
@@ -811,10 +782,96 @@ Effect::newWidget()
++it;
}
- upd_params = false;
return dynamic_cast<Gtk::Widget *>(vbox);
}
+/**
+ * This *creates* a new widget, with default values setter
+ */
+Gtk::Widget *
+Effect::defaultParamSet()
+{
+ // use manage here, because after deletion of Effect object, others might still be pointing to this widget.
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() );
+ Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox() );
+ Glib::ustring effectname = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_label(effectType());
+ Glib::ustring effectkey = (Glib::ustring)Inkscape::LivePathEffect::LPETypeConverter.get_key(effectType());
+ std::vector<Parameter *>::iterator it = param_vector.begin();
+ Inkscape::UI::Widget::Registry * wr;
+ bool has_params = false;
+ while (it != param_vector.end()) {
+ if ((*it)->widget_is_visible) {
+ has_params = true;
+ Parameter * param = *it;
+ Glib::ustring * tip = param->param_getTooltip();
+ const gchar * key = param->param_key.c_str();
+ const gchar * value = param->param_label.c_str();
+ const gchar * tooltip_extra = _(". Change custom values for this parameter");
+ Glib::ustring tooltip = param->param_tooltip + (Glib::ustring)tooltip_extra;
+ Glib::ustring pref_path = (Glib::ustring)"/live_effects/" +
+ effectkey +
+ (Glib::ustring)"/" +
+ (Glib::ustring)key;
+ bool valid = prefs->getEntry(pref_path).isValid();
+ const gchar * set_or_upd;
+ if (valid) {
+ set_or_upd = _("Update");
+ } else {
+ set_or_upd = _("Set");
+ }
+ Gtk::HBox * vbox_param = Gtk::manage( new Gtk::HBox(true) );
+ Gtk::Label *parameter_label = Gtk::manage(new Gtk::Label(value, Gtk::ALIGN_START));
+ parameter_label->set_use_markup(true);
+ parameter_label->set_use_underline (true);
+ parameter_label->set_ellipsize(Pango::ELLIPSIZE_END);
+ vbox_param->pack_start(*parameter_label, true, true, 2);
+ Gtk::Button *set = Gtk::manage(new Gtk::Button((Glib::ustring)set_or_upd));
+ Gtk::Button *unset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Unset"))));
+ unset->signal_clicked().connect(sigc::bind<Glib::ustring, Gtk::Button *, Gtk::Button *>(sigc::mem_fun(*this, &Effect::unsetDefaultParam), pref_path, set, unset));
+ set->signal_clicked().connect(sigc::bind<Glib::ustring, gchar *, Gtk::Button *, Gtk::Button *>(sigc::mem_fun(*this, &Effect::setDefaultParam), pref_path, param->param_getSVGValue(), set, unset));
+ if (!valid) {
+ unset->set_sensitive(false);
+ }
+ vbox_param->pack_start(*set, true, true, 2);
+ vbox_param->pack_start(*unset, true, true, 2);
+
+ vbox_expander->pack_start(*vbox_param, true, true, 2);
+ }
+ ++it;
+ }
+ Glib::ustring tip = "<b>" + effectname + (Glib::ustring)_("</b>: Set default parameters");
+ Gtk::Expander * expander = Gtk::manage(new Gtk::Expander(tip));
+ expander->set_use_markup(true);
+ expander->add(*vbox_expander);
+ expander->set_expanded(false);
+ vbox->pack_start(*dynamic_cast<Gtk::Widget *> (expander), true, true, 2);
+ if (has_params) {
+ return dynamic_cast<Gtk::Widget *>(vbox);
+ } else {
+ return NULL;
+ }
+}
+
+void
+Effect::setDefaultParam(Glib::ustring pref_path, gchar * value, Gtk::Button *set , Gtk::Button *unset)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setString(pref_path, (Glib::ustring)value);
+ gchar * label = _("Update");
+ set->set_label((Glib::ustring)label);
+ unset->set_sensitive(true);
+}
+
+void
+Effect::unsetDefaultParam(Glib::ustring pref_path, Gtk::Button *set, Gtk::Button *unset)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->remove(pref_path);
+ gchar * label = _("Set");
+ set->set_label((Glib::ustring)label);
+ unset->set_sensitive(false);
+}
Inkscape::XML::Node *Effect::getRepr()
{
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 6c11e0b67..c34c391c0 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -65,9 +65,8 @@ public:
void doOnApply_impl(SPLPEItem const* lpeitem);
void doBeforeEffect_impl(SPLPEItem const* lpeitem);
void setCurrentZoom(double cZ);
- void setSelectedNodePos(std::vector<Geom::Point> selected_nodes_pos_data);
- void setSelectedNodeIndex(Geom::PathVector pv);
- bool isNodeSelected(Geom::Point const &nodePoint) const;
+ void setSelectedNodePoints(std::vector<Geom::Point> sNP);
+ bool isNodePointSelected(Geom::Point const &nodePoint) const;
virtual void doOnApply (SPLPEItem const* lpeitem);
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
@@ -95,7 +94,7 @@ public:
virtual void doEffect (SPCurve * curve);
virtual Gtk::Widget * newWidget();
-
+ virtual Gtk::Widget * defaultParamSet();
/**
* Sets all parameters to their default values and writes them to SVG.
*/
@@ -173,14 +172,15 @@ protected:
// this boolean defaults to false, it concatenates the input path to one pwd2,
// instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each.
bool concatenate_before_pwd2;
-
SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
SPShape * sp_shape; // these get stored in doBeforeEffect_impl before doEffect chain, or in performPathEffects on groups, and derived classes may do as they please with them.
std::vector<const char *> items;
double current_zoom;
- std::vector<Geom::Point> selected_nodes_pos;
- std::vector<size_t> selected_nodes_index;
+ std::vector<Geom::Point> selectedNodesPoints;
+
private:
+ void setDefaultParam(Glib::ustring pref_path, gchar * value, Gtk::Button *set , Gtk::Button *unset);
+ void unsetDefaultParam(Glib::ustring pref_path, Gtk::Button *set , Gtk::Button *unset);
bool provides_own_flash_paths; // if true, the standard flash path is suppressed
bool is_ready;
diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp
index b1e133292..363356cac 100644
--- a/src/live_effects/lpe-bendpath.cpp
+++ b/src/live_effects/lpe-bendpath.cpp
@@ -57,10 +57,10 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) :
scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false),
vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false)
{
- registerParameter( dynamic_cast<Parameter *>(&bend_path) );
- registerParameter( dynamic_cast<Parameter *>(&prop_scale) );
- registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );
- registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) );
+ registerParameter( &bend_path );
+ registerParameter( &prop_scale);
+ registerParameter( &scale_y_rel);
+ registerParameter( &vertical_pattern);
prop_scale.param_set_digits(3);
prop_scale.param_set_increments(0.01, 0.10);
diff --git a/src/live_effects/lpe-bounding-box.cpp b/src/live_effects/lpe-bounding-box.cpp
index 11fb34e04..c83d7e3bc 100644
--- a/src/live_effects/lpe-bounding-box.cpp
+++ b/src/live_effects/lpe-bounding-box.cpp
@@ -20,8 +20,8 @@ LPEBoundingBox::LPEBoundingBox(LivePathEffectObject *lpeobject) :
linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this),
visual_bounds(_("Visual Bounds"), _("Uses the visual bounding box"), "visualbounds", &wr, this)
{
- registerParameter( dynamic_cast<Parameter *>(&linked_path) );
- registerParameter( dynamic_cast<Parameter *>(&visual_bounds) );
+ registerParameter(&linked_path);
+ registerParameter(&visual_bounds);
//perceived_path = true;
}
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 3fed11d5a..5c227e68a 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -86,7 +86,7 @@ Gtk::Widget *LPEBSpline::newWidget()
// use manage here, because after deletion of Effect object, others might
// still be pointing to this widget.
Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
-
+ vbox->set_homogeneous(false);
vbox->set_border_width(5);
std::vector<Parameter *>::iterator it = param_vector.begin();
while (it != param_vector.end()) {
@@ -398,7 +398,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
(apply_no_weight && Geom::are_near((*cubic)[1], point_at0)) ||
(apply_with_weight && !Geom::are_near((*cubic)[1], point_at0)))
{
- if (isNodeSelected(point_at0) || !only_selected) {
+ if (isNodePointSelected(point_at0) || !only_selected) {
point_at1 = sbasis_in.valueAt(weight_ammount);
if (weight_ammount != NO_POWER) {
point_at1 =
@@ -414,7 +414,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
(apply_no_weight && Geom::are_near((*cubic)[2], point_at3)) ||
(apply_with_weight && !Geom::are_near((*cubic)[2], point_at3)))
{
- if (isNodeSelected(point_at3) || !only_selected) {
+ if (isNodePointSelected(point_at3) || !only_selected) {
point_at2 = sbasis_in.valueAt(1 - weight_ammount);
if (weight_ammount != NO_POWER) {
point_at2 =
@@ -431,14 +431,14 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
(apply_no_weight && weight_ammount == NO_POWER) ||
(apply_with_weight && weight_ammount != NO_POWER))
{
- if (isNodeSelected(point_at0) || !only_selected) {
+ if (isNodePointSelected(point_at0) || !only_selected) {
point_at1 = sbasis_in.valueAt(weight_ammount);
point_at1 =
Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
} else {
point_at1 = in->first_segment()->initialPoint();
}
- if (isNodeSelected(point_at3) || !only_selected) {
+ if (isNodePointSelected(point_at3) || !only_selected) {
point_at2 = sbasis_in.valueAt(1 - weight_ammount);
point_at2 =
Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp
index c41b1ef95..d97a990af 100644
--- a/src/live_effects/lpe-clone-original.cpp
+++ b/src/live_effects/lpe-clone-original.cpp
@@ -20,8 +20,7 @@ namespace LivePathEffect {
LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
- linked_path("LEGACY FALLBACK", "LEGACY FALLBACK", "linkedpath", &wr, this),
- linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this),
+ linkeditem(_("Linked Item:"), _("Item from which to take the original data"), "linkeditem", &wr, this),
scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0),
preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false),
inverse(_("Inverse clone"), _("Use LPE item as origin"), "inverse", &wr, this, false),
@@ -37,8 +36,15 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) :
expanded(false),
origin(Geom::Point(0,0))
{
- registerParameter(&linked_path);
- registerParameter(&linked_item);
+ //0.92 compatibility
+ const gchar * linkedpath = this->getRepr()->attribute("linkedpath");
+ if (linkedpath && strcmp(linkedpath, "") != 0){
+ this->getRepr()->setAttribute("linkeditem", linkedpath);
+ this->getRepr()->setAttribute("linkedpath", NULL);
+ this->getRepr()->setAttribute("transform", "false");
+ };
+
+ registerParameter(&linkeditem);
registerParameter(&scale);
registerParameter(&attributes);
registerParameter(&style_attributes);
@@ -208,19 +214,8 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co
void
LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){
- if (linked_path.linksToPath()) { //Legacy staff
- Glib::ustring attributes_value("d");
- attributes.param_setValue(attributes_value);
- attributes.write_to_SVG();
- Glib::ustring style_attributes_value("");
- style_attributes.param_setValue(style_attributes_value);
- style_attributes.write_to_SVG();
- linked_item.param_readSVGValue(linked_path.param_getSVGValue());
- linked_path.param_readSVGValue("");
- }
-
- if (linked_item.linksToItem()) {
- linked_item.setInverse(inverse);
+ if (linkeditem.linksToItem()) {
+ linkeditem.setInverse(inverse);
if ( preserve_position_changed != preserve_position ) {
if (!preserve_position) {
sp_svg_transform_read(SP_ITEM(sp_lpe_item)->getAttribute("transform"), &preserve_affine);
@@ -262,8 +257,8 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){
}
style_attr.append(Glib::ustring(style_attributes.param_getSVGValue()).append(","));
- SPItem * from = inverse ? SP_ITEM(sp_lpe_item) : SP_ITEM(linked_item.getObject());
- SPItem * to = !inverse ? SP_ITEM(sp_lpe_item) : SP_ITEM(linked_item.getObject());
+ SPItem * from = inverse ? SP_ITEM(sp_lpe_item) : SP_ITEM(linkeditem.getObject());
+ SPItem * to = !inverse ? SP_ITEM(sp_lpe_item) : SP_ITEM(linkeditem.getObject());
cloneAttrbutes(from, to, true, g_strdup(attr.c_str()), g_strdup(style_attr.c_str()), true);
Geom::OptRect bbox = from->geometricBounds();
if (bbox && preserve_position && origin != Geom::Point(0,0)) {
@@ -323,7 +318,6 @@ LPECloneOriginal::newWidget()
expander->set_expanded(expanded);
expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPECloneOriginal::onExpanderChanged) );
vbox->pack_start(*expander, true, true, 2);
- this->upd_params = false;
return dynamic_cast<Gtk::Widget *>(vbox);
}
@@ -346,15 +340,15 @@ LPECloneOriginal::~LPECloneOriginal()
void
LPECloneOriginal::transform_multiply(Geom::Affine const& postmul, bool set)
{
- if (linked_item.linksToItem()) {
- linked_item.getObject()->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ if (linkeditem.linksToItem()) {
+ linkeditem.getObject()->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
}
void
LPECloneOriginal::doEffect (SPCurve * curve)
{
- if (linked_item.linksToItem() && !inverse) {
+ if (linkeditem.linksToItem() && !inverse) {
SPShape * shape = getCurrentShape();
if(shape){
curve->set_pathvector(shape->getCurve()->get_pathvector());
diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h
index e4328c169..9bab8553f 100644
--- a/src/live_effects/lpe-clone-original.h
+++ b/src/live_effects/lpe-clone-original.h
@@ -32,8 +32,7 @@ public:
void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root);
private:
- OriginalPathParam linked_path;
- OriginalItemParam linked_item;
+ OriginalItemParam linkeditem;
ScalarParam scale;
BoolParam preserve_position;
BoolParam inverse;
diff --git a/src/live_effects/lpe-constructgrid.cpp b/src/live_effects/lpe-constructgrid.cpp
index 8d24f9f47..db620fa95 100644
--- a/src/live_effects/lpe-constructgrid.cpp
+++ b/src/live_effects/lpe-constructgrid.cpp
@@ -24,8 +24,8 @@ LPEConstructGrid::LPEConstructGrid(LivePathEffectObject *lpeobject) :
nr_x(_("Size _X:"), _("The size of the grid in X direction."), "nr_x", &wr, this, 5),
nr_y(_("Size _Y:"), _("The size of the grid in Y direction."), "nr_y", &wr, this, 5)
{
- registerParameter( dynamic_cast<Parameter *>(&nr_x) );
- registerParameter( dynamic_cast<Parameter *>(&nr_y) );
+ registerParameter(&nr_x);
+ registerParameter(&nr_y);
nr_x.param_make_integer();
nr_y.param_make_integer();
diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp
index bf82b5deb..ffd2ef4cf 100644
--- a/src/live_effects/lpe-copy_rotate.cpp
+++ b/src/live_effects/lpe-copy_rotate.cpp
@@ -30,6 +30,14 @@
namespace Inkscape {
namespace LivePathEffect {
+static const Util::EnumData<RotateMethod> RotateMethodData[RM_END] = {
+ { RM_NORMAL, N_("Normal"), "normal" },
+ { RM_KALEIDOSCOPE, N_("Kaleidoscope"), "kaleidoskope" },
+ { RM_FUSE, N_("Fuse paths"), "fuse_paths" }
+};
+static const Util::EnumDataConverter<RotateMethod>
+RMConverter(RotateMethodData, RM_END);
+
bool
pointInTriangle(Geom::Point const &p, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3)
{
@@ -52,30 +60,37 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) :
starting_angle(_("Starting angle"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0),
rotation_angle(_("Rotation angle"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0),
num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6),
- split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001),
+ gap(_("Gap"), _("Gap"), "gap", &wr, this, -0.0001),
copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true),
- fuse_paths(_("Kaleidoskope"), _("Kaleidoskope by helper line, use fill-rule: evenodd for best result"), "fuse_paths", &wr, this, false),
- join_paths(_("Join paths"), _("Join paths, use fill-rule: evenodd for best result"), "join_paths", &wr, this, false),
+ method(_("Method:"), _("Rotate methods"), "method", RMConverter, &wr, this, RM_NORMAL),
+ mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, false),
split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false),
dist_angle_handle(100.0)
{
show_orig_path = true;
_provides_knotholder_entities = true;
+ //0.92 compatibility
+ if (this->getRepr()->attribute("fuse_paths") && strcmp(this->getRepr()->attribute("fuse_paths"), "true") == 0){
+ this->getRepr()->setAttribute("fuse_paths", NULL);
+ this->getRepr()->setAttribute("method", "kaleidoskope");
+ this->getRepr()->setAttribute("mirror_copies", "true");
+ };
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter(&copies_to_360);
- registerParameter(&fuse_paths);
- registerParameter(&join_paths);
- registerParameter(&split_items);
+ registerParameter(&method);
+ registerParameter(&num_copies);
registerParameter(&starting_angle);
registerParameter(&starting_point);
registerParameter(&rotation_angle);
- registerParameter(&num_copies);
- registerParameter(&split_gap);
+ registerParameter(&gap);
registerParameter(&origin);
- split_gap.param_set_range(-999999.0, 999999.0);
- split_gap.param_set_increments(0.1, 0.1);
- split_gap.param_set_digits(5);
- num_copies.param_set_range(0, 999999);
+ registerParameter(&copies_to_360);
+ registerParameter(&mirror_copies);
+ registerParameter(&split_items);
+
+ gap.param_set_range(-99999.0, 99999.0);
+ gap.param_set_increments(0.1, 0.1);
+ gap.param_set_digits(5);
+ num_copies.param_set_range(1, 999999);
num_copies.param_make_integer(true);
apply_to_clippath_and_mask = true;
previous_num_copies = num_copies;
@@ -132,38 +147,21 @@ LPECopyRotate::doAfterEffect (SPLPEItem const* lpeitem)
counter++;
}
g_free(id);
- double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
- Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
- double size_divider = Geom::distance(origin,bbox) + (diagonal * 2);
- Geom::Point line_start = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))) * size_divider;
- Geom::Point line_end = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(rotation_angle + starting_angle))) * size_divider;
Geom::Affine m = Geom::Translate(-origin) * Geom::Rotate(-(Geom::rad_from_deg(starting_angle)));
- if (fuse_paths) {
- size_t rest = 0;
- for (size_t i = 1; i < num_copies; ++i) {
- Geom::Affine r = Geom::identity();
- Geom::Point dir = unit_vector((Geom::Point)origin - Geom::middle_point(line_start,line_end));
- if( rest%2 == 0) {
- r *= Geom::Rotate(Geom::Angle(dir)).inverse();
- r *= Geom::Scale(1, -1);
- r *= Geom::Rotate(Geom::Angle(dir));
- }
- Geom::Rotate rot(-(Geom::rad_from_deg(rotation_angle * i)));
- Geom::Affine t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin);
- if( rest%2 == 0) {
- t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)).inverse() * Geom::Translate(origin);
- }
- t *= sp_lpe_item->transform;
- toItem(t, i-1, reset);
- rest ++;
+ for (size_t i = 1; i < num_copies; ++i) {
+ Geom::Affine r = Geom::identity();
+ if( i%2 != 0 && mirror_copies) {
+ r *= Geom::Rotate(Geom::Angle(half_dir)).inverse();
+ r *= Geom::Scale(1, -1);
+ r *= Geom::Rotate(Geom::Angle(half_dir));
}
- } else {
- for (size_t i = 1; i < num_copies; ++i) {
- Geom::Rotate rot(-(Geom::rad_from_deg(rotation_angle * i)));
- Geom::Affine t = m * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin);
- t *= sp_lpe_item->transform;
- toItem(t, i - 1, reset);
+ Geom::Rotate rot(-(Geom::rad_from_deg(rotation_angle * i)));
+ Geom::Affine t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin);
+ if( i%2 != 0 && mirror_copies) {
+ t = m * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)).inverse() * Geom::Translate(origin);
}
+ t *= sp_lpe_item->transform;
+ toItem(t, i-1, reset);
}
reset = false;
} else {
@@ -302,15 +300,6 @@ Gtk::Widget * LPECopyRotate::newWidget()
vbox->set_border_width(5);
vbox->set_homogeneous(false);
vbox->set_spacing(2);
- Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0));
- Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) );
- vbox_expander->set_border_width(0);
- vbox_expander->set_spacing(2);
- Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles"))));
- reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPECopyRotate::resetStyles));
- reset_button->set_size_request(140,30);
- vbox->pack_start(*hbox, true,true,2);
- hbox->pack_start(*reset_button, false, false,2);
std::vector<Parameter *>::iterator it = param_vector.begin();
while (it != param_vector.end()) {
if ((*it)->widget_is_visible) {
@@ -332,6 +321,12 @@ Gtk::Widget * LPECopyRotate::newWidget()
++it;
}
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0));
+ Gtk::Button * reset_button = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset styles"))));
+ reset_button->signal_clicked().connect(sigc::mem_fun (*this,&LPECopyRotate::resetStyles));
+ reset_button->set_size_request(110,20);
+ vbox->pack_start(*hbox, true,true,2);
+ hbox->pack_start(*reset_button, false, false,2);
return dynamic_cast<Gtk::Widget *>(vbox);
}
@@ -344,7 +339,7 @@ LPECopyRotate::doOnApply(SPLPEItem const* lpeitem)
A = Point(boundingbox_X.min(), boundingbox_Y.middle());
B = Point(boundingbox_X.middle(), boundingbox_Y.middle());
- origin.param_setValue(A, true);
+ origin.param_setValue(A);
origin.param_update_default(A);
dist_angle_handle = L2(B - A);
dir = unit_vector(B - A);
@@ -366,13 +361,14 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem)
{
using namespace Geom;
original_bbox(lpeitem);
- if (copies_to_360) {
+ if (copies_to_360 && num_copies > 2) {
rotation_angle.param_set_value(360.0/(double)num_copies);
}
- if (fuse_paths && rotation_angle * num_copies > 360.1 && rotation_angle > 0) {
+
+ if ((method == RM_KALEIDOSCOPE || method == RM_FUSE) && rotation_angle * num_copies > 360.1 && rotation_angle > 0) {
num_copies.param_set_value(floor(360/rotation_angle));
}
- if (fuse_paths && copies_to_360) {
+ if ((method == RM_KALEIDOSCOPE || method == RM_FUSE) && mirror_copies && copies_to_360) {
num_copies.param_set_increments(2.0,10.0);
if ((int)num_copies%2 !=0) {
num_copies.param_set_value(num_copies+1);
@@ -391,7 +387,7 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem)
// I first suspected the minus sign to be a bug in 2geom but it is
// likely due to SVG's choice of coordinate system orientation (max)
bool near = Geom::are_near(previous_start_point, (Geom::Point)starting_point, 0.01);
- if (!near) {
+ if (!near) {
starting_angle.param_set_value(deg_from_rad(-angle_between(dir, starting_point - origin)));
if (GDK_SHIFT_MASK) {
dist_angle_handle = L2(B - A);
@@ -405,11 +401,11 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem)
start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle;
rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle;
near = Geom::are_near(start_pos, (Geom::Point)starting_point, 0.01);
- if (!near) {
- starting_point.param_setValue(start_pos, true);
+ if (!near) {
+ starting_point.param_setValue(start_pos);
}
previous_start_point = (Geom::Point)starting_point;
- if ( fuse_paths || copies_to_360 ) {
+ if ( method == RM_FUSE || copies_to_360 ) {
rot_pos = origin;
}
}
@@ -486,19 +482,21 @@ LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double s
}
Geom::PathVector tmp_path_helper;
Geom::Path append_path = original;
-
+ Geom::Point previous = original.finalPoint();
for (int i = 0; i < num_copies; ++i) {
Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i)));
Geom::Affine m = pre * rot * Geom::Translate(origin);
- if (i%2 != 0) {
- Geom::Point A = (Geom::Point)origin;
- Geom::Point B = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider;
- Geom::Line ls(A,B);
- m = Geom::reflection (ls.vector(), A);
+ if (i%2 != 0 && mirror_copies) {
+ Geom::Point point_a = (Geom::Point)origin;
+ Geom::Point point_b = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider;
+ Geom::Line ls(point_a, point_b);
+ m = Geom::reflection (ls.vector(), point_a);
+ append_path *= m;
} else {
append_path = original;
+ append_path *= m;
}
- append_path *= m;
+ previous = append_path.finalPoint();
if (tmp_path_helper.size() > 0) {
if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.finalPoint())) {
Geom::Path tmp_append = append_path.reversed();
@@ -588,118 +586,83 @@ Geom::PathVector
LPECopyRotate::doEffect_path (Geom::PathVector const & path_in)
{
Geom::PathVector path_out;
- if (split_items && (fuse_paths || join_paths)) {
+ double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
+ Geom::OptRect bbox = sp_lpe_item->geometricBounds();
+ size_divider = Geom::distance(origin,bbox) + (diagonal * 6);
+ Geom::Point line_start = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))) * size_divider;
+ Geom::Point line_end = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(rotation_angle + starting_angle))) * size_divider;
+ divider = Geom::Path(line_start);
+ divider.appendNew<Geom::LineSegment>((Geom::Point)origin);
+ divider.appendNew<Geom::LineSegment>(line_end);
+ divider.close();
+ half_dir = unit_vector(Geom::middle_point(line_start,line_end) - (Geom::Point)origin);
+ if (method == RM_KALEIDOSCOPE || method == RM_FUSE) {
+ if (method != RM_KALEIDOSCOPE) {
+ path_out = doEffect_path_post(path_in);
+ } else {
+ path_out = pathv_to_linear_and_cubic_beziers(path_in);
+ }
if (num_copies == 0) {
return path_out;
}
- path_out = pathv_to_linear_and_cubic_beziers(path_in);
- double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
- Geom::OptRect bbox = sp_lpe_item->geometricBounds();
- double size_divider = Geom::distance(origin,bbox) + (diagonal * 2);
- Geom::Point line_start = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(starting_angle))) * size_divider;
- Geom::Point line_end = origin + dir * Geom::Rotate(-(Geom::rad_from_deg(rotation_angle + starting_angle))) * size_divider;
- Geom::Path divider = Geom::Path(line_start);
- divider.appendNew<Geom::LineSegment>((Geom::Point)origin);
- divider.appendNew<Geom::LineSegment>(line_end);
- divider.close();
Geom::PathVector triangle;
triangle.push_back(divider);
Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(triangle, path_out);
- if (pig && ! path_out.empty() && !triangle.empty()) {
- //TODO: Here can produce a crash because some knows problems in new boolops code
+ if (pig && !path_out.empty() && !triangle.empty()) {
path_out = pig->getIntersection();
}
- Geom::Affine r = Geom::identity();
- Geom::Point dir = unit_vector(Geom::middle_point(line_start,line_end) - (Geom::Point)origin);
- Geom::Point gap = dir * split_gap;
- path_out *= Geom::Translate(gap);
- } else {
- // default behavior
- for (unsigned int i=0; i < path_in.size(); i++) {
- Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = path_in[i].toPwSb();
- Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect_pwd2(pwd2_in);
- Geom::PathVector path = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);
- // add the output path vector to the already accumulated vector:
- for (unsigned int j=0; j < path.size(); j++) {
- path_out.push_back(path[j]);
- }
+ path_out *= Geom::Translate(half_dir * gap);
+ if ( !split_items ) {
+ path_out *= Geom::Translate(half_dir * gap).inverse();
+ path_out = doEffect_path_post(path_out);
}
+ } else {
+ path_out = doEffect_path_post(path_in);
}
return pathv_to_linear_and_cubic_beziers(path_out);
}
-Geom::Piecewise<Geom::D2<Geom::SBasis> >
-LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
+Geom::PathVector
+LPECopyRotate::doEffect_path_post (Geom::PathVector const & path_in)
{
- using namespace Geom;
-
- if ((num_copies == 1 && !fuse_paths) || split_items) {
- return pwd2_in;
+ if ((split_items || num_copies == 1) && method != RM_FUSE && method != RM_KALEIDOSCOPE) {
+ return path_in;
}
- double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
- Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
- double size_divider = Geom::distance(origin,bbox) + (diagonal * 2);
- Geom::Point line_start = origin + dir * Rotate(-rad_from_deg(starting_angle)) * size_divider;
- Geom::Point line_end = origin + dir * Rotate(-rad_from_deg(rotation_angle + starting_angle)) * size_divider;
- //Note:: beter way to do this
- //Whith AppendNew have problems whith the crossing order
- Geom::Path divider = Geom::Path(line_start);
- divider.appendNew<Geom::LineSegment>((Geom::Point)origin);
- divider.appendNew<Geom::LineSegment>(line_end);
- Piecewise<D2<SBasis> > output;
- Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle));
- PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001));
- if (fuse_paths) {
- Geom::PathVector path_out;
- Geom::PathVector tmp_path;
- for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
- if (path_it->empty()) {
- continue;
- }
- bool end_open = false;
- if (path_it->closed()) {
- const Geom::Curve &closingline = path_it->back_closed();
- if (!are_near(closingline.initialPoint(), closingline.finalPoint())) {
- end_open = true;
- }
- }
- Geom::Path original = (Geom::Path)(*path_it);
- if (end_open && path_it->closed()) {
- original.close(false);
- original.appendNew<Geom::LineSegment>( original.initialPoint() );
- original.close(true);
- }
- tmp_path.push_back(original);
- setFusion(tmp_path, divider, size_divider);
- path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end());
- tmp_path.clear();
+ Geom::Affine pre = Geom::Translate(-origin) * Geom::Rotate(-Geom::rad_from_deg(starting_angle));
+ Geom::PathVector original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
+ Geom::PathVector output_pv;
+ Geom::PathVector output;
+ for (int i = 0; i < num_copies; ++i) {
+ Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * i));
+ Geom::Affine r = Geom::identity();
+ if( i%2 != 0 && mirror_copies) {
+ r *= Geom::Rotate(Geom::Angle(half_dir)).inverse();
+ r *= Geom::Scale(1, -1);
+ r *= Geom::Rotate(Geom::Angle(half_dir));
}
- if (path_out.size()>0) {
- output = paths_to_pw(path_out);
+ Geom::Affine t = pre * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)) * Geom::Translate(origin);
+ if(mirror_copies && i%2 != 0) {
+ t = pre * r * rot * Geom::Rotate(Geom::rad_from_deg(starting_angle)).inverse() * Geom::Translate(origin);
}
- } else {
- Geom::PathVector output_pv;
- for (int i = 0; i < num_copies; ++i) {
- Rotate rot(-rad_from_deg(rotation_angle * i));
- Affine t = pre * rot * Translate(origin);
- if (join_paths) {
- Geom::PathVector join_pv = path_from_piecewise(pwd2_in * t , 0.01);
- Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(output_pv, join_pv);
- if (pig) {
- if (!output_pv.empty()) {
- output_pv = pig->getUnion();
- } else {
- output_pv = join_pv;
- }
+ if (method == RM_FUSE || method == RM_KALEIDOSCOPE) {
+ Geom::PathVector join_pv = original_pathv * t;
+ join_pv *= Geom::Translate(half_dir * rot * gap);
+ Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(output_pv, join_pv);
+ if (pig) {
+ if (!output_pv.empty()) {
+ output_pv = pig->getUnion();
+ } else {
+ output_pv = join_pv;
}
- } else {
- output.concat(pwd2_in * t);
}
+ } else {
+ output_pv = path_in * t;
+ output.insert(output.end(), output_pv.begin(), output_pv.end());
}
- if (join_paths) {
- output = paths_to_pw(output_pv);
- }
+ }
+ if (method == RM_FUSE || method == RM_KALEIDOSCOPE) {
+ output = output_pv;
}
return output;
}
diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h
index dbec2e1c3..542a4e36e 100644
--- a/src/live_effects/lpe-copy_rotate.h
+++ b/src/live_effects/lpe-copy_rotate.h
@@ -15,6 +15,7 @@
*/
#include "live_effects/effect.h"
+#include "live_effects/parameter/enum.h"
#include "live_effects/parameter/parameter.h"
#include "live_effects/parameter/text.h"
#include "live_effects/parameter/point.h"
@@ -23,13 +24,20 @@
namespace Inkscape {
namespace LivePathEffect {
+enum RotateMethod {
+ RM_NORMAL,
+ RM_KALEIDOSCOPE,
+ RM_FUSE,
+ RM_END
+};
+
class LPECopyRotate : public Effect, GroupBBoxEffect {
public:
LPECopyRotate(LivePathEffectObject *lpeobject);
virtual ~LPECopyRotate();
virtual void doOnApply (SPLPEItem const* lpeitem);
virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in);
- virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
+ Geom::PathVector doEffect_path_post (Geom::PathVector const & path_in);
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
virtual void doAfterEffect (SPLPEItem const* lpeitem);
virtual void setFusion(Geom::PathVector &path_in, Geom::Path divider, double sizeDivider);
@@ -51,18 +59,21 @@ private:
ScalarParam starting_angle;
ScalarParam rotation_angle;
ScalarParam num_copies;
- ScalarParam split_gap;
+ ScalarParam gap;
BoolParam copies_to_360;
- BoolParam fuse_paths;
- BoolParam join_paths;
+ EnumParam<RotateMethod> method;
+ BoolParam mirror_copies;
BoolParam split_items;
Geom::Point A;
Geom::Point B;
Geom::Point dir;
+ Geom::Point half_dir;
Geom::Point start_pos;
Geom::Point rot_pos;
Geom::Point previous_start_point;
double dist_angle_handle;
+ double size_divider;
+ Geom::Path divider;
double previous_num_copies;
bool reset;
SPObject * container;
diff --git a/src/live_effects/lpe-curvestitch.cpp b/src/live_effects/lpe-curvestitch.cpp
index f2fc00aeb..f8d2e56ca 100644
--- a/src/live_effects/lpe-curvestitch.cpp
+++ b/src/live_effects/lpe-curvestitch.cpp
@@ -40,14 +40,14 @@ LPECurveStitch::LPECurveStitch(LivePathEffectObject *lpeobject) :
prop_scale(_("Scale _width:"), _("Scale the width of the stitch path"), "prop_scale", &wr, this, 1),
scale_y_rel(_("Scale _width relative to length"), _("Scale the width of the stitch path relative to its length"), "scale_y_rel", &wr, this, false)
{
- registerParameter( dynamic_cast<Parameter *>(&nrofpaths) );
- registerParameter( dynamic_cast<Parameter *>(&startpoint_edge_variation) );
- registerParameter( dynamic_cast<Parameter *>(&startpoint_spacing_variation) );
- registerParameter( dynamic_cast<Parameter *>(&endpoint_edge_variation) );
- registerParameter( dynamic_cast<Parameter *>(&endpoint_spacing_variation) );
- registerParameter( dynamic_cast<Parameter *>(&strokepath) );
- registerParameter( dynamic_cast<Parameter *>(&prop_scale) );
- registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );
+ registerParameter(&nrofpaths);
+ registerParameter(&startpoint_edge_variation);
+ registerParameter(&startpoint_spacing_variation);
+ registerParameter(&endpoint_edge_variation);
+ registerParameter(&endpoint_spacing_variation);
+ registerParameter(&strokepath );
+ registerParameter(&prop_scale);
+ registerParameter(&scale_y_rel);
nrofpaths.param_make_integer();
nrofpaths.param_set_range(2, Geom::infinity());
diff --git a/src/live_effects/lpe-dynastroke.cpp b/src/live_effects/lpe-dynastroke.cpp
index 50bbe6451..33e754a8a 100644
--- a/src/live_effects/lpe-dynastroke.cpp
+++ b/src/live_effects/lpe-dynastroke.cpp
@@ -55,17 +55,17 @@ LPEDynastroke::LPEDynastroke(LivePathEffectObject *lpeobject) :
capping(_("Capping:"), _("left capping"), "capping", &wr, this, "M 100,5 C 50,5 0,0 0,0 0,0 50,-5 100,-5")
{
- registerParameter( dynamic_cast<Parameter *>(& method) );
- registerParameter( dynamic_cast<Parameter *>(& width) );
- registerParameter( dynamic_cast<Parameter *>(& roundness) );
- registerParameter( dynamic_cast<Parameter *>(& angle) );
- //registerParameter( dynamic_cast<Parameter *>(& modulo_pi) );
- registerParameter( dynamic_cast<Parameter *>(& start_cap) );
- registerParameter( dynamic_cast<Parameter *>(& growfor) );
- registerParameter( dynamic_cast<Parameter *>(& end_cap) );
- registerParameter( dynamic_cast<Parameter *>(& fadefor) );
- registerParameter( dynamic_cast<Parameter *>(& round_ends) );
- registerParameter( dynamic_cast<Parameter *>(& capping) );
+ registerParameter(&method);
+ registerParameter(&width);
+ registerParameter(&roundness);
+ registerParameter(&angle);
+ //registerParameter(&modulo_pi) );
+ registerParameter(&start_cap);
+ registerParameter(&growfor);
+ registerParameter(&end_cap);
+ registerParameter(&fadefor);
+ registerParameter(&round_ends);
+ registerParameter(&capping);
width.param_set_range(0, Geom::infinity());
roundness.param_set_range(0.01, 1);
diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp
index 61a696435..8528ab14d 100644
--- a/src/live_effects/lpe-envelope.cpp
+++ b/src/live_effects/lpe-envelope.cpp
@@ -23,12 +23,12 @@ LPEEnvelope::LPEEnvelope(LivePathEffectObject *lpeobject) :
xx(_("_Enable left & right paths"), _("Enable the left and right deformation paths"), "xx", &wr, this, true),
yy(_("_Enable top & bottom paths"), _("Enable the top and bottom deformation paths"), "yy", &wr, this, true)
{
- registerParameter( dynamic_cast<Parameter *>(&yy) );
- registerParameter( dynamic_cast<Parameter *>(&xx) );
- registerParameter( dynamic_cast<Parameter *>(&bend_path1) );
- registerParameter( dynamic_cast<Parameter *>(&bend_path2) );
- registerParameter( dynamic_cast<Parameter *>(&bend_path3) );
- registerParameter( dynamic_cast<Parameter *>(&bend_path4) );
+ registerParameter(&yy);
+ registerParameter(&xx);
+ registerParameter(&bend_path1);
+ registerParameter(&bend_path2);
+ registerParameter(&bend_path3);
+ registerParameter(&bend_path4);
concatenate_before_pwd2 = true;
apply_to_clippath_and_mask = true;
}
diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp
index daa30d45a..4a3ad7508 100644
--- a/src/live_effects/lpe-extrude.cpp
+++ b/src/live_effects/lpe-extrude.cpp
@@ -27,7 +27,7 @@ LPEExtrude::LPEExtrude(LivePathEffectObject *lpeobject) :
show_orig_path = true;
concatenate_before_pwd2 = false;
- registerParameter( dynamic_cast<Parameter *>(&extrude_vector) );
+ registerParameter(&extrude_vector);
}
LPEExtrude::~LPEExtrude()
diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp
index 2e1fe0dc1..40fa91c68 100644
--- a/src/live_effects/lpe-fill-between-many.cpp
+++ b/src/live_effects/lpe-fill-between-many.cpp
@@ -25,11 +25,11 @@ LPEFillBetweenMany::LPEFillBetweenMany(LivePathEffectObject *lpeobject) :
join(_("Join subpaths"), _("Join subpaths"), "join", &wr, this, true),
close(_("Close"), _("Close path"), "close", &wr, this, true)
{
- registerParameter( dynamic_cast<Parameter *>(&linked_paths) );
- registerParameter( dynamic_cast<Parameter *>(&fuse) );
- registerParameter( dynamic_cast<Parameter *>(&allow_transforms) );
- registerParameter( dynamic_cast<Parameter *>(&join) );
- registerParameter( dynamic_cast<Parameter *>(&close) );
+ registerParameter(&linked_paths);
+ registerParameter(&fuse);
+ registerParameter(&allow_transforms);
+ registerParameter(&join);
+ registerParameter(&close);
transformmultiply = false;
}
diff --git a/src/live_effects/lpe-fill-between-strokes.cpp b/src/live_effects/lpe-fill-between-strokes.cpp
index 43fef4288..f8d86ae99 100644
--- a/src/live_effects/lpe-fill-between-strokes.cpp
+++ b/src/live_effects/lpe-fill-between-strokes.cpp
@@ -25,13 +25,13 @@ LPEFillBetweenStrokes::LPEFillBetweenStrokes(LivePathEffectObject *lpeobject) :
join(_("Join subpaths"), _("Join subpaths"), "join", &wr, this, true),
close(_("Close"), _("Close path"), "close", &wr, this, true)
{
- registerParameter( dynamic_cast<Parameter *>(&linked_path) );
- registerParameter( dynamic_cast<Parameter *>(&second_path) );
- registerParameter( dynamic_cast<Parameter *>(&reverse_second) );
- registerParameter( dynamic_cast<Parameter *>(&fuse) );
- registerParameter( dynamic_cast<Parameter *>(&allow_transforms) );
- registerParameter( dynamic_cast<Parameter *>(&join) );
- registerParameter( dynamic_cast<Parameter *>(&close) );
+ registerParameter(&linked_path);
+ registerParameter(&second_path);
+ registerParameter(&reverse_second);
+ registerParameter(&fuse);
+ registerParameter(&allow_transforms);
+ registerParameter(&join);
+ registerParameter(&close);
transformmultiply = false;
}
diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp
index 410d6f0fc..b9e96cb72 100644
--- a/src/live_effects/lpe-fillet-chamfer.cpp
+++ b/src/live_effects/lpe-fillet-chamfer.cpp
@@ -305,6 +305,8 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem)
} else {
satellites_param.setHelperSize(helper_size);
}
+ std::vector<size_t> selected_nodes_index;
+ size_t index = 0;
for (size_t i = 0; i < satellites.size(); ++i) {
for (size_t j = 0; j < satellites[i].size(); ++j) {
if (satellites[i][j].is_time != flexible) {
@@ -326,6 +328,11 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem)
satellites[i][j].has_mirror = mirror_knots;
}
satellites[i][j].hidden = hide_knots;
+ Geom::Curve const &curve_in = pathv[i][j];
+ if (only_selected && isNodePointSelected(curve_in.initialPoint()) ){
+ selected_nodes_index.push_back(index);
+ }
+ index ++;
}
}
if (!_pathvector_satellites) {
@@ -334,7 +341,6 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem)
_pathvector_satellites->setPathVector(pathv);
_pathvector_satellites->setSatellites(satellites);
if (only_selected) {
- setSelectedNodeIndex(pathv);
_pathvector_satellites->setSelected(selected_nodes_index);
}
satellites_param.setPathVectorSatellites(_pathvector_satellites);
diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp
index e95dc5f38..db3faa307 100644
--- a/src/live_effects/lpe-interpolate.cpp
+++ b/src/live_effects/lpe-interpolate.cpp
@@ -30,9 +30,9 @@ LPEInterpolate::LPEInterpolate(LivePathEffectObject *lpeobject) :
{
show_orig_path = true;
- registerParameter( dynamic_cast<Parameter *>(&trajectory_path) );
- registerParameter( dynamic_cast<Parameter *>(&equidistant_spacing) );
- registerParameter( dynamic_cast<Parameter *>(&number_of_steps) );
+ registerParameter(&trajectory_path);
+ registerParameter(&equidistant_spacing);
+ registerParameter(&number_of_steps);
number_of_steps.param_make_integer();
number_of_steps.param_set_range(2, Geom::infinity());
diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp
index 2defecb77..261612fdb 100644
--- a/src/live_effects/lpe-knot.cpp
+++ b/src/live_effects/lpe-knot.cpp
@@ -356,12 +356,12 @@ LPEKnot::LPEKnot(LivePathEffectObject *lpeobject) :
switcher(0.,0.)
{
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter( dynamic_cast<Parameter *>(&interruption_width) );
- registerParameter( dynamic_cast<Parameter *>(&prop_to_stroke_width) );
- registerParameter( dynamic_cast<Parameter *>(&add_stroke_width) );
- registerParameter( dynamic_cast<Parameter *>(&add_other_stroke_width) );
- registerParameter( dynamic_cast<Parameter *>(&switcher_size) );
- registerParameter( dynamic_cast<Parameter *>(&crossing_points_vector) );
+ registerParameter(&interruption_width);
+ registerParameter(&prop_to_stroke_width);
+ registerParameter(&add_stroke_width);
+ registerParameter(&add_other_stroke_width);
+ registerParameter(&switcher_size);
+ registerParameter(&crossing_points_vector);
_provides_knotholder_entities = true;
}
diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp
index acffed000..124a7a9c6 100644
--- a/src/live_effects/lpe-lattice.cpp
+++ b/src/live_effects/lpe-lattice.cpp
@@ -50,22 +50,22 @@ LPELattice::LPELattice(LivePathEffectObject *lpeobject) :
{
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter( dynamic_cast<Parameter *>(&grid_point0) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point1) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point2) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point3) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point4) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point5) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point6) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point7) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point8) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point9) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point10) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point11) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point12) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point13) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point14) );
- registerParameter( dynamic_cast<Parameter *>(&grid_point15) );
+ registerParameter(&grid_point0);
+ registerParameter(&grid_point1);
+ registerParameter(&grid_point2);
+ registerParameter(&grid_point3);
+ registerParameter(&grid_point4);
+ registerParameter(&grid_point5);
+ registerParameter(&grid_point6);
+ registerParameter(&grid_point7);
+ registerParameter(&grid_point8);
+ registerParameter(&grid_point9);
+ registerParameter(&grid_point10);
+ registerParameter(&grid_point11);
+ registerParameter(&grid_point12);
+ registerParameter(&grid_point13);
+ registerParameter(&grid_point14);
+ registerParameter(&grid_point15);
apply_to_clippath_and_mask = true;
}
diff --git a/src/live_effects/lpe-line_segment.cpp b/src/live_effects/lpe-line_segment.cpp
index cc024fb92..fd23da804 100644
--- a/src/live_effects/lpe-line_segment.cpp
+++ b/src/live_effects/lpe-line_segment.cpp
@@ -32,7 +32,7 @@ LPELineSegment::LPELineSegment(LivePathEffectObject *lpeobject) :
end_type(_("End type:"), _("Determines on which side the line or line segment is infinite."), "end_type", EndTypeConverter, &wr, this, END_OPEN_BOTH)
{
/* register all your parameters here, so Inkscape knows which parameters this effect has: */
- registerParameter( dynamic_cast<Parameter *>(&end_type) );
+ registerParameter(&end_type);
}
LPELineSegment::~LPELineSegment()
diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp
index 86d72615c..892744462 100644
--- a/src/live_effects/lpe-measure-line.cpp
+++ b/src/live_effects/lpe-measure-line.cpp
@@ -49,32 +49,33 @@ static const Util::EnumDataConverter<OrientationMethod> OMConverter(OrientationM
LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
- unit(_("Unit*"), _("Unit"), "unit", &wr, this, "px"),
- fontbutton(_("Font*"), _("Font Selector"), "fontbutton", &wr, this),
+ unit(_("Unit"), _("Unit"), "unit", &wr, this, "px"),
+ fontbutton(_("Font"), _("Font Selector"), "fontbutton", &wr, this),
orientation(_("Orientation"), _("Orientation method"), "orientation", OMConverter, &wr, this, OM_PARALLEL, false),
curve_linked(_("Curve on origin"), _("Curve on origin, set 0 to start/end"), "curve_linked", &wr, this, 1),
- precision(_("Precision*"), _("Precision"), "precision", &wr, this, 2),
- position(_("Position*"), _("Position"), "position", &wr, this, 5),
- text_top_bottom(_("Text top/bottom*"), _("Text top/bottom"), "text_top_bottom", &wr, this, 0),
- text_right_left(_("Text right/left*"), _("Text right/left"), "text_right_left", &wr, this, 0),
- helpline_distance(_("Helpline distance*"), _("Helpline distance"), "helpline_distance", &wr, this, 0.0),
- helpline_overlap(_("Helpline overlap*"), _("Helpline overlap"), "helpline_overlap", &wr, this, 2.0),
- scale(_("Scale*"), _("Scaling factor"), "scale", &wr, this, 1.0),
- format(_("Format*"), _("Format the number ex:{measure} {unit}, return to save"), "format", &wr, this,"{measure}{unit}"),
+ precision(_("Precision"), _("Precision"), "precision", &wr, this, 2),
+ position(_("Position"), _("Position"), "position", &wr, this, 5),
+ text_top_bottom(_("Text top/bottom"), _("Text top/bottom"), "text_top_bottom", &wr, this, 0),
+ text_right_left(_("Text right/left"), _("Text right/left"), "text_right_left", &wr, this, 0),
+ helpline_distance(_("Helpline distance"), _("Helpline distance"), "helpline_distance", &wr, this, 0.0),
+ helpline_overlap(_("Helpline overlap"), _("Helpline overlap"), "helpline_overlap", &wr, this, 2.0),
+ scale(_("Scale"), _("Scaling factor"), "scale", &wr, this, 1.0),
+ format(_("Format"), _("Format the number ex:{measure} {unit}, return to save"), "format", &wr, this,"{measure}{unit}"),
id_origin("id_origin", "id_origin", "id_origin", &wr, this,""),
arrows_outside(_("Arrows outside"), _("Arrows outside"), "arrows_outside", &wr, this, false),
- flip_side(_("Flip side*"), _("Flip side"), "flip_side", &wr, this, false),
- scale_sensitive(_("Scale sensitive*"), _("Costrained scale sensitive to transformed containers"), "scale_sensitive", &wr, this, true),
- local_locale(_("Local Number Format*"), _("Local number format"), "local_locale", &wr, this, true),
- line_group_05(_("Line Group 0.5*"), _("Line Group 0.5, from 0.7"), "line_group_05", &wr, this, true),
- rotate_anotation(_("Rotate Anotation*"), _("Rotate Anotation"), "rotate_anotation", &wr, this, true),
- hide_back(_("Hide if label over*"), _("Hide DIN line if label over"), "hide_back", &wr, this, true),
- dimline_format(_("CSS DIN line*"), _("Override CSS to DIN line, return to save, empty to reset to DIM"), "dimline_format", &wr, this,""),
- helperlines_format(_("CSS helpers*"), _("Override CSS to helper lines, return to save, empty to reset to DIM"), "helperlines_format", &wr, this,""),
- anotation_format(_("CSS anotation*"), _("Override CSS to anotation text, return to save, empty to reset to DIM"), "anotation_format", &wr, this,""),
- arrows_format(_("CSS arrows*"), _("Override CSS to arrows, return to save, empty to reset DIM"), "arrows_format", &wr, this,""),
+ flip_side(_("Flip side"), _("Flip side"), "flip_side", &wr, this, false),
+ scale_sensitive(_("Scale sensitive"), _("Costrained scale sensitive to transformed containers"), "scale_sensitive", &wr, this, true),
+ local_locale(_("Local Number Format"), _("Local number format"), "local_locale", &wr, this, true),
+ line_group_05(_("Line Group 0.5"), _("Line Group 0.5, from 0.7"), "line_group_05", &wr, this, true),
+ rotate_anotation(_("Rotate Anotation"), _("Rotate Anotation"), "rotate_anotation", &wr, this, true),
+ hide_back(_("Hide if label over"), _("Hide DIN line if label over"), "hide_back", &wr, this, true),
+ dimline_format(_("CSS DIN line"), _("Override CSS to DIN line, return to save, empty to reset to DIM"), "dimline_format", &wr, this,""),
+ helperlines_format(_("CSS helpers"), _("Override CSS to helper lines, return to save, empty to reset to DIM"), "helperlines_format", &wr, this,""),
+ anotation_format(_("CSS anotation"), _("Override CSS to anotation text, return to save, empty to reset to DIM"), "anotation_format", &wr, this,""),
+ arrows_format(_("CSS arrows"), _("Override CSS to arrows, return to save, empty to reset DIM"), "arrows_format", &wr, this,""),
expanded(false)
{
+ //set to true the parameters you want to be changed his default values
registerParameter(&unit);
registerParameter(&fontbutton);
registerParameter(&orientation);
@@ -99,39 +100,16 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) :
registerParameter(&anotation_format);
registerParameter(&arrows_format);
registerParameter(&id_origin);
+
id_origin.param_hide_canvas_text();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- Glib::ustring fontbutton_value = prefs->getString("/live_effects/measure-line/fontbutton");
- if(fontbutton_value.empty()){
- fontbutton_value = "Sans 10";
- }
- fontbutton.param_update_default(fontbutton_value);
- scale.param_update_default(prefs->getDouble("/live_effects/measure-line/scale", 1.0));
- precision.param_update_default(prefs->getInt("/live_effects/measure-line/precision", 2));
- position.param_update_default(prefs->getDouble("/live_effects/measure-line/position", 10.0));
- text_top_bottom.param_update_default(prefs->getDouble("/live_effects/measure-line/text_top_bottom", 5.0));
- helpline_distance.param_update_default(prefs->getDouble("/live_effects/measure-line/helpline_distance", 0.0));
- helpline_overlap.param_update_default(prefs->getDouble("/live_effects/measure-line/helpline_overlap", 0.0));
- Glib::ustring unit_value = prefs->getString("/live_effects/measure-line/unit");
- if(unit_value.empty()){
- unit_value = "px";
- }
- unit.param_update_default(unit_value);
+
Glib::ustring format_value = prefs->getString("/live_effects/measure-line/format");
if(format_value.empty()){
format_value = "{measure}{unit}";
}
- format.param_update_default(format_value);
- dimline_format.param_update_default(prefs->getString("/live_effects/measure-line/dimline_format"));
- helperlines_format.param_update_default(prefs->getString("/live_effects/measure-line/helperlines_format"));
- anotation_format.param_update_default(prefs->getString("/live_effects/measure-line/anotation_format"));
- arrows_format.param_update_default(prefs->getString("/live_effects/measure-line/arrows_format"));
- flip_side.param_update_default(prefs->getBool("/live_effects/measure-line/flip_side"));
- scale_sensitive.param_update_default(prefs->getBool("/live_effects/measure-line/scale_sensitive"));
- local_locale.param_update_default(prefs->getBool("/live_effects/measure-line/local_locale"));
- line_group_05.param_update_default(prefs->getBool("/live_effects/measure-line/line_group_05"));
- rotate_anotation.param_update_default(prefs->getBool("/live_effects/measure-line/rotate_anotation"));
- hide_back.param_update_default(prefs->getBool("/live_effects/measure-line/hide_back"));
+ format.param_update_default(format_value.c_str());
+
format.param_hide_canvas_text();
dimline_format.param_hide_canvas_text();
helperlines_format.param_hide_canvas_text();
@@ -375,7 +353,7 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl
items.push_back(id);
Geom::OptRect bounds = SP_ITEM(elemref)->bounds(SPItem::GEOMETRIC_BBOX);
if (bounds) {
- anotation_width = bounds->width() * 1.4;
+ anotation_width = bounds->width() * 1.15;
}
}
@@ -405,8 +383,14 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, const char * id, b
k = (Geom::distance(start,end)/2.0) - arrow_gap - (anotation_width/2.0);
}
if (Geom::distance(start,end) < anotation_width){
- return;
+ if ((elemref = document->getObjectById(id))) {
+ if (remove) {
+ elemref->deleteObject();
+ }
+ return;
+ }
}
+ //k = std::max(k , arrow_gap -1);
Geom::Ray ray(end, start);
Geom::Coord angle = ray.angle();
line_path.start(start);
@@ -527,7 +511,6 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem)
pathvector *= writed_transform;
if ((Glib::ustring(format.param_getSVGValue()).empty())) {
format.param_setValue(Glib::ustring("{measure}{unit}"));
- this->upd_params = true;
}
size_t ncurves = pathvector.curveCount();
if (ncurves != (size_t)curve_linked.param_get_max()) {
@@ -622,6 +605,9 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem)
}
bool overflow = false;
const char * downline = g_strdup(Glib::ustring("downline-").append(this->getRepr()->attribute("id")).c_str());
+ //delete residual lines if exist
+ createLine(Geom::Point(),Geom::Point(), downline, true, overflow, true, false);
+ //Create it
if ((anotation_width/2) + std::abs(text_right_left) > Geom::distance(start,end)/2.0) {
Geom::Point sstart = end - Point::polar(angle_cross, position);
Geom::Point send = end - Point::polar(angle_cross, position);
@@ -645,9 +631,6 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem)
}
overflow = true;
createLine(sstart, prog_end, downline, true, overflow, false, false);
- } else {
- //erase it
- createLine(Geom::Point(),Geom::Point(), downline, true, overflow, true, false);
}
//LINE
arrow_gap = 8 * Inkscape::Util::Quantity::convert(0.35 / doc_scale, "mm", display_unit.c_str());
@@ -708,44 +691,41 @@ Gtk::Widget *LPEMeasureLine::newWidget()
vbox->set_spacing(2);
std::vector<Parameter *>::iterator it = param_vector.begin();
- Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0));
Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) );
vbox_expander->set_border_width(0);
vbox_expander->set_spacing(2);
while (it != param_vector.end()) {
if ((*it)->widget_is_visible) {
Parameter *param = *it;
- Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
- Glib::ustring *tip = param->param_getTooltip();
- if (widg) {
- if (param->param_key != "dimline_format" &&
- param->param_key != "helperlines_format" &&
- param->param_key != "arrows_format" &&
- param->param_key != "anotation_format") {
- vbox->pack_start(*widg, true, true, 2);
- } else {
- vbox_expander->pack_start(*widg, true, true, 2);
- }
- if (tip) {
- widg->set_tooltip_text(*tip);
- } else {
- widg->set_tooltip_text("");
- widg->set_has_tooltip(false);
+ if (param->param_key != "id_origin") {
+ Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
+ Glib::ustring *tip = param->param_getTooltip();
+ if (widg) {
+ if (param->param_key != "dimline_format" &&
+ param->param_key != "helperlines_format" &&
+ param->param_key != "arrows_format" &&
+ param->param_key != "anotation_format") {
+ vbox->pack_start(*widg, true, true, 2);
+ } else {
+ vbox_expander->pack_start(*widg, true, true, 2);
+ }
+ if (tip) {
+ widg->set_tooltip_text(*tip);
+ } else {
+ widg->set_tooltip_text("");
+ widg->set_has_tooltip(false);
+ }
}
}
}
++it;
}
- Gtk::Button *save_default = Gtk::manage(new Gtk::Button(Glib::ustring(_("Save '*' as default"))));
- save_default->signal_clicked().connect(sigc::mem_fun(*this, &LPEMeasureLine::saveDefault));
- button1->pack_start(*save_default, true, true, 2);
expander = Gtk::manage(new Gtk::Expander(Glib::ustring(_("Show DIM CSS style override"))));
expander->add(*vbox_expander);
expander->set_expanded(expanded);
expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPEMeasureLine::onExpanderChanged) );
vbox->pack_start(*expander, true, true, 2);
- vbox->pack_start(*button1, true, true, 2);
return dynamic_cast<Gtk::Widget *>(vbox);
}
@@ -766,31 +746,6 @@ LPEMeasureLine::doEffect_path(Geom::PathVector const &path_in)
return path_in;
}
-void
-LPEMeasureLine::saveDefault()
-{
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setString("/live_effects/measure-line/fontbutton", Glib::ustring(fontbutton.param_getSVGValue()));
- prefs->setDouble("/live_effects/measure-line/scale", scale);
- prefs->setInt("/live_effects/measure-line/precision", precision);
- prefs->setDouble("/live_effects/measure-line/position", position);
- prefs->setDouble("/live_effects/measure-line/text_top_bottom", text_top_bottom);
- prefs->setDouble("/live_effects/measure-line/helpline_distance", helpline_distance);
- prefs->setDouble("/live_effects/measure-line/helpline_overlap", helpline_overlap);
- prefs->setString("/live_effects/measure-line/unit", Glib::ustring(unit.get_abbreviation()));
- prefs->setString("/live_effects/measure-line/format", Glib::ustring(format.param_getSVGValue()));
- prefs->setString("/live_effects/measure-line/dimline_format", Glib::ustring(dimline_format.param_getSVGValue()));
- prefs->setString("/live_effects/measure-line/helperlines_format", Glib::ustring(helperlines_format.param_getSVGValue()));
- prefs->setString("/live_effects/measure-line/anotation_format", Glib::ustring(anotation_format.param_getSVGValue()));
- prefs->setString("/live_effects/measure-line/arrows_format", Glib::ustring(arrows_format.param_getSVGValue()));
- prefs->setBool("/live_effects/measure-line/flip_side", flip_side);
- prefs->setBool("/live_effects/measure-line/scale_sensitive", scale_sensitive);
- prefs->setBool("/live_effects/measure-line/local_locale", local_locale);
- prefs->setBool("/live_effects/measure-line/line_group_05", line_group_05);
- prefs->setBool("/live_effects/measure-line/rotate_anotation", rotate_anotation);
- prefs->setBool("/live_effects/measure-line/hide_back", hide_back);
-}
-
}; //namespace LivePathEffect
}; /* namespace Inkscape */
diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h
index 724c0d924..b42f7cfd5 100644
--- a/src/live_effects/lpe-measure-line.h
+++ b/src/live_effects/lpe-measure-line.h
@@ -49,7 +49,6 @@ public:
void createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove, bool valid);
void onExpanderChanged();
void createArrowMarker(const char * mode);
- void saveDefault();
virtual Gtk::Widget *newWidget();
private:
UnitParam unit;
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index 97015c34d..4e93a2572 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -126,61 +126,61 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
point_b = Geom::Point(center_point[X],boundingbox_Y.max());
}
if ((Geom::Point)start_point == (Geom::Point)end_point) {
- start_point.param_setValue(point_a, true);
- end_point.param_setValue(point_b, true);
+ start_point.param_setValue(point_a);
+ end_point.param_setValue(point_b);
previous_center = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point);
- center_point.param_setValue(previous_center, true);
+ center_point.param_setValue(previous_center);
return;
}
if ( mode == MT_X || mode == MT_Y ) {
if (!are_near(previous_center, (Geom::Point)center_point, 0.01)) {
center_point.param_setValue(Geom::middle_point(point_a, point_b), true);
- end_point.param_setValue(point_b, true);
- start_point.param_setValue(point_a, true);
+ end_point.param_setValue(point_b);
+ start_point.param_setValue(point_a);
} else {
if ( mode == MT_X ) {
if (!are_near(start_point[X], point_a[X], 0.01)) {
- start_point.param_setValue(point_a, true);
+ start_point.param_setValue(point_a);
}
if (!are_near(end_point[X], point_b[X], 0.01)) {
- end_point.param_setValue(point_b, true);
+ end_point.param_setValue(point_b);
}
} else { //MT_Y
if (!are_near(start_point[Y], point_a[Y], 0.01)) {
- start_point.param_setValue(point_a, true);
+ start_point.param_setValue(point_a);
}
if (!are_near(end_point[Y], point_b[Y], 0.01)) {
- end_point.param_setValue(point_b, true);
+ end_point.param_setValue(point_b);
}
}
}
} else if ( mode == MT_FREE) {
if (are_near(previous_center, (Geom::Point)center_point, 0.01)) {
- center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point), true);
+ center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point));
} else {
Geom::Point trans = center_point - Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point);
- start_point.param_setValue(start_point * trans, true);
- end_point.param_setValue(end_point * trans, true);
+ start_point.param_setValue(start_point * trans);
+ end_point.param_setValue(end_point * trans);
}
} else if ( mode == MT_V){
SPDocument * document = SP_ACTIVE_DOCUMENT;
if (document) {
Geom::Affine transform = i2anc_affine(SP_OBJECT(lpeitem), NULL).inverse();
Geom::Point sp = Geom::Point(document->getWidth().value("px")/2.0, 0) * transform;
- start_point.param_setValue(sp, true);
+ start_point.param_setValue(sp);
Geom::Point ep = Geom::Point(document->getWidth().value("px")/2.0, document->getHeight().value("px")) * transform;
- end_point.param_setValue(ep, true);
- center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point), true);
+ end_point.param_setValue(ep);
+ center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point));
}
} else { //horizontal page
SPDocument * document = SP_ACTIVE_DOCUMENT;
if (document) {
Geom::Affine transform = i2anc_affine(SP_OBJECT(lpeitem), NULL).inverse();
Geom::Point sp = Geom::Point(0, document->getHeight().value("px")/2.0) * transform;
- start_point.param_setValue(sp, true);
+ start_point.param_setValue(sp);
Geom::Point ep = Geom::Point(document->getWidth().value("px"), document->getHeight().value("px")/2.0) * transform;
- end_point.param_setValue(ep, true);
- center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point), true);
+ end_point.param_setValue(ep);
+ center_point.param_setValue(Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point));
}
}
previous_center = center_point;
@@ -335,7 +335,6 @@ LPEMirrorSymmetry::newWidget()
++it;
}
- this->upd_params = false;
return dynamic_cast<Gtk::Widget *>(vbox);
}
@@ -382,7 +381,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem)
start_point.param_update_default(point_a);
end_point.param_setValue(point_b);
end_point.param_update_default(point_b);
- center_point.param_setValue(point_c, true);
+ center_point.param_setValue(point_c);
previous_center = center_point;
SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem);
if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet
diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp
index 057f404e0..a5d1d23c8 100644
--- a/src/live_effects/lpe-offset.cpp
+++ b/src/live_effects/lpe-offset.cpp
@@ -27,7 +27,7 @@ LPEOffset::LPEOffset(LivePathEffectObject *lpeobject) :
{
show_orig_path = true;
apply_to_clippath_and_mask = true;
- registerParameter(dynamic_cast<Parameter *>(&offset_pt));
+ registerParameter(&offset_pt);
}
LPEOffset::~LPEOffset()
@@ -39,7 +39,7 @@ LPEOffset::doOnApply(SPLPEItem const* lpeitem)
{
Geom::Point offset = *(SP_SHAPE(lpeitem)->_curve->first_point());
offset_pt.param_update_default(offset);
- offset_pt.param_setValue(offset,true);
+ offset_pt.param_setValue(offset);
}
static void append_half_circle(Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2,
diff --git a/src/live_effects/lpe-parallel.cpp b/src/live_effects/lpe-parallel.cpp
index 276749c43..271442c7d 100644
--- a/src/live_effects/lpe-parallel.cpp
+++ b/src/live_effects/lpe-parallel.cpp
@@ -51,9 +51,9 @@ LPEParallel::LPEParallel(LivePathEffectObject *lpeobject) :
show_orig_path = true;
_provides_knotholder_entities = true;
- registerParameter(dynamic_cast<Parameter *>(&offset_pt));
- registerParameter( dynamic_cast<Parameter *>(&length_left) );
- registerParameter( dynamic_cast<Parameter *>(&length_right) );
+ registerParameter(&offset_pt);
+ registerParameter(&length_left);
+ registerParameter(&length_right);
}
LPEParallel::~LPEParallel()
diff --git a/src/live_effects/lpe-path_length.cpp b/src/live_effects/lpe-path_length.cpp
index a06dbde98..61818a73b 100644
--- a/src/live_effects/lpe-path_length.cpp
+++ b/src/live_effects/lpe-path_length.cpp
@@ -26,10 +26,10 @@ LPEPathLength::LPEPathLength(LivePathEffectObject *lpeobject) :
unit(_("Unit:"), _("Unit"), "unit", &wr, this),
display_unit(_("Display unit"), _("Print unit after path length"), "display_unit", &wr, this, true)
{
- registerParameter(dynamic_cast<Parameter *>(&scale));
- registerParameter(dynamic_cast<Parameter *>(&info_text));
- registerParameter(dynamic_cast<Parameter *>(&unit));
- registerParameter(dynamic_cast<Parameter *>(&display_unit));
+ registerParameter(&scale);
+ registerParameter(&info_text);
+ registerParameter(&unit);
+ registerParameter(&display_unit);
}
LPEPathLength::~LPEPathLength()
diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp
index 966e9020e..b026bbc22 100644
--- a/src/live_effects/lpe-patternalongpath.cpp
+++ b/src/live_effects/lpe-patternalongpath.cpp
@@ -85,16 +85,16 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) :
fuse_tolerance(_("_Fuse nearby ends:"), _("Fuse ends closer than this number. 0 means don't fuse."),
"fuse_tolerance", &wr, this, 0)
{
- registerParameter( dynamic_cast<Parameter *>(&pattern) );
- registerParameter( dynamic_cast<Parameter *>(&copytype) );
- registerParameter( dynamic_cast<Parameter *>(&prop_scale) );
- registerParameter( dynamic_cast<Parameter *>(&scale_y_rel) );
- registerParameter( dynamic_cast<Parameter *>(&spacing) );
- registerParameter( dynamic_cast<Parameter *>(&normal_offset) );
- registerParameter( dynamic_cast<Parameter *>(&tang_offset) );
- registerParameter( dynamic_cast<Parameter *>(&prop_units) );
- registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) );
- registerParameter( dynamic_cast<Parameter *>(&fuse_tolerance) );
+ registerParameter(&pattern);
+ registerParameter(&copytype);
+ registerParameter(&prop_scale);
+ registerParameter(&scale_y_rel);
+ registerParameter(&spacing);
+ registerParameter(&normal_offset);
+ registerParameter(&tang_offset);
+ registerParameter(&prop_units);
+ registerParameter(&vertical_pattern);
+ registerParameter(&fuse_tolerance);
prop_scale.param_set_digits(3);
prop_scale.param_set_increments(0.01, 0.10);
diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp
index bce22250a..dab169cfe 100644
--- a/src/live_effects/lpe-perp_bisector.cpp
+++ b/src/live_effects/lpe-perp_bisector.cpp
@@ -99,8 +99,8 @@ LPEPerpBisector::LPEPerpBisector(LivePathEffectObject *lpeobject) :
_provides_knotholder_entities = true;
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter( dynamic_cast<Parameter *>(&length_left) );
- registerParameter( dynamic_cast<Parameter *>(&length_right) );
+ registerParameter(&length_left);
+ registerParameter(&length_right);
}
LPEPerpBisector::~LPEPerpBisector()
diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp
index 365ff5389..3cff83fed 100644
--- a/src/live_effects/lpe-perspective-envelope.cpp
+++ b/src/live_effects/lpe-perspective-envelope.cpp
@@ -110,15 +110,15 @@ void LPEPerspectiveEnvelope::doEffect(SPCurve *curve)
int position_c = Geom::sgn(Geom::cross(handles[2] - handles[3], handles[0] - handles[3]));
if (position_a != 1 && move0) {
Geom::Point point_a = line_a.pointAt(line_a.nearestTime(handles[0]));
- down_left_point.param_setValue(point_a, true);
+ down_left_point.param_setValue(point_a);
}
if (position_b == 1 && move0) {
Geom::Point point_b = line_b.pointAt(line_b.nearestTime(handles[0]));
- down_left_point.param_setValue(point_b, true);
+ down_left_point.param_setValue(point_b);
}
if (position_c == 1 && move0) {
Geom::Point point_c = line_c.pointAt(line_c.nearestTime(handles[0]));
- down_left_point.param_setValue(point_c, true);
+ down_left_point.param_setValue(point_c);
}
line_a.setPoints(handles[0],handles[2]);
line_b.setPoints(handles[2],handles[3]);
@@ -128,15 +128,15 @@ void LPEPerspectiveEnvelope::doEffect(SPCurve *curve)
position_c = Geom::sgn(Geom::cross(handles[3] - handles[0], handles[1] - handles[0]));
if (position_a != 1 && move1) {
Geom::Point point_a = line_a.pointAt(line_a.nearestTime(handles[1]));
- up_left_point.param_setValue(point_a, true);
+ up_left_point.param_setValue(point_a);
}
if (position_b == 1 && move1) {
Geom::Point point_b = line_b.pointAt(line_b.nearestTime(handles[1]));
- up_left_point.param_setValue(point_b, true);
+ up_left_point.param_setValue(point_b);
}
if (position_c == 1 && move1) {
Geom::Point point_c = line_c.pointAt(line_c.nearestTime(handles[1]));
- up_left_point.param_setValue(point_c, true);
+ up_left_point.param_setValue(point_c);
}
line_a.setPoints(handles[1],handles[3]);
line_b.setPoints(handles[3],handles[0]);
@@ -146,15 +146,15 @@ void LPEPerspectiveEnvelope::doEffect(SPCurve *curve)
position_c = Geom::sgn(Geom::cross(handles[0] - handles[1], handles[2] - handles[1]));
if (position_a != 1 && move2) {
Geom::Point point_a = line_a.pointAt(line_a.nearestTime(handles[2]));
- up_right_point.param_setValue(point_a, true);
+ up_right_point.param_setValue(point_a);
}
if (position_b == 1 && move2) {
Geom::Point point_b = line_b.pointAt(line_b.nearestTime(handles[2]));
- up_right_point.param_setValue(point_b, true);
+ up_right_point.param_setValue(point_b);
}
if (position_c == 1 && move2) {
Geom::Point point_c = line_c.pointAt(line_c.nearestTime(handles[2]));
- up_right_point.param_setValue(point_c, true);
+ up_right_point.param_setValue(point_c);
}
line_a.setPoints(handles[2],handles[0]);
line_b.setPoints(handles[0],handles[1]);
@@ -164,15 +164,15 @@ void LPEPerspectiveEnvelope::doEffect(SPCurve *curve)
position_c = Geom::sgn(Geom::cross(handles[1] - handles[2], handles[3] - handles[2]));
if (position_a != 1 && move3) {
Geom::Point point_a = line_a.pointAt(line_a.nearestTime(handles[3]));
- down_right_point.param_setValue(point_a, true);
+ down_right_point.param_setValue(point_a);
}
if (position_b == 1 && move3) {
Geom::Point point_b = line_b.pointAt(line_b.nearestTime(handles[3]));
- down_right_point.param_setValue(point_b, true);
+ down_right_point.param_setValue(point_b);
}
if (position_c == 1 && move3) {
Geom::Point point_c = line_c.pointAt(line_c.nearestTime(handles[3]));
- down_right_point.param_setValue(point_c, true);
+ down_right_point.param_setValue(point_c);
}
} else {
handles.resize(4);
@@ -434,8 +434,8 @@ LPEPerspectiveEnvelope::vertical(PointParam &param_one, PointParam &param_two, G
}
A[Geom::X] = nearest[Geom::X] - distance_middle;
B[Geom::X] = nearest[Geom::X] + distance_middle;
- param_one.param_setValue(A, true);
- param_two.param_setValue(B, true);
+ param_one.param_setValue(A);
+ param_two.param_setValue(B);
}
void
@@ -455,8 +455,8 @@ LPEPerspectiveEnvelope::horizontal(PointParam &param_one, PointParam &param_two,
}
A[Geom::Y] = nearest[Geom::Y] - distance_middle;
B[Geom::Y] = nearest[Geom::Y] + distance_middle;
- param_one.param_setValue(A, true);
- param_two.param_setValue(B, true);
+ param_one.param_setValue(A);
+ param_two.param_setValue(B);
}
void
diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp
index b83fb67d7..435c91c2d 100644
--- a/src/live_effects/lpe-perspective_path.cpp
+++ b/src/live_effects/lpe-perspective_path.cpp
@@ -51,11 +51,11 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) :
uses_plane_xy(_("Uses XY plane?"), _("If true, put the path on the left side of an imaginary box, otherwise on the right side"), "uses_plane_xy", &wr, this, true)
{
// register all your parameters here, so Inkscape knows which parameters this effect has:
- registerParameter( dynamic_cast<Parameter *>(&scalex) );
- registerParameter( dynamic_cast<Parameter *>(&scaley) );
- registerParameter( dynamic_cast<Parameter *>(&offsetx) );
- registerParameter( dynamic_cast<Parameter *>(&offsety) );
- registerParameter( dynamic_cast<Parameter *>(&uses_plane_xy) );
+ registerParameter( &scalex);
+ registerParameter( &scaley);
+ registerParameter( &offsetx);
+ registerParameter( &offsety);
+ registerParameter( &uses_plane_xy);
concatenate_before_pwd2 = true; // don't split the path into its subpaths
_provides_knotholder_entities = true;
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index e9f3975c7..d87f92fcc 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -179,14 +179,14 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) :
interpolator_beta.addSlider(true);
interpolator_beta.param_set_range(0.,1.);
- registerParameter( dynamic_cast<Parameter *>(&offset_points) );
- registerParameter( dynamic_cast<Parameter *>(&sort_points) );
- registerParameter( dynamic_cast<Parameter *>(&interpolator_type) );
- registerParameter( dynamic_cast<Parameter *>(&interpolator_beta) );
- registerParameter( dynamic_cast<Parameter *>(&start_linecap_type) );
- registerParameter( dynamic_cast<Parameter *>(&linejoin_type) );
- registerParameter( dynamic_cast<Parameter *>(&miter_limit) );
- registerParameter( dynamic_cast<Parameter *>(&end_linecap_type) );
+ registerParameter(&offset_points);
+ registerParameter(&sort_points);
+ registerParameter(&interpolator_type);
+ registerParameter(&interpolator_beta);
+ registerParameter(&start_linecap_type);
+ registerParameter(&linejoin_type);
+ registerParameter(&miter_limit);
+ registerParameter(&end_linecap_type);
}
LPEPowerStroke::~LPEPowerStroke()
diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp
index aa0db920b..47613f58e 100644
--- a/src/live_effects/lpe-recursiveskeleton.cpp
+++ b/src/live_effects/lpe-recursiveskeleton.cpp
@@ -28,7 +28,7 @@ LPERecursiveSkeleton::LPERecursiveSkeleton(LivePathEffectObject *lpeobject) :
concatenate_before_pwd2 = true;
iterations.param_make_integer(true);
iterations.param_set_range(1, 15);
- registerParameter( dynamic_cast<Parameter *>(&iterations) );
+ registerParameter(&iterations);
}
diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp
index 3cc8658ea..d832b3615 100644
--- a/src/live_effects/lpe-rough-hatches.cpp
+++ b/src/live_effects/lpe-rough-hatches.cpp
@@ -241,26 +241,26 @@ LPERoughHatches::LPERoughHatches(LivePathEffectObject *lpeobject) :
//
bender(_("Global bending"), _("Relative position to a reference point defines global bending direction and amount"), "bender", &wr, this, Geom::Point(-5,0))
{
- registerParameter( dynamic_cast<Parameter *>(&direction) );
- registerParameter( dynamic_cast<Parameter *>(&dist_rdm) );
- registerParameter( dynamic_cast<Parameter *>(&growth) );
- registerParameter( dynamic_cast<Parameter *>(&do_bend) );
- registerParameter( dynamic_cast<Parameter *>(&bender) );
- registerParameter( dynamic_cast<Parameter *>(&top_edge_variation) );
- registerParameter( dynamic_cast<Parameter *>(&bot_edge_variation) );
- registerParameter( dynamic_cast<Parameter *>(&top_tgt_variation) );
- registerParameter( dynamic_cast<Parameter *>(&bot_tgt_variation) );
- registerParameter( dynamic_cast<Parameter *>(&scale_tf) );
- registerParameter( dynamic_cast<Parameter *>(&scale_tb) );
- registerParameter( dynamic_cast<Parameter *>(&scale_bf) );
- registerParameter( dynamic_cast<Parameter *>(&scale_bb) );
- registerParameter( dynamic_cast<Parameter *>(&top_smth_variation) );
- registerParameter( dynamic_cast<Parameter *>(&bot_smth_variation) );
- registerParameter( dynamic_cast<Parameter *>(&fat_output) );
- registerParameter( dynamic_cast<Parameter *>(&stroke_width_top) );
- registerParameter( dynamic_cast<Parameter *>(&stroke_width_bot) );
- registerParameter( dynamic_cast<Parameter *>(&front_thickness) );
- registerParameter( dynamic_cast<Parameter *>(&back_thickness) );
+ registerParameter(&direction);
+ registerParameter(&dist_rdm);
+ registerParameter(&growth);
+ registerParameter(&do_bend);
+ registerParameter(&bender);
+ registerParameter(&top_edge_variation);
+ registerParameter(&bot_edge_variation);
+ registerParameter(&top_tgt_variation);
+ registerParameter(&bot_tgt_variation);
+ registerParameter(&scale_tf);
+ registerParameter(&scale_tb);
+ registerParameter(&scale_bf);
+ registerParameter(&scale_bb);
+ registerParameter(&top_smth_variation);
+ registerParameter(&bot_smth_variation);
+ registerParameter(&fat_output);
+ registerParameter(&stroke_width_top);
+ registerParameter(&stroke_width_bot);
+ registerParameter(&front_thickness);
+ registerParameter(&back_thickness);
//hatch_dist.param_set_range(0.1, Geom::infinity());
growth.param_set_range(0, Geom::infinity());
diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp
index 60c2a3e1c..852592219 100644
--- a/src/live_effects/lpe-ruler.cpp
+++ b/src/live_effects/lpe-ruler.cpp
@@ -45,15 +45,15 @@ LPERuler::LPERuler(LivePathEffectObject *lpeobject) :
offset(_("_Offset:"), _("Offset of first mark"), "offset", &wr, this, 0.0),
border_marks(_("Border marks:"), _("Choose whether to draw marks at the beginning and end of the path"), "border_marks", BorderMarkTypeConverter, &wr, this, BORDERMARK_BOTH)
{
- registerParameter(dynamic_cast<Parameter *>(&unit));
- registerParameter(dynamic_cast<Parameter *>(&mark_distance));
- registerParameter(dynamic_cast<Parameter *>(&mark_length));
- registerParameter(dynamic_cast<Parameter *>(&minor_mark_length));
- registerParameter(dynamic_cast<Parameter *>(&major_mark_steps));
- registerParameter(dynamic_cast<Parameter *>(&shift));
- registerParameter(dynamic_cast<Parameter *>(&offset));
- registerParameter(dynamic_cast<Parameter *>(&mark_dir));
- registerParameter(dynamic_cast<Parameter *>(&border_marks));
+ registerParameter(&unit);
+ registerParameter(&mark_distance);
+ registerParameter(&mark_length);
+ registerParameter(&minor_mark_length);
+ registerParameter(&major_mark_steps);
+ registerParameter(&shift);
+ registerParameter(&offset);
+ registerParameter(&mark_dir);
+ registerParameter(&border_marks);
major_mark_steps.param_make_integer();
major_mark_steps.param_set_range(1, 1000);
diff --git a/src/live_effects/lpe-skeleton.cpp b/src/live_effects/lpe-skeleton.cpp
index 4fc18cee2..d3c94269a 100644
--- a/src/live_effects/lpe-skeleton.cpp
+++ b/src/live_effects/lpe-skeleton.cpp
@@ -37,7 +37,7 @@ LPESkeleton::LPESkeleton(LivePathEffectObject *lpeobject) :
//_provides_knotholder_entities
/* register all your parameters here, so Inkscape knows which parameters this effect has: */
- registerParameter( dynamic_cast<Parameter *>(&number) );
+ registerParameter(&number);
}
LPESkeleton::~LPESkeleton()
diff --git a/src/live_effects/lpe-sketch.cpp b/src/live_effects/lpe-sketch.cpp
index e01516f2e..e3376b7e5 100644
--- a/src/live_effects/lpe-sketch.cpp
+++ b/src/live_effects/lpe-sketch.cpp
@@ -62,25 +62,25 @@ LPESketch::LPESketch(LivePathEffectObject *lpeobject) :
// register all your parameters here, so Inkscape knows which parameters this effect has:
//Add some comment in the UI: *warning* the precise output of this effect might change in future releases!
//convert to path if you want to keep exact output unchanged in future releases...
- //registerParameter( dynamic_cast<Parameter *>(&testpointA) );
- registerParameter( dynamic_cast<Parameter *>(&nbiter_approxstrokes) );
- registerParameter( dynamic_cast<Parameter *>(&strokelength) );
- registerParameter( dynamic_cast<Parameter *>(&strokelength_rdm) );
- registerParameter( dynamic_cast<Parameter *>(&strokeoverlap) );
- registerParameter( dynamic_cast<Parameter *>(&strokeoverlap_rdm) );
- registerParameter( dynamic_cast<Parameter *>(&ends_tolerance) );
- registerParameter( dynamic_cast<Parameter *>(&parallel_offset) );
- registerParameter( dynamic_cast<Parameter *>(&tremble_size) );
- registerParameter( dynamic_cast<Parameter *>(&tremble_frequency) );
+ //registerParameter(&testpointA) );
+ registerParameter(&nbiter_approxstrokes);
+ registerParameter(&strokelength);
+ registerParameter(&strokelength_rdm);
+ registerParameter(&strokeoverlap);
+ registerParameter(&strokeoverlap_rdm);
+ registerParameter(&ends_tolerance);
+ registerParameter(&parallel_offset);
+ registerParameter(&tremble_size);
+ registerParameter(&tremble_frequency);
#ifdef LPE_SKETCH_USE_CONSTRUCTION_LINES
- registerParameter( dynamic_cast<Parameter *>(&nbtangents) );
- registerParameter( dynamic_cast<Parameter *>(&tgt_places_rdmness) );
- registerParameter( dynamic_cast<Parameter *>(&tgtscale) );
- registerParameter( dynamic_cast<Parameter *>(&tgtlength) );
- registerParameter( dynamic_cast<Parameter *>(&tgtlength_rdm) );
+ registerParameter(&nbtangents);
+ registerParameter(&tgt_places_rdmness);
+ registerParameter(&tgtscale);
+ registerParameter(&tgtlength);
+ registerParameter(&tgtlength_rdm);
#ifdef LPE_SKETCH_USE_CURVATURE
- registerParameter( dynamic_cast<Parameter *>(&min_curvature) );
- registerParameter( dynamic_cast<Parameter *>(&max_curvature) );
+ registerParameter(&min_curvature);
+ registerParameter(&max_curvature);
#endif
#endif
diff --git a/src/live_effects/lpe-tangent_to_curve.cpp b/src/live_effects/lpe-tangent_to_curve.cpp
index 5f63e1ee9..69a4dfad9 100644
--- a/src/live_effects/lpe-tangent_to_curve.cpp
+++ b/src/live_effects/lpe-tangent_to_curve.cpp
@@ -60,10 +60,10 @@ LPETangentToCurve::LPETangentToCurve(LivePathEffectObject *lpeobject) :
show_orig_path = true;
_provides_knotholder_entities = true;
- registerParameter( dynamic_cast<Parameter *>(&angle) );
- registerParameter( dynamic_cast<Parameter *>(&t_attach) );
- registerParameter( dynamic_cast<Parameter *>(&length_left) );
- registerParameter( dynamic_cast<Parameter *>(&length_right) );
+ registerParameter(&angle);
+ registerParameter(&t_attach);
+ registerParameter(&length_left);
+ registerParameter(&length_right);
}
LPETangentToCurve::~LPETangentToCurve()
diff --git a/src/live_effects/lpe-test-doEffect-stack.cpp b/src/live_effects/lpe-test-doEffect-stack.cpp
index 324893706..c484c88a2 100644
--- a/src/live_effects/lpe-test-doEffect-stack.cpp
+++ b/src/live_effects/lpe-test-doEffect-stack.cpp
@@ -21,12 +21,12 @@ LPEdoEffectStackTest::LPEdoEffectStackTest(LivePathEffectObject *lpeobject) :
point(_("Point param:"), "tooltip of point parameter", "point_param", &wr, this),
path(_("Path param:"), "tooltip of path parameter", "path_param", &wr, this,"M 0,100 100,0")
{
- registerParameter( dynamic_cast<Parameter *>(&step) );
- registerParameter( dynamic_cast<Parameter *>(&point) );
- registerParameter( dynamic_cast<Parameter *>(&path) );
+ registerParameter(&step);
+ registerParameter(&point);
+ registerParameter(&path);
point.set_oncanvas_looks(SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, 0x00ff0000);
- point.param_setValue(point,true);
+ point.param_setValue(point);
}
LPEdoEffectStackTest::~LPEdoEffectStackTest()
diff --git a/src/live_effects/lpe-text_label.cpp b/src/live_effects/lpe-text_label.cpp
index 709d05e18..0c1db2f04 100644
--- a/src/live_effects/lpe-text_label.cpp
+++ b/src/live_effects/lpe-text_label.cpp
@@ -23,7 +23,7 @@ LPETextLabel::LPETextLabel(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
label(_("Label:"), _("Text label attached to the path"), "label", &wr, this, "This is a label")
{
- registerParameter( dynamic_cast<Parameter *>(&label) );
+ registerParameter(&label);
}
LPETextLabel::~LPETextLabel()
diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp
index ef2900775..f4d233d56 100644
--- a/src/live_effects/lpe-transform_2pts.cpp
+++ b/src/live_effects/lpe-transform_2pts.cpp
@@ -138,14 +138,22 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem)
size_t nnodes = nodeCount(pathvector);
first_knot.param_set_range(1, last_knot-1);
last_knot.param_set_range(first_knot+1, nnodes);
- from_original_width.param_setValue(false);
+ if (from_original_width){
+ from_original_width.param_setValue(false);
+ }
} else {
- first_knot.param_set_value(1);
- last_knot.param_set_value(2);
+ if (first_knot != 1){
+ first_knot.param_set_value(1);
+ }
+ if (last_knot != 2){
+ last_knot.param_set_value(2);
+ }
first_knot.param_set_range(1,1);
last_knot.param_set_range(2,2);
- from_original_width.param_setValue(true);
append_path = false;
+ if (!from_original_width){
+ from_original_width.param_setValue(true);
+ }
}
if(lock_lenght && !lock_angle && previous_lenght != -1) {
Geom::Ray transformed((Geom::Point)start,(Geom::Point)end);
@@ -251,6 +259,8 @@ LPETransform2Pts::reset()
first_knot.param_set_value(1);
last_knot.param_set_value(2);
}
+ offset.param_set_value(0.0);
+ stretch.param_set_value(1.0);
Geom::Ray transformed(point_a, point_b);
previous_angle = transformed.angle();
previous_lenght = Geom::distance(point_a, point_b);
diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp
index 47e2a1cec..b9fd8908a 100644
--- a/src/live_effects/lpe-vonkoch.cpp
+++ b/src/live_effects/lpe-vonkoch.cpp
@@ -53,15 +53,15 @@ LPEVonKoch::LPEVonKoch(LivePathEffectObject *lpeobject) :
maxComplexity(_("_Max complexity:"), _("Disable effect if the output is too complex"), "maxComplexity", &wr, this, 1000)
{
//FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug.
- registerParameter( dynamic_cast<Parameter *>(&ref_path) );
- //registerParameter( dynamic_cast<Parameter *>(&refA) );
- //registerParameter( dynamic_cast<Parameter *>(&refB) );
- registerParameter( dynamic_cast<Parameter *>(&generator) );
- registerParameter( dynamic_cast<Parameter *>(&similar_only) );
- registerParameter( dynamic_cast<Parameter *>(&nbgenerations) );
- registerParameter( dynamic_cast<Parameter *>(&drawall) );
- registerParameter( dynamic_cast<Parameter *>(&maxComplexity) );
- //registerParameter( dynamic_cast<Parameter *>(&draw_boxes) );
+ registerParameter(&ref_path);
+ //registerParameter(&refA) );
+ //registerParameter(&refB) );
+ registerParameter(&generator);
+ registerParameter(&similar_only);
+ registerParameter(&nbgenerations);
+ registerParameter(&drawall);
+ registerParameter(&maxComplexity);
+ //registerParameter(&draw_boxes) );
apply_to_clippath_and_mask = true;
nbgenerations.param_make_integer();
nbgenerations.param_set_range(0, Geom::infinity());
diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h
index 9204ede1f..10a3ea018 100644
--- a/src/live_effects/parameter/array.h
+++ b/src/live_effects/parameter/array.h
@@ -60,7 +60,7 @@ public:
g_strfreev (strarray);
return true;
}
-
+ virtual void param_update_default(const gchar * default_value){};
virtual gchar * param_getSVGValue() const {
Inkscape::SVGOStringStream os;
writesvg(os, _vector);
diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp
index 813c06b4e..9cb91bdd6 100644
--- a/src/live_effects/parameter/bool.cpp
+++ b/src/live_effects/parameter/bool.cpp
@@ -42,6 +42,12 @@ BoolParam::param_update_default(bool const default_value)
defvalue = default_value;
}
+void
+BoolParam::param_update_default(const gchar * default_value)
+{
+ param_update_default(helperfns_read_bool(default_value, defvalue));
+}
+
bool
BoolParam::param_readSVGValue(const gchar * strvalue)
{
@@ -72,7 +78,6 @@ BoolParam::param_newWidget()
checkwdg->setActive(value);
checkwdg->setProgrammatically = false;
checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter"));
- param_effect->upd_params = false;
return dynamic_cast<Gtk::Widget *> (checkwdg);
} else {
return NULL;
diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h
index 7ad8a9368..39f328eaa 100644
--- a/src/live_effects/parameter/bool.h
+++ b/src/live_effects/parameter/bool.h
@@ -37,8 +37,8 @@ public:
void param_setValue(bool newvalue);
virtual void param_set_default();
void param_update_default(bool const default_value);
+ virtual void param_update_default(const gchar * default_value);
bool get_value() const { return value; };
-
inline operator bool() const { return value; };
private:
diff --git a/src/live_effects/parameter/enum.h b/src/live_effects/parameter/enum.h
index dbfc68623..6cadd6953 100644
--- a/src/live_effects/parameter/enum.h
+++ b/src/live_effects/parameter/enum.h
@@ -76,8 +76,17 @@ public:
void param_set_default() {
param_set_value(defvalue);
}
-
+
+ void param_update_default(E default_value) {
+ defvalue = default_value;
+ }
+
+ virtual void param_update_default(const gchar * default_value) {
+ param_update_default(enumdataconv->get_id_from_key(Glib::ustring(default_value)));
+ }
+
void param_set_value(E val) {
+ param_effect->upd_params = true;
value = val;
}
diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp
index 64c203093..5add69c1d 100644
--- a/src/live_effects/parameter/fontbutton.cpp
+++ b/src/live_effects/parameter/fontbutton.cpp
@@ -33,9 +33,11 @@ FontButtonParam::param_set_default()
{
param_setValue(defvalue);
}
+
void
-FontButtonParam::param_update_default(const Glib::ustring default_value){
- defvalue = default_value;
+FontButtonParam::param_update_default(const gchar * default_value)
+{
+ defvalue = (Glib::ustring)strdup(default_value);
}
bool
@@ -66,16 +68,17 @@ FontButtonParam::param_newWidget()
Glib::ustring fontspec = param_getSVGValue();
fontbuttonwdg->setValue( fontspec);
fontbuttonwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change font button parameter"));
- param_effect->upd_params = false;
return dynamic_cast<Gtk::Widget *> (fontbuttonwdg);
}
void
FontButtonParam::param_setValue(const Glib::ustring newvalue)
{
+ param_effect->upd_params = true;
value = newvalue;
}
+
} /* namespace LivePathEffect */
} /* namespace Inkscape */
diff --git a/src/live_effects/parameter/fontbutton.h b/src/live_effects/parameter/fontbutton.h
index df47251a2..60e1aa46e 100644
--- a/src/live_effects/parameter/fontbutton.h
+++ b/src/live_effects/parameter/fontbutton.h
@@ -21,15 +21,15 @@ public:
const Glib::ustring& key,
Inkscape::UI::Widget::Registry* wr,
Effect* effect,
- const Glib::ustring default_value = "");
+ const Glib::ustring default_value = "Sans 10");
virtual ~FontButtonParam() {}
virtual Gtk::Widget * param_newWidget();
virtual bool param_readSVGValue(const gchar * strvalue);
- void param_update_default(const Glib::ustring defvalue);
+ void param_update_default(const gchar * default_value);
virtual gchar * param_getSVGValue() const;
- void param_setValue(const Glib::ustring newvalue);
+ void param_setValue(Glib::ustring newvalue);
virtual void param_set_default();
diff --git a/src/live_effects/parameter/item.cpp b/src/live_effects/parameter/item.cpp
index 93cf2b15f..7b40f4540 100644
--- a/src/live_effects/parameter/item.cpp
+++ b/src/live_effects/parameter/item.cpp
@@ -60,6 +60,10 @@ ItemParam::param_set_default()
param_readSVGValue(defvalue);
}
+void
+ItemParam::param_update_default(const gchar * default_value){
+ defvalue = strdup(default_value);
+}
void
ItemParam::param_set_and_write_default()
diff --git a/src/live_effects/parameter/item.h b/src/live_effects/parameter/item.h
index 6c719d451..89c32f9bd 100644
--- a/src/live_effects/parameter/item.h
+++ b/src/live_effects/parameter/item.h
@@ -36,6 +36,7 @@ public:
virtual gchar * param_getSVGValue() const;
virtual void param_set_default();
+ virtual void param_update_default(const gchar * default_value);
void param_set_and_write_default();
virtual void addCanvasIndicators(SPLPEItem const* lpeitem, std::vector<Geom::PathVector> &hp_vec);
diff --git a/src/live_effects/parameter/originalpatharray.h b/src/live_effects/parameter/originalpatharray.h
index 296c0f7f7..fe9371644 100644
--- a/src/live_effects/parameter/originalpatharray.h
+++ b/src/live_effects/parameter/originalpatharray.h
@@ -65,12 +65,11 @@ public:
virtual bool param_readSVGValue(const gchar * strvalue);
virtual gchar * param_getSVGValue() const;
virtual void param_set_default();
-
+ virtual void param_update_default(const gchar * default_value){};
/** Disable the canvas indicators of parent class by overriding this method */
virtual void param_editOncanvas(SPItem * /*item*/, SPDesktop * /*dt*/) {};
/** Disable the canvas indicators of parent class by overriding this method */
virtual void addCanvasIndicators(SPLPEItem const* /*lpeitem*/, std::vector<Geom::PathVector> & /*hp_vec*/) {};
-
std::vector<PathAndDirection*> _vector;
protected:
diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp
index befac4df1..1c1063960 100644
--- a/src/live_effects/parameter/parameter.cpp
+++ b/src/live_effects/parameter/parameter.cpp
@@ -39,6 +39,7 @@ Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip,
void
Parameter::param_write_to_repr(const char * svgd)
{
+ param_effect->upd_params = true;
param_effect->getRepr()->setAttribute(param_key.c_str(), svgd);
}
@@ -107,6 +108,16 @@ ScalarParam::param_update_default(gdouble default_value)
defvalue = default_value;
}
+void
+ScalarParam::param_update_default(const gchar * default_value)
+{
+ double newval;
+ unsigned int success = sp_svg_number_read_d(default_value, &newval);
+ if (success == 1) {
+ param_update_default(newval);
+ }
+}
+
void
ScalarParam::param_set_value(gdouble val)
{
@@ -128,7 +139,6 @@ ScalarParam::param_set_range(gdouble min, gdouble max)
// Once again, in gtk2, this is not a problem. But in gtk3,
// widgets get allocated the amount of size they ask for,
// leading to excessively long widgets.
- param_effect->upd_params = true;
if (min >= -SCALARPARAM_G_MAXDOUBLE) {
this->min = min;
} else {
@@ -145,7 +155,6 @@ ScalarParam::param_set_range(gdouble min, gdouble max)
void
ScalarParam::param_make_integer(bool yes)
{
- param_effect->upd_params = true;
integer = yes;
digits = 0;
inc_step = 1;
@@ -176,7 +185,6 @@ ScalarParam::param_newWidget()
if(!overwrite_widget){
rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter"));
}
- param_effect->upd_params = false;
return dynamic_cast<Gtk::Widget *> (rsu);
} else {
return NULL;
@@ -186,14 +194,12 @@ ScalarParam::param_newWidget()
void
ScalarParam::param_set_digits(unsigned digits)
{
- param_effect->upd_params = true;
this->digits = digits;
}
void
ScalarParam::param_set_increments(double step, double page)
{
- param_effect->upd_params = true;
inc_step = step;
inc_page = page;
}
diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h
index 6cf10710c..ee1d2d547 100644
--- a/src/live_effects/parameter/parameter.h
+++ b/src/live_effects/parameter/parameter.h
@@ -60,7 +60,7 @@ public:
void write_to_SVG();
virtual void param_set_default() = 0;
-
+ virtual void param_update_default(const gchar * default_value) = 0;
// This creates a new widget (newed with Gtk::manage(new ...);)
virtual Gtk::Widget * param_newWidget() = 0;
@@ -77,6 +77,7 @@ public:
virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/) {};
Glib::ustring param_key;
+ Glib::ustring param_tooltip;
Inkscape::UI::Widget::Registry * param_wr;
Glib::ustring param_label;
@@ -84,7 +85,6 @@ public:
bool widget_is_visible;
protected:
- Glib::ustring param_tooltip;
Effect* param_effect;
@@ -112,6 +112,7 @@ public:
virtual void param_set_default();
void param_update_default(gdouble default_value);
+ virtual void param_update_default(const gchar * default_value);
void param_set_value(gdouble val);
void param_make_integer(bool yes = true);
void param_set_range(gdouble min, gdouble max);
@@ -120,7 +121,6 @@ public:
void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; };
double param_get_max() { return max; };
double param_get_min() { return min; };
-
void param_overwrite_widget(bool overwrite_widget);
virtual Gtk::Widget * param_newWidget();
diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp
index dafc6d406..aa87508ab 100644
--- a/src/live_effects/parameter/path.cpp
+++ b/src/live_effects/parameter/path.cpp
@@ -439,6 +439,10 @@ PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/)
SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
+void
+PathParam::param_update_default(const gchar * default_value){
+ defvalue = strdup(default_value);
+}
/* CALLBACK FUNCTIONS FOR THE BUTTONS */
void
diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h
index d2dddbe97..5381a6b36 100644
--- a/src/live_effects/parameter/path.h
+++ b/src/live_effects/parameter/path.h
@@ -40,6 +40,7 @@ public:
virtual gchar * param_getSVGValue() const;
virtual void param_set_default();
+ virtual void param_update_default(const gchar * default_value);
void param_set_and_write_default();
void set_new_value (Geom::PathVector const &newpath, bool write_to_svg);
void set_new_value (Geom::Piecewise<Geom::D2<Geom::SBasis> > const &newpath, bool write_to_svg);
diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp
index c87b1e299..4ca88a6b8 100644
--- a/src/live_effects/parameter/point.cpp
+++ b/src/live_effects/parameter/point.cpp
@@ -26,8 +26,7 @@ PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip,
: Parameter(label, tip, key, wr, effect),
defvalue(default_value),
liveupdate(live_update),
- knoth(NULL),
- _pointwdg(NULL)
+ knoth(NULL)
{
knot_shape = SP_KNOT_SHAPE_DIAMOND;
knot_mode = SP_KNOT_MODE_XOR;
@@ -59,12 +58,25 @@ PointParam::param_get_default() const{
}
void
-PointParam::param_update_default(const Geom::Point default_point)
+PointParam::param_update_default(Geom::Point default_point)
{
defvalue = default_point;
}
void
+PointParam::param_update_default(const gchar * default_point)
+{
+ gchar ** strarray = g_strsplit(default_point, ",", 2);
+ double newx, newy;
+ unsigned int success = sp_svg_number_read_d(strarray[0], &newx);
+ success += sp_svg_number_read_d(strarray[1], &newy);
+ g_strfreev (strarray);
+ if (success == 2) {
+ param_update_default( Geom::Point(newx, newy) );
+ }
+}
+
+void
PointParam::param_setValue(Geom::Point newpoint, bool write)
{
*dynamic_cast<Geom::Point *>( this ) = newpoint;
@@ -78,9 +90,6 @@ PointParam::param_setValue(Geom::Point newpoint, bool write)
if(knoth && liveupdate){
knoth->update_knots();
}
- if (_pointwdg) {
- _pointwdg->setValue( newpoint );
- }
}
bool
@@ -116,7 +125,7 @@ PointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/)
Gtk::Widget *
PointParam::param_newWidget()
{
- _pointwdg = Gtk::manage(
+ Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage(
new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label,
param_tooltip,
param_key,
@@ -125,15 +134,14 @@ PointParam::param_newWidget()
param_effect->getSPDoc() ) );
Geom::Affine transf = Geom::Scale(1, -1);
transf[5] = SP_ACTIVE_DOCUMENT->getHeight().value("px");
- _pointwdg->setTransform(transf);
- _pointwdg->setValue( *this );
- _pointwdg->clearProgrammatically();
- _pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));
+ pointwdg->setTransform(transf);
+ pointwdg->setValue( *this );
+ pointwdg->clearProgrammatically();
+ pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));
Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() );
- static_cast<Gtk::HBox*>(hbox)->pack_start(*_pointwdg, true, true);
+ static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true);
static_cast<Gtk::HBox*>(hbox)->show_all_children();
- param_effect->upd_params = false;
return dynamic_cast<Gtk::Widget *> (hbox);
}
@@ -173,7 +181,7 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or
s = A;
}
}
- pparam->param_setValue(s, this->pparam->liveupdate);
+ pparam->param_setValue(s);
SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item);
if(splpeitem && this->pparam->liveupdate){
sp_lpe_item_update_patheffect(splpeitem, false, false);
diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h
index e8cb66225..a5153ad80 100644
--- a/src/live_effects/parameter/point.h
+++ b/src/live_effects/parameter/point.h
@@ -43,14 +43,15 @@ public:
void param_set_default();
Geom::Point param_get_default() const;
void param_set_liveupdate(bool live_update);
- void param_update_default(const Geom::Point default_point);
+ void param_update_default(Geom::Point default_point);
+
+ virtual void param_update_default(const gchar * default_point);
virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/);
void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
virtual bool providesKnotHolderEntities() const { return true; }
virtual void addKnotHolderEntities(KnotHolder *knotholder, SPItem *item);
-
friend class PointParamKnotHolderEntity;
private:
PointParam(const PointParam&);
@@ -62,7 +63,6 @@ private:
SPKnotModeType knot_mode;
guint32 knot_color;
gchar *handle_tip;
- Inkscape::UI::Widget::RegisteredTransformedPoint * _pointwdg;
};
diff --git a/src/live_effects/parameter/powerstrokepointarray.h b/src/live_effects/parameter/powerstrokepointarray.h
index 56a609fa8..a34163ca1 100644
--- a/src/live_effects/parameter/powerstrokepointarray.h
+++ b/src/live_effects/parameter/powerstrokepointarray.h
@@ -39,13 +39,13 @@ public:
virtual bool providesKnotHolderEntities() const { return true; }
virtual void addKnotHolderEntities(KnotHolder *knotholder, SPItem *item);
+ virtual void param_update_default(const gchar * default_value){};
void set_pwd2(Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in, Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_normal_in);
Geom::Piecewise<Geom::D2<Geom::SBasis> > const & get_pwd2() const { return last_pwd2; }
Geom::Piecewise<Geom::D2<Geom::SBasis> > const & get_pwd2_normal() const { return last_pwd2_normal; }
void recalculate_controlpoints_for_new_pwd2(Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
-
friend class PowerStrokePointArrayParamKnotHolderEntity;
private:
diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp
index 075e85ee1..90e53ca0e 100644
--- a/src/live_effects/parameter/random.cpp
+++ b/src/live_effects/parameter/random.cpp
@@ -78,6 +78,20 @@ RandomParam::param_set_default()
}
void
+RandomParam::param_update_default(gdouble default_value){
+ defvalue = default_value;
+}
+
+void
+RandomParam::param_update_default(const gchar * default_value){
+ double newval;
+ unsigned int success = sp_svg_number_read_d(default_value, &newval);
+ if (success == 1) {
+ param_update_default(newval);
+ }
+}
+
+void
RandomParam::param_set_value(gdouble val, long newseed)
{
value = val;
diff --git a/src/live_effects/parameter/random.h b/src/live_effects/parameter/random.h
index ca4440336..5fb6027ac 100644
--- a/src/live_effects/parameter/random.h
+++ b/src/live_effects/parameter/random.h
@@ -38,9 +38,9 @@ public:
void param_set_value(gdouble val, long newseed);
void param_make_integer(bool yes = true);
void param_set_range(gdouble min, gdouble max);
-
+ void param_update_default(gdouble default_value);
+ virtual void param_update_default(const gchar * default_value);
void resetRandomizer();
-
operator gdouble();
inline gdouble get_value() { return value; } ;
diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp
index 5c4cdf4c6..4062a4dc7 100644
--- a/src/live_effects/parameter/text.cpp
+++ b/src/live_effects/parameter/text.cpp
@@ -50,9 +50,9 @@ TextParam::param_set_default()
}
void
-TextParam::param_update_default(Glib::ustring default_value)
+TextParam::param_update_default(const gchar * default_value)
{
- defvalue = default_value;
+ defvalue = (Glib::ustring)default_value;
}
void
@@ -125,14 +125,12 @@ TextParam::param_newWidget()
rsu->setProgrammatically = false;
rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change text parameter"));
- param_effect->upd_params = false;
return dynamic_cast<Gtk::Widget *> (rsu);
}
void
TextParam::param_setValue(const Glib::ustring newvalue)
{
- param_effect->upd_params = true;
value = newvalue;
if (!_hide_canvas_text) {
sp_canvastext_set_text (canvas_text, newvalue.c_str());
diff --git a/src/live_effects/parameter/text.h b/src/live_effects/parameter/text.h
index 553c84c0a..137f3ee02 100644
--- a/src/live_effects/parameter/text.h
+++ b/src/live_effects/parameter/text.h
@@ -39,16 +39,16 @@ public:
virtual bool param_readSVGValue(const gchar * strvalue);
virtual gchar * param_getSVGValue() const;
- void param_setValue(const Glib::ustring newvalue);
+ void param_setValue(Glib::ustring newvalue);
void param_hide_canvas_text();
virtual void param_set_default();
- void param_update_default(Glib::ustring default_value);
+ virtual void param_update_default(const gchar * default_value);
void setPos(Geom::Point pos);
void setPosAndAnchor(const Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2,
const double t, const double length, bool use_curvature = false);
void setAnchor(double x_value, double y_value);
- const Glib::ustring get_value() const { return defvalue; };
+ const Glib::ustring get_value() const { return value; };
private:
TextParam(const TextParam&);
diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp
index b3f6442bb..9eb89fea5 100644
--- a/src/live_effects/parameter/togglebutton.cpp
+++ b/src/live_effects/parameter/togglebutton.cpp
@@ -60,6 +60,18 @@ ToggleButtonParam::param_getSVGValue() const
return str;
}
+void
+ToggleButtonParam::param_update_default(bool default_value)
+{
+ defvalue = default_value;
+}
+
+void
+ToggleButtonParam::param_update_default(const gchar * default_value)
+{
+ param_update_default(helperfns_read_bool(default_value, defvalue));
+}
+
Gtk::Widget *
ToggleButtonParam::param_newWidget()
{
@@ -68,7 +80,7 @@ ToggleButtonParam::param_newWidget()
}
checkwdg = Gtk::manage(
- new Inkscape::UI::Widget::RegisteredToggleButton( param_label,
+ new Inkscape::UI::Widget::RegisteredToggleButton(param_label,
param_tooltip,
param_key,
*param_wr,
@@ -112,7 +124,6 @@ ToggleButtonParam::param_newWidget()
checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change togglebutton parameter"));
_toggled_connection = checkwdg->signal_toggled().connect(sigc::mem_fun(*this, &ToggleButtonParam::toggled));
- param_effect->upd_params = false;
return checkwdg;
}
@@ -153,14 +164,13 @@ ToggleButtonParam::refresh_button()
void
ToggleButtonParam::param_setValue(bool newvalue)
{
+ param_effect->upd_params = true;
value = newvalue;
refresh_button();
}
void
ToggleButtonParam::toggled() {
- //Force redraw for update widgets
- param_effect->upd_params = true;
if (SP_ACTIVE_DESKTOP) {
Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection();
selection->emitModified();
diff --git a/src/live_effects/parameter/togglebutton.h b/src/live_effects/parameter/togglebutton.h
index 8390fec86..d6ca15e75 100644
--- a/src/live_effects/parameter/togglebutton.h
+++ b/src/live_effects/parameter/togglebutton.h
@@ -51,6 +51,8 @@ public:
sigc::signal<void>& signal_toggled() { return _signal_toggled; }
virtual void toggled();
+ void param_update_default(bool default_value);
+ virtual void param_update_default(const gchar * default_value);
private:
ToggleButtonParam(const ToggleButtonParam&);
diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp
index 0d03432c3..22d5ba3a4 100644
--- a/src/live_effects/parameter/transformedpoint.cpp
+++ b/src/live_effects/parameter/transformedpoint.cpp
@@ -82,6 +82,25 @@ TransformedPointParam::param_getSVGValue() const
return str;
}
+void
+TransformedPointParam::param_update_default(Geom::Point default_point)
+{
+ defvalue = default_point;
+}
+
+void
+TransformedPointParam::param_update_default(const gchar * default_point)
+{
+ gchar ** strarray = g_strsplit(default_point, ",", 2);
+ double newx, newy;
+ unsigned int success = sp_svg_number_read_d(strarray[0], &newx);
+ success += sp_svg_number_read_d(strarray[1], &newy);
+ g_strfreev (strarray);
+ if (success == 2) {
+ param_update_default( Geom::Point(newx, newy) );
+ }
+}
+
Gtk::Widget *
TransformedPointParam::param_newWidget()
{
diff --git a/src/live_effects/parameter/transformedpoint.h b/src/live_effects/parameter/transformedpoint.h
index c96bedb53..269cc508e 100644
--- a/src/live_effects/parameter/transformedpoint.h
+++ b/src/live_effects/parameter/transformedpoint.h
@@ -51,7 +51,9 @@ public:
void set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
void set_oncanvas_color(guint32 color);
-
+ Geom::Point param_get_default() { return defvalue; }
+ void param_update_default(Geom::Point default_point);
+ virtual void param_update_default(const gchar * default_point);
virtual bool providesKnotHolderEntities() const { return true; }
virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
diff --git a/src/live_effects/parameter/unit.cpp b/src/live_effects/parameter/unit.cpp
index b6ea99bfe..b9b91c1e6 100644
--- a/src/live_effects/parameter/unit.cpp
+++ b/src/live_effects/parameter/unit.cpp
@@ -55,14 +55,15 @@ UnitParam::param_set_default()
}
void
-UnitParam::param_update_default(const Glib::ustring default_unit)
+UnitParam::param_update_default(const gchar * default_unit)
{
- defunit = unit_table.getUnit(default_unit);
+ defunit = unit_table.getUnit((Glib::ustring)default_unit);
}
void
UnitParam::param_set_value(Inkscape::Util::Unit const &val)
{
+ param_effect->upd_params = true;
unit = new Inkscape::Util::Unit(val);
}
diff --git a/src/live_effects/parameter/unit.h b/src/live_effects/parameter/unit.h
index ae58cf956..c662b6edc 100644
--- a/src/live_effects/parameter/unit.h
+++ b/src/live_effects/parameter/unit.h
@@ -33,11 +33,10 @@ public:
virtual gchar * param_getSVGValue() const;
virtual void param_set_default();
void param_set_value(Inkscape::Util::Unit const &val);
- void param_update_default(const Glib::ustring default_unit);
+ virtual void param_update_default(const gchar * default_unit);
const gchar *get_abbreviation() const;
-
virtual Gtk::Widget * param_newWidget();
-
+
operator Inkscape::Util::Unit const *() const { return unit; }
private:
diff --git a/src/live_effects/parameter/vector.cpp b/src/live_effects/parameter/vector.cpp
index 55b4d4b32..470fa9c2d 100644
--- a/src/live_effects/parameter/vector.cpp
+++ b/src/live_effects/parameter/vector.cpp
@@ -48,6 +48,25 @@ VectorParam::param_set_default()
setVector(defvalue);
}
+void
+VectorParam::param_update_default(Geom::Point default_point)
+{
+ defvalue = default_point;
+}
+
+void
+VectorParam::param_update_default(const gchar * default_point)
+{
+ gchar ** strarray = g_strsplit(default_point, ",", 2);
+ double newx, newy;
+ unsigned int success = sp_svg_number_read_d(strarray[0], &newx);
+ success += sp_svg_number_read_d(strarray[1], &newy);
+ g_strfreev (strarray);
+ if (success == 2) {
+ param_update_default( Geom::Point(newx, newy) );
+ }
+}
+
bool
VectorParam::param_readSVGValue(const gchar * strvalue)
{
diff --git a/src/live_effects/parameter/vector.h b/src/live_effects/parameter/vector.h
index edee4ff4d..d270e9f43 100644
--- a/src/live_effects/parameter/vector.h
+++ b/src/live_effects/parameter/vector.h
@@ -51,7 +51,8 @@ public:
void set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
void set_origin_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
void set_oncanvas_color(guint32 color);
-
+ void param_update_default(Geom::Point default_point);
+ virtual void param_update_default(const gchar * default_point);
virtual bool providesKnotHolderEntities() const { return true; }
virtual void addKnotHolderEntities(KnotHolder *knotholder, SPItem *item);
diff --git a/src/main.cpp b/src/main.cpp
index 8be9e2e44..f23f9a9f7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -146,6 +146,7 @@ enum {
SP_ARG_EXPORT_BACKGROUND,
SP_ARG_EXPORT_BACKGROUND_OPACITY,
SP_ARG_EXPORT_SVG,
+ SP_ARG_EXPORT_INKSCAPE_SVG,
SP_ARG_EXPORT_PS,
SP_ARG_EXPORT_EPS,
SP_ARG_EXPORT_PS_LEVEL,
@@ -205,6 +206,7 @@ static gboolean sp_export_area_snap = FALSE;
static gboolean sp_export_use_hints = FALSE;
static gboolean sp_export_id_only = FALSE;
static gchar *sp_export_svg = NULL;
+static gchar *sp_export_inkscape_svg = NULL;
static gchar *sp_export_ps = NULL;
static gchar *sp_export_eps = NULL;
static gint sp_export_ps_level = 3;
@@ -229,6 +231,7 @@ static gchar *sp_dbus_name = NULL;
#endif // WITH_DBUS
static gchar *sp_export_png_utf8 = NULL;
static gchar *sp_export_svg_utf8 = NULL;
+static gchar *sp_export_inkscape_svg_utf8 = NULL;
static gchar *sp_global_printer_utf8 = NULL;
#ifdef WITH_YAML
@@ -257,6 +260,7 @@ static void resetCommandlineGlobals() {
sp_export_use_hints = FALSE;
sp_export_id_only = FALSE;
sp_export_svg = NULL;
+ sp_export_inkscape_svg = NULL;
sp_export_ps = NULL;
sp_export_eps = NULL;
sp_export_ps_level = 3;
@@ -282,6 +286,7 @@ static void resetCommandlineGlobals() {
sp_export_png_utf8 = NULL;
sp_export_svg_utf8 = NULL;
+ sp_export_inkscape_svg_utf8 = NULL;
sp_global_printer_utf8 = NULL;
}
@@ -392,6 +397,10 @@ struct poptOption options[] = {
N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"),
N_("VALUE")},
+ {"export-inkscape-svg", 0,
+ POPT_ARG_STRING, &sp_export_inkscape_svg, SP_ARG_EXPORT_INKSCAPE_SVG,
+ N_("Export document to an inkscape SVG file (similar to save as.)"),
+ N_("FILENAME")},
{"export-plain-svg", 'l',
POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG,
N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"),
@@ -903,6 +912,7 @@ static int sp_common_main( int argc, char const **argv, GSList **flDest )
{
fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
+ fixupSingleFilename( &sp_export_inkscape_svg, &sp_export_inkscape_svg_utf8 );
fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
#ifdef WITH_YAML
fixupSingleFilename( &sp_xverbs_yaml, &sp_xverbs_yaml_utf8 );
@@ -914,6 +924,8 @@ static int sp_common_main( int argc, char const **argv, GSList **flDest )
sp_export_png_utf8 = g_strdup( sp_export_png );
if ( sp_export_svg )
sp_export_svg_utf8 = g_strdup( sp_export_svg );
+ if ( sp_export_inkscape_svg )
+ sp_export_inkscape_svg_utf8 = g_strdup( sp_export_inkscape_svg );
if ( sp_global_printer )
sp_global_printer_utf8 = g_strdup( sp_global_printer );
#ifdef WITH_YAML
@@ -1135,20 +1147,21 @@ static int sp_process_file_list(GSList *fl)
}
#endif // WITH_DBUS
- if (!sp_export_svg && (sp_vacuum_defs || has_performed_actions)) {
+ if (!sp_export_svg && !sp_export_inkscape_svg && (sp_vacuum_defs || has_performed_actions)) {
// save under the name given in the command line
Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"), doc, filename, false,
false, false, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
}
+
if (sp_global_printer) {
sp_print_document_to_file(doc, sp_global_printer);
}
if (sp_export_png || (sp_export_id && sp_export_use_hints)) {
retVal |= sp_do_export_png(doc);
}
- if (sp_export_svg) {
+ if (sp_export_svg || sp_export_inkscape_svg) {
if (sp_export_text_to_path) {
- std::vector<SPItem*> items;
+ std::vector<SPItem*> items;
SPRoot *root = doc->getRoot();
doc->ensureUpToDate();
for (auto& iter: root->children) {
@@ -1180,9 +1193,15 @@ static int sp_process_file_list(GSList *fl)
s.set(obj);
s.fitCanvas(false);
}
-
- Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.plain"), doc, sp_export_svg, false,
- false, false, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
+ if (sp_export_svg) {
+ Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.plain"), doc, sp_export_svg, false,
+ false, false, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
+ }
+ if (sp_export_inkscape_svg) {
+ // Export as inkscape SVG.
+ Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"), doc, sp_export_inkscape_svg, false,
+ false, false, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
+ }
}
if (sp_export_ps) {
retVal |= do_export_ps_pdf(doc, sp_export_ps, "image/x-postscript");
diff --git a/src/preferences.cpp b/src/preferences.cpp
index 4d522a1d8..2849fe068 100644
--- a/src/preferences.cpp
+++ b/src/preferences.cpp
@@ -512,6 +512,35 @@ void Preferences::remove(Glib::ustring const &pref_path)
Inkscape::XML::Node *node = _getNode(pref_path, false);
if (node && node->parent()) {
node->parent()->removeChild(node);
+ } else { //Handle to remove also attributes in path not only the container node
+ // verify path
+ g_assert( pref_path.at(0) == '/' );
+ if (_prefs_doc == NULL){
+ return;
+ }
+ node = _prefs_doc->root();
+ Inkscape::XML::Node *child = NULL;
+ gchar **splits = g_strsplit(pref_path.c_str(), "/", 0);
+ if ( splits ) {
+ for (int part_i = 0; splits[part_i]; ++part_i) {
+ // skip empty path segments
+ if (!splits[part_i][0]) {
+ continue;
+ }
+ if (!node->firstChild()) {
+ node->setAttribute(splits[part_i], NULL);
+ g_strfreev(splits);
+ return;
+ }
+ for (child = node->firstChild(); child; child = child->next()) {
+ if (!strcmp(splits[part_i], child->attribute("id"))) {
+ break;
+ }
+ }
+ node = child;
+ }
+ }
+ g_strfreev(splits);
}
}
diff --git a/src/print.cpp b/src/print.cpp
index 479401995..7cd05ac93 100644
--- a/src/print.cpp
+++ b/src/print.cpp
@@ -79,7 +79,6 @@ unsigned int sp_print_text(SPPrintContext *ctx, char const *text, Geom::Point p,
void
sp_print_document(Gtk::Window& parentWindow, SPDocument *doc)
{
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
doc->ensureUpToDate();
// Build arena
@@ -89,7 +88,6 @@ sp_print_document(Gtk::Window& parentWindow, SPDocument *doc)
Inkscape::UI::Dialog::Print printop(doc,base);
Gtk::PrintOperationResult res = printop.run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, parentWindow);
(void)res; // TODO handle this
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
}
void sp_print_document_to_file(SPDocument *doc, gchar const *filename)
diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp
index ca0f78a00..b5c89b69d 100644
--- a/src/sp-lpe-item.cpp
+++ b/src/sp-lpe-item.cpp
@@ -493,8 +493,8 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths)
}
PathEffectList new_list = *this->path_effect_list;
new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list
+ *this->path_effect_list = new_list;
this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list));
-
if (!keep_paths) {
// Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible.
if( SP_IS_GENERICELLIPSE(this)) {
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index 403b8a41b..c40006a92 100644
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
@@ -19,12 +19,7 @@
#include "event-log.h"
#include <2geom/transforms.h>
-#include "display/sp-canvas-group.h"
-#include "display/canvas-bpath.h"
-#include "display/canvas-temporary-item.h"
-#include "display/canvas-temporary-item-list.h"
#include "display/canvas-grid.h"
-#include "display/curve.h"
#include "util/units.h"
#include "svg/svg-color.h"
#include "xml/repr.h"
@@ -34,15 +29,12 @@
#include "desktop-events.h"
#include "sp-guide.h"
-#include "sp-root.h"
#include "sp-item-group.h"
#include "sp-namedview.h"
#include "preferences.h"
#include "desktop.h"
-#include "selection.h"
-#include "object-set.h"
-#include "inkscape.h"
#include "conn-avoid-ref.h" // for defaultConnSpacing.
+#include "sp-root.h"
#include <gtkmm/window.h>
using Inkscape::DocumentUndo;
@@ -80,7 +72,6 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) {
this->pagecolor = 0;
this->cx = 0;
this->pageshadow = 0;
- this->document_rotation = 0;
this->window_width = 0;
this->window_height = 0;
this->window_maximized = 0;
@@ -101,13 +92,9 @@ SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) {
this->default_layer_id = 0;
this->connector_spacing = defaultConnSpacing;
- this->page_border_rotated = NULL;
}
SPNamedView::~SPNamedView() {
- if(!this->getViewList().empty()) { // >0 Desktops
- this->getViewList()[0]->remove_temporary_canvasitem(this->page_border_rotated);
- }
}
static void sp_namedview_generate_old_grid(SPNamedView * /*nv*/, SPDocument *document, Inkscape::XML::Node *repr) {
@@ -225,7 +212,6 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) {
this->readAttr( "inkscape:zoom" );
this->readAttr( "inkscape:cx" );
this->readAttr( "inkscape:cy" );
- this->readAttr( "inkscape:document-rotation" );
this->readAttr( "inkscape:window-width" );
this->readAttr( "inkscape:window-height" );
this->readAttr( "inkscape:window-x" );
@@ -423,11 +409,6 @@ void SPNamedView::set(unsigned int key, const gchar* value) {
this->cy = value ? g_ascii_strtod(value, NULL) : HUGE_VAL; // HUGE_VAL means not set
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
- case SP_ATTR_INKSCAPE_DOCUMENT_ROTATION:
- this->document_rotation = value ? g_ascii_strtod(value, NULL) : 0;
- sp_namedview_set_document_rotation(this);
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
case SP_ATTR_INKSCAPE_WINDOW_WIDTH:
this->window_width = value? atoi(value) : -1; // -1 means not set
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -970,81 +951,6 @@ static void sp_namedview_lock_guides(SPNamedView *nv)
}
}
-//void sp_namedview_doc_rotate_guides(SPNamedView *nv)
-//{
-// bool saved = DocumentUndo::getUndoSensitive(nv->document);
-// DocumentUndo::setUndoSensitive(nv->document, false);
-// SPRoot * root = nv->document->getRoot();
-// Geom::Point page_center = root->viewBox.midpoint() * root->vbt;
-// Geom::Affine rot = Geom::identity();
-// rot *= Geom::Translate(page_center).inverse();
-// rot *= Geom::Rotate(Geom::rad_from_deg((nv->document_rotation - root->get_rotation()) * -1));
-// rot *= Geom::Translate(page_center);
-// for(std::vector<SPGuide *>::iterator it=nv->guides.begin();it!=nv->guides.end();++it ) {
-// Geom::Point const on_line = (*it)->getPoint() * rot ;
-// (*it)->moveto(on_line, true);
-// Geom::Affine rot_normal_affine = Geom::Rotate(Geom::rad_from_deg((nv->document_rotation - root->get_rotation()) * -1));
-// Geom::Point const rot_normal = (*it)->getNormal() * rot_normal_affine;
-// (*it)->set_normal(rot_normal, true);
-// }
-// DocumentUndo::setUndoSensitive(nv->document, saved);
-// nv->document->setModifiedSinceSave();
-//}
-
-void sp_namedview_set_document_rotation(SPNamedView *nv)
-{
- if ( nv->document->getRoot()->get_rotation() == nv->document_rotation) return;
- if(!nv->getViewList().empty()) { // >0 Desktops
- SPDesktop *desktop = nv->getViewList()[0];
- desktop->remove_temporary_canvasitem(nv->page_border_rotated);
- SPRoot * root = nv->document->getRoot();
- SPCurve *c = new SPCurve();
- c->moveto(root->viewBox.min());
- c->lineto(Geom::Point(root->viewBox.max()[Geom::X],root->viewBox.min()[Geom::Y]));
- c->lineto(Geom::Point(root->viewBox.max()[Geom::X],root->viewBox.max()[Geom::Y]));
- c->lineto(Geom::Point(root->viewBox.min()[Geom::X],root->viewBox.max()[Geom::Y]));
- c->closepath();
- Geom::Point page_center = root->viewBox.midpoint();
- Geom::PathVector const box = c->get_pathvector();
- Geom::Affine rot = Geom::identity();
- rot *= Geom::Translate(page_center).inverse();
- rot *= Geom::Rotate(Geom::rad_from_deg(nv->document_rotation * -1));
- rot *= Geom::Translate(page_center);
- if (nv->document_rotation) {
- SPCanvasItem *canvas_border = sp_canvas_bpath_new(desktop->getTempGroup(), c, true);
- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(canvas_border), 0xFF00009A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
- sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(canvas_border), 0, SP_WIND_RULE_NONZERO);
- sp_canvas_item_affine_absolute(canvas_border, rot * root->vbt);
- nv->page_border_rotated = desktop->add_temporary_canvasitem(canvas_border, 0);
- }
- //sp_namedview_doc_rotate_guides(nv);
- nv->document->getRoot()->set_rotation(nv->document_rotation);
- c->unref();
- }
- if (nv->document_rotation) {
- nv->showborder = FALSE;
- } else {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- nv->showborder = prefs->getBool("/template/base/showborder", 1.0);
- }
-
- SPDesktop * desktop = SP_ACTIVE_DESKTOP;
- if (desktop) {
-//TODO: Remove knots of shapes on selected items
-// Inkscape::Selection * sel = desktop->getSelection();
-// std::vector<SPItem*> il(sel->items().begin(), sel->items().end());
-// for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){
-// SPItem *item = *l;
-// sel->remove(item->getRepr());
-// sel->add(item->getRepr());
-// }
- SPObject *updated = desktop->getDocument()->getRoot();
- if (updated) {
- updated->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- }
- }
-}
-
static void sp_namedview_show_single_guide(SPGuide* guide, bool show)
{
if (show) {
@@ -1059,8 +965,6 @@ static void sp_namedview_lock_single_guide(SPGuide* guide, bool locked)
guide->set_locked(locked, true);
}
-
-
void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr)
{
unsigned int v;
diff --git a/src/sp-namedview.h b/src/sp-namedview.h
index 9d11c13b7..d8ac1a77e 100644
--- a/src/sp-namedview.h
+++ b/src/sp-namedview.h
@@ -21,7 +21,6 @@
#include "snap.h"
#include "document.h"
#include "util/units.h"
-#include "display/sp-canvas.h"
#include <vector>
namespace Inkscape {
@@ -29,9 +28,6 @@ namespace Inkscape {
namespace Util {
class Unit;
}
- namespace Display {
- class TemporaryItem;
- }
}
typedef unsigned int guint32;
@@ -42,7 +38,7 @@ enum {
SP_BORDER_LAYER_TOP
};
-class SPNamedView : public SPObjectGroup{
+class SPNamedView : public SPObjectGroup {
public:
SPNamedView();
virtual ~SPNamedView();
@@ -58,7 +54,6 @@ public:
double zoom;
double cx;
double cy;
- double document_rotation;
int window_width;
int window_height;
int window_x;
@@ -71,7 +66,7 @@ public:
Inkscape::Util::Unit const *display_units; // Units used for the UI (*not* the same as units of SVG coordinates)
Inkscape::Util::Unit const *page_size_units; // Only used in "Custom size" part of Document Properties dialog
- Inkscape::Display::TemporaryItem *page_border_rotated;
+
GQuark default_layer_id;
double connector_spacing;
@@ -126,7 +121,7 @@ SPNamedView const *sp_document_namedview(SPDocument const *document, char const
void sp_namedview_window_from_document(SPDesktop *desktop);
void sp_namedview_document_from_window(SPDesktop *desktop);
void sp_namedview_update_layers_from_document (SPDesktop *desktop);
-void sp_namedview_set_document_rotation(SPNamedView *nv);
+
void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr);
void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr);
void sp_namedview_show_grids(SPNamedView *namedview, bool show, bool dirty_document);
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index 22efe38ed..c594a6426 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -46,6 +46,7 @@
#include "splivarot.h"
#include "verbs.h"
#include "2geom/svg-path-parser.h" // to get from SVG on boolean to Geom::Path
+#include "util/units.h" // to get abbr for document units
using Inkscape::DocumentUndo;
@@ -1688,7 +1689,7 @@ void
sp_selected_path_offset(SPDesktop *desktop)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- double prefOffset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px");
+ double prefOffset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, desktop->getDocument()->getDisplayUnit()->abbr);
sp_selected_path_do_offset(desktop, true, prefOffset);
}
@@ -1696,7 +1697,7 @@ void
sp_selected_path_inset(SPDesktop *desktop)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- double prefOffset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px");
+ double prefOffset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, desktop->getDocument()->getDisplayUnit()->abbr);
sp_selected_path_do_offset(desktop, false, prefOffset);
}
@@ -1782,7 +1783,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool
{
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- o_width = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px");
+ o_width = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, desktop->getDocument()->getDisplayUnit()->abbr);
}
if (o_width < 0.01){
@@ -2066,17 +2067,6 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset)
res->Reset();
theRes->ConvertToForme(res);
- if (o_width >= 1.0)
- {
- res->ConvertEvenLines(1.0);
- res->Simplify(1.0);
- }
- else
- {
- res->ConvertEvenLines(1.0*o_width);
- res->Simplify(1.0 * o_width);
- }
-
delete theShape;
delete theRes;
}
diff --git a/src/text-editing.cpp b/src/text-editing.cpp
index 6809a4bc5..193f4b15a 100644
--- a/src/text-editing.cpp
+++ b/src/text-editing.cpp
@@ -942,9 +942,9 @@ sp_te_set_repr_text_multiline(SPItem *text, gchar const *str)
gchar *content = g_strdup (str);
repr->setContent("");
- for (auto& child: object->children) {
- if (!SP_IS_FLOWREGION(&child) && !SP_IS_FLOWREGIONEXCLUDE(&child)) {
- repr->removeChild(child.getRepr());
+ for (auto& child: object->childList(false)) {
+ if (!SP_IS_FLOWREGION(child) && !SP_IS_FLOWREGIONEXCLUDE(child)) {
+ repr->removeChild(child->getRepr());
}
}
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 259a06013..389e8902a 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -177,6 +177,7 @@ set(ui_SRC
control-types.h
dialog-events.h
draw-anchor.h
+ event-debug.h
icon-names.h
interface.h
object-edit.h
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 734640584..3cc8ac098 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -708,7 +708,7 @@ void ClipboardManagerImpl::_copySelection(ObjectSet *selection)
// (we're dealing with unattached representations, so we write to their attributes
// instead of using sp_item_set_transform)
SPUse *use=dynamic_cast<SPUse *>(item);
- if( use && selection->includes(use->get_original()) ){//we are copying something whose parent is also copied (!)
+ if( use && use->get_original() && use->get_original()->parent ){//we are copying something whose parent is also copied (!)
transform = ((SPItem*)(use->get_original()->parent))->i2doc_affine().inverse() * transform;
}
gchar *transform_str = sp_svg_transform_write(transform );
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index b7207fd50..1bb952de4 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -978,9 +978,7 @@ void Export::onExport ()
SPNamedView *nv = desktop->getNamedView();
SPDocument *doc = desktop->getDocument();
- Geom::Affine rot = doc->getRoot()->c2p;
- doc->getRoot()->c2p = doc->getRoot()->rotation.inverse() * doc->getRoot()->c2p;
- doc->ensureUpToDate();
+
bool exportSuccessful = false;
bool hide = hide_export.get_active ();
@@ -1005,7 +1003,6 @@ void Export::onExport ()
if (num < 1) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No items selected."));
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1097,7 +1094,6 @@ void Export::onExport ()
if (filename.empty()) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename."));
sp_ui_error_dialog(_("You have to enter a filename"));
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1114,7 +1110,6 @@ void Export::onExport ()
if (!((x1 > x0) && (y1 > y0) && (width > 0) && (height > 0))) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The chosen area to be exported is invalid."));
sp_ui_error_dialog(_("The chosen area to be exported is invalid"));
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1137,7 +1132,6 @@ void Export::onExport ()
g_free(safeDir);
g_free(error);
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
return;
}
@@ -1287,7 +1281,6 @@ void Export::onExport ()
}
}
}
- doc->getRoot()->c2p *= doc->getRoot()->rotation;
} // end of sp_export_export_clicked()
/// Called when Browse button is clicked
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index c5e8a6de6..646439613 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -1310,6 +1310,9 @@ void InkscapePreferences::initPageBehavior()
_steps_zoom.init ( "/options/zoomincrement/value", 101.0, 500.0, 1.0, 1.0, M_SQRT2, true, true);
_page_steps.add_line( false, _("_Zoom in/out by:"), _steps_zoom, _("%"),
_("Zoom tool click, +/- keys, and middle click zoom in and out by this multiplier"), false);
+ _steps_rotate.init ( "/options/rotateincrement/value", 1, 90, 1.0, 5.0, 15, false, false);
+ _page_steps.add_line( false, _("_Rotate canvas by:"), _steps_rotate, _("degrees"),
+ _("Rotate canvas clockwise and counter-clockwise by this amount."), false);
this->AddPage(_page_steps, _("Steps"), iter_behavior, PREFS_PAGE_BEHAVIOR_STEPS);
// Clones options
@@ -1408,6 +1411,10 @@ void InkscapePreferences::initPageRendering()
_rendering_cache_size.init("/options/renderingcache/size", 0.0, 4096.0, 1.0, 32.0, 64.0, true, false);
_page_rendering.add_line( false, _("Rendering _cache size:"), _rendering_cache_size, C_("mebibyte (2^20 bytes) abbreviation","MiB"), _("Set the amount of memory per document which can be used to store rendered parts of the drawing for later reuse; set to zero to disable caching"), false);
+ // rendering tile multiplier
+ _rendering_tile_multiplier.init("/options/rendering/tile-multiplier", 1.0, 64.0, 1.0, 4.0, 1.0, true, false);
+ _page_rendering.add_line( false, _("Rendering tile multiplier:"), _rendering_tile_multiplier, _("requires restart"), _("Set the relative size of tiles used to render the canvas. The larger the value, the bigger the tile size."), false);
+
/* blur quality */
_blur_quality_best.init ( _("Best quality (slowest)"), "/options/blurquality/value",
BLUR_QUALITY_BEST, false, 0);
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 781b5e48e..e6ba4e4b2 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -215,6 +215,7 @@ protected:
UI::Widget::PrefSpinUnit _steps_scale;
UI::Widget::PrefSpinUnit _steps_inset;
UI::Widget::PrefSpinButton _steps_zoom;
+ UI::Widget::PrefSpinButton _steps_rotate;
UI::Widget::PrefRadioButton _t_sel_trans_obj;
UI::Widget::PrefRadioButton _t_sel_trans_outl;
@@ -294,6 +295,7 @@ protected:
UI::Widget::PrefCombo _switcher_style;
UI::Widget::PrefCheckButton _rendering_image_outline;
UI::Widget::PrefSpinButton _rendering_cache_size;
+ UI::Widget::PrefSpinButton _rendering_tile_multiplier;
UI::Widget::PrefSpinButton _filter_multi_threaded;
UI::Widget::PrefCheckButton _trans_scale_stroke;
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index e5becdb5c..bb9b61504 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -19,7 +19,7 @@
#include "livepatheffect-editor.h"
#include "desktop.h"
-
+#include <gtkmm/expander.h>
#include "document.h"
#include "document-undo.h"
#include "helper/action.h"
@@ -47,16 +47,21 @@ namespace Dialog {
/*####################
* Callback functions
*/
+
+
void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data)
{
LivePathEffectEditor *lpeeditor = static_cast<LivePathEffectEditor *>(data);
lpeeditor->lpe_list_locked = false;
- lpeeditor->onSelectionChanged(selection, true);
+ lpeeditor->lpe_changed = true;
+ lpeeditor->onSelectionChanged(selection);
}
-static void lpeeditor_selection_modified (Inkscape::Selection * selection, guint /*flags*/, gpointer data)
+void lpeeditor_selection_modified (Inkscape::Selection * selection, guint /*flags*/, gpointer data)
{
+
LivePathEffectEditor *lpeeditor = static_cast<LivePathEffectEditor *>(data);
+ lpeeditor->lpe_list_locked = false;
lpeeditor->onSelectionChanged(selection);
}
@@ -80,6 +85,7 @@ LivePathEffectEditor::LivePathEffectEditor()
: UI::Widget::Panel("", "/dialogs/livepatheffect", SP_VERB_DIALOG_LIVE_PATH_EFFECT),
deskTrack(),
lpe_list_locked(false),
+ lpe_changed(true),
effectwidget(NULL),
status_label("", Gtk::ALIGN_CENTER),
effectcontrol_frame(""),
@@ -190,11 +196,22 @@ LivePathEffectEditor::~LivePathEffectEditor()
void
LivePathEffectEditor::showParams(LivePathEffect::Effect& effect)
{
- if ( ! effect.upd_params ) {
+ if (!effect.upd_params && !lpe_changed) {
+ lpe_changed = false;
return;
}
+ bool expanderopen = false;
+ Gtk::Widget * defaultswidget = effect.defaultParamSet();
if (effectwidget) {
+ if (defaultswidget) {
+ Gtk::Expander * expander = NULL;
+ std::vector<Gtk::Widget *> childs = dynamic_cast<Gtk::Box *> (effectwidget)->get_children();
+ std::vector<Gtk::Widget *> childs_default = dynamic_cast<Gtk::Box *> (childs[childs.size()-1])->get_children();
+ if ((expander = dynamic_cast<Gtk::Expander *>(childs_default[childs_default.size()-1]))){
+ expanderopen = expander->get_expanded();
+ }
+ }
effectcontrol_vbox.remove(*effectwidget);
delete effectwidget;
effectwidget = NULL;
@@ -204,6 +221,15 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect& effect)
effectwidget = effect.newWidget();
if (effectwidget) {
+
+ if (defaultswidget) {
+ Gtk::Expander * expander = NULL;
+ std::vector<Gtk::Widget *> childs_default = dynamic_cast<Gtk::Box *> (defaultswidget)->get_children();
+ if ((expander = dynamic_cast<Gtk::Expander *>(childs_default[childs_default.size()-1]))){
+ expander->set_expanded(expanderopen);
+ }
+ dynamic_cast<Gtk::Box *> (effectwidget)->pack_start(*defaultswidget, true, true);
+ }
effectcontrol_vbox.pack_start(*effectwidget, true, true);
}
button_remove.show();
@@ -212,6 +238,8 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect& effect)
effectcontrol_frame.show();
effectcontrol_vbox.show_all_children();
// fixme: add resizing of dialog
+ effect.upd_params = false;
+ lpe_changed = false;
}
void
@@ -254,16 +282,15 @@ LivePathEffectEditor::set_sensitize_all(bool sensitive)
}
void
-LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel, bool upd_params)
+LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
{
if (lpe_list_locked) {
// this was triggered by selecting a row in the list, so skip reloading
lpe_list_locked = false;
return;
}
-
- effectlist_store->clear();
current_lpeitem = NULL;
+ effectlist_store->clear();
if ( sel && !sel->isEmpty() ) {
SPItem *item = sel->singleItem();
@@ -278,9 +305,6 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel, bool upd_para
if ( lpeitem->hasPathEffect() ) {
Inkscape::LivePathEffect::Effect *lpe = lpeitem->getCurrentLPE();
if (lpe) {
- if (upd_params) {
- lpe->upd_params = true;
- }
showParams(*lpe);
lpe_list_locked = true;
selectInList(lpe);
@@ -484,18 +508,12 @@ LivePathEffectEditor::onRemove()
SPItem *item = sel->singleItem();
SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
if ( lpeitem ) {
- if (current_lperef && current_lperef->lpeobject) {
- LivePathEffect::Effect * effect = current_lperef->lpeobject->get_lpe();
- if (effect) {
- effect->upd_params = true;
- }
- }
lpeitem->removeCurrentPathEffect(false);
-
+ current_lperef = NULL;
DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
_("Remove path effect") );
-
- effect_list_reload(lpeitem);
+ lpe_list_locked = false;
+ onSelectionChanged(sel);
}
}
@@ -512,7 +530,7 @@ void LivePathEffectEditor::onUp()
DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
_("Move path effect up") );
-
+
effect_list_reload(lpeitem);
}
}
@@ -529,7 +547,6 @@ void LivePathEffectEditor::onDown()
DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
_("Move path effect down") );
-
effect_list_reload(lpeitem);
}
}
@@ -554,7 +571,7 @@ void LivePathEffectEditor::on_effect_selection_changed()
current_lperef = lperef;
LivePathEffect::Effect * effect = lperef->lpeobject->get_lpe();
if (effect) {
- effect->upd_params = true;
+ lpe_changed = true;
showParams(*effect);
}
}
@@ -563,6 +580,7 @@ void LivePathEffectEditor::on_effect_selection_changed()
void LivePathEffectEditor::on_visibility_toggled( Glib::ustring const& str )
{
+
Gtk::TreeModel::Children::iterator iter = effectlist_view.get_model()->get_iter(str);
Gtk::TreeModel::Row row = *iter;
diff --git a/src/ui/dialog/livepatheffect-editor.h b/src/ui/dialog/livepatheffect-editor.h
index a7c749ef3..7f6f56fd2 100644
--- a/src/ui/dialog/livepatheffect-editor.h
+++ b/src/ui/dialog/livepatheffect-editor.h
@@ -45,7 +45,7 @@ public:
static LivePathEffectEditor &getInstance() { return *new LivePathEffectEditor(); }
- void onSelectionChanged(Inkscape::Selection *sel, bool upd_params = false);
+ void onSelectionChanged(Inkscape::Selection *sel);
void onSelectionModified(Inkscape::Selection *sel);
virtual void on_effect_selection_changed();
void setDesktop(SPDesktop *desktop);
@@ -96,7 +96,7 @@ private:
};
bool lpe_list_locked;
-
+ bool lpe_changed;
//Inkscape::UI::Widget::ComboBoxEnum<LivePathEffect::EffectType> combo_effecttype;
Gtk::Widget * effectwidget;
@@ -126,6 +126,7 @@ private:
LivePathEffect::LPEObjectReference * current_lperef;
friend void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data);
+ friend void lpeeditor_selection_modified (Inkscape::Selection * selection, guint /*flags*/, gpointer data);
LivePathEffectEditor(LivePathEffectEditor const &d);
LivePathEffectEditor& operator=(LivePathEffectEditor const &d);
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
index 740ff4f39..e9a13620b 100644
--- a/src/ui/dialog/symbols.cpp
+++ b/src/ui/dialog/symbols.cpp
@@ -57,7 +57,10 @@
#include <librevenge-stream/librevenge-stream.h>
using librevenge::RVNGFileStream;
+ using librevenge::RVNGString;
using librevenge::RVNGStringVector;
+ using librevenge::RVNGPropertyList;
+ using librevenge::RVNGSVGDrawingGenerator;
#else
#include <libwpd-stream/libwpd-stream.h>
@@ -451,6 +454,31 @@ void SymbolsDialog::iconChanged() {
}
#ifdef WITH_LIBVISIO
+
+#if WITH_LIBVISIO01
+// Extend libvisio's native RVNGSVGDrawingGenerator with support for extracting stencil names (to be used as ID/title)
+class REVENGE_API RVNGSVGDrawingGenerator_WithTitle : public RVNGSVGDrawingGenerator {
+ public:
+ RVNGSVGDrawingGenerator_WithTitle(RVNGStringVector &output, RVNGStringVector &titles, const RVNGString &nmSpace)
+ : RVNGSVGDrawingGenerator(output, nmSpace)
+ , _titles(titles)
+ {}
+
+ void startPage(const RVNGPropertyList &propList)
+ {
+ RVNGSVGDrawingGenerator::startPage(propList);
+ if (propList["draw:name"]) {
+ _titles.append(propList["draw:name"]->getStr());
+ } else {
+ _titles.append("");
+ }
+ }
+
+ private:
+ RVNGStringVector &_titles;
+};
+#endif
+
// Read Visio stencil files
SPDocument* read_vss( gchar* fullname, Glib::ustring name ) {
@@ -472,8 +500,9 @@ SPDocument* read_vss( gchar* fullname, Glib::ustring name ) {
}
RVNGStringVector output;
+ RVNGStringVector titles;
#if WITH_LIBVISIO01
- librevenge::RVNGSVGDrawingGenerator generator(output, "svg");
+ RVNGSVGDrawingGenerator_WithTitle generator(output, titles, "svg");
if (!libvisio::VisioDocument::parseStencils(&input, &generator)) {
#else
@@ -488,7 +517,7 @@ SPDocument* read_vss( gchar* fullname, Glib::ustring name ) {
// prepare a valid title for the symbol file
Glib::ustring title = Glib::Markup::escape_text(name);
- // prepare a valid id prefix for the symbols (unfortunately libvisio doesn't give us a name)
+ // prepare a valid id prefix for symbols libvisio doesn't give us a name for
Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create("[^a-zA-Z0-9_-]");
Glib::ustring id = regex1->replace(name, 0, "_", Glib::REGEX_MATCH_PARTIAL);
@@ -505,25 +534,30 @@ SPDocument* read_vss( gchar* fullname, Glib::ustring name ) {
tmpSVGOutput += "</title>\n";
tmpSVGOutput += " <defs>\n";
- // Each "symbol" is in it's own SVG file, we wrap with <symbol> and merge into one file.
+ // Each "symbol" is in its own SVG file, we wrap with <symbol> and merge into one file.
for (unsigned i=0; i<output.size(); ++i) {
std::stringstream ss;
- ss << i;
+ if (titles.size() == output.size() && titles[i] != "") {
+ // TODO: Do we need to check for duplicated titles?
+ ss << regex1->replace(titles[i].cstr(), 0, "_", Glib::REGEX_MATCH_PARTIAL);
+ } else {
+ ss << id << "_" << i;
+ }
+
+ tmpSVGOutput += " <symbol id=\"" + ss.str() + "\">\n";
- tmpSVGOutput += " <symbol id=\"";
- tmpSVGOutput += id;
- tmpSVGOutput += "_";
- tmpSVGOutput += ss.str();
- tmpSVGOutput += "\">\n";
+#if WITH_LIBVISIO01
+ if (titles.size() == output.size() && titles[i] != "") {
+ tmpSVGOutput += " <title>" + Glib::ustring(RVNGString::escapeXML(titles[i].cstr()).cstr()) + "</title>\n";
+ }
+#endif
std::istringstream iss( output[i].cstr() );
std::string line;
while( std::getline( iss, line ) ) {
- // std::cout << line << std::endl;
if( line.find( "svg:svg" ) == std::string::npos ) {
- tmpSVGOutput += line;
- tmpSVGOutput += "\n";
+ tmpSVGOutput += " " + line + "\n";
}
}
diff --git a/src/ui/event-debug.h b/src/ui/event-debug.h
new file mode 100644
index 000000000..dd33ca0e3
--- /dev/null
+++ b/src/ui/event-debug.h
@@ -0,0 +1,132 @@
+#ifndef SEEN_UI_EVENT_DEBUG_H
+#define SEEN_UI_EVENT_DEBUG_H
+
+/**
+ * @file
+ * Dump event data.
+ */
+/*
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtk/gtk.h>
+#include <glibmm/ustring.h>
+
+// See: https://developer.gnome.org/gdk3/stable/gdk3-Events.html
+
+inline void ui_dump_event (GdkEvent *event, Glib::ustring const &prefix, bool merge = true) {
+
+ static GdkEventType old_type = GDK_NOTHING;
+ static unsigned count = 0;
+
+ // Doesn't usually help to dump a zillion events of the same type (e.g. GDK_MOTION_NOTIFY).
+ ++count;
+ if (merge && event->type == old_type) {
+ if ( count == 1 ) {
+ std::cout << prefix << " ... ditto" << std::endl;
+ }
+ return;
+ }
+ count = 0;
+ old_type = event->type;
+
+ std::cout << prefix << ": ";
+
+ switch (event->type) {
+
+ case GDK_KEY_PRESS:
+ std::cout << "GDK_KEY_PRESS: " << event->key.hardware_keycode << std::endl;
+ break;
+ case GDK_KEY_RELEASE:
+ std::cout << "GDK_KEY_RELEASE: " << event->key.hardware_keycode << std::endl;
+ break;
+
+ case GDK_BUTTON_PRESS:
+ std::cout << "GDK_BUTTON_PRESS: " << event->button.button << std::endl;
+ break;
+ case GDK_2BUTTON_PRESS:
+ std::cout << "GDK_2BUTTON_PRESS: " << event->button.button << std::endl;
+ break;
+ case GDK_3BUTTON_PRESS:
+ std::cout << "GDK_3BUTTON_PRESS: " << event->button.button << std::endl;
+ break;
+ case GDK_BUTTON_RELEASE:
+ std::cout << "GDK_BUTTON_RELEASE: " << event->button.button << std::endl;
+ break;
+
+ case GDK_SCROLL:
+ std::cout << "GDK_SCROLL" << std::endl;
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ std::cout << "GDK_MOTION_NOTIFY" << std::endl;
+ break;
+ case GDK_ENTER_NOTIFY:
+ std::cout << "GDK_ENTER_NOTIFY" << std::endl;
+ break;
+ case GDK_LEAVE_NOTIFY:
+ std::cout << "GDK_LEAVE_NOTIFY" << std::endl;
+ break;
+
+ case GDK_TOUCH_BEGIN:
+ std::cout << "GDK_TOUCH_BEGIN" << std::endl;
+ break;
+ case GDK_TOUCH_UPDATE:
+ std::cout << "GDK_TOUCH_UPDATE" << std::endl;
+ break;
+ case GDK_TOUCH_END:
+ std::cout << "GDK_TOUCH_END" << std::endl;
+ break;
+ case GDK_TOUCH_CANCEL:
+ std::cout << "GDK_TOUCH_CANCEL" << std::endl;
+ break;
+
+#if GTK_CHECK_VERSION(3,18,0)
+
+ case GDK_TOUCHPAD_SWIPE:
+ std::cout << "GDK_TOUCHPAD_SWIPE" << std::endl;
+ break;
+ case GDK_TOUCHPAD_PINCH:
+ std::cout << "GDK_TOUCHPAD_PINCH" << std::endl;
+ break;
+
+#endif
+
+#if GTK_CHECK_VERSION(3,22,0)
+
+ case GDK_PAD_BUTTON_PRESS:
+ std::cout << "GDK_PAD_BUTTON_PRESS" << std::endl;
+ break;
+ case GDK_PAD_BUTTON_RELEASE:
+ std::cout << "GDK_PAD_BUTTON_RELEASE" << std::endl;
+ break;
+ case GDK_PAD_RING:
+ std::cout << "GDK_PAD_RING" << std::endl;
+ break;
+ case GDK_PAD_STRIP:
+ std::cout << "GDK_PAD_STRIP" << std::endl;
+ break;
+ case GDK_PAD_GROUP_MODE:
+ std::cout << "GDK_PAD_GROUP_MODE" << std::endl;
+ break;
+
+#endif
+
+ default:
+ std::cout << "GDK event not recognized!" << std::endl;
+ break;
+ }
+}
+
+#endif // SEEN_UI_EVENT_DEBUG_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp
index b11a61710..c1d85a896 100644
--- a/src/ui/object-edit.cpp
+++ b/src/ui/object-edit.cpp
@@ -782,6 +782,12 @@ public:
virtual void knot_click(unsigned int state);
};
+class ArcKnotHolderEntityCenter : public KnotHolderEntity {
+public:
+ virtual Geom::Point knot_get() const;
+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state);
+};
+
/*
* return values:
* 1 : inside
@@ -983,6 +989,30 @@ ArcKnotHolderEntityRY::knot_click(unsigned int state)
}
}
+void
+ArcKnotHolderEntityCenter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state)
+{
+ SPGenericEllipse *ge = dynamic_cast<SPGenericEllipse *>(item);
+ g_assert(ge != NULL);
+
+ Geom::Point const s = snap_knot_position(p, state);
+
+ ge->cx = s[Geom::X];
+ ge->cy = s[Geom::Y];
+
+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
+Geom::Point
+ArcKnotHolderEntityCenter::knot_get() const
+{
+ SPGenericEllipse const *ge = dynamic_cast<SPGenericEllipse *>(item);
+ g_assert(ge != NULL);
+
+ return Geom::Point(ge->cx.computed, ge->cy.computed);
+}
+
+
ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) :
KnotHolder(desktop, item, relhandler)
{
@@ -990,6 +1020,7 @@ ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRelea
ArcKnotHolderEntityRY *entity_ry = new ArcKnotHolderEntityRY();
ArcKnotHolderEntityStart *entity_start = new ArcKnotHolderEntityStart();
ArcKnotHolderEntityEnd *entity_end = new ArcKnotHolderEntityEnd();
+ ArcKnotHolderEntityCenter *entity_center = new ArcKnotHolderEntityCenter();
entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER,
_("Adjust ellipse <b>width</b>, with <b>Ctrl</b> to make circle"),
@@ -1011,10 +1042,15 @@ ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRelea
"ellipse for arc, <b>outside</b> for segment"),
SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR);
+ entity_center->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT,
+ _("Move the ellipse"),
+ SP_KNOT_SHAPE_CROSS);
+
entity.push_back(entity_rx);
entity.push_back(entity_ry);
entity.push_back(entity_start);
entity.push_back(entity_end);
+ entity.push_back(entity_center);
add_pattern_knotholder();
}
@@ -1035,6 +1071,12 @@ public:
virtual void knot_click(unsigned int state);
};
+class StarKnotHolderEntityCenter : public KnotHolderEntity {
+public:
+ virtual Geom::Point knot_get() const;
+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state);
+};
+
void
StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state)
{
@@ -1092,6 +1134,17 @@ StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origi
}
}
+void
+StarKnotHolderEntityCenter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state)
+{
+ SPStar *star = dynamic_cast<SPStar *>(item);
+ g_assert(star != NULL);
+
+ star->center = snap_knot_position(p, state);
+
+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
Geom::Point
StarKnotHolderEntity1::knot_get() const
{
@@ -1115,6 +1168,17 @@ StarKnotHolderEntity2::knot_get() const
return sp_star_get_xy(star, SP_STAR_POINT_KNOT2, 0);
}
+Geom::Point
+StarKnotHolderEntityCenter::knot_get() const
+{
+ g_assert(item != NULL);
+
+ SPStar const *star = dynamic_cast<SPStar const *>(item);
+ g_assert(star != NULL);
+
+ return star->center;
+}
+
static void
sp_star_knot_click(SPItem *item, unsigned int state)
{
@@ -1166,6 +1230,12 @@ StarKnotHolder::StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRel
entity.push_back(entity2);
}
+ StarKnotHolderEntityCenter *entity_center = new StarKnotHolderEntityCenter();
+ entity_center->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT,
+ _("Move the star"),
+ SP_KNOT_SHAPE_CROSS);
+ entity.push_back(entity_center);
+
add_pattern_knotholder();
}
diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp
index c2b86b538..7228a52bc 100644
--- a/src/ui/tools/calligraphic-tool.cpp
+++ b/src/ui/tools/calligraphic-tool.cpp
@@ -60,6 +60,7 @@
#include "verbs.h"
#include "ui/tools/calligraphic-tool.h"
+#include "ui/tools/freehand-base.h"
using Inkscape::DocumentUndo;
@@ -771,6 +772,8 @@ bool CalligraphicTool::root_handler(GdkEvent* event) {
this->message_context->clear();
ret = TRUE;
+ } else if (!this->dragging && event->button.button == 1 && !this->space_panning){
+ spdc_create_single_dot(this, this->desktop->w2d(motion_w), "/tools/calligraphic", event->button.state);
}
break;
}
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index 056c723ee..4af70a816 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -913,7 +913,8 @@ static void spdc_free_colors(FreehandBase *dc)
}
void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *tool, guint event_state) {
- g_return_if_fail(!strcmp(tool, "/tools/freehand/pen") || !strcmp(tool, "/tools/freehand/pencil"));
+ g_return_if_fail(!strcmp(tool, "/tools/freehand/pen") || !strcmp(tool, "/tools/freehand/pencil")
+ || !strcmp(tool, "/tools/calligraphic") );
Glib::ustring tool_path = tool;
SPDesktop *desktop = ec->desktop;
@@ -937,7 +938,8 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too
// unset stroke and set fill color to former stroke color
gchar * str;
- str = g_strdup_printf("fill:#%06x;stroke:none;", sp_desktop_get_color_tool(desktop, tool, false) >> 8);
+ str = strcmp(tool, "/tools/calligraphic") ? g_strdup_printf("fill:#%06x;stroke:none;", sp_desktop_get_color_tool(desktop, tool, false) >> 8)
+ : g_strdup_printf("fill:#%06x;stroke:#%06x;", sp_desktop_get_color_tool(desktop, tool, true) >> 8, sp_desktop_get_color_tool(desktop, tool, false) >> 8);
repr->setAttribute("style", str);
g_free(str);
@@ -948,6 +950,8 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too
Geom::Affine const i2d (item->i2dt_affine ());
Geom::Point pp = pt * i2d.inverse();
double rad = 0.5 * prefs->getDouble(tool_path + "/dot-size", 3.0);
+ if (!strcmp(tool, "/tools/calligraphic"))
+ rad = 0.1 * prefs->getDouble(tool_path + "/width", 3.0) / desktop->current_zoom();
if (event_state & GDK_MOD1_MASK) {
// TODO: We vary the dot size between 0.5*rad and 1.5*rad, where rad is the dot size
// as specified in prefs. Very simple, but it might be sufficient in practice. If not,
diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp
index 8561e234f..0c948c91c 100644
--- a/src/ui/tools/node-tool.cpp
+++ b/src/ui/tools/node-tool.cpp
@@ -297,9 +297,8 @@ void sp_update_helperpath() {
Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i);
selectedNodesPositions.push_back(n->position());
}
- lpe->setSelectedNodePos(selectedNodesPositions);
+ lpe->setSelectedNodePoints(selectedNodesPositions);
lpe->setCurrentZoom(desktop->current_zoom());
-
SPCurve *c = new SPCurve();
SPCurve *cc = new SPCurve();
std::vector<Geom::PathVector> cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem()));
diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp
index 8c7f54d14..3d755eadc 100644
--- a/src/ui/tools/tool-base.cpp
+++ b/src/ui/tools/tool-base.cpp
@@ -22,12 +22,21 @@
#include "shortcuts.h"
#include "file.h"
+
+#include "ui/interface.h"
+#include "ui/event-debug.h"
+#include "ui/tool/control-point.h"
+#include "ui/shape-editor.h"
#include "ui/tools/tool-base.h"
+#include "ui/tools-switch.h"
+#include "ui/tools/lpe-tool.h"
#include <gdk/gdkkeysyms.h>
#include <glibmm/i18n.h>
#include "display/sp-canvas.h"
+#include "display/sp-canvas-group.h"
+#include "display/canvas-rotate.h"
#include "xml/node-event-vector.h"
#include "sp-cursor.h"
#include "desktop.h"
@@ -36,16 +45,11 @@
#include "desktop-style.h"
#include "sp-namedview.h"
#include "selection.h"
-#include "ui/interface.h"
#include "macros.h"
-#include "ui/tools-switch.h"
#include "message-context.h"
#include "gradient-drag.h"
#include "rubberband.h"
#include "selcue.h"
-#include "ui/tools/lpe-tool.h"
-#include "ui/tool/control-point.h"
-#include "ui/shape-editor.h"
#include "sp-guide.h"
#include "knot-ptr.h"
@@ -94,7 +98,6 @@ ToolBase::ToolBase(gchar const *const *cursor_shape, gint hot_x, gint hot_y, boo
, _grdrag(NULL)
, shape_editor(NULL)
, space_panning(false)
- , rotating_mode(false)
, _delayed_snap_event(NULL)
, _dse_callback_in_process(false)
, desktop(NULL)
@@ -324,134 +327,120 @@ static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration,
}
bool ToolBase::root_handler(GdkEvent* event) {
+
+ // ui_dump_event (event, "ToolBase::root_handler");
static Geom::Point button_w;
static unsigned int panning = 0;
static unsigned int panning_cursor = 0;
static unsigned int zoom_rb = 0;
- static double angle = 0;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
/// @todo REmove redundant /value in preference keys
tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
bool allow_panning = prefs->getBool("/options/spacebarpans/value");
- int rotation_snap = 180.0/prefs->getInt("/options/rotationsnapsperpi/value", 12);
gint ret = FALSE;
switch (event->type) {
- case GDK_2BUTTON_PRESS:
- if (panning) {
- panning = 0;
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
+ case GDK_2BUTTON_PRESS:
+ if (panning) {
+ panning = 0;
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
+ ret = TRUE;
+ } else {
+ /* sp_desktop_dialog(); */
+ }
+ break;
+
+ case GDK_BUTTON_PRESS:
+ // save drag origin
+ xp = (gint) event->button.x;
+ yp = (gint) event->button.y;
+ within_tolerance = true;
+
+ button_w = Geom::Point(event->button.x, event->button.y);
+
+ switch (event->button.button) {
+ case 1:
+ if (this->space_panning) {
+ // When starting panning, make sure there are no snap events pending because these might disable the panning again
+ if (_uses_snap) {
+ sp_event_context_discard_delayed_snap_event(this);
+ }
+ panning = 1;
+
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK, NULL,
+ event->button.time - 1);
+
ret = TRUE;
- } else {
- /* sp_desktop_dialog(); */
}
break;
- case GDK_BUTTON_PRESS:
- // save drag origin
- xp = (gint) event->button.x;
- yp = (gint) event->button.y;
- within_tolerance = true;
+ case 2:
+ if (event->button.state & GDK_CONTROL_MASK) {
+ // On screen canvas rotation preview
+
+ // Grab background before doing anything else
+ sp_canvas_rotate_start (SP_CANVAS_ROTATE(desktop->canvas_rotate),
+ desktop->canvas->_backing_store);
+ sp_canvas_item_ungrab (desktop->acetate, event->button.time);
+ sp_canvas_item_show (desktop->canvas_rotate);
+ sp_canvas_item_grab (desktop->canvas_rotate,
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL, event->button.time );
+ // sp_canvas_item_hide (desktop->drawing);
+
+ } else if (event->button.state & GDK_SHIFT_MASK) {
+ zoom_rb = 2;
+ } else {
+ // When starting panning, make sure there are no snap events pending because these might disable the panning again
+ if (_uses_snap) {
+ sp_event_context_discard_delayed_snap_event(this);
+ }
+ panning = 2;
- button_w = Geom::Point(event->button.x, event->button.y);
- switch (event->button.button) {
- case 1:
- if (this->space_panning) {
- // When starting panning, make sure there are no snap events pending because these might disable the panning again
- if (_uses_snap) {
- sp_event_context_discard_delayed_snap_event(this);
- }
- panning = 1;
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK,
+ NULL, event->button.time - 1);
- sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK, NULL,
- event->button.time - 1);
+ }
- ret = TRUE;
- }
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
- break;
+ ret = TRUE;
+ break;
- case 2:
- if (event->button.state & GDK_CONTROL_MASK) {
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
- desktop->canvas->startRotateTo(desktop->namedview->document_rotation);
- this->rotating_mode = true;
- this->message_context->set(Inkscape::INFORMATION_MESSAGE,
- _("<b>MMB + mouse move</b> to rotate canvas, use modifiers on screen to change snaps"));
- } else {
- if (event->button.state & GDK_SHIFT_MASK) {
- zoom_rb = 2;
- } else {
- // When starting panning, make sure there are no snap events pending because these might disable the panning again
- if (_uses_snap) {
- sp_event_context_discard_delayed_snap_event(this);
- }
- panning = 2;
-
- sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK, NULL,
- event->button.time - 1);
- }
- ret = TRUE;
+ case 3:
+ if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) {
+ // When starting panning, make sure there are no snap events pending because these might disable the panning again
+ if (_uses_snap) {
+ sp_event_context_discard_delayed_snap_event(this);
}
- ret = TRUE;
- break;
-
- case 3:
- if ((event->button.state & GDK_SHIFT_MASK) || (event->button.state & GDK_CONTROL_MASK)) {
- // When starting panning, make sure there are no snap events pending because these might disable the panning again
- if (_uses_snap) {
- sp_event_context_discard_delayed_snap_event(this);
- }
- panning = 3;
+ panning = 3;
- sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK, NULL,
- event->button.time);
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK, NULL,
+ event->button.time);
- ret = TRUE;
- } else if( !this->space_panning) {
- sp_event_root_menu_popup(desktop, NULL, event);
- }
ret = TRUE;
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
- break;
-
- default:
- break;
+ } else {
+ sp_event_root_menu_popup(desktop, NULL, event);
}
break;
- case GDK_MOTION_NOTIFY:
- if (this->rotating_mode) {
- button_w = Geom::Point(event->motion.x, event->motion.y);
- Geom::Point const motion_dt(desktop->doc2dt(desktop->w2d(button_w)));
- Geom::Rect view = desktop->get_display_area();
- Geom::Point view_center = desktop->doc2dt(view.midpoint());
- Geom::Ray center_ray(motion_dt, view_center);
- angle = Geom::deg_from_rad(center_ray.angle()) - 90;
- if (event->motion.state & GDK_SHIFT_MASK && event->motion.state & GDK_CONTROL_MASK) {
- angle = 0;
- } else if(event->motion.state & GDK_CONTROL_MASK) {
- angle = floor(angle/rotation_snap) * rotation_snap;
- } else if (event->motion.state & GDK_SHIFT_MASK) {
- angle = desktop->namedview->document_rotation;
- } else if (event->motion.state & GDK_MOD1_MASK) {
- //Decimal raw angle
- } else {
- angle = floor(angle);
- }
- desktop->canvas->rotateTo(angle);
- } else if (panning == 4 && !xp && !yp ) {
+ default:
+ break;
+ }
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ if (panning) {
+ if (panning == 4 && !xp && !yp ) {
// <Space> + mouse panning started, save location and grab canvas
xp = event->motion.x;
yp = event->motion.y;
@@ -463,465 +452,430 @@ bool ToolBase::root_handler(GdkEvent* event) {
| GDK_POINTER_MOTION_HINT_MASK, NULL,
event->motion.time - 1);
}
- if (panning && !this->rotating_mode) {
- if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_MASK))
- || (panning == 1 && !(event->motion.state & GDK_BUTTON1_MASK))
- || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) {
- /* Gdk seems to lose button release for us sometimes :-( */
- panning = 0;
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
- ret = TRUE;
- } else {
- if (within_tolerance && (abs((gint) event->motion.x - xp)
- < tolerance) && (abs((gint) event->motion.y - yp)
- < tolerance)) {
- // do not drag if we're within tolerance from origin
- break;
- }
-
- // Once the user has moved farther than tolerance from
- // the original location (indicating they intend to move
- // the object, not click), then always process the motion
- // notify coordinates as given (no snapping back to origin)
- within_tolerance = false;
-
- // gobble subsequent motion events to prevent "sticking"
- // when scrolling is slow
- gobble_motion_events(panning == 2 ? GDK_BUTTON2_MASK : (panning
- == 1 ? GDK_BUTTON1_MASK : GDK_BUTTON3_MASK));
-
- if (panning_cursor == 0) {
- panning_cursor = 1;
- this->sp_event_context_set_cursor(GDK_FLEUR);
- }
-
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- Geom::Point const moved_w(motion_w - button_w);
- this->desktop->scroll_relative(moved_w, true); // we're still scrolling, do not redraw
- ret = TRUE;
- }
- } else if (zoom_rb) {
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- Geom::Point const motion_dt(desktop->w2d(motion_w));
+ if ((panning == 2 && !(event->motion.state & GDK_BUTTON2_MASK))
+ || (panning == 1 && !(event->motion.state & GDK_BUTTON1_MASK))
+ || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) {
+ /* Gdk seems to lose button release for us sometimes :-( */
+ panning = 0;
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
+ ret = TRUE;
+ } else {
if (within_tolerance && (abs((gint) event->motion.x - xp)
< tolerance) && (abs((gint) event->motion.y - yp)
< tolerance)) {
- break; // do not drag if we're within tolerance from origin
+ // do not drag if we're within tolerance from origin
+ break;
}
- // Once the user has moved farther than tolerance from the original location
- // (indicating they intend to move the object, not click), then always process the
- // motion notify coordinates as given (no snapping back to origin)
+ // Once the user has moved farther than tolerance from
+ // the original location (indicating they intend to move
+ // the object, not click), then always process the motion
+ // notify coordinates as given (no snapping back to origin)
within_tolerance = false;
- if (Inkscape::Rubberband::get(desktop)->is_started()) {
- Inkscape::Rubberband::get(desktop)->move(motion_dt);
- } else {
- Inkscape::Rubberband::get(desktop)->start(desktop, motion_dt);
- }
+ // gobble subsequent motion events to prevent "sticking"
+ // when scrolling is slow
+ gobble_motion_events(panning == 2 ? GDK_BUTTON2_MASK : (panning
+ == 1 ? GDK_BUTTON1_MASK : GDK_BUTTON3_MASK));
- if (zoom_rb == 2) {
- gobble_motion_events(GDK_BUTTON2_MASK);
+ if (panning_cursor == 0) {
+ panning_cursor = 1;
+ this->sp_event_context_set_cursor(GDK_FLEUR);
}
- }
- break;
- case GDK_BUTTON_RELEASE:
- if (this->rotating_mode && event->button.button == 2) {
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const moved_w(motion_w - button_w);
+ this->desktop->scroll_relative(moved_w, true); // we're still scrolling, do not redraw
ret = TRUE;
- if (desktop->canvas->endRotateTo()) {
- sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle);
- }
+ }
+ } else if (zoom_rb) {
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt(desktop->w2d(motion_w));
+
+ if (within_tolerance && (abs((gint) event->motion.x - xp)
+ < tolerance) && (abs((gint) event->motion.y - yp)
+ < tolerance)) {
+ break; // do not drag if we're within tolerance from origin
+ }
+
+ // Once the user has moved farther than tolerance from the original location
+ // (indicating they intend to move the object, not click), then always process the
+ // motion notify coordinates as given (no snapping back to origin)
+ within_tolerance = false;
+
+ if (Inkscape::Rubberband::get(desktop)->is_started()) {
+ Inkscape::Rubberband::get(desktop)->move(motion_dt);
} else {
- xp = yp = 0;
- if (panning_cursor == 1) {
- panning_cursor = 0;
- GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas());
- gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor);
- }
+ Inkscape::Rubberband::get(desktop)->start(desktop, motion_dt);
+ }
- if (within_tolerance && (panning || zoom_rb)) {
- zoom_rb = 0;
+ if (zoom_rb == 2) {
+ gobble_motion_events(GDK_BUTTON2_MASK);
+ }
+ }
+ break;
- if (panning) {
- panning = 0;
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
- event->button.time);
- }
+ case GDK_BUTTON_RELEASE:
- Geom::Point const event_w(event->button.x, event->button.y);
- Geom::Point const event_dt(desktop->w2d(event_w));
+ xp = yp = 0;
- double const zoom_inc = prefs->getDoubleLimited(
- "/options/zoomincrement/value", M_SQRT2, 1.01, 10);
+ if (panning_cursor == 1) {
+ panning_cursor = 0;
+ GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas());
+ gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor);
+ }
- desktop->zoom_relative_keep_point(event_dt, (event->button.state
- & GDK_SHIFT_MASK) ? 1 / zoom_inc : zoom_inc);
+ if (within_tolerance && (panning || zoom_rb)) {
+ zoom_rb = 0;
- desktop->updateNow();
- ret = TRUE;
- } else if (panning == event->button.button) {
- panning = 0;
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
- event->button.time);
+ if (panning) {
+ panning = 0;
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
+ event->button.time);
+ }
- // in slow complex drawings, some of the motion events are lost;
- // to make up for this, we scroll it once again to the button-up event coordinates
- // (i.e. canvas will always get scrolled all the way to the mouse release point,
- // even if few intermediate steps were visible)
- Geom::Point const motion_w(event->button.x, event->button.y);
- Geom::Point const moved_w(motion_w - button_w);
+ Geom::Point const event_w(event->button.x, event->button.y);
+ Geom::Point const event_dt(desktop->w2d(event_w));
- this->desktop->scroll_relative(moved_w);
- desktop->updateNow();
- ret = TRUE;
- } else if (zoom_rb == event->button.button) {
- zoom_rb = 0;
+ double const zoom_inc = prefs->getDoubleLimited(
+ "/options/zoomincrement/value", M_SQRT2, 1.01, 10);
- Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle();
- Inkscape::Rubberband::get(desktop)->stop();
+ desktop->zoom_relative_keep_point(event_dt, (event->button.state
+ & GDK_SHIFT_MASK) ? 1 / zoom_inc : zoom_inc);
- if (b && !within_tolerance) {
- desktop->set_display_area(*b, 10);
- }
+ desktop->updateNow();
+ ret = TRUE;
+ } else if (panning == event->button.button) {
+ panning = 0;
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
+ event->button.time);
+
+ // in slow complex drawings, some of the motion events are lost;
+ // to make up for this, we scroll it once again to the button-up event coordinates
+ // (i.e. canvas will always get scrolled all the way to the mouse release point,
+ // even if few intermediate steps were visible)
+ Geom::Point const motion_w(event->button.x, event->button.y);
+ Geom::Point const moved_w(motion_w - button_w);
+
+ this->desktop->scroll_relative(moved_w);
+ desktop->updateNow();
+ ret = TRUE;
+ } else if (zoom_rb == event->button.button) {
+ zoom_rb = 0;
- ret = TRUE;
- }
- if (this->rotating_mode && event->button.button != 3) {
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
- ret = TRUE;
- desktop->canvas->endRotateTo();
- }
- }
- break;
+ Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle();
+ Inkscape::Rubberband::get(desktop)->stop();
- case GDK_KEY_PRESS: {
- double const acceleration = prefs->getDoubleLimited(
- "/options/scrollingacceleration/value", 0, 0, 6);
- int const key_scroll = prefs->getIntLimited("/options/keyscroll/value",
- 10, 0, 1000);
-
- if (this->rotating_mode &&
- get_group0_keyval(&event->key) != GDK_KEY_space &&
- get_group0_keyval(&event->key) != GDK_KEY_Shift_L &&
- get_group0_keyval(&event->key) != GDK_KEY_Shift_R &&
- get_group0_keyval(&event->key) != GDK_KEY_Control_L &&
- get_group0_keyval(&event->key) != GDK_KEY_Control_R &&
- get_group0_keyval(&event->key) != GDK_KEY_Alt_L &&
- get_group0_keyval(&event->key) != GDK_KEY_Alt_R )
- {
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
- ret = TRUE;
- desktop->canvas->endRotateTo();
- break;
+ if (b && !within_tolerance) {
+ desktop->set_display_area(*b, 10);
}
- switch (get_group0_keyval(&event->key)) {
- // GDK insists on stealing these keys (F1 for no idea what, tab for cycling widgets
- // in the editing window). So we resteal them back and run our regular shortcut
- // invoker on them.
- unsigned int shortcut;
- case GDK_KEY_Tab:
- case GDK_KEY_ISO_Left_Tab:
- case GDK_KEY_F1:
- shortcut = get_group0_keyval(&event->key);
-
- if (event->key.state & GDK_SHIFT_MASK) {
- shortcut |= SP_SHORTCUT_SHIFT_MASK;
- }
+ ret = TRUE;
+ }
+ break;
- if (event->key.state & GDK_CONTROL_MASK) {
- shortcut |= SP_SHORTCUT_CONTROL_MASK;
- }
+ case GDK_KEY_PRESS: {
+ double const acceleration = prefs->getDoubleLimited(
+ "/options/scrollingacceleration/value", 0, 0, 6);
+ int const key_scroll = prefs->getIntLimited("/options/keyscroll/value",
+ 10, 0, 1000);
+
+ switch (get_group0_keyval(&event->key)) {
+ // GDK insists on stealing these keys (F1 for no idea what, tab for cycling widgets
+ // in the editing window). So we resteal them back and run our regular shortcut
+ // invoker on them.
+ unsigned int shortcut;
+ case GDK_KEY_Tab:
+ case GDK_KEY_ISO_Left_Tab:
+ case GDK_KEY_F1:
+ shortcut = get_group0_keyval(&event->key);
+
+ if (event->key.state & GDK_SHIFT_MASK) {
+ shortcut |= SP_SHORTCUT_SHIFT_MASK;
+ }
- if (event->key.state & GDK_MOD1_MASK) {
- shortcut |= SP_SHORTCUT_ALT_MASK;
- }
+ if (event->key.state & GDK_CONTROL_MASK) {
+ shortcut |= SP_SHORTCUT_CONTROL_MASK;
+ }
- ret = sp_shortcut_invoke(shortcut, desktop);
- break;
+ if (event->key.state & GDK_MOD1_MASK) {
+ shortcut |= SP_SHORTCUT_ALT_MASK;
+ }
- case GDK_KEY_Q:
- case GDK_KEY_q:
- if (desktop->quick_zoomed()) {
- ret = TRUE;
- }
- if (!MOD__SHIFT(event) && !MOD__CTRL(event) && !MOD__ALT(event)) {
- desktop->zoom_quick(true);
- ret = TRUE;
- }
- break;
+ ret = sp_shortcut_invoke(shortcut, desktop);
+ break;
- case GDK_KEY_W:
- case GDK_KEY_w:
- case GDK_KEY_F4:
- /* Close view */
- if (MOD__CTRL_ONLY(event)) {
- sp_ui_close_view(NULL);
- ret = TRUE;
- }
- break;
+ case GDK_KEY_Q:
+ case GDK_KEY_q:
+ if (desktop->quick_zoomed()) {
+ ret = TRUE;
+ }
+ if (!MOD__SHIFT(event) && !MOD__CTRL(event) && !MOD__ALT(event)) {
+ desktop->zoom_quick(true);
+ ret = TRUE;
+ }
+ break;
- case GDK_KEY_Left: // Ctrl Left
- case GDK_KEY_KP_Left:
- case GDK_KEY_KP_4:
- if (MOD__CTRL_ONLY(event)) {
- int i = (int) floor(key_scroll * accelerate_scroll(event,
- acceleration, desktop->getCanvas()));
+ case GDK_KEY_W:
+ case GDK_KEY_w:
+ case GDK_KEY_F4:
+ /* Close view */
+ if (MOD__CTRL_ONLY(event)) {
+ sp_ui_close_view(NULL);
+ ret = TRUE;
+ }
+ break;
- gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
- this->desktop->scroll_relative(Geom::Point(i, 0));
- ret = TRUE;
- }
- break;
+ case GDK_KEY_Left: // Ctrl Left
+ case GDK_KEY_KP_Left:
+ case GDK_KEY_KP_4:
+ if (MOD__CTRL_ONLY(event)) {
+ int i = (int) floor(key_scroll * accelerate_scroll(event,
+ acceleration, desktop->getCanvas()));
- case GDK_KEY_Up: // Ctrl Up
- case GDK_KEY_KP_Up:
- case GDK_KEY_KP_8:
- if (MOD__CTRL_ONLY(event)) {
- int i = (int) floor(key_scroll * accelerate_scroll(event,
- acceleration, desktop->getCanvas()));
+ gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
+ this->desktop->scroll_relative(Geom::Point(i, 0));
+ ret = TRUE;
+ }
+ break;
- gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
- this->desktop->scroll_relative(Geom::Point(0, i));
- ret = TRUE;
- }
- break;
+ case GDK_KEY_Up: // Ctrl Up
+ case GDK_KEY_KP_Up:
+ case GDK_KEY_KP_8:
+ if (MOD__CTRL_ONLY(event)) {
+ int i = (int) floor(key_scroll * accelerate_scroll(event,
+ acceleration, desktop->getCanvas()));
- case GDK_KEY_Right: // Ctrl Right
- case GDK_KEY_KP_Right:
- case GDK_KEY_KP_6:
- if (MOD__CTRL_ONLY(event)) {
- int i = (int) floor(key_scroll * accelerate_scroll(event,
- acceleration, desktop->getCanvas()));
+ gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
+ this->desktop->scroll_relative(Geom::Point(0, i));
+ ret = TRUE;
+ }
+ break;
- gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
- this->desktop->scroll_relative(Geom::Point(-i, 0));
- ret = TRUE;
- }
- break;
+ case GDK_KEY_Right: // Ctrl Right
+ case GDK_KEY_KP_Right:
+ case GDK_KEY_KP_6:
+ if (MOD__CTRL_ONLY(event)) {
+ int i = (int) floor(key_scroll * accelerate_scroll(event,
+ acceleration, desktop->getCanvas()));
- case GDK_KEY_Down: // Ctrl Down
- case GDK_KEY_KP_Down:
- case GDK_KEY_KP_2:
- if (MOD__CTRL_ONLY(event)) {
- int i = (int) floor(key_scroll * accelerate_scroll(event,
- acceleration, desktop->getCanvas()));
+ gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
+ this->desktop->scroll_relative(Geom::Point(-i, 0));
+ ret = TRUE;
+ }
+ break;
- gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
- this->desktop->scroll_relative(Geom::Point(0, -i));
- ret = TRUE;
- }
- break;
+ case GDK_KEY_Down: // Ctrl Down
+ case GDK_KEY_KP_Down:
+ case GDK_KEY_KP_2:
+ if (MOD__CTRL_ONLY(event)) {
+ int i = (int) floor(key_scroll * accelerate_scroll(event,
+ acceleration, desktop->getCanvas()));
- case GDK_KEY_Menu:
- sp_event_root_menu_popup(desktop, NULL, event);
+ gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK);
+ this->desktop->scroll_relative(Geom::Point(0, -i));
ret = TRUE;
- break;
+ }
+ break;
- case GDK_KEY_F10:
- if (MOD__SHIFT_ONLY(event)) {
- sp_event_root_menu_popup(desktop, NULL, event);
- ret = TRUE;
- }
- break;
+ case GDK_KEY_Menu:
+ sp_event_root_menu_popup(desktop, NULL, event);
+ ret = TRUE;
+ break;
- case GDK_KEY_space:
-// if (event->key.state & GDK_CONTROL_MASK) {
-// sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time);
-// desktop->canvas->startRotateTo(desktop->namedview->document_rotation);
-// this->rotating_mode = true;
-// this->message_context->set(Inkscape::INFORMATION_MESSAGE,
-// _("<b>Space+mouse move</b> to rotate canvas, use modifiers on screen to change snaps"));
-// } else {
- within_tolerance = true;
- xp = yp = 0;
- if (!allow_panning) break;
- panning = 4;
- this->space_panning = true;
- this->message_context->set(Inkscape::INFORMATION_MESSAGE,
- _("<b>Space+mouse move</b> to pan canvas"));
-// }
+ case GDK_KEY_F10:
+ if (MOD__SHIFT_ONLY(event)) {
+ sp_event_root_menu_popup(desktop, NULL, event);
ret = TRUE;
- break;
+ }
+ break;
- case GDK_KEY_z:
- case GDK_KEY_Z:
- if (MOD__ALT_ONLY(event)) {
- desktop->zoom_grab_focus();
- ret = TRUE;
- }
- break;
+ case GDK_KEY_space:
+ within_tolerance = true;
+ xp = yp = 0;
+ if (!allow_panning) break;
+ panning = 4;
+ this->space_panning = true;
+ this->message_context->set(Inkscape::INFORMATION_MESSAGE,
+ _("<b>Space+mouse move</b> to pan canvas"));
- default:
- break;
- }
- }
+ ret = TRUE;
break;
- case GDK_KEY_RELEASE:
- if (this->rotating_mode &&
- get_group0_keyval(&event->key) != GDK_KEY_space &&
- get_group0_keyval(&event->key) != GDK_KEY_Shift_L &&
- get_group0_keyval(&event->key) != GDK_KEY_Shift_R &&
- get_group0_keyval(&event->key) != GDK_KEY_Control_L &&
- get_group0_keyval(&event->key) != GDK_KEY_Control_R &&
- get_group0_keyval(&event->key) != GDK_KEY_Alt_L &&
- get_group0_keyval(&event->key) != GDK_KEY_Alt_R )
- {
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
+ case GDK_KEY_z:
+ case GDK_KEY_Z:
+ if (MOD__ALT_ONLY(event)) {
+ desktop->zoom_grab_focus();
ret = TRUE;
- desktop->canvas->endRotateTo();
- break;
}
+ break;
- // Stop panning on any key release
- if (this->space_panning) {
- this->space_panning = false;
- this->message_context->clear();
+ default:
+ break;
}
+ }
+ break;
- if (panning) {
- panning = 0;
- xp = yp = 0;
+ case GDK_KEY_RELEASE:
+ // Stop panning on any key release
+ if (this->space_panning) {
+ this->space_panning = false;
+ this->message_context->clear();
+ }
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
- event->key.time);
+ if (panning) {
+ panning = 0;
+ xp = yp = 0;
+
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate),
+ event->key.time);
+
+ desktop->updateNow();
+ }
+
+ if (panning_cursor == 1) {
+ panning_cursor = 0;
+ GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas());
+ gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor);
+ }
+
+ switch (get_group0_keyval(&event->key)) {
+ case GDK_KEY_space:
+ if (within_tolerance) {
+ // Space was pressed, but not panned
+ sp_toggle_selector(desktop);
- desktop->updateNow();
+ // Be careful, sp_toggle_selector will delete ourselves.
+ // Thus, make sure we return immediately.
+ return true;
}
- if (panning_cursor == 1) {
- panning_cursor = 0;
- GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas());
- gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor);
+ break;
+
+ case GDK_KEY_Q:
+ case GDK_KEY_q:
+ if (desktop->quick_zoomed()) {
+ desktop->zoom_quick(false);
+ ret = TRUE;
}
+ break;
- switch (get_group0_keyval(&event->key)) {
- case GDK_KEY_space:
-// if (this->rotating_mode) {
-// desktop->canvas->clearRotateTo();
-// this->rotating_mode = false;
-// ret = TRUE;
-// if (desktop->canvas->endRotateTo()) {
-// sp_repr_set_svg_double(desktop->namedview->getRepr(), "inkscape:document-rotation", angle);
-// }
-// }
- if (within_tolerance) {
- // Space was pressed, but not panned
- sp_toggle_selector(desktop);
-
- // Be careful, sp_toggle_selector will delete ourselves.
- // Thus, make sure we return immediately.
- return true;
- }
+ default:
+ break;
+ }
+ break;
+
+ case GDK_SCROLL: {
+ bool ctrl = (event->scroll.state & GDK_CONTROL_MASK);
+ bool shift = (event->scroll.state & GDK_SHIFT_MASK);
+ bool wheelzooms = prefs->getBool("/options/wheelzooms/value");
+
+ int const wheel_scroll = prefs->getIntLimited(
+ "/options/wheelscroll/value", 40, 0, 1000);
+
+ // Size of smooth-scrolls (only used in GTK+ 3)
+ gdouble delta_x = 0;
+ gdouble delta_y = 0;
+
+ if (ctrl & shift) {
+ /* ctrl + shift, rotate */
+
+ double rotate_inc = prefs->getDoubleLimited(
+ "/options/rotateincrement/value", 15, 1, 90, "°" );
+ rotate_inc *= M_PI/180.0;
+
+ switch (event->scroll.direction) {
+ case GDK_SCROLL_UP:
+ // Do nothing
break;
- case GDK_KEY_Q:
- case GDK_KEY_q:
- if (desktop->quick_zoomed()) {
- desktop->zoom_quick(false);
- ret = TRUE;
- }
+ case GDK_SCROLL_DOWN:
+ rotate_inc = -rotate_inc;
break;
default:
+ rotate_inc = 0.0;
break;
}
- break;
- case GDK_SCROLL: {
- if (this->rotating_mode) {
- desktop->canvas->clearRotateTo();
- this->rotating_mode = false;
- desktop->canvas->endRotateTo();
+ if (rotate_inc != 0.0) {
+ Geom::Point const scroll_dt = desktop->point();
+ desktop->rotate_relative_keep_point(scroll_dt, rotate_inc);
}
- bool ctrl = (event->scroll.state & GDK_CONTROL_MASK);
- bool wheelzooms = prefs->getBool("/options/wheelzooms/value");
-
- int const wheel_scroll = prefs->getIntLimited(
- "/options/wheelscroll/value", 40, 0, 1000);
- // Size of smooth-scrolls (only used in GTK+ 3)
- gdouble delta_x = 0;
- gdouble delta_y = 0;
+ } else if (event->scroll.state & GDK_SHIFT_MASK) {
+ /* shift + wheel, pan left--right */
- /* shift + wheel, pan left--right */
- if (event->scroll.state & GDK_SHIFT_MASK) {
- switch (event->scroll.direction) {
- case GDK_SCROLL_UP:
- desktop->scroll_relative(Geom::Point(wheel_scroll, 0));
- break;
+ switch (event->scroll.direction) {
+ case GDK_SCROLL_UP:
+ desktop->scroll_relative(Geom::Point(wheel_scroll, 0));
+ break;
- case GDK_SCROLL_DOWN:
- desktop->scroll_relative(Geom::Point(-wheel_scroll, 0));
- break;
+ case GDK_SCROLL_DOWN:
+ desktop->scroll_relative(Geom::Point(-wheel_scroll, 0));
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
- /* ctrl + wheel, zoom in--out */
- } else if ((ctrl && !wheelzooms) || (!ctrl && wheelzooms)) {
- double rel_zoom;
- double const zoom_inc = prefs->getDoubleLimited(
- "/options/zoomincrement/value", M_SQRT2, 1.01, 10);
+ } else if ((ctrl && !wheelzooms) || (!ctrl && wheelzooms)) {
+ /* ctrl + wheel, zoom in--out */
+ double rel_zoom;
+ double const zoom_inc = prefs->getDoubleLimited(
+ "/options/zoomincrement/value", M_SQRT2, 1.01, 10);
- switch (event->scroll.direction) {
- case GDK_SCROLL_UP:
- rel_zoom = zoom_inc;
- break;
+ switch (event->scroll.direction) {
+ case GDK_SCROLL_UP:
+ rel_zoom = zoom_inc;
+ break;
- case GDK_SCROLL_DOWN:
- rel_zoom = 1 / zoom_inc;
- break;
+ case GDK_SCROLL_DOWN:
+ rel_zoom = 1 / zoom_inc;
+ break;
- default:
- rel_zoom = 0.0;
- break;
- }
+ default:
+ rel_zoom = 0.0;
+ break;
+ }
- if (rel_zoom != 0.0) {
- Geom::Point const scroll_dt = desktop->point();
- desktop->zoom_relative_keep_point(scroll_dt, rel_zoom);
- }
+ if (rel_zoom != 0.0) {
+ Geom::Point const scroll_dt = desktop->point();
+ desktop->zoom_relative_keep_point(scroll_dt, rel_zoom);
+ }
- /* no modifier, pan up--down (left--right on multiwheel mice?) */
- } else {
- switch (event->scroll.direction) {
- case GDK_SCROLL_UP:
- desktop->scroll_relative(Geom::Point(0, wheel_scroll));
- break;
+ /* no modifier, pan up--down (left--right on multiwheel mice?) */
+ } else {
+ switch (event->scroll.direction) {
+ case GDK_SCROLL_UP:
+ desktop->scroll_relative(Geom::Point(0, wheel_scroll));
+ break;
- case GDK_SCROLL_DOWN:
- desktop->scroll_relative(Geom::Point(0, -wheel_scroll));
- break;
+ case GDK_SCROLL_DOWN:
+ desktop->scroll_relative(Geom::Point(0, -wheel_scroll));
+ break;
- case GDK_SCROLL_LEFT:
- desktop->scroll_relative(Geom::Point(wheel_scroll, 0));
- break;
+ case GDK_SCROLL_LEFT:
+ desktop->scroll_relative(Geom::Point(wheel_scroll, 0));
+ break;
- case GDK_SCROLL_RIGHT:
- desktop->scroll_relative(Geom::Point(-wheel_scroll, 0));
- break;
+ case GDK_SCROLL_RIGHT:
+ desktop->scroll_relative(Geom::Point(-wheel_scroll, 0));
+ break;
- case GDK_SCROLL_SMOOTH:
- gdk_event_get_scroll_deltas(event, &delta_x, &delta_y);
- desktop->scroll_relative(Geom::Point(delta_x, delta_y));
- break;
- }
+ case GDK_SCROLL_SMOOTH:
+ gdk_event_get_scroll_deltas(event, &delta_x, &delta_y);
+ desktop->scroll_relative(Geom::Point(delta_x, delta_y));
+ break;
}
- break;
}
- default:
- break;
+ break;
}
+ default:
+ break;
+ }
+
return ret;
}
@@ -1255,47 +1209,6 @@ sp_event_context_get_shape_editor(ToolBase *ec) {
return ec->shape_editor;
}
-void event_context_print_event_info(GdkEvent *event, bool print_return) {
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- g_print("GDK_BUTTON_PRESS");
- break;
- case GDK_2BUTTON_PRESS:
- g_print("GDK_2BUTTON_PRESS");
- break;
- case GDK_3BUTTON_PRESS:
- g_print("GDK_3BUTTON_PRESS");
- break;
-
- case GDK_MOTION_NOTIFY:
- g_print("GDK_MOTION_NOTIFY");
- break;
- case GDK_ENTER_NOTIFY:
- g_print("GDK_ENTER_NOTIFY");
- break;
-
- case GDK_LEAVE_NOTIFY:
- g_print("GDK_LEAVE_NOTIFY");
- break;
- case GDK_BUTTON_RELEASE:
- g_print("GDK_BUTTON_RELEASE");
- break;
-
- case GDK_KEY_PRESS:
- g_print("GDK_KEY_PRESS: %d", get_group0_keyval(&event->key));
- break;
- case GDK_KEY_RELEASE:
- g_print("GDK_KEY_RELEASE: %d", get_group0_keyval(&event->key));
- break;
- default:
- //g_print ("even type not recognized");
- break;
- }
-
- if (print_return) {
- g_print("\n");
- }
-}
/**
* Analyses the current event, calculates the mouse speed, turns snapping off (temporarily) if the
diff --git a/src/ui/tools/zoom-tool.cpp b/src/ui/tools/zoom-tool.cpp
index ca42d2d6f..d40d2e969 100644
--- a/src/ui/tools/zoom-tool.cpp
+++ b/src/ui/tools/zoom-tool.cpp
@@ -103,12 +103,14 @@ bool ZoomTool::root_handler(GdkEvent* event) {
desktop->zoom_relative_keep_point(button_dt, zoom_rel);
ret = true;
}
-
- sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
- NULL, event->button.time);
- this->grabbed = SP_CANVAS_ITEM(desktop->acetate);
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK,
+ NULL, event->button.time);
+
+ this->grabbed = SP_CANVAS_ITEM(desktop->acetate);
break;
}
@@ -156,10 +158,10 @@ bool ZoomTool::root_handler(GdkEvent* event) {
Inkscape::Rubberband::get(desktop)->stop();
- if (this->grabbed) {
- sp_canvas_item_ungrab(this->grabbed, event->button.time);
- this->grabbed = NULL;
- }
+ if (this->grabbed) {
+ sp_canvas_item_ungrab(this->grabbed, event->button.time);
+ this->grabbed = NULL;
+ }
xp = yp = 0;
escaped = false;
diff --git a/src/ui/view/edit-widget-interface.h b/src/ui/view/edit-widget-interface.h
index fcba0c6da..c93b1f0ee 100644
--- a/src/ui/view/edit-widget-interface.h
+++ b/src/ui/view/edit-widget-interface.h
@@ -128,6 +128,9 @@ struct EditWidgetInterface
/// The zoom display will get the keyboard focus.
virtual void letZoomGrabFocus() = 0;
+ /// Temporarily block signals and update rotation display
+ virtual void updateRotation() = 0;
+
/// In auxiliary toolbox, set focus to widget having specific id
virtual void setToolboxFocusTo (const gchar *) = 0;
diff --git a/src/ui/widget/color-scales.cpp b/src/ui/widget/color-scales.cpp
index 89913b01b..4023d227c 100644
--- a/src/ui/widget/color-scales.cpp
+++ b/src/ui/widget/color-scales.cpp
@@ -48,6 +48,7 @@ ColorScales::ColorScales(SelectedColor &color, SPColorScalesMode mode)
, _rangeLimit(255.0)
, _updating(FALSE)
, _dragging(FALSE)
+ , _mode(SP_COLOR_SCALES_MODE_NONE)
{
for (gint i = 0; i < 5; i++) {
_l[i] = 0;
diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp
index e0de22335..0e290730d 100644
--- a/src/ui/widget/rotateable.cpp
+++ b/src/ui/widget/rotateable.cpp
@@ -34,6 +34,7 @@ Rotateable::Rotateable():
signal_button_press_event().connect(sigc::mem_fun(*this, &Rotateable::on_click));
signal_motion_notify_event().connect(sigc::mem_fun(*this, &Rotateable::on_motion));
signal_button_release_event().connect(sigc::mem_fun(*this, &Rotateable::on_release));
+ gtk_widget_add_events(GTK_WIDGET(gobj()), GDK_SCROLL_MASK);
signal_scroll_event().connect(sigc::mem_fun(*this, &Rotateable::on_scroll));
}
diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp
index 0370d55db..65d68195c 100644
--- a/src/ui/widget/selected-style.cpp
+++ b/src/ui/widget/selected-style.cpp
@@ -1380,13 +1380,8 @@ RotateableStrokeWidth::value_adjust(double current, double by, guint /*modifier*
{
double newval;
// by is -1..1
- if (by < 0) {
- // map negative 0..-1 to current..0
- newval = current * (1 + by);
- } else {
- // map positive 0..1 to current..4*current
- newval = current * (1 + by) * (1 + by);
- }
+ double max_f = 50; // maximum width is (current * max_f), minimum - zero
+ newval = current * (std::exp(std::log(max_f-1) * (by+1)) - 1) / (max_f-2);
SPCSSAttr *css = sp_repr_css_attr_new ();
if (final && newval < 1e-6) {
@@ -1394,6 +1389,7 @@ RotateableStrokeWidth::value_adjust(double current, double by, guint /*modifier*
// if it's not final, leave it a chance to increase again (which is not possible with "none")
sp_repr_css_set_property (css, "stroke", "none");
} else {
+ newval = Inkscape::Util::Quantity::convert(newval, parent->_sw_unit, "px");
Inkscape::CSSOStringStream os;
os << newval;
sp_repr_css_set_property (css, "stroke-width", os.str().c_str());
diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h
index efac29f73..065d745f0 100644
--- a/src/ui/widget/selected-style.h
+++ b/src/ui/widget/selected-style.h
@@ -131,6 +131,7 @@ public:
guint _mode[2];
double current_stroke_width;
+ Inkscape::Util::Unit const *_sw_unit; // points to object in UnitTable, do not delete
protected:
SPDesktop *_desktop;
@@ -271,8 +272,6 @@ protected:
void on_popup_preset(int i);
Gtk::MenuItem _popup_sw_remove;
- Inkscape::Util::Unit const *_sw_unit; /// points to object in UnitTable, do not delete
-
void *_drop[2];
bool _dropEnabled[2];
};
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 8b3d7a5a2..b7b6da340 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -41,6 +41,7 @@
#include "desktop.h"
#include "display/curve.h"
+#include "display/sp-canvas.h"
#include "document.h"
#include "ui/tools/freehand-base.h"
#include "extension/effect.h"
@@ -1881,8 +1882,11 @@ void ZoomVerb::perform(SPAction *action, void *data)
Inkscape::XML::Node *repr = dt->namedview->getRepr();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- gdouble zoom_inc =
- prefs->getDoubleLimited( "/options/zoomincrement/value", M_SQRT2, 1.01, 10 );
+ gdouble zoom_inc =
+ prefs->getDoubleLimited( "/options/zoomincrement/value", M_SQRT2, 1.01, 10 );
+ gdouble rotate_inc =
+ prefs->getDoubleLimited( "/options/rotateincrement/value", 15, 1, 90, "°" );
+ rotate_inc *= M_PI/180.0;
double zcorr = 1.0;
Glib::ustring abbr = prefs->getString("/options/zoomcorrection/unit");
@@ -1957,6 +1961,75 @@ void ZoomVerb::perform(SPAction *action, void *data)
case SP_VERB_ZOOM_PREV:
dt->prev_transform();
break;
+ case SP_VERB_ROTATE_CW:
+ {
+ gint mul = 1 + Inkscape::UI::Tools::gobble_key_events( GDK_KEY_parenleft, 0);
+ // While drawing with the pen/pencil tool, rotate towards the end of the unfinished path
+ if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) {
+ SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve;
+ if (!rc->is_empty()) {
+ Geom::Point const rotate_to (*rc->last_point());
+ dt->rotate_relative_keep_point(rotate_to, -mul*rotate_inc);
+ break;
+ }
+ }
+
+ dt->rotate_relative_center_point( midpoint, -mul*rotate_inc);
+ break;
+ }
+ case SP_VERB_ROTATE_CCW:
+ {
+ gint mul = 1 + Inkscape::UI::Tools::gobble_key_events( GDK_KEY_parenright, 0);
+ // While drawing with the pen/pencil tool, rotate towards the end of the unfinished path
+ if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) {
+ SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve;
+ if (!rc->is_empty()) {
+ Geom::Point const rotate_to (*rc->last_point());
+ dt->rotate_relative_keep_point(rotate_to, mul*rotate_inc);
+ break;
+ }
+ }
+
+ dt->rotate_relative_center_point( midpoint, mul*rotate_inc);
+ break;
+ }
+ case SP_VERB_ROTATE_ZERO:
+ dt->rotate_absolute_center_point( midpoint, 0.0 );
+ break;
+ case SP_VERB_FLIP_HORIZONTAL:
+ {
+ // While drawing with the pen/pencil tool, flip towards the end of the unfinished path
+ if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) {
+ SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve;
+ if (!rc->is_empty()) {
+ Geom::Point const flip_to (*rc->last_point());
+ dt->flip_relative_keep_point(flip_to, SPDesktop::FLIP_HORIZONTAL);
+ break;
+ }
+ }
+
+ dt->flip_relative_center_point( midpoint, SPDesktop::FLIP_HORIZONTAL);
+ break;
+ }
+ case SP_VERB_FLIP_VERTICAL:
+ {
+ gint mul = 1 + Inkscape::UI::Tools::gobble_key_events( GDK_KEY_parenright, 0);
+ // While drawing with the pen/pencil tool, flip towards the end of the unfinished path
+ if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) {
+ SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve;
+ if (!rc->is_empty()) {
+ Geom::Point const flip_to (*rc->last_point());
+ dt->flip_relative_keep_point(flip_to, SPDesktop::FLIP_VERTICAL);
+ break;
+ }
+ }
+
+ dt->flip_relative_center_point( midpoint, SPDesktop::FLIP_VERTICAL);
+ break;
+ }
+ case SP_VERB_FLIP_NONE:
+ dt->flip_absolute_center_point( midpoint, SPDesktop::FLIP_NONE);
+ break;
case SP_VERB_TOGGLE_RULERS:
dt->toggleRulers();
break;
@@ -2895,10 +2968,41 @@ Verb *Verb::_base_verbs[] = {
N_("Open Preferences for the Eraser tool"), NULL),
new ContextVerb(SP_VERB_CONTEXT_LPETOOL_PREFS, "LPEToolPrefs", N_("LPE Tool Preferences"),
N_("Open Preferences for the LPETool tool"), NULL),
- // Zoom/View
+
+ // Zoom
new ZoomVerb(SP_VERB_ZOOM_IN, "ZoomIn", N_("Zoom In"), N_("Zoom in"), INKSCAPE_ICON("zoom-in")),
new ZoomVerb(SP_VERB_ZOOM_OUT, "ZoomOut", N_("Zoom Out"), N_("Zoom out"), INKSCAPE_ICON("zoom-out")),
- // WHY ARE THE FOLLOWING ZoomVerbs???
+ new ZoomVerb(SP_VERB_ZOOM_NEXT, "ZoomNext", N_("Nex_t Zoom"), N_("Next zoom (from the history of zooms)"),
+ INKSCAPE_ICON("zoom-next")),
+ new ZoomVerb(SP_VERB_ZOOM_PREV, "ZoomPrev", N_("Pre_vious Zoom"), N_("Previous zoom (from the history of zooms)"),
+ INKSCAPE_ICON("zoom-previous")),
+ new ZoomVerb(SP_VERB_ZOOM_1_1, "Zoom1:0", N_("Zoom 1:_1"), N_("Zoom to 1:1"),
+ INKSCAPE_ICON("zoom-original")),
+ new ZoomVerb(SP_VERB_ZOOM_1_2, "Zoom1:2", N_("Zoom 1:_2"), N_("Zoom to 1:2"),
+ INKSCAPE_ICON("zoom-half-size")),
+ new ZoomVerb(SP_VERB_ZOOM_2_1, "Zoom2:1", N_("_Zoom 2:1"), N_("Zoom to 2:1"),
+ INKSCAPE_ICON("zoom-double-size")),
+ new ZoomVerb(SP_VERB_ZOOM_PAGE, "ZoomPage", N_("_Page"),
+ N_("Zoom to fit page in window"), INKSCAPE_ICON("zoom-fit-page")),
+ new ZoomVerb(SP_VERB_ZOOM_PAGE_WIDTH, "ZoomPageWidth", N_("Page _Width"),
+ N_("Zoom to fit page width in window"), INKSCAPE_ICON("zoom-fit-width")),
+ new ZoomVerb(SP_VERB_ZOOM_DRAWING, "ZoomDrawing", N_("_Drawing"),
+ N_("Zoom to fit drawing in window"), INKSCAPE_ICON("zoom-fit-drawing")),
+ new ZoomVerb(SP_VERB_ZOOM_SELECTION, "ZoomSelection", N_("_Selection"),
+ N_("Zoom to fit selection in window"), INKSCAPE_ICON("zoom-fit-selection")),
+
+ new ZoomVerb(SP_VERB_ROTATE_CW, "RotateClockwise", N_("Rotate Clockwise"), N_("Rotate canvas clockwise"), NULL),
+ new ZoomVerb(SP_VERB_ROTATE_CCW, "RotateCounterClockwise", N_("Rotate Counter-Clockwise"), N_("Rotate canvas counter-clockwise"), NULL),
+ new ZoomVerb(SP_VERB_ROTATE_ZERO, "RotateZero", N_("Rotate Zero"), N_("Reset canvas rotation to zero"), NULL),
+
+ new ZoomVerb(SP_VERB_FLIP_HORIZONTAL, "FlipHorizontal", N_("Flip Horizontal"), N_("Flip canvas horizontally"), INKSCAPE_ICON("object-flip-horizontal")),
+ new ZoomVerb(SP_VERB_FLIP_VERTICAL, "FlipVertical", N_("Flip Vertical"), N_("Flip canvas vertically"), INKSCAPE_ICON("object-flip-vertical")),
+ new ZoomVerb(SP_VERB_FLIP_NONE, "FlipNone", N_("Flip None"), N_("Undo any flip"), NULL),
+
+
+// WHY ARE THE FOLLOWING ZoomVerbs???
+
+ // View
new ZoomVerb(SP_VERB_TOGGLE_RULERS, "ToggleRulers", N_("_Rulers"), N_("Show or hide the canvas rulers"), NULL),
new ZoomVerb(SP_VERB_TOGGLE_SCROLLBARS, "ToggleScrollbars", N_("Scroll_bars"), N_("Show or hide the canvas scrollbars"), NULL),
new ZoomVerb(SP_VERB_TOGGLE_GRID, "ToggleGrid", N_("Page _Grid"), N_("Show or hide the page grid"), INKSCAPE_ICON("show-grid")),
@@ -2910,16 +3014,7 @@ Verb *Verb::_base_verbs[] = {
new ZoomVerb(SP_VERB_TOGGLE_TOOLBOX, "ToggleToolbox", N_("_Toolbox"), N_("Show or hide the main toolbox (on the left)"), NULL),
new ZoomVerb(SP_VERB_TOGGLE_PALETTE, "TogglePalette", N_("_Palette"), N_("Show or hide the color palette"), NULL),
new ZoomVerb(SP_VERB_TOGGLE_STATUSBAR, "ToggleStatusbar", N_("_Statusbar"), N_("Show or hide the statusbar (at the bottom of the window)"), NULL),
- new ZoomVerb(SP_VERB_ZOOM_NEXT, "ZoomNext", N_("Nex_t Zoom"), N_("Next zoom (from the history of zooms)"),
- INKSCAPE_ICON("zoom-next")),
- new ZoomVerb(SP_VERB_ZOOM_PREV, "ZoomPrev", N_("Pre_vious Zoom"), N_("Previous zoom (from the history of zooms)"),
- INKSCAPE_ICON("zoom-previous")),
- new ZoomVerb(SP_VERB_ZOOM_1_1, "Zoom1:0", N_("Zoom 1:_1"), N_("Zoom to 1:1"),
- INKSCAPE_ICON("zoom-original")),
- new ZoomVerb(SP_VERB_ZOOM_1_2, "Zoom1:2", N_("Zoom 1:_2"), N_("Zoom to 1:2"),
- INKSCAPE_ICON("zoom-half-size")),
- new ZoomVerb(SP_VERB_ZOOM_2_1, "Zoom2:1", N_("_Zoom 2:1"), N_("Zoom to 2:1"),
- INKSCAPE_ICON("zoom-double-size")),
+
new ZoomVerb(SP_VERB_FULLSCREEN, "FullScreen", N_("_Fullscreen"), N_("Stretch this document window to full screen"),
INKSCAPE_ICON("view-fullscreen")),
new ZoomVerb(SP_VERB_FULLSCREENFOCUS, "FullScreenFocus", N_("Fullscreen & Focus Mode"), N_("Stretch this document window to full screen"),
@@ -2953,14 +3048,6 @@ Verb *Verb::_base_verbs[] = {
new ZoomVerb(SP_VERB_VIEW_ICON_PREVIEW, "ViewIconPreview", N_("Ico_n Preview..."),
N_("Open a window to preview objects at different icon resolutions"), INKSCAPE_ICON("dialog-icon-preview")),
- new ZoomVerb(SP_VERB_ZOOM_PAGE, "ZoomPage", N_("_Page"),
- N_("Zoom to fit page in window"), INKSCAPE_ICON("zoom-fit-page")),
- new ZoomVerb(SP_VERB_ZOOM_PAGE_WIDTH, "ZoomPageWidth", N_("Page _Width"),
- N_("Zoom to fit page width in window"), INKSCAPE_ICON("zoom-fit-width")),
- new ZoomVerb(SP_VERB_ZOOM_DRAWING, "ZoomDrawing", N_("_Drawing"),
- N_("Zoom to fit drawing in window"), INKSCAPE_ICON("zoom-fit-drawing")),
- new ZoomVerb(SP_VERB_ZOOM_SELECTION, "ZoomSelection", N_("_Selection"),
- N_("Zoom to fit selection in window"), INKSCAPE_ICON("zoom-fit-selection")),
// Dialogs
new DialogVerb(SP_VERB_DIALOG_PROTOTYPE, "DialogPrototype", N_("Prototype..."),
diff --git a/src/verbs.h b/src/verbs.h
index b6b7b54dc..6846f1f40 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -252,9 +252,31 @@ enum {
SP_VERB_CONTEXT_ERASER_PREFS,
SP_VERB_CONTEXT_LPETOOL_PREFS,
- /* Zooming and desktop settings */
+
+ /* Zooming */
SP_VERB_ZOOM_IN,
SP_VERB_ZOOM_OUT,
+ SP_VERB_ZOOM_NEXT,
+ SP_VERB_ZOOM_PREV,
+ SP_VERB_ZOOM_1_1,
+ SP_VERB_ZOOM_1_2,
+ SP_VERB_ZOOM_2_1,
+ SP_VERB_ZOOM_PAGE,
+ SP_VERB_ZOOM_PAGE_WIDTH,
+ SP_VERB_ZOOM_DRAWING,
+ SP_VERB_ZOOM_SELECTION,
+
+ /* Canvas Rotation */
+ SP_VERB_ROTATE_CW,
+ SP_VERB_ROTATE_CCW,
+ SP_VERB_ROTATE_ZERO,
+
+ /* Canvas Flip */
+ SP_VERB_FLIP_HORIZONTAL,
+ SP_VERB_FLIP_VERTICAL,
+ SP_VERB_FLIP_NONE,
+
+ /* Desktop settings */
SP_VERB_TOGGLE_RULERS,
SP_VERB_TOGGLE_SCROLLBARS,
SP_VERB_TOGGLE_GRID,
@@ -266,11 +288,6 @@ enum {
SP_VERB_TOGGLE_TOOLBOX,
SP_VERB_TOGGLE_PALETTE,
SP_VERB_TOGGLE_STATUSBAR,
- SP_VERB_ZOOM_NEXT,
- SP_VERB_ZOOM_PREV,
- SP_VERB_ZOOM_1_1,
- SP_VERB_ZOOM_1_2,
- SP_VERB_ZOOM_2_1,
SP_VERB_FULLSCREEN,
SP_VERB_FULLSCREENFOCUS,
SP_VERB_FOCUSTOGGLE,
@@ -282,14 +299,12 @@ enum {
SP_VERB_VIEW_MODE_TOGGLE,
SP_VERB_VIEW_COLOR_MODE_NORMAL,
SP_VERB_VIEW_COLOR_MODE_GRAYSCALE,
+
// SP_VERB_VIEW_COLOR_MODE_PRINT_COLORS_PREVIEW,
SP_VERB_VIEW_COLOR_MODE_TOGGLE,
SP_VERB_VIEW_CMS_TOGGLE,
SP_VERB_VIEW_ICON_PREVIEW,
- SP_VERB_ZOOM_PAGE,
- SP_VERB_ZOOM_PAGE_WIDTH,
- SP_VERB_ZOOM_DRAWING,
- SP_VERB_ZOOM_SELECTION,
+
/* Dialogs */
SP_VERB_DIALOG_PROTOTYPE,
SP_VERB_DIALOG_DISPLAY,
diff --git a/src/viewbox.cpp b/src/viewbox.cpp
index 1fa33117a..1b50fe71c 100644
--- a/src/viewbox.cpp
+++ b/src/viewbox.cpp
@@ -17,8 +17,6 @@
#include "viewbox.h"
#include "enums.h"
#include "sp-item.h"
-#include "inkscape.h"
-#include "desktop.h"
SPViewBox::SPViewBox()
: viewBox_set(false)
@@ -27,11 +25,6 @@ SPViewBox::SPViewBox()
, aspect_align(SP_ASPECT_XMID_YMID) // Default per spec
, aspect_clip(SP_ASPECT_MEET)
, c2p(Geom::identity())
- , vbt(Geom::identity())
- , rotation(Geom::identity())
- , angle(0)
- , previous_angle(0)
- , rotated(false)
{
}
@@ -166,16 +159,6 @@ void SPViewBox::set_preserveAspectRatio(const gchar* value) {
}
}
-double SPViewBox::get_rotation() {
- return this->angle;
-}
-
-void SPViewBox::set_rotation(double angle_val) {
- this->previous_angle = this->angle;
- this->angle = angle_val;
- this->rotated = true;
-}
-
// Apply scaling from viewbox
void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) {
@@ -239,41 +222,22 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) {
break;
}
}
+
/* Viewbox transform from scale and position */
- vbt = Geom::identity();
- vbt[0] = scale_x;
- vbt[1] = 0.0;
- vbt[2] = 0.0;
- vbt[3] = scale_y;
- vbt[4] = x - scale_x * this->viewBox.left();
- vbt[5] = y - scale_y * this->viewBox.top();
- /* Append viewbox and turn transformation */
- Geom::Point page_center = this->viewBox.midpoint();
- SPDesktop * desktop = SP_ACTIVE_DESKTOP;
- if (this->angle > 0.0 || this->angle < 0.0 ) { //!0
- if (desktop) {
- rotation = Geom::Translate(page_center).inverse() * Geom::Rotate(Geom::rad_from_deg(angle)) * Geom::Translate(page_center);
- this->c2p = rotation * vbt * this->c2p;
- } else {
- this->c2p = vbt * this->c2p;
- }
- } else {
- this->c2p = vbt * this->c2p;
- }
- if (desktop && this->rotated) {
- Geom::Rect view = desktop->get_display_area();
- Geom::Point view_center = desktop->doc2dt(view.midpoint());
- Geom::Affine center_rotation = Geom::identity();
- center_rotation *= Geom::Translate(page_center * vbt).inverse();
- center_rotation *= Geom::Rotate(Geom::rad_from_deg(this->angle - this->previous_angle));
- center_rotation *= Geom::Translate(page_center * vbt);
- view_center = desktop->dt2doc(view_center * center_rotation);
- desktop->zoom_relative_center_point(view_center, 1.0);
- this->rotated = false;
- }
+ Geom::Affine q;
+ q[0] = scale_x;
+ q[1] = 0.0;
+ q[2] = 0.0;
+ q[3] = scale_y;
+ q[4] = x - scale_x * this->viewBox.left();
+ q[5] = y - scale_y * this->viewBox.top();
+
+ // std::cout << " q\n" << q << std::endl;
+
+ /* Append viewbox transformation */
+ this->c2p = q * this->c2p;
}
-
SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx, double scale_none) {
/* Create copy of item context */
diff --git a/src/viewbox.h b/src/viewbox.h
index 2f107132c..c71abb610 100644
--- a/src/viewbox.h
+++ b/src/viewbox.h
@@ -36,14 +36,7 @@ public:
/* Child to parent additional transform */
Geom::Affine c2p;
- Geom::Affine vbt;
- Geom::Affine rotation;
- double angle;
- double previous_angle;
- bool rotated;
- double get_rotation();
- void set_rotation(double angle_val);
void set_viewBox(const gchar* value);
void set_preserveAspectRatio(const gchar* value);
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index 122b19e22..d8c27f5b7 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -91,20 +91,8 @@ static void sp_update_guides_lock( GtkWidget *button, gpointer data );
static void cms_adjust_toggled( GtkWidget *button, gpointer data );
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
static void cms_adjust_set_sensitive( SPDesktopWidget *dtw, bool enabled );
-static void sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw);
static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw);
-static gint sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer data);
-static bool sp_dtw_rotation_output (GtkSpinButton *spin, gpointer data);
-static void sp_dtw_rotation_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data);
-static void sp_dtw_rotate_minus_180 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_minus_135 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_minus_90 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_minus_45 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_0 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_45 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_90 (GtkMenuItem *item, SPDesktopWidget * data);
-static void sp_dtw_rotate_135 (GtkMenuItem *item, SPDesktopWidget * data);
static gdouble sp_dtw_zoom_value_to_display (gdouble value);
static gdouble sp_dtw_zoom_display_to_value (gdouble value);
static gint sp_dtw_zoom_input (GtkSpinButton *spin, gdouble *new_val, gpointer data);
@@ -112,14 +100,13 @@ static bool sp_dtw_zoom_output (GtkSpinButton *spin, gpointer data);
static void sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data);
static void sp_dtw_zoom_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data);
static void sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor);
-static void sp_dtw_zoom_50 (GtkMenuItem *item, gpointer data);
-static void sp_dtw_zoom_100 (GtkMenuItem *item, gpointer data);
-static void sp_dtw_zoom_200 (GtkMenuItem *item, gpointer data);
-static void sp_dtw_zoom_page (GtkMenuItem *item, gpointer data);
-static void sp_dtw_zoom_drawing (GtkMenuItem *item, gpointer data);
-static void sp_dtw_zoom_selection (GtkMenuItem *item, gpointer data);
static void sp_dtw_sticky_zoom_toggled (GtkMenuItem *item, gpointer data);
+static gint sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer data);
+static bool sp_dtw_rotation_output (GtkSpinButton *spin, gpointer data);
+static void sp_dtw_rotation_value_changed (GtkSpinButton *spin, gpointer data);
+static void sp_dtw_rotation_populate_popup (GtkEntry *entry, GtkMenu *menu, gpointer data);
+
SPViewWidgetClass *dtw_parent_class;
class CMSPrefWatcher {
@@ -576,44 +563,52 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw )
gtk_box_pack_start (GTK_BOX (dtw->statusbar), dtw->select_status, TRUE, TRUE, 0);
- // Zoom status spinbutton
+ // Zoom status spinbutton ---------------
dtw->zoom_status = gtk_spin_button_new_with_range (log(SP_DESKTOP_ZOOM_MIN)/log(2), log(SP_DESKTOP_ZOOM_MAX)/log(2), 0.1);
- gtk_widget_set_name(dtw->zoom_status, "ZoomStatus");
+ g_object_set_data (G_OBJECT (dtw->zoom_status), "dtw", dtw->canvas);
gtk_widget_set_tooltip_text (dtw->zoom_status, _("Zoom"));
gtk_widget_set_size_request (dtw->zoom_status, STATUS_ZOOM_WIDTH, -1);
gtk_entry_set_width_chars (GTK_ENTRY (dtw->zoom_status), 6);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->zoom_status), FALSE);
gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->zoom_status), GTK_UPDATE_ALWAYS);
+
+ // Callbacks
g_signal_connect (G_OBJECT (dtw->zoom_status), "input", G_CALLBACK (sp_dtw_zoom_input), dtw);
g_signal_connect (G_OBJECT (dtw->zoom_status), "output", G_CALLBACK (sp_dtw_zoom_output), dtw);
- g_object_set_data (G_OBJECT (dtw->zoom_status), "dtw", dtw->canvas);
g_signal_connect (G_OBJECT (dtw->zoom_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->zoom_status);
g_signal_connect (G_OBJECT (dtw->zoom_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->zoom_status);
dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "value_changed", G_CALLBACK (sp_dtw_zoom_value_changed), dtw);
- dtw->zoom_update = g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw);
+ g_signal_connect (G_OBJECT (dtw->zoom_status), "populate_popup", G_CALLBACK (sp_dtw_zoom_populate_popup), dtw);
+
+ // Style
auto css_provider_spinbutton = Gtk::CssProvider::create();
- css_provider_spinbutton->load_from_data("* { padding-left: 2px; padding-right: 2px; padding-top: 0px; padding-bottom: 0px;}");
+ css_provider_spinbutton->load_from_data("* { padding-left: 2px; padding-right: 2px; padding-top: 0px; padding-bottom: 0px;}"); // Shouldn't this be in a style sheet? Used also by rotate.
+
auto zoomstat = Glib::wrap(dtw->zoom_status);
zoomstat->set_name("ZoomStatus");
auto context_zoom = zoomstat->get_style_context();
context_zoom->add_provider(css_provider_spinbutton, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- // Rotate status spinbutton
+ // Rotate status spinbutton ---------------
dtw->rotation_status = gtk_spin_button_new_with_range (-360.0,360.0, 1.0);
- gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation. Can be interactive with CTRL+MMB"));
+ g_object_set_data (G_OBJECT (dtw->rotation_status), "dtw", dtw->canvas);
+ gtk_widget_set_tooltip_text (dtw->rotation_status, _("Rotation. (Also Ctrl+Shift+Scroll)"));
gtk_widget_set_size_request (dtw->rotation_status, STATUS_ROTATION_WIDTH, -1);
gtk_entry_set_width_chars (GTK_ENTRY (dtw->rotation_status), 7);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE);
- gtk_spin_button_set_digits (GTK_SPIN_BUTTON (dtw->rotation_status), 2);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (dtw->rotation_status), FALSE);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (dtw->rotation_status), 2);
+ gtk_spin_button_set_increments (GTK_SPIN_BUTTON (dtw->rotation_status), 1.0, 15.0);
gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (dtw->rotation_status), GTK_UPDATE_ALWAYS);
+
+ // Callbacks
g_signal_connect (G_OBJECT (dtw->rotation_status), "input", G_CALLBACK (sp_dtw_rotation_input), dtw);
g_signal_connect (G_OBJECT (dtw->rotation_status), "output", G_CALLBACK (sp_dtw_rotation_output), dtw);
- g_object_set_data (G_OBJECT (dtw->rotation_status), "dtw", dtw->canvas);
g_signal_connect (G_OBJECT (dtw->rotation_status), "focus-in-event", G_CALLBACK (spinbutton_focus_in), dtw->rotation_status);
g_signal_connect (G_OBJECT (dtw->rotation_status), "key-press-event", G_CALLBACK (spinbutton_keypress), dtw->rotation_status);
- dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_desktop_widget_rotate_document), dtw);
- dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotation_populate_popup), dtw);
+ dtw->rotation_update = g_signal_connect (G_OBJECT (dtw->rotation_status), "value_changed", G_CALLBACK (sp_dtw_rotation_value_changed), dtw);
+ g_signal_connect (G_OBJECT (dtw->rotation_status), "populate_popup", G_CALLBACK (sp_dtw_rotation_populate_popup), dtw);
+ // Style
auto rotstat = Glib::wrap(dtw->rotation_status);
rotstat->set_name("RotationStatus");
auto context_rotation = rotstat->get_style_context();
@@ -717,16 +712,22 @@ static void sp_desktop_widget_dispose(GObject *object)
if ( watcher ) {
watcher->remove(dtw);
}
+
+ // Zoom
g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK(sp_dtw_zoom_input), dtw);
g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK(sp_dtw_zoom_output), dtw);
g_signal_handlers_disconnect_matched (G_OBJECT (dtw->zoom_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->zoom_status);
g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_value_changed), dtw);
g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->zoom_status), (gpointer) G_CALLBACK (sp_dtw_zoom_populate_popup), dtw);
+
+ // Rotation
g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK(sp_dtw_rotation_input), dtw);
g_signal_handlers_disconnect_by_func(G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK(sp_dtw_rotation_output), dtw);
g_signal_handlers_disconnect_matched (G_OBJECT (dtw->rotation_status), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dtw->rotation_status);
- g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_desktop_widget_rotate_document), dtw);
+ g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_rotation_value_changed), dtw);
g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->rotation_status), (gpointer) G_CALLBACK (sp_dtw_rotation_populate_popup), dtw);
+
+ // Canvas
g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas), (gpointer) G_CALLBACK (sp_desktop_widget_event), dtw);
g_signal_handlers_disconnect_by_func (G_OBJECT (dtw->canvas_tbl), (gpointer) G_CALLBACK (canvas_tbl_size_allocate), dtw);
@@ -1667,8 +1668,7 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview)
SPNamedView *nv = dtw->desktop->namedview;
gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, FALSE, FALSE, 0);
dtw->layoutWidgets();
- gtk_spin_button_set_value(GTK_SPIN_BUTTON (dtw->rotation_status), namedview->document_rotation);
- sp_namedview_set_document_rotation(namedview);
+
std::vector<GtkWidget *> toolboxes;
toolboxes.push_back(dtw->tool_toolbox);
toolboxes.push_back(dtw->aux_toolbox);
@@ -1708,8 +1708,6 @@ sp_desktop_widget_update_rulers (SPDesktopWidget *dtw)
void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags)
{
SPNamedView *nv=SP_NAMEDVIEW(obj);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(this->rotation_status), desktop->namedview->document_rotation);
- sp_namedview_set_document_rotation(nv);
if (flags & SP_OBJECT_MODIFIED_FLAG) {
this->dt2r = 1. / nv->display_units->factor;
@@ -1768,18 +1766,6 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags)
}
static void
-sp_desktop_widget_rotate_document(GtkSpinButton *spin, SPDesktopWidget *dtw)
-{
- SPNamedView *nv = dtw->desktop->namedview;
- double value = gtk_spin_button_get_value (spin);
- if (!dtw->desktop->getDocument()->getRoot()->rotated && value != nv->document_rotation) {
- sp_repr_set_svg_double(nv->getRepr(), "inkscape:document-rotation", value);
- }
- spinbutton_defocus (GTK_WIDGET(spin));
-}
-
-
-static void
sp_desktop_widget_adjustment_value_changed (GtkAdjustment */*adj*/, SPDesktopWidget *dtw)
{
if (dtw->update)
@@ -1811,6 +1797,7 @@ bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*)
return false;
}
+// ------------------------ Zoom ------------------------
static gdouble
sp_dtw_zoom_value_to_display (gdouble value)
{
@@ -1858,38 +1845,6 @@ sp_dtw_zoom_output (GtkSpinButton *spin, gpointer /*data*/)
return TRUE;
}
-static gint
-sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer /*data*/)
-{
- gchar *b = g_strdup (gtk_entry_get_text (GTK_ENTRY (spin)));
-
- gchar *comma = g_strstr_len (b, -1, ",");
- if (comma) {
- *comma = '.';
- }
-
- char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL));
- setlocale (LC_NUMERIC, "C");
- gdouble new_value = atof (b);
- setlocale (LC_NUMERIC, oldlocale);
- g_free (oldlocale);
- g_free (b);
-
- *new_val = new_value;
- return TRUE;
-}
-
-static bool
-sp_dtw_rotation_output (GtkSpinButton *spin, gpointer /*data*/)
-{
- gchar b[64];
- double val = gtk_spin_button_get_value (spin);
- g_snprintf (b, 64, "%7.2f°", val);
-
- gtk_entry_set_text (GTK_ENTRY (spin), b);
- return TRUE;
-}
-
static void
sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data)
{
@@ -1908,7 +1863,14 @@ sp_dtw_zoom_value_changed (GtkSpinButton *spin, gpointer data)
spinbutton_defocus (GTK_WIDGET(spin));
}
+static void
+sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor)
+{
+ Geom::Rect const d = dt->get_display_area();
+ dt->zoom_absolute_center_point (d.midpoint(), factor);
+}
+// Zoom Popup Menu
static void
sp_dtw_zoom_10 (GtkMenuItem */*item*/, gpointer data)
{
@@ -1972,124 +1934,142 @@ sp_dtw_zoom_selection (GtkMenuItem */*item*/, gpointer data)
static void
sp_dtw_zoom_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data)
{
- GList *children, *iter;
- GtkWidget *item;
SPDesktop *dt = SP_DESKTOP_WIDGET (data)->desktop;
- children = gtk_container_get_children (GTK_CONTAINER (menu));
- for ( iter = children ; iter ; iter = g_list_next (iter)) {
+ GList* children = gtk_container_get_children (GTK_CONTAINER (menu));
+ for ( auto iter = children ; iter ; iter = g_list_next (iter)) {
gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data));
}
g_list_free (children);
+ GtkWidget *item;
+
item = gtk_menu_item_new_with_label ("1000%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_1000), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label ("500%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_500), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label ("200%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_200), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label ("100%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_100), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label ("50%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_50), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label ("25%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_25), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label ("10%");
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_10), dt);
- gtk_widget_show (item);
-
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = gtk_separator_menu_item_new ();
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = gtk_menu_item_new_with_label (_("Page"));
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_page), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label (_("Drawing"));
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_drawing), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
item = gtk_menu_item_new_with_label (_("Selection"));
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_zoom_selection), dt);
- gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ gtk_widget_show_all (GTK_WIDGET (menu));
}
static void
-sp_dtw_rotation_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data)
+sp_dtw_sticky_zoom_toggled (GtkMenuItem *, gpointer data)
{
- GList *children, *iter;
- GtkWidget *item;
- SPDesktopWidget *dtw = static_cast<SPDesktopWidget*>(data);
- children = gtk_container_get_children (GTK_CONTAINER (menu));
- for ( iter = children ; iter ; iter = g_list_next (iter)) {
- gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data));
+ SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(data);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/options/stickyzoom/value", SP_BUTTON_IS_DOWN(dtw->sticky_zoom));
+}
+
+
+void
+sp_desktop_widget_update_zoom (SPDesktopWidget *dtw)
+{
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(dtw->zoom_status));
+
+ g_signal_handler_block (G_OBJECT (dtw->zoom_status), dtw->zoom_update);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dtw->zoom_status), log(dtw->desktop->current_zoom()) / log(2));
+ gtk_widget_queue_draw(GTK_WIDGET(dtw->zoom_status));
+ if (window)
+ gdk_window_process_updates(window, TRUE);
+ g_signal_handler_unblock (G_OBJECT (dtw->zoom_status), dtw->zoom_update);
+}
+
+
+// ---------------------- Rotation ------------------------
+static gint
+sp_dtw_rotation_input (GtkSpinButton *spin, gdouble *new_val, gpointer /*data*/)
+{
+ gchar *b = g_strdup (gtk_entry_get_text (GTK_ENTRY (spin)));
+
+ gchar *comma = g_strstr_len (b, -1, ",");
+ if (comma) {
+ *comma = '.';
}
- g_list_free (children);
- item = gtk_menu_item_new_with_label ("-180°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_180), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- item = gtk_menu_item_new_with_label ("-135°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_135), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- item = gtk_menu_item_new_with_label ("-90°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_90), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- item = gtk_menu_item_new_with_label ("-45°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_45), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- item = gtk_menu_item_new_with_label ("0°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_0), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
- item = gtk_menu_item_new_with_label ("45°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_45), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
-
- item = gtk_menu_item_new_with_label ("90°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_90), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-
+ char *oldlocale = g_strdup (setlocale(LC_NUMERIC, NULL));
+ setlocale (LC_NUMERIC, "C");
+ gdouble new_value = atof (b);
+ setlocale (LC_NUMERIC, oldlocale);
+ g_free (oldlocale);
+ g_free (b);
- item = gtk_menu_item_new_with_label ("135°");
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_135), dtw);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ *new_val = new_value;
+ return TRUE;
+}
+
+static bool
+sp_dtw_rotation_output (GtkSpinButton *spin, gpointer /*data*/)
+{
+ gchar b[64];
+ double val = gtk_spin_button_get_value (spin);
+
+ if (val < -180) val += 360;
+ if (val > 180) val -= 360;
+
+ g_snprintf (b, 64, "%7.2f°", val);
+
+ gtk_entry_set_text (GTK_ENTRY (spin), b);
+ return TRUE;
}
static void
-sp_dtw_rotate_minus_180 (GtkMenuItem */*item*/, SPDesktopWidget * data)
+sp_dtw_rotation_value_changed (GtkSpinButton *spin, gpointer data)
{
- gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status),-180);
+ double const rotate_factor = M_PI / 180.0 * gtk_spin_button_get_value (spin);
+ // std::cout << "sp_dtw_rotation_value_changed: "
+ // << gtk_spin_button_get_value (spin)
+ // << " (" << rotate_factor << ")" <<std::endl;
+
+ SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (data);
+ SPDesktop *desktop = dtw->desktop;
+
+ // Rotate around center of window
+ Geom::Rect const d_canvas = desktop->getCanvas()->getViewbox();
+ g_signal_handler_block(spin, dtw->rotation_update);
+ Geom::Point midpoint = desktop->w2d(d_canvas.midpoint());
+ desktop->rotate_absolute_center_point (midpoint, rotate_factor);
+ g_signal_handler_unblock(spin, dtw->rotation_update);
+
+ spinbutton_defocus (GTK_WIDGET(spin));
}
static void
@@ -2135,35 +2115,75 @@ sp_dtw_rotate_135 (GtkMenuItem */*item*/, SPDesktopWidget * data)
}
static void
-sp_dtw_zoom_menu_handler (SPDesktop *dt, gdouble factor)
+sp_dtw_rotate_180 (GtkMenuItem */*item*/, SPDesktopWidget * data)
{
- Geom::Rect const d = dt->get_display_area();
- dt->zoom_absolute_center_point (d.midpoint(), factor);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON((data)->rotation_status),180);
}
-
static void
-sp_dtw_sticky_zoom_toggled (GtkMenuItem *, gpointer data)
+sp_dtw_rotation_populate_popup (GtkEntry */*entry*/, GtkMenu *menu, gpointer data)
{
- SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(data);
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setBool("/options/stickyzoom/value", SP_BUTTON_IS_DOWN(dtw->sticky_zoom));
+ SPDesktopWidget *dtw = static_cast<SPDesktopWidget*>(data);
+
+ GList* children = gtk_container_get_children (GTK_CONTAINER (menu));
+ for ( auto iter = children ; iter ; iter = g_list_next (iter)) {
+ gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (iter->data));
+ }
+ g_list_free (children);
+
+ GtkWidget *item;
+
+ item = gtk_menu_item_new_with_label ("-135°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_135), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("-90°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_90), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("-45°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_minus_45), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("0°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_0), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("45°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_45), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("90°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_90), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("135°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_135), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_menu_item_new_with_label ("180°");
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (sp_dtw_rotate_180), dtw);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ gtk_widget_show_all (GTK_WIDGET (menu));
}
void
-sp_desktop_widget_update_zoom (SPDesktopWidget *dtw)
+sp_desktop_widget_update_rotation (SPDesktopWidget *dtw)
{
- GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(dtw->zoom_status));
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(dtw->rotation_status));
- g_signal_handlers_block_by_func (G_OBJECT (dtw->zoom_status), (gpointer)G_CALLBACK (sp_dtw_zoom_value_changed), dtw);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (dtw->zoom_status), log(dtw->desktop->current_zoom()) / log(2));
- gtk_widget_queue_draw(GTK_WIDGET(dtw->zoom_status));
+ g_signal_handler_block(G_OBJECT(dtw->rotation_status), dtw->rotation_update);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dtw->rotation_status), dtw->desktop->current_rotation() / M_PI * 180.0);
+ gtk_widget_queue_draw(GTK_WIDGET(dtw->rotation_status));
if (window)
gdk_window_process_updates(window, TRUE);
- g_signal_handlers_unblock_by_func (G_OBJECT (dtw->zoom_status), (gpointer)G_CALLBACK (sp_dtw_zoom_value_changed), dtw);
+ g_signal_handler_unblock(G_OBJECT(dtw->rotation_status), dtw->rotation_update);
}
+
+// --------------- Rulers/Scrollbars/Etc. -----------------
void
sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw)
{
diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h
index 61c3b8b37..0d5f40987 100644
--- a/src/widgets/desktop-widget.h
+++ b/src/widgets/desktop-widget.h
@@ -40,6 +40,7 @@ void sp_desktop_widget_iconify(SPDesktopWidget *dtw);
void sp_desktop_widget_maximize(SPDesktopWidget *dtw);
void sp_desktop_widget_fullscreen(SPDesktopWidget *dtw);
void sp_desktop_widget_update_zoom(SPDesktopWidget *dtw);
+void sp_desktop_widget_update_rotation(SPDesktopWidget *dtw);
void sp_desktop_widget_update_rulers (SPDesktopWidget *dtw);
void sp_desktop_widget_update_hruler (SPDesktopWidget *dtw);
void sp_desktop_widget_update_vruler (SPDesktopWidget *dtw);
@@ -78,7 +79,7 @@ struct SPDesktopWidget {
GtkWidget *hbox;
- GtkWidget *menubar, *statusbar, *rotatebar;
+ GtkWidget *menubar, *statusbar;
Inkscape::UI::Dialogs::SwatchesPanel *panels;
@@ -193,6 +194,8 @@ struct SPDesktopWidget {
{ sp_desktop_widget_update_zoom (_dtw); }
virtual void letZoomGrabFocus()
{ _dtw->letZoomGrabFocus(); }
+ virtual void updateRotation()
+ { sp_desktop_widget_update_rotation (_dtw); }
virtual void setToolboxFocusTo (const gchar * id)
{ _dtw->setToolboxFocusTo (id); }
virtual void setToolboxAdjustmentValue (const gchar *id, double val)
diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp
index ae6f238d4..d8e0f5418 100644
--- a/src/xml/repr-io.cpp
+++ b/src/xml/repr-io.cpp
@@ -404,7 +404,12 @@ Document *sp_repr_read_mem (const gchar * buffer, gint length, const gchar *defa
g_return_val_if_fail (buffer != NULL, NULL);
- doc = xmlParseMemory (const_cast<gchar *>(buffer), length);
+ int parser_options = XML_PARSE_HUGE | XML_PARSE_RECOVER;
+ parser_options |= XML_PARSE_NONET; // TODO: should we allow network access?
+ // proper solution would be to check the preference "/options/externalresources/xml/allow_net_access"
+ // as done in XmlSource::readXml which gets called by the analogous sp_repr_read_file()
+ // but sp_repr_read_mem() seems to be called in locations where Inkscape::Preferences::get() fails badly
+ doc = xmlReadMemory (const_cast<gchar *>(buffer), length, NULL, NULL, parser_options);
rdoc = sp_repr_do_read (doc, default_ns);
if (doc) {