Engauge Digitizer  2
DlgSettingsCoords.cpp
1 #include "CallbackBoundingRects.h"
2 #include "CmdMediator.h"
3 #include "CmdSettingsCoords.h"
4 #include "CoordUnitsDate.h"
5 #include "CoordUnitsTime.h"
6 #include "DlgSettingsCoords.h"
7 #include "DlgValidatorAbstract.h"
8 #include "DlgValidatorFactory.h"
9 #include "DocumentModelCoords.h"
10 #include "EngaugeAssert.h"
11 #include "Logger.h"
12 #include "MainWindow.h"
13 #include <math.h>
14 #include <QComboBox>
15 #include <QDebug>
16 #include <QDoubleValidator>
17 #include <QGraphicsRectItem>
18 #include <QGridLayout>
19 #include <QGroupBox>
20 #include <QGraphicsScene>
21 #include <QLabel>
22 #include <QLineEdit>
23 #include <QPalette>
24 #include <QRadioButton>
25 #include <QStackedWidget>
26 #include <QVBoxLayout>
27 #include "Transformation.h"
28 #include "ViewPreview.h"
29 
30 const QString OVERRIDDEN_VALUE(""); // Values are overridden in updateControls
31 
32 const int COLUMN_0 = 0;
33 const int COLUMN_1 = 1;
34 
35 const int STEPS_PER_CYCLE = 4; // Repeat STEPS_PER_CYLE-1 unhighlighted steps plus 1 highlighted step in each cycle
36 const int STEPS_CYCLE_COUNT = 4; // Repeat one highlighted step + STEPS_UNHIGHLIGHTED_PER_HIGHLIGHTED steps this many times
37 const int NUM_COORD_STEPS = 1 + STEPS_PER_CYCLE * STEPS_CYCLE_COUNT;
38 
39 const int MAX_WIDTH_EDIT_ORIGIN_RADIUS = 140;
40 
41 const int CARTESIAN_COORD_MAX = 100;
42 const int CARTESIAN_COORD_MIN = -100;
43 const double CARTESIAN_COORD_STEP = (CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN) / (NUM_COORD_STEPS - 1.0);
44 
45 const int POLAR_RADIUS = CARTESIAN_COORD_MAX;
46 const double POLAR_STEP = POLAR_RADIUS / (NUM_COORD_STEPS - 1.0);
47 
48 const int POLAR_THETA_MAX = 360;
49 const int POLAR_THETA_MIN = 0;
50 const double POLAR_THETA_STEP = (POLAR_THETA_MAX - POLAR_THETA_MIN) / (NUM_COORD_STEPS - 1.0);
51 
52 const double XCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
53 const double YCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
54 
55 const double LINE_WIDTH_THIN = 0.0;
56 const double LINE_WIDTH_THICK = 2.0;
57 
58 const double PI = 3.1415926535;
59 const double DEG_2_RAD = PI / 180.0;
60 
61 const int FONT_SIZE = 6;
62 
63 const double POWER_FOR_LOG = 10.0; // Need a larger power (certainly more than e) to make log gradient obvious
64 
66  DlgSettingsAbstractBase ("Coordinates",
67  "DlgSettingsCoords",
68  mainWindow),
69  m_btnCartesian (0),
70  m_btnPolar (0),
71  m_validatorOriginRadius (0),
72  m_cmbDate (0),
73  m_cmbTime (0),
74  m_scenePreview (0),
75  m_viewPreview (0),
76  m_modelCoordsBefore (0),
77  m_modelCoordsAfter (0)
78 {
79  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::DlgSettingsCoords";
80 
81  QWidget *subPanel = createSubPanel ();
82  finishPanel (subPanel);
83 }
84 
85 DlgSettingsCoords::~DlgSettingsCoords()
86 {
87  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::~DlgSettingsCoords";
88 }
89 
90 void DlgSettingsCoords::annotateAngles (const QFont &defaultFont) {
91 
92  // 0=+x, 1=+y, 2=-x, 3=-y
93  for (int direction = 0; direction < 4; direction++) {
94 
95  QString angle;
96  CoordUnitsPolarTheta thetaUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData().toInt();
97 
98  switch (thetaUnits) {
99  case COORD_UNITS_POLAR_THETA_DEGREES:
100  case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
101  case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
102  angle = QString::number (90.0 * direction);
103  break;
104 
105  case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
106  angle = QString::number (90.0 * direction);
107  if (direction == 1) {
108  angle = "90E";
109  } else if (direction == 3) {
110  angle = "90W";
111  }
112  break;
113 
114  case COORD_UNITS_POLAR_THETA_GRADIANS:
115  angle = QString::number (100.0 * direction);
116  break;
117 
118  case COORD_UNITS_POLAR_THETA_RADIANS:
119  {
120  static QString radiansUnits [] = {"0", "PI / 2", "PI", "3 * PI / 2"};
121  ENGAUGE_ASSERT (direction < 4);
122  angle = radiansUnits [direction];
123  }
124  break;
125 
126  case COORD_UNITS_POLAR_THETA_TURNS:
127  {
128  static QString turnsUnits [] = {"0", "1 / 4", "1 / 2", "3 / 4"};
129  ENGAUGE_ASSERT (direction < 4);
130  angle = turnsUnits [direction];
131  }
132  break;
133 
134  default:
135  break;
136  }
137 
138  QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
139  textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
140  double x = 0, y = 0; // Initialized to prevent compiler warning
141  switch (direction) {
142  case 0:
143  x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
144  break;
145  case 1:
146  case 3:
147  x = XCENTER - textAngle->boundingRect().width () / 2.0;
148  break;
149  case 2:
150  x = CARTESIAN_COORD_MIN;
151  break;
152  }
153  switch (direction) {
154  case 0:
155  case 2:
156  y = YCENTER;
157  break;
158  case 1:
159  y = CARTESIAN_COORD_MIN;
160  break;
161  case 3:
162  y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
163  break;
164  }
165 
166  textAngle->setPos (x, y);
167  }
168 }
169 
170 void DlgSettingsCoords::annotateRadiusAtOrigin(const QFont &defaultFont) {
171 
172  QGraphicsTextItem *textRadius = m_scenePreview->addText (m_editOriginRadius->text());
173  textRadius->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
174  textRadius->setPos (XCENTER - textRadius->boundingRect().width () / 2.0,
175  YCENTER);
176 }
177 
178 QRectF DlgSettingsCoords::boundingRectGraph (CmdMediator &cmdMediator,
179  bool &isEmpty) const
180 {
181  CallbackBoundingRects ftor (mainWindow().transformation());
182 
183  Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
185 
186  // There may or may one, two or three axis points. Even if all three are not defined (so
187  // transformation is not defined), we can still get coordinates if there are one or two
188  cmdMediator.iterateThroughCurvePointsAxes (ftorWithCallback);
189 
190  // If the transformation is not defined, then there are no graph coordinates to extract
191  // from the graph curves (and probably trigger an assert)
192  if (mainWindow().transformIsDefined()) {
193  cmdMediator.iterateThroughCurvesPointsGraphs (ftorWithCallback);
194  }
195 
196  return ftor.boundingRectGraph(isEmpty);
197 }
198 
199 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
200  int &row)
201 {
202  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createDateTime";
203 
204  QLabel *label = new QLabel("Date/Time:");
205  layout->addWidget (label, row, 1);
206 
207  QWidget *widgetCombos = new QWidget;
208  layout->addWidget (widgetCombos, row++, 2);
209  QHBoxLayout *layoutCombos = new QHBoxLayout;
210  widgetCombos->setLayout (layoutCombos);
211 
212  // Put date and time comboboxes into same widget
213  m_cmbDate = new QComboBox;
214  m_cmbDate->setWhatsThis ("Date format to be used for date values, and date portion of mixed date/time values, "
215  "during input and output.\n\n"
216  "Setting the format to an empty value results in just the time portion appearing in output.");
217  connect (m_cmbDate, SIGNAL (activated (const QString &)), this, SLOT (slotDate (const QString &)));
218  layoutCombos->addWidget (m_cmbDate);
219 
220  m_cmbTime = new QComboBox;
221  m_cmbTime->setWhatsThis ("Time format to be used for time values, and time portion of mixed date/time values, "
222  "during input and output.\n\n"
223  "Setting the format to an empty value results in just the date portion appearing in output.");
224  connect (m_cmbTime, SIGNAL (activated (const QString &)), this, SLOT (slotTime (const QString &)));
225  layoutCombos->addWidget (m_cmbTime);
226 }
227 
228 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
229  int &row)
230 {
231  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createGroupCoordsType";
232 
233  m_boxCoordsType = new QGroupBox("Coordinates Types");
234  layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
235 
236  QVBoxLayout *layoutGroup = new QVBoxLayout (m_boxCoordsType);
237 
238  QString polarButtonText = QString("Polar (") + THETA + QString(", R)");
239 
240  m_btnCartesian = new QRadioButton ("Cartesian (X, Y)", m_boxCoordsType);
241  m_btnCartesian->setWhatsThis (QString(tr("Select cartesian coordinates.\n\n"
242  "The X and Y coordinates will be used")));
243  connect (m_btnCartesian, SIGNAL (toggled(bool)), this, SLOT (slotCartesianPolar (bool)));
244  layoutGroup->addWidget (m_btnCartesian);
245 
246  m_btnPolar = new QRadioButton (polarButtonText, m_boxCoordsType);
247  m_btnPolar->setWhatsThis (QString(tr("Select polar coordinates.\n\n"
248  "The Theta and R coordinates will be used.\n\n"
249  "Polar coordinates are not allowed with log scale for Theta")));
250  connect (m_btnPolar, SIGNAL (toggled(bool)), this, SLOT (slotCartesianPolar (bool)));
251  layoutGroup->addWidget (m_btnPolar);
252 }
253 
254 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
255  int &row)
256 {
257  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createGroupXTheta";
258 
259  m_boxXTheta = new QGroupBox(OVERRIDDEN_VALUE);
260  layout->addWidget (m_boxXTheta, row++, 1, 1, 2);
261 
262  QGridLayout *layoutXTheta = new QGridLayout (m_boxXTheta);
263  m_boxXTheta->setLayout (layoutXTheta);
264  int rowGroup = 0;
265 
266  QLabel *labelScale = new QLabel ("Scale:");
267  layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
268 
269  m_xThetaLinear = new QRadioButton ("Linear", m_boxXTheta);
270  m_xThetaLinear->setWhatsThis (QString(tr("Specifies linear scale for the X or Theta coordinate")));
271  connect (m_xThetaLinear, SIGNAL (released ()), this, SLOT (slotXThetaLinear()));
272  layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
273 
274  m_xThetaLog = new QRadioButton ("Log", m_boxXTheta);
275  m_xThetaLog->setWhatsThis (QString(tr("Specifies logarithmic scale for the X or Theta coordinate.\n\n"
276  "Log scale is not allowed if there are negative coordinates.\n\n"
277  "Log scale is not allowed for the Theta coordinate.")));
278  connect (m_xThetaLog, SIGNAL (released ()), this, SLOT (slotXThetaLog()));
279  layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
280 
281  QLabel *labelThetaUnits = new QLabel("Units:");
282  layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
283 
284  m_cmbXThetaUnits = new QComboBox;
285  connect (m_cmbXThetaUnits, SIGNAL (activated (const QString &)), this, SLOT (slotUnitsXTheta(const QString &))); // activated() ignores code changes
286  layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
287 }
288 
289 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
290  int &row)
291 {
292  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createGroupYRadius";
293 
294  m_boxYRadius = new QGroupBox (OVERRIDDEN_VALUE);
295  layout->addWidget (m_boxYRadius, row++, 1, 1, 2);
296 
297  QGridLayout *layoutYRadius = new QGridLayout (m_boxYRadius);
298  m_boxYRadius->setLayout (layoutYRadius);
299  int rowGroup = 0;
300 
301  QLabel *labelScale = new QLabel ("Scale:");
302  layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
303 
304  m_yRadiusLinear = new QRadioButton ("Linear", m_boxYRadius);
305  m_yRadiusLinear->setWhatsThis (QString(tr("Specifies linear scale for the Y or R coordinate")));
306  connect (m_yRadiusLinear, SIGNAL(released()), this, SLOT (slotYRadiusLinear()));
307  layoutYRadius->addWidget (m_yRadiusLinear, rowGroup++, COLUMN_0);
308 
309  m_yRadiusLog = new QRadioButton ("Log", m_boxYRadius);
310  m_yRadiusLog->setWhatsThis (QString(tr("Specifies logarithmic scale for the Y or R coordinate\n\n"
311  "Log scale is not allowed if there are negative coordinates.")));
312  connect (m_yRadiusLog, SIGNAL(released ()), this, SLOT (slotYRadiusLog ()));
313  layoutYRadius->addWidget (m_yRadiusLog, rowGroup++, COLUMN_0);
314 
315  QLabel *labelUnits = new QLabel("Units:");
316  layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
317 
318  m_cmbYRadiusUnits = new QComboBox;
319  connect (m_cmbYRadiusUnits, SIGNAL (activated (const QString &)), this, SLOT (slotUnitsYRadius(const QString &))); // activated() ignores code changes
320  layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
321 
322  rowGroup = 0;
323  QLabel *labelOriginRadius = new QLabel("Origin radius value:");
324  layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
325 
326  m_editOriginRadius = new QLineEdit (m_boxYRadius);
327  m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
328  m_editOriginRadius->setWhatsThis (QString(tr("Specify radius value at origin.\n\n"
329  "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases "
330  "(like when the radial units are decibels).")));
331  connect (m_editOriginRadius, SIGNAL (textChanged (const QString &)), this, SLOT (slotPolarOriginRadius(const QString &)));
332  layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
333 }
334 
335 void DlgSettingsCoords::createPreview (QGridLayout *layout,
336  int &row)
337 {
338  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createPreview";
339 
340  QLabel *labelPreview = new QLabel ("Preview");
341  layout->addWidget (labelPreview, row++, 0, 1, 4);
342 
343  m_scenePreview = new QGraphicsScene (this);
344  m_viewPreview = new ViewPreview (m_scenePreview, this);
345  m_viewPreview->setWhatsThis (tr ("Preview window that shows how current settings affect the coordinate system."));
346  m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
347  m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
348  m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
349 
350  layout->addWidget (m_viewPreview, row++, 0, 1, 4);
351 }
352 
354 {
355  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createSubPanel";
356 
357  QWidget *subPanel = new QWidget ();
358  QGridLayout *layout = new QGridLayout (subPanel);
359  subPanel->setLayout (layout);
360 
361  layout->setColumnStretch(0, 1); // Empty first column
362  layout->setColumnStretch(1, 0); // Labels
363  layout->setColumnStretch(2, 0); // User controls
364  layout->setColumnStretch(3, 1); // Empty last column
365 
366  int row = 0;
367  createGroupCoordsType(layout, row);
368  createGroupXTheta (layout, row);
369  createGroupYRadius (layout, row);
370  createDateTime (layout, row);
371  createPreview (layout, row);
372 
373  return subPanel;
374 }
375 
376 void DlgSettingsCoords::drawCartesianLinearX ()
377 {
378  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLinearX";
379 
380  bool isAxis = true;
381  for (int step = 0; step < NUM_COORD_STEPS; step++) {
382  double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
383  QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
384  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
385  line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
386  LINE_WIDTH_THIN,
387  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
388  if (isAxis) {
389  line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
390  line->setPen(QPen (QBrush (Qt::black),
391  LINE_WIDTH_THICK));
392  }
393  isAxis = false;
394  }
395 }
396 
397 void DlgSettingsCoords::drawCartesianLinearY ()
398 {
399  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLinearY";
400 
401  bool isAxis = true;
402  for (int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
403  double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
404  QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
405  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
406  line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
407  LINE_WIDTH_THIN,
408  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
409  if (isAxis) {
410  line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
411  line->setPen(QPen (QBrush (Qt::black),
412  LINE_WIDTH_THICK));
413  }
414  isAxis = false;
415  }
416 }
417 
418 void DlgSettingsCoords::drawCartesianLogX ()
419 {
420  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLogX";
421 
422  bool isAxis = true;
423  for (int step = 0; step < NUM_COORD_STEPS; step++) {
424  double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
425  (exp (1.0) - 1.0);
426  double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
427  QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
428  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
429  line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
430  LINE_WIDTH_THIN,
431  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
432  if (isAxis) {
433  line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
434  line->setPen(QPen (QBrush (Qt::black),
435  LINE_WIDTH_THICK));
436  }
437  isAxis = false;
438  }
439 }
440 
441 void DlgSettingsCoords::drawCartesianLogY ()
442 {
443  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLogY";
444 
445  bool isAxis = true;
446  for (int step = 0; step < NUM_COORD_STEPS; step++) {
447  double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
448  (pow (POWER_FOR_LOG, 1.0) - 1.0);
449  double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN; // Invert y coordinate (min<->max)
450  QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
451  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
452  line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
453  LINE_WIDTH_THIN,
454  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
455  if (isAxis) {
456  line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
457  line->setPen(QPen (QBrush (Qt::black),
458  LINE_WIDTH_THICK));
459  }
460  isAxis = false;
461  }
462 }
463 
464 void DlgSettingsCoords::drawPolarLinearRadius ()
465 {
466  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawPolarLinearRadius";
467 
468  for (int step = 0; step < NUM_COORD_STEPS; step++) {
469  double radius = step * POLAR_STEP;
470  QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
471  YCENTER - radius,
472  2.0 * radius,
473  2.0 * radius);
474  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
475  line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
476  LINE_WIDTH_THIN,
477  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
478  }
479 }
480 
481 void DlgSettingsCoords::drawPolarLogRadius ()
482 {
483  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawPolarLogRadius";
484 
485  for (int step = 0; step < NUM_COORD_STEPS; step++) {
486  double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
487  (pow (POWER_FOR_LOG, 1.0) - 1.0);
488  double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
489  QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
490  YCENTER - radius,
491  2.0 * radius,
492  2.0 * radius);
493  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
494  line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
495  LINE_WIDTH_THIN,
496  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
497  }
498 }
499 
500 void DlgSettingsCoords::drawPolarTheta ()
501 {
502  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawPolarTheta";
503 
504  bool isAxis = true;
505  for (int step = 0; step < NUM_COORD_STEPS; step++) {
506  double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
507  double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
508  double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
509  QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
510  bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
511  line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
512  LINE_WIDTH_THIN,
513  (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
514  if (isAxis) {
515  line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
516  line->setPen(QPen (QBrush (Qt::black),
517  LINE_WIDTH_THICK));
518  }
519  isAxis = false;
520  }
521 }
522 
524 {
525  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::handleOk";
526 
528  cmdMediator ().document(),
529  *m_modelCoordsBefore,
530  *m_modelCoordsAfter);
531  cmdMediator ().push (cmd);
532 
533  hide ();
534 }
535 
537 {
538  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::load";
539 
540  setCmdMediator (cmdMediator);
541 
542  // Remove if coordinates are log so later constraints can be applied
543  bool isEmpty;
544  QRectF rectGraph = boundingRectGraph (cmdMediator,
545  isEmpty);
546  bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
547  bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
548  m_xThetaLinear->setEnabled (!xThetaGoesNegative);
549  m_xThetaLog->setEnabled (!xThetaGoesNegative);
550  m_yRadiusLinear->setEnabled (!yRGoesNegative);
551  m_yRadiusLog->setEnabled (!yRGoesNegative);
552 
553  // Flush old data
554  if (m_modelCoordsBefore != 0) {
555  delete m_modelCoordsBefore;
556  }
557  if (m_modelCoordsAfter != 0) {
558  delete m_modelCoordsAfter;
559  }
560 
561  // Save new data
562  m_modelCoordsBefore = new DocumentModelCoords (cmdMediator.document().modelCoords());
563  m_modelCoordsAfter = new DocumentModelCoords (cmdMediator.document().modelCoords());
564 
565  // Populate controls
566  DlgValidatorFactory dlgValidatorFactory;
567  m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->coordScaleYRadius(),
568  m_modelCoordsAfter->coordUnitsRadius(),
569  m_modelCoordsAfter->coordUnitsDate(),
570  m_modelCoordsAfter->coordUnitsTime());
571  m_editOriginRadius->setValidator (m_validatorOriginRadius); // Set before call to setText so validator is defined in updateControls
572  m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->originRadius ()));
573 
574  if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
575  m_btnCartesian->setChecked (true);
576  } else {
577  m_btnPolar->setChecked (true);
578  }
579 
580  // X and Y units
581  if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
582  loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
583  m_modelCoordsAfter->coordUnitsX());
584  loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
585  m_modelCoordsAfter->coordUnitsY());
586  } else {
587  loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
588  m_modelCoordsAfter->coordUnitsTheta());
589  loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
590  m_modelCoordsAfter->coordUnitsRadius());
591  }
592 
593  loadComboBoxDate();
594  loadComboBoxTime ();
595 
596  m_xThetaLinear->setChecked (m_modelCoordsAfter->coordScaleXTheta() == COORD_SCALE_LINEAR);
597  m_xThetaLog->setChecked (m_modelCoordsAfter->coordScaleXTheta() == COORD_SCALE_LOG);
598  m_yRadiusLinear->setChecked (m_modelCoordsAfter->coordScaleYRadius() == COORD_SCALE_LINEAR);
599  m_yRadiusLog->setChecked (m_modelCoordsAfter->coordScaleYRadius() == COORD_SCALE_LOG);
600 
601  updateControls (); // Probably redundant due to the setChecked just above
602  enableOk (false); // Disable Ok button since there not yet any changes
603  updatePreview();
604 }
605 
606 void DlgSettingsCoords::loadComboBoxDate()
607 {
608  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxDate";
609 
610  m_cmbDate->clear ();
611 
612  m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
613  QVariant (COORD_UNITS_DATE_SKIP));
614  m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
615  QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
616  m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
617  QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
618  m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
619  QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
620 
621  ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
622 
623  int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->coordUnitsDate()));
624  m_cmbDate->setCurrentIndex (index);
625 }
626 
627 void DlgSettingsCoords::loadComboBoxTime()
628 {
629  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxTime";
630 
631  m_cmbTime->clear ();
632 
633  m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
634  QVariant (COORD_UNITS_TIME_SKIP));
635  m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
636  QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
637  m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
638  QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
639 
640  ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
641 
642  int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->coordUnitsTime()));
643  m_cmbTime->setCurrentIndex (index);
644 }
645 
646 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
647  CoordUnitsNonPolarTheta coordUnits)
648 {
649  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxUnitsNonPolar";
650 
651  cmb.clear();
652 
653  cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
654  QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
655  cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
656  QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
657  cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
658  QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
659  cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
660  QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
661 
662  ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
663 
664  cmb.setWhatsThis (QString (tr ("Numbers have the simplest and most general format.\n\n"
665  "Date and time values have date and/or time components.\n\n"
666  "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
667  "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
668 
669  int index = cmb.findData (coordUnits);
670  cmb.setCurrentIndex (index);
671 }
672 
673 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
674  CoordUnitsPolarTheta coordUnits)
675 {
676  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxUnitsPolar";
677 
678  cmb.clear();
679 
680  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
681  QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
682  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
683  QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
684  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
685  QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
686  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
687  QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
688  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
689  QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
690  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
691  QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
692  cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
693  QVariant (COORD_UNITS_POLAR_THETA_TURNS));
694 
695  ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
696 
697  cmb.setWhatsThis (QString (tr ("Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n"
698  "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are "
699  "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n"
700  "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
701  "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n"
702  "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n"
703  "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n"
704  "Turns format uses a single real number. One complete revolution is one turn.")));
705 
706  int index = cmb.findData (coordUnits);
707  cmb.setCurrentIndex (index);
708 }
709 
710 void DlgSettingsCoords::resetSceneRectangle ()
711 {
712  QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
713  CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
714  CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
715  CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
716 
717  QGraphicsRectItem *itemPerimeter = new QGraphicsRectItem(rect);
718  itemPerimeter->setVisible(false);
719  m_scenePreview->addItem (itemPerimeter);
720  m_viewPreview->centerOn (QPointF (0.0, 0.0));
721 }
722 
723 void DlgSettingsCoords::slotCartesianPolar (bool)
724 {
725  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotCartesian";
726 
727  if (m_btnCartesian->isChecked ()) {
728  m_modelCoordsAfter->setCoordsType (COORDS_TYPE_CARTESIAN);
729  } else {
730  m_modelCoordsAfter->setCoordsType(COORDS_TYPE_POLAR);
731  }
732  updateControls();
733  updatePreview();
734 }
735 
736 void DlgSettingsCoords::slotDate(const QString &)
737 {
738  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotDate";
739 
740  CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
741  m_modelCoordsAfter->setCoordUnitsDate(coordUnits);
742  updateControls();
743  updatePreview();
744 }
745 
746 void DlgSettingsCoords::slotPolarOriginRadius(const QString &)
747 {
748  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotPolarOriginRadius";
749 
750  QString numberText = m_editOriginRadius->text();
751 
752  m_modelCoordsAfter->setOriginRadius(numberText.toDouble ());
753  updateControls();
754  updatePreview();
755 }
756 
757 void DlgSettingsCoords::slotTime(const QString &)
758 {
759  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotTime";
760 
761  CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
762  m_modelCoordsAfter->setCoordUnitsTime(coordUnits);
763  updateControls();
764  updatePreview();
765 }
766 
767 void DlgSettingsCoords::slotUnitsXTheta(const QString &)
768 {
769  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotUnitsXTheta";
770 
771  if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
772  CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
773  m_modelCoordsAfter->setCoordUnitsX(coordUnits);
774  } else {
775  CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
776  m_modelCoordsAfter->setCoordUnitsTheta(coordUnits);
777  }
778  updateControls ();
779  updatePreview();
780 }
781 
782 void DlgSettingsCoords::slotUnitsYRadius(const QString &)
783 {
784  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotUnitsYRadius";
785 
786  CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
787  if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
788  m_modelCoordsAfter->setCoordUnitsY(coordUnits);
789  } else {
790  m_modelCoordsAfter->setCoordUnitsRadius(coordUnits);
791  }
792  updateControls ();
793  updatePreview();
794 }
795 
796 void DlgSettingsCoords::slotXThetaLinear()
797 {
798  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotXThetaLinear";
799 
800  m_modelCoordsAfter->setCoordScaleXTheta(COORD_SCALE_LINEAR);
801  updateControls ();
802  updatePreview();
803 }
804 
805 void DlgSettingsCoords::slotXThetaLog()
806 {
807  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotXThetaLog";
808 
809  m_modelCoordsAfter->setCoordScaleXTheta(COORD_SCALE_LOG);
810  updateControls ();
811  updatePreview();
812 }
813 
814 void DlgSettingsCoords::slotYRadiusLinear()
815 {
816  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotYRadiusLinear";
817 
818  delete m_validatorOriginRadius;
819 
820  DlgValidatorFactory dlgValidatorFactory;
821  m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (COORD_SCALE_LINEAR,
822  m_modelCoordsAfter->coordUnitsRadius(),
823  m_modelCoordsAfter->coordUnitsDate(),
824  m_modelCoordsAfter->coordUnitsTime());
825  m_editOriginRadius->setValidator (m_validatorOriginRadius);
826 
827  m_modelCoordsAfter->setCoordScaleYRadius((COORD_SCALE_LINEAR));
828  updateControls ();
829  updatePreview();
830 }
831 
832 void DlgSettingsCoords::slotYRadiusLog()
833 {
834  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotYRadiusLog";
835 
836  delete m_validatorOriginRadius;
837 
838  DlgValidatorFactory dlgValidatorFactory;
839  m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (COORD_SCALE_LOG,
840  m_modelCoordsAfter->coordUnitsRadius(),
841  m_modelCoordsAfter->coordUnitsDate(),
842  m_modelCoordsAfter->coordUnitsTime());
843  m_editOriginRadius->setValidator (m_validatorOriginRadius);
844 
845  m_modelCoordsAfter->setCoordScaleYRadius(COORD_SCALE_LOG);
846  updateControls ();
847  updatePreview();
848 }
849 
850 void DlgSettingsCoords::updateControls ()
851 {
852  // LOG4CPP_INFO_S is below
853 
854  QString textOriginRadius = m_editOriginRadius->text();
855  int posOriginRadius = 0;
856 
857  bool goodOriginRadius = true; // Cartesian coordinates do not use origin radius
858  if (m_editOriginRadius->isEnabled ()) {
859 
860  // Origin radius must be greater than zero
861  goodOriginRadius = (m_validatorOriginRadius->validate (textOriginRadius,
862  posOriginRadius) == QValidator::Acceptable);
863  }
864 
865  enableOk (goodOriginRadius);
866 
867  m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
868 
869  m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
870  m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
871  if (m_btnCartesian->isChecked()) {
872  m_yRadiusLinear->setEnabled (true);
873  m_yRadiusLog->setEnabled (true);
874  } else {
875 
876  // Use temporary validator to see if current origin radius would be correct in OTHER linear/log mode
877  DlgValidatorFactory dlgValidatorFactory;
878  DlgValidatorAbstract *dlg = dlgValidatorFactory.createWithNonPolar (m_yRadiusLinear->isChecked () ? COORD_SCALE_LOG : COORD_SCALE_LINEAR,
879  m_modelCoordsAfter->coordUnitsRadius(),
880  m_modelCoordsAfter->coordUnitsDate(),
881  m_modelCoordsAfter->coordUnitsTime());
882  int posOriginRadiusOther;
883  bool goodOriginRadiusOther = (dlg->validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
884 
885  delete dlg; // Deallocate
886 
887  m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
888  m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
889  }
890  m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
891 
892  QString captionXTheta = (m_btnCartesian->isChecked () ?
893  QString ("X") :
894  THETA) + QString (" Coordinates");
895  QString captionYRadius = (m_btnCartesian->isChecked () ?
896  QString ("Y") :
897  QString ("R")) + QString (" Coordinates");
898 
899  if (m_boxXTheta->title() != captionXTheta) {
900  m_boxXTheta->setTitle (captionXTheta);
901  }
902 
903  if (m_boxYRadius->title () != captionYRadius) {
904  m_boxYRadius->setTitle (captionYRadius);
905  }
906 
907  bool enableDateTime;
908  if (m_btnCartesian->isChecked()) {
909  enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
910  ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
911  } else {
912  enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
913  }
914  m_cmbDate->setEnabled (enableDateTime);
915  m_cmbTime->setEnabled (enableDateTime);
916 
917  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::updateControls"
918  << " textOriginRadius=" << textOriginRadius.toLatin1().data()
919  << " goodOriginRadius=" << (goodOriginRadius ? "true" : "false")
920  << " originRadius=" << posOriginRadius
921  << " btnPolarChecked=" << (m_btnPolar->isChecked() ? "true" : "false")
922  << " enableDateTime=" << (enableDateTime ? "true" : "false");
923 }
924 
925 void DlgSettingsCoords::updatePreview()
926 {
927  m_scenePreview->clear();
928 
929  // General approach
930  // 1) Axis lines are extra thick, but since they sometimes disappear as the preview window is rescaled, we keep the
931  // constant-pixel line under each axis line
932  // 2) Every STEPS_UNHIGHLIGHTED_PER_HIGHLIGHTED out of STEPS_UNHIGHLIGHTED_PER_HIGHLIGHTED+1 lines are dashed to make
933  // them more subtle
934 
935  if (m_btnCartesian->isChecked()) {
936 
937  // Cartesian
938  if (m_xThetaLinear->isChecked()) {
939  drawCartesianLinearX ();
940  } else {
941  drawCartesianLogX ();
942  }
943 
944  if (m_yRadiusLinear->isChecked()) {
945  drawCartesianLinearY ();
946  } else {
947  drawCartesianLogY ();
948  }
949 
950  } else {
951 
952  // Polar
953  drawPolarTheta ();
954  if (m_yRadiusLinear->isChecked()) {
955  drawPolarLinearRadius ();
956  } else {
957  drawPolarLogRadius ();
958  }
959 
960  QFont defaultFont;
961  annotateRadiusAtOrigin (defaultFont);
962  annotateAngles (defaultFont);
963  }
964 
965  resetSceneRectangle();
966 }
void setCoordUnitsTime(CoordUnitsTime coordUnits)
Set method for time units.
void setCoordUnitsDate(CoordUnitsDate coordUnits)
Set method for date units.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
void setCoordUnitsY(CoordUnitsNonPolarTheta coordUnits)
Set method for y units.
void setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)
Set method for x units.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
void setCoordScaleYRadius(CoordScale coordScale)
Set method for linear/log scale on y/radius.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition: Document.cpp:631
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
Abstract validator for all numeric formats.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:61
CoordUnitsTime coordUnitsTime() const
Get method for time format when used.
Command for DlgSettingsCoords.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window...
Definition: ViewPreview.h:8
CoordUnitsNonPolarTheta coordUnitsY() const
Get method for x units.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
void setCoordUnitsTheta(CoordUnitsPolarTheta coordUnits)
Set method for theta units.
CoordsType coordsType() const
Get method for coordinates type.
CoordUnitsNonPolarTheta coordUnitsX() const
Get method for x units.
Model for DlgSettingsCoords and CmdSettingsCoords.
void setOriginRadius(double originRadius)
Set method for origin radius in polar mode.
CoordUnitsDate coordUnitsDate() const
Get method for date format when used.
DlgValidatorAbstract * createWithNonPolar(CoordScale coordScale, CoordUnitsNonPolarTheta coordUnits, CoordUnitsDate coordUnitsDate, CoordUnitsTime coordUnitsTime) const
Factory method for generating validators when cartesian/polar case handling is handled externally...
void setCoordUnitsRadius(CoordUnitsNonPolarTheta coordUnits)
Set method for radius units.
void finishPanel(QWidget *subPanel)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
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.
Command queue stack.
Definition: CmdMediator.h:16
Abstract base class for all Settings dialogs.
Validator factory.
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
Definition: CmdMediator.cpp:86
void iterateThroughCurvePointsAxes(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for the single axes curve.
Definition: CmdMediator.cpp:76
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
MainWindow & mainWindow()
Get method for MainWindow.
virtual void handleOk()
Process slotOk.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:60
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void setCoordScaleXTheta(CoordScale coordScale)
Set method for linear/log scale on x/theta.
DlgSettingsCoords(MainWindow &mainWindow)
Single constructor.
CoordUnitsPolarTheta coordUnitsTheta() const
Get method for theta unit.
void setCoordsType(CoordsType coordsType)
Set method for coordinates type.