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:
119 static QString radiansUnits [] = {
"0",
"PI / 2",
"PI",
"3 * PI / 2"};
120 ENGAUGE_ASSERT (direction < 4);
121 angle = radiansUnits [direction];
124 case COORD_UNITS_POLAR_THETA_TURNS:
125 static QString turnsUnits [] = {
"0",
"1 / 4",
"1 / 2",
"3 / 4"};
126 ENGAUGE_ASSERT (direction < 4);
127 angle = turnsUnits [direction];
134 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
135 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
139 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
143 x = XCENTER - textAngle->boundingRect().width () / 2.0;
146 x = CARTESIAN_COORD_MIN;
155 y = CARTESIAN_COORD_MIN;
158 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
162 textAngle->setPos (x, y);
166 void DlgSettingsCoords::annotateRadiusAtOrigin(
const QFont &defaultFont) {
168 QGraphicsTextItem *textRadius = m_scenePreview->addText (m_editOriginRadius->text());
169 textRadius->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
170 textRadius->setPos (XCENTER - textRadius->boundingRect().width () / 2.0,
174 QRectF DlgSettingsCoords::boundingRectGraph (
CmdMediator &cmdMediator,
179 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
192 return ftor.boundingRectGraph(isEmpty);
195 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
198 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
200 QLabel *label =
new QLabel(
"Date/Time:");
201 layout->addWidget (label, row, 1);
203 QWidget *widgetCombos =
new QWidget;
204 layout->addWidget (widgetCombos, row++, 2);
205 QHBoxLayout *layoutCombos =
new QHBoxLayout;
206 widgetCombos->setLayout (layoutCombos);
209 m_cmbDate =
new QComboBox;
210 m_cmbDate->setWhatsThis (
"Date format to be used for date values, and date portion of mixed date/time values, "
211 "during input and output.\n\n"
212 "Setting the format to an empty value results in just the time portion appearing in output.");
213 connect (m_cmbDate, SIGNAL (activated (
const QString &)),
this, SLOT (slotDate (
const QString &)));
214 layoutCombos->addWidget (m_cmbDate);
216 m_cmbTime =
new QComboBox;
217 m_cmbTime->setWhatsThis (
"Time format to be used for time values, and time portion of mixed date/time values, "
218 "during input and output.\n\n"
219 "Setting the format to an empty value results in just the date portion appearing in output.");
220 connect (m_cmbTime, SIGNAL (activated (
const QString &)),
this, SLOT (slotTime (
const QString &)));
221 layoutCombos->addWidget (m_cmbTime);
224 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
227 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
229 m_boxCoordsType =
new QGroupBox(
"Coordinates Types");
230 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
232 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
234 QString polarButtonText = QString(
"Polar (") + THETA + QString(
", R)");
236 m_btnCartesian =
new QRadioButton (
"Cartesian (X, Y)", m_boxCoordsType);
237 m_btnCartesian->setWhatsThis (QString(tr(
"Select cartesian coordinates.\n\n"
238 "The X and Y coordinates will be used")));
239 connect (m_btnCartesian, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
240 layoutGroup->addWidget (m_btnCartesian);
242 m_btnPolar =
new QRadioButton (polarButtonText, m_boxCoordsType);
243 m_btnPolar->setWhatsThis (QString(tr(
"Select polar coordinates.\n\n"
244 "The Theta and R coordinates will be used.\n\n"
245 "Polar coordinates are not allowed with log scale for Theta")));
246 connect (m_btnPolar, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
247 layoutGroup->addWidget (m_btnPolar);
250 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
253 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
255 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
256 layout->addWidget (m_boxXTheta, row++, 1, 1, 2);
258 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
259 m_boxXTheta->setLayout (layoutXTheta);
262 QLabel *labelScale =
new QLabel (
"Scale:");
263 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
265 m_xThetaLinear =
new QRadioButton (
"Linear", m_boxXTheta);
266 m_xThetaLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the X or Theta coordinate")));
267 connect (m_xThetaLinear, SIGNAL (released ()),
this, SLOT (slotXThetaLinear()));
268 layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
270 m_xThetaLog =
new QRadioButton (
"Log", m_boxXTheta);
271 m_xThetaLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the X or Theta coordinate.\n\n"
272 "Log scale is not allowed if there are negative coordinates.\n\n"
273 "Log scale is not allowed for the Theta coordinate.")));
274 connect (m_xThetaLog, SIGNAL (released ()),
this, SLOT (slotXThetaLog()));
275 layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
277 QLabel *labelThetaUnits =
new QLabel(
"Units:");
278 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
280 m_cmbXThetaUnits =
new QComboBox;
281 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
282 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
285 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
288 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
290 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
291 layout->addWidget (m_boxYRadius, row++, 1, 1, 2);
293 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
294 m_boxYRadius->setLayout (layoutYRadius);
297 QLabel *labelScale =
new QLabel (
"Scale:");
298 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
300 m_yRadiusLinear =
new QRadioButton (
"Linear", m_boxYRadius);
301 m_yRadiusLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the Y or R coordinate")));
302 connect (m_yRadiusLinear, SIGNAL(released()),
this, SLOT (slotYRadiusLinear()));
303 layoutYRadius->addWidget (m_yRadiusLinear, rowGroup++, COLUMN_0);
305 m_yRadiusLog =
new QRadioButton (
"Log", m_boxYRadius);
306 m_yRadiusLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the Y or R coordinate\n\n"
307 "Log scale is not allowed if there are negative coordinates.")));
308 connect (m_yRadiusLog, SIGNAL(released ()),
this, SLOT (slotYRadiusLog ()));
309 layoutYRadius->addWidget (m_yRadiusLog, rowGroup++, COLUMN_0);
311 QLabel *labelUnits =
new QLabel(
"Units:");
312 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
314 m_cmbYRadiusUnits =
new QComboBox;
315 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
316 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
319 QLabel *labelOriginRadius =
new QLabel(
"Origin radius value:");
320 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
322 m_editOriginRadius =
new QLineEdit (m_boxYRadius);
323 m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
324 m_editOriginRadius->setWhatsThis (QString(tr(
"Specify radius value at origin.\n\n"
325 "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases "
326 "(like when the radial units are decibels).")));
327 connect (m_editOriginRadius, SIGNAL (textChanged (
const QString &)),
this, SLOT (slotPolarOriginRadius(
const QString &)));
328 layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
331 void DlgSettingsCoords::createPreview (QGridLayout *layout,
334 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
336 QLabel *labelPreview =
new QLabel (
"Preview");
337 layout->addWidget (labelPreview, row++, 0, 1, 4);
339 m_scenePreview =
new QGraphicsScene (
this);
340 m_viewPreview =
new ViewPreview (m_scenePreview,
this);
341 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
342 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
343 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
346 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
351 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
353 QWidget *subPanel =
new QWidget ();
354 QGridLayout *layout =
new QGridLayout (subPanel);
355 subPanel->setLayout (layout);
357 layout->setColumnStretch(0, 1);
358 layout->setColumnStretch(1, 0);
359 layout->setColumnStretch(2, 0);
360 layout->setColumnStretch(3, 1);
363 createGroupCoordsType(layout, row);
364 createGroupXTheta (layout, row);
365 createGroupYRadius (layout, row);
366 createDateTime (layout, row);
367 createPreview (layout, row);
372 void DlgSettingsCoords::drawCartesianLinearX ()
374 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
377 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
378 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
379 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
380 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
381 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
383 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
385 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
386 line->setPen(QPen (QBrush (Qt::black),
393 void DlgSettingsCoords::drawCartesianLinearY ()
395 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
398 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
399 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
400 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
401 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
402 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
404 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
406 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
407 line->setPen(QPen (QBrush (Qt::black),
414 void DlgSettingsCoords::drawCartesianLogX ()
416 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
419 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
420 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
422 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
423 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
424 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
425 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
427 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
429 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
430 line->setPen(QPen (QBrush (Qt::black),
437 void DlgSettingsCoords::drawCartesianLogY ()
439 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
442 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
443 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
444 (pow (POWER_FOR_LOG, 1.0) - 1.0);
445 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
446 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
447 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
448 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
450 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
452 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
453 line->setPen(QPen (QBrush (Qt::black),
460 void DlgSettingsCoords::drawPolarLinearRadius ()
462 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
464 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
465 double radius = step * POLAR_STEP;
466 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
470 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
471 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
473 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
477 void DlgSettingsCoords::drawPolarLogRadius ()
479 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
481 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
482 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
483 (pow (POWER_FOR_LOG, 1.0) - 1.0);
484 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
485 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
489 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
490 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
492 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
496 void DlgSettingsCoords::drawPolarTheta ()
498 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
501 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
502 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
503 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
504 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
505 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
506 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
507 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
509 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
511 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
512 line->setPen(QPen (QBrush (Qt::black),
521 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
524 cmdMediator ().document(),
525 *m_modelCoordsBefore,
526 *m_modelCoordsAfter);
534 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
540 QRectF rectGraph = boundingRectGraph (cmdMediator,
542 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
543 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
544 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
545 m_xThetaLog->setEnabled (!xThetaGoesNegative);
546 m_yRadiusLinear->setEnabled (!yRGoesNegative);
547 m_yRadiusLog->setEnabled (!yRGoesNegative);
550 if (m_modelCoordsBefore != 0) {
551 delete m_modelCoordsBefore;
553 if (m_modelCoordsAfter != 0) {
554 delete m_modelCoordsAfter;
563 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
567 m_editOriginRadius->setValidator (m_validatorOriginRadius);
568 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
570 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
571 m_btnCartesian->setChecked (
true);
573 m_btnPolar->setChecked (
true);
577 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
578 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
580 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
583 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
585 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
592 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
593 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
594 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
595 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
602 void DlgSettingsCoords::loadComboBoxDate()
604 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
608 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
609 QVariant (COORD_UNITS_DATE_SKIP));
610 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
611 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
612 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
613 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
614 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
615 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
617 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
619 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
620 m_cmbDate->setCurrentIndex (index);
623 void DlgSettingsCoords::loadComboBoxTime()
625 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
629 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
630 QVariant (COORD_UNITS_TIME_SKIP));
631 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
632 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
633 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
634 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
636 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
638 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
639 m_cmbTime->setCurrentIndex (index);
642 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
643 CoordUnitsNonPolarTheta coordUnits)
645 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
649 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
650 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
651 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
652 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
653 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
654 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
655 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
656 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
658 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
660 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n"
661 "Date and time values have date and/or time components.\n\n"
662 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
663 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
665 int index = cmb.findData (coordUnits);
666 cmb.setCurrentIndex (index);
669 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
670 CoordUnitsPolarTheta coordUnits)
672 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
676 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
677 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
678 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
679 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
680 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
681 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
682 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
683 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
684 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
685 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
686 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
687 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
688 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
689 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
691 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
693 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n"
694 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are "
695 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n"
696 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
697 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n"
698 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n"
699 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n"
700 "Turns format uses a single real number. One complete revolution is one turn.")));
702 int index = cmb.findData (coordUnits);
703 cmb.setCurrentIndex (index);
706 void DlgSettingsCoords::resetSceneRectangle ()
708 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
709 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
710 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
711 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
713 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
714 itemPerimeter->setVisible(
false);
715 m_scenePreview->addItem (itemPerimeter);
716 m_viewPreview->centerOn (QPointF (0.0, 0.0));
719 void DlgSettingsCoords::slotCartesianPolar (
bool)
721 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
723 if (m_btnCartesian->isChecked ()) {
732 void DlgSettingsCoords::slotDate(
const QString &)
734 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
736 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
742 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
744 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
746 QString numberText = m_editOriginRadius->text();
753 void DlgSettingsCoords::slotTime(
const QString &)
755 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
757 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
763 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
765 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
767 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
768 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
771 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
778 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
780 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
782 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
783 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
792 void DlgSettingsCoords::slotXThetaLinear()
794 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
801 void DlgSettingsCoords::slotXThetaLog()
803 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
810 void DlgSettingsCoords::slotYRadiusLinear()
812 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
814 delete m_validatorOriginRadius;
821 m_editOriginRadius->setValidator (m_validatorOriginRadius);
828 void DlgSettingsCoords::slotYRadiusLog()
830 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
832 delete m_validatorOriginRadius;
839 m_editOriginRadius->setValidator (m_validatorOriginRadius);
846 void DlgSettingsCoords::updateControls ()
850 QString textOriginRadius = m_editOriginRadius->text();
851 int posOriginRadius = 0;
853 bool goodOriginRadius =
true;
854 if (m_editOriginRadius->isEnabled ()) {
857 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
858 posOriginRadius) == QValidator::Acceptable);
863 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
865 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
866 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
867 if (m_btnCartesian->isChecked()) {
868 m_yRadiusLinear->setEnabled (
true);
869 m_yRadiusLog->setEnabled (
true);
878 int posOriginRadiusOther;
879 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
883 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
884 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
886 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
888 QString captionXTheta = (m_btnCartesian->isChecked () ?
890 THETA) + QString (
" Coordinates");
891 QString captionYRadius = (m_btnCartesian->isChecked () ?
893 QString (
"R")) + QString (
" Coordinates");
895 if (m_boxXTheta->title() != captionXTheta) {
896 m_boxXTheta->setTitle (captionXTheta);
899 if (m_boxYRadius->title () != captionYRadius) {
900 m_boxYRadius->setTitle (captionYRadius);
904 if (m_btnCartesian->isChecked()) {
905 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
906 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
908 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
910 m_cmbDate->setEnabled (enableDateTime);
911 m_cmbTime->setEnabled (enableDateTime);
913 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls"
914 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
915 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
916 <<
" originRadius=" << posOriginRadius
917 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
918 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
921 void DlgSettingsCoords::updatePreview()
923 m_scenePreview->clear();
931 if (m_btnCartesian->isChecked()) {
934 if (m_xThetaLinear->isChecked()) {
935 drawCartesianLinearX ();
937 drawCartesianLogX ();
940 if (m_yRadiusLinear->isChecked()) {
941 drawCartesianLinearY ();
943 drawCartesianLogY ();
950 if (m_yRadiusLinear->isChecked()) {
951 drawPolarLinearRadius ();
953 drawPolarLogRadius ();
957 annotateRadiusAtOrigin (defaultFont);
958 annotateAngles (defaultFont);
961 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.