diff --git a/icons/22-actions-segment_golden_point.png b/icons/22-actions-segment_golden_point.png
new file mode 100644
index 00000000..e69de29b
diff --git a/icons/32-actions-segment_golden_point.png b/icons/32-actions-segment_golden_point.png
new file mode 100644
index 00000000..e69de29b
diff --git a/icons/CMakeLists.txt b/icons/CMakeLists.txt
index a28ecbea..446cf1f1 100644
--- a/icons/CMakeLists.txt
+++ b/icons/CMakeLists.txt
@@ -1,279 +1,282 @@
ecm_install_icons(ICONS
32-actions-square.png
22-actions-intersection.png
22-actions-centerofcurvature.png
22-actions-rbezier4.png
sc-actions-conicasymptotes.svgz
22-actions-point.png
32-actions-coniclineintersection.png
32-actions-translation.png
32-actions-tangent.png
sc-actions-conicb5p.svgz
22-actions-rbezier3.png
sc-actions-square.svgz
sc-actions-bisection.svgz
32-actions-perpendicular.png
22-actions-perpendicular.png
32-actions-circlebps.png
sc-actions-segment_midpoint.svgz
+ sc-actions-segment_golden_point.svgz
32-actions-genericaffinity.png
sc-actions-bezier4.svgz
32-actions-ellipsebffp.png
22-actions-convexhull.png
sc-actions-circlelineintersection.svgz
32-actions-inversion.png
sc-actions-equilateralhyperbolab4p.svgz
sc-actions-bezier3.svgz
16-actions-kig_xfig.png
32-actions-directrix.png
sc-actions-distance.svgz
22-actions-similitude.png
22-actions-bezierN.png
32-actions-rbezier4.png
22-actions-inversion.png
22-actions-distance.png
32-actions-rotation.png
32-actions-segmentaxis.png
sc-actions-paint.svgz
22-actions-bisection.png
32-actions-hexagonbcv.png
sc-actions-sizer.svgz
32-actions-curvelineintersection.png
32-actions-convexhull.png
sc-actions-centerofcurvature.svgz
sc-actions-inversion.svgz
32-actions-locus.png
32-actions-areaCircle.png
sc-actions-harmonichomology.svgz
22-actions-kig_polygon.png
22-actions-vectordifference.png
sc-actions-rbezier3.svgz
22-actions-hexagonbcv.png
32-actions-kig_polygon.png
32-actions-triangle.png
32-actions-rbezierN.png
sc-actions-hyperbolabffp.svgz
32-actions-pointOnLine.png
22-actions-line.png
22-actions-segment.png
22-actions-circlelineintersection.png
22-actions-circlebpd.png
32-actions-bezier4.png
32-actions-bisection.png
sc-actions-curvelineintersection.svgz
32-actions-vector.png
22-actions-vector.png
32-actions-stretch.png
22-actions-vectorsum.png
22-actions-arc_center.png
22-actions-arc.png
22-actions-view_fit_to_page.png
sc-actions-parallel.svgz
32-actions-python.png
sc-actions-circlebcp.svgz
22-actions-polygonvertices.png
sc-actions-perpendicular.svgz
sc-actions-line.svgz
32-actions-parallel.png
32-actions-arc.png
32-actions-openpolygon.png
22-actions-segmentaxis.png
sc-actions-tangent.svgz
32-actions-testcollinear.png
sc-actions-test.svgz
32-actions-kig_numericvalue.png
32-actions-attacher.png
sc-actions-baseCircle.svgz
32-actions-w.png
22-actions-angle_bisector.png
32-actions-equitriangle.png
22-actions-attacher.png
sc-actions-attacher.svgz
32-actions-genericprojectivity.png
32-actions-circlebcl.png
sc-actions-rbezierN.svgz
sc-actions-testdistance.svgz
22-actions-harmonichomology.png
32-actions-conicasymptotes.png
22-actions-coniclineintersection.png
22-actions-slope.png
sc-actions-testorthogonal.svgz
32-actions-angle_bisector.png
22-actions-circlebcl.png
32-actions-arc_center.png
22-actions-controlpolygon.png
sc-actions-hexagonbcv.svgz
sc-actions-segmentaxis.svgz
32-actions-parabolabtp.png
sc-actions-vectordifference.svgz
sc-actions-areaCircle.svgz
22-actions-baseCircle.png
32-actions-linebyvector.png
22-actions-sizer.png
22-actions-bezier3.png
sc-actions-conicsradicalline.svgz
22-actions-square.png
22-actions-genericaffinity.png
32-actions-testcontains.png
22-actions-segment_midpoint.png
+ 22-actions-segment_golden_point.png
32-actions-kig_text.png
22-actions-conicasymptotes.png
22-actions-directrix.png
sc-actions-circlebpd.svgz
22-actions-locus.png
22-actions-ray.png
sc-actions-polygonsides.svgz
22-actions-w.png
22-actions-circumference.png
sc-actions-centralsymmetry.svgz
32-actions-bezierN.png
32-actions-circumference.png
32-actions-point.png
22-actions-equilateralhyperbolab4p.png
32-actions-paint.png
sc-actions-directrix.svgz
22-actions-python.png
22-actions-testdistance.png
22-actions-conicsradicalline.png
32-actions-halflinebyvector.png
22-actions-areaCircle.png
sc-actions-kig_numericvalue.svgz
sc-actions-halflinebyvector.svgz
22-actions-paint.png
22-actions-bezier4.png
32-actions-projection.png
22-actions-triangle.png
22-actions-openpolygon.png
32-actions-rbezier3.png
22-actions-parallel.png
sc-actions-parabolabtp.svgz
22-actions-testparallel.png
22-actions-polygonsides.png
32-actions-circlebtp.png
sc-actions-genericprojectivity.svgz
32-actions-scale.png
32-actions-beziercurves.png
32-actions-vectordifference.png
sc-actions-python.svgz
22-actions-pointOnLine.png
sc-actions-equitriangle.svgz
22-actions-angle.png
32-actions-hyperbolabffp.png
22-actions-pointxy.png
32-actions-polygonvertices.png
22-actions-hyperbolabffp.png
32-actions-controlpolygon.png
32-actions-slope.png
sc-actions-linebyvector.svgz
sc-actions-arc.svgz
sc-actions-ray.svgz
22-actions-beziercurves.png
22-actions-testcontains.png
22-actions-ellipsebffp.png
22-actions-stretch.png
sc-actions-scale.svgz
sc-actions-intersection.svgz
22-actions-kig_text.png
sc-actions-point.svgz
sc-actions-similitude.svgz
sc-actions-vector.svgz
sc-actions-coniclineintersection.svgz
22-actions-translation.png
32-actions-bezier3.png
22-actions-radicalline.png
32-actions-vectorsum.png
32-actions-centerofcurvature.png
sc-actions-openpolygon.svgz
sc-actions-circlebcl.svgz
22-actions-rbezierN.png
32-actions-polygonsides.png
sc-actions-locus.svgz
22-actions-tangent.png
32-actions-sizer.png
32-actions-harmonichomology.png
22-actions-testcollinear.png
22-actions-en.png
32-actions-conicb5p.png
32-actions-distance.png
22-actions-circlebtp.png
22-actions-kig_numericvalue.png
sc-actions-vectorsum.svgz
32-actions-line.png
32-actions-testdistance.png
sc-actions-kig_text.svgz
32-actions-angle.png
sc-actions-angle.svgz
sc-actions-controlpolygon.svgz
22-actions-parabolabtp.png
sc-actions-w.svgz
22-actions-test.png
22-actions-curvelineintersection.png
32-actions-test.png
22-actions-equitriangle.png
32-actions-mirrorpoint.png
32-actions-centralsymmetry.png
sc-actions-mirrorpoint.svgz
sc-actions-triangle.svgz
sc-actions-genericaffinity.svgz
sc-actions-segment.svgz
sc-actions-bezierN.svgz
sc-actions-radicalline.svgz
32-actions-segment_midpoint.png
+ 32-actions-segment_golden_point.png
sc-actions-slope.svgz
32-actions-ray.png
22-actions-projection.png
32-actions-testparallel.png
sc-actions-translation.svgz
sc-actions-pointxy.svgz
22-actions-circlebcp.png
32-actions-segment.png
sc-actions-convexhull.svgz
sc-actions-testcontains.svgz
sc-actions-en.svgz
sc-actions-arc_center.svgz
22-actions-genericprojectivity.png
22-actions-testorthogonal.png
22-actions-rotation.png
sc-actions-pointOnLine.svgz
sc-actions-beziercurves.svgz
32-actions-pointxy.png
22-actions-mirrorpoint.png
32-actions-equilateralhyperbolab4p.png
sc-actions-kig_polygon.svgz
32-actions-en.png
22-actions-scale.png
32-actions-angle_size.png
32-actions-testorthogonal.png
22-actions-centralsymmetry.png
32-actions-baseCircle.png
sc-actions-angle_size.svgz
sc-actions-circlebtp.svgz
32-actions-circlelineintersection.png
32-actions-circlebcp.png
22-actions-angle_size.png
22-actions-linebyvector.png
sc-actions-rotation.svgz
22-actions-conicb5p.png
32-actions-intersection.png
sc-actions-circlebps.svgz
32-actions-conicsradicalline.png
sc-actions-testparallel.svgz
sc-actions-stretch.svgz
22-actions-circlebps.png
32-actions-similitude.png
sc-actions-projection.svgz
sc-actions-circumference.svgz
sc-actions-ellipsebffp.svgz
sc-actions-angle_bisector.svgz
sc-actions-polygonvertices.svgz
32-actions-radicalline.png
22-actions-halflinebyvector.png
sc-actions-rbezier4.svgz
32-actions-circlebpd.png
sc-actions-testcollinear.svgz
DESTINATION ${CMAKE_INSTALL_DATADIR}/kig/icons
THEME hicolor
)
diff --git a/icons/sc-actions-segment_golden_point.svgz b/icons/sc-actions-segment_golden_point.svgz
new file mode 100644
index 00000000..e69de29b
diff --git a/kig/kigpartui.rc b/kig/kigpartui.rc
index a99f2466..b6e3323e 100644
--- a/kig/kigpartui.rc
+++ b/kig/kigpartui.rc
@@ -1,322 +1,323 @@
&Types
&Tools
Main Toolbar
Points
Lines
Vectors && Segments
Circles && Arcs
Conics
Bézier Curves
Angles
Transformations
Tests
Other Objects
View
diff --git a/misc/builtin_stuff.cc b/misc/builtin_stuff.cc
index e1de877d..f2a3d5d5 100644
--- a/misc/builtin_stuff.cc
+++ b/misc/builtin_stuff.cc
@@ -1,717 +1,743 @@
// Copyright (C) 2003 Dominique Devriese
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301, USA.
#include "builtin_stuff.h"
#include
#include "object_constructor.h"
#include "lists.h"
#include "special_constructors.h"
#include "guiaction.h"
#include "../objects/angle_type.h"
#include "../objects/arc_type.h"
#include "../objects/circle_type.h"
#include "../objects/conic_types.h"
#include "../objects/cubic_type.h"
#include "../objects/intersection_types.h"
#include "../objects/inversion_type.h"
#include "../objects/line_imp.h"
#include "../objects/line_type.h"
#include "../objects/object_imp.h"
#include "../objects/other_imp.h"
#include "../objects/other_type.h"
#include "../objects/point_type.h"
#include "../objects/tests_type.h"
#include "../objects/transform_types.h"
#include "../objects/vector_type.h"
#include "../objects/polygon_type.h"
#include "../objects/bezier_type.h"
void setupBuiltinStuff()
{
static bool done = false;
if ( ! done )
{
ObjectConstructorList* ctors = ObjectConstructorList::instance();
GUIActionList* actions = GUIActionList::instance();
ObjectConstructor* c = 0;
// point by coords...
c = new SimpleObjectTypeConstructor(
PointByCoordsType::instance(),
I18N_NOOP( "Point by Numeric Labels" ),
I18N_NOOP( "A point whose coordinates are given by two numeric labels" ),
"pointxy" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_point_by_coords" ) );
// segment...
c = new SimpleObjectTypeConstructor(
SegmentABType::instance(), I18N_NOOP( "Segment" ),
I18N_NOOP( "A segment constructed from its start and end point" ),
"segment" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_segment", Qt::Key_S ) );
// segment axis...
c = new SimpleObjectTypeConstructor(
SegmentAxisType::instance(), I18N_NOOP( "Segment Axis" ),
I18N_NOOP( "The perpendicular line through a given segment's mid point." ),
"segmentaxis" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_segment_axis" ) );
// line by two points..
c = new SimpleObjectTypeConstructor(
LineABType::instance(), I18N_NOOP( "Line by Two Points" ),
I18N_NOOP( "A line constructed through two points"), "line" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_linettp", Qt::Key_L ) );
// ray by two points..
c = new SimpleObjectTypeConstructor(
RayABType::instance(), I18N_NOOP( "Half-Line" ),
I18N_NOOP( "A half-line by its start point, and another point somewhere on it." ),
"ray" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_ray", Qt::Key_R ) );
// perpendicular line
c = new SimpleObjectTypeConstructor(
LinePerpendLPType::instance(), I18N_NOOP( "Perpendicular" ),
I18N_NOOP( "A line constructed through a point, perpendicular to another line or segment." ),
"perpendicular" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_lineperpend" ) );
// parallel line
c = new SimpleObjectTypeConstructor(
LineParallelLPType::instance(), I18N_NOOP( "Parallel" ),
I18N_NOOP( "A line constructed through a point, and parallel to another line or segment" ),
"parallel" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_lineparallel" ) );
// circle
c = new SimpleObjectTypeConstructor(
CircleBCPType::instance(), I18N_NOOP( "Circle by Center && Point" ),
I18N_NOOP( "A circle constructed by its center and a point that pertains to it" ),
"circlebcp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_circlebcp", Qt::Key_C ) );
c = new SimpleObjectTypeConstructor(
CircleBTPType::instance(), I18N_NOOP( "Circle by Three Points" ),
I18N_NOOP( "A circle constructed through three points" ),
"circlebtp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_circlebtp" ) );
c = new SimpleObjectTypeConstructor(
CircleBPRType::instance(), I18N_NOOP( "Circle by Point && Radius" ),
I18N_NOOP( "A circle defined by its center and the length of the radius" ),
"circlebps" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_circlebpr" ) );
// declare this object static to this function, so it gets deleted
// at the end of the program, without us having to wonder about
// deleting it.. We don't want to register this
// object-constructor, because that way, "construct the bisector"
// would appear twice in the angle popup menu: once as the generic
// construct a property stuff, and once because of this ctor..
// we only register the guiaction, cause it makes sense to have a
// toolbar icon for this..
static PropertyObjectConstructor anglebisectionctor(
AngleImp::stype(),
I18N_NOOP( "Construct Bisector of This Angle" ),
I18N_NOOP( "Select the angle you want to construct the bisector of..." ),
I18N_NOOP( "Angle Bisector" ),
I18N_NOOP( "The bisector of an angle" ),
"angle_bisector",
"angle-bisector" );
actions->add( new ConstructibleAction( &anglebisectionctor, "objects_new_angle_bisector" ) );
// conic stuff
c = new SimpleObjectTypeConstructor(
ConicB5PType::instance(), I18N_NOOP( "Conic by Five Points" ),
I18N_NOOP( "A conic constructed through five points" ),
"conicb5p" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_conicb5p" ) );
c = new SimpleObjectTypeConstructor(
ConicBAAPType::instance(),
I18N_NOOP( "Hyperbola by Asymptotes && Point" ),
I18N_NOOP( "A hyperbola with given asymptotes through a point" ),
"conicbaap" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_conicbaap" ) );
c = new SimpleObjectTypeConstructor(
EllipseBFFPType::instance(),
I18N_NOOP( "Ellipse by Focuses && Point" ), // focuses is used in preference to foci
I18N_NOOP( "An ellipse constructed by its focuses and a point that pertains to it" ),
"ellipsebffp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_ellipsebffp" ) );
c = new SimpleObjectTypeConstructor(
HyperbolaBFFPType::instance(),
I18N_NOOP( "Hyperbola by Focuses && Point" ), // focuses is used in preference to foci
I18N_NOOP( "A hyperbola constructed by its focuses and a point that pertains to it" ),
"hyperbolabffp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_hyperbolabffp" ) );
c = new SimpleObjectTypeConstructor(
ConicBDFPType::instance(),
I18N_NOOP( "Conic by Directrix, Focus && Point" ),
I18N_NOOP( "A conic with given directrix and focus, through a point" ),
"conicbdfp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_conicbdfp" ) );
c = new SimpleObjectTypeConstructor(
ParabolaBTPType::instance(),
I18N_NOOP( "Vertical Parabola by Three Points" ),
I18N_NOOP( "A vertical parabola constructed through three points" ),
"parabolabtp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_parabolabtp" ) );
c = new SimpleObjectTypeConstructor(
CubicB9PType::instance(),
I18N_NOOP( "Cubic Curve by Nine Points" ),
I18N_NOOP( "A cubic curve constructed through nine points" ),
"cubicb9p" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_cubicb9p" ) );
c = new SimpleObjectTypeConstructor(
ConicPolarPointType::instance(),
I18N_NOOP( "Polar Point of a Line" ),
I18N_NOOP( "The polar point of a line with respect to a conic." ),
"polarpoint" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_pointpolar" ) );
c = new SimpleObjectTypeConstructor(
ConicPolarLineType::instance(),
I18N_NOOP( "Polar Line of a Point" ),
I18N_NOOP( "The polar line of a point with respect to a conic." ),
"polarline" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_linepolar" ) );
c = new SimpleObjectTypeConstructor(
CubicNodeB6PType::instance(),
I18N_NOOP( "Cubic Curve with Node by Six Points" ),
I18N_NOOP( "A cubic curve with a nodal point at the origin through six points" ),
"cubicnodeb6p" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_cubicnodeb6p" ) );
c = new SimpleObjectTypeConstructor(
CubicCuspB4PType::instance(),
I18N_NOOP( "Cubic Curve with Cusp by Four Points" ),
I18N_NOOP( "A cubic curve with a horizontal cusp at the origin through four points" ),
"cubiccuspb4p" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_cubiccuspb4p" ) );
c = new SimpleObjectTypeConstructor(
VerticalCubicB4PType::instance(),
I18N_NOOP( "Cubic Function by Four Points" ),
I18N_NOOP( "A cubic function through four points" ),
"verticalcubicb4p" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_verticalcubicb4p" ) );
c = new SimpleObjectTypeConstructor(
ConicDirectrixType::instance(),
I18N_NOOP( "Directrix of a Conic" ),
I18N_NOOP( "The directrix line of a conic." ),
"directrix" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_linedirectrix" ) );
c = new SimpleObjectTypeConstructor(
AngleType::instance(),
I18N_NOOP( "Angle by Three Points" ),
I18N_NOOP( "An angle defined by three points" ),
"angle" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_angle", Qt::Key_A ) );
c = new SimpleObjectTypeConstructor(
EquilateralHyperbolaB4PType::instance(),
I18N_NOOP( "Equilateral Hyperbola by Four Points" ),
I18N_NOOP( "An equilateral hyperbola constructed through four points" ),
"equilateralhyperbolab4p" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_equilateralhyperbolab4p" ) );
{
// now for the Mid Point action. It does both the mid point of
// a segment, and the mid point of two points. The midpoint of
// two segments just shows the mid point property, and therefore
// doesn't need to be added to the ctors, because there are
// already facilities to construct an object's properties..
// therefore, we add only an mpotp to the ctors, and add the
// merged constructor only to the actions..
ctors->add( new MidPointOfTwoPointsConstructor() );
ObjectConstructor* mpotp = new MidPointOfTwoPointsConstructor();
ObjectConstructor* mpos = new PropertyObjectConstructor(
SegmentImp::stype(), I18N_NOOP( "Construct the midpoint of this segment" ),
"", "", "", "", "mid-point" );
// make this a static object, so it gets deleted at the end of
// the program.
static MergeObjectConstructor m(
I18N_NOOP( "Mid Point" ),
I18N_NOOP( "The midpoint of a segment or two other points" ),
"bisection" );
m.merge( mpotp );
m.merge( mpos );
actions->add( new ConstructibleAction( &m, "objects_new_midpoint", Qt::Key_M ) );
};
+ {
+ // now for the Golden Ratio Point action. It does both the golden ratio point of
+ // a segment, and the golden ratio point of two points. The golden ratio point of
+ // two segments just shows the golden ratio point property, and therefore
+ // doesn't need to be added to the ctors, because there are
+ // already facilities to construct an object's properties..
+ // therefore, we add only an mpotp to the ctors, and add the
+ // merged constructor only to the actions..
+ ctors->add( new GoldenPointOfTwoPointsConstructor() );
+
+ ObjectConstructor* mpotp = new GoldenPointOfTwoPointsConstructor();
+ ObjectConstructor* mpos = new PropertyObjectConstructor(
+ SegmentImp::stype(), I18N_NOOP( "Construct the golden ratio point of this segment" ),
+ "", "", "", "", "golden-point" );
+
+ // make this a static object, so it gets deleted at the end of
+ // the program.
+ static MergeObjectConstructor m(
+ I18N_NOOP( "Golden Ratio Point" ),
+ I18N_NOOP( "The golden ratio point of a segment or two other points" ),
+ "segment_golden_point" );
+ m.merge( mpotp );
+ m.merge( mpos );
+ actions->add( new ConstructibleAction( &m, "objects_new_golden_point", Qt::Key_G ) );
+ };
+
c = new SimpleObjectTypeConstructor(
VectorType::instance(),
I18N_NOOP( "Vector" ),
I18N_NOOP( "Construct a vector from two given points." ),
"vector" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_vector", Qt::Key_V ) );
c = new SimpleObjectTypeConstructor(
VectorSumType::instance(),
I18N_NOOP( "Vector Sum" ),
I18N_NOOP( "Construct the vector sum of two vectors." ),
"vectorsum" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_vectorsum", 0 ) );
c = new SimpleObjectTypeConstructor(
LineByVectorType::instance(),
I18N_NOOP( "Line by Vector" ),
I18N_NOOP( "Construct the line by a given vector though a given point." ),
"linebyvector" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_linebyvector", 0 ) );
c = new SimpleObjectTypeConstructor(
HalflineByVectorType::instance(),
I18N_NOOP( "Half-Line by Vector" ),
I18N_NOOP( "Construct the half-line by a given vector starting at given point." ),
"halflinebyvector" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_halflinebyvector", 0 ) );
c = new SimpleObjectTypeConstructor(
ArcBTPType::instance(),
I18N_NOOP( "Arc by Three Points" ),
I18N_NOOP( "Construct an arc through three points." ),
"arc" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_arcbtp" ) );
c = new SimpleObjectTypeConstructor(
ConicArcBCTPType::instance(),
I18N_NOOP( "Conic Arc by Center and Three Points" ),
I18N_NOOP( "Construct a conic arc with given center through three points." ),
"conicarc" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_conicarcbctp" ) );
c = new SimpleObjectTypeConstructor(
ConicArcB5PType::instance(),
I18N_NOOP( "Conic Arc by Five Points" ),
I18N_NOOP( "Construct a conic arc through five points." ),
"conicarc" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_conicarcb5p" ) );
c = new SimpleObjectTypeConstructor(
ArcBCPAType::instance(),
I18N_NOOP( "Arc by Center, Angle && Point" ),
I18N_NOOP( "Construct an arc by its center and a given angle, "
"starting at a given point" ),
"arcbcpa" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_arcbcpa" ) );
c = new SimpleObjectTypeConstructor(
ParabolaBDPType::instance(),
I18N_NOOP( "Parabola by Directrix && Focus" ),
I18N_NOOP( "A parabola defined by its directrix and focus" ),
"parabolabdp" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_parabolabdp" ) );
// Transformation stuff..
// c = new SimpleObjectTypeConstructor(
// CircularInversionType::instance(),
// I18N_NOOP( "Invert" ),
// I18N_NOOP( "The inversion of an object with respect to a circle" ),
// "inversion" );
// ctors->add( c );
// actions->add( new ConstructibleAction( c, "objects_new_inversion" ) );
c = new InversionConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_inversion" ) );
c = new SimpleObjectTypeConstructor(
TranslatedType::instance(),
I18N_NOOP( "Translate" ),
I18N_NOOP( "The translation of an object by a vector" ),
"translation" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_translation" ) );
c = new SimpleObjectTypeConstructor(
PointReflectionType::instance(),
I18N_NOOP( "Reflect in Point" ),
I18N_NOOP( "An object reflected in a point" ),
"centralsymmetry" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_pointreflection" ) );
c = new SimpleObjectTypeConstructor(
LineReflectionType::instance(),
I18N_NOOP( "Reflect in Line" ),
I18N_NOOP( "An object reflected in a line" ),
"mirrorpoint" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_linereflection" ) );
c = new SimpleObjectTypeConstructor(
RotationType::instance(),
I18N_NOOP( "Rotate" ),
I18N_NOOP( "An object rotated by an angle around a point" ),
"rotation" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_rotation" ) );
c = new SimpleObjectTypeConstructor(
ScalingOverCenterType::instance(),
I18N_NOOP( "Scale" ),
I18N_NOOP( "Scale an object over a point, by the ratio given by the length of a segment" ),
"scale" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_scalingovercenter" ) );
c = new SimpleObjectTypeConstructor(
ScalingOverLineType::instance(),
I18N_NOOP( "Scale over Line" ),
I18N_NOOP( "An object scaled over a line, by the ratio given by the length of a segment" ),
"stretch" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_scalingoverline" ) );
c = new SimpleObjectTypeConstructor(
ScalingOverCenter2Type::instance(),
I18N_NOOP( "Scale (ratio given by two segments)" ),
I18N_NOOP( "Scale an object over a point, by the ratio given by the length of two segments" ),
"scale" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_scalingovercenter2" ) );
c = new SimpleObjectTypeConstructor(
ScalingOverLine2Type::instance(),
I18N_NOOP( "Scale over Line (ratio given by two segments)" ),
I18N_NOOP( "An object scaled over a line, by the ratio given by the length of two segments" ),
"stretch" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_scalingoverline2" ) );
c = new SimpleObjectTypeConstructor(
SimilitudeType::instance(),
I18N_NOOP( "Apply Similitude" ),
I18N_NOOP( "Apply a similitude to an object (the sequence of a scaling and rotation around a center)" ),
"similitude" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_similitude" ) );
c = new SimpleObjectTypeConstructor(
HarmonicHomologyType::instance(),
I18N_NOOP( "Harmonic Homology" ),
I18N_NOOP( "The harmonic homology with a given center and a given axis (this is a projective transformation)" ),
"harmonichomology" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_harmonichomology" ) );
c = new GenericAffinityConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_genericaffinity" ) );
c = new GenericProjectivityConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_genericprojectivity" ) );
c = new SimpleObjectTypeConstructor(
CastShadowType::instance(),
I18N_NOOP( "Draw Projective Shadow" ),
I18N_NOOP( "The shadow of an object with a given light source and projection plane (indicated by a line)" ),
"castshadow" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_castshadow" ) );
// c = new SimpleObjectTypeConstructor(
// ProjectiveRotationType::instance(),
// I18N_NOOP( "Rotate Projectively" ),
// I18N_NOOP( "An object projectively rotated by an angle and a half-line" ),
// "projectiverotation" );
// ctors->add( c );
// actions->add( new ConstructibleAction( c, "objects_new_projectiverotation" ) );
c = new MultiObjectTypeConstructor(
ConicAsymptoteType::instance(),
I18N_NOOP( "Asymptotes of a Hyperbola" ),
I18N_NOOP( "The two asymptotes of a hyperbola." ),
"conicasymptotes", -1, 1 );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_lineconicasymptotes" ) );
c = new ConicRadicalConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_lineconicradical") );
/* ----------- start polygons --------- */
c = new SimpleObjectTypeConstructor(
TriangleB3PType::instance(),
I18N_NOOP( "Triangle by Its Vertices" ),
I18N_NOOP( "Construct a triangle given its three vertices." ),
"triangle" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_trianglebtp" ) );
c = new PolygonBNPTypeConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_polygonbnp" ));
c = new OpenPolygonTypeConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_openpolygon" ));
c = new PolygonBCVConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_polygonbcv" ) );
c = new PolygonVertexTypeConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_polygonvertices" ));
c = new PolygonSideTypeConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_polygonsides" ));
c = new SimpleObjectTypeConstructor(
ConvexHullType::instance(), I18N_NOOP( "Convex Hull" ),
I18N_NOOP( "A polygon that corresponds to the convex hull of another polygon" ),
"convexhull" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_convexhull" ) );
/* ----------- end polygons --------- */
/* ----------- start bezier --------- */
c = new SimpleObjectTypeConstructor(
BezierQuadricType::instance(),
I18N_NOOP( "Bézier Quadratic by its Control Points" ),
I18N_NOOP( "Construct a Bézier quadratic given its three control points." ),
"bezier3" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_bezierquadratic" ) );
c = new SimpleObjectTypeConstructor(
BezierCubicType::instance(),
I18N_NOOP( "Bézier Cubic by its Control Points" ),
I18N_NOOP( "Construct a Bézier cubic given its four control points." ),
"bezier4" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_beziercubic" ) );
c = new BezierCurveTypeConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_beziercurve" ));
c = new SimpleObjectTypeConstructor(
RationalBezierQuadricType::instance(),
I18N_NOOP( "Rational Bézier Quadratic by its Control Points" ),
I18N_NOOP( "Construct a Rational Bézier quadratic given its three control points." ),
"rbezier3" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_rationalbezierquadratic" ) );
c = new SimpleObjectTypeConstructor(
RationalBezierCubicType::instance(),
I18N_NOOP( "Rational Bézier Cubic by its Control Points" ),
I18N_NOOP( "Construct a Rational Bézier cubic given its four control points." ),
"rbezier4" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_rationalbeziercubic" ) );
c = new RationalBezierCurveTypeConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_rationalbeziercurve" ));
/* ----------- end bezier ----------- */
c = new LocusConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_locus" ) );
// tests
c = new TestConstructor(
AreParallelType::instance(),
I18N_NOOP( "Parallel Test" ),
I18N_NOOP( "Test whether two given lines are parallel" ),
"testparallel" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_areparallel" ) );
c = new TestConstructor(
AreOrthogonalType::instance(),
I18N_NOOP( "Orthogonal Test" ),
I18N_NOOP( "Test whether two given lines are orthogonal" ),
"testorthogonal" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_areorthogonal" ) );
c = new TestConstructor(
AreCollinearType::instance(),
I18N_NOOP( "Collinear Test" ),
I18N_NOOP( "Test whether three given points are collinear" ),
"testcollinear" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_arecollinear" ) );
c = new TestConstructor(
ContainsTestType::instance(),
I18N_NOOP( "Contains Test" ),
I18N_NOOP( "Test whether a given curve contains a given point" ),
"testcontains" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_containstest" ) );
c = new TestConstructor(
InPolygonTestType::instance(),
I18N_NOOP( "In Polygon Test" ),
I18N_NOOP( "Test whether a given polygon contains a given point" ),
"test" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_inpolygontest" ) );
c = new TestConstructor(
ConvexPolygonTestType::instance(),
I18N_NOOP( "Convex Polygon Test" ),
I18N_NOOP( "Test whether a given polygon is convex" ),
"test" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_convexpolygontest" ) );
c = new TestConstructor(
ExistenceTestType::instance(),
I18N_NOOP( "Existence Test" ),
I18N_NOOP( "Test whether a given object is constructible" ),
"test" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_existencetest" ) );
c = new TestConstructor(
SameDistanceType::instance(),
I18N_NOOP( "Distance Test" ),
I18N_NOOP( "Test whether a given point have the same distance from a given point "
"and from another given point" ),
"testdistance" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_distancetest" ) );
c = new TestConstructor(
VectorEqualityTestType::instance(),
I18N_NOOP( "Vector Equality Test" ),
I18N_NOOP( "Test whether two vectors are equal" ),
"test" );
// "testequal" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_vectorequalitytest" ) );
c = new MeasureTransportConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_measuretransport" ));
// c = new SimpleObjectTypeConstructor(
// MeasureTransportType::instance(),
// I18N_NOOP( "Measure Transport" ),
// I18N_NOOP( "Transport the measure of a segment or arc over a line or circle." ),
// "measuretransport" );
// ctors->add( c );
// actions->add( new ConstructibleAction( c, "objects_new_measuretransport" ) );
c = new SimpleObjectTypeConstructor(
ProjectedPointType::instance(),
I18N_NOOP( "Point Projection" ),
I18N_NOOP( "Project a point on a line" ),
"projection" );
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_projection" ) );
// the generic intersection constructor..
c = new GenericIntersectionConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_intersection", Qt::Key_I ) );
// the generic tangent constructor
c = new TangentConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_tangent", Qt::Key_T ) );
// the generic center of curvature constructor
c = new CocConstructor();
ctors->add( c );
actions->add( new ConstructibleAction( c, "objects_new_centerofcurvature" ) );
actions->add( new ConstructPointAction( "objects_new_normalpoint" ) );
actions->add( new ConstructTextLabelAction( "objects_new_textlabel" ) );
actions->add( new AddFixedPointAction( "objects_new_point_xy" ) );
actions->add( new ConstructNumericLabelAction( "objects_new_numericlabel" ) );
#ifdef KIG_ENABLE_PYTHON_SCRIPTING
#include "../scripting/script-common.h"
actions->add( new NewScriptAction(
I18N_NOOP( "Python Script" ),
I18N_NOOP( "Construct a new Python script." ),
"objects_new_script_python",
ScriptType::Python ) );
#endif
#if 0
actions->add( new TestAction( "test_stuff" ) );
#endif
};
done = true;
}
diff --git a/misc/special_constructors.cc b/misc/special_constructors.cc
index 8b096cf6..794e8ce5 100644
--- a/misc/special_constructors.cc
+++ b/misc/special_constructors.cc
@@ -1,2317 +1,2377 @@
// Copyright (C) 2003 Dominique Devriese
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301, USA.
#include "special_constructors.h"
#include
#include "calcpaths.h"
#include "common.h"
#include "conic-common.h"
#include "guiaction.h"
#include "kigpainter.h"
#include "../kig/kig_part.h"
#include "../kig/kig_document.h"
#include "../modes/construct_mode.h"
#include "../objects/special_imptypes.h"
#include "../objects/bogus_imp.h"
#include "../objects/centerofcurvature_type.h"
#include "../objects/circle_imp.h"
#include "../objects/conic_imp.h"
#include "../objects/conic_types.h"
#include "../objects/cubic_imp.h"
#include "../objects/intersection_types.h"
#include "../objects/inversion_type.h"
#include "../objects/line_imp.h"
#include "../objects/line_type.h"
#include "../objects/locus_imp.h"
#include "../objects/object_calcer.h"
#include "../objects/object_drawer.h"
#include "../objects/object_factory.h"
#include "../objects/object_holder.h"
#include "../objects/object_imp.h"
#include "../objects/object_type.h"
#include "../objects/other_imp.h"
#include "../objects/other_type.h"
#include "../objects/point_imp.h"
#include "../objects/point_type.h"
#include "../objects/polygon_imp.h"
#include "../objects/polygon_type.h"
#include "../objects/bezier_imp.h"
#include "../objects/bezier_type.h"
#include "../objects/tangent_type.h"
#include "../objects/text_imp.h"
#include "../objects/transform_types.h"
#include
#include
#include
#include
/*
* conic-line and circle-circle intersection (with search for already computed
* intersections)
* the previous "ConicLineIntersectionConstructor" is now
* dead code, which could be remove in the future
*/
TwoOrOneIntersectionConstructor::TwoOrOneIntersectionConstructor(
const ArgsParserObjectType* t_std,
const ArgsParserObjectType* t_special,
const char* iconfile,
const struct ArgsParser::spec argsspecv[] )
: StandardConstructorBase( "SHOULD NOT BE SEEN", "SHOULD NOT BE SEEN",
iconfile, margsparser ),
mtype_std( t_std ),
mtype_special( t_special ),
margsparser( argsspecv, 2 )
{
}
TwoOrOneIntersectionConstructor::~TwoOrOneIntersectionConstructor()
{
}
void TwoOrOneIntersectionConstructor::drawprelim(
const ObjectDrawer& drawer,
KigPainter& p,
const std::vector& parents,
const KigDocument& doc ) const
{
Args args;
if ( parents.size() != 2 ) return;
transform( parents.begin(), parents.end(),
back_inserter( args ), std::mem_fun( &ObjectCalcer::imp ) );
for ( int i = -1; i <= 1; i += 2 )
{
IntImp param( i );
args.push_back( ¶m );
ObjectImp* data = mtype_std->calc( args, doc );
drawer.draw( *data, p, true );
delete data;
args.pop_back();
}
}
std::vector removeDuplicatedPoints( std::vector points )
{
std::vector ret;
for ( std::vector::iterator i = points.begin();
i != points.end(); ++i )
{
for ( std::vector::iterator j = ret.begin();
j != ret.end(); ++j )
{
if ( coincidentPoints( (*i)->imp(), (*j)->imp() ) ) break;
}
ret.push_back( *i );
}
return ret;
}
bool coincidentPoints( const ObjectImp* p1, const ObjectImp* p2 )
{
const PointImp* pt1 = dynamic_cast( p1 );
if ( !pt1 ) return false;
const PointImp* pt2 = dynamic_cast( p2 );
if ( !pt2 ) return false;
Coordinate diff = pt1->coordinate() - pt2->coordinate();
if ( diff.squareLength() < 1e-12 ) return true;
return false;
}
std::vector TwoOrOneIntersectionConstructor::build(
const std::vector& parents,
KigDocument& doc,
KigWidget& ) const
{
std::vector ret;
assert( parents.size() == 2 );
std::vector points = doc.findIntersectionPoints( parents[0], parents[1] );
std::vector uniquepoints = removeDuplicatedPoints( points );
if ( uniquepoints.size() == 1 )
{
std::vector args( parents );
args.push_back( uniquepoints[0] );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer(
mtype_special, args
) ) );
return ret;
}
for ( int i = -1; i <= 1; i += 2 )
{
ObjectConstCalcer* d = new ObjectConstCalcer( new IntImp( i ) );
std::vector args( parents );
args.push_back( d );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer(
mtype_std, args
) ) );
}
return ret;
}
void TwoOrOneIntersectionConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool TwoOrOneIntersectionConstructor::isTransform() const
{
return false;
}
ThreeTwoOneIntersectionConstructor::ThreeTwoOneIntersectionConstructor(
const ArgsParserObjectType* t_std,
const ArgsParserObjectType* t_special,
const char* iconfile,
const struct ArgsParser::spec argsspecv[] )
: StandardConstructorBase( "SHOULD NOT BE SEEN", "SHOULD NOT BE SEEN",
iconfile, margsparser ),
mtype_std( t_std ),
mtype_special( t_special ),
margsparser( argsspecv, 2 )
{
}
ThreeTwoOneIntersectionConstructor::~ThreeTwoOneIntersectionConstructor()
{
}
void ThreeTwoOneIntersectionConstructor::drawprelim(
const ObjectDrawer& drawer,
KigPainter& p,
const std::vector& parents,
const KigDocument& doc ) const
{
Args args;
if ( parents.size() != 2 ) return;
transform( parents.begin(), parents.end(),
back_inserter( args ), std::mem_fun( &ObjectCalcer::imp ) );
for ( int i = 1; i <= 3; i += 1 )
{
IntImp param( i );
args.push_back( ¶m );
ObjectImp* data = mtype_std->calc( args, doc );
drawer.draw( *data, p, true );
delete data;
args.pop_back();
}
}
std::vector ThreeTwoOneIntersectionConstructor::build(
const std::vector& parents,
KigDocument& doc,
KigWidget& ) const
{
std::vector ret;
assert( parents.size() == 2 );
std::vector points = doc.findIntersectionPoints( parents[0], parents[1] );
std::vector uniquepoints = removeDuplicatedPoints( points );
if ( uniquepoints.size() == 2 )
{
std::vector args( parents );
args.push_back( uniquepoints[0] );
args.push_back( uniquepoints[1] );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer(
mtype_special, args
) ) );
return ret;
}
if ( uniquepoints.size() == 1 )
{
for ( int i = -1; i <= 1; i += 2 )
{
std::vector args( parents );
args.push_back( uniquepoints[0] );
ObjectConstCalcer* d = new ObjectConstCalcer( new IntImp( i ) );
args.push_back( d );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer(
CubicLineTwoIntersectionType::instance(), args
) ) );
args.clear();
}
return ret;
}
for ( int i = 1; i <= 3; i += 1 )
{
ObjectConstCalcer* d = new ObjectConstCalcer( new IntImp( i ) );
std::vector args( parents );
args.push_back( d );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer(
mtype_std, args
) ) );
}
return ret;
}
void ThreeTwoOneIntersectionConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool ThreeTwoOneIntersectionConstructor::isTransform() const
{
return false;
}
/*
* conic-conic intersection
*/
class ConicConicIntersectionConstructor
: public StandardConstructorBase
{
protected:
ArgsParser mparser;
public:
ConicConicIntersectionConstructor();
~ConicConicIntersectionConstructor();
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const Q_DECL_OVERRIDE;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const Q_DECL_OVERRIDE;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
class ConicLineIntersectionConstructor
: public MultiObjectTypeConstructor
{
public:
ConicLineIntersectionConstructor();
~ConicLineIntersectionConstructor();
};
class ArcLineIntersectionConstructor
: public MultiObjectTypeConstructor
{
public:
ArcLineIntersectionConstructor();
~ArcLineIntersectionConstructor();
};
ConicRadicalConstructor::ConicRadicalConstructor()
: StandardConstructorBase(
I18N_NOOP( "Radical Lines for Conics" ),
I18N_NOOP( "The lines constructed through the intersections "
"of two conics. This is also defined for "
"non-intersecting conics." ),
"conicsradicalline", mparser ),
mtype( ConicRadicalType::instance() ),
mparser( mtype->argsParser().without( IntImp::stype() ) )
{
}
ConicRadicalConstructor::~ConicRadicalConstructor()
{
}
void ConicRadicalConstructor::drawprelim(
const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& doc ) const
{
if ( parents.size() == 2 && parents[0]->imp()->inherits( ConicImp::stype() ) &&
parents[1]->imp()->inherits( ConicImp::stype() ) )
{
Args args;
std::transform( parents.begin(), parents.end(),
std::back_inserter( args ), std::mem_fun( &ObjectCalcer::imp ) );
for ( int i = -1; i < 2; i += 2 )
{
IntImp root( i );
IntImp zeroindex( 1 );
args.push_back( &root );
args.push_back( &zeroindex );
ObjectImp* data = mtype->calc( args, doc );
drawer.draw( *data, p, true );
delete data; data = 0;
args.pop_back();
args.pop_back();
};
};
}
std::vector ConicRadicalConstructor::build( const std::vector& os, KigDocument&, KigWidget& ) const
{
using namespace std;
std::vector ret;
ObjectCalcer* zeroindexcalcer = new ObjectConstCalcer( new IntImp( 1 ) );
for ( int i = -1; i < 2; i += 2 )
{
std::vector args;
std::copy( os.begin(), os.end(), back_inserter( args ) );
args.push_back( new ObjectConstCalcer( new IntImp( i ) ) );
// we use only one zeroindex dataobject, so that if you switch one
// radical line around, then the other switches along..
args.push_back( zeroindexcalcer );
ret.push_back(
new ObjectHolder( new ObjectTypeCalcer( mtype, args ) ) );
};
return ret;
}
static const struct ArgsParser::spec argsspecpp[] =
{
{ PointImp::stype(), I18N_NOOP( "Moving Point" ),
I18N_NOOP( "Select the moving point, which will be moved around while drawing the locus..." ), false },
{ PointImp::stype(), I18N_NOOP( "Following Point" ),
I18N_NOOP( "Select the following point, whose locations the locus will be drawn through..." ), true }
};
LocusConstructor::LocusConstructor()
: StandardConstructorBase( I18N_NOOP( "Locus" ), I18N_NOOP( "A locus" ),
"locus", margsparser ),
margsparser( argsspecpp, 2 )
{
}
LocusConstructor::~LocusConstructor()
{
}
void LocusConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
// this function is rather ugly, but it is necessary to do it this
// way in order to play nice with Kig's design..
if ( parents.size() != 2 ) return;
const ObjectTypeCalcer* constrained = dynamic_cast( parents.front() );
const ObjectCalcer* moving = parents.back();
if ( ! constrained || ! constrained->type()->inherits( ObjectType::ID_ConstrainedPointType ) )
{
// moving is in fact the constrained point.. swap them..
moving = parents.front();
constrained = dynamic_cast( parents.back() );
assert( constrained );
};
assert( constrained->type()->inherits( ObjectType::ID_ConstrainedPointType ) );
const ObjectImp* oimp = constrained->parents().back()->imp();
if( !oimp->inherits( CurveImp::stype() ) )
oimp = constrained->parents().front()->imp();
assert( oimp->inherits( CurveImp::stype() ) );
const CurveImp* cimp = static_cast( oimp );
ObjectHierarchy hier( constrained, moving );
LocusImp limp( cimp->copy(), hier );
drawer.draw( limp, p, true );
}
int LocusConstructor::wantArgs(
const std::vector& os, const KigDocument&, const KigWidget&
) const
{
int ret = margsparser.check( os );
if ( ret == ArgsParser::Invalid ) return ret;
else if ( os.size() != 2 ) return ret;
if ( dynamic_cast( os.front() ) &&
static_cast( os.front() )->type()->inherits( ObjectType::ID_ConstrainedPointType ) )
{
std::set children = getAllChildren( os.front() );
return children.find( os.back() ) != children.end() ? ret : ArgsParser::Invalid;
}
if ( dynamic_cast( os.back() ) &&
static_cast( os.back() )->type()->inherits( ObjectType::ID_ConstrainedPointType ) )
{
std::set children = getAllChildren( os.back() );
return children.find( os.front() ) != children.end() ? ret : ArgsParser::Invalid;
}
return ArgsParser::Invalid;
}
std::vector LocusConstructor::build( const std::vector& parents, KigDocument&, KigWidget& ) const
{
std::vector ret;
assert( parents.size() == 2 );
ObjectTypeCalcer* constrained = dynamic_cast( parents.front() );
ObjectCalcer* moving = parents.back();
if ( ! constrained || ! constrained->type()->inherits( ObjectType::ID_ConstrainedPointType ) )
{
// moving is in fact the constrained point.. swap them..
moving = parents.front();
constrained = dynamic_cast( parents.back() );
assert( constrained );
};
assert( constrained->type()->inherits( ObjectType::ID_ConstrainedPointType ) );
ret.push_back( ObjectFactory::instance()->locus( constrained, moving ) );
return ret;
}
QString LocusConstructor::useText( const ObjectCalcer& o, const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
if ( dynamic_cast( &o ) &&
static_cast( o ).type()->inherits( ObjectType::ID_ConstrainedPointType ) &&
( os.empty() || !dynamic_cast( os[0] ) ||
!static_cast( os[0] )->type()->inherits( ObjectType::ID_ConstrainedPointType ) )
) return i18n( "Moving Point" );
else return i18n( "Dependent Point" );
}
void ConicRadicalConstructor::plug( KigPart*, KigGUIAction* )
{
}
void LocusConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool ConicRadicalConstructor::isTransform() const
{
return mtype->isTransform();
}
bool LocusConstructor::isTransform() const
{
return false;
}
/*
* generic sequence of points constructor
*/
PointSequenceConstructor::PointSequenceConstructor(
const char* descname,
const char* desc,
const char* iconfile,
const ObjectType* type )
: mdescname( descname ),
mdesc( desc ),
miconfile( iconfile ),
mtype( type )
{
}
const QString PointSequenceConstructor::descriptiveName() const
{
return i18n( mdescname );
}
const QString PointSequenceConstructor::description() const
{
return i18n( mdesc );
}
const QByteArray PointSequenceConstructor::iconFileName( const bool ) const
{
return miconfile;
}
void PointSequenceConstructor::handleArgs(
const std::vector& os, KigPart& d,
KigWidget& v ) const
{
std::vector bos = build( os, d.document(), v );
for ( std::vector::iterator i = bos.begin();
i != bos.end(); ++i )
{
(*i)->calc( d.document() );
}
d.addObjects( bos );
}
void PointSequenceConstructor::handlePrelim(
KigPainter& p, const std::vector& os,
const KigDocument& d, const KigWidget&
) const
{
uint count = os.size();
if ( count < 2 ) return;
for ( uint i = 0; i < count; i++ )
{
assert ( os[i]->imp()->inherits( PointImp::stype() ) );
}
std::vector args = os;
p.setBrushStyle( Qt::NoBrush );
p.setBrushColor( Qt::red );
p.setPen( QPen ( Qt::red, 1) );
p.setWidth( -1 ); // -1 means the default width for the object being
// drawn..
ObjectDrawer drawer( Qt::red );
drawprelim( drawer, p, args, d );
}
std::vector PointSequenceConstructor::build( const std::vector& parents, KigDocument&, KigWidget& ) const
{
uint count = parents.size() - 1;
assert ( count >= 3 );
std::vector args;
for ( uint i = 0; i < count; ++i ) args.push_back( parents[i] );
ObjectTypeCalcer* calcer = new ObjectTypeCalcer( mtype, args );
ObjectHolder* h = new ObjectHolder( calcer );
std::vector ret;
ret.push_back( h );
return ret;
}
void PointSequenceConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool PointSequenceConstructor::isTransform() const
{
return false;
}
/*
* generic polygon constructor
*/
PolygonBNPTypeConstructor::PolygonBNPTypeConstructor()
: PointSequenceConstructor(
I18N_NOOP( "Polygon by Its Vertices" ),
I18N_NOOP( "Construct a polygon by giving its vertices" ),
"kig_polygon",
PolygonBNPType::instance() )
{
}
PolygonBNPTypeConstructor::~PolygonBNPTypeConstructor()
{
}
bool PolygonBNPTypeConstructor::isAlreadySelectedOK(
const std::vector& os, const uint& pos ) const
{
if ( pos == 0 && os.size() >= 3 ) return true;
return false;
}
int PolygonBNPTypeConstructor::wantArgs( const std::vector& os,
const KigDocument&,
const KigWidget& ) const
{
int count=os.size() - 1;
for ( int i = 0; i <= count; i++ )
{
if ( ! ( os[i]->imp()->inherits( PointImp::stype() ) ) ) return ArgsParser::Invalid;
}
if ( count < 3 ) return ArgsParser::Valid;
if ( os[0] == os[count] ) return ArgsParser::Complete;
return ArgsParser::Valid;
}
QString PolygonBNPTypeConstructor::useText( const ObjectCalcer&, const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
if ( os.size() > 3 )
return i18n("... with this vertex (click on the first vertex to terminate construction)");
else return i18n("Construct a polygon with this vertex");
}
QString PolygonBNPTypeConstructor::selectStatement(
const std::vector&, const KigDocument&,
const KigWidget& ) const
{
return i18n("Select a point to be a vertex of the new polygon...");
}
void PolygonBNPTypeConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() < 2 ) return;
std::vector points;
for ( uint i = 0; i < parents.size(); ++i )
{
const Coordinate vertex =
static_cast( parents[i]->imp() )->coordinate();
points.push_back( vertex );
}
if ( parents.size() == 2 )
{
SegmentImp segment = SegmentImp( points[0], points[1] );
drawer.draw( segment, p, true );
} else {
FilledPolygonImp polygon = FilledPolygonImp( points );
drawer.draw( polygon, p, true );
}
}
/*
* open polygon (polyline) constructor
*/
OpenPolygonTypeConstructor::OpenPolygonTypeConstructor()
: PointSequenceConstructor(
I18N_NOOP( "Open Polygon (Polygonal Line)" ),
I18N_NOOP( "Construct an open polygon" ),
"openpolygon",
OpenPolygonType::instance() )
{
}
OpenPolygonTypeConstructor::~OpenPolygonTypeConstructor()
{
}
bool OpenPolygonTypeConstructor::isAlreadySelectedOK(
const std::vector& os, const uint& pos ) const
{
if ( pos == os.size() - 1 && os.size() >= 2 ) return true;
return false;
}
int OpenPolygonTypeConstructor::wantArgs( const std::vector& os,
const KigDocument&,
const KigWidget& ) const
{
int count=os.size() - 1;
for ( int i = 0; i <= count; i++ )
{
if ( ! ( os[i]->imp()->inherits( PointImp::stype() ) ) ) return ArgsParser::Invalid;
}
if ( count < 2 ) return ArgsParser::Valid;
if ( os[count] == os[count - 1] ) return ArgsParser::Complete;
return ArgsParser::Valid;
}
QString OpenPolygonTypeConstructor::useText( const ObjectCalcer&, const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
if ( os.size() > 2 )
return i18n("... with this vertex (click again on the last vertex to terminate construction)");
else return i18n("Construct a polygonal line with this vertex");
}
QString OpenPolygonTypeConstructor::selectStatement(
const std::vector&, const KigDocument&,
const KigWidget& ) const
{
return i18n("Select a point to be a vertex of the new polygonal line...");
}
void OpenPolygonTypeConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() < 2 ) return;
std::vector points;
for ( uint i = 0; i < parents.size(); ++i )
{
const Coordinate vertex =
static_cast( parents[i]->imp() )->coordinate();
points.push_back( vertex );
}
if ( parents.size() == 2 )
{
SegmentImp segment = SegmentImp( points[0], points[1] );
drawer.draw( segment, p, true );
} else {
OpenPolygonalImp polygon = OpenPolygonalImp( points );
drawer.draw( polygon, p, true );
}
}
/*
* construction of polygon vertices
*/
static const struct ArgsParser::spec argsspecpv[] =
{
{ FilledPolygonImp::stype(), I18N_NOOP( "Polygon" ),
I18N_NOOP( "Construct the vertices of this polygon..." ), true }
};
PolygonVertexTypeConstructor::PolygonVertexTypeConstructor()
: StandardConstructorBase( I18N_NOOP( "Vertices of a Polygon" ),
I18N_NOOP( "The vertices of a polygon." ),
"polygonvertices", margsparser ),
mtype( PolygonVertexType::instance() ),
margsparser( argsspecpv, 1 )
{
}
PolygonVertexTypeConstructor::~PolygonVertexTypeConstructor()
{
}
void PolygonVertexTypeConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() != 1 ) return;
const FilledPolygonImp* polygon = dynamic_cast( parents.front()->imp() );
const std::vector points = polygon->points();
int sides = points.size();
for ( int i = 0; i < sides; ++i )
{
PointImp point = PointImp( points[i] );
drawer.draw( point, p, true );
}
}
std::vector PolygonVertexTypeConstructor::build( const std::vector& parents, KigDocument&, KigWidget& ) const
{
std::vector ret;
assert( parents.size() == 1 );
const FilledPolygonImp* polygon = dynamic_cast( parents.front()->imp() );
const std::vector points = polygon->points();
int sides = points.size();
for ( int i = 0; i < sides; ++i )
{
ObjectConstCalcer* d = new ObjectConstCalcer( new IntImp( i ) );
std::vector args( parents );
args.push_back( d );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer( mtype, args ) ) );
}
return ret;
}
void PolygonVertexTypeConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool PolygonVertexTypeConstructor::isTransform() const
{
return false;
}
/*
* construction of polygon sides
*/
static const struct ArgsParser::spec argsspecps[] =
{
{ FilledPolygonImp::stype(), I18N_NOOP( "Polygon" ),
I18N_NOOP( "Construct the sides of this polygon..." ), false }
};
PolygonSideTypeConstructor::PolygonSideTypeConstructor()
: StandardConstructorBase( I18N_NOOP( "Sides of a Polygon" ),
I18N_NOOP( "The sides of a polygon." ),
"polygonsides", margsparser ),
mtype( PolygonSideType::instance() ),
margsparser( argsspecps, 1 )
{
}
PolygonSideTypeConstructor::~PolygonSideTypeConstructor()
{
}
void PolygonSideTypeConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() != 1 ) return;
const FilledPolygonImp* polygon = dynamic_cast( parents.front()->imp() );
const std::vector points = polygon->points();
uint sides = points.size();
for ( uint i = 0; i < sides; ++i )
{
uint nexti = ( i + 1 < sides )?(i + 1):0;
SegmentImp segment = SegmentImp( points[i], points[nexti] );
drawer.draw( segment, p, true );
}
}
std::vector PolygonSideTypeConstructor::build( const std::vector& parents, KigDocument&, KigWidget& ) const
{
std::vector ret;
assert( parents.size() == 1 );
const FilledPolygonImp* polygon = dynamic_cast( parents.front()->imp() );
const std::vector points = polygon->points();
uint sides = points.size();
for ( uint i = 0; i < sides; ++i )
{
ObjectConstCalcer* d = new ObjectConstCalcer( new IntImp( i ) );
std::vector args( parents );
args.push_back( d );
ret.push_back( new ObjectHolder( new ObjectTypeCalcer( mtype, args ) ) );
}
return ret;
}
void PolygonSideTypeConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool PolygonSideTypeConstructor::isTransform() const
{
return false;
}
/*
* polygon by center and vertex
*/
PolygonBCVConstructor::PolygonBCVConstructor()
: mtype( PolygonBCVType::instance() )
{
}
PolygonBCVConstructor::~PolygonBCVConstructor()
{
}
const QString PolygonBCVConstructor::descriptiveName() const
{
return i18n("Regular Polygon with Given Center");
}
const QString PolygonBCVConstructor::description() const
{
return i18n("Construct a regular polygon with a given center and vertex");
}
const QByteArray PolygonBCVConstructor::iconFileName( const bool ) const
{
return "hexagonbcv";
}
bool PolygonBCVConstructor::isAlreadySelectedOK(
const std::vector&, const uint& ) const
{
return false;
}
int PolygonBCVConstructor::wantArgs( const std::vector& os,
const KigDocument&,
const KigWidget& ) const
{
if ( os.size() > 3 ) return ArgsParser::Invalid;
uint imax = ( os.size() <= 2) ? os.size() : 2;
for ( uint i = 0; i < imax; ++i )
if ( ! ( os[i]->imp()->inherits( PointImp::stype() ) ) ) return ArgsParser::Invalid;
if ( os.size() < 3 ) return ArgsParser::Valid;
if ( ! ( os[2]->imp()->inherits( BogusPointImp::stype() ) ) )
return ArgsParser::Invalid;
return ArgsParser::Complete;
}
void PolygonBCVConstructor::handleArgs(
const std::vector& os, KigPart& d,
KigWidget& v ) const
{
std::vector bos = build( os, d.document(), v );
for ( std::vector::iterator i = bos.begin();
i != bos.end(); ++i )
{
(*i)->calc( d.document() );
}
d.addObjects( bos );
}
void PolygonBCVConstructor::handlePrelim(
KigPainter& p, const std::vector& os,
const KigDocument& d, const KigWidget&
) const
{
if ( os.size() < 2 ) return;
for ( uint i = 0; i < 2; i++ )
{
assert ( os[i]->imp()->inherits( PointImp::stype() ) );
}
Coordinate c = static_cast( os[0]->imp() )->coordinate();
Coordinate v = static_cast( os[1]->imp() )->coordinate();
int nsides = 6;
bool moreinfo = false;
int winding = 0; // 0 means allow winding > 1
if ( os.size() == 3 )
{
assert ( os[2]->imp()->inherits( BogusPointImp::stype() ) );
Coordinate cntrl = static_cast( os[2]->imp() )->coordinate();
nsides = computeNsides( c, v, cntrl, winding );
moreinfo = true;
}
std::vector args;
args.push_back( os[0] );
args.push_back( os[1] );
ObjectConstCalcer* ns = new ObjectConstCalcer( new IntImp( nsides ) );
args.push_back( ns );
if ( winding > 1 )
{
ns = new ObjectConstCalcer( new IntImp( winding ) );
args.push_back( ns );
}
p.setBrushStyle( Qt::NoBrush );
p.setBrushColor( Qt::red );
p.setPen( QPen ( Qt::red, 1) );
p.setWidth( -1 ); // -1 means the default width for the object being
// drawn..
ObjectDrawer drawer( Qt::red );
drawprelim( drawer, p, args, d );
if ( moreinfo )
{
p.setPointStyle( Kig::RoundEmpty );
p.setWidth( 6 );
double ro = 1.0/(2.5);
Coordinate where = getRotatedCoord( c, (1-ro)*c+ro*v, 4*M_PI/5.0 );
PointImp ptn = PointImp( where );
TextImp text = TextImp( "(5,2)", where, false );
ptn.draw( p );
text.draw( p );
for ( int i = 3; i < 9; ++i )
{
where = getRotatedCoord( c, v, 2.0*M_PI/i );
ptn = PointImp( where );
ptn.draw( p );
if ( i > 5 ) continue;
text = TextImp( QString( "(%1)" ).arg(i), where, false );
text.draw( p );
}
p.setStyle( Qt::DotLine );
p.setWidth( 1 );
double radius = ( v - c ).length();
CircleImp circle = CircleImp( c, radius );
circle.draw( p );
for ( int i = 2; i < 5; i++ )
{
ro = 1.0/(i+0.5);
CircleImp circle = CircleImp( c, ro*radius );
circle.draw( p );
}
}
delete_all( args.begin() + 2, args.end() );
}
std::vector PolygonBCVConstructor::build( const std::vector& parents, KigDocument&, KigWidget& ) const
{
assert ( parents.size() == 3 );
std::vector args;
Coordinate c = static_cast( parents[0]->imp() )->coordinate();
Coordinate v = static_cast( parents[1]->imp() )->coordinate();
Coordinate cntrl = static_cast( parents[2]->imp() )->coordinate();
args.push_back( parents[0] );
args.push_back( parents[1] );
int winding = 0;
int nsides = computeNsides( c, v, cntrl, winding );
ObjectConstCalcer* d = new ObjectConstCalcer( new IntImp( nsides ) );
args.push_back( d );
if ( winding > 1 )
{
d = new ObjectConstCalcer( new IntImp( winding ) );
args.push_back( d );
}
ObjectTypeCalcer* calcer = new ObjectTypeCalcer( mtype, args );
ObjectHolder* h = new ObjectHolder( calcer );
std::vector ret;
ret.push_back( h );
return ret;
}
QString PolygonBCVConstructor::useText( const ObjectCalcer&, const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
switch ( os.size() )
{
case 1:
return i18n( "Construct a regular polygon with this center" );
break;
case 2:
return i18n( "Construct a regular polygon with this vertex" );
break;
case 3:
Coordinate c = static_cast( os[0]->imp() )->coordinate();
Coordinate v = static_cast( os[1]->imp() )->coordinate();
Coordinate cntrl = static_cast( os[2]->imp() )->coordinate();
int winding = 0;
int nsides = computeNsides( c, v, cntrl, winding );
if ( winding > 1 )
{
QString result = i18n( "Adjust the number of sides (%1/%2)", nsides, winding );
return result;
} else
{
QString result = i18n( "Adjust the number of sides (%1)", nsides );
return result;
}
break;
}
return "";
}
QString PolygonBCVConstructor::selectStatement(
const std::vector& os, const KigDocument&,
const KigWidget& ) const
{
switch ( os.size() )
{
case 1:
return i18n( "Select the center of the new polygon..." );
break;
case 2:
return i18n( "Select a vertex for the new polygon..." );
break;
case 3:
return i18n( "Move the cursor to get the desired number of sides..." );
break;
}
return "";
}
void PolygonBCVConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& doc ) const
{
if ( parents.size() < 3 || parents.size() > 4 ) return;
assert ( parents[0]->imp()->inherits( PointImp::stype() ) &&
parents[1]->imp()->inherits( PointImp::stype() ) &&
parents[2]->imp()->inherits( IntImp::stype() ) );
if ( parents.size() == 4 )
assert ( parents[3]->imp()->inherits( IntImp::stype() ) );
Args args;
std::transform( parents.begin(), parents.end(),
std::back_inserter( args ), std::mem_fun( &ObjectCalcer::imp ) );
ObjectImp* data = mtype->calc( args, doc );
drawer.draw( *data, p, true );
delete data;
data = 0;
}
void PolygonBCVConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool PolygonBCVConstructor::isTransform() const
{
return false;
}
Coordinate PolygonBCVConstructor::getRotatedCoord( const Coordinate& c,
const Coordinate& v, double alpha ) const
{
double cosalpha = cos(alpha);
double sinalpha = sin(alpha);
double dx = v.x - c.x;
double dy = v.y - c.y;
return c + Coordinate( cosalpha*dx - sinalpha*dy, sinalpha*dx + cosalpha*dy );
}
int PolygonBCVConstructor::computeNsides ( const Coordinate& c,
const Coordinate& v, const Coordinate& cntrl, int& winding ) const
{
Coordinate lvect = v - c;
Coordinate rvect = cntrl - c;
double angle = atan2( rvect.y, rvect.x ) - atan2( lvect.y, lvect.x );
angle = fabs( angle/(2*M_PI) );
while ( angle > 1 ) angle -= 1;
if ( angle > 0.5 ) angle = 1 - angle;
double realsides = 1.0/angle; // this is bigger that 2
if ( angle == 0. ) realsides = 3;
if ( winding <= 0 ) // free to compute winding
{
winding = 1;
double ratio = lvect.length()/rvect.length();
winding = int ( ratio );
if ( winding < 1 ) winding = 1;
if ( winding > 50 ) winding = 50;
}
int nsides = int( winding*realsides + 0.5 ); // nsides/winding should be reduced!
if ( nsides > 100 ) nsides = 100; // well, 100 seems large enough!
if ( nsides < 3 ) nsides = 3;
while ( !relativePrimes ( nsides, winding ) ) ++nsides;
return nsides;
}
/*
* generic Bézier curve constructor
*/
BezierCurveTypeConstructor::BezierCurveTypeConstructor()
: PointSequenceConstructor(
I18N_NOOP( "Bézier Curve by its Control Points" ),
I18N_NOOP( "Construct a Bézier curve by giving its control points" ),
"bezierN",
BezierCurveType::instance() )
{
}
BezierCurveTypeConstructor::~BezierCurveTypeConstructor()
{
}
bool BezierCurveTypeConstructor::isAlreadySelectedOK(
const std::vector& os, const uint& pos ) const
{
if ( pos == os.size() - 1 && os.size() >= 3 ) return true;
return false;
}
int BezierCurveTypeConstructor::wantArgs( const std::vector& os,
const KigDocument&,
const KigWidget& ) const
{
int count=os.size() - 1;
for ( int i = 0; i <= count; i++ )
{
if ( ! ( os[i]->imp()->inherits( PointImp::stype() ) ) ) return ArgsParser::Invalid;
}
if ( count < 3 ) return ArgsParser::Valid;
if ( os[count] == os[count - 1] ) return ArgsParser::Complete;
return ArgsParser::Valid;
}
QString BezierCurveTypeConstructor::useText( const ObjectCalcer&, const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
if ( os.size() > 3 )
return i18n("... with this control point (click again on the last control point to terminate construction)");
else return i18n("Construct a Bézier curve with this control point");
}
QString BezierCurveTypeConstructor::selectStatement(
const std::vector&, const KigDocument&,
const KigWidget& ) const
{
return i18n("Select a point to be a control point of the new Bézier curve...");
}
void BezierCurveTypeConstructor::drawprelim( const ObjectDrawer& ,
KigPainter& p,
const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() < 2 ) return;
std::vector points;
for ( uint i = 0; i < parents.size(); ++i )
{
const Coordinate vertex =
static_cast( parents[i]->imp() )->coordinate();
points.push_back( vertex );
}
BezierImp B = BezierImp( points );
B.draw( p );
}
/*
* generic rational Bézier curve constructor
*/
RationalBezierCurveTypeConstructor::RationalBezierCurveTypeConstructor()
{
}
RationalBezierCurveTypeConstructor::~RationalBezierCurveTypeConstructor()
{
}
const QString RationalBezierCurveTypeConstructor::descriptiveName() const
{
return i18n( "Rational Bézier Curve by its Control Points" );
}
const QString RationalBezierCurveTypeConstructor::description() const
{
return i18n( "Construct a Bézier curve by giving its control points and positive weights" );
}
const QByteArray RationalBezierCurveTypeConstructor::iconFileName( const bool ) const
{
return "rbezierN";
}
bool RationalBezierCurveTypeConstructor::isAlreadySelectedOK(
const std::vector& os, const uint& pos ) const
{
if ( pos % 2 == 1 ) return true;
if ( pos == os.size() - 2 && os.size() >= 3 ) return true;
return false;
}
int RationalBezierCurveTypeConstructor::wantArgs( const std::vector& os,
const KigDocument&,
const KigWidget& ) const
{
int count=os.size() - 1;
for ( int i = 0; i <= count; i++ )
{
if ( ! ( os[i]->imp()->inherits( i % 2 == 0 ? PointImp::stype() : &weightimptypeinstance ) ) )
return ArgsParser::Invalid;
}
if ( count < 6 ) return ArgsParser::Valid;
if ( count % 2 == 0 && ( os[count] == os[count - 2] ) ) return ArgsParser::Complete;
return ArgsParser::Valid;
}
std::vector RationalBezierCurveTypeConstructor::build( const std::vector& parents, KigDocument&, KigWidget& ) const
{
uint count = parents.size() - 1;
assert ( count >= 3 );
std::vector args;
for ( uint i = 0; i < count; ++i ) args.push_back( parents[i] );
ObjectTypeCalcer* calcer = new ObjectTypeCalcer( RationalBezierCurveType::instance(), args );
ObjectHolder* h = new ObjectHolder( calcer );
std::vector ret;
ret.push_back( h );
return ret;
}
void RationalBezierCurveTypeConstructor::handleArgs( const std::vector& os,
KigPart& d,
KigWidget& v ) const
{
std::vector bos = build( os, d.document(), v );
for ( std::vector::iterator i = bos.begin();
i != bos.end(); ++i )
{
(*i)->calc( d.document() );
}
d.addObjects( bos );
}
QString RationalBezierCurveTypeConstructor::useText( const ObjectCalcer&,
const std::vector& os,
const KigDocument&,
const KigWidget& ) const
{
if ( os.size() % 2 == 0 )
return i18n("... assign this weight to last selected control point");
if ( os.size() > 6 )
return i18n("... with this control point (click again on the last control point or weight to terminate construction)");
else return i18n("Construct a rational Bézier curve with this control point");
}
QString RationalBezierCurveTypeConstructor::selectStatement(
const std::vector& os, const KigDocument&,
const KigWidget& ) const
{
if ( os.size() % 2 == 0 )
return i18n("Select a point to be a control point of the new rational Bézier curve...");
else
return i18n("Select a numeric label to be a weight of last selected point...");
}
void RationalBezierCurveTypeConstructor::drawprelim( const ObjectDrawer& ,
KigPainter& p,
const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() < 5 ) return;
std::vector points;
std::vector weights;
uint count = parents.size();
for ( uint i = 0; i < count; i += 2 )
{
bool valid;
assert ( parents[i]->imp()->inherits( PointImp::stype() ) );
const Coordinate vertex =
static_cast( parents[i]->imp() )->coordinate();
points.push_back( vertex );
if ( i+1 >= count ) break;
assert ( parents[i+1]->imp()->inherits( &weightimptypeinstance ) );
const double weight =
getDoubleFromImp( parents[i+1]->imp(), valid );
assert ( valid );
weights.push_back( weight );
}
if ( count % 2 == 1 )
{
// point was selected, we
weights.push_back( 1 ); // don't have its weight so far
}
assert ( points.size() == weights.size() );
RationalBezierImp rB = RationalBezierImp( points, weights );
rB.draw( p );
}
void RationalBezierCurveTypeConstructor::handlePrelim(
KigPainter& p, const std::vector& os,
const KigDocument& d, const KigWidget&
) const
{
uint count = os.size();
if ( count < 5 ) return;
for ( uint i = 0; i < count; i += 2 )
{
assert ( os[i]->imp()->inherits( PointImp::stype() ) );
if ( i+1 >= count ) break;
assert ( os[i+1]->imp()->inherits( &weightimptypeinstance ) );
}
std::vector args = os;
p.setBrushStyle( Qt::NoBrush );
p.setBrushColor( Qt::red );
p.setPen( QPen ( Qt::red, 1) );
p.setWidth( -1 ); // -1 means the default width for the object being
// drawn..
ObjectDrawer drawer( Qt::red );
drawprelim( drawer, p, args, d );
}
void RationalBezierCurveTypeConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool RationalBezierCurveTypeConstructor::isTransform() const
{
return false;
}
/*
* ConicConic intersection...
*/
static const ArgsParser::spec argsspectc[] = {
{ ConicImp::stype(), "SHOULD NOT BE SEEN", "SHOULD NOT BE SEEN", true },
{ ConicImp::stype(), "SHOULD NOT BE SEEN", "SHOULD NOT BE SEEN", true }
};
ConicConicIntersectionConstructor::ConicConicIntersectionConstructor()
: StandardConstructorBase( "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection", mparser ),
mparser( argsspectc, 2 )
{
}
ConicConicIntersectionConstructor::~ConicConicIntersectionConstructor()
{
}
void ConicConicIntersectionConstructor::drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() != 2 ) return;
assert ( parents[0]->imp()->inherits( ConicImp::stype() ) &&
parents[1]->imp()->inherits( ConicImp::stype() ) );
const ConicCartesianData conica =
static_cast( parents[0]->imp() )->cartesianData();
const ConicCartesianData conicb =
static_cast( parents[1]->imp() )->cartesianData();
bool ok = true;
for ( int wr = -1; wr < 2; wr += 2 )
{
LineData radical = calcConicRadical( conica, conicb, wr, 1, ok );
if ( ok )
{
for ( int wi = -1; wi < 2; wi += 2 )
{
Coordinate c = calcConicLineIntersect( conica, radical, 0.0, wi );
if ( c.valid() ) {
PointImp pi( c );
drawer.draw( pi, p, true );
}
};
};
};
}
std::vector ConicConicIntersectionConstructor::build(
const std::vector& os, KigDocument& doc, KigWidget& ) const
{
assert( os.size() == 2 );
std::vector ret;
ObjectCalcer* conica = os[0];
ObjectConstCalcer* zeroindexdo = new ObjectConstCalcer( new IntImp( 1 ) );
for ( int wr = -1; wr < 2; wr += 2 )
{
std::vector args = os;
args.push_back( new ObjectConstCalcer( new IntImp( wr ) ) );
args.push_back( zeroindexdo );
ObjectTypeCalcer* radical =
new ObjectTypeCalcer( ConicRadicalType::instance(), args );
radical->calc( doc );
for ( int wi = -1; wi < 2; wi += 2 )
{
args.clear();
args.push_back( conica );
args.push_back( radical );
args.push_back( new ObjectConstCalcer( new IntImp( wi ) ) );
ret.push_back(
new ObjectHolder(
new ObjectTypeCalcer(
ConicLineIntersectionType::instance(), args ) ) );
};
};
return ret;
}
void ConicConicIntersectionConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool ConicConicIntersectionConstructor::isTransform() const
{
return false;
}
ConicLineIntersectionConstructor::ConicLineIntersectionConstructor()
: MultiObjectTypeConstructor(
ConicLineIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection", -1, 1 )
{
}
ConicLineIntersectionConstructor::~ConicLineIntersectionConstructor()
{
}
ArcLineIntersectionConstructor::ArcLineIntersectionConstructor()
: MultiObjectTypeConstructor(
ArcLineIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection", -1, 1 )
{
}
ArcLineIntersectionConstructor::~ArcLineIntersectionConstructor()
{
}
QString ConicRadicalConstructor::useText( const ObjectCalcer& o, const std::vector&,
const KigDocument&, const KigWidget& ) const
{
if ( o.imp()->inherits( CircleImp::stype() ) )
return i18n( "Construct the Radical Lines of This Circle" );
else
return i18n( "Construct the Radical Lines of This Conic" );
}
/*
* generic affinity and generic projectivity. A unique affinity can be
* obtained by specifying the image of three points (four for projectivity)
* in the end we need, besides the object to be transformed, a total of
* six point or (alternatively) two triangles; our affinity will map the
* first triangle onto the second with corresponding ordering of their
* vertices. Since we allow for two different ways of specifying the six
* points we shall use a Generic constructor, like that for intersections.
*/
GenericAffinityConstructor::GenericAffinityConstructor()
: MergeObjectConstructor(
I18N_NOOP( "Generic Affinity" ),
I18N_NOOP( "The unique affinity that maps three points (or a triangle) onto three other points (or a triangle)" ),
"genericaffinity" )
{
SimpleObjectTypeConstructor* b2tr =
new SimpleObjectTypeConstructor(
AffinityB2TrType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"genericaffinity" );
SimpleObjectTypeConstructor* gi3p =
new SimpleObjectTypeConstructor(
AffinityGI3PType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"genericaffinity" );
merge( b2tr );
merge( gi3p );
}
GenericAffinityConstructor::~GenericAffinityConstructor() {}
bool GenericAffinityConstructor::isAlreadySelectedOK(const std::vector< ObjectCalcer* >& , const uint& ) const
{
return true;
}
GenericProjectivityConstructor::GenericProjectivityConstructor()
: MergeObjectConstructor(
I18N_NOOP( "Generic Projective Transformation" ),
I18N_NOOP( "The unique projective transformation that maps four points (or a quadrilateral) onto four other points (or a quadrilateral)" ),
"genericprojectivity" )
{
SimpleObjectTypeConstructor* b2qu =
new SimpleObjectTypeConstructor(
ProjectivityB2QuType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"genericprojectivity" );
SimpleObjectTypeConstructor* gi4p =
new SimpleObjectTypeConstructor(
ProjectivityGI4PType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"genericprojectivity" );
merge( b2qu );
merge( gi4p );
}
GenericProjectivityConstructor::~GenericProjectivityConstructor() {}
bool GenericProjectivityConstructor::isAlreadySelectedOK(const std::vector< ObjectCalcer* >& , const uint& ) const
{
return true;
}
/*
* inversion of points, lines with respect to a circle
*/
InversionConstructor::InversionConstructor()
: MergeObjectConstructor(
I18N_NOOP( "Inversion of Point, Line or Circle" ),
I18N_NOOP( "The inversion of a point, line or circle with respect to a circle" ),
"inversion" )
{
SimpleObjectTypeConstructor* pointobj =
new SimpleObjectTypeConstructor(
InvertPointType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"inversion" );
SimpleObjectTypeConstructor* curveobj =
new SimpleObjectTypeConstructor(
CircularInversionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"inversion" );
// SimpleObjectTypeConstructor* lineobj =
// new SimpleObjectTypeConstructor(
// InvertLineType::instance(),
// "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
// "inversion" );
//
// SimpleObjectTypeConstructor* segmentobj =
// new SimpleObjectTypeConstructor(
// InvertSegmentType::instance(),
// "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
// "inversion" );
//
// SimpleObjectTypeConstructor* circleobj =
// new SimpleObjectTypeConstructor(
// InvertCircleType::instance(),
// "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
// "inversion" );
//
// SimpleObjectTypeConstructor* arcobj =
// new SimpleObjectTypeConstructor(
// InvertArcType::instance(),
// "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
// "inversion" );
// merge( arcobj );
// merge( circleobj );
merge( curveobj );
merge( pointobj );
// merge( segmentobj );
// merge( lineobj );
}
InversionConstructor::~InversionConstructor() {}
/*
* Transport of Measure
*/
MeasureTransportConstructor::MeasureTransportConstructor()
: mtype( MeasureTransportType::instance() )
{
}
MeasureTransportConstructor::~MeasureTransportConstructor()
{
}
const QString MeasureTransportConstructor::descriptiveName() const
{
return i18n("Measure Transport");
}
const QString MeasureTransportConstructor::description() const
{
return i18n("Transport the measure of a segment or arc over a line or circle.");
}
const QByteArray MeasureTransportConstructor::iconFileName( const bool ) const
{
return "measuretransport";
}
bool MeasureTransportConstructor::isAlreadySelectedOK(
const std::vector&, const uint& ) const
{
return false;
}
/*
* we want the arguments in the exact order, this makes
* the code simpler, but I guess it is also less confusing
* to the user
*/
int MeasureTransportConstructor::wantArgs(
const std::vector& os,
const KigDocument& doc,
const KigWidget& ) const
{
if ( os.size() == 0 ) return ArgsParser::Valid;
if ( ! os[0]->imp()->inherits( &lengthimptypeinstance ) )
return ArgsParser::Invalid;
if ( os.size() == 1 ) return ArgsParser::Valid;
if ( ! os[1]->imp()->inherits( LineImp::stype() ) &&
! os[1]->imp()->inherits( CircleImp::stype() ) )
return ArgsParser::Invalid;
const CurveImp* c = static_cast( os[1]->imp() );
if ( os.size() == 2 ) return ArgsParser::Valid;
if ( ! os[2]->imp()->inherits( PointImp::stype() ) )
return ArgsParser::Invalid;
const PointImp* p = static_cast( os[2]->imp() );
// we have two choices:
// - using "isPointOnCurve" produces a "by construction" incidence
// test. This would be fine, but doesn't always work; e.g. if we
// have two points A, B, the segment s = AB and we construct the
// support line of the segment (property of segments), then kig
// is not able to understand that A is "by construction" on the
// constructed line.
// Moreover there are problems when hovering the cursor over points
// that are on both a segment and its support line.
// if ( ! isPointOnCurve( os[2], os[1] ) )
// - using "containsPoint", which is actually the test performed
// when calc-ing the TransportOfMeasure; the risk here is to
// be able to select points that are only coincidentally on the line.
if ( ! c->containsPoint( p->coordinate(), doc ) )
return ArgsParser::Invalid;
if ( os.size() == 3 ) return ArgsParser::Complete;
return ArgsParser::Invalid;
}
void MeasureTransportConstructor::handleArgs(
const std::vector& os, KigPart& d,
KigWidget& v ) const
{
std::vector bos = build( os, d.document(), v );
for ( std::vector::iterator i = bos.begin();
i != bos.end(); ++i )
{
(*i)->calc( d.document() );
}
d.addObjects( bos );
}
void MeasureTransportConstructor::handlePrelim(
KigPainter& p, const std::vector& os,
const KigDocument& d, const KigWidget&
) const
{
p.setBrushStyle( Qt::NoBrush );
p.setBrushColor( Qt::red );
p.setPen( QPen ( Qt::red, 1) );
p.setWidth( -1 ); // -1 means the default width for the object being
// drawn..
ObjectDrawer drawer( Qt::red );
drawprelim( drawer, p, os, d );
}
void MeasureTransportConstructor::drawprelim( const ObjectDrawer& drawer,
KigPainter& p,
const std::vector& parents,
const KigDocument& doc ) const
{
Args args;
using namespace std;
transform( parents.begin(), parents.end(),
back_inserter( args ), mem_fun( &ObjectCalcer::imp ) );
ObjectImp* data = mtype->calc( args, doc );
drawer.draw( *data, p, true );
delete data;
}
QString MeasureTransportConstructor::useText( const ObjectCalcer& o,
const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
if ( o.imp()->inherits( SegmentImp::stype() ) )
return i18n("Segment to transport");
if ( o.imp()->inherits( ArcImp::stype() ) )
return i18n("Arc to transport");
if ( o.imp()->inherits( NumericTextImp::stype() ) )
return i18n("Value to transport");
if ( o.imp()->inherits( LineImp::stype() ) )
return i18n("Transport a measure on this line");
if ( o.imp()->inherits( CircleImp::stype() ) )
return i18n("Transport a measure on this circle");
if ( o.imp()->inherits( PointImp::stype() ) )
{
if ( os[1]->imp()->inherits( CircleImp::stype() ) )
return i18n("Start transport from this point of the circle");
if ( os[1]->imp()->inherits( LineImp::stype() ) )
return i18n("Start transport from this point of the line");
else
return i18n("Start transport from this point of the curve");
// well, this isn't impemented yet, should never get here
}
return "";
}
QString MeasureTransportConstructor::selectStatement(
const std::vector& os, const KigDocument&,
const KigWidget& ) const
{
switch ( os.size() )
{
case 0:
return i18n( "Select a segment, arc or numeric label to be transported..." );
break;
case 1:
return i18n( "Select a destination line or circle..." );
break;
case 2:
return i18n( "Choose a starting point on the line/circle..." );
break;
}
return "";
}
std::vector MeasureTransportConstructor::build(
const std::vector& parents,
KigDocument&, KigWidget& ) const
{
assert ( parents.size() == 3 );
// std::vector args;
// for ( uint i = 0; i < count; ++i ) args.push_back( parents[i] );
ObjectTypeCalcer* calcer = new ObjectTypeCalcer( mtype, parents );
ObjectHolder* h = new ObjectHolder( calcer );
std::vector ret;
ret.push_back( h );
return ret;
}
void MeasureTransportConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool MeasureTransportConstructor::isTransform() const
{
return false;
}
/*
* Generic intersection
*/
/*
* these two argsparser spec vectors are used for the special
* construction of conic-line and circle-circle constructions
*/
static const struct ArgsParser::spec argsspeccli[] =
{
{ ConicImp::stype(), I18N_NOOP( "Intersect with this conic" ),
"SHOULD NOT BE SEEN", true },
{ AbstractLineImp::stype(), I18N_NOOP( "Intersect with this line" ),
"SHOULD NOT BE SEEN", true }
};
static const struct ArgsParser::spec argsspeccbli[] =
{
{ CubicImp::stype(), I18N_NOOP( "Intersect with this cubic" ),
"SHOULD NOT BE SEEN", true },
{ AbstractLineImp::stype(), I18N_NOOP( "Intersect with this line" ),
"SHOULD NOT BE SEEN", true }
};
static const struct ArgsParser::spec argsspeccci[] =
{
{ CircleImp::stype(), I18N_NOOP( "Intersect with this circle" ),
"SHOULD NOT BE SEEN", true },
{ CircleImp::stype(), I18N_NOOP( "Intersect with this circle" ),
"SHOULD NOT BE SEEN", true }
};
GenericIntersectionConstructor::GenericIntersectionConstructor()
: MergeObjectConstructor(
I18N_NOOP( "Intersect" ),
I18N_NOOP( "The intersection of two objects" ),
"curvelineintersection" )
{
// intersection type..
// There is one "toplevel" object_constructor, that is composed
// of multiple subconstructors.. First we build the
// subconstructors:
SimpleObjectTypeConstructor* lineline =
new SimpleObjectTypeConstructor(
LineLineIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection" );
ObjectConstructor* lineconic =
// new ConicLineIntersectionConstructor();
new TwoOrOneIntersectionConstructor(
ConicLineIntersectionType::instance(),
ConicLineOtherIntersectionType::instance(),
"curvelineintersection",
argsspeccli);
ObjectConstructor* arcline =
new ArcLineIntersectionConstructor();
ObjectConstructor* linecubic =
new ThreeTwoOneIntersectionConstructor(
CubicLineIntersectionType::instance(),
CubicLineOtherIntersectionType::instance(),
"curvelineintersection",
argsspeccbli);
ObjectConstructor* conicconic =
new ConicConicIntersectionConstructor();
// MultiObjectTypeConstructor* circlecircle =
// new MultiObjectTypeConstructor(
// CircleCircleIntersectionType::instance(),
// "SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
// "circlecircleintersection", -1, 1 );
ObjectConstructor* circlecircle =
new TwoOrOneIntersectionConstructor(
CircleCircleIntersectionType::instance(),
CircleCircleOtherIntersectionType::instance(),
"circlecircleintersection",
argsspeccci);
SimpleObjectTypeConstructor* polygonline =
new SimpleObjectTypeConstructor(
PolygonLineIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection" );
SimpleObjectTypeConstructor* polygonpolygon =
new SimpleObjectTypeConstructor(
PolygonPolygonIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection" );
MultiObjectTypeConstructor* opolygonalline =
new MultiObjectTypeConstructor(
OPolygonalLineIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection", -1, 1 );
MultiObjectTypeConstructor* cpolygonalline =
new MultiObjectTypeConstructor(
CPolygonalLineIntersectionType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"curvelineintersection", -1, 1 );
merge( lineline );
merge( circlecircle );
merge( lineconic );
merge( linecubic );
merge( conicconic );
merge( arcline );
merge( polygonline );
merge( opolygonalline );
merge( cpolygonalline );
merge( polygonpolygon );
}
GenericIntersectionConstructor::~GenericIntersectionConstructor()
{
}
bool GenericIntersectionConstructor::isIntersection() const
{
return true;
}
QString GenericIntersectionConstructor::useText(
const ObjectCalcer& o, const std::vector& os,
const KigDocument&, const KigWidget& ) const
{
QString preamble;
switch (os.size())
{
case 1:
if ( o.imp()->inherits( CircleImp::stype() ) )
return i18n( "Intersect this Circle" );
else if ( o.imp()->inherits( ConicImp::stype() ) )
return i18n( "Intersect this Conic" );
else if ( o.imp()->inherits( SegmentImp::stype() ) )
return i18n( "Intersect this Segment" );
else if ( o.imp()->inherits( RayImp::stype() ) )
return i18n( "Intersect this Half-line" );
else if ( o.imp()->inherits( LineImp::stype() ) )
return i18n( "Intersect this Line" );
else if ( o.imp()->inherits( CubicImp::stype() ) )
return i18n( "Intersect this Cubic Curve" );
else if ( o.imp()->inherits( ArcImp::stype() ) )
return i18n( "Intersect this Arc" );
else if ( o.imp()->inherits( FilledPolygonImp::stype() ) )
return i18n( "Intersect this Polygon" );
else if ( o.imp()->inherits( AbstractPolygonImp::stype() ) )
return i18n( "Intersect this Polygonal" );
else assert( false );
break;
case 2:
if ( o.imp()->inherits( CircleImp::stype() ) )
return i18n( "with this Circle" );
else if ( o.imp()->inherits( ConicImp::stype() ) )
return i18n( "with this Conic" );
else if ( o.imp()->inherits( SegmentImp::stype() ) )
return i18n( "with this Segment" );
else if ( o.imp()->inherits( RayImp::stype() ) )
return i18n( "with this Half-line" );
else if ( o.imp()->inherits( LineImp::stype() ) )
return i18n( "with this Line" );
else if ( o.imp()->inherits( CubicImp::stype() ) )
return i18n( "with this Cubic Curve" );
else if ( o.imp()->inherits( ArcImp::stype() ) )
return i18n( "with this Arc" );
else if ( o.imp()->inherits( FilledPolygonImp::stype() ) )
return i18n( "with this Polygon" );
else if ( o.imp()->inherits( AbstractPolygonImp::stype() ) )
return i18n( "with this Polygonal" );
else assert( false );
break;
}
return QString();
}
static const ArgsParser::spec argsspecMidPointOfTwoPoints[] =
{
- { PointImp::stype(), I18N_NOOP( "Construct Midpoint of This Point and Another One" ),
+ { PointImp::stype(), I18N_NOOP( "Construct midpoint of this point and another one" ),
I18N_NOOP( "Select the first of the points of which you want to construct the midpoint..." ), false },
{ PointImp::stype(), I18N_NOOP( "Construct the midpoint of this point and another one" ),
I18N_NOOP( "Select the other of the points of which to construct the midpoint..." ), false }
};
MidPointOfTwoPointsConstructor::MidPointOfTwoPointsConstructor()
: StandardConstructorBase( "Mid Point",
"Construct the midpoint of two points",
"bisection", mparser ),
mparser( argsspecMidPointOfTwoPoints, 2 )
{
}
MidPointOfTwoPointsConstructor::~MidPointOfTwoPointsConstructor()
{
}
void MidPointOfTwoPointsConstructor::drawprelim(
const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
const KigDocument& ) const
{
if ( parents.size() != 2 ) return;
assert( parents[0]->imp()->inherits( PointImp::stype() ) );
assert( parents[1]->imp()->inherits( PointImp::stype() ) );
const Coordinate m =
( static_cast( parents[0]->imp() )->coordinate() +
static_cast( parents[1]->imp() )->coordinate() ) / 2;
drawer.draw( PointImp( m ), p, true );
}
std::vector MidPointOfTwoPointsConstructor::build(
const std::vector& os, KigDocument& d, KigWidget& ) const
{
ObjectTypeCalcer* seg = new ObjectTypeCalcer( SegmentABType::instance(), os );
seg->calc( d );
// int index = seg->imp()->propertiesInternalNames().indexOf( "mid-point" );
// assert( index != -1 );
ObjectPropertyCalcer* prop = new ObjectPropertyCalcer( seg, "mid-point" );
prop->calc( d );
std::vector ret;
ret.push_back( new ObjectHolder( prop ) );
return ret;
}
void MidPointOfTwoPointsConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool MidPointOfTwoPointsConstructor::isTransform() const
{
return false;
}
+static const ArgsParser::spec argsspecGoldenPointOfTwoPoints[] =
+{
+ { PointImp::stype(), I18N_NOOP( "Construct golden ratio point of this point and another one" ),
+ I18N_NOOP( "Select the first of the points of which you want to construct the golden ratio point..." ), false },
+ { PointImp::stype(), I18N_NOOP( "Construct the golden ratio point of this point and another one" ),
+ I18N_NOOP( "Select the other of the points of which to construct the golden ratio point..." ), false }
+};
+
+GoldenPointOfTwoPointsConstructor::GoldenPointOfTwoPointsConstructor()
+ : StandardConstructorBase( "Golden Ratio Point",
+ "Construct the golden ratio point of two points",
+ "bisection", mparser ),
+ mparser( argsspecGoldenPointOfTwoPoints, 2 )
+{
+}
+
+GoldenPointOfTwoPointsConstructor::~GoldenPointOfTwoPointsConstructor()
+{
+}
+
+void GoldenPointOfTwoPointsConstructor::drawprelim(
+ const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents,
+ const KigDocument& ) const
+{
+ if ( parents.size() != 2 ) return;
+ assert( parents[0]->imp()->inherits( PointImp::stype() ) );
+ assert( parents[1]->imp()->inherits( PointImp::stype() ) );
+ const Coordinate m =
+ ( static_cast( parents[0]->imp() )->coordinate() +
+ (sqrt(5) - 1) / 2 *
+ ( static_cast( parents[1]->imp() )->coordinate() -
+ static_cast( parents[0]->imp() )->coordinate()
+ )
+ );
+ drawer.draw( PointImp( m ), p, true );
+}
+
+std::vector GoldenPointOfTwoPointsConstructor::build(
+ const std::vector& os, KigDocument& d, KigWidget& ) const
+{
+ ObjectTypeCalcer* seg = new ObjectTypeCalcer( SegmentABType::instance(), os );
+ seg->calc( d );
+// int index = seg->imp()->propertiesInternalNames().indexOf( "golden-point" );
+// assert( index != -1 );
+ ObjectPropertyCalcer* prop = new ObjectPropertyCalcer( seg, "golden-point" );
+ prop->calc( d );
+ std::vector ret;
+ ret.push_back( new ObjectHolder( prop ) );
+ return ret;
+}
+
+void GoldenPointOfTwoPointsConstructor::plug( KigPart*, KigGUIAction* )
+{
+}
+
+bool GoldenPointOfTwoPointsConstructor::isTransform() const
+{
+ return false;
+}
+
TestConstructor::TestConstructor( const ArgsParserObjectType* type, const char* descname,
const char* desc, const char* iconfile )
: StandardConstructorBase( descname, desc, iconfile, type->argsParser() ),
mtype( type )
{
}
TestConstructor::~TestConstructor()
{
}
void TestConstructor::drawprelim( const ObjectDrawer&, KigPainter&, const std::vector&,
const KigDocument& ) const
{
// not used, only here because of the wrong
// ObjectConstructor-GUIAction design. See the TODO
}
std::vector TestConstructor::build( const std::vector&, KigDocument&,
KigWidget& ) const
{
// not used, only here because of the wrong
// ObjectConstructor-GUIAction design. See the TODO
std::vector ret;
return ret;
}
void TestConstructor::plug( KigPart*, KigGUIAction* )
{
}
bool TestConstructor::isTransform() const
{
return false;
}
bool TestConstructor::isTest() const
{
return true;
}
BaseConstructMode* TestConstructor::constructMode( KigPart& doc )
{
return new TestConstructMode( doc, mtype );
}
int TestConstructor::wantArgs( const std::vector& os,
const KigDocument& d, const KigWidget& v ) const
{
int ret = StandardConstructorBase::wantArgs( os, d, v );
if ( ret == ArgsParser::Complete ) ret = ArgsParser::Valid;
return ret;
}
QString GenericIntersectionConstructor::selectStatement(
const std::vector& sel, const KigDocument&,
const KigWidget& ) const
{
if ( sel.size() == 0 )
return i18n( "Select the first object to intersect..." );
else
return i18n( "Select the second object to intersect..." );
}
TangentConstructor::TangentConstructor()
: MergeObjectConstructor(
I18N_NOOP( "Tangent" ),
I18N_NOOP( "The line tangent to a curve" ),
"tangent" )
{
SimpleObjectTypeConstructor* conic =
new SimpleObjectTypeConstructor(
TangentConicType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"tangentconic" );
SimpleObjectTypeConstructor* arc =
new SimpleObjectTypeConstructor(
TangentArcType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"tangentarc" );
SimpleObjectTypeConstructor* cubic =
new SimpleObjectTypeConstructor(
TangentCubicType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"tangentcubic" );
SimpleObjectTypeConstructor* curve =
new SimpleObjectTypeConstructor(
TangentCurveType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"tangentcurve" );
merge( conic );
merge( arc );
merge( cubic );
merge( curve );
}
TangentConstructor::~TangentConstructor()
{
}
QString TangentConstructor::useText(
const ObjectCalcer& o, const std::vector&,
const KigDocument&, const KigWidget& ) const
{
if ( o.imp()->inherits( CircleImp::stype() ) )
return i18n( "Tangent to This Circle" );
else if ( o.imp()->inherits( ConicImp::stype() ) )
return i18n( "Tangent to This Conic" );
else if ( o.imp()->inherits( ArcImp::stype() ) )
return i18n( "Tangent to This Arc" );
else if ( o.imp()->inherits( CubicImp::stype() ) )
return i18n( "Tangent to This Cubic Curve" );
else if ( o.imp()->inherits( CurveImp::stype() ) )
return i18n( "Tangent to This Curve" );
else if ( o.imp()->inherits( PointImp::stype() ) )
return i18n( "Tangent at This Point" );
// else assert( false );
return QString();
}
//QString TangentConstructor::selectStatement(
// const std::vector& sel, const KigDocument&,
// const KigWidget& ) const
//{
// if ( sel.size() == 0 )
// return i18n( "Select the object..." );
// else
// return i18n( "Select the point for the tangent to go through..." );
//}
/*
* center of curvature of a curve
*/
CocConstructor::CocConstructor()
: MergeObjectConstructor(
I18N_NOOP( "Center Of Curvature" ),
I18N_NOOP( "The center of the osculating circle to a curve" ),
"centerofcurvature" )
{
SimpleObjectTypeConstructor* conic =
new SimpleObjectTypeConstructor(
CocConicType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"cocconic" );
SimpleObjectTypeConstructor* cubic =
new SimpleObjectTypeConstructor(
CocCubicType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"coccubic" );
SimpleObjectTypeConstructor* curve =
new SimpleObjectTypeConstructor(
CocCurveType::instance(),
"SHOULDNOTBESEEN", "SHOULDNOTBESEEN",
"coccurve" );
merge( conic );
merge( cubic );
merge( curve );
}
CocConstructor::~CocConstructor()
{
}
QString CocConstructor::useText(
const ObjectCalcer& o, const std::vector&,
const KigDocument&, const KigWidget& ) const
{
if ( o.imp()->inherits( ConicImp::stype() ) )
return i18n( "Center of Curvature of This Conic" );
else if ( o.imp()->inherits( CubicImp::stype() ) )
return i18n( "Center of Curvature of This Cubic Curve" );
else if ( o.imp()->inherits( CurveImp::stype() ) )
return i18n( "Center of Curvature of This Curve" );
else if ( o.imp()->inherits( PointImp::stype() ) )
return i18n( "Center of Curvature at This Point" );
return QString();
}
bool relativePrimes( int n, int p )
{
if ( p > n ) return relativePrimes( p, n );
assert ( p >= 0 );
if ( p == 0 ) return false;
if ( p == 1 ) return true;
int d = int( n/p );
return relativePrimes( p, n-d*p );
}
//QString CocConstructor::selectStatement(
// const std::vector& sel, const KigDocument&,
// const KigWidget& ) const
//{
// if ( sel.size() == 0 )
// return i18n( "Select the object..." );
// else
// return i18n( "Select the point where to compute the center of curvature..." );
//}
diff --git a/misc/special_constructors.h b/misc/special_constructors.h
index f333a1f9..a61d2298 100644
--- a/misc/special_constructors.h
+++ b/misc/special_constructors.h
@@ -1,467 +1,482 @@
// Copyright (C) 2003 Dominique Devriese
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// 02110-1301, USA.
#ifndef KIG_MISC_SPECIAL_CONSTRUCTORS_H
#define KIG_MISC_SPECIAL_CONSTRUCTORS_H
#include "object_constructor.h"
class TwoOrOneIntersectionConstructor
: public StandardConstructorBase
{
const ArgsParserObjectType* mtype_std;
const ArgsParserObjectType* mtype_special;
ArgsParser margsparser;
public:
TwoOrOneIntersectionConstructor( const ArgsParserObjectType* t_std,
const ArgsParserObjectType* t_special,
const char* iconfile,
const struct ArgsParser::spec argsspecv[] );
~TwoOrOneIntersectionConstructor();
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const Q_DECL_OVERRIDE;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
class ThreeTwoOneIntersectionConstructor
: public StandardConstructorBase
{
const ArgsParserObjectType* mtype_std;
const ArgsParserObjectType* mtype_special;
ArgsParser margsparser;
public:
ThreeTwoOneIntersectionConstructor( const ArgsParserObjectType* t_std,
const ArgsParserObjectType* t_special,
const char* iconfile,
const struct ArgsParser::spec argsspecv[] );
~ThreeTwoOneIntersectionConstructor();
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const Q_DECL_OVERRIDE;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
class PolygonVertexTypeConstructor
: public StandardConstructorBase
{
const ArgsParserObjectType* mtype;
ArgsParser margsparser;
public:
PolygonVertexTypeConstructor();
~PolygonVertexTypeConstructor();
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const Q_DECL_OVERRIDE;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
class PolygonSideTypeConstructor
: public StandardConstructorBase
{
const ArgsParserObjectType* mtype;
ArgsParser margsparser;
public:
PolygonSideTypeConstructor();
~PolygonSideTypeConstructor();
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const Q_DECL_OVERRIDE;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
/*
*/
class PointSequenceConstructor
: public ObjectConstructor
{
const char* mdescname;
const char* mdesc;
const char* miconfile;
const ObjectType* mtype;
public:
PointSequenceConstructor( const char* descname,
const char* desc,
const char* iconfile,
const ObjectType* type );
const QString descriptiveName() const Q_DECL_OVERRIDE;
const QString description() const Q_DECL_OVERRIDE;
const QByteArray iconFileName( const bool canBeNull = false ) const Q_DECL_OVERRIDE;
void handleArgs( const std::vector& os,
KigPart& d,
KigWidget& v
) const Q_DECL_OVERRIDE;
void handlePrelim( KigPainter& p,
const std::vector& sel,
const KigDocument& d,
const KigWidget& v
) const Q_DECL_OVERRIDE;
// TODO: move here actual drawprelm when AbstractPolygon is in place!
virtual void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const = 0;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
/*
* classes PolygonBNPTypeConstructor, OpenPolygonTypeConstructor and
* BezierCurveTypeConstructor
* all inherit from the PointSequenceConstructor
*/
class PolygonBNPTypeConstructor
: public PointSequenceConstructor
{
public:
PolygonBNPTypeConstructor();
~PolygonBNPTypeConstructor();
bool isAlreadySelectedOK( const std::vector& os, const uint& ) const Q_DECL_OVERRIDE;
int wantArgs( const std::vector& os, const KigDocument& d, const KigWidget& v) const Q_DECL_OVERRIDE;
QString useText( const ObjectCalcer& o, const std::vector& sel,
const KigDocument& d, const KigWidget& v
) const Q_DECL_OVERRIDE;
QString selectStatement(
const std::vector& sel, const KigDocument& d,
const KigWidget& w ) const Q_DECL_OVERRIDE;
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
};
class OpenPolygonTypeConstructor
: public PointSequenceConstructor
{
public:
OpenPolygonTypeConstructor();
~OpenPolygonTypeConstructor();
bool isAlreadySelectedOK( const std::vector& os, const uint& ) const Q_DECL_OVERRIDE;
int wantArgs( const std::vector& os, const KigDocument& d, const KigWidget& v) const Q_DECL_OVERRIDE;
QString useText( const ObjectCalcer& o, const std::vector& sel,
const KigDocument& d, const KigWidget& v
) const Q_DECL_OVERRIDE;
QString selectStatement(
const std::vector& sel, const KigDocument& d,
const KigWidget& w ) const Q_DECL_OVERRIDE;
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
};
class PolygonBCVConstructor
: public ObjectConstructor
{
const ObjectType* mtype;
public:
PolygonBCVConstructor();
~PolygonBCVConstructor();
const QString descriptiveName() const Q_DECL_OVERRIDE;
const QString description() const Q_DECL_OVERRIDE;
const QByteArray iconFileName( const bool canBeNull = false ) const Q_DECL_OVERRIDE;
bool isAlreadySelectedOK( const std::vector& os, const uint& ) const Q_DECL_OVERRIDE;
int wantArgs( const std::vector& os,
const KigDocument& d,
const KigWidget& v
) const Q_DECL_OVERRIDE;
void handleArgs( const std::vector& os,
KigPart& d,
KigWidget& v
) const Q_DECL_OVERRIDE;
QString useText( const ObjectCalcer& o, const std::vector& sel,
const KigDocument& d, const KigWidget& v
) const Q_DECL_OVERRIDE;
QString selectStatement(
const std::vector& sel, const KigDocument& d,
const KigWidget& w ) const Q_DECL_OVERRIDE;
void handlePrelim( KigPainter& p,
const std::vector& sel,
const KigDocument& d,
const KigWidget& v
) const Q_DECL_OVERRIDE;
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
int computeNsides( const Coordinate& c, const Coordinate& v, const Coordinate& cntrl, int& winding ) const;
Coordinate getRotatedCoord( const Coordinate& c1,
const Coordinate& c2, double alpha ) const;
};
class BezierCurveTypeConstructor
: public PointSequenceConstructor
{
public:
BezierCurveTypeConstructor();
~BezierCurveTypeConstructor();
bool isAlreadySelectedOK( const std::vector& os, const uint& ) const Q_DECL_OVERRIDE;
int wantArgs( const std::vector& os, const KigDocument& d, const KigWidget& v) const Q_DECL_OVERRIDE;
QString useText( const ObjectCalcer& o, const std::vector& sel,
const KigDocument& d, const KigWidget& v
) const Q_DECL_OVERRIDE;
QString selectStatement(
const std::vector& sel, const KigDocument& d,
const KigWidget& w ) const Q_DECL_OVERRIDE;
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const Q_DECL_OVERRIDE;
};
class RationalBezierCurveTypeConstructor
: public ObjectConstructor
{
public:
RationalBezierCurveTypeConstructor();
~RationalBezierCurveTypeConstructor();
const QString descriptiveName() const Q_DECL_OVERRIDE;
const QString description() const Q_DECL_OVERRIDE;
const QByteArray iconFileName( const bool canBeNull = false ) const Q_DECL_OVERRIDE;
bool isAlreadySelectedOK( const std::vector& os, const uint& ) const Q_DECL_OVERRIDE;
int wantArgs( const std::vector& os, const KigDocument& d, const KigWidget& v) const Q_DECL_OVERRIDE;
std::vector build( const std::vector& os, KigDocument& d, KigWidget& w ) const;
void handleArgs( const std::vector& os,
KigPart& d,
KigWidget& v ) const Q_DECL_OVERRIDE;
QString useText( const ObjectCalcer& o,
const std::vector& sel,
const KigDocument& d,
const KigWidget& v ) const Q_DECL_OVERRIDE;
QString selectStatement( const std::vector& sel,
const KigDocument& d,
const KigWidget& w ) const Q_DECL_OVERRIDE;
void handlePrelim( KigPainter& p,
const std::vector& sel,
const KigDocument& d,
const KigWidget& v ) const Q_DECL_OVERRIDE;
void drawprelim( const ObjectDrawer& drawer,
KigPainter& p,
const std::vector& parents,
const KigDocument& d ) const;
void plug( KigPart* doc, KigGUIAction* kact ) Q_DECL_OVERRIDE;
bool isTransform() const Q_DECL_OVERRIDE;
};
class MeasureTransportConstructor
: public ObjectConstructor
{
const ObjectType* mtype;
public:
MeasureTransportConstructor();
~MeasureTransportConstructor();
const QString descriptiveName() const Q_DECL_OVERRIDE;
const QString description() const Q_DECL_OVERRIDE;
const QByteArray iconFileName( const bool canBeNull = false ) const Q_DECL_OVERRIDE;
bool isAlreadySelectedOK( const std::vector& os,
const uint& ) const Q_DECL_OVERRIDE;
int wantArgs( const std::vector& os,
const KigDocument& d,
const KigWidget& v
) const Q_DECL_OVERRIDE;
void handleArgs( const std::vector& os,
KigPart& d,
KigWidget& v
) const Q_DECL_OVERRIDE;
QString useText( const ObjectCalcer& o, const std::vector& sel,
const KigDocument& d, const KigWidget& v
) const Q_DECL_OVERRIDE;
QString selectStatement(
const std::vector& sel, const KigDocument& d,
const KigWidget& w ) const Q_DECL_OVERRIDE;
void handlePrelim( KigPainter& p,
const std::vector& sel,
const KigDocument& d,
const KigWidget& v
) const Q_DECL_OVERRIDE;
void drawprelim( const ObjectDrawer& drawer, KigPainter& p, const std::vector& parents, const KigDocument& ) const;
std::vector