00001
00002
00003
00004
00005
00006
00007 #include "DataKey.h"
00008 #include "EngaugeAssert.h"
00009 #include "EnumsToQt.h"
00010 #include "GeometryWindow.h"
00011 #include "GraphicsItemType.h"
00012 #include "GraphicsLinesForCurve.h"
00013 #include "GraphicsPoint.h"
00014 #include "GraphicsScene.h"
00015 #include "LineStyle.h"
00016 #include "Logger.h"
00017 #include "Point.h"
00018 #include "PointStyle.h"
00019 #include <QGraphicsItem>
00020 #include <QMap>
00021 #include <QPen>
00022 #include <QTextStream>
00023 #include "QtToString.h"
00024 #include "Spline.h"
00025 #include "Transformation.h"
00026 #include "ZValues.h"
00027
00028 using namespace std;
00029
00030 typedef QMap<double, double> XOrThetaToOrdinal;
00031
00032 GraphicsLinesForCurve::GraphicsLinesForCurve(const QString &curveName) :
00033 m_curveName (curveName)
00034 {
00035 setZValue (Z_VALUE_CURVE);
00036 setData (DATA_KEY_GRAPHICS_ITEM_TYPE,
00037 GRAPHICS_ITEM_TYPE_LINE);
00038 setData (DATA_KEY_IDENTIFIER,
00039 QVariant (m_curveName));
00040 }
00041
00042 GraphicsLinesForCurve::~GraphicsLinesForCurve()
00043 {
00044 OrdinalToGraphicsPoint::iterator itr;
00045 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00046 GraphicsPoint *point = itr.value();
00047 delete point;
00048 }
00049
00050 m_graphicsPoints.clear();
00051 }
00052
00053 void GraphicsLinesForCurve::addPoint (const QString &pointIdentifier,
00054 double ordinal,
00055 GraphicsPoint &graphicsPoint)
00056 {
00057 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::addPoint"
00058 << " curve=" << m_curveName.toLatin1().data()
00059 << " identifier=" << pointIdentifier.toLatin1().data()
00060 << " ordinal=" << ordinal
00061 << " pos=" << QPointFToString (graphicsPoint.pos()).toLatin1().data()
00062 << " newPointCount=" << (m_graphicsPoints.count() + 1);
00063
00064 m_graphicsPoints [ordinal] = &graphicsPoint;
00065 }
00066
00067 QPainterPath GraphicsLinesForCurve::drawLinesSmooth ()
00068 {
00069 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::drawLinesSmooth"
00070 << " curve=" << m_curveName.toLatin1().data();
00071
00072 QPainterPath path;
00073
00074
00075 vector<double> t;
00076 vector<SplinePair> xy;
00077 OrdinalToGraphicsPoint::const_iterator itr;
00078 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00079
00080 double ordinal = itr.key();
00081 const GraphicsPoint *point = itr.value();
00082
00083 t.push_back (ordinal);
00084 xy.push_back (SplinePair (point->pos ().x(),
00085 point->pos ().y()));
00086 }
00087
00088
00089 if (xy.size() > 0) {
00090
00091
00092 Spline spline (t, xy);
00093
00094
00095 int segmentEndingAtPointI = 0;
00096
00097
00098 bool isFirst = true;
00099 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00100
00101 const GraphicsPoint *point = itr.value();
00102
00103 if (isFirst) {
00104 isFirst = false;
00105 path.moveTo (point->pos());
00106 } else {
00107
00108 QPointF p1 (spline.p1 (segmentEndingAtPointI).x(),
00109 spline.p1 (segmentEndingAtPointI).y());
00110 QPointF p2 (spline.p2 (segmentEndingAtPointI).x(),
00111 spline.p2 (segmentEndingAtPointI).y());
00112
00113 path.cubicTo (p1,
00114 p2,
00115 point->pos ());
00116
00117 ++segmentEndingAtPointI;
00118 }
00119 }
00120 }
00121
00122 return path;
00123 }
00124
00125 QPainterPath GraphicsLinesForCurve::drawLinesStraight ()
00126 {
00127 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::drawLinesStraight"
00128 << " curve=" << m_curveName.toLatin1().data();
00129
00130 QPainterPath path;
00131
00132
00133 bool isFirst = true;
00134 OrdinalToGraphicsPoint::const_iterator itr;
00135 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00136
00137 const GraphicsPoint *point = itr.value();
00138
00139 if (isFirst) {
00140 isFirst = false;
00141 path.moveTo (point->pos ());
00142 } else {
00143 path.lineTo (point->pos ());
00144 }
00145 }
00146
00147 return path;
00148 }
00149
00150 double GraphicsLinesForCurve::identifierToOrdinal (const QString &identifier) const
00151 {
00152 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::identifierToOrdinal"
00153 << " identifier=" << identifier.toLatin1().data();
00154
00155 OrdinalToGraphicsPoint::const_iterator itr;
00156 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00157
00158 const GraphicsPoint *point = itr.value();
00159
00160 if (point->data (DATA_KEY_IDENTIFIER) == identifier) {
00161 return itr.key();
00162 }
00163 }
00164
00165 ENGAUGE_ASSERT (false);
00166
00167 return 0;
00168 }
00169
00170 void GraphicsLinesForCurve::lineMembershipPurge (const LineStyle &lineStyle)
00171 {
00172 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::lineMembershipPurge"
00173 << " curve=" << m_curveName.toLatin1().data();
00174
00175 OrdinalToGraphicsPoint::iterator itr, itrNext;
00176 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr = itrNext) {
00177
00178 itrNext = itr;
00179 ++itrNext;
00180
00181 GraphicsPoint *point = *itr;
00182
00183 if (!point->wanted ()) {
00184
00185 double ordinal = itr.key ();
00186
00187 delete point;
00188 m_graphicsPoints.remove (ordinal);
00189 }
00190 }
00191
00192
00193 QPen pen;
00194 if (lineStyle.paletteColor() == COLOR_PALETTE_TRANSPARENT) {
00195
00196 pen = QPen (Qt::NoPen);
00197
00198 } else {
00199
00200 pen = QPen (QBrush (ColorPaletteToQColor (lineStyle.paletteColor())),
00201 lineStyle.width());
00202
00203 }
00204
00205 setPen (pen);
00206
00207 updateGraphicsLinesToMatchGraphicsPoints (lineStyle);
00208 }
00209
00210 void GraphicsLinesForCurve::lineMembershipReset ()
00211 {
00212 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::lineMembershipReset"
00213 << " curve=" << m_curveName.toLatin1().data();
00214
00215 OrdinalToGraphicsPoint::iterator itr;
00216 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00217
00218 GraphicsPoint *point = itr.value();
00219
00220 point->reset ();
00221 }
00222 }
00223
00224 bool GraphicsLinesForCurve::needOrdinalRenumbering () const
00225 {
00226
00227 bool needRenumbering = false;
00228 for (int ordinalKeyWanted = 0; ordinalKeyWanted < m_graphicsPoints.count(); ordinalKeyWanted++) {
00229
00230 double ordinalKeyGot = m_graphicsPoints.keys().at (ordinalKeyWanted);
00231
00232
00233 ENGAUGE_ASSERT (ordinalKeyGot != Point::UNDEFINED_ORDINAL ());
00234
00235 if (ordinalKeyWanted != ordinalKeyGot) {
00236 needRenumbering = true;
00237 break;
00238 }
00239 }
00240
00241 return needRenumbering;
00242 }
00243
00244 void GraphicsLinesForCurve::printStream (QString indentation,
00245 QTextStream &str) const
00246 {
00247 DataKey type = (DataKey) data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt();
00248
00249 str << indentation << "GraphicsLinesForCurve=" << m_curveName
00250 << " dataIdentifier=" << data (DATA_KEY_IDENTIFIER).toString().toLatin1().data()
00251 << " dataType=" << dataKeyToString (type).toLatin1().data() << "\n";
00252
00253 indentation += INDENTATION_DELTA;
00254
00255 OrdinalToGraphicsPoint::const_iterator itr;
00256 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00257
00258 double ordinalKey = itr.key();
00259 const GraphicsPoint *point = itr.value();
00260
00261 point->printStream (indentation,
00262 str,
00263 ordinalKey);
00264 }
00265 }
00266
00267 void GraphicsLinesForCurve::removePoint (double ordinal)
00268 {
00269 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::removePoint"
00270 << " point=" << ordinal
00271 << " pointCount=" << m_graphicsPoints.count();
00272
00273 ENGAUGE_ASSERT (m_graphicsPoints.contains (ordinal));
00274 GraphicsPoint *graphicsPoint = m_graphicsPoints [ordinal];
00275
00276 m_graphicsPoints.remove (ordinal);
00277
00278 delete graphicsPoint;
00279 }
00280
00281 void GraphicsLinesForCurve::removeTemporaryPointIfExists()
00282 {
00283 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::removeTemporaryPointIfExists";
00284
00285 OrdinalToGraphicsPoint::iterator itr;
00286 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00287
00288 GraphicsPoint *graphicsPoint = itr.value();
00289
00290 m_graphicsPoints.remove (itr.key());
00291
00292 delete graphicsPoint;
00293
00294 break;
00295 }
00296 }
00297
00298 void GraphicsLinesForCurve::renumberOrdinals ()
00299 {
00300 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::renumberOrdinals";
00301
00302 int ordinalKeyWanted;
00303
00304
00305
00306 QList<GraphicsPoint*> points;
00307 for (ordinalKeyWanted = 0; ordinalKeyWanted < m_graphicsPoints.count(); ordinalKeyWanted++) {
00308
00309 GraphicsPoint *graphicsPoint = m_graphicsPoints.values().at (ordinalKeyWanted);
00310 points << graphicsPoint;
00311 }
00312
00313 m_graphicsPoints.clear ();
00314
00315 for (ordinalKeyWanted = 0; ordinalKeyWanted < points.count(); ordinalKeyWanted++) {
00316
00317 GraphicsPoint *graphicsPoint = points.at (ordinalKeyWanted);
00318 m_graphicsPoints [ordinalKeyWanted] = graphicsPoint;
00319 }
00320 }
00321
00322 void GraphicsLinesForCurve::updateAfterCommand (GraphicsScene &scene,
00323 const PointStyle &pointStyle,
00324 const Point &point,
00325 GeometryWindow *geometryWindow)
00326 {
00327 LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsLinesForCurve::updateAfterCommand"
00328 << " curve=" << m_curveName.toLatin1().data()
00329 << " pointCount=" << m_graphicsPoints.count();
00330
00331 GraphicsPoint *graphicsPoint = 0;
00332 if (m_graphicsPoints.contains (point.ordinal())) {
00333
00334 graphicsPoint = m_graphicsPoints [point.ordinal()];
00335
00336
00337
00338
00339
00340 graphicsPoint->setPos (point.posScreen());
00341 graphicsPoint->setData (DATA_KEY_IDENTIFIER, point.identifier());
00342
00343 } else {
00344
00345
00346 graphicsPoint = scene.createPoint (point.identifier (),
00347 pointStyle,
00348 point.posScreen(),
00349 geometryWindow);
00350 m_graphicsPoints [point.ordinal ()] = graphicsPoint;
00351
00352 }
00353
00354
00355 ENGAUGE_CHECK_PTR (graphicsPoint);
00356 graphicsPoint->setWanted ();
00357 }
00358
00359 void GraphicsLinesForCurve::updateCurveStyle (const CurveStyle &curveStyle)
00360 {
00361 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::updateCurveStyle";
00362
00363 OrdinalToGraphicsPoint::const_iterator itr;
00364 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00365
00366 GraphicsPoint *point = itr.value();
00367 point->updateCurveStyle (curveStyle);
00368 }
00369 }
00370
00371 void GraphicsLinesForCurve::updateHighlightOpacity (double highlightOpacity)
00372 {
00373 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::updateCurveStyle"
00374 << " curve=" << m_curveName.toLatin1().data()
00375 << " highlightOpacity=" << highlightOpacity;
00376
00377 OrdinalToGraphicsPoint::const_iterator itr;
00378 for (itr = m_graphicsPoints.begin(); itr != m_graphicsPoints.end(); itr++) {
00379
00380 GraphicsPoint *point = itr.value();
00381 point->setHighlightOpacity (highlightOpacity);
00382 }
00383 }
00384
00385 void GraphicsLinesForCurve::updateGraphicsLinesToMatchGraphicsPoints (const LineStyle &lineStyle)
00386 {
00387
00388
00389 bool needRenumbering = needOrdinalRenumbering ();
00390 if (needRenumbering) {
00391
00392 renumberOrdinals();
00393
00394 }
00395
00396 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsLinesForCurve::updateGraphicsLinesToMatchGraphicsPoints"
00397 << " numberPoints=" << m_graphicsPoints.count()
00398 << " ordinalRenumbering=" << (needRenumbering ? "true" : "false");
00399
00400 if (lineStyle.curveConnectAs() != CONNECT_SKIP_FOR_AXIS_CURVE) {
00401
00402
00403
00404 QPainterPath path;
00405 if (lineStyle.curveConnectAs() == CONNECT_AS_FUNCTION_STRAIGHT ||
00406 lineStyle.curveConnectAs() == CONNECT_AS_RELATION_STRAIGHT ||
00407 m_graphicsPoints.count () < 3) {
00408
00409 path = drawLinesStraight ();
00410 } else {
00411 path = drawLinesSmooth ();
00412 }
00413
00414 setPath (path);
00415 }
00416 }
00417
00418 void GraphicsLinesForCurve::updatePointOrdinalsAfterDrag (const LineStyle &lineStyle,
00419 const Transformation &transformation)
00420 {
00421 CurveConnectAs curveConnectAs = lineStyle.curveConnectAs();
00422
00423 LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsLinesForCurve::updateGraphicsLinesToMatchGraphicsPoints"
00424 << " curve=" << m_curveName.toLatin1().data()
00425 << " curveConnectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
00426
00427 if (curveConnectAs == CONNECT_AS_FUNCTION_SMOOTH ||
00428 curveConnectAs == CONNECT_AS_FUNCTION_STRAIGHT) {
00429
00430
00431
00432
00433 XOrThetaToOrdinal xOrThetaToOrdinal;
00434 OrdinalToGraphicsPoint::iterator itrP;
00435 for (itrP = m_graphicsPoints.begin(); itrP != m_graphicsPoints.end(); itrP++) {
00436
00437 double ordinal = itrP.key();
00438 const GraphicsPoint *point = itrP.value();
00439
00440
00441 QPointF pointGraph;
00442 transformation.transformScreenToRawGraph(point->pos (),
00443 pointGraph);
00444
00445 xOrThetaToOrdinal [pointGraph.x()] = ordinal;
00446 }
00447
00448
00449 OrdinalToGraphicsPoint temporaryList;
00450 int ordinalNew = 0;
00451 XOrThetaToOrdinal::const_iterator itrX;
00452 for (itrX = xOrThetaToOrdinal.begin(); itrX != xOrThetaToOrdinal.end(); itrX++) {
00453
00454 double ordinalOld = *itrX;
00455 GraphicsPoint *point = m_graphicsPoints [ordinalOld];
00456
00457 temporaryList [ordinalNew++] = point;
00458 }
00459
00460
00461 m_graphicsPoints.clear();
00462 for (itrP = temporaryList.begin(); itrP != temporaryList.end(); itrP++) {
00463
00464 double ordinal = itrP.key();
00465 GraphicsPoint *point = itrP.value();
00466
00467 m_graphicsPoints [ordinal] = point;
00468 }
00469 }
00470 }