Engauge Digitizer  2
DlgSettingsCurveProperties.cpp
1 /******************************************************************************************************
2  * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5  ******************************************************************************************************/
6 
7 #include "CmdMediator.h"
8 #include "CmdSettingsCurveProperties.h"
9 #include "ColorPalette.h"
10 #include "DlgSettingsCurveProperties.h"
11 #include "EngaugeAssert.h"
12 #include "EnumsToQt.h"
13 #include "GeometryWindow.h"
14 #include "GraphicsPoint.h"
15 #include "GraphicsPointFactory.h"
16 #include "GraphicsView.h"
17 #include "Logger.h"
18 #include "MainWindow.h"
19 #include <QCheckBox>
20 #include <QComboBox>
21 #include <QDebug>
22 #include <QGraphicsRectItem>
23 #include <QGraphicsScene>
24 #include <QGridLayout>
25 #include <QGroupBox>
26 #include <QLabel>
27 #include <QLineEdit>
28 #include <QListWidget>
29 #include <qmath.h>
30 #include <QPen>
31 #include <QPushButton>
32 #include <QSettings>
33 #include <QSpacerItem>
34 #include <QSpinBox>
35 #include <QTransform>
36 #include "Settings.h"
37 #include "SettingsForGraph.h"
38 #include "Spline.h"
39 #include "SplinePair.h"
40 #include <vector>
41 #include "ViewPreview.h"
42 
43 using namespace std;
44 
45 const QString CONNECT_AS_FUNCTION_SMOOTH_STR ("Function - Smooth");
46 const QString CONNECT_AS_FUNCTION_STRAIGHT_STR ("Function - Straight");
47 const QString CONNECT_AS_RELATION_SMOOTH_STR ("Relation - Smooth");
48 const QString CONNECT_AS_RELATION_STRAIGHT_STR ("Relation - Straight");
49 
50 const double PREVIEW_WIDTH = 100.0;
51 const double PREVIEW_HEIGHT = 100.0;
52 const int MINIMUM_HEIGHT = 500;
53 
54 const QPointF POS_LEFT (PREVIEW_WIDTH / 3.0,
55  PREVIEW_HEIGHT * 2.0 / 3.0);
56 const QPointF POS_CENTER (PREVIEW_WIDTH / 2.0,
57  PREVIEW_HEIGHT / 3.0);
58 const QPointF POS_RIGHT (2.0 * PREVIEW_WIDTH / 3.0,
59  PREVIEW_HEIGHT * 2.0 / 3.0);
60 
62  DlgSettingsAbstractBase (tr ("Curve Properties"),
63  "DlgSettingsCurveProperties",
64  mainWindow),
65  m_modelMainWindow (mainWindow.modelMainWindow()),
66  m_scenePreview (nullptr),
67  m_viewPreview (nullptr),
68  m_modelCurveStylesBefore (nullptr),
69  m_modelCurveStylesAfter (nullptr)
70 {
71  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::DlgSettingsCurveProperties";
72 
73  QWidget *subPanel = createSubPanel ();
74  finishPanel (subPanel);
75 
76  setMinimumWidth (740); // Override finishPanel width for room for m_cmbLineType and preview to be completely visible
77 }
78 
79 DlgSettingsCurveProperties::~DlgSettingsCurveProperties()
80 {
81  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::~DlgSettingsCurveProperties";
82 }
83 
84 void DlgSettingsCurveProperties::createCurveName (QGridLayout *layout,
85  int &row)
86 {
87  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::createCurveName";
88 
89  QLabel *labelCurveName = new QLabel (QString ("%1:").arg (tr ("Curve Name")));
90  layout->addWidget (labelCurveName, row, 1);
91 
92  m_cmbCurveName = new QComboBox ();
93  m_cmbCurveName->setWhatsThis (tr ("Name of the curve that is currently selected for editing"));
94  connect (m_cmbCurveName, SIGNAL (activated (const QString &)), this, SLOT (slotCurveName (const QString &))); // activated() ignores code changes
95  layout->addWidget (m_cmbCurveName, row++, 2);
96 }
97 
98 void DlgSettingsCurveProperties::createLine (QGridLayout *layout,
99  int &row)
100 {
101  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::createLine";
102 
103  m_groupLine = new QGroupBox (tr ("Line"));
104  layout->addWidget (m_groupLine, row++, 2);
105 
106  QGridLayout *layoutGroup = new QGridLayout;
107  m_groupLine->setLayout (layoutGroup);
108 
109  QLabel *labelLineWidth = new QLabel (QString ("%1:").arg (tr ("Width")));
110  layoutGroup->addWidget (labelLineWidth, 0, 0);
111 
112  m_spinLineWidth = new QSpinBox (m_groupLine);
113  m_spinLineWidth->setWhatsThis (tr ("Select a width for the lines drawn between points.\n\n"
114  "This applies only to graph curves. No lines are ever drawn between axis points."));
115  m_spinLineWidth->setMinimum(1);
116  connect (m_spinLineWidth, SIGNAL (valueChanged (int)), this, SLOT (slotLineWidth (int)));
117  layoutGroup->addWidget (m_spinLineWidth, 0, 1);
118 
119  QLabel *labelLineColor = new QLabel (QString ("%1:").arg (tr ("Color")));
120  layoutGroup->addWidget (labelLineColor, 1, 0);
121 
122  m_cmbLineColor = new QComboBox (m_groupLine);
123  m_cmbLineColor->setWhatsThis (tr ("Select a color for the lines drawn between points.\n\n"
124  "This applies only to graph curves. No lines are ever drawn between axis points."));
125  populateColorComboWithTransparent (*m_cmbLineColor);
126  connect (m_cmbLineColor, SIGNAL (activated (const QString &)), this, SLOT (slotLineColor (const QString &))); // activated() ignores code changes
127  layoutGroup->addWidget (m_cmbLineColor, 1, 1);
128 
129  QLabel *labelLineType = new QLabel (QString ("%1:").arg (tr ("Connect as")));
130  layoutGroup->addWidget (labelLineType, 2, 0);
131 
132  m_cmbLineType = new QComboBox (m_groupLine);
133  m_cmbLineType->addItem (CONNECT_AS_FUNCTION_STRAIGHT_STR, QVariant (CONNECT_AS_FUNCTION_STRAIGHT));
134  m_cmbLineType->addItem (CONNECT_AS_FUNCTION_SMOOTH_STR, QVariant (CONNECT_AS_FUNCTION_SMOOTH));
135  m_cmbLineType->addItem (CONNECT_AS_RELATION_STRAIGHT_STR, QVariant (CONNECT_AS_RELATION_STRAIGHT));
136  m_cmbLineType->addItem (CONNECT_AS_RELATION_SMOOTH_STR, QVariant (CONNECT_AS_RELATION_SMOOTH));
137  m_cmbLineType->setWhatsThis (tr ("Select rule for connecting points with lines.\n\n"
138  "If the curve is connected as a single-valued function then the points are ordered by "
139  "increasing value of the independent variable.\n\n"
140  "If the curve is connected as a closed contour, then the points are ordered by age, except for "
141  "points placed along an existing line. Any point placed on top of any existing line is inserted "
142  "between the two endpoints of that line - as if its age was between the ages of the two "
143  "endpoints.\n\n"
144  "Lines are drawn between successively ordered points.\n\n"
145  "Straight curves are drawn with straight lines between successive points. Smooth curves are drawn "
146  "with smooth lines between successive points, using natural cubic splines of (x,y) pairs versus "
147  "scalar ordinal (t) values.\n\n"
148  "This applies only to graph curves. No lines are ever drawn between axis points."));
149  connect (m_cmbLineType, SIGNAL (activated (const QString &)), this, SLOT (slotLineType (const QString &))); // activated() ignores code changes
150  layoutGroup->addWidget (m_cmbLineType, 2, 1);
151 }
152 
153 void DlgSettingsCurveProperties::createPoint (QGridLayout *layout,
154  int &row)
155 {
156  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::createPoint";
157 
158  m_groupPoint = new QGroupBox (tr ("Point"));
159  layout->addWidget (m_groupPoint, row++, 1);
160 
161  QGridLayout *layoutGroup = new QGridLayout;
162  m_groupPoint->setLayout (layoutGroup);
163 
164  QLabel *labelPointShape = new QLabel(QString ("%1:").arg (tr ("Shape")));
165  layoutGroup->addWidget (labelPointShape, 0, 0);
166 
167  m_cmbPointShape = new QComboBox (m_groupPoint);
168  m_cmbPointShape->setWhatsThis (tr ("Select a shape for the points"));
169  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_CIRCLE),
170  POINT_SHAPE_CIRCLE);
171  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_CROSS),
172  POINT_SHAPE_CROSS);
173  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_DIAMOND),
174  POINT_SHAPE_DIAMOND);
175  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_HOURGLASS),
176  POINT_SHAPE_HOURGLASS);
177  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_SQUARE),
178  POINT_SHAPE_SQUARE);
179  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_TRIANGLE),
180  POINT_SHAPE_TRIANGLE);
181  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_TRIANGLE2),
182  POINT_SHAPE_TRIANGLE2);
183  m_cmbPointShape->addItem (pointShapeToString (POINT_SHAPE_X),
184  POINT_SHAPE_X);
185  connect (m_cmbPointShape, SIGNAL (activated (const QString &)), this, SLOT (slotPointShape (const QString &))); // activated() ignores code changes
186  layoutGroup->addWidget (m_cmbPointShape, 0, 1);
187 
188  QLabel *labelPointRadius = new QLabel (QString ("%1:").arg (tr ("Radius")));
189  layoutGroup->addWidget (labelPointRadius, 1, 0);
190 
191  m_spinPointRadius = new QSpinBox (m_groupPoint);
192  m_spinPointRadius->setWhatsThis (tr ("Select a radius, in pixels, for the points"));
193  m_spinPointRadius->setMinimum (1);
194  connect (m_spinPointRadius, SIGNAL (valueChanged (int)), this, SLOT (slotPointRadius (int)));
195  layoutGroup->addWidget (m_spinPointRadius, 1, 1);
196 
197  QLabel *labelPointLineWidth = new QLabel (QString ("%1:").arg (tr ("Line width")));
198  layoutGroup->addWidget (labelPointLineWidth, 2, 0);
199 
200  m_spinPointLineWidth = new QSpinBox (m_groupPoint);
201  m_spinPointLineWidth->setWhatsThis (tr ("Select a line width, in pixels, for the points.\n\n"
202  "A larger width results in a thicker line, with the exception of a value of zero "
203  "which always results in a line that is one pixel wide (which is easy to see even "
204  "when zoomed far out)"));
205  m_spinPointLineWidth->setMinimum (0);
206  connect (m_spinPointLineWidth, SIGNAL (valueChanged (int)), this, SLOT (slotPointLineWidth (int)));
207  layoutGroup->addWidget (m_spinPointLineWidth, 2, 1);
208 
209  QLabel *labelPointColor = new QLabel (QString ("%1:").arg (tr ("Color")));
210  layoutGroup->addWidget (labelPointColor, 3, 0);
211 
212  m_cmbPointColor = new QComboBox (m_groupPoint);
213  m_cmbPointColor->setWhatsThis (tr ("Select a color for the line used to draw the point shapes"));
214  populateColorComboWithoutTransparent (*m_cmbPointColor);
215  connect (m_cmbPointColor, SIGNAL (activated (const QString &)), this, SLOT (slotPointColor (const QString &))); // activated() ignores code changes
216  layoutGroup->addWidget (m_cmbPointColor, 3, 1);
217 }
218 
220 {
221  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::createOptionalSaveDefault";
222 
223  m_btnSaveDefault = new QPushButton ("Save As Default");
224  m_btnSaveDefault->setWhatsThis (tr ("Save the visible curve settings for use as future defaults, according to the curve name selection.\n\n"
225  "If the visible settings are for the axes curve, then they will be used for future "
226  "axes curves, until new settings are saved as the defaults.\n\n"
227  "If the visible settings are for the Nth graph curve in the curve list, then they will be used for future "
228  "graph curves that are also the Nth graph curve in their curve list, until new settings are saved as the defaults."));
229  connect (m_btnSaveDefault, SIGNAL (released ()), this, SLOT (slotSaveDefault ()));
230  layout->addWidget (m_btnSaveDefault, 0, Qt::AlignLeft);
231 }
232 
233 void DlgSettingsCurveProperties::createPreview (QGridLayout *layout,
234  int &row)
235 {
236  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::createPreview";
237 
238  QLabel *labelPreview = new QLabel (tr ("Preview"));
239  layout->addWidget (labelPreview, row++, 0, 1, 4);
240 
241  m_scenePreview = new QGraphicsScene (this);
242  m_viewPreview = new ViewPreview (m_scenePreview,
243  ViewPreview::VIEW_ASPECT_RATIO_ONE_TO_ONE,
244  this);
245  m_viewPreview->setWhatsThis (tr ("Preview window that shows how current settings affect the points and line of the selected curve.\n\n"
246  "The X coordinate is in the horizontal direction, and the Y coordinate is in the vertical direction. A "
247  "function can have only one Y value, at most, for any X value, but a relation can have multiple Y values "
248  "for one X value."));
249  m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
250  m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
251  m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
252  m_viewPreview->setRenderHint (QPainter::Antialiasing);
253 
254  layout->addWidget (m_viewPreview, row++, 0, 1, 4);
255 }
256 
258 {
259  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::createSubPanel";
260 
261  QWidget *subPanel = new QWidget ();
262  QGridLayout *layout = new QGridLayout (subPanel);
263  subPanel->setLayout (layout);
264 
265  int row = 0;
266  createCurveName (layout, row);
267 
268  int rowLeft = row, rowRight = row++;
269  createPoint (layout, rowLeft);
270  createLine (layout, rowRight);
271  createPreview (layout, row);
272 
273  layout->setColumnStretch(0, 1); // Empty first column
274  layout->setColumnStretch(1, 0); // Point group
275  layout->setColumnStretch(2, 0); // Line group
276  layout->setColumnStretch(3, 1); // Empty last column
277 
278  layout->setRowStretch (0, 1); // Expand empty first row
279 
280  return subPanel;
281 }
282 
283 void DlgSettingsCurveProperties::drawLine (bool isRelation,
284  const LineStyle &lineStyle)
285 {
286  const double Z_LINE = -1.0; // Looks nicer if line goes under the points, so points are unobscured
287 
288  // Line between points. Start with function connection
289  QPainterPath path;
290  QPointF p0 (POS_LEFT), p1 (POS_CENTER), p2 (POS_RIGHT);
291  if (isRelation) {
292 
293  // Relation connection
294  p1 = POS_RIGHT;
295  p2 = POS_CENTER;
296  }
297 
298  // Draw straight or smooth
299  if (lineStyle.curveConnectAs() == CONNECT_AS_FUNCTION_SMOOTH ||
300  lineStyle.curveConnectAs() == CONNECT_AS_RELATION_SMOOTH) {
301 
302  vector<double> t;
303  vector<SplinePair> xy;
304  t.push_back(0);
305  t.push_back(1);
306  t.push_back(2);
307  xy.push_back (SplinePair (p0.x(), p0.y()));
308  xy.push_back (SplinePair (p1.x(), p1.y()));
309  xy.push_back (SplinePair (p2.x(), p2.y()));
310  Spline spline (t, xy);
311  path.moveTo (p0);
312  path.cubicTo (QPointF (spline.p1(0).x(),
313  spline.p1(0).y()),
314  QPointF (spline.p2(0).x(),
315  spline.p2(0).y()),
316  p1);
317  path.cubicTo (QPointF (spline.p1(1).x(),
318  spline.p1(1).y()),
319  QPointF (spline.p2(1).x(),
320  spline.p2(1).y()),
321  p2);
322  } else {
323  path.moveTo (p0);
324  path.lineTo (p1);
325  path.lineTo (p2);
326  }
327 
328  QGraphicsPathItem *line = new QGraphicsPathItem (path);
329  line->setPen (QPen (QBrush (ColorPaletteToQColor (lineStyle.paletteColor())),
330  lineStyle.width()));
331  line->setZValue (Z_LINE);
332  m_scenePreview->addItem (line);
333 }
334 
335 void DlgSettingsCurveProperties::drawPoints (const PointStyle &pointStyle)
336 {
337  const QString NULL_IDENTIFIER;
338  GeometryWindow *NULL_GEOMETRY_WINDOW = nullptr;
339 
340  GraphicsPointFactory pointFactory;
341 
342  // Left point
343  GraphicsPoint *pointLeft = pointFactory.createPoint (*m_scenePreview,
344  NULL_IDENTIFIER,
345  POS_LEFT,
346  pointStyle,
347  NULL_GEOMETRY_WINDOW);
348  pointLeft->setPointStyle (pointStyle);
349 
350  // Center point
351  GraphicsPoint *pointCenter = pointFactory.createPoint (*m_scenePreview,
352  NULL_IDENTIFIER,
353  POS_CENTER,
354  pointStyle,
355  NULL_GEOMETRY_WINDOW);
356  pointCenter->setPointStyle (pointStyle);
357 
358  // Right point
359  GraphicsPoint *pointRight = pointFactory.createPoint (*m_scenePreview,
360  NULL_IDENTIFIER,
361  POS_RIGHT,
362  pointStyle,
363  NULL_GEOMETRY_WINDOW);
364  pointRight->setPointStyle (pointStyle);
365 }
366 
368 {
369  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::handleOk";
370 
371  ENGAUGE_CHECK_PTR (m_modelCurveStylesBefore);
372  ENGAUGE_CHECK_PTR (m_modelCurveStylesAfter);
373 
375  cmdMediator ().document(),
376  *m_modelCurveStylesBefore,
377  *m_modelCurveStylesAfter);
378  cmdMediator ().push (cmd);
379 
380  hide ();
381 }
382 
384 {
385  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::load";
386 
388 
389  // Flush old data
390  delete m_modelCurveStylesBefore;
391  delete m_modelCurveStylesAfter;
392 
393  // Save new data
394  m_modelCurveStylesBefore = new CurveStyles (cmdMediator.coordSystem());
395  m_modelCurveStylesAfter = new CurveStyles (cmdMediator.coordSystem());
396 
397  // Populate controls. First load curve name combobox. The curve-specific controls get loaded in slotCurveName
398  m_cmbCurveName->clear ();
399  m_cmbCurveName->addItem (AXIS_CURVE_NAME);
400  QStringList curveNames = cmdMediator.curvesGraphsNames();
401  QStringList::const_iterator itr;
402  for (itr = curveNames.begin (); itr != curveNames.end (); itr++) {
403 
404  QString curveName = *itr;
405  m_cmbCurveName->addItem (curveName);
406  }
407 
408  loadForCurveName (mainWindow().selectedGraphCurve());
409 
410  m_isDirty = false;
411  enableOk (false); // Disable Ok button since there not yet any changes
412 }
413 
414 void DlgSettingsCurveProperties::loadForCurveName (const QString &curveName)
415 {
416  int indexCurveName = m_cmbCurveName->findText(curveName);
417  ENGAUGE_ASSERT (indexCurveName >= 0);
418  m_cmbCurveName->setCurrentIndex(indexCurveName);
419 
420  int indexPointShape = m_cmbPointShape->findData (QVariant (m_modelCurveStylesAfter->pointShape (curveName)));
421  ENGAUGE_ASSERT (indexPointShape >= 0);
422  m_cmbPointShape->setCurrentIndex (indexPointShape);
423 
424  m_spinPointRadius->setValue (m_modelCurveStylesAfter->pointRadius(curveName));
425  m_spinPointLineWidth->setValue (m_modelCurveStylesAfter->pointLineWidth(curveName));
426 
427  int indexPointColor = m_cmbPointColor->findData (QVariant (m_modelCurveStylesAfter->pointColor(curveName)));
428  ENGAUGE_ASSERT (indexPointColor >= 0);
429  m_cmbPointColor->setCurrentIndex (indexPointColor);
430 
431  int indexLineColor = m_cmbLineColor->findData (QVariant (m_modelCurveStylesAfter->lineColor(curveName)));
432  ENGAUGE_ASSERT (indexLineColor >= 0);
433  m_cmbLineColor->setCurrentIndex (indexLineColor);
434 
435  m_spinLineWidth->setValue (m_modelCurveStylesAfter->lineWidth(curveName));
436 
437  int indexCurveConnectAs = m_cmbLineType->findData (QVariant (m_modelCurveStylesAfter->lineConnectAs (curveName)));
438  if (indexCurveConnectAs >= 0) {
439  // Value is not CONNECT_SKIP_FOR_AXIS_CURVE
440  m_cmbLineType->setCurrentIndex (indexCurveConnectAs);
441  }
442 
443  // Disable line controls for axis curve since connecting with visible lines is better handled by Checker class
444  m_cmbLineColor->setEnabled (curveName != AXIS_CURVE_NAME);
445  m_spinLineWidth->setEnabled (curveName != AXIS_CURVE_NAME);
446  m_cmbLineType->setEnabled (curveName != AXIS_CURVE_NAME);
447 
448  updateControls();
449  updatePreview();
450 }
451 
452 void DlgSettingsCurveProperties::resetSceneRectangle ()
453 {
454 
455  QRect rect (0,
456  0,
457  qFloor (PREVIEW_WIDTH),
458  qFloor (PREVIEW_HEIGHT));
459 
460  QGraphicsRectItem *itemPerimeter = new QGraphicsRectItem(rect);
461  itemPerimeter->setVisible(false);
462  m_scenePreview->addItem (itemPerimeter);
463  m_viewPreview->centerOn (QPointF (0.0, 0.0));
464 }
465 
466 void DlgSettingsCurveProperties::setCurveName (const QString &curveName)
467 {
468  m_cmbCurveName->setCurrentText (curveName);
469  loadForCurveName (curveName);
470 }
471 
473 {
474  if (!smallDialogs) {
475  setMinimumHeight (MINIMUM_HEIGHT);
476  }
477 }
478 
479 void DlgSettingsCurveProperties::slotCurveName(const QString &curveName)
480 {
481  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotCurveName";
482 
483  // Dirty flag is not set when simply changing to new curve
484 
485  // Do nothing if combobox is getting cleared, or load has not been called yet
486  if (!curveName.isEmpty () && (m_modelCurveStylesAfter != nullptr)) {
487 
488  loadForCurveName (curveName);
489  }
490 }
491 
492 void DlgSettingsCurveProperties::slotLineColor(const QString &lineColor)
493 {
494  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotLineColor color=" << lineColor.toLatin1().data();
495 
496  m_isDirty = true;
497 
498  m_modelCurveStylesAfter->setLineColor(m_cmbCurveName->currentText(),
499  static_cast<ColorPalette> (m_cmbLineColor->currentData().toInt()));
500  updateControls();
501  updatePreview();
502 }
503 
504 void DlgSettingsCurveProperties::slotLineWidth(int width)
505 {
506  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotLineWidth width=" << width;
507 
508  m_isDirty = true;
509 
510  m_modelCurveStylesAfter->setLineWidth(m_cmbCurveName->currentText(),
511  width);
512  updateControls ();
513  updatePreview();
514 }
515 
516 void DlgSettingsCurveProperties::slotLineType(const QString &lineType)
517 {
518  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotLineType lineType=" << lineType.toLatin1().data();
519 
520  m_isDirty = true;
521 
522  m_modelCurveStylesAfter->setLineConnectAs(m_cmbCurveName->currentText(),
523  static_cast<CurveConnectAs> (m_cmbLineType->currentData().toInt ()));
524  updateControls();
525  updatePreview();
526 }
527 
528 void DlgSettingsCurveProperties::slotPointColor(const QString &pointColor)
529 {
530  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotPointColor pointColor=" << pointColor.toLatin1().data();
531 
532  m_isDirty = true;
533 
534  m_modelCurveStylesAfter->setPointColor(m_cmbCurveName->currentText(),
535  static_cast<ColorPalette> (m_cmbPointColor->currentData().toInt ()));
536  updateControls();
537  updatePreview();
538 }
539 
540 void DlgSettingsCurveProperties::slotPointLineWidth(int lineWidth)
541 {
542  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotPointLineWidth lineWidth=" << lineWidth;
543 
544  m_isDirty = true;
545 
546  m_modelCurveStylesAfter->setPointLineWidth(m_cmbCurveName->currentText(),
547  lineWidth);
548  updateControls();
549  updatePreview();
550 }
551 
552 void DlgSettingsCurveProperties::slotPointRadius(int radius)
553 {
554  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotPointRadius radius=" << radius;
555 
556  m_isDirty = true;
557 
558  m_modelCurveStylesAfter->setPointRadius(m_cmbCurveName->currentText(),
559  radius);
560  updateControls();
561  updatePreview();
562 }
563 
564 void DlgSettingsCurveProperties::slotPointShape(const QString &)
565 {
566  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotPointShape";
567 
568  m_isDirty = true;
569 
570  m_modelCurveStylesAfter->setPointShape(m_cmbCurveName->currentText(),
571  static_cast<PointShape> (m_cmbPointShape->currentData().toInt ()));
572  updateControls();
573  updatePreview();
574 }
575 
576 void DlgSettingsCurveProperties::slotSaveDefault()
577 {
578  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCurveProperties::slotSaveDefault";
579 
580  QString curve = m_cmbCurveName->currentText ();
581 
582  QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
583  if (curve == AXIS_CURVE_NAME) {
584 
585  settings.beginGroup (SETTINGS_GROUP_CURVE_AXES);
586 
587  } else {
588 
589  SettingsForGraph settingsForGraph;
590  QString groupName = settingsForGraph.groupNameForNthCurve(m_cmbCurveName->currentIndex());
591  settings.beginGroup (groupName);
592 
593  }
594 
595  settings.setValue (SETTINGS_CURVE_POINT_SHAPE,
596  m_modelCurveStylesAfter->pointShape(curve));
597  settings.setValue (SETTINGS_CURVE_LINE_COLOR,
598  m_modelCurveStylesAfter->lineColor(curve));
599  settings.setValue (SETTINGS_CURVE_LINE_CONNECT_AS,
600  m_modelCurveStylesAfter->lineConnectAs(curve));
601  settings.setValue (SETTINGS_CURVE_LINE_WIDTH,
602  m_modelCurveStylesAfter->lineWidth(curve));
603  settings.setValue (SETTINGS_CURVE_POINT_COLOR,
604  m_modelCurveStylesAfter->pointColor (curve));
605  settings.setValue (SETTINGS_CURVE_POINT_LINE_WIDTH,
606  m_modelCurveStylesAfter->pointLineWidth(curve));
607  settings.setValue (SETTINGS_CURVE_POINT_RADIUS,
608  m_modelCurveStylesAfter->pointRadius(curve));
609  settings.endGroup ();
610 }
611 
612 void DlgSettingsCurveProperties::updateControls()
613 {
614  bool isGoodState = !m_spinPointRadius->text().isEmpty () &&
615  !m_spinPointLineWidth->text().isEmpty () &&
616  !m_spinLineWidth->text().isEmpty ();
617  m_cmbCurveName->setEnabled (isGoodState); // User needs to fix state before switching curves
618  enableOk (isGoodState && m_isDirty);
619 }
620 
621 void DlgSettingsCurveProperties::updatePreview()
622 {
623  m_scenePreview->clear();
624 
625  QString currentCurve = m_cmbCurveName->currentText();
626 
627  const PointStyle pointStyle = m_modelCurveStylesAfter->curveStyle (currentCurve).pointStyle();
628  const LineStyle lineStyle = m_modelCurveStylesAfter->curveStyle (currentCurve).lineStyle();
629 
630  // Function or relation?
631  bool isRelation = (lineStyle.curveConnectAs() == CONNECT_AS_RELATION_SMOOTH ||
632  lineStyle.curveConnectAs() == CONNECT_AS_RELATION_STRAIGHT);
633 
634  drawPoints (pointStyle);
635  drawLine (isRelation,
636  lineStyle);
637 
638  resetSceneRectangle();
639 }
void setLineColor(const QString &curveName, ColorPalette lineColor)
Set method for line color in specified curve.
Manage storage and retrieval of the settings for the curves.
CurveStyle curveStyle(const QString &curveName) const
CurveStyle in specified curve.
Definition: CurveStyles.cpp:79
Factor for generating GraphicsPointAbstractBase class objects.
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
void setLineConnectAs(const QString &curveName, CurveConnectAs curveConnectAs)
Set method for connect as method for lines in specified curve.
void setCurveName(const QString &curveName)
Load information for the specified curve name. When called externally, the load method must have been...
void setLineWidth(const QString &curveName, int width)
Set method for line width in specified curve.
Cubic interpolation given independent and dependent value vectors.
Definition: Spline.h:29
void setPointLineWidth(const QString &curveName, int width)
Set method for curve point perimeter line width.
unsigned int width() const
Width of line.
Definition: LineStyle.cpp:173
Model for DlgSettingsCurveProperties and CmdSettingsCurveProperties.
Definition: CurveStyles.h:22
int lineWidth(const QString &curveName) const
Get method for line width in specified curve.
PointStyle pointStyle() const
Get method for PointStyle.
Definition: CurveStyle.cpp:75
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Command for DlgSettingsCurveProperties.
DlgSettingsCurveProperties(MainWindow &mainWindow)
Single constructor.
Window that displays the geometry information, as a table, for the current curve.
virtual void handleOk()
Process slotOk.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH, int minimumHeightOrZero=0)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
void setPointStyle(const PointStyle &pointStyle)
Update the point style.
GraphicsPoint * createPoint(QGraphicsScene &scene, const QString &identifier, const QPointF &posScreen, const PointStyle &pointStyle, GeometryWindow *geometryWindow)
Create circle or polygon point according to the PointStyle.
PointShape pointShape(const QString &curveName) const
Get method for curve point shape.
ColorPalette pointColor(const QString &curveName) const
Get method for curve point color in specified curve.
ColorPalette paletteColor() const
Line color.
Definition: LineStyle.cpp:128
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window,...
Definition: ViewPreview.h:14
Details for a specific Point.
Definition: PointStyle.h:20
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
void populateColorComboWithoutTransparent(QComboBox &combo)
Add colors in color palette to combobox, without transparent entry at end.
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:26
int pointRadius(const QString &curveName) const
Get method for curve point radius.
Details for a specific Line.
Definition: LineStyle.h:19
Graphics item for drawing a circular or polygonal Point.
Definition: GraphicsPoint.h:43
void setPointRadius(const QString &curveName, int radius)
Set method for curve point radius.
CurveConnectAs lineConnectAs(const QString &curveName) const
Get method for connect as method for lines in specified curve.
Definition: CurveStyles.cpp:91
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
QString groupNameForNthCurve(int indexOneBased) const
Return the group name, that appears in the settings file/registry, for the specified curve index.
Command queue stack.
Definition: CmdMediator.h:23
void populateColorComboWithTransparent(QComboBox &combo)
Add colors in color palette to combobox, with transparent entry at end.
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
Abstract base class for all Settings dialogs.
ColorPalette lineColor(const QString &curveName) const
Get method for line color in specified curve.
Definition: CurveStyles.cpp:85
int pointLineWidth(const QString &curveName) const
Get method for curve point line width.
void setPointShape(const QString &curveName, PointShape shape)
Set method for curve point shape in specified curve.
const CoordSystem & coordSystem() const
Provide the current CoordSystem to commands with read-only access, primarily for undo/redo processing...
Definition: CmdMediator.cpp:52
MainWindow & mainWindow()
Get method for MainWindow.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:91
Single X/Y pair for cubic spline interpolation initialization and calculations.
Definition: SplinePair.h:13
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: CmdMediator.cpp:62
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void setPointColor(const QString &curveName, ColorPalette curveColor)
Set method curve point color in specified curve.