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"
12 #include "MainWindow.h"
16 #include <QDoubleValidator>
17 #include <QGraphicsRectItem>
18 #include <QGridLayout>
20 #include <QGraphicsScene>
24 #include <QRadioButton>
25 #include <QStackedWidget>
26 #include <QVBoxLayout>
27 #include "Transformation.h"
28 #include "ViewPreview.h"
30 const QString OVERRIDDEN_VALUE(
"");
32 const int COLUMN_0 = 0;
33 const int COLUMN_1 = 1;
35 const int STEPS_PER_CYCLE = 4;
36 const int STEPS_CYCLE_COUNT = 4;
37 const int NUM_COORD_STEPS = 1 + STEPS_PER_CYCLE * STEPS_CYCLE_COUNT;
39 const int MAX_WIDTH_EDIT_ORIGIN_RADIUS = 140;
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);
45 const int POLAR_RADIUS = CARTESIAN_COORD_MAX;
46 const double POLAR_STEP = POLAR_RADIUS / (NUM_COORD_STEPS - 1.0);
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);
52 const double XCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
53 const double YCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
55 const double LINE_WIDTH_THIN = 0.0;
56 const double LINE_WIDTH_THICK = 2.0;
58 const double PI = 3.1415926535;
59 const double DEG_2_RAD = PI / 180.0;
61 const int FONT_SIZE = 6;
63 const double POWER_FOR_LOG = 10.0;
71 m_validatorOriginRadius (0),
76 m_modelCoordsBefore (0),
77 m_modelCoordsAfter (0)
79 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::DlgSettingsCoords";
85 DlgSettingsCoords::~DlgSettingsCoords()
87 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::~DlgSettingsCoords";
90 void DlgSettingsCoords::annotateAngles (
const QFont &defaultFont) {
93 for (
int direction = 0; direction < 4; direction++) {
96 CoordUnitsPolarTheta thetaUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData().toInt();
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);
105 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
106 angle = QString::number (90.0 * direction);
107 if (direction == 1) {
109 }
else if (direction == 3) {
114 case COORD_UNITS_POLAR_THETA_GRADIANS:
115 angle = QString::number (100.0 * direction);
118 case COORD_UNITS_POLAR_THETA_RADIANS:
120 static QString radiansUnits [] = {
"0",
"PI / 2",
"PI",
"3 * PI / 2"};
121 ENGAUGE_ASSERT (direction < 4);
122 angle = radiansUnits [direction];
126 case COORD_UNITS_POLAR_THETA_TURNS:
128 static QString turnsUnits [] = {
"0",
"1 / 4",
"1 / 2",
"3 / 4"};
129 ENGAUGE_ASSERT (direction < 4);
130 angle = turnsUnits [direction];
138 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
139 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
143 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
147 x = XCENTER - textAngle->boundingRect().width () / 2.0;
150 x = CARTESIAN_COORD_MIN;
159 y = CARTESIAN_COORD_MIN;
162 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
166 textAngle->setPos (x, y);
170 void DlgSettingsCoords::annotateRadiusAtOrigin(
const QFont &defaultFont) {
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,
178 QRectF DlgSettingsCoords::boundingRectGraph (
CmdMediator &cmdMediator,
183 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
196 return ftor.boundingRectGraph(isEmpty);
199 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
202 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
204 QLabel *label =
new QLabel(
"Date/Time:");
205 layout->addWidget (label, row, 1);
207 QWidget *widgetCombos =
new QWidget;
208 layout->addWidget (widgetCombos, row++, 2);
209 QHBoxLayout *layoutCombos =
new QHBoxLayout;
210 widgetCombos->setLayout (layoutCombos);
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);
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);
228 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
231 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
233 m_boxCoordsType =
new QGroupBox(
"Coordinates Types");
234 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
236 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
238 QString polarButtonText = QString(
"Polar (") + THETA + QString(
", R)");
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);
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);
254 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
257 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
259 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
260 layout->addWidget (m_boxXTheta, row++, 1, 1, 2);
262 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
263 m_boxXTheta->setLayout (layoutXTheta);
266 QLabel *labelScale =
new QLabel (
"Scale:");
267 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
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);
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);
281 QLabel *labelThetaUnits =
new QLabel(
"Units:");
282 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
284 m_cmbXThetaUnits =
new QComboBox;
285 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
286 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
289 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
292 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
294 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
295 layout->addWidget (m_boxYRadius, row++, 1, 1, 2);
297 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
298 m_boxYRadius->setLayout (layoutYRadius);
301 QLabel *labelScale =
new QLabel (
"Scale:");
302 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
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);
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);
315 QLabel *labelUnits =
new QLabel(
"Units:");
316 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
318 m_cmbYRadiusUnits =
new QComboBox;
319 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
320 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
323 QLabel *labelOriginRadius =
new QLabel(
"Origin radius value:");
324 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
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);
335 void DlgSettingsCoords::createPreview (QGridLayout *layout,
338 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
340 QLabel *labelPreview =
new QLabel (
"Preview");
341 layout->addWidget (labelPreview, row++, 0, 1, 4);
343 m_scenePreview =
new QGraphicsScene (
this);
345 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
347 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
348 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
349 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
352 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
357 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
359 QWidget *subPanel =
new QWidget ();
360 QGridLayout *layout =
new QGridLayout (subPanel);
361 subPanel->setLayout (layout);
363 layout->setColumnStretch(0, 1);
364 layout->setColumnStretch(1, 0);
365 layout->setColumnStretch(2, 0);
366 layout->setColumnStretch(3, 1);
369 createGroupCoordsType(layout, row);
370 createGroupXTheta (layout, row);
371 createGroupYRadius (layout, row);
372 createDateTime (layout, row);
373 createPreview (layout, row);
378 void DlgSettingsCoords::drawCartesianLinearX ()
380 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
383 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
384 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
385 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
386 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
387 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
389 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
391 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
392 line->setPen(QPen (QBrush (Qt::black),
399 void DlgSettingsCoords::drawCartesianLinearY ()
401 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
404 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
405 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
406 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
407 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
408 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
410 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
412 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
413 line->setPen(QPen (QBrush (Qt::black),
420 void DlgSettingsCoords::drawCartesianLogX ()
422 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
425 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
426 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
428 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
429 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
430 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
431 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
433 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
435 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
436 line->setPen(QPen (QBrush (Qt::black),
443 void DlgSettingsCoords::drawCartesianLogY ()
445 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
448 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
449 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
450 (pow (POWER_FOR_LOG, 1.0) - 1.0);
451 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
452 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
453 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
454 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
456 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
458 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
459 line->setPen(QPen (QBrush (Qt::black),
466 void DlgSettingsCoords::drawPolarLinearRadius ()
468 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
470 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
471 double radius = step * POLAR_STEP;
472 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
476 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
477 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
479 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
483 void DlgSettingsCoords::drawPolarLogRadius ()
485 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
487 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
488 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
489 (pow (POWER_FOR_LOG, 1.0) - 1.0);
490 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
491 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
495 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
496 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
498 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
502 void DlgSettingsCoords::drawPolarTheta ()
504 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
507 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
508 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
509 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
510 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
511 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
512 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
513 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
515 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
517 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
518 line->setPen(QPen (QBrush (Qt::black),
527 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
530 cmdMediator ().document(),
531 *m_modelCoordsBefore,
532 *m_modelCoordsAfter);
540 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
546 QRectF rectGraph = boundingRectGraph (cmdMediator,
548 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
549 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
550 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
551 m_xThetaLog->setEnabled (!xThetaGoesNegative);
552 m_yRadiusLinear->setEnabled (!yRGoesNegative);
553 m_yRadiusLog->setEnabled (!yRGoesNegative);
556 if (m_modelCoordsBefore != 0) {
557 delete m_modelCoordsBefore;
559 if (m_modelCoordsAfter != 0) {
560 delete m_modelCoordsAfter;
569 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
573 m_editOriginRadius->setValidator (m_validatorOriginRadius);
574 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
576 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
577 m_btnCartesian->setChecked (
true);
579 m_btnPolar->setChecked (
true);
583 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
584 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
586 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
589 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
591 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
598 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
599 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
600 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
601 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
608 void DlgSettingsCoords::loadComboBoxDate()
610 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
614 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
615 QVariant (COORD_UNITS_DATE_SKIP));
616 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
617 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
618 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
619 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
620 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
621 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
623 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
625 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
626 m_cmbDate->setCurrentIndex (index);
629 void DlgSettingsCoords::loadComboBoxTime()
631 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
635 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
636 QVariant (COORD_UNITS_TIME_SKIP));
637 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
638 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
639 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
640 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
642 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
644 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
645 m_cmbTime->setCurrentIndex (index);
648 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
649 CoordUnitsNonPolarTheta coordUnits)
651 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
655 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
656 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
657 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
658 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
659 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
660 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
661 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
662 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
664 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
666 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n"
667 "Date and time values have date and/or time components.\n\n"
668 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
669 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
671 int index = cmb.findData (coordUnits);
672 cmb.setCurrentIndex (index);
675 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
676 CoordUnitsPolarTheta coordUnits)
678 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
682 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
683 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
684 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
685 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
686 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
687 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
688 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
689 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
690 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
691 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
692 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
693 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
694 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
695 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
697 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
699 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n"
700 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are "
701 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n"
702 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
703 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n"
704 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n"
705 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n"
706 "Turns format uses a single real number. One complete revolution is one turn.")));
708 int index = cmb.findData (coordUnits);
709 cmb.setCurrentIndex (index);
712 void DlgSettingsCoords::resetSceneRectangle ()
714 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
715 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
716 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
717 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
719 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
720 itemPerimeter->setVisible(
false);
721 m_scenePreview->addItem (itemPerimeter);
722 m_viewPreview->centerOn (QPointF (0.0, 0.0));
725 void DlgSettingsCoords::slotCartesianPolar (
bool)
727 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
729 if (m_btnCartesian->isChecked ()) {
738 void DlgSettingsCoords::slotDate(
const QString &)
740 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
742 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
748 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
750 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
752 QString numberText = m_editOriginRadius->text();
759 void DlgSettingsCoords::slotTime(
const QString &)
761 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
763 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
769 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
771 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
773 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
774 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
777 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
784 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
786 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
788 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
789 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
798 void DlgSettingsCoords::slotXThetaLinear()
800 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
807 void DlgSettingsCoords::slotXThetaLog()
809 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
816 void DlgSettingsCoords::slotYRadiusLinear()
818 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
820 delete m_validatorOriginRadius;
827 m_editOriginRadius->setValidator (m_validatorOriginRadius);
834 void DlgSettingsCoords::slotYRadiusLog()
836 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
838 delete m_validatorOriginRadius;
845 m_editOriginRadius->setValidator (m_validatorOriginRadius);
852 void DlgSettingsCoords::updateControls ()
856 QString textOriginRadius = m_editOriginRadius->text();
857 int posOriginRadius = 0;
859 bool goodOriginRadius =
true;
860 if (m_editOriginRadius->isEnabled ()) {
863 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
864 posOriginRadius) == QValidator::Acceptable);
869 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
871 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
872 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
873 if (m_btnCartesian->isChecked()) {
874 m_yRadiusLinear->setEnabled (
true);
875 m_yRadiusLog->setEnabled (
true);
884 int posOriginRadiusOther;
885 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
889 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
890 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
892 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
894 QString captionXTheta = (m_btnCartesian->isChecked () ?
896 THETA) + QString (
" Coordinates");
897 QString captionYRadius = (m_btnCartesian->isChecked () ?
899 QString (
"R")) + QString (
" Coordinates");
901 if (m_boxXTheta->title() != captionXTheta) {
902 m_boxXTheta->setTitle (captionXTheta);
905 if (m_boxYRadius->title () != captionYRadius) {
906 m_boxYRadius->setTitle (captionYRadius);
910 if (m_btnCartesian->isChecked()) {
911 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
912 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
914 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
916 m_cmbDate->setEnabled (enableDateTime);
917 m_cmbTime->setEnabled (enableDateTime);
919 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls"
920 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
921 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
922 <<
" originRadius=" << posOriginRadius
923 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
924 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
927 void DlgSettingsCoords::updatePreview()
929 m_scenePreview->clear();
937 if (m_btnCartesian->isChecked()) {
940 if (m_xThetaLinear->isChecked()) {
941 drawCartesianLinearX ();
943 drawCartesianLogX ();
946 if (m_yRadiusLinear->isChecked()) {
947 drawCartesianLinearY ();
949 drawCartesianLogY ();
956 if (m_yRadiusLinear->isChecked()) {
957 drawPolarLinearRadius ();
959 drawPolarLogRadius ();
963 annotateRadiusAtOrigin (defaultFont);
964 annotateAngles (defaultFont);
967 resetSceneRectangle();
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.
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
Abstract validator for all numeric formats.
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...
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.
Abstract base class for all Settings dialogs.
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...
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.