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);
339 void DlgSettingsCoords::createPreview (QGridLayout *layout,
342 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
344 QLabel *labelPreview =
new QLabel (
"Preview");
345 layout->addWidget (labelPreview, row++, 0, 1, 4);
347 m_scenePreview =
new QGraphicsScene (
this);
349 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
351 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
352 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
353 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
356 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
361 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
363 QWidget *subPanel =
new QWidget ();
364 QGridLayout *layout =
new QGridLayout (subPanel);
365 subPanel->setLayout (layout);
367 layout->setColumnStretch(0, 1);
368 layout->setColumnStretch(1, 0);
369 layout->setColumnStretch(2, 0);
370 layout->setColumnStretch(3, 1);
373 createGroupCoordsType(layout, row);
374 createGroupXTheta (layout, row);
375 createGroupYRadius (layout, row);
376 createDateTime (layout, row);
377 createPreview (layout, row);
382 void DlgSettingsCoords::drawCartesianLinearX ()
384 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
387 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
388 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
389 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
390 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
391 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
393 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
395 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
396 line->setPen(QPen (QBrush (Qt::black),
403 void DlgSettingsCoords::drawCartesianLinearY ()
405 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
408 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
409 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
410 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
411 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
412 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
414 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
416 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
417 line->setPen(QPen (QBrush (Qt::black),
424 void DlgSettingsCoords::drawCartesianLogX ()
426 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
429 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
430 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
432 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
433 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
434 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
435 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
437 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
439 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
440 line->setPen(QPen (QBrush (Qt::black),
447 void DlgSettingsCoords::drawCartesianLogY ()
449 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
452 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
453 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
454 (pow (POWER_FOR_LOG, 1.0) - 1.0);
455 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
456 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
457 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
458 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
460 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
462 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
463 line->setPen(QPen (QBrush (Qt::black),
470 void DlgSettingsCoords::drawPolarLinearRadius ()
472 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
474 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
475 double radius = step * POLAR_STEP;
476 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
480 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
481 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
483 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
487 void DlgSettingsCoords::drawPolarLogRadius ()
489 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
491 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
492 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
493 (pow (POWER_FOR_LOG, 1.0) - 1.0);
494 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
495 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - 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)));
506 void DlgSettingsCoords::drawPolarTheta ()
508 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
511 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
512 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
513 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
514 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
515 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
516 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
517 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
519 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
521 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
522 line->setPen(QPen (QBrush (Qt::black),
531 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
534 cmdMediator ().document(),
535 *m_modelCoordsBefore,
536 *m_modelCoordsAfter);
544 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
550 QRectF rectGraph = boundingRectGraph (cmdMediator,
552 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
553 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
554 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
555 m_xThetaLog->setEnabled (!xThetaGoesNegative);
556 m_yRadiusLinear->setEnabled (!yRGoesNegative);
557 m_yRadiusLog->setEnabled (!yRGoesNegative);
560 if (m_modelCoordsBefore != 0) {
561 delete m_modelCoordsBefore;
563 if (m_modelCoordsAfter != 0) {
564 delete m_modelCoordsAfter;
573 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
578 m_editOriginRadius->setValidator (m_validatorOriginRadius);
579 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
581 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
582 m_btnCartesian->setChecked (
true);
584 m_btnPolar->setChecked (
true);
588 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
589 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
591 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
594 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
596 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
603 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
604 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
605 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
606 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
613 void DlgSettingsCoords::loadComboBoxDate()
615 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
619 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
620 QVariant (COORD_UNITS_DATE_SKIP));
621 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
622 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
623 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
624 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
625 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
626 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
628 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
630 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
631 m_cmbDate->setCurrentIndex (index);
634 void DlgSettingsCoords::loadComboBoxTime()
636 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
640 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
641 QVariant (COORD_UNITS_TIME_SKIP));
642 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
643 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
644 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
645 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
647 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
649 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
650 m_cmbTime->setCurrentIndex (index);
653 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
654 CoordUnitsNonPolarTheta coordUnits)
656 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
660 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
661 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
662 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
663 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
664 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
665 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
666 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
667 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
669 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
671 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n"
672 "Date and time values have date and/or time components.\n\n"
673 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
674 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
676 int index = cmb.findData (coordUnits);
677 cmb.setCurrentIndex (index);
680 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
681 CoordUnitsPolarTheta coordUnits)
683 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
687 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
688 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
689 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
690 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
691 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
692 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
693 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
694 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
695 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
696 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
697 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
698 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
699 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
700 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
702 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
704 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n"
705 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are "
706 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n"
707 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
708 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n"
709 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n"
710 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n"
711 "Turns format uses a single real number. One complete revolution is one turn.")));
713 int index = cmb.findData (coordUnits);
714 cmb.setCurrentIndex (index);
717 void DlgSettingsCoords::resetSceneRectangle ()
719 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
720 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
721 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
722 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
724 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
725 itemPerimeter->setVisible(
false);
726 m_scenePreview->addItem (itemPerimeter);
727 m_viewPreview->centerOn (QPointF (0.0, 0.0));
730 void DlgSettingsCoords::slotCartesianPolar (
bool)
732 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
734 if (m_btnCartesian->isChecked ()) {
743 void DlgSettingsCoords::slotDate(
const QString &)
745 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
747 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
753 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
755 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
757 QString numberText = m_editOriginRadius->text();
764 void DlgSettingsCoords::slotTime(
const QString &)
766 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
768 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
774 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
776 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
778 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
779 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
782 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
789 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
791 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
793 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
794 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
803 void DlgSettingsCoords::slotXThetaLinear()
805 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
812 void DlgSettingsCoords::slotXThetaLog()
814 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
821 void DlgSettingsCoords::slotYRadiusLinear()
823 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
825 delete m_validatorOriginRadius;
833 m_editOriginRadius->setValidator (m_validatorOriginRadius);
840 void DlgSettingsCoords::slotYRadiusLog()
842 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
844 delete m_validatorOriginRadius;
852 m_editOriginRadius->setValidator (m_validatorOriginRadius);
859 void DlgSettingsCoords::updateControls ()
863 QString textOriginRadius = m_editOriginRadius->text();
864 int posOriginRadius = 0;
866 bool goodOriginRadius =
true;
867 if (m_editOriginRadius->isEnabled ()) {
870 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
871 posOriginRadius) == QValidator::Acceptable);
876 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
878 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
879 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
880 if (m_btnCartesian->isChecked()) {
881 m_yRadiusLinear->setEnabled (
true);
882 m_yRadiusLog->setEnabled (
true);
892 int posOriginRadiusOther;
893 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
897 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
898 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
900 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
902 QString captionXTheta = (m_btnCartesian->isChecked () ?
904 THETA) + QString (
" Coordinates");
905 QString captionYRadius = (m_btnCartesian->isChecked () ?
907 QString (
"R")) + QString (
" Coordinates");
909 if (m_boxXTheta->title() != captionXTheta) {
910 m_boxXTheta->setTitle (captionXTheta);
913 if (m_boxYRadius->title () != captionYRadius) {
914 m_boxYRadius->setTitle (captionYRadius);
918 if (m_btnCartesian->isChecked()) {
919 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
920 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
922 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
924 m_cmbDate->setEnabled (enableDateTime);
925 m_cmbTime->setEnabled (enableDateTime);
927 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls"
928 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
929 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
930 <<
" originRadius=" << posOriginRadius
931 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
932 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
935 void DlgSettingsCoords::updatePreview()
937 m_scenePreview->clear();
945 if (m_btnCartesian->isChecked()) {
948 if (m_xThetaLinear->isChecked()) {
949 drawCartesianLinearX ();
951 drawCartesianLogX ();
954 if (m_yRadiusLinear->isChecked()) {
955 drawCartesianLinearY ();
957 drawCartesianLogY ();
964 if (m_yRadiusLinear->isChecked()) {
965 drawPolarLinearRadius ();
967 drawPolarLogRadius ();
971 annotateRadiusAtOrigin (defaultFont);
972 annotateAngles (defaultFont);
975 resetSceneRectangle();
void setCoordUnitsTime(CoordUnitsTime coordUnits)
Set method for time units.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
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.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
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.
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.
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.
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...
Abstract base class for all Settings dialogs.
QLocale locale() const
Get method for locale.
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...
MainWindowModel modelMainWindow() const
Get method for main window model.
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.