summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShlomi Fish <shlomif@shlomifish.org>2016-10-08 15:39:06 +0000
committerShlomi Fish <shlomif@shlomifish.org>2016-10-08 15:39:06 +0000
commit2a5534a166dff8bfe6b56c8a3b496e989280fbd1 (patch)
treedbd8330a6b3dcfb201ee751dbf283a17a41a2dfa
parentMerged. (diff)
parent[Bug #770681] KEY MAPPING: Comma and period hijacked by scaling. (diff)
downloadinkscape-2a5534a166dff8bfe6b56c8a3b496e989280fbd1.tar.gz
inkscape-2a5534a166dff8bfe6b56c8a3b496e989280fbd1.zip
Merged.
(bzr r15100.1.31)
-rw-r--r--AUTHORS1
-rw-r--r--CMakeLists.txt2
-rw-r--r--CMakeScripts/DefineDependsandFlags.cmake11
-rw-r--r--CMakeScripts/Modules/Findyaml.cmake49
-rw-r--r--po/POTFILES.in2
-rw-r--r--share/keys/default.xml18
-rw-r--r--share/keys/inkscape.xml24
-rw-r--r--share/keys/xara.xml8
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/gradient-chemistry.cpp5
-rw-r--r--src/live_effects/CMakeLists.txt4
-rw-r--r--src/live_effects/effect-enum.h1
-rw-r--r--src/live_effects/effect.cpp13
-rw-r--r--src/live_effects/effect.h3
-rw-r--r--src/live_effects/lpe-ellipse_5pts.cpp2
-rw-r--r--src/live_effects/lpe-extrude.cpp2
-rw-r--r--src/live_effects/lpe-knot.cpp4
-rw-r--r--src/live_effects/lpe-measure-line.cpp892
-rw-r--r--src/live_effects/lpe-measure-line.h103
-rw-r--r--src/live_effects/lpe-powerstroke.cpp3
-rw-r--r--src/live_effects/lpe-transform_2pts.cpp1
-rw-r--r--src/live_effects/lpeobject.h10
-rw-r--r--src/live_effects/parameter/bool.cpp6
-rw-r--r--src/live_effects/parameter/bool.h2
-rw-r--r--src/live_effects/parameter/enum.h8
-rw-r--r--src/live_effects/parameter/fontbutton.cpp92
-rw-r--r--src/live_effects/parameter/fontbutton.h62
-rw-r--r--src/live_effects/parameter/parameter.cpp22
-rw-r--r--src/live_effects/parameter/parameter.h3
-rw-r--r--src/live_effects/parameter/point.cpp37
-rw-r--r--src/live_effects/parameter/point.h5
-rw-r--r--src/live_effects/parameter/text.cpp52
-rw-r--r--src/live_effects/parameter/text.h4
-rw-r--r--src/live_effects/parameter/togglebutton.cpp10
-rw-r--r--src/live_effects/parameter/unit.cpp6
-rw-r--r--src/live_effects/parameter/unit.h1
-rw-r--r--src/main-cmdlineact.cpp54
-rw-r--r--src/main-cmdlineact.h19
-rw-r--r--src/main-cmdlinexact.cpp576
-rw-r--r--src/main-cmdlinexact.h54
-rw-r--r--src/main.cpp31
-rw-r--r--src/selection.h2
-rw-r--r--src/sp-item.cpp2
-rw-r--r--src/sp-lpe-item.cpp7
-rw-r--r--src/sp-object.cpp5
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp46
-rw-r--r--src/ui/dialog/filter-effects-dialog.h8
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp39
-rw-r--r--src/ui/dialog/livepatheffect-editor.h11
-rw-r--r--src/ui/tools/eraser-tool.cpp12
-rw-r--r--src/ui/tools/measure-tool.cpp112
-rw-r--r--src/ui/tools/measure-tool.h9
-rw-r--r--src/ui/tools/node-tool.cpp11
-rw-r--r--src/ui/tools/select-tool.cpp32
-rw-r--r--src/ui/widget/combo-enums.h9
-rw-r--r--src/ui/widget/font-button.cpp58
-rw-r--r--src/ui/widget/font-button.h63
-rw-r--r--src/ui/widget/registered-enums.h6
-rw-r--r--src/ui/widget/registered-widget.cpp54
-rw-r--r--src/ui/widget/registered-widget.h20
-rw-r--r--src/ui/widget/scalar.cpp6
-rw-r--r--src/ui/widget/scalar.h2
-rw-r--r--src/ui/widget/text.cpp6
-rw-r--r--src/ui/widget/text.h4
-rw-r--r--src/verbs.cpp54
-rw-r--r--src/verbs.h8
-rw-r--r--src/widgets/pencil-toolbar.cpp9
68 files changed, 2622 insertions, 179 deletions
diff --git a/AUTHORS b/AUTHORS
index 975705433..f5f3a4069 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -148,6 +148,7 @@ Abhishek Sharma
Shivaken
Michael Sloan
John Smith
+Sandra Snan
Boštjan Špetič
Aaron Spike
Kaushik Sridharan
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d928f2aac..300af32a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,7 @@ option(WITH_LIBCDR "Compile with support of libcdr for CorelDRAW Diagrams" ON)
option(WITH_LIBVISIO "Compile with support of libvisio for Microsoft Visio Diagrams" ON)
option(WITH_LIBWPG "Compile with support of libwpg for WordPerfect Graphics" ON)
option(WITH_NLS "Compile with Native Language Support (using gettext)" ON)
+option(WITH_YAML "Compile with YAML support (enables xverbs)" ON)
option(ENABLE_BINRELOC "Enable relocatable binaries" OFF)
@@ -255,6 +256,7 @@ message("WITH_LIBWPG: ${WITH_LIBWPG}")
message("WITH_NLS: ${WITH_NLS}")
message("WITH_OPENMP: ${WITH_OPENMP}")
message("WITH_PROFILING: ${WITH_PROFILING}")
+message("WITH_YAML: ${WITH_YAML}")
if(WIN32)
message("")
diff --git a/CMakeScripts/DefineDependsandFlags.cmake b/CMakeScripts/DefineDependsandFlags.cmake
index e3bc9258e..ad2d51724 100644
--- a/CMakeScripts/DefineDependsandFlags.cmake
+++ b/CMakeScripts/DefineDependsandFlags.cmake
@@ -387,6 +387,17 @@ list(APPEND INKSCAPE_LIBS ${SIGC++_LDFLAGS})
list(APPEND INKSCAPE_CXX_FLAGS ${SIGC++_CFLAGS_OTHER})
+find_package(yaml)
+if(YAML_FOUND)
+ set (WITH_YAML ON)
+ list(APPEND INKSCAPE_INCS_SYS ${YAML_INCLUDE_DIRS})
+ list(APPEND INKSCAPE_LIBS ${YAML_LIBRARIES})
+ add_definitions(-DWITH_YAML)
+else(YAML_FOUND)
+ set(WITH_YAML OFF)
+ message(STATUS "Could not locate the yaml library headers: xverb feature will be disabled")
+endif()
+
list(REMOVE_DUPLICATES INKSCAPE_CXX_FLAGS)
foreach(flag ${INKSCAPE_CXX_FLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" CACHE STRING "" FORCE)
diff --git a/CMakeScripts/Modules/Findyaml.cmake b/CMakeScripts/Modules/Findyaml.cmake
new file mode 100644
index 000000000..154f2ed43
--- /dev/null
+++ b/CMakeScripts/Modules/Findyaml.cmake
@@ -0,0 +1,49 @@
+# - Try to find the YAML library
+# Once done this will define
+#
+# YAML_FOUND - system has yaml
+# YAML_INCLUDE_DIR - the yaml include directory
+# YAML_LIBRARIES - the libraries needed to use yaml
+
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+if (YAML_INCLUDE_DIR AND YAML_LIBRARIES)
+ # in cache already
+ SET(YAML_FOUND TRUE)
+else (YAML_INCLUDE_DIR AND YAML_LIBRARIES)
+ IF (NOT WIN32)
+ FIND_PACKAGE(PkgConfig)
+ IF (PKG_CONFIG_FOUND)
+ # use pkg-config to get the directories and then use these values
+ # in the FIND_PATH() and FIND_LIBRARY() calls
+ pkg_check_modules(_YAML_PC QUIET yaml-1)
+ ENDIF (PKG_CONFIG_FOUND)
+ ENDIF (NOT WIN32)
+
+ FIND_PATH(YAML_INCLUDE_DIR yaml.h
+ /usr/include
+ /usr/local/include
+ )
+
+ FIND_LIBRARY(YAML_LIBRARIES NAMES yaml
+ PATHS)
+
+ if (YAML_INCLUDE_DIR AND YAML_LIBRARIES)
+ set(YAML_FOUND TRUE)
+ endif (YAML_INCLUDE_DIR AND YAML_LIBRARIES)
+
+
+ if (YAML_FOUND)
+ if (NOT YAML_FIND_QUIETLY)
+ message(STATUS "Found YAML: ${YAML_LIBRARIES}")
+ endif (NOT YAML_FIND_QUIETLY)
+ else (YAML_FOUND)
+ if (YAML_FIND_REQUIRED)
+ message(FATAL_ERROR "Could NOT find YAML")
+ endif (YAML_FIND_REQUIRED)
+ endif (YAML_FOUND)
+
+ MARK_AS_ADVANCED(YAML_INCLUDE_DIR YAML_LIBRARIES)
+
+endif (YAML_INCLUDE_DIR AND YAML_LIBRARIES)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8824a72c8..f73e3a9d9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -154,6 +154,7 @@ src/live_effects/lpe-powerstroke.cpp
src/live_effects/lpe-rough-hatches.cpp
src/live_effects/lpe-roughen.cpp
src/live_effects/lpe-ruler.cpp
+src/live_effects/lpe-measure-line.cpp
src/live_effects/lpe-show_handles.cpp
src/live_effects/lpe-simplify.cpp
src/live_effects/lpe-sketch.cpp
@@ -171,6 +172,7 @@ src/live_effects/parameter/point.cpp
src/live_effects/parameter/powerstrokepointarray.cpp
src/live_effects/parameter/random.cpp
src/live_effects/parameter/text.cpp
+src/live_effects/parameter/fontbutton.cpp
src/live_effects/parameter/togglebutton.cpp
src/live_effects/parameter/transformedpoint.cpp
src/live_effects/parameter/unit.cpp
diff --git a/share/keys/default.xml b/share/keys/default.xml
index f16be0689..581716d12 100644
--- a/share/keys/default.xml
+++ b/share/keys/default.xml
@@ -405,6 +405,24 @@ override) the bindings in the main default.xml.
<bind key="Page_Down" action="SelectionLower" display="true" />
<bind key="KP_Page_Down" action="SelectionLower" />
+
+ <bind key="comma" action="SelectionShrink" display="true" />
+ <bind key="less" action="SelectionShrink" />
+
+ <bind key="comma" modifiers="Alt" action="SelectionShrinkScreen" />
+ <bind key="less" modifiers="Alt" action="SelectionShrinkScreen" />
+
+ <bind key="comma" modifiers="Ctrl" action="SelectionShrinkHalve" />
+ <bind key="less" modifiers="Ctrl" action="SelectionShrinkHalve" />
+
+ <bind key="period" action="SelectionGrow" display="true" />
+ <bind key="greater" action="SelectionGrow" />
+
+ <bind key="period" modifiers="Alt" action="SelectionGrowScreen" />
+ <bind key="greater" modifiers="Alt" action="SelectionGrowScreen" />
+
+ <bind key="period" modifiers="Ctrl" action="SelectionGrowDouble" />
+ <bind key="greater" modifiers="Ctrl" action="SelectionGrowDouble" />
<bind key="g" modifiers="Ctrl" action="SelectionGroup" display="true" />
<bind key="G" modifiers="Ctrl" action="SelectionGroup" />
diff --git a/share/keys/inkscape.xml b/share/keys/inkscape.xml
index 07192cb37..581716d12 100644
--- a/share/keys/inkscape.xml
+++ b/share/keys/inkscape.xml
@@ -297,8 +297,7 @@ override) the bindings in the main default.xml.
<bind key="z" modifiers="Ctrl" action="EditUndo" display="true" />
<bind key="Z" modifiers="Ctrl" action="EditUndo" />
- <bind key="y" modifiers="Ctrl,Shift" action="EditUndo" />
- <bind key="Y" modifiers="Ctrl,Shift" action="EditUndo" />
+ <!--Do not put in Ctrl,Shift+Y, already used-->
<bind key="z" modifiers="Ctrl,Shift" action="EditRedo" display="true" />
<bind key="Z" modifiers="Ctrl,Shift" action="EditRedo" />
@@ -384,6 +383,9 @@ override) the bindings in the main default.xml.
<bind key="7" action="EditNextPathEffectParameter" display="true" />
+ <bind key="r" modifiers="Ctrl,Shift" action="FitCanvasToSelectionOrDrawing" display="true" />
+ <bind key="R" modifiers="Ctrl,Shift" action="FitCanvasToSelectionOrDrawing" display="true" />
+
<!-- Objects/selection -->
<bind key="h" action="ObjectFlipHorizontally" display="true" />
@@ -403,6 +405,24 @@ override) the bindings in the main default.xml.
<bind key="Page_Down" action="SelectionLower" display="true" />
<bind key="KP_Page_Down" action="SelectionLower" />
+
+ <bind key="comma" action="SelectionShrink" display="true" />
+ <bind key="less" action="SelectionShrink" />
+
+ <bind key="comma" modifiers="Alt" action="SelectionShrinkScreen" />
+ <bind key="less" modifiers="Alt" action="SelectionShrinkScreen" />
+
+ <bind key="comma" modifiers="Ctrl" action="SelectionShrinkHalve" />
+ <bind key="less" modifiers="Ctrl" action="SelectionShrinkHalve" />
+
+ <bind key="period" action="SelectionGrow" display="true" />
+ <bind key="greater" action="SelectionGrow" />
+
+ <bind key="period" modifiers="Alt" action="SelectionGrowScreen" />
+ <bind key="greater" modifiers="Alt" action="SelectionGrowScreen" />
+
+ <bind key="period" modifiers="Ctrl" action="SelectionGrowDouble" />
+ <bind key="greater" modifiers="Ctrl" action="SelectionGrowDouble" />
<bind key="g" modifiers="Ctrl" action="SelectionGroup" display="true" />
<bind key="G" modifiers="Ctrl" action="SelectionGroup" />
diff --git a/share/keys/xara.xml b/share/keys/xara.xml
index 25ebfcb48..92a84d33e 100644
--- a/share/keys/xara.xml
+++ b/share/keys/xara.xml
@@ -263,13 +263,13 @@ Hom/end keys-select minimum or maximum feather values
<bind key="Z" modifiers="Ctrl" action="EditUndo" display="true"/>
<bind key="y" modifiers="Ctrl,Shift" action="EditUndo" />
<bind key="Y" modifiers="Ctrl,Shift" action="EditUndo" />
- <bind key="less" modifiers="Ctrl" action="EditUndo" /> <!-- FIXME: stolen by scaling, redirect that through a verb -->
- <bind key="comma" modifiers="Ctrl" action="EditUndo" /> <!-- FIXME: stolen by scaling, redirect that through a verb -->
+ <bind key="less" modifiers="Ctrl" action="EditUndo" />
+ <bind key="comma" modifiers="Ctrl" action="EditUndo" />
<bind key="y" modifiers="Ctrl" action="EditRedo" display="true"/>
<bind key="Y" modifiers="Ctrl" action="EditRedo" />
- <bind key="greater" modifiers="Ctrl" action="EditRedo" /> <!-- FIXME: stolen by scaling, redirect that through a verb -->
- <bind key="period" modifiers="Ctrl" action="EditRedo" /> <!-- FIXME: stolen by scaling, redirect that through a verb -->
+ <bind key="greater" modifiers="Ctrl" action="EditRedo" />
+ <bind key="period" modifiers="Ctrl" action="EditRedo" />
<bind key="x" modifiers="Ctrl" action="EditCut" display="true"/>
<bind key="X" modifiers="Ctrl" action="EditCut" />
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c4f28aa8..6a2af6b4b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -221,6 +221,7 @@ set(inkscape_SRC
line-geometry.cpp
line-snapper.cpp
main-cmdlineact.cpp
+ main-cmdlinexact.cpp
media.cpp
message-context.cpp
message-stack.cpp
@@ -337,6 +338,7 @@ set(inkscape_SRC
line-snapper.h
macros.h
main-cmdlineact.h
+ main-cmdlinexact.h
media.h
menus-skeleton.h
message-context.h
diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp
index 061fadbaa..cf5cda180 100644
--- a/src/gradient-chemistry.cpp
+++ b/src/gradient-chemistry.cpp
@@ -434,6 +434,11 @@ SPGradient *sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar
return gr;
}
+ // FIXME Transforming a mesh gradient is more complicated... probably need to add function to SPMeshArray.wq
+ if ( gr && SP_IS_MESHGRADIENT( gr ) ) {
+ return gr;
+ }
+
// First, fork it if it is shared
gr = sp_gradient_fork_private_if_necessary(gr, gr->getVector(),
SP_IS_RADIALGRADIENT(gr) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, item);
diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt
index 9a2f06a76..784317090 100644
--- a/src/live_effects/CMakeLists.txt
+++ b/src/live_effects/CMakeLists.txt
@@ -27,6 +27,7 @@ set(live_effects_SRC
lpe-lattice.cpp
lpe-lattice2.cpp
lpe-line_segment.cpp
+ lpe-measure-line.cpp
lpe-mirror_symmetry.cpp
lpe-offset.cpp
lpe-parallel.cpp
@@ -68,6 +69,7 @@ set(live_effects_SRC
parameter/powerstrokepointarray.cpp
parameter/random.cpp
parameter/text.cpp
+ parameter/fontbutton.cpp
parameter/togglebutton.cpp
parameter/transformedpoint.cpp
parameter/unit.cpp
@@ -105,6 +107,7 @@ set(live_effects_SRC
lpe-lattice.h
lpe-lattice2.h
lpe-line_segment.h
+ lpe-measure-line.h
lpe-mirror_symmetry.h
lpe-offset.h
lpe-parallel.h
@@ -148,6 +151,7 @@ set(live_effects_SRC
parameter/powerstrokepointarray.h
parameter/random.h
parameter/text.h
+ parameter/fontbutton.h
parameter/togglebutton.h
parameter/transformedpoint.h
parameter/unit.h
diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h
index eea26184c..3682aa1bd 100644
--- a/src/live_effects/effect-enum.h
+++ b/src/live_effects/effect-enum.h
@@ -36,6 +36,7 @@ enum EffectType {
CONSTRUCT_GRID,
PERP_BISECTOR,
TANGENT_TO_CURVE,
+ MEASURE_LINE,
MIRROR_SYMMETRY,
CIRCLE_3PTS,
TRANSFORM_2PTS,
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 007a8ca38..792bb5d7a 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -39,6 +39,7 @@
#include "live_effects/lpe-lattice2.h"
#include "live_effects/lpe-lattice.h"
#include "live_effects/lpe-line_segment.h"
+#include "live_effects/lpe-measure-line.h"
#include "live_effects/lpe-mirror_symmetry.h"
#include "live_effects/lpe-offset.h"
#include "live_effects/lpe-parallel.h"
@@ -135,6 +136,8 @@ const Util::EnumData<EffectType> LPETypeData[] = {
{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"},
};
const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
@@ -303,6 +306,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
case TRANSFORM_2PTS:
neweffect = static_cast<Effect*> ( new LPETransform2Pts(lpeobj) );
break;
+ case MEASURE_LINE:
+ neweffect = static_cast<Effect*> ( new LPEMeasureLine(lpeobj) );
+ break;
default:
g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr);
neweffect = NULL;
@@ -348,6 +354,7 @@ Effect::Effect(LivePathEffectObject *lpeobject)
concatenate_before_pwd2(false),
sp_lpe_item(NULL),
current_zoom(1),
+ upd_params(true),
sp_curve(NULL),
provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden
is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden
@@ -431,7 +438,9 @@ void Effect::doAfterEffect (SPLPEItem const* /*lpeitem*/)
void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/)
{
}
-
+void Effect::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/)
+{
+}
//secret impl methods (shhhh!)
void Effect::doOnApply_impl(SPLPEItem const* lpeitem)
{
@@ -690,7 +699,7 @@ Effect::newWidget()
++it;
}
-
+ upd_params = false;
return dynamic_cast<Gtk::Widget *>(vbox);
}
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 840f723fa..5ca53486c 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -66,7 +66,7 @@ public:
virtual void doAfterEffect (SPLPEItem const* lpeitem);
virtual void doOnRemove (SPLPEItem const* lpeitem);
-
+ virtual void doOnVisibilityToggled(SPLPEItem const* lpeitem);
void writeParamsToSVG();
virtual void acceptParamPath (SPPath const* param_path);
@@ -123,6 +123,7 @@ public:
void editNextParamOncanvas(SPItem * item, SPDesktop * desktop);
bool apply_to_clippath_and_mask;
+ bool upd_params;
protected:
Effect(LivePathEffectObject *lpeobject);
diff --git a/src/live_effects/lpe-ellipse_5pts.cpp b/src/live_effects/lpe-ellipse_5pts.cpp
index 8f0f8e18a..0371fc313 100644
--- a/src/live_effects/lpe-ellipse_5pts.cpp
+++ b/src/live_effects/lpe-ellipse_5pts.cpp
@@ -170,7 +170,7 @@ LPEEllipse5Pts::doEffect_path (Geom::PathVector const & path_in)
// figure out if we have a slice, guarding against rounding errors
- Path p(Geom::Point(cos(0), sin(0)));
+ Geom::Path p(Geom::Point(cos(0), sin(0)));
double end = 2 * M_PI;
for (s = 0; s < end; s += M_PI_2) {
diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp
index 22cdf3c3e..d22007f76 100644
--- a/src/live_effects/lpe-extrude.cpp
+++ b/src/live_effects/lpe-extrude.cpp
@@ -61,7 +61,7 @@ LPEExtrude::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2
using namespace Geom;
// generate connecting lines (the 'sides' of the extrusion)
- Path path(Point(0.,0.));
+ Geom::Path path(Point(0.,0.));
path.appendNew<Geom::LineSegment>( extrude_vector.getVector() );
Piecewise<D2<SBasis> > connector = path.toPwSb();
diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp
index 221d03ebf..fbc32cf3e 100644
--- a/src/live_effects/lpe-knot.cpp
+++ b/src/live_effects/lpe-knot.cpp
@@ -94,7 +94,7 @@ findShadowedTime(Geom::Path const &patha, std::vector<Geom::Point> const &pt_and
Affine mat = from_basis( T, N, pt_and_dir[0] );
mat = mat.inverse();
- Path p = patha * mat;
+ Geom::Path p = patha * mat;
std::vector<double> times;
@@ -477,7 +477,7 @@ LPEKnot::doEffect_path (Geom::PathVector const &path_in)
// std::cout<<"fusing first and last component\n";
++beg_comp;
--end_comp;
- Path first = gpaths[i0].portion(dom.back());
+ Geom::Path first = gpaths[i0].portion(dom.back());
//FIXME: stitching should not be necessary (?!?)
first.setStitching(true);
first.append(gpaths[i0].portion(dom.front()));
diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp
new file mode 100644
index 000000000..e8ceb7e51
--- /dev/null
+++ b/src/live_effects/lpe-measure-line.cpp
@@ -0,0 +1,892 @@
+/*
+ * Author(s):
+ * Jabiertxo Arraiza Cenoz <jabier.arraiza@marker.es>
+ * Some code and ideas migrated from dimensioning.py by
+ * Johannes B. Rutzmoser, johannes.rutzmoser (at) googlemail (dot) com
+ * https://github.com/Rutzmoser/inkscape_dimensioning
+ * Copyright (C) 2014 Author(s)
+
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#include "live_effects/lpe-measure-line.h"
+#include <pangomm/fontdescription.h>
+#include "ui/dialog/livepatheffect-editor.h"
+#include <libnrtype/font-lister.h>
+#include "inkscape.h"
+#include "xml/node.h"
+#include "uri.h"
+#include "uri-references.h"
+#include "preferences.h"
+#include "util/units.h"
+#include "svg/svg-length.h"
+#include "svg/svg-color.h"
+#include "svg/svg.h"
+#include "display/curve.h"
+#include "2geom/affine.h"
+#include "style.h"
+#include "sp-root.h"
+#include "sp-defs.h"
+#include "sp-item.h"
+#include "sp-shape.h"
+#include "sp-path.h"
+#include "desktop.h"
+#include "document.h"
+#include <iomanip>
+
+// TODO due to internal breakage in glibmm headers, this must be last:
+#include <glibmm/i18n.h>
+
+using namespace Geom;
+namespace Inkscape {
+namespace LivePathEffect {
+
+static const Util::EnumData<OrientationMethod> OrientationMethodData[] = {
+ { OM_HORIZONTAL, N_("Horizontal"), "horizontal" },
+ { OM_VERTICAL, N_("Vertical"), "vertical" },
+ { OM_PARALLEL, N_("Parallel"), "parallel" }
+};
+static const Util::EnumDataConverter<OrientationMethod> OMConverter(OrientationMethodData, OM_END);
+
+LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) :
+ Effect(lpeobject),
+ 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(_("Positon*"), _("Positon"), "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"),
+ arrows_outside(_("Arrows outside"), _("Arrows outside"), "arrows_outside", &wr, this, false),
+ flip_side(_("Flip side*"), _("Flip side"), "flip_side", &wr, this, false),
+ scale_insensitive(_("Scale insensitive*"), _("Scale insensitive to transforms in element, parents..."), "scale_insensitive", &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)
+{
+ registerParameter(&unit);
+ registerParameter(&fontbutton);
+ registerParameter(&orientation);
+ registerParameter(&curve_linked);
+ registerParameter(&precision);
+ registerParameter(&position);
+ registerParameter(&text_top_bottom);
+ registerParameter(&text_right_left);
+ registerParameter(&helpline_distance);
+ registerParameter(&helpline_overlap);
+ registerParameter(&scale);
+ registerParameter(&format);
+ registerParameter(&arrows_outside);
+ registerParameter(&flip_side);
+ registerParameter(&scale_insensitive);
+ registerParameter(&local_locale);
+ registerParameter(&line_group_05);
+ registerParameter(&rotate_anotation);
+ registerParameter(&hide_back);
+ registerParameter(&dimline_format);
+ registerParameter(&helperlines_format);
+ registerParameter(&anotation_format);
+ registerParameter(&arrows_format);
+ 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_insensitive.param_update_default(prefs->getBool("/live_effects/measure-line/scale_insensitive"));
+ 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_hide_canvas_text();
+ dimline_format.param_hide_canvas_text();
+ helperlines_format.param_hide_canvas_text();
+ anotation_format.param_hide_canvas_text();
+ arrows_format.param_hide_canvas_text();
+ precision.param_set_range(0, 100);
+ precision.param_set_increments(1, 1);
+ precision.param_set_digits(0);
+ precision.param_make_integer(true);
+ curve_linked.param_set_range(0, 999);
+ curve_linked.param_set_increments(1, 1);
+ curve_linked.param_set_digits(0);
+ curve_linked.param_make_integer(true);
+ precision.param_make_integer(true);
+ position.param_set_range(-999999.0, 999999.0);
+ position.param_set_increments(1, 1);
+ position.param_set_digits(2);
+ text_top_bottom.param_set_range(-999999.0, 999999.0);
+ text_top_bottom.param_set_increments(1, 1);
+ text_top_bottom.param_set_digits(2);
+ text_right_left.param_set_range(-999999.0, 999999.0);
+ text_right_left.param_set_increments(1, 1);
+ text_right_left.param_set_digits(2);
+ helpline_distance.param_set_range(-999999.0, 999999.0);
+ helpline_distance.param_set_increments(1, 1);
+ helpline_distance.param_set_digits(2);
+ helpline_overlap.param_set_range(-999999.0, 999999.0);
+ helpline_overlap.param_set_increments(1, 1);
+ helpline_overlap.param_set_digits(2);
+ erase = true;
+}
+
+LPEMeasureLine::~LPEMeasureLine() {}
+
+void swap(Geom::Point &A, Geom::Point &B){
+ Geom::Point tmp = A;
+ A = B;
+ B = tmp;
+}
+void
+LPEMeasureLine::doOnApply(SPLPEItem const* lpeitem)
+{
+ if (!SP_IS_SHAPE(lpeitem)) {
+ g_warning("LPE measure line can only be applied to shapes (not groups).");
+ SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
+ item->removeCurrentPathEffect(false);
+ }
+}
+
+void
+LPEMeasureLine::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/)
+{
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
+ SVGElemRef->attach(SVGElem_uri);
+ SPObject *elemref = NULL;
+ Inkscape::XML::Node *node = NULL;
+ if (elemref = SVGElemRef->getObject()) {
+ node = elemref->getRepr();
+ if (!this->isVisible()) {
+ node->setAttribute("style", "display:none");
+ } else {
+ node->setAttribute("style", NULL);
+ }
+ }
+ Inkscape::URI SVGElem_uri2(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri2);
+ if (elemref = SVGElemRef->getObject()) {
+ node = elemref->getRepr();
+ if (!this->isVisible()) {
+ node->setAttribute("style", "display:none");
+ } else {
+ node->setAttribute("style", NULL);
+ }
+ }
+ Inkscape::URI SVGElem_uri3(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri3);
+ if (elemref = SVGElemRef->getObject()) {
+ node = elemref->getRepr();
+ if (!this->isVisible()) {
+ node->setAttribute("style", "display:none");
+ } else {
+ node->setAttribute("style", NULL);
+ }
+ }
+ Inkscape::URI SVGElem_uri4(((Glib::ustring)"#" + (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri4);
+ if (elemref = SVGElemRef->getObject()) {
+ node = elemref->getRepr();
+ if (!this->isVisible()) {
+ node->setAttribute("style", "display:none");
+ } else {
+ node->setAttribute("style", NULL);
+ }
+ }
+ Inkscape::URI SVGElem_uri5(((Glib::ustring)"#" + (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri5);
+ if (elemref = SVGElemRef->getObject()) {
+ node = elemref->getRepr();
+ if (!this->isVisible()) {
+ node->setAttribute("style", "display:none");
+ } else {
+ node->setAttribute("style", NULL);
+ }
+ }
+ }
+}
+
+void
+LPEMeasureLine::createArrowMarker(Glib::ustring mode)
+{
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + mode).c_str());
+ Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
+ SVGElemRef->attach(SVGElem_uri);
+ SPObject *elemref = NULL;
+ Inkscape::XML::Node *arrow = NULL;
+ if (!(elemref = SVGElemRef->getObject())) {
+ arrow = xml_doc->createElement("svg:marker");
+ arrow->setAttribute("id", mode.c_str());
+ arrow->setAttribute("inkscape:stockid", mode.c_str());
+ arrow->setAttribute("orient", "auto");
+ arrow->setAttribute("refX", "0.0");
+ arrow->setAttribute("refY", "0.0");
+ arrow->setAttribute("style", "overflow:visible");
+ arrow->setAttribute("sodipodi:insensitive", "true");
+ /* Create <path> */
+ Inkscape::XML::Node *arrow_path = xml_doc->createElement("svg:path");
+ if (mode == (Glib::ustring)"ArrowDIN-start") {
+ arrow_path->setAttribute("d", "M -8,0 8,-2.11 8,2.11 z");
+ } else if (mode == (Glib::ustring)"ArrowDIN-end") {
+ arrow_path->setAttribute("d", "M 8,0 -8,2.11 -8,-2.11 z");
+ } else if (mode == (Glib::ustring)"ArrowDINout-start") {
+ arrow_path->setAttribute("d", "M 0,0 -16,2.11 -16,0.5 -26,0.5 -26,-0.5 -16,-0.5 -16,-2.11 z");
+ } else {
+ arrow_path->setAttribute("d", "M 0,0 16,2.11 16,0.5 26,0.5 26,-0.5 16,-0.5 16,-2.11 z");
+ }
+
+ arrow_path->setAttribute("id", (mode + (Glib::ustring)"_path").c_str());
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_set_property (css, "fill","#000000");
+ sp_repr_css_set_property (css, "stroke","none" );
+ sp_repr_css_attr_add_from_string(css, arrows_format.param_getSVGValue());
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ arrow_path->setAttribute("style", css_str.c_str());
+ arrow->addChild(arrow_path, NULL);
+ Inkscape::GC::release(arrow_path);
+ elemref = SP_OBJECT(desktop->getDocument()->getDefs()->appendChildRepr(arrow));
+ Inkscape::GC::release(arrow);
+ } else {
+ Inkscape::XML::Node *arrow= elemref->getRepr();
+ if (arrow) {
+ arrow->setAttribute("sodipodi:insensitive", "true");
+ Inkscape::XML::Node *arrow_data = arrow->firstChild();
+ if (arrow_data) {
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_set_property (css, "fill","#000000");
+ sp_repr_css_set_property (css, "stroke","none" );
+ sp_repr_css_attr_add_from_string(css, arrows_format.param_getSVGValue());
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ arrow_data->setAttribute("style", css_str.c_str());
+ }
+ }
+ }
+ }
+}
+
+void
+LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove)
+{
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ Inkscape::XML::Node *rtext = NULL;
+ double doc_w = desktop->getDocument()->getRoot()->width.value;
+ Geom::Scale scale = desktop->getDocument()->getDocumentScale();
+ SPNamedView *nv = desktop->getNamedView();
+ Glib::ustring display_unit = nv->display_units->abbr;
+ if (display_unit.empty()) {
+ display_unit = "px";
+ }
+ //only check constrain viewbox on X
+ doc_scale = Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units );
+ if( doc_scale > 0 ) {
+ doc_scale= 1.0/doc_scale;
+ } else {
+ doc_scale = 1.0;
+ }
+ Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
+ SVGElemRef->attach(SVGElem_uri);
+ SPObject *elemref = NULL;
+ Inkscape::XML::Node *rtspan = NULL;
+
+ if (elemref = SVGElemRef->getObject()) {
+ if (remove) {
+ elemref->deleteObject();
+ return;
+ }
+ pos = pos - Point::polar(angle, text_right_left);
+ rtext = elemref->getRepr();
+ sp_repr_set_svg_double(rtext, "x", pos[Geom::X]);
+ sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]);
+ rtext->setAttribute("sodipodi:insensitive", "true");
+ } else {
+ if (remove) {
+ return;
+ }
+ rtext = xml_doc->createElement("svg:text");
+ rtext->setAttribute("xml:space", "preserve");
+ rtext->setAttribute("id", ( (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ rtext->setAttribute("sodipodi:insensitive", "true");
+ pos = pos - Point::polar(angle, text_right_left);
+ sp_repr_set_svg_double(rtext, "x", pos[Geom::X]);
+ sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]);
+ rtspan = xml_doc->createElement("svg:tspan");
+ rtspan->setAttribute("sodipodi:role", "line");
+ }
+ gchar * transform;
+ Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse());
+ angle = std::fmod(angle, 2*M_PI);
+ if (angle < 0) angle += 2*M_PI;
+ if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) {
+ angle = std::fmod(angle + rad_from_deg(180), 2*M_PI);
+ if (angle < 0) angle += 2*M_PI;
+ }
+ affine *= Geom::Rotate(angle);
+ affine *= Geom::Translate(pos);
+ if (rotate_anotation) {
+ transform = sp_svg_transform_write(affine);
+ } else {
+ transform = NULL;
+ }
+ rtext->setAttribute("transform", transform);
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_attr_add_from_string(css, anotation_format.param_getSVGValue());
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->fill_css( css, (Glib::ustring)fontbutton.param_getSVGValue() );
+ std::stringstream font_size;
+ font_size.imbue(std::locale::classic());
+ font_size << fontsize << "pt";
+
+ sp_repr_css_set_property (css, "font-size",font_size.str().c_str());
+ sp_repr_css_set_property (css, "line-height","125%");
+ sp_repr_css_set_property (css, "letter-spacing","0");
+ sp_repr_css_set_property (css, "word-spacing", "0");
+ sp_repr_css_set_property (css, "text-align", "center");
+ sp_repr_css_set_property (css, "text-anchor", "middle");
+ sp_repr_css_set_property (css, "fill", "#000000");
+ sp_repr_css_set_property (css, "fill-opacity", "1");
+ sp_repr_css_set_property (css, "stroke", "none");
+ sp_repr_css_attr_add_from_string(css, anotation_format.param_getSVGValue());
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ if (!rtspan) {
+ rtspan = rtext->firstChild();
+ }
+ rtext->setAttribute("style", css_str.c_str());
+ rtspan->setAttribute("style", NULL);
+ sp_repr_css_attr_unref (css);
+ if (!elemref) {
+ rtext->addChild(rtspan, NULL);
+ Inkscape::GC::release(rtspan);
+ }
+ length = Inkscape::Util::Quantity::convert(length / doc_scale, display_unit.c_str(), unit.get_abbreviation());
+ std::stringstream length_str;
+ length_str.precision(precision);
+ length_str.setf(std::ios::fixed, std::ios::floatfield);
+ if (local_locale) {
+ length_str.imbue(std::locale(""));
+ } else {
+ length_str.imbue(std::locale::classic());
+ }
+ length_str << std::fixed << length;
+ Glib::ustring label_value = Glib::ustring(format.param_getSVGValue());
+ size_t s = label_value.find((Glib::ustring)"{measure}",0);
+ if(s < label_value.length()) {
+ label_value.replace(s,s+9,length_str.str());
+ }
+ s = label_value.find((Glib::ustring)"{unit}",0);
+ if(s < label_value.length()) {
+ label_value.replace(s,s+6,unit.get_abbreviation());
+ }
+ Inkscape::XML::Node *rstring = NULL;
+ if (!elemref) {
+ rstring = xml_doc->createTextNode(label_value.c_str());
+ rtspan->addChild(rstring, NULL);
+ Inkscape::GC::release(rstring);
+ } else {
+ rstring = rtspan->firstChild();
+ rstring->setContent(label_value.c_str());
+ }
+ if (!elemref) {
+ elemref = SP_OBJECT(desktop->currentLayer()->appendChildRepr(rtext));
+ Inkscape::GC::release(rtext);
+ }
+ Inkscape::XML::Node *tmp_node = rtext->duplicate(xml_doc);
+ affine = Geom::Affine(Geom::Scale(1.4));
+ tmp_node->setAttribute("transform", sp_svg_transform_write(affine));
+ SPObject * tmp_obj = SP_OBJECT(desktop->currentLayer()->appendChildRepr(tmp_node));
+ Inkscape::GC::release(tmp_node);
+ tmp_obj->updateRepr();
+ Geom::OptRect bounds = SP_ITEM(tmp_obj)->bounds(SPItem::GEOMETRIC_BBOX);
+ if (bounds) {
+ anotation_width = bounds->width();
+ }
+ tmp_obj->deleteObject();
+ }
+}
+
+void
+LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, Glib::ustring id, bool main, bool overflow, bool remove, bool arrows)
+{
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str());
+ Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
+ SVGElemRef->attach(SVGElem_uri);
+ SPObject *elemref = NULL;
+ Inkscape::XML::Node *line = NULL;
+ if (!main) {
+ Geom::Ray ray(start, end);
+ Geom::Coord angle = ray.angle();
+ start = start + Point::polar(angle, helpline_distance );
+ end = end + Point::polar(angle, helpline_overlap );
+ }
+ Geom::PathVector line_pathv;
+ if (main && std::abs(text_top_bottom) < fontsize/1.5 && hide_back && !overflow){
+ Geom::Path line_path;
+ double k = 0;
+ if (flip_side) {
+ k = (Geom::distance(start,end)/2.0) + arrow_gap - (anotation_width/2.0);
+ } else {
+ k = (Geom::distance(start,end)/2.0) - arrow_gap - (anotation_width/2.0);
+ }
+ if (Geom::distance(start,end) < anotation_width){
+ return;
+ }
+ Geom::Ray ray(end, start);
+ Geom::Coord angle = ray.angle();
+ line_path.start(start);
+ line_path.appendNew<Geom::LineSegment>(start - Point::polar(angle, k));
+ line_pathv.push_back(line_path);
+ line_path.clear();
+ line_path.start(end + Point::polar(angle, k));
+ line_path.appendNew<Geom::LineSegment>(end);
+ line_pathv.push_back(line_path);
+ } else {
+ Geom::Path line_path;
+ line_path.start(start);
+ line_path.appendNew<Geom::LineSegment>(end);
+ line_pathv.push_back(line_path);
+ }
+
+ if (elemref = SVGElemRef->getObject()) {
+ if (remove) {
+ elemref->deleteObject();
+ return;
+ }
+ line = elemref->getRepr();
+
+ gchar * line_str = sp_svg_write_path( line_pathv );
+ line->setAttribute("d" , line_str);
+ } else {
+ if (remove) {
+ return;
+ }
+ line = xml_doc->createElement("svg:path");
+ line->setAttribute("id", id.c_str());
+ gchar * line_str = sp_svg_write_path( line_pathv );
+ line->setAttribute("d" , line_str);
+ }
+ line->setAttribute("sodipodi:insensitive", "true");
+ line_pathv.clear();
+
+ Glib::ustring style = (Glib::ustring)"stroke:#000000;fill:none;";
+ if (overflow && !arrows) {
+ line->setAttribute("inkscape:label", "downline");
+ } else if (main) {
+ line->setAttribute("inkscape:label", "dinline");
+ if (arrows_outside) {
+ style = style + (Glib::ustring)"marker-start:url(#ArrowDINout-start);marker-end:url(#ArrowDINout-end);";
+ } else {
+ style = style + (Glib::ustring)"marker-start:url(#ArrowDIN-start);marker-end:url(#ArrowDIN-end);";
+ }
+ } else {
+ line->setAttribute("inkscape:label", "dinhelpline");
+ }
+ std::stringstream stroke_w;
+ stroke_w.imbue(std::locale::classic());
+ if (line_group_05) {
+ double stroke_width = Inkscape::Util::Quantity::convert(0.25 / doc_scale, "mm", display_unit.c_str());
+ stroke_w << stroke_width;
+ style = style + (Glib::ustring)"stroke-width:" + (Glib::ustring)stroke_w.str();
+ } else {
+ double stroke_width = Inkscape::Util::Quantity::convert(0.35 / doc_scale, "mm", display_unit.c_str());
+ stroke_w << stroke_width;
+ style = style + (Glib::ustring)"stroke-width:" + (Glib::ustring)stroke_w.str();
+ }
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_attr_add_from_string(css, style.c_str());
+ if (main) {
+ sp_repr_css_attr_add_from_string(css, dimline_format.param_getSVGValue());
+ } else {
+ sp_repr_css_attr_add_from_string(css, helperlines_format.param_getSVGValue());
+ }
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ line->setAttribute("style", css_str.c_str());
+ if (!elemref) {
+ elemref = SP_OBJECT(desktop->currentLayer()->appendChildRepr(line));
+ Inkscape::GC::release(line);
+ }
+ }
+}
+
+void
+LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem)
+{
+ SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem);
+ SPPath *sp_path = dynamic_cast<SPPath *>(splpeitem);
+ if (sp_path) {
+ SPDocument * doc = SP_ACTIVE_DOCUMENT;
+ Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem)->parent, SP_OBJECT(doc->getRoot()));
+ double parents_scale = (affinetransform.inverse().expansionX() + affinetransform.inverse().expansionY()) / 2.0;
+
+ Geom::PathVector pathvector = sp_path->get_original_curve()->get_pathvector();
+ pathvector *= affinetransform;
+ if (arrows_outside) {
+ createArrowMarker((Glib::ustring)"ArrowDINout-start");
+ createArrowMarker((Glib::ustring)"ArrowDINout-end");
+ } else {
+ createArrowMarker((Glib::ustring)"ArrowDIN-start");
+ createArrowMarker((Glib::ustring)"ArrowDIN-end");
+ }
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ if (((Glib::ustring)format.param_getSVGValue()).empty()) {
+ format.param_setValue((Glib::ustring)"{measure}{unit}");
+ this->upd_params = true;
+ }
+ size_t ncurves = pathvector.curveCount();
+ curve_linked.param_set_range(0, ncurves);
+ Geom::Point start = pathvector.initialPoint();
+ Geom::Point end = pathvector.finalPoint();
+ if (curve_linked) { //!0
+ start = pathvector.pointAt(curve_linked -1);
+ end = pathvector.pointAt(curve_linked);
+ }
+ Geom::Point hstart = start;
+ Geom::Point hend = end;
+ bool remove = false;
+ if (Geom::are_near(hstart, hend)) {
+ remove = true;
+ }
+ if (orientation == OM_VERTICAL) {
+ Coord xpos = std::max(hstart[Geom::X],hend[Geom::X]);
+ if (flip_side) {
+ xpos = std::min(hstart[Geom::X],hend[Geom::X]);
+ }
+ hstart[Geom::X] = xpos;
+ hend[Geom::X] = xpos;
+ if (hstart[Geom::Y] > hend[Geom::Y]) {
+ swap(hstart,hend);
+ swap(start,end);
+ }
+ if (Geom::are_near(hstart[Geom::Y], hend[Geom::Y])) {
+ remove = true;
+ }
+ }
+ if (orientation == OM_HORIZONTAL) {
+ Coord ypos = std::max(hstart[Geom::Y],hend[Geom::Y]);
+ if (flip_side) {
+ ypos = std::min(hstart[Geom::Y],hend[Geom::Y]);
+ }
+ hstart[Geom::Y] = ypos;
+ hend[Geom::Y] = ypos;
+ if (hstart[Geom::X] < hend[Geom::X]) {
+ swap(hstart,hend);
+ swap(start,end);
+ }
+ if (Geom::are_near(hstart[Geom::X], hend[Geom::X])) {
+ remove = true;
+ }
+ }
+ double length = Geom::distance(hstart,hend) * scale;
+ Geom::Point pos = Geom::middle_point(hstart,hend);
+ Geom::Ray ray(hstart,hend);
+ Geom::Coord angle = ray.angle();
+ if (flip_side) {
+ angle = std::fmod(angle + rad_from_deg(180), 2*M_PI);
+ if (angle < 0) angle += 2*M_PI;
+ }
+ //We get the font size to offset the text to the middle
+ Pango::FontDescription fontdesc((Glib::ustring)fontbutton.param_getSVGValue());
+ fontsize = fontdesc.get_size()/(double)Pango::SCALE;
+ fontsize *= desktop->doc()->getRoot()->c2p.inverse().expansionX();
+ Geom::Coord angle_cross = std::fmod(angle + rad_from_deg(90), 2*M_PI);
+ if (angle_cross < 0) angle_cross += 2*M_PI;
+ angle = std::fmod(angle, 2*M_PI);
+ if (angle < 0) angle += 2*M_PI;
+ if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) {
+ pos = pos - Point::polar(angle_cross, (position - text_top_bottom) + fontsize/2.5);
+ } else {
+ pos = pos - Point::polar(angle_cross, (position + text_top_bottom) - fontsize/2.5);
+ }
+ if (scale_insensitive) {
+ length *= parents_scale;
+ }
+ createTextLabel(pos, length, angle, remove);
+ bool overflow = false;
+ 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);
+ if (text_right_left < 0 && flip_side || text_right_left > 0 && !flip_side) {
+ sstart = start - Point::polar(angle_cross, position);
+ send = start - Point::polar(angle_cross, position);
+ }
+ Geom::Point prog_end = Geom::Point();
+ if (std::abs(text_top_bottom) < fontsize/1.5 && hide_back) {
+ if (text_right_left > 0 ) {
+ prog_end = sstart - Point::polar(angle, std::abs(text_right_left) - (anotation_width/1.9) - (Geom::distance(start,end)/2.0));
+ } else {
+ prog_end = sstart + Point::polar(angle, std::abs(text_right_left) - (anotation_width/1.9) - (Geom::distance(start,end)/2.0));
+ }
+ } else {
+ if (text_right_left > 0 ) {
+ prog_end = sstart - Point::polar(angle,(anotation_width/2) + std::abs(text_right_left) - (Geom::distance(start,end)/2.0));
+ } else {
+ prog_end = sstart + Point::polar(angle,(anotation_width/2) + std::abs(text_right_left) - (Geom::distance(start,end)/2.0));
+ }
+ }
+ overflow = true;
+ createLine(sstart, prog_end, (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id"), true, overflow, false, false);
+ } else {
+ //erase it
+ createLine(Geom::Point(),Geom::Point(), (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id"), true, overflow, true, false);
+ }
+ //LINE
+ arrow_gap = 8 * Inkscape::Util::Quantity::convert(0.35 / doc_scale, "mm", display_unit.c_str());
+ if (line_group_05) {
+ arrow_gap = 8 * Inkscape::Util::Quantity::convert(0.25 / doc_scale, "mm", display_unit.c_str());
+ }
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_attr_add_from_string(css, dimline_format.param_getSVGValue());
+ setlocale(LC_NUMERIC, std::locale::classic().name().c_str());
+ double width_line = atof(sp_repr_css_property(css,"stroke-width","-1"));
+ setlocale(LC_NUMERIC, std::locale("").name().c_str());
+ if (width_line > -0.0001) {
+ arrow_gap = 8 * Inkscape::Util::Quantity::convert(width_line/ doc_scale, "mm", display_unit.c_str());
+ }
+ if (flip_side) {
+ arrow_gap *= -1;
+ }
+ hstart = hstart - Point::polar(angle_cross, position);
+ Glib::ustring id = (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id");
+ createLine(start, hstart, id, false, false, remove);
+ hend = hend - Point::polar(angle_cross, position);
+ id = (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id");
+ createLine(end, hend, id, false, false, remove);
+ if (!arrows_outside) {
+ hstart = hstart + Point::polar(angle, arrow_gap);
+ hend = hend - Point::polar(angle, arrow_gap );
+ }
+ id = (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id");
+ createLine(hstart, hend, id, true, overflow, remove, true);
+ }
+ }
+}
+
+void LPEMeasureLine::doOnRemove (SPLPEItem const* lpeitem)
+{
+ if (!erase) return;
+
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
+ SVGElemRef->attach(SVGElem_uri);
+ SPObject *elemref = NULL;
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->deleteObject();
+ }
+ Inkscape::URI SVGElem_uri2(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri2);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->deleteObject();
+ }
+ Inkscape::URI SVGElem_uri3(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri3);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->deleteObject();
+ }
+ Inkscape::URI SVGElem_uri4(((Glib::ustring)"#" + (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri4);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->deleteObject();
+ }
+ Inkscape::URI SVGElem_uri5(((Glib::ustring)"#" + (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri5);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->deleteObject();
+ }
+ }
+}
+
+void LPEMeasureLine::toObjects()
+{
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+
+ Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
+ SVGElemRef->attach(SVGElem_uri);
+ SPObject *elemref = NULL;
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL);
+ }
+ Inkscape::URI SVGElem_uri2(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri2);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL);
+ }
+ Inkscape::URI SVGElem_uri3(((Glib::ustring)"#" + (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri3);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL);
+ }
+ Inkscape::URI SVGElem_uri4(((Glib::ustring)"#" + (Glib::ustring)"infoline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri4);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL);
+ }
+ Inkscape::URI SVGElem_uri5(((Glib::ustring)"#" + (Glib::ustring)"downline-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
+ SVGElemRef->attach(SVGElem_uri5);
+ if (elemref = SVGElemRef->getObject()) {
+ elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL);
+ }
+ erase = false;
+ sp_lpe_item->removeCurrentPathEffect(true);
+ //TODO: find better way to refresh effect list
+ if (SP_IS_OBJECT(sp_lpe_item)){
+ Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection();
+ selection->remove(SP_OBJECT(sp_lpe_item));
+ selection->add(SP_OBJECT(sp_lpe_item));
+ }
+ }
+}
+
+Gtk::Widget *LPEMeasureLine::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_border_width(5);
+ vbox->set_homogeneous(false);
+ vbox->set_spacing(2);
+
+ std::vector<Parameter *>::iterator it = param_vector.begin();
+ Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0));
+ Gtk::HBox * button2 = 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);
+ }
+ }
+ }
+
+ ++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);
+ Gtk::Button *remove = Gtk::manage(new Gtk::Button(Glib::ustring(_("Convert to objects"))));
+ remove->signal_clicked().connect(sigc::mem_fun(*this, &LPEMeasureLine::toObjects));
+ button2->pack_start(*remove, 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);
+ vbox->pack_start(*button2, true, true, 2);
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
+void
+LPEMeasureLine::onExpanderChanged()
+{
+ expanded = expander->get_expanded();
+ if(expanded) {
+ expander->set_label (Glib::ustring(_("Hide DIM CSS style override")));
+ } else {
+ expander->set_label (Glib::ustring(_("Show DIM CSS style override")));
+ }
+}
+
+Geom::PathVector
+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_insensitive", scale_insensitive);
+ 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 */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offset:((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/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h
new file mode 100644
index 000000000..2fab9dbb9
--- /dev/null
+++ b/src/live_effects/lpe-measure-line.h
@@ -0,0 +1,103 @@
+#ifndef INKSCAPE_LPE_MEASURE_LINE_H
+#define INKSCAPE_LPE_MEASURE_LINE_H
+
+/*
+ * Author(s):
+ * Jabiertxo Arraiza Cenoz <jabier.arraiza@marker.es>
+ *
+ * Copyright (C) 2014 Author(s)
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/enum.h"
+#include "live_effects/parameter/fontbutton.h"
+#include "live_effects/parameter/text.h"
+#include "live_effects/parameter/unit.h"
+#include "live_effects/parameter/bool.h"
+#include "live_effects/parameter/originalpath.h"
+#include <libnrtype/font-lister.h>
+#include <2geom/angle.h>
+#include <2geom/ray.h>
+#include <2geom/point.h>
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+enum OrientationMethod {
+ OM_HORIZONTAL,
+ OM_VERTICAL,
+ OM_PARALLEL,
+ OM_END
+};
+
+class LPEMeasureLine : public Effect {
+public:
+ LPEMeasureLine(LivePathEffectObject *lpeobject);
+ virtual ~LPEMeasureLine();
+ virtual void doBeforeEffect (SPLPEItem const* lpeitem);
+ virtual void doOnApply(SPLPEItem const* lpeitem);
+ virtual void doOnRemove (SPLPEItem const* lpeitem);
+ virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/);
+ virtual Geom::PathVector doEffect_path(Geom::PathVector const &path_in);
+ void createLine(Geom::Point start,Geom::Point end,Glib::ustring id, bool main, bool overflow, bool remove, bool arrows = false);
+ void createTextLabel(Geom::Point pos, double length, Geom::Coord angle, bool remove);
+ void onExpanderChanged();
+ void toObjects();
+ void createArrowMarker(Glib::ustring mode);
+ void saveDefault();
+ virtual Gtk::Widget *newWidget();
+private:
+ UnitParam unit;
+ FontButtonParam fontbutton;
+ EnumParam<OrientationMethod> orientation;
+ ScalarParam curve_linked;
+ ScalarParam precision;
+ ScalarParam position;
+ ScalarParam text_top_bottom;
+ ScalarParam text_right_left;
+ ScalarParam helpline_distance;
+ ScalarParam helpline_overlap;
+ ScalarParam scale;
+ TextParam format;
+ BoolParam arrows_outside;
+ BoolParam flip_side;
+ BoolParam scale_insensitive;
+ BoolParam local_locale;
+ BoolParam line_group_05;
+ BoolParam rotate_anotation;
+ BoolParam hide_back;
+ TextParam dimline_format;
+ TextParam helperlines_format;
+ TextParam anotation_format;
+ TextParam arrows_format;
+ Glib::ustring display_unit;
+ bool expanded;
+ Gtk::Expander * expander;
+ double doc_scale;
+ double fontsize;
+ double anotation_width;
+ double arrow_gap;
+ bool erase;
+/* Geom::Affine affine_over;*/
+ LPEMeasureLine(const LPEMeasureLine &);
+ LPEMeasureLine &operator=(const LPEMeasureLine &);
+
+};
+
+} //namespace LivePathEffect
+} //namespace Inkscape
+
+#endif
+
+/*
+ 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/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index 0de668847..329a00756 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -609,11 +609,12 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
// find time values for which x lies outside path domain
// and only take portion of x and y that lies within those time values
std::vector< double > rtsmin = roots (x - pwd2_in.domain().min());
- std::vector< double > rtsmax = roots (x - pwd2_in.domain().max());
+ std::vector< double > rtsmax = roots (x + pwd2_in.domain().max());
if ( !rtsmin.empty() && !rtsmax.empty() ) {
x = portion(x, rtsmin.at(0), rtsmax.at(0));
y = portion(y, rtsmin.at(0), rtsmax.at(0));
}
+
LineJoinType jointype = static_cast<LineJoinType>(linejoin_type.get_value());
Piecewise<D2<SBasis> > pwd2_out = compose(pwd2_in,x) + y*compose(n,x);
diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp
index 2b03a4bb2..78db622f2 100644
--- a/src/live_effects/lpe-transform_2pts.cpp
+++ b/src/live_effects/lpe-transform_2pts.cpp
@@ -87,7 +87,6 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem)
{
using namespace Geom;
original_bbox(lpeitem);
-
point_a = Point(boundingbox_X.min(), boundingbox_Y.middle());
point_b = Point(boundingbox_X.max(), boundingbox_Y.middle());
SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem);
diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h
index 2e62707e3..087223947 100644
--- a/src/live_effects/lpeobject.h
+++ b/src/live_effects/lpeobject.h
@@ -38,8 +38,14 @@ public:
/* Note that the returned pointer can be NULL in a valid LivePathEffectObject contained in a valid list of lpeobjects in an lpeitem!
* So one should always check whether the returned value is NULL or not */
- Inkscape::LivePathEffect::Effect * get_lpe() { return lpe; };
- Inkscape::LivePathEffect::Effect const * get_lpe() const { return lpe; };
+ Inkscape::LivePathEffect::Effect * get_lpe() {
+ if(this) return lpe;
+ else return NULL;
+ }
+ Inkscape::LivePathEffect::Effect const * get_lpe() const {
+ if(this) return lpe;
+ else return NULL;
+ };
Inkscape::LivePathEffect::Effect *lpe; // this can be NULL in a valid LivePathEffectObject
diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp
index 9ecadbdeb..af99ef362 100644
--- a/src/live_effects/parameter/bool.cpp
+++ b/src/live_effects/parameter/bool.cpp
@@ -36,6 +36,12 @@ BoolParam::param_set_default()
param_setValue(defvalue);
}
+void
+BoolParam::param_update_default(bool const default_value)
+{
+ defvalue = default_value;
+}
+
bool
BoolParam::param_readSVGValue(const gchar * strvalue)
{
diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h
index 403dd0b87..7ad8a9368 100644
--- a/src/live_effects/parameter/bool.h
+++ b/src/live_effects/parameter/bool.h
@@ -36,7 +36,7 @@ public:
void param_setValue(bool newvalue);
virtual void param_set_default();
-
+ void param_update_default(bool const default_value);
bool get_value() const { return value; };
inline operator bool() const { return value; };
diff --git a/src/live_effects/parameter/enum.h b/src/live_effects/parameter/enum.h
index 2340663c3..dbfc68623 100644
--- a/src/live_effects/parameter/enum.h
+++ b/src/live_effects/parameter/enum.h
@@ -27,12 +27,14 @@ public:
const Util::EnumDataConverter<E>& c,
Inkscape::UI::Widget::Registry* wr,
Effect* effect,
- E default_value)
+ E default_value,
+ bool sort = true)
: Parameter(label, tip, key, wr, effect)
{
enumdataconv = &c;
defvalue = default_value;
value = defvalue;
+ sorted = sort;
};
virtual ~EnumParam() { };
@@ -40,12 +42,11 @@ public:
virtual Gtk::Widget * param_newWidget() {
Inkscape::UI::Widget::RegisteredEnum<E> *regenum = Gtk::manage (
new Inkscape::UI::Widget::RegisteredEnum<E>( param_label, param_tooltip,
- param_key, *enumdataconv, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) );
+ param_key, *enumdataconv, *param_wr, param_effect->getRepr(), param_effect->getSPDoc(), sorted ) );
regenum->set_active_by_id(value);
regenum->combobox()->setProgrammatically = false;
regenum->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change enumeration parameter"));
-
return dynamic_cast<Gtk::Widget *> (regenum);
};
@@ -86,6 +87,7 @@ private:
E value;
E defvalue;
+ bool sorted;
const Util::EnumDataConverter<E> * enumdataconv;
};
diff --git a/src/live_effects/parameter/fontbutton.cpp b/src/live_effects/parameter/fontbutton.cpp
new file mode 100644
index 000000000..ff8ab76a0
--- /dev/null
+++ b/src/live_effects/parameter/fontbutton.cpp
@@ -0,0 +1,92 @@
+/*
+ * Authors:
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+
+#include "ui/widget/registered-widget.h"
+#include "live_effects/parameter/fontbutton.h"
+#include "live_effects/effect.h"
+#include "ui/widget/font-button.h"
+#include "svg/svg.h"
+#include "svg/stringstream.h"
+#include "verbs.h"
+
+#include <glibmm/i18n.h>
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+FontButtonParam::FontButtonParam( const Glib::ustring& label, const Glib::ustring& tip,
+ const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+ Effect* effect, const Glib::ustring default_value )
+ : Parameter(label, tip, key, wr, effect),
+ value(default_value),
+ defvalue(default_value)
+{
+}
+
+void
+FontButtonParam::param_set_default()
+{
+ param_setValue(defvalue);
+}
+void
+FontButtonParam::param_update_default(const Glib::ustring default_value){
+ defvalue = default_value;
+}
+
+bool
+FontButtonParam::param_readSVGValue(const gchar * strvalue)
+{
+ Inkscape::SVGOStringStream os;
+ os << strvalue;
+ param_setValue((Glib::ustring)os.str());
+ return true;
+}
+
+gchar *
+FontButtonParam::param_getSVGValue() const
+{
+ return g_strdup(value.c_str());
+}
+
+Gtk::Widget *
+FontButtonParam::param_newWidget()
+{
+ Inkscape::UI::Widget::RegisteredFontButton * fontbuttonwdg = Gtk::manage(
+ new Inkscape::UI::Widget::RegisteredFontButton( param_label,
+ param_tooltip,
+ param_key,
+ *param_wr,
+ param_effect->getRepr(),
+ param_effect->getSPDoc() ) );
+ 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)
+{
+ value = newvalue;
+}
+
+} /* namespace LivePathEffect */
+
+} /* namespace Inkscape */
+
+/*
+ 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/live_effects/parameter/fontbutton.h b/src/live_effects/parameter/fontbutton.h
new file mode 100644
index 000000000..387ad130b
--- /dev/null
+++ b/src/live_effects/parameter/fontbutton.h
@@ -0,0 +1,62 @@
+#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_FONT_H
+#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_FONT_H
+
+/*
+ * Inkscape::LivePathEffectParameters
+ *
+ * Authors:
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#include <glib.h>
+#include <gtkmm.h>
+#include "live_effects/parameter/parameter.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+class FontButtonParam : public Parameter {
+public:
+ FontButtonParam( const Glib::ustring& label,
+ const Glib::ustring& tip,
+ const Glib::ustring& key,
+ Inkscape::UI::Widget::Registry* wr,
+ Effect* effect,
+ const Glib::ustring default_value = "");
+ virtual ~FontButtonParam() {}
+
+ virtual Gtk::Widget * param_newWidget();
+ virtual bool param_readSVGValue(const gchar * strvalue);
+ void param_update_default(const Glib::ustring defvalue);
+ virtual gchar * param_getSVGValue() const;
+
+ void param_setValue(const Glib::ustring newvalue);
+
+ virtual void param_set_default();
+
+ const Glib::ustring get_value() const { return defvalue; };
+
+private:
+ FontButtonParam(const FontButtonParam&);
+ FontButtonParam& operator=(const FontButtonParam&);
+ Glib::ustring value;
+ Glib::ustring defvalue;
+
+};
+
+} //namespace LivePathEffect
+
+} //namespace Inkscape
+
+#endif
+
+/*
+ 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/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp
index d4e213948..befac4df1 100644
--- a/src/live_effects/parameter/parameter.cpp
+++ b/src/live_effects/parameter/parameter.cpp
@@ -4,11 +4,9 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include "ui/widget/registered-widget.h"
-#include <glibmm/i18n.h>
-#include "live_effects/parameter/parameter.h"
#include "live_effects/effect.h"
+#include "live_effects/parameter/parameter.h"
#include "svg/svg.h"
#include "xml/repr.h"
@@ -16,6 +14,8 @@
#include "verbs.h"
+#include <glibmm/i18n.h>
+
#define noLPEREALPARAM_DEBUG
namespace Inkscape {
@@ -101,9 +101,16 @@ ScalarParam::param_set_default()
param_set_value(defvalue);
}
+void
+ScalarParam::param_update_default(gdouble default_value)
+{
+ defvalue = default_value;
+}
+
void
ScalarParam::param_set_value(gdouble val)
{
+ param_effect->upd_params = true;
value = val;
if (integer)
value = round(value);
@@ -121,7 +128,7 @@ 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 {
@@ -130,15 +137,15 @@ ScalarParam::param_set_range(gdouble min, gdouble max)
if (max <= SCALARPARAM_G_MAXDOUBLE) {
this->max = max;
} else {
- this->max = SCALARPARAM_G_MAXDOUBLE;
+ this->max = SCALARPARAM_G_MAXDOUBLE;
}
-
param_set_value(value); // reset value to see whether it is in ranges
}
void
ScalarParam::param_make_integer(bool yes)
{
+ param_effect->upd_params = true;
integer = yes;
digits = 0;
inc_step = 1;
@@ -169,6 +176,7 @@ 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;
@@ -178,12 +186,14 @@ 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 0ef28650a..3658bded8 100644
--- a/src/live_effects/parameter/parameter.h
+++ b/src/live_effects/parameter/parameter.h
@@ -12,6 +12,7 @@
#include <glibmm/ustring.h>
#include <2geom/forward.h>
#include <2geom/pathvector.h>
+#include "ui/widget/registered-widget.h"
// In gtk2, this wasn't an issue; we could toss around
// G_MAXDOUBLE and not worry about size allocations. But
@@ -110,12 +111,12 @@ public:
virtual gchar * param_getSVGValue() const;
virtual void param_set_default();
+ void param_update_default(gdouble default_value);
void param_set_value(gdouble val);
void param_make_integer(bool yes = true);
void param_set_range(gdouble min, gdouble max);
void param_set_digits(unsigned digits);
void param_set_increments(double step, double page);
-
void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; };
void param_overwrite_widget(bool overwrite_widget);
diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp
index ca3471b29..3442fd851 100644
--- a/src/live_effects/parameter/point.cpp
+++ b/src/live_effects/parameter/point.cpp
@@ -4,7 +4,6 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include "ui/widget/registered-widget.h"
#include "live_effects/parameter/point.h"
#include "live_effects/effect.h"
#include "svg/svg.h"
@@ -30,7 +29,8 @@ PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip,
: Parameter(label, tip, key, wr, effect),
defvalue(default_value),
liveupdate(live_update),
- knoth(NULL)
+ knoth(NULL),
+ _pointwdg(NULL)
{
knot_shape = SP_KNOT_SHAPE_DIAMOND;
knot_mode = SP_KNOT_MODE_XOR;
@@ -62,9 +62,9 @@ PointParam::param_get_default() const{
}
void
-PointParam::param_update_default(Geom::Point newpoint)
+PointParam::param_update_default(const Geom::Point default_point)
{
- defvalue = newpoint;
+ defvalue = default_point;
}
void
@@ -81,6 +81,9 @@ PointParam::param_setValue(Geom::Point newpoint, bool write)
if(knoth && liveupdate){
knoth->update_knots();
}
+ if (_pointwdg) {
+ _pointwdg->setValue( newpoint );
+ }
}
bool
@@ -116,7 +119,7 @@ PointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/)
Gtk::Widget *
PointParam::param_newWidget()
{
- Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage(
+ _pointwdg = Gtk::manage(
new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label,
param_tooltip,
param_key,
@@ -126,15 +129,15 @@ PointParam::param_newWidget()
// TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP)
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
Geom::Affine transf = desktop->doc2dt();
- 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);
}
@@ -191,13 +194,13 @@ void
PointParamKnotHolderEntity::knot_click(guint state)
{
if (state & GDK_CONTROL_MASK) {
- if (state & GDK_MOD1_MASK) {
- this->pparam->param_set_default();
- SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item);
- if(splpeitem){
- sp_lpe_item_update_patheffect(splpeitem, false, false);
- }
+ if (state & GDK_MOD1_MASK) {
+ this->pparam->param_set_default();
+ SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item);
+ if(splpeitem){
+ 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 4329e0bcd..62c6fb83d 100644
--- a/src/live_effects/parameter/point.h
+++ b/src/live_effects/parameter/point.h
@@ -11,7 +11,7 @@
#include <glib.h>
#include <2geom/point.h>
-
+#include "ui/widget/registered-widget.h"
#include "live_effects/parameter/parameter.h"
#include "knot-holder-entity.h"
@@ -43,7 +43,7 @@ public:
void param_set_default();
Geom::Point param_get_default() const;
void param_set_liveupdate(bool live_update);
- void param_update_default(Geom::Point newpoint);
+ void param_update_default(const Geom::Point default_point);
virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/);
void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color);
@@ -62,6 +62,7 @@ private:
SPKnotModeType knot_mode;
guint32 knot_color;
gchar *handle_tip;
+ Inkscape::UI::Widget::RegisteredTransformedPoint * _pointwdg;
};
diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp
index 234a6174d..0650b7e66 100644
--- a/src/live_effects/parameter/text.cpp
+++ b/src/live_effects/parameter/text.cpp
@@ -31,12 +31,16 @@ TextParam::TextParam( const Glib::ustring& label, const Glib::ustring& tip,
Effect* effect, const Glib::ustring default_value )
: Parameter(label, tip, key, wr, effect),
value(default_value),
- defvalue(default_value)
+ defvalue(default_value),
+ _hide_canvas_text(false)
{
- SPDesktop *desktop = SP_ACTIVE_DESKTOP; // FIXME: we shouldn't use this!
- canvas_text = (SPCanvasText *) sp_canvastext_new(desktop->getTempGroup(), desktop, Geom::Point(0,0), "");
- sp_canvastext_set_text (canvas_text, default_value.c_str());
- sp_canvastext_set_coords (canvas_text, 0, 0);
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { // FIXME: we shouldn't use this!
+ canvas_text = (SPCanvasText *) sp_canvastext_new(desktop->getTempGroup(), desktop, Geom::Point(0,0), "");
+ sp_canvastext_set_text (canvas_text, default_value.c_str());
+ sp_canvastext_set_coords (canvas_text, 0, 0);
+ } else {
+ _hide_canvas_text = true;
+ }
}
void
@@ -46,9 +50,26 @@ TextParam::param_set_default()
}
void
+TextParam::param_update_default(Glib::ustring default_value)
+{
+ defvalue = default_value;
+}
+
+void
+TextParam::param_hide_canvas_text()
+{
+ if (!_hide_canvas_text) {
+ sp_canvastext_set_text(canvas_text, " ");
+ _hide_canvas_text = true;
+ }
+}
+
+void
TextParam::setPos(Geom::Point pos)
{
- sp_canvastext_set_coords (canvas_text, pos);
+ if (!_hide_canvas_text) {
+ sp_canvastext_set_coords (canvas_text, pos);
+ }
}
void
@@ -63,9 +84,10 @@ TextParam::setPosAndAnchor(const Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2,
Point dir = unit_vector(derivative(pwd2_reparam).valueAt(t_reparam));
Point n = -rot90(dir);
double angle = Geom::angle_between(dir, Point(1,0));
-
- sp_canvastext_set_coords(canvas_text, pos + n * length);
- sp_canvastext_set_anchor_manually(canvas_text, std::sin(angle), -std::cos(angle));
+ if (!_hide_canvas_text) {
+ sp_canvastext_set_coords(canvas_text, pos + n * length);
+ sp_canvastext_set_anchor_manually(canvas_text, std::sin(angle), -std::cos(angle));
+ }
}
void
@@ -73,7 +95,9 @@ TextParam::setAnchor(double x_value, double y_value)
{
anchor_x = x_value;
anchor_y = y_value;
- sp_canvastext_set_anchor_manually (canvas_text, anchor_x, anchor_y);
+ if (!_hide_canvas_text) {
+ sp_canvastext_set_anchor_manually (canvas_text, anchor_x, anchor_y);
+ }
}
bool
@@ -94,8 +118,7 @@ TextParam::param_newWidget()
{
Inkscape::UI::Widget::RegisteredText *rsu = Gtk::manage(new Inkscape::UI::Widget::RegisteredText(
param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc()));
-
- rsu->setText(value.c_str());
+ rsu->setText(value);
rsu->setProgrammatically = false;
rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change text parameter"));
@@ -107,8 +130,9 @@ void
TextParam::param_setValue(const Glib::ustring newvalue)
{
value = newvalue;
-
- sp_canvastext_set_text (canvas_text, newvalue.c_str());
+ if (!_hide_canvas_text) {
+ sp_canvastext_set_text (canvas_text, newvalue.c_str());
+ }
}
} /* namespace LivePathEffect */
diff --git a/src/live_effects/parameter/text.h b/src/live_effects/parameter/text.h
index 62de70eec..553c84c0a 100644
--- a/src/live_effects/parameter/text.h
+++ b/src/live_effects/parameter/text.h
@@ -40,7 +40,9 @@ public:
virtual gchar * param_getSVGValue() const;
void param_setValue(const Glib::ustring newvalue);
+ void param_hide_canvas_text();
virtual void param_set_default();
+ void param_update_default(Glib::ustring 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);
@@ -53,7 +55,7 @@ private:
TextParam& operator=(const TextParam&);
double anchor_x;
double anchor_y;
-
+ bool _hide_canvas_text;
Glib::ustring value;
Glib::ustring defvalue;
diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp
index 023bebc03..b3f6442bb 100644
--- a/src/live_effects/parameter/togglebutton.cpp
+++ b/src/live_effects/parameter/togglebutton.cpp
@@ -12,6 +12,7 @@
#include "live_effects/effect.h"
#include "svg/svg.h"
#include "svg/stringstream.h"
+#include "selection.h"
#include "widgets/icon.h"
#include "inkscape.h"
#include "verbs.h"
@@ -104,13 +105,14 @@ ToggleButtonParam::param_newWidget()
}else{
gtk_box_pack_start (GTK_BOX(box_button), label_button, false, false, 1);
}
+
checkwdg->add(*Gtk::manage(Glib::wrap(box_button)));
checkwdg->setActive(value);
checkwdg->setProgrammatically = false;
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;
}
@@ -157,6 +159,12 @@ ToggleButtonParam::param_setValue(bool newvalue)
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();
+ }
_signal_toggled.emit();
}
diff --git a/src/live_effects/parameter/unit.cpp b/src/live_effects/parameter/unit.cpp
index 0ee553e2c..b6ea99bfe 100644
--- a/src/live_effects/parameter/unit.cpp
+++ b/src/live_effects/parameter/unit.cpp
@@ -54,6 +54,12 @@ UnitParam::param_set_default()
param_set_value(*defunit);
}
+void
+UnitParam::param_update_default(const Glib::ustring default_unit)
+{
+ defunit = unit_table.getUnit(default_unit);
+}
+
void
UnitParam::param_set_value(Inkscape::Util::Unit const &val)
{
diff --git a/src/live_effects/parameter/unit.h b/src/live_effects/parameter/unit.h
index 59a483018..ae58cf956 100644
--- a/src/live_effects/parameter/unit.h
+++ b/src/live_effects/parameter/unit.h
@@ -33,6 +33,7 @@ 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);
const gchar *get_abbreviation() const;
virtual Gtk::Widget * param_newWidget();
diff --git a/src/main-cmdlineact.cpp b/src/main-cmdlineact.cpp
index a23c036a0..03bf4083c 100644
--- a/src/main-cmdlineact.cpp
+++ b/src/main-cmdlineact.cpp
@@ -14,6 +14,7 @@
#include <verbs.h>
#include <inkscape.h>
#include <document.h>
+#include <file.h>
#include <glibmm/i18n.h>
@@ -23,8 +24,7 @@ namespace Inkscape {
std::list <CmdLineAction *> CmdLineAction::_list;
-CmdLineAction::CmdLineAction(bool isVerb, gchar const *arg) : _isVerb(isVerb), _arg(NULL)
-{
+CmdLineAction::CmdLineAction (bool isVerb, gchar const * arg) : _isVerb(isVerb), _arg(NULL) {
if (arg != NULL) {
_arg = g_strdup(arg);
}
@@ -34,58 +34,68 @@ CmdLineAction::CmdLineAction(bool isVerb, gchar const *arg) : _isVerb(isVerb), _
return;
}
-CmdLineAction::~CmdLineAction()
-{
+CmdLineAction::~CmdLineAction () {
if (_arg != NULL) {
g_free(_arg);
}
}
+bool
+CmdLineAction::isExtended() {
+ return false;
+}
+
void
-CmdLineAction::doIt(ActionContext const &context)
+CmdLineAction::doItX (ActionContext const & context)
{
+ (void)context;
+ printf("CmdLineAction::doItX() %s\n", _arg);
+}
+
+void
+CmdLineAction::doIt (ActionContext const & context) {
//printf("Doing: %s\n", _arg);
if (_isVerb) {
- Inkscape::Verb *verb = Inkscape::Verb::getbyid(_arg);
+ if (isExtended()) {
+ doItX(context);
+ return;
+ }
+
+ Inkscape::Verb * verb = Inkscape::Verb::getbyid(_arg);
if (verb == NULL) {
printf(_("Unable to find verb ID '%s' specified on the command line.\n"), _arg);
return;
}
- SPAction *action = verb->get_action(context);
+ SPAction * action = verb->get_action(context);
sp_action_perform(action, NULL);
} else {
- if (context.getDocument() == NULL || context.getSelection() == NULL) {
- return;
- }
+ if (context.getDocument() == NULL || context.getSelection() == NULL) { return; }
- SPDocument *doc = context.getDocument();
- SPObject *obj = doc->getObjectById(_arg);
+ SPDocument * doc = context.getDocument();
+ SPObject * obj = doc->getObjectById(_arg);
if (obj == NULL) {
printf(_("Unable to find node ID: '%s'\n"), _arg);
return;
}
- Inkscape::Selection *selection = context.getSelection();
+ Inkscape::Selection * selection = context.getSelection();
selection->add(obj);
}
return;
}
bool
-CmdLineAction::doList(ActionContext const &context)
-{
+CmdLineAction::doList (ActionContext const & context) {
bool hasActions = !_list.empty();
- for (std::list<CmdLineAction *>::iterator i = _list.begin();
- i != _list.end(); ++i) {
- CmdLineAction *entry = *i;
+ for (std::list<CmdLineAction *>::iterator i = _list.begin(); i != _list.end(); ++i) {
+ CmdLineAction * entry = *i;
entry->doIt(context);
}
return hasActions;
}
bool
-CmdLineAction::idle(void)
-{
+CmdLineAction::idle (void) {
std::list<SPDesktop *> desktops;
INKSCAPE.get_all_desktops(desktops);
@@ -93,8 +103,8 @@ CmdLineAction::idle(void)
// should have had time to make more at this point.
for (std::list<SPDesktop *>::iterator i = desktops.begin();
i != desktops.end(); ++i) {
- SPDesktop *desktop = *i;
- //Inkscape::UI::View::View * view = dynamic_cast<Inkscape::UI::View::View *>(desktop);
+ SPDesktop * desktop = *i;
+ //Inkscape::UI::View::View * view = dynamic_cast<Inkscape::UI::View::View *>(desktop);
doList(ActionContext(desktop));
}
return false;
diff --git a/src/main-cmdlineact.h b/src/main-cmdlineact.h
index 171313401..f50e70e5a 100644
--- a/src/main-cmdlineact.h
+++ b/src/main-cmdlineact.h
@@ -21,18 +21,23 @@ class ActionContext;
class CmdLineAction {
bool _isVerb;
- char *_arg;
-
static std::list <CmdLineAction *> _list;
+ static bool _requestQuit;
+
+protected:
+ char * _arg;
public:
- CmdLineAction(bool isVerb, char const *arg);
- virtual ~CmdLineAction();
+ CmdLineAction (bool isVerb, char const * arg);
+ virtual ~CmdLineAction ();
+ virtual bool isExtended();
+ virtual void doItX (ActionContext const & context);
+
+ void doIt (ActionContext const & context);
- void doIt(ActionContext const &context);
/** Return true if any actions were performed */
- static bool doList(ActionContext const &context);
- static bool idle(void);
+ static bool doList (ActionContext const & context);
+ static bool idle (void);
};
} // Inkscape
diff --git a/src/main-cmdlinexact.cpp b/src/main-cmdlinexact.cpp
new file mode 100644
index 000000000..99f0c699b
--- /dev/null
+++ b/src/main-cmdlinexact.cpp
@@ -0,0 +1,576 @@
+/*
+ * Authors:
+ * Dmitry Zhulanov <dmitry.zhulanov@gmail.com>
+ *
+ * Copyright (C) 2016 Authors
+ *
+ * Released under GNU GPL v2, read the file 'COPYING' for more information
+ *
+ * Format of xverbs.yaml
+ * using: $ inkscape -B xverbs.yaml
+ *
+ * verbose: yes # only "verbose: yes" enable logging
+ * run:
+ * # open document to process
+ * - xverb-id: XFileOpen, gfx_sources/loading_screen/sandclock_atlas.svg
+ * - xverb-id: XUndoLabel, fresh_document # set label for UndoToLabel xverb works
+ * # note: if something wrong with undo labels use verb EditUndo instead of XUndoLabel and UndoToLabel at all
+ *
+ * # select element to handle
+ * - xverb-id: XSelectElement, top_sand
+ *
+ * # verbs
+ * - verb-id: EditInvertInAllLayers
+ * - verb-id: EditDelete
+ * - verb-id: FitCanvasToDrawing
+ *
+ * # save element to separated svg document
+ * - xverb-id: XFileSaveAs, output/thegame/linux/data/gfx/loading_screen/top_sand.svg
+ *
+ * # also save png preview
+ * - xverb-id: XFileExportPNG, output/thegame/linux/data/gfx_preview/loading_screen/top_sand.png
+ *
+ * # return to the fresh_state of document
+ * - xverb-id: UndoToLabel, fresh_document
+ *
+ * # do any other handling
+ *
+ * # inkscape have a lot of useful verbs
+ * - verb-id: FileQuit
+ */
+#ifdef WITH_YAML
+#include <ui/view/view.h>
+#include <desktop.h>
+#include <helper/action.h>
+#include <helper/action-context.h>
+#include <selection.h>
+#include <verbs.h>
+#include <inkscape.h>
+
+#include <document.h>
+
+#include <glibmm/i18n.h>
+
+#include "main-cmdlinexact.h"
+
+#include "yaml.h"
+
+#include "extension/system.h"
+#include "file.h"
+#include <glib.h>
+#include "sp-root.h"
+#include "document-undo.h"
+#include "util/units.h"
+#include "sp-namedview.h"
+#include "resource-manager.h"
+#include "ui/dialog/font-substitution.h"
+#include "extension/db.h"
+#include "preferences.h"
+#include "helper/png-write.h"
+#include <document-undo.h>
+#include <ui/view/view-widget.h>
+#include <ui/interface.h>
+#include <verbs.h>
+
+#define DPI_BASE Inkscape::Util::Quantity::convert(1, "in", "px")
+
+namespace
+{
+bool s_verbose = false;
+
+bool createDirForFilename( const std::string &filename )
+{
+ size_t found = filename.find_last_of("/\\");
+ std::string output_directory = filename.substr(0,found);
+
+ if( output_directory == filename )
+ return true;
+
+ if (g_mkdir_with_parents(output_directory.c_str(), 0755)) {
+ printf("Can't create directory %s\n", output_directory.c_str());
+ fflush(stdout);
+
+ return false;
+ }
+
+ return true;
+}
+
+std::vector<std::string> vectorFromString(const std::string &csv)
+{
+ std::vector<std::string> result;
+
+ std::string delimiters = ",";
+
+ // Skip delimiters at beginning.
+ std::string::size_type lastPos = csv.find_first_not_of(delimiters, 0);
+
+ // Find first non-delimiter.
+ std::string::size_type pos = csv.find_first_of(delimiters, lastPos);
+
+ while (std::string::npos != pos || std::string::npos != lastPos) {
+ // Found a token, add it to the vector.
+ std::string token = csv.substr(lastPos, pos - lastPos);
+ token.erase(0, token.find_first_not_of(' ')); //prefixing spaces
+ token.erase(token.find_last_not_of(' ')+1); //surfixing spaces
+ result.push_back(token);
+
+ // Skip delimiters.
+ lastPos = csv.find_first_not_of(delimiters, pos);
+
+ // Find next non-delimiter.
+ pos = csv.find_first_of(delimiters, lastPos);
+ }
+
+ return result;
+}
+
+void xFileOpen( const Glib::ustring &uri )
+{
+ if (s_verbose) {
+ printf("open %s\n", uri.c_str());
+ fflush(stdout);
+ }
+
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (desktop) {
+ SPDocument *old_document = desktop->getDocument();
+ desktop->setWaitingCursor();
+ Inkscape::DocumentUndo::clearRedo(old_document);
+ }
+
+ SPDocument *doc = NULL;
+ Inkscape::Extension::Extension *key = NULL;
+ try {
+ doc = Inkscape::Extension::open(key, uri.c_str());
+ } catch (std::exception &e) {
+ doc = NULL;
+ std::string exeption_mgs = e.what();
+ printf("Error: open %s:%s\n",uri.c_str(), exeption_mgs.c_str() );
+ fflush(stdout);
+ }
+
+ // Set viewBox if it doesn't exist
+ if (!doc->getRoot()->viewBox_set
+ && (doc->getRoot()->width.unit != SVGLength::PERCENT)
+ && (doc->getRoot()->height.unit != SVGLength::PERCENT)) {
+ doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit())));
+ }
+
+ desktop->change_document(doc);
+ doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px"));
+ if(desktop)
+ desktop->clearWaitingCursor();
+
+ doc->virgin = FALSE;
+
+ // everyone who cares now has a reference, get rid of our`s
+ doc->doUnref();
+
+ // resize the window to match the document properties
+ sp_namedview_window_from_document(desktop);
+ sp_namedview_update_layers_from_document(desktop);
+
+ if ( INKSCAPE.use_gui() ) {
+ // Perform a fixup pass for hrefs.
+ if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(doc) ) {
+ Glib::ustring msg = _("Broken links have been changed to point to existing files.");
+ desktop->showInfoDialog(msg);
+ }
+
+ // Check for font substitutions
+ Inkscape::UI::Dialog::FontSubstitution::getInstance().checkFontSubstitutions(doc);
+ }
+}
+
+void xFileSaveAs( Inkscape::ActionContext const & context, const Glib::ustring &uri )
+{
+ SPDocument *doc = context.getDocument();
+ if (s_verbose) {
+ printf("save as %s\n", uri.c_str());
+ fflush(stdout);
+ }
+
+ if( createDirForFilename( uri )) {
+ Inkscape::Extension::save(
+ Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"),
+ doc, uri.c_str(), false, false, true, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS);
+ if (s_verbose) {
+ printf("save done: %s\n", uri.c_str() );
+ fflush(stdout);
+ }
+ }
+ else {
+ printf("can't create dirs for filename %s\n", uri.c_str() );
+ fflush(stdout);
+ }
+}
+
+void xFileExportPNG( Inkscape::ActionContext const & context, const Glib::ustring &uri )
+{
+ if (s_verbose) {
+ printf("export png %s\n", uri.c_str());
+ fflush(stdout);
+ }
+
+ SPDocument *doc = context.getDocument();
+
+ gdouble dpi = 200.0;
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ dpi = prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE);
+
+ gdouble width = doc->getWidth().value(doc->getDisplayUnit());
+ gdouble height = doc->getHeight().value(doc->getDisplayUnit());
+
+ gdouble bmwidth = (width) * dpi / DPI_BASE;
+ gdouble bmheight = (height) * dpi / DPI_BASE;
+
+ int png_width = (int)(0.5 + bmwidth);
+ int png_height = (int)(0.5 + bmheight);
+
+ SPNamedView *nv = desktop->getNamedView();
+
+ ExportResult status = sp_export_png_file(doc, uri.c_str(),
+ Geom::Rect(Geom::Point(0,0), Geom::Point(width, height)), png_width, png_height, dpi, dpi,
+ nv->pagecolor, 0, 0, TRUE);
+}
+
+void xSelectElement( Inkscape::ActionContext const & context, const Glib::ustring &uri )
+{
+ if (context.getDocument() == NULL || context.getSelection() == NULL) {
+ return;
+ }
+
+ if (s_verbose) {
+ printf("select element: %s\n", uri.c_str());
+ fflush(stdout);
+ }
+
+ SPDocument * doc = context.getDocument();
+ SPObject * obj = doc->getObjectById(uri);
+
+ if (obj == NULL) {
+ printf(_("Unable to find node ID: '%s'\n"), uri.c_str());
+ fflush(stdout);
+ return;
+ }
+
+ Inkscape::Selection * selection = context.getSelection();
+ selection->add(obj);
+
+ if (s_verbose) {
+ printf("select done %s\n", uri.c_str());
+ fflush(stdout);
+ }
+}
+
+} // end of unnamed namespace
+
+namespace Inkscape {
+
+CmdLineXAction::CmdLineXAction (gchar const * arg, xaction_args_values_map_t &values_map):
+ CmdLineAction(true, arg), _values_map(values_map) {
+ this->arg = (char *)arg;
+ return;
+}
+
+bool
+CmdLineXAction::isExtended() {
+ return true;
+}
+
+void
+CmdLineXAction::doItX (ActionContext const & context) {
+ (void)(context);
+
+ if( arg == "XFileSaveAs")
+ xFileSaveAs( context, _values_map["filename"] );
+ else if (arg == "XFileOpen")
+ xFileOpen( _values_map["filename"] );
+ else if (arg == "XFileExportPNG")
+ xFileExportPNG( context, _values_map["png_filename"] );
+ else if (arg == "XSelectElement")
+ xSelectElement( context, _values_map["element-id"] );
+ else {
+ printf("unknown xverb: %s", arg.c_str());
+ fflush(stdout);
+ }
+
+ return;
+}
+
+enum parser_state_t { HANDLING_ROOT,
+ HANDLING_VERBOSE, // options
+ HANDLING_RUN, HANDLING_RUN_LIST, HANDLING_RUN_LIST_ENTRY
+ }; // run entries
+
+struct verb_info_t
+{
+ bool xverb;
+ std::vector<std::string> args;
+};
+
+typedef std::list<verb_info_t> verbs_list_t;
+
+static verbs_list_t
+parseVerbsYAMLFile(gchar const *yaml_filename)
+{
+ verbs_list_t verbs_list;
+
+ FILE *fh = fopen(yaml_filename, "r");
+ if(fh == NULL) {
+ printf("Failed to open file!\n");
+ fflush(stdout);
+ return verbs_list;
+ }
+
+ yaml_parser_t parser;
+ if(!yaml_parser_initialize(&parser)) {
+ printf("Failed to initialize parser!\n");
+ fflush(stdout);
+ return verbs_list;
+ }
+
+ /* Set input file */
+ yaml_parser_set_input_file(&parser, fh);
+
+ parser_state_t state = HANDLING_ROOT;
+
+ bool handling_key = false;
+ bool handling_value = false;
+
+ std::string key;
+
+ // parse
+ yaml_token_t token;
+ do {
+ yaml_parser_scan(&parser, &token);
+ switch(token.type)
+ {
+ // avoid "warning: enumeration value", "-Wswitch"
+ case YAML_NO_TOKEN:
+ break;
+ case YAML_STREAM_START_TOKEN:
+ break;
+ case YAML_STREAM_END_TOKEN:
+ break;
+ case YAML_VERSION_DIRECTIVE_TOKEN:
+ break;
+ case YAML_TAG_DIRECTIVE_TOKEN:
+ break;
+ case YAML_DOCUMENT_START_TOKEN:
+ break;
+ case YAML_DOCUMENT_END_TOKEN:
+ break;
+ case YAML_FLOW_SEQUENCE_START_TOKEN:
+ break;
+ case YAML_FLOW_SEQUENCE_END_TOKEN:
+ break;
+ case YAML_FLOW_MAPPING_START_TOKEN:
+ break;
+ case YAML_FLOW_MAPPING_END_TOKEN:
+ break;
+ case YAML_FLOW_ENTRY_TOKEN:
+ break;
+ case YAML_ALIAS_TOKEN:
+ break;
+ case YAML_ANCHOR_TOKEN:
+ break;
+ case YAML_TAG_TOKEN:
+ break;
+
+ /* Token types (read before actual token) */
+ case YAML_KEY_TOKEN:
+ handling_key = true;
+ handling_value = false;
+ break;
+ case YAML_VALUE_TOKEN:
+ handling_key = false;
+ handling_value = true;
+ break;
+
+ /* Block delimeters */
+ case YAML_BLOCK_SEQUENCE_START_TOKEN:
+ if( state == HANDLING_ROOT ) {
+ if( key == "run" )
+ state = HANDLING_RUN;
+ }
+ break;
+ case YAML_BLOCK_ENTRY_TOKEN:
+ if( state == HANDLING_RUN )
+ state = HANDLING_RUN_LIST;
+ else if( state == HANDLING_RUN_LIST )
+ state = HANDLING_RUN_LIST_ENTRY;
+ else if( state == HANDLING_VERBOSE )
+ state = HANDLING_ROOT;
+ break;
+ case YAML_BLOCK_END_TOKEN:
+ if( state == HANDLING_RUN_LIST_ENTRY )
+ state = HANDLING_RUN_LIST;
+ else if( state == HANDLING_RUN_LIST )
+ state = HANDLING_RUN;
+ else if( state == HANDLING_VERBOSE )
+ state = HANDLING_ROOT;
+ else if( state == HANDLING_RUN )
+ state = HANDLING_ROOT;
+ break;
+
+ /* Data */
+ case YAML_BLOCK_MAPPING_START_TOKEN:
+ break;
+ case YAML_SCALAR_TOKEN:
+ if( handling_key )
+ key = (char *)token.data.scalar.value;
+ else if ( handling_value ) {
+ if(state == HANDLING_RUN_LIST) {
+ if(key == "xverb-id") {
+ verb_info_t verb;
+ verb.xverb = true;
+ verb.args = vectorFromString((char *)token.data.scalar.value);
+ if ((verb.args.size() > 1) && Verb::getbyid((char *)token.data.scalar.value, false))
+ verb.xverb = false;
+ verbs_list.push_back(verb);
+ }
+ else if(key == "verb-id") {
+ verb_info_t verb;
+ verb.xverb = false;
+ verb.args = vectorFromString((char *)token.data.scalar.value);
+ verbs_list.push_back(verb);
+ }
+ else {
+ printf("unknown verb type [%s]\n", key.c_str());
+ fflush(stdout);
+ }
+ }
+ else if(state == HANDLING_ROOT) {
+ std::string value = (char *)token.data.scalar.value;
+ if( (key == "verbose") && (value == "yes") )
+ s_verbose = true;
+ }
+ }
+ break;
+ }
+ } while(token.type != YAML_STREAM_END_TOKEN);
+
+ /* Cleanup */
+ yaml_token_delete(&token);
+ yaml_parser_delete(&parser);
+ fclose(fh);
+
+ return verbs_list;
+}
+
+void
+CmdLineXAction::createActionsFromYAML( gchar const *yaml_filename )
+{
+ verbs_list_t verbs_list = parseVerbsYAMLFile(yaml_filename);
+
+ typedef std::map<std::string,int> undo_labels_map_t;
+ undo_labels_map_t undo_labels_map;
+ int undo_counter = 0;
+
+ verbs_list_t::iterator iter = verbs_list.begin();
+ for (; iter != verbs_list.end(); ++iter) {
+ verb_info_t &verb = *iter;
+ std::string &verb_word = verb.args[0];
+ if (s_verbose)
+ printf("handle %s and args count is %d\n", verb_word.c_str(), (int)verb.args.size());
+
+ if (verb_word == "XFileOpen") {
+ if( verb.args.size() < 2 )
+ {
+ printf("bad arguments for XFileOpen\n");
+ continue;
+ }
+
+ xaction_args_values_map_t values_map;
+ values_map["filename"] = verb.args[1];
+ new CmdLineXAction(verb_word.c_str(), values_map);
+ } else if (verb_word == "XFileSaveAs")
+ {
+ if (verb.args.size() < 2) {
+ printf("bad arguments for XFileSaveAs\n");
+ continue;
+ }
+
+ xaction_args_values_map_t values_map;
+ values_map["filename"] = verb.args[1];
+ new CmdLineXAction(verb_word.c_str(), values_map);
+ } else if (verb_word == "XUndoLabel") {
+ if (verb.args.size() < 2) {
+ printf("bad arguments for XUndoLabel\n");
+ continue;
+ }
+ undo_labels_map[verb.args[1]] = undo_counter;
+ } else if (verb_word == "UndoToLabel") {
+ if (verb.args.size() < 2) {
+ printf("bad arguments for UndoToLabel\n");
+ continue;
+ }
+
+ undo_labels_map_t::iterator iter = undo_labels_map.find(verb.args[1]);
+ if(iter != undo_labels_map.end()) {
+ int counter = undo_counter - iter->second;
+ if( counter > 0 ) {
+ for(int i = 0; i < counter; ++i)
+ new CmdLineAction(true, "EditUndo");
+ undo_counter -= counter;
+ }
+ }
+ } else if (verb_word == "XSelectElement") {
+ if (verb.args.size() < 2) {
+ printf("bad arguments for XSelectElement\n");
+ continue;
+ }
+ ++undo_counter;
+
+ xaction_args_values_map_t values_map;
+ values_map["element-id"] = verb.args[1];
+ new CmdLineXAction(verb_word.c_str(), values_map);
+ } else if (verb_word == "XFileExportPNG") {
+ if (verb.args.size() < 2) {
+ printf("bad arguments for XFileExportPNG\n");
+ continue;
+ }
+
+ xaction_args_values_map_t values_map;
+ std::string &png_filename = verb.args[1];
+ values_map["png_filename"] = png_filename;
+ if(createDirForFilename( png_filename ))
+ new CmdLineXAction(verb_word.c_str(), values_map);
+ }
+ else if(!verb.xverb) {
+ ++undo_counter;
+ new CmdLineAction(true, verb.args[0].c_str());
+ }
+ else if( Verb::getbyid(verb.args[0].c_str()) != NULL )
+ {
+ ++undo_counter;
+ new CmdLineAction(true, verb.args[0].c_str());
+ }
+ else {
+ printf("Unhadled xverb %s\n", verb.args[0].c_str());
+ fflush(stdout);
+ }
+ }
+
+ fflush(stdout);
+}
+
+
+} // Inkscape
+
+#endif // WITH_YAML
+
+/*
+ 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/main-cmdlinexact.h b/src/main-cmdlinexact.h
new file mode 100644
index 000000000..8634f3875
--- /dev/null
+++ b/src/main-cmdlinexact.h
@@ -0,0 +1,54 @@
+
+#ifndef __INK_MAIN_CMD_LINE_XACTIONS_H__
+#define __INK_MAIN_CMD_LINE_XACTIONS_H__
+
+#ifdef WITH_YAML
+
+/** \file
+ * Extended actions that can be queued at the yaml file
+ */
+
+/*
+ * Authors:
+ * Dmitry Zhulanov <dmitry.zhulanov@gmail.com>
+ *
+ * Copyright (C) 2016 Authors
+ *
+ * Released under GNU GPL v2.x, read the file 'COPYING' for more information
+ */
+
+#include "main-cmdlineact.h"
+#include <string>
+
+namespace Inkscape {
+
+typedef std::map<std::string, std::string > xaction_args_values_map_t;
+
+class CmdLineXAction : public CmdLineAction {
+ std::string arg;
+ xaction_args_values_map_t _values_map;
+public:
+ CmdLineXAction (gchar const * arg, xaction_args_values_map_t &values_map);
+
+ virtual void doItX (ActionContext const & context);
+ virtual bool isExtended();
+
+ static void createActionsFromYAML( gchar const *filename );
+};
+
+} // Inkscape
+
+
+#endif // WITH_YAML
+#endif /* __INK_MAIN_CMD_LINE_XACTIONS_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/main.cpp b/src/main.cpp
index 004d96191..0d5f35797 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -112,6 +112,7 @@
#endif
#include "main-cmdlineact.h"
+#include "main-cmdlinexact.h"
#include "widgets/icon.h"
#include <errno.h>
@@ -127,6 +128,7 @@ enum {
SP_ARG_NOGUI,
SP_ARG_GUI,
SP_ARG_FILE,
+ SP_ARG_XVERBS,
SP_ARG_PRINT,
SP_ARG_EXPORT_PNG,
SP_ARG_EXPORT_DPI,
@@ -227,6 +229,11 @@ static gchar *sp_export_png_utf8 = NULL;
static gchar *sp_export_svg_utf8 = NULL;
static gchar *sp_global_printer_utf8 = NULL;
+#ifdef WITH_YAML
+static gchar *sp_xverbs_yaml_utf8 = NULL;
+static gchar *sp_xverbs_yaml = NULL;
+#endif // WITH_YAML
+
/**
* Reset variables to default values.
@@ -300,7 +307,12 @@ struct poptOption options[] = {
POPT_ARG_STRING, NULL, SP_ARG_FILE,
N_("Open specified document(s) (option string may be excluded)"),
N_("FILENAME")},
-
+#ifdef WITH_YAML
+ {"xverbs", 0,
+ POPT_ARG_STRING, &sp_xverbs_yaml, SP_ARG_XVERBS,
+ N_("xverbs command"),
+ N_("XVERBS_FILENAME")},
+#endif // WITH_YAML
{"print", 'p',
POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT,
N_("Print document(s) to specified output file (use '| program' for pipe)"),
@@ -881,6 +893,9 @@ 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_global_printer, &sp_global_printer_utf8 );
+#ifdef WITH_YAML
+ fixupSingleFilename( &sp_xverbs_yaml, &sp_xverbs_yaml_utf8 );
+#endif // WITH_YAML
}
else
{
@@ -890,6 +905,10 @@ static int sp_common_main( int argc, char const **argv, GSList **flDest )
sp_export_svg_utf8 = g_strdup( sp_export_svg );
if ( sp_global_printer )
sp_global_printer_utf8 = g_strdup( sp_global_printer );
+#ifdef WITH_YAML
+ if ( sp_xverbs_yaml )
+ sp_xverbs_yaml_utf8 = g_strdup( sp_xverbs_yaml );
+#endif // WITH_YAML
}
#ifdef WITH_DBUS
@@ -2131,6 +2150,16 @@ sp_process_args(poptContext ctx)
}
break;
}
+#ifdef WITH_YAML
+ case SP_ARG_XVERBS: {
+ gchar const *fn = poptGetOptArg(ctx);
+ if (fn != NULL) {
+ sp_xverbs_yaml = g_strdup(fn);
+ Inkscape::CmdLineXAction::createActionsFromYAML((const char *)sp_xverbs_yaml);
+ }
+ break;
+ }
+#endif // WITH_YAML
case SP_ARG_VERSION: {
printf("Inkscape %s (%s)\n", Inkscape::version_string, __DATE__);
exit(0);
diff --git a/src/selection.h b/src/selection.h
index 4ea70c38d..cf00ba1f4 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -134,6 +134,7 @@ public:
*/
void setReprList(std::vector<XML::Node*> const &reprs);
+
using ObjectSet::includes;
/**
@@ -166,6 +167,7 @@ public:
*
* @return the resulting connection
*/
+ void emitModified(){ _emitModified(this->_flags); };
sigc::connection connectChanged(sigc::slot<void, Selection *> const &slot) {
return _changed_signal.connect(slot);
}
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index d161562fd..f52784489 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -76,7 +76,6 @@ SPItem::SPItem() : SPObject() {
transform_center_y = 0;
freeze_stroke_width = false;
-
_is_evaluated = true;
_evaluated_status = StatusUnknown;
@@ -1409,7 +1408,6 @@ Geom::Affine SPItem::set_transform(Geom::Affine const &transform) {
void SPItem::doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &transform, Geom::Affine const *adv, bool compensate)
{
g_return_if_fail(repr != NULL);
-
// calculate the relative transform, if not given by the adv attribute
Geom::Affine advertized_transform;
if (adv != NULL) {
diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp
index d39540cd9..c4247bd5a 100644
--- a/src/sp-lpe-item.cpp
+++ b/src/sp-lpe-item.cpp
@@ -73,6 +73,7 @@ void SPLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) {
void SPLPEItem::release() {
// disconnect all modified listeners:
+
for (std::list<sigc::connection>::iterator mod_it = this->lpe_modified_connection_list->begin();
mod_it != this->lpe_modified_connection_list->end(); ++mod_it)
{
@@ -83,7 +84,7 @@ void SPLPEItem::release() {
this->lpe_modified_connection_list = NULL;
PathEffectList::iterator it = this->path_effect_list->begin();
-
+
while ( it != this->path_effect_list->end() ) {
// unlink and delete all references in the list
(*it)->unlink();
@@ -121,8 +122,10 @@ void SPLPEItem::set(unsigned int key, gchar const* value) {
while ( it != this->path_effect_list->end() )
{
+ LivePathEffectObject *lpeobj = (*it)->lpeobject;
+ lpeobj->get_lpe()->doOnRemove(this);
(*it)->unlink();
- delete *it;
+ delete (*it);
it = this->path_effect_list->erase(it);
}
diff --git a/src/sp-object.cpp b/src/sp-object.cpp
index da4367d5b..cbd7aa969 100644
--- a/src/sp-object.cpp
+++ b/src/sp-object.cpp
@@ -485,13 +485,16 @@ void SPObject::_sendDeleteSignalRecursive() {
void SPObject::deleteObject(bool propagate, bool propagate_descendants)
{
sp_object_ref(this, NULL);
+ if ( SP_IS_LPE_ITEM(this) ) {
+ SP_LPE_ITEM(this)->removeAllPathEffects(false);
+ }
if (propagate) {
_delete_signal.emit(this);
}
if (propagate_descendants) {
this->_sendDeleteSignalRecursive();
}
-
+
Inkscape::XML::Node *repr = getRepr();
if (repr && repr->parent()) {
sp_repr_unparent(repr);
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 9e641edc3..f2a256698 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -128,6 +128,7 @@ set(ui_SRC
widget/entity-entry.cpp
widget/entry.cpp
widget/filter-effect-chooser.cpp
+ widget/font-button.cpp
widget/font-variants.cpp
widget/frame.cpp
widget/highlight-picker.cpp
@@ -312,6 +313,7 @@ set(ui_SRC
widget/entity-entry.h
widget/entry.h
widget/filter-effect-chooser.h
+ widget/font-button.h
widget/font-variants.h
widget/frame.h
widget/highlight-picker.h
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index a0cd786dc..f657e1b76 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -860,6 +860,17 @@ public:
return dss;
}
+ // SpinButton
+ SpinButtonAttr* add_spinbutton(double defalt_value, const SPAttributeEnum attr, const Glib::ustring& label,
+ const double lo, const double hi, const double step_inc,
+ const double climb, const int digits, char* tip = NULL)
+ {
+ SpinButtonAttr* sb = new SpinButtonAttr(lo, hi, step_inc, climb, digits, attr, defalt_value, tip);
+ add_widget(sb, label);
+ add_attr_widget(sb);
+ return sb;
+ }
+
// DualSpinButton
DualSpinButton* add_dualspinbutton(char* defalt_value, const SPAttributeEnum attr, const Glib::ustring& label,
const double lo, const double hi, const double step_inc,
@@ -2785,8 +2796,14 @@ void FilterEffectsDialog::init_settings_widgets()
_settings->type(NR_FILTER_IMAGE);
_settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image:"));
-
+ _image_x = _settings->add_entry(SP_ATTR_X,_("X"),_("X"));
+ _image_x->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::image_x_changed));
+ //This commented because we want the default empty value of X or Y and couldent get it from SpinButton
+ //_image_y = _settings->add_spinbutton(0, SP_ATTR_Y, _("Y:"), -DBL_MAX, DBL_MAX, 1, 1, 5, _("Y"));
+ _image_y = _settings->add_entry(SP_ATTR_Y,_("Y"),_("Y"));
+ _image_y->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::image_y_changed));
_settings->type(NR_FILTER_OFFSET);
+ _settings->add_checkbutton(false, SP_ATTR_PRESERVEALPHA, _("Preserve Alpha"), "true", "false", _("If set, the alpha channel won't be altered by this filter primitive."));
_settings->add_spinscale(0, SP_ATTR_DX, _("Delta X:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right"));
_settings->add_spinscale(0, SP_ATTR_DY, _("Delta Y:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards"));
@@ -2926,6 +2943,33 @@ void FilterEffectsDialog::convolve_order_changed()
_convolve_target->get_spinbuttons()[1]->get_adjustment()->set_upper(_convolve_order->get_spinbutton2().get_value() - 1);
}
+bool number_or_empy(const Glib::ustring& text) {
+ if (text.empty()) {
+ return true;
+ }
+ double n = atof( text.c_str() );
+ if (n == 0.0 && strcmp(text.c_str(), "0") != 0 && strcmp(text.c_str(), "0.0") != 0) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+void FilterEffectsDialog::image_x_changed()
+{
+ if (number_or_empy(_image_x->get_text())) {
+ _image_x->set_from_attribute(_primitive_list.get_selected());
+ }
+}
+
+void FilterEffectsDialog::image_y_changed()
+{
+ if (number_or_empy(_image_y->get_text())) {
+ _image_y->set_from_attribute(_primitive_list.get_selected());
+ }
+}
+
void FilterEffectsDialog::set_attr_direct(const AttrWidget* input)
{
set_attr(_primitive_list.get_selected(), input->get_attribute(), input->get_as_attribute().c_str());
diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h
index eae0fc317..32fabb741 100644
--- a/src/ui/dialog/filter-effects-dialog.h
+++ b/src/ui/dialog/filter-effects-dialog.h
@@ -35,6 +35,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
+class EntryAttr;
+//class SpinButtonAttr;
class DualSpinButton;
class MultiSpinButton;
class FilterEffectsDialog : public UI::Widget::Panel {
@@ -258,6 +260,8 @@ private:
void remove_primitive();
void duplicate_primitive();
void convolve_order_changed();
+ void image_x_changed();
+ void image_y_changed();
void set_attr_direct(const UI::Widget::AttrWidget*);
void set_child_attr_direct(const UI::Widget::AttrWidget*);
@@ -308,6 +312,10 @@ private:
DualSpinButton* _convolve_order;
MultiSpinButton* _convolve_target;
+ // Image
+ EntryAttr* _image_x;
+ EntryAttr* _image_y;
+
// For controlling setting sensitivity
Gtk::Widget* _k1, *_k2, *_k3, *_k4;
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 459d8d4ee..73f8debd6 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -52,7 +52,7 @@ void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data
{
LivePathEffectEditor *lpeeditor = static_cast<LivePathEffectEditor *>(data);
lpeeditor->lpe_list_locked = false;
- lpeeditor->onSelectionChanged(selection);
+ lpeeditor->onSelectionChanged(selection, true);
}
static void lpeeditor_selection_modified (Inkscape::Selection * selection, guint /*flags*/, gpointer data)
@@ -89,7 +89,8 @@ LivePathEffectEditor::LivePathEffectEditor()
button_up(),
button_down(),
current_desktop(NULL),
- current_lpeitem(NULL)
+ current_lpeitem(NULL),
+ current_lperef(NULL)
{
Gtk::Box *contents = _getContents();
contents->set_spacing(4);
@@ -190,6 +191,10 @@ LivePathEffectEditor::~LivePathEffectEditor()
void
LivePathEffectEditor::showParams(LivePathEffect::Effect& effect)
{
+ if ( ! effect.upd_params ) {
+ return;
+ }
+
if (effectwidget) {
effectcontrol_vbox.remove(*effectwidget);
delete effectwidget;
@@ -249,9 +254,8 @@ LivePathEffectEditor::set_sensitize_all(bool sensitive)
button_down.set_sensitive(sensitive);
}
-
void
-LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
+LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel, bool upd_params)
{
if (lpe_list_locked) {
// this was triggered by selecting a row in the list, so skip reloading
@@ -275,6 +279,9 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
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);
@@ -478,6 +485,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);
DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
@@ -532,11 +545,17 @@ void LivePathEffectEditor::on_effect_selection_changed()
Gtk::TreeModel::iterator it = sel->get_selected();
LivePathEffect::LPEObjectReference * lperef = (*it)[columns.lperef];
- if (lperef && current_lpeitem) {
+ if (lperef && current_lpeitem && current_lperef != lperef) {
+ //The last condition ignore Gtk::TreeModel may occasionally be changed emitted when nothing has happened
if (lperef->lpeobject->get_lpe()) {
lpe_list_locked = true; // prevent reload of the list which would lose selection
current_lpeitem->setCurrentPathEffect(lperef);
- showParams(*lperef->lpeobject->get_lpe());
+ current_lperef = lperef;
+ LivePathEffect::Effect * effect = lperef->lpeobject->get_lpe();
+ if (effect) {
+ effect->upd_params = true;
+ showParams(*effect);
+ }
}
}
}
@@ -554,6 +573,14 @@ void LivePathEffectEditor::on_visibility_toggled( Glib::ustring const& str )
/* FIXME: this explicit writing to SVG is wrong. The lpe_item should have a method to disable/enable an effect within its stack.
* So one can call: lpe_item->setActive(lpeobjref->lpeobject); */
lpeobjref->lpeobject->get_lpe()->getRepr()->setAttribute("is_visible", newValue ? "true" : "false");
+ Inkscape::Selection *sel = _getSelection();
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
+ SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
+ if ( lpeitem ) {
+ lpeobjref->lpeobject->get_lpe()->doOnVisibilityToggled(lpeitem);
+ }
+ }
DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
newValue ? _("Activate path effect") : _("Deactivate path effect"));
}
diff --git a/src/ui/dialog/livepatheffect-editor.h b/src/ui/dialog/livepatheffect-editor.h
index b69ee007a..a7c749ef3 100644
--- a/src/ui/dialog/livepatheffect-editor.h
+++ b/src/ui/dialog/livepatheffect-editor.h
@@ -45,7 +45,8 @@ public:
static LivePathEffectEditor &getInstance() { return *new LivePathEffectEditor(); }
- void onSelectionChanged(Inkscape::Selection *sel);
+ void onSelectionChanged(Inkscape::Selection *sel, bool upd_params = false);
+ void onSelectionModified(Inkscape::Selection *sel);
virtual void on_effect_selection_changed();
void setDesktop(SPDesktop *desktop);
@@ -63,15 +64,15 @@ private:
sigc::connection selection_changed_connection;
sigc::connection selection_modified_connection;
+ // void add_entry(const char* name );
+ void effect_list_reload(SPLPEItem *lpeitem);
+
void set_sensitize_all(bool sensitive);
void showParams(LivePathEffect::Effect& effect);
void showText(Glib::ustring const &str);
void selectInList(LivePathEffect::Effect* effect);
- // void add_entry(const char* name );
- void effect_list_reload(SPLPEItem *lpeitem);
-
// callback methods for buttons on grids page.
void onAdd();
void onRemove();
@@ -122,6 +123,8 @@ private:
SPLPEItem * current_lpeitem;
+ LivePathEffect::LPEObjectReference * current_lperef;
+
friend void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data);
LivePathEffectEditor(LivePathEffectEditor const &d);
diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp
index 38c72cac0..12686160b 100644
--- a/src/ui/tools/eraser-tool.cpp
+++ b/src/ui/tools/eraser-tool.cpp
@@ -766,9 +766,17 @@ void EraserTool::set_to_accumulated() {
if (bbox && bbox->intersects(*eraserBbox)) {
SPClipPath *clip_path = item->clip_ref->getObject();
if (clip_path) {
- SPPath *clip_data = SP_PATH(clip_path->firstChild());
+ std::vector<SPItem*> selected;
+ selected.push_back(SP_ITEM(clip_path->firstChild()));
+ std::vector<Inkscape::XML::Node*> to_select;
+ std::vector<SPItem*> items(selected);
+ sp_item_list_to_curves(items, selected, to_select);
+ Inkscape::XML::Node * clip_data = SP_ITEM(clip_path->firstChild())->getRepr();
+ if (!clip_data && !to_select.empty()) {
+ clip_data = *(to_select.begin());
+ }
if (clip_data) {
- Inkscape::XML::Node *dup_clip = SP_OBJECT(clip_data)->getRepr()->duplicate(xml_doc);
+ Inkscape::XML::Node *dup_clip = clip_data->duplicate(xml_doc);
if (dup_clip) {
SPItem * dup_clip_obj = SP_ITEM(item_repr->parent->appendChildRepr(dup_clip));
if (dup_clip_obj) {
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index c941b9bee..f3185649b 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -378,6 +378,10 @@ MeasureTool::~MeasureTool()
sp_canvas_item_destroy(measure_tmp_items[idx]);
}
measure_tmp_items.clear();
+ for (size_t idx = 0; idx < measure_item.size(); ++idx) {
+ sp_canvas_item_destroy(measure_item[idx]);
+ }
+ measure_item.clear();
for (size_t idx = 0; idx < measure_phantom_items.size(); ++idx) {
sp_canvas_item_destroy(measure_phantom_items[idx]);
}
@@ -591,6 +595,12 @@ bool MeasureTool::root_handler(GdkEvent* event)
snap_manager.preSnap(scp);
snap_manager.unSetup();
}
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ if(event->motion.state & GDK_SHIFT_MASK) {
+ showInfoBox(motion_w, true);
+ } else {
+ showInfoBox(motion_w, false);
+ }
} else {
ret = TRUE;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -1111,6 +1121,108 @@ void MeasureTool::setMeasureCanvasControlLine(Geom::Point start, Geom::Point end
}
}
+void MeasureTool::showItemInfoText(Geom::Point pos, gchar *measure_str, double fontsize)
+{
+ SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
+ desktop,
+ pos,
+ measure_str);
+ sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
+ canvas_tooltip->rgba = 0xffffffff;
+ canvas_tooltip->outline = false;
+ canvas_tooltip->background = true;
+ canvas_tooltip->anchor_position = TEXT_ANCHOR_LEFT;
+ canvas_tooltip->rgba_background = 0x00000099;
+ measure_item.push_back(SP_CANVAS_ITEM(canvas_tooltip));
+ sp_canvas_item_show(SP_CANVAS_ITEM(canvas_tooltip));
+}
+
+void MeasureTool::showInfoBox(Geom::Point cursor, bool into_groups)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Inkscape::Util::Unit const * unit = desktop->getNamedView()->getDisplayUnit();
+ for (size_t idx = 0; idx < measure_item.size(); ++idx) {
+ sp_canvas_item_destroy(measure_item[idx]);
+ }
+ measure_item.clear();
+
+ SPItem *newover = desktop->getItemAtPoint(cursor, into_groups);
+ if (newover) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double fontsize = prefs->getDouble("/tools/measure/fontsize", 10.0);
+ double scale = prefs->getDouble("/tools/measure/scale", 100.0) / 100.0;
+ int precision = prefs->getInt("/tools/measure/precision", 2);
+ Glib::ustring unit_name = prefs->getString("/tools/measure/unit");
+ if (!unit_name.compare("")) {
+ unit_name = "px";
+ }
+ Geom::Scale zoom = Geom::Scale(Inkscape::Util::Quantity::convert(desktop->current_zoom(), "px", unit->abbr)).inverse();
+ if(newover != over){
+ over = newover;
+ Preferences *prefs = Preferences::get();
+ int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
+ SPItem::BBoxType bbox_type = !prefs_bbox ? SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
+ Geom::OptRect bbox = over->bounds(bbox_type);
+ if (bbox) {
+
+ item_width = Inkscape::Util::Quantity::convert((*bbox).width() * scale, unit->abbr, unit_name);
+ item_height = Inkscape::Util::Quantity::convert((*bbox).height() * scale, unit->abbr, unit_name);
+ item_x = Inkscape::Util::Quantity::convert((*bbox).left(), unit->abbr, unit_name);
+ Geom::Point y_point(0,Inkscape::Util::Quantity::convert((*bbox).bottom() * scale, unit->abbr, "px"));
+ y_point *= desktop->doc2dt();
+ item_y = Inkscape::Util::Quantity::convert(y_point[Geom::Y] * scale, "px", unit_name);
+ if (SP_IS_SHAPE(over)) {
+ Geom::PathVector shape = SP_SHAPE(over)->getCurve()->get_pathvector();
+ item_length = Geom::length(paths_to_pw(shape));
+ item_length = Inkscape::Util::Quantity::convert(item_length * scale, unit->abbr, unit_name);
+ }
+ }
+ }
+ gchar *measure_str = NULL;
+ std::stringstream precision_str;
+ precision_str.imbue(std::locale::classic());
+ double origin = Inkscape::Util::Quantity::convert(14, "px", unit->abbr);
+ Geom::Point rel_position = Geom::Point(origin, origin);
+ Geom::Point pos = desktop->w2d(cursor);
+ double gap = Inkscape::Util::Quantity::convert(7 + fontsize, "px", unit->abbr);
+ if (SP_IS_SHAPE(over)) {
+ precision_str << _("Length") << ": %." << precision << "f %s";
+ measure_str = g_strdup_printf(precision_str.str().c_str(), item_length, unit_name.c_str());
+ precision_str.str("");
+ showItemInfoText(pos + (rel_position * zoom),measure_str,fontsize);
+ rel_position = Geom::Point(rel_position[Geom::X], rel_position[Geom::Y] + gap);
+ } else if (SP_IS_GROUP(over)) {
+ measure_str = _("Shift to measure into group");
+ showItemInfoText(pos + (rel_position * zoom),measure_str,fontsize);
+ rel_position = Geom::Point(rel_position[Geom::X], rel_position[Geom::Y] + gap);
+ }
+
+ precision_str << "Y: %." << precision << "f %s";
+ measure_str = g_strdup_printf(precision_str.str().c_str(), item_y, unit_name.c_str());
+ precision_str.str("");
+ showItemInfoText(pos + (rel_position * zoom),measure_str,fontsize);
+ rel_position = Geom::Point(rel_position[Geom::X], rel_position[Geom::Y] + gap);
+
+ precision_str << "X: %." << precision << "f %s";
+ measure_str = g_strdup_printf(precision_str.str().c_str(), item_x, unit_name.c_str());
+ precision_str.str("");
+ showItemInfoText(pos + (rel_position * zoom),measure_str,fontsize);
+ rel_position = Geom::Point(rel_position[Geom::X], rel_position[Geom::Y] + gap);
+
+ precision_str << _("Height") << ": %." << precision << "f %s";
+ measure_str = g_strdup_printf(precision_str.str().c_str(), item_height, unit_name.c_str());
+ precision_str.str("");
+ showItemInfoText(pos + (rel_position * zoom),measure_str,fontsize);
+ rel_position = Geom::Point(rel_position[Geom::X], rel_position[Geom::Y] + gap);
+
+ precision_str << _("Width") << ": %." << precision << "f %s";
+ measure_str = g_strdup_printf(precision_str.str().c_str(), item_width, unit_name.c_str());
+ precision_str.str("");
+ showItemInfoText(pos + (rel_position * zoom),measure_str,fontsize);
+ g_free(measure_str);
+ }
+}
+
void MeasureTool::showCanvasItems(bool to_guides, bool to_item, bool to_phantom, Inkscape::XML::Node *measure_repr)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h
index 14fc9f81a..42122dca1 100644
--- a/src/ui/tools/measure-tool.h
+++ b/src/ui/tools/measure-tool.h
@@ -54,6 +54,8 @@ public:
virtual void setMarker(bool isStart);
virtual const std::string& getPrefsPath();
Geom::Point readMeasurePoint(bool is_start);
+ void showInfoBox(Geom::Point cursor, bool into_groups);
+ void showItemInfoText(Geom::Point pos, gchar *measure_str, double fontsize);
void writeMeasurePoint(Geom::Point point, bool is_start);
void setGuide(Geom::Point origin, double angle, const char *label);
void setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr);
@@ -77,6 +79,13 @@ private:
Geom::Point end_p;
std::vector<SPCanvasItem *> measure_tmp_items;
std::vector<SPCanvasItem *> measure_phantom_items;
+ std::vector<SPCanvasItem *> measure_item;
+ double item_width;
+ double item_height;
+ double item_x;
+ double item_y;
+ double item_length;
+ SPItem *over;
sigc::connection _knot_start_moved_connection;
sigc::connection _knot_start_ungrabbed_connection;
sigc::connection _knot_start_click_connection;
diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp
index 2bd4fdea3..f3679b40f 100644
--- a/src/ui/tools/node-tool.cpp
+++ b/src/ui/tools/node-tool.cpp
@@ -285,13 +285,11 @@ void NodeTool::update_helperpath () {
if (SP_IS_LPE_ITEM(selection->singleItem())) {
Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE();
if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) {
- Inkscape::UI::ControlPointSelection::Set &selectionNodes = _selected_nodes->allPoints();
+ Inkscape::UI::ControlPointSelection *selectionNodes = _selected_nodes;
std::vector<Geom::Point> selectedNodesPositions;
- for (Inkscape::UI::ControlPointSelection::Set::iterator i = selectionNodes.begin(); i != selectionNodes.end(); ++i) {
- if ((*i)->selected()) {
- Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i);
- selectedNodesPositions.push_back(n->position());
- }
+ for (Inkscape::UI::ControlPointSelection::iterator i = selectionNodes->begin(); i != selectionNodes->end(); ++i) {
+ Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i);
+ selectedNodesPositions.push_back(n->position());
}
lpe->setSelectedNodePoints(selectedNodesPositions);
lpe->setCurrentZoom(this->desktop->current_zoom());
@@ -470,6 +468,7 @@ bool NodeTool::root_handler(GdkEvent* event) {
switch (event->type)
{
case GDK_MOTION_NOTIFY: {
+ update_helperpath();
combine_motion_events(desktop->canvas, event->motion, 0);
SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button),
FALSE, TRUE);
diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp
index 86a2dbed3..0cdeda0b6 100644
--- a/src/ui/tools/select-tool.cpp
+++ b/src/ui/tools/select-tool.cpp
@@ -1045,37 +1045,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
ret = TRUE;
break;
-
- case GDK_KEY_less:
- case GDK_KEY_comma:
- if (MOD__ALT(event)) {
- gint mul = 1 + gobble_key_events(get_group0_keyval(&event->key), 0); // with any mask
- sp_selection_scale_screen(selection, -2*mul);
- } else if (MOD__CTRL(event)) {
- sp_selection_scale_times(selection, 0.5);
- } else {
- gint mul = 1 + gobble_key_events(get_group0_keyval(&event->key), 0); // with any mask
- sp_selection_scale(selection, -offset*mul);
- }
-
- ret = TRUE;
- break;
-
- case GDK_KEY_greater:
- case GDK_KEY_period:
- if (MOD__ALT(event)) {
- gint mul = 1 + gobble_key_events(get_group0_keyval(&event->key), 0); // with any mask
- sp_selection_scale_screen(selection, 2*mul);
- } else if (MOD__CTRL(event)) {
- sp_selection_scale_times(selection, 2);
- } else {
- gint mul = 1 + gobble_key_events(get_group0_keyval(&event->key), 0); // with any mask
- sp_selection_scale(selection, offset*mul);
- }
-
- ret = TRUE;
- break;
-
+
case GDK_KEY_Return:
if (MOD__CTRL_ONLY(event)) {
if (selection->singleItem()) {
diff --git a/src/ui/widget/combo-enums.h b/src/ui/widget/combo-enums.h
index 4678ab83b..e7524ac71 100644
--- a/src/ui/widget/combo-enums.h
+++ b/src/ui/widget/combo-enums.h
@@ -16,7 +16,6 @@
#include <gtkmm/liststore.h>
#include "attr-widget.h"
#include "util/enums.h"
-
#include <glibmm/i18n.h>
namespace Inkscape {
@@ -190,9 +189,11 @@ public:
const Util::EnumDataConverter<E>& c,
Glib::ustring const &suffix = "",
Glib::ustring const &icon = "",
- bool mnemonic = true)
- : Labelled(label, tooltip, new ComboBoxEnum<E>(c), suffix, icon, mnemonic)
- { }
+ bool mnemonic = true,
+ bool sorted = true)
+ : Labelled(label, tooltip, new ComboBoxEnum<E>(c, SP_ATTR_INVALID, sorted), suffix, icon, mnemonic)
+ {
+ }
ComboBoxEnum<E>* getCombobox() {
return static_cast< ComboBoxEnum<E>* > (_widget);
diff --git a/src/ui/widget/font-button.cpp b/src/ui/widget/font-button.cpp
new file mode 100644
index 000000000..a472ac6a4
--- /dev/null
+++ b/src/ui/widget/font-button.cpp
@@ -0,0 +1,58 @@
+/*
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "font-button.h"
+#include <glibmm/i18n.h>
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+FontButton::FontButton(Glib::ustring const &label, Glib::ustring const &tooltip,
+ Glib::ustring const &suffix,
+ Glib::ustring const &icon,
+ bool mnemonic)
+ : Labelled(label, tooltip, new Gtk::FontButton("Sans 10"), suffix, icon, mnemonic)
+{
+}
+
+Glib::ustring FontButton::getValue() const
+{
+ g_assert(_widget != NULL);
+ return static_cast<Gtk::FontButton*>(_widget)->get_font_name();
+}
+
+
+void FontButton::setValue (Glib::ustring fontspec)
+{
+ g_assert(_widget != NULL);
+ static_cast<Gtk::FontButton*>(_widget)->set_font_name(fontspec);
+}
+
+Glib::SignalProxy0<void> FontButton::signal_font_value_changed()
+{
+ g_assert(_widget != NULL);
+ return static_cast<Gtk::FontButton*>(_widget)->signal_font_set();
+}
+
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+/*
+ 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/ui/widget/font-button.h b/src/ui/widget/font-button.h
new file mode 100644
index 000000000..1f1ad2d01
--- /dev/null
+++ b/src/ui/widget/font-button.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * Copyright (C) 2007 Author
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_FONT_BUTTON_H
+#define INKSCAPE_UI_WIDGET_FONT_BUTTON_H
+
+#include <gtkmm.h>
+#include "labelled.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+/**
+ * A labelled font button for entering font values
+ */
+class FontButton : public Labelled
+{
+public:
+ /**
+ * Construct a FontButton Widget.
+ *
+ * @param label Label.
+ * @param suffix Suffix, placed after the widget (defaults to "").
+ * @param icon Icon filename, placed before the label (defaults to "").
+ * @param mnemonic Mnemonic toggle; if true, an underscore (_) in the label
+ * indicates the next character should be used for the
+ * mnemonic accelerator key (defaults to false).
+ */
+ FontButton( Glib::ustring const &label,
+ Glib::ustring const &tooltip,
+ Glib::ustring const &suffix = "",
+ Glib::ustring const &icon = "",
+ bool mnemonic = true);
+
+ Glib::ustring getValue() const;
+ void setValue (Glib::ustring fontspec);
+ /**
+ * Signal raised when the font button's value changes.
+ */
+ Glib::SignalProxy0<void> signal_font_value_changed();
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_RANDOM_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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/registered-enums.h b/src/ui/widget/registered-enums.h
index 9e1682c7d..1d5074836 100644
--- a/src/ui/widget/registered-enums.h
+++ b/src/ui/widget/registered-enums.h
@@ -33,11 +33,11 @@ public:
const Util::EnumDataConverter<E>& c,
Registry& wr,
Inkscape::XML::Node* repr_in = NULL,
- SPDocument *doc_in = NULL )
- : RegisteredWidget< LabelledComboBoxEnum<E> >(label, tip, c)
+ SPDocument *doc_in = NULL,
+ bool sorted = true )
+ : RegisteredWidget< LabelledComboBoxEnum<E> >(label, tip, c, (const Glib::ustring &)"", (const Glib::ustring &)"", true, sorted)
{
RegisteredWidget< LabelledComboBoxEnum<E> >::init_parent(key, wr, repr_in, doc_in);
-
_changed_connection = combobox()->signal_changed().connect (sigc::mem_fun (*this, &RegisteredEnum::on_changed));
}
diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp
index 7dc5abc75..be677a434 100644
--- a/src/ui/widget/registered-widget.cpp
+++ b/src/ui/widget/registered-widget.cpp
@@ -285,7 +285,6 @@ RegisteredScalar::on_value_changed()
setProgrammatically = false;
return;
}
-
if (_wr->isUpdating()) {
return;
}
@@ -319,8 +318,6 @@ RegisteredText::RegisteredText ( const Glib::ustring& label, const Glib::ustring
init_parent(key, wr, repr_in, doc_in);
setProgrammatically = false;
-
- setText("");
_activate_connection = signal_activate().connect (sigc::mem_fun (*this, &RegisteredText::on_activate));
}
@@ -336,16 +333,12 @@ RegisteredText::on_activate()
return;
}
_wr->setUpdating (true);
-
- Inkscape::SVGOStringStream os;
- os << getText();
-
+ Glib::ustring str(getText());
set_sensitive(false);
+ Inkscape::SVGOStringStream os;
+ os << str;
write_to_xml(os.str().c_str());
set_sensitive(true);
-
- setText(os.str().c_str());
-
_wr->setUpdating (false);
}
@@ -791,6 +784,47 @@ RegisteredRandom::on_value_changed()
_wr->setUpdating (false);
}
+/*#########################################
+ * Registered FONT-BUTTON
+ */
+
+RegisteredFontButton::~RegisteredFontButton()
+{
+ _signal_font_set.disconnect();
+}
+
+RegisteredFontButton::RegisteredFontButton ( const Glib::ustring& label, const Glib::ustring& tip,
+ const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
+ SPDocument* doc_in )
+ : RegisteredWidget<FontButton>(label, tip)
+{
+ init_parent(key, wr, repr_in, doc_in);
+ _signal_font_set = signal_font_value_changed().connect (sigc::mem_fun (*this, &RegisteredFontButton::on_value_changed));
+}
+
+void
+RegisteredFontButton::setValue (Glib::ustring fontspec)
+{
+ FontButton::setValue(fontspec);
+}
+
+void
+RegisteredFontButton::on_value_changed()
+{
+
+ if (_wr->isUpdating())
+ return;
+
+ _wr->setUpdating (true);
+
+ Inkscape::SVGOStringStream os;
+ os << getValue();
+
+ write_to_xml(os.str().c_str());
+
+ _wr->setUpdating (false);
+}
+
} // namespace Dialog
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h
index ab2e4c8e4..d410dbfe6 100644
--- a/src/ui/widget/registered-widget.h
+++ b/src/ui/widget/registered-widget.h
@@ -22,6 +22,7 @@
#include "ui/widget/text.h"
#include "ui/widget/random.h"
#include "ui/widget/unit-menu.h"
+#include "ui/widget/font-button.h"
#include "ui/widget/color-picker.h"
#include "inkscape.h"
@@ -77,6 +78,8 @@ protected:
RegisteredWidget( A& a, B& b, C c, D d ): W( a, b, c, d ) { construct(); }
template< typename A, typename B, typename C, typename D, typename E , typename F>
RegisteredWidget( A& a, B& b, C c, D& d, E& e, F* f): W( a, b, c, d, e, f) { construct(); }
+ template< typename A, typename B, typename C, typename D, typename E , typename F, typename G>
+ RegisteredWidget( A& a, B& b, C& c, D& d, E& e, F f, G& g): W( a, b, c, d, e, f, g) { construct(); }
virtual ~RegisteredWidget() {};
@@ -418,6 +421,23 @@ protected:
void on_value_changed();
};
+class RegisteredFontButton : public RegisteredWidget<FontButton> {
+public:
+ virtual ~RegisteredFontButton();
+ RegisteredFontButton ( const Glib::ustring& label,
+ const Glib::ustring& tip,
+ const Glib::ustring& key,
+ Registry& wr,
+ Inkscape::XML::Node* repr_in = NULL,
+ SPDocument *doc_in = NULL);
+
+ void setValue (Glib::ustring fontspec);
+
+protected:
+ sigc::connection _signal_font_set;
+ void on_value_changed();
+};
+
} // namespace Widget
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp
index 434c2c0bb..f8543a371 100644
--- a/src/ui/widget/scalar.cpp
+++ b/src/ui/widget/scalar.cpp
@@ -122,10 +122,12 @@ void Scalar::setRange(double min, double max)
static_cast<SpinButton*>(_widget)->set_range(min, max);
}
-void Scalar::setValue(double value)
+void Scalar::setValue(double value, bool setProg)
{
g_assert(_widget != NULL);
- setProgrammatically = true; // callback is supposed to reset back, if it cares
+ if (setProg) {
+ setProgrammatically = true; // callback is supposed to reset back, if it cares
+ }
static_cast<SpinButton*>(_widget)->set_value(value);
}
diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h
index 847790b96..f186f46ac 100644
--- a/src/ui/widget/scalar.h
+++ b/src/ui/widget/scalar.h
@@ -135,7 +135,7 @@ public:
/**
* Sets the value of the spin button.
*/
- void setValue(double value);
+ void setValue(double value, bool setProg = true);
/**
* Manually forces an update of the spin button.
diff --git a/src/ui/widget/text.cpp b/src/ui/widget/text.cpp
index ec58d5bb4..e6795b138 100644
--- a/src/ui/widget/text.cpp
+++ b/src/ui/widget/text.cpp
@@ -28,13 +28,13 @@ Text::Text(Glib::ustring const &label, Glib::ustring const &tooltip,
{
}
-const char *Text::getText() const
+Glib::ustring const Text::getText() const
{
g_assert(_widget != NULL);
- return static_cast<Gtk::Entry*>(_widget)->get_text().c_str();
+ return static_cast<Gtk::Entry*>(_widget)->get_text();
}
-void Text::setText(const char* text)
+void Text::setText(Glib::ustring const text)
{
g_assert(_widget != NULL);
setProgrammatically = true; // callback is supposed to reset back, if it cares
diff --git a/src/ui/widget/text.h b/src/ui/widget/text.h
index b90788940..593875b23 100644
--- a/src/ui/widget/text.h
+++ b/src/ui/widget/text.h
@@ -44,12 +44,12 @@ public:
/**
* Get the text in the entry.
*/
- const char* getText() const;
+ Glib::ustring const getText() const;
/**
* Sets the text of the text entry.
*/
- void setText(const char* text);
+ void setText(Glib::ustring const text);
void update();
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 5130f1701..e061eaab6 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -817,7 +817,7 @@ Verb *Verb::get_search(unsigned int code)
*
* @param id Which id to search for.
*/
-Verb *Verb::getbyid(gchar const *id)
+Verb *Verb::getbyid(gchar const *id, bool verbose)
{
Verb *verb = NULL;
VerbIDTable::iterator verb_found = _verb_ids.find(id);
@@ -833,8 +833,10 @@ Verb *Verb::getbyid(gchar const *id)
&& strcmp(id, "SelectionTrace") != 0
&& strcmp(id, "PaintBucketPrefs") != 0
#endif
- )
- printf("Unable to find: %s\n", id);
+ ) {
+ if (verbose)
+ printf("Unable to find: %s\n", id);
+ }
return verb;
}
@@ -1099,6 +1101,7 @@ void SelectionVerb::perform(SPAction *action, void *data)
{
Inkscape::Selection *selection = sp_action_get_selection(action);
SPDesktop *dt = sp_action_get_desktop(action);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// Some of these operations have been modified so they work in command-line mode!
// In this case, all we need is a selection
@@ -1126,6 +1129,38 @@ void SelectionVerb::perform(SPAction *action, void *data)
case SP_VERB_SELECTION_SLICE:
sp_selected_path_slice(selection, dt);
break;
+ case SP_VERB_SELECTION_GROW:
+ {
+ // FIXME these and the other grow/shrink they should use gobble_key_events.
+ // the problem is how to get access to which key, if any, to gobble.
+ sp_selection_scale(selection, prefs->getDoubleLimited("/options/defaultscale/value", 2, 0, 1000));
+ break;
+ }
+ case SP_VERB_SELECTION_GROW_SCREEN:
+ {
+ sp_selection_scale_screen(selection, 2);
+ break;
+ }
+ case SP_VERB_SELECTION_GROW_DOUBLE:
+ {
+ sp_selection_scale_times(selection, 2);
+ break;
+ }
+ case SP_VERB_SELECTION_SHRINK:
+ {
+ sp_selection_scale(selection, -prefs->getDoubleLimited("/options/defaultscale/value", 2, 0, 1000));
+ break;
+ }
+ case SP_VERB_SELECTION_SHRINK_SCREEN:
+ {
+ sp_selection_scale_screen(selection, -2);
+ break;
+ }
+ case SP_VERB_SELECTION_SHRINK_HALVE:
+ {
+ sp_selection_scale_times(selection, 0.5);
+ break;
+ }
case SP_VERB_SELECTION_TO_FRONT:
sp_selection_raise_to_top(selection, dt);
break;
@@ -1856,6 +1891,7 @@ void ZoomVerb::perform(SPAction *action, void *data)
{
gint mul = 1 + Inkscape::UI::Tools::gobble_key_events(
GDK_KEY_KP_Add, 0); // with any mask
+ // FIXME what if zoom out is bound to something other than subtract?
// While drawing with the pen/pencil tool, zoom 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;
@@ -2585,6 +2621,18 @@ Verb *Verb::_base_verbs[] = {
// Advanced tutorial for more info
new SelectionVerb(SP_VERB_SELECTION_SLICE, "SelectionCutPath", N_("Cut _Path"),
N_("Cut the bottom path's stroke into pieces, removing fill"), INKSCAPE_ICON("path-cut")),
+ new SelectionVerb(SP_VERB_SELECTION_GROW, "SelectionGrow", N_("_Grow"),
+ N_("Make selected objects bigger"), INKSCAPE_ICON("selection-grow")),
+ new SelectionVerb(SP_VERB_SELECTION_GROW_SCREEN, "SelectionGrowScreen", N_("_Grow on screen"),
+ N_("Make selected objects bigger relative to screen"), INKSCAPE_ICON("selection-grow-screen")),
+ new SelectionVerb(SP_VERB_SELECTION_GROW_DOUBLE, "SelectionGrowDouble", N_("_Double size"),
+ N_("Double the size of selected objects"), INKSCAPE_ICON("selection-grow-double")),
+ new SelectionVerb(SP_VERB_SELECTION_SHRINK, "SelectionShrink", N_("_Shrink"),
+ N_("Make selected objects smaller"), INKSCAPE_ICON("selection-shrink")),
+ new SelectionVerb(SP_VERB_SELECTION_SHRINK_SCREEN, "SelectionShrinkScreen", N_("_Shrink on screen"),
+ N_("Make selected objects smaller relative to screen"), INKSCAPE_ICON("selection-shrink-screen")),
+ new SelectionVerb(SP_VERB_SELECTION_SHRINK_HALVE, "SelectionShrinkHalve", N_("_Halve size"),
+ N_("Halve the size of selected objects"), INKSCAPE_ICON("selection-shrink-halve")),
// TRANSLATORS: "outset": expand a shape by offsetting the object's path,
// i.e. by displacing it perpendicular to the path in each point.
// See also the Advanced Tutorial for explanation.
diff --git a/src/verbs.h b/src/verbs.h
index 16f88c408..1780e0ebf 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -126,6 +126,12 @@ enum {
SP_VERB_SELECTION_SYMDIFF,
SP_VERB_SELECTION_CUT,
SP_VERB_SELECTION_SLICE,
+ SP_VERB_SELECTION_GROW,
+ SP_VERB_SELECTION_GROW_SCREEN,
+ SP_VERB_SELECTION_GROW_DOUBLE,
+ SP_VERB_SELECTION_SHRINK,
+ SP_VERB_SELECTION_SHRINK_SCREEN,
+ SP_VERB_SELECTION_SHRINK_HALVE,
SP_VERB_SELECTION_OFFSET,
SP_VERB_SELECTION_OFFSET_SCREEN,
SP_VERB_SELECTION_OFFSET_SCREEN_10,
@@ -575,7 +581,7 @@ public:
return get_search(code);
}
}
- static Verb * getbyid (gchar const * id);
+ static Verb * getbyid (gchar const * id, bool verbose = true);
/**
* Print a message to stderr indicating that this verb needs a GUI to run
diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp
index 582fb66ba..96733cb22 100644
--- a/src/widgets/pencil-toolbar.cpp
+++ b/src/widgets/pencil-toolbar.cpp
@@ -238,11 +238,12 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj)
{
SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(obj, "desktop"));
auto selected = desktop->getSelection()->items();
+ SPLPEItem* lpeitem = NULL;
for (auto it(selected.begin()); it != selected.end(); ++it){
- SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it);
+ lpeitem = dynamic_cast<SPLPEItem*>(*it);
if (lpeitem && lpeitem->hasPathEffect()){
PathEffectList lpelist = lpeitem->getEffectList();
- std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i;
+ PathEffectList::iterator i;
for (i = lpelist.begin(); i != lpelist.end(); ++i) {
LivePathEffectObject *lpeobj = (*i)->lpeobject;
if (lpeobj) {
@@ -267,6 +268,10 @@ static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj)
}
}
}
+ if (lpeitem) {
+ desktop->getSelection()->remove(lpeitem->getRepr());
+ desktop->getSelection()->add(lpeitem->getRepr());
+ }
}
static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl)