23 #include "../kig/kig_document.h"
24 #include "../kig/kig_view.h"
37 #include <knumvalidator.h>
46 for (
int i = 0; i < s; ++i )
53 class CoordinateValidator
60 static const char reEuclidean[];
61 static const char rePolar[];
63 CoordinateValidator(
bool polar );
64 ~CoordinateValidator();
69 const char CoordinateValidator::reEuclidean[] =
"\\s*\\(?\\s*([0-9.,+-]+)\\s*;\\s*([0-9.,+-]+)\\s*\\)?\\s*";
70 const char CoordinateValidator::rePolar[] =
"\\s*\\(?\\s*([0-9.,+-]+)\\s*;\\s*([0-9.,+-]+) ?°?\\s*\\)?\\s*";
72 CoordinateValidator::CoordinateValidator(
bool polar )
73 :
QValidator( 0L ), mpolar( polar ), mdv( 0L ),
74 mre(
QString::fromUtf8( polar ? rePolar : reEuclidean ) )
78 CoordinateValidator::~CoordinateValidator()
82 QValidator::State CoordinateValidator::validate(
QString & input,
int & pos )
const
91 if ( !tinput.
isEmpty() && tinput.
at( tinput.
length() - 1 ).unicode() == 176 )
94 if ( tinput[0] ==
'(' ) tinput = tinput.
mid( 1 );
95 int scp = tinput.
indexOf(
';' );
96 if ( scp == -1 )
return mdv.validate( tinput, pos ) == Invalid ? Invalid : Intermediate;
102 State ret = Acceptable;
105 ret =
kigMin( ret, mdv.validate( p1, boguspos ) );
108 ret =
kigMin( ret, mdv.validate( p2, boguspos ) );
114 void CoordinateValidator::fixup(
QString & input )
const
116 int nsc = input.
count(
';' );
122 input = input.
left( i );
129 KLocale* l = KGlobal::locale();
138 mre.exactMatch( input );
157 QString xs = KGlobal::locale()->formatNumber( p.
x, l );
158 QString ys = KGlobal::locale()->formatNumber( p.
y, l );
170 KLocale* l = KGlobal::locale();
171 double x = l->readNumber( xs, &ok );
174 double y = l->readNumber( ys, &ok );
191 int exp = (int) log10( x );
192 double f = x/pow( 10., exp );
196 if ( f < 1.5 ) nf = 1.;
197 else if ( f < 3. ) nf = 2.;
198 else if ( f < 7. ) nf = 5.;
203 if ( f <= 1. ) nf = 1.;
204 else if ( f <= 2. ) nf = 2.;
205 else if ( f <= 5. ) nf = 5.;
208 return nf * pow( 10., exp );
217 if ( !( showgrid || showaxes ) )
225 const double hmin = floor( p.
window().
left() );
226 const double vmax = ceil( p.
window().
top() );
231 const int ntick =
static_cast<int>(
234 double hrange =
nicenum( hmax - hmin,
false );
235 double vrange =
nicenum( vmax - vmin,
false );
236 const double newrange =
kigMin( hrange, vrange );
240 const double hd =
nicenum( hrange / ( ntick - 1 ),
true );
241 const double vd =
nicenum( vrange / ( ntick - 1 ),
true );
243 const double hgraphmin = ceil( hmin / hd) * hd;
244 const double hgraphmax = floor( hmax / hd ) * hd;
245 const double vgraphmin = ceil( vmin / vd ) * vd;
246 const double vgraphmax = floor( vmax / vd ) * vd;
248 const int hnfrac =
kigMax( (
int) - floor( log10( hd ) ), 0 );
249 const int vnfrac =
kigMax( (
int) - floor( log10( vd ) ), 0 );
254 p.
setPen(
QPen( Qt::lightGray, 0, Qt::DotLine ) );
256 for (
double i = hgraphmin; i <= hgraphmax + hd/2; i += hd )
260 for (
double i = vgraphmin; i <= vgraphmax + vd/2; i += vd )
268 p.
setPen(
QPen( Qt::gray, 1, Qt::SolidLine ) );
277 for(
double i = hgraphmin; i <= hgraphmax + hd / 2; i += hd )
281 if( fabs( i ) < 1e-8 )
continue;
285 KGlobal::locale()->formatNumber( i, hnfrac ),
286 Qt::AlignLeft | Qt::AlignTop
290 for (
double i = vgraphmin; i <= vgraphmax + vd/2; i += vd )
292 if( fabs( i ) < 1e-8 )
continue;
294 KGlobal::locale()->formatNumber( i, vnfrac ),
295 Qt::AlignBottom | Qt::AlignLeft
299 p.
setPen(
QPen( Qt::gray, 1, Qt::SolidLine ) );
301 std::vector<Coordinate> a;
306 a.push_back(
Coordinate( hmax - 6 * u, -3 * u) );
308 a.push_back(
Coordinate( hmax - 6 * u, 3 * u ) );
315 a.push_back(
Coordinate( 3 * u, vmax - 6 * u ) );
317 a.push_back(
Coordinate( -3 * u, vmax - 6 * u ) );
325 return i18n(
"Enter coordinates in the following format: \"x;y\",\n"
326 "where x is the x coordinate, and y is the y coordinate." );
331 return i18n(
"Enter coordinates in the following format: <b>\"x;y\"</b>,<br />"
332 "where x is the x coordinate, and y is the y coordinate." );
362 QString rs = KGlobal::locale()->formatNumber( r, l );
363 QString ts = KGlobal::locale()->formatNumber( theta, 0 );
371 return i18n(
"Enter coordinates in the following format: \"r; \xCE\xB8°\",\n"
372 "where r and \xCE\xB8 are the polar coordinates." );
378 return i18n(
"Enter coordinates in the following format: <b>\"r; \xCE\xB8°\"</b>,<br />"
379 "where r and \xCE\xB8 are the polar coordinates." );
385 ok = ( regexp.
indexIn( s ) == 0 );
389 double r = KGlobal::locale()->readNumber( rs, &ok );
393 double theta = KGlobal::locale()->readNumber( ts, &ok );
394 if ( ! ok ) theta = ts.
toDouble( &ok );
398 return Coordinate( cos( theta ) * r, sin( theta ) * r );
409 if ( !( showgrid || showaxes ) )
417 const double hmin = M_SQRT2*p.
window().
left();
418 const double vmax = M_SQRT2*p.
window().
top();
423 const int ntick =
static_cast<int>(
426 const double hrange =
nicenum( hmax - hmin,
false );
427 const double vrange =
nicenum( vmax - vmin,
false );
429 const double hd =
nicenum( hrange / ( ntick - 1 ),
true );
430 const double vd =
nicenum( vrange / ( ntick - 1 ),
true );
432 const double hgraphmin = floor( hmin / hd) * hd;
433 const double hgraphmax = ceil( hmax / hd ) * hd;
434 const double vgraphmin = floor( vmin / vd ) * vd;
435 const double vgraphmax = ceil( vmax / vd ) * vd;
437 const int hnfrac =
kigMax( (
int) - floor( log10( hd ) ), 0 );
438 const int vnfrac =
kigMax( (
int) - floor( log10( vd ) ), 0 );
439 const int nfrac =
kigMax( hnfrac, vnfrac );
444 double d =
kigMin( hd, vd );
448 double end =
kigMax( hgraphmax, vgraphmax );
453 p.
setPen(
QPen( Qt::lightGray, 0, Qt::DotLine ) );
454 for (
double i = begin; i <= end + d / 2; i += d )
455 drawGridLine( p, c, fabs( i ) );
461 p.
setPen(
QPen( Qt::gray, 1, Qt::SolidLine ) );
470 for(
double i = hgraphmin; i <= hgraphmax + hd / 2; i += hd )
474 if( fabs( i ) < 1e-8 )
continue;
476 QString is = KGlobal::locale()->formatNumber( fabs( i ), nfrac );
479 is, Qt::AlignLeft | Qt::AlignTop );
482 for (
double i = vgraphmin; i <= vgraphmax + vd / 2; i += vd )
484 if( fabs( i ) < 1e-8 )
continue;
486 QString is = KGlobal::locale()->formatNumber( fabs( i ), nfrac );
489 is, Qt::AlignBottom | Qt::AlignLeft
493 p.
setPen(
QPen( Qt::gray, 1, Qt::SolidLine ) );
495 std::vector<Coordinate> a;
500 a.push_back(
Coordinate( hmax - 6 * u, -3 * u) );
502 a.push_back(
Coordinate( hmax - 6 * u, 3 * u ) );
509 a.push_back(
Coordinate( 3 * u, vmax - 6 * u ) );
511 a.push_back(
Coordinate( -3 * u, vmax - 6 * u ) );
519 return new CoordinateValidator(
false );
524 return new CoordinateValidator(
true );
530 ret << i18n(
"&Euclidean" )
539 else if ( which ==
Polar )
549 if ( std::string( euclideanTypeString ) == type )
551 if ( std::string( polarTypeString ) == type )
581 return i18n(
"Set Euclidean Coordinate System" );
583 return i18n(
"Set Polar Coordinate System" );
600 const double hmax = rect.
right();
601 const double hmin = rect.
left();
602 const double vmax = rect.
top();
603 const double vmin = rect.
bottom();
607 const int ntick =
static_cast<int>(
610 const double hrange =
nicenum( hmax - hmin,
false );
611 const double vrange =
nicenum( vmax - vmin,
false );
613 const double hd =
nicenum( hrange / ( ntick - 1 ),
true );
614 const double vd =
nicenum( vrange / ( ntick - 1 ),
true );
616 const double hgraphmin = ceil( hmin / hd) * hd;
617 const double vgraphmin = ceil( vmin / vd ) * vd;
619 const double nx = qRound( ( c.
x - hgraphmin ) / hd ) * hd + hgraphmin;
620 const double ny = qRound( ( c.
y - vgraphmin ) / vd ) * vd + vgraphmin;
635 const double hmax = M_SQRT2 * r.
right();
636 const double hmin = M_SQRT2 * r.
left();
637 const double vmax = M_SQRT2 * r.
top();
638 const double vmin = M_SQRT2 * r.
bottom();
642 const int ntick =
static_cast<int>(
645 const double hrange =
nicenum( hmax - hmin,
false );
646 const double vrange =
nicenum( vmax - vmin,
false );
648 const double hd =
nicenum( hrange / ( ntick - 1 ),
true );
649 const double vd =
nicenum( vrange / ( ntick - 1 ),
true );
651 double d =
kigMin( hd, vd );
654 double ndist = qRound( dist / d ) * d;
661 #ifdef KIG_TESSELLATE_POLAR_GRID_CIRCLE
674 static const iterdata_t iterdata[] =
681 for (
int i = 0; i < 4; ++i )
683 int xd = iterdata[i].xd;
684 int yd = iterdata[i].yd;
685 Coordinate point = ( rect.*iterdata[i].point )();
686 Coordinate opppoint = ( rect.*iterdata[i].oppositepoint )();
687 double horizangle = iterdata[i].horizAngle;
688 double vertangle = iterdata[i].vertAngle;
690 if ( ( c.
x - point.
x )*xd > 0 || ( c.
y - point.
y )*yd > 0 )
692 if ( ( c.
x - opppoint.
x )*-xd > r || ( c.
y - opppoint.
y )*-yd > r )
696 double hd = ( point.
x - c.
x )*xd;
700 double anglediff = acos( hd/r );
701 horizangle += posdir * anglediff;
704 hd = ( c.
x - opppoint.
x )*-xd;
707 double anglediff = asin( hd/r );
708 vertangle -= posdir * anglediff;
711 double vd = ( point.
y - c.
y )*yd;
715 double anglediff = acos( vd/r );
716 vertangle -= posdir * anglediff;
719 vd = ( c.
y - opppoint.
y ) * -xd;
722 double anglediff = asin( hd/r );
723 horizangle += posdir * anglediff;
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString cap(int nth) const
static CoordinateSystem * build(int which)
QString & append(QChar ch)
a CoordinateSystem is what the user sees: it is kept by KigPart to show the user a grid...
QValidator * coordinateValidator() const
void truncate(int position)
void setWholeWinOverlay()
this is called by some drawing functions that modify the 'entire' screen, i.e.
void drawCircle(const Coordinate ¢er, double radius)
draw a circle...
void drawText(const Rect &r, const QString &s, int textFlags=0)
draw text...
QString coordinateFormatNotice() const
This returns a notice to say in which format coordinates should be entered.
virtual void fixup(QString &input) const
Coordinate snapToGrid(const Coordinate &c, const KigWidget &w) const
QString coordinateFormatNoticeMarkup() const
Like coordinateFormatNotice(), but with HTML tags useful to have a rich text...
Coordinate bottomLeft() const
This file is part of Kig, a KDE program for Interactive Geometry...
QString fromScreen(const Coordinate &pt, const KigDocument &w) const
void setBrush(const QBrush &b)
double toDouble(bool *ok) const
static QString setCoordinateSystemStatement(int id)
static QStringList names()
QString fromScreen(const Coordinate &pt, const KigDocument &w) const
virtual ~CoordinateSystem()
The Coordinate class is the basic class representing a 2D location by its x and y components...
int getCoordinatePrecision() const
double length() const
Length.
int indexIn(const QString &str, int offset, CaretMode caretMode) const
QString fromUtf8(const char *str, int size)
const Coordinate normalize(double length=1) const
Normalize.
KigPainter is an extended QPainter.
const char * type() const
Coordinate topLeft() const
T kigMax(const T &a, const T &b)
static QString withoutSpaces(const QString &str)
This file is part of Kig, a KDE program for Interactive Geometry...
Rect window()
what rect are we drawing on ?
void drawArc(const Coordinate ¢er, double radius, double startangle, double angle)
draw the arc ( a part of a circle ), of the circle with center center, radius radius, with size angle, starting at the angle startAngle.
static const char euclideanTypeString[]
QValidator * coordinateValidator() const
Coordinate snapToGrid(const Coordinate &c, const KigWidget &w) const
static double convert(const double angle, const Goniometry::System from, const Goniometry::System to)
The most useful method of this class: convert the specified angle from the system from to the system ...
virtual State validate(QString &input, int &pos) const =0
QString coordinateFormatNoticeMarkup() const
Like coordinateFormatNotice(), but with HTML tags useful to have a rich text...
T kigMin(const T &a, const T &b)
Coordinate topRight() const
Coordinate toScreen(const QString &pt, bool &ok) const
QString mid(int position, int n) const
void drawGrid(KigPainter &p, bool showgrid=true, bool showaxes=true) const
void setPen(const QPen &p)
const QChar at(int position) const
KigDocument is the class holding the real data in a Kig document.
void drawGrid(KigPainter &p, bool showgrid=true, bool showaxes=true) const
QString left(int n) const
QString fromLatin1(const char *str, int size)
Coordinate bottomRight() const
static double nicenum(double x, bool round)
copied and adapted from a ( public domain ) function i found in the first Graphics Gems book...
static const char polarTypeString[]
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void drawSegment(const Coordinate &from, const Coordinate &to)
draw a segment...
Coordinate toScreen(const QString &pt, bool &ok) const
void drawArea(const std::vector< Coordinate > &pts, bool border=true)
draw an area defined by the points in pts filled with the set color...
const char * type() const
QString coordinateFormatNotice() const
This returns a notice to say in which format coordinates should be entered.