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