7 #include "CallbackBoundingRects.h"
8 #include "CmdMediator.h"
9 #include "CmdSettingsCoords.h"
10 #include "CoordUnitsDate.h"
11 #include "CoordUnitsTime.h"
12 #include "DlgSettingsCoords.h"
13 #include "DlgValidatorAbstract.h"
14 #include "DlgValidatorFactory.h"
15 #include "DocumentModelCoords.h"
16 #include "EngaugeAssert.h"
18 #include "MainWindow.h"
22 #include <QDoubleValidator>
23 #include <QGraphicsRectItem>
24 #include <QGridLayout>
26 #include <QGraphicsScene>
31 #include <QRadioButton>
32 #include <QStackedWidget>
33 #include <QVBoxLayout>
34 #include "Transformation.h"
35 #include "ViewPreview.h"
37 const QString OVERRIDDEN_VALUE(
"");
39 const int COLUMN_0 = 0;
40 const int COLUMN_1 = 1;
42 const int STEPS_PER_CYCLE = 4;
43 const int STEPS_CYCLE_COUNT = 4;
44 const int NUM_COORD_STEPS = 1 + STEPS_PER_CYCLE * STEPS_CYCLE_COUNT;
46 const int MAX_WIDTH_EDIT_ORIGIN_RADIUS = 140;
48 const int CARTESIAN_COORD_MAX = 100;
49 const int CARTESIAN_COORD_MIN = -100;
50 const double CARTESIAN_COORD_STEP = (CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN) / (NUM_COORD_STEPS - 1.0);
52 const int POLAR_RADIUS = CARTESIAN_COORD_MAX;
53 const double POLAR_STEP = POLAR_RADIUS / (NUM_COORD_STEPS - 1.0);
55 const int POLAR_THETA_MAX = 360;
56 const int POLAR_THETA_MIN = 0;
57 const double POLAR_THETA_STEP = (POLAR_THETA_MAX - POLAR_THETA_MIN) / (NUM_COORD_STEPS - 1.0);
59 const double XCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
60 const double YCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
62 const double LINE_WIDTH_THIN = 0.0;
63 const double LINE_WIDTH_THICK = 2.0;
65 const double PI = 3.1415926535;
66 const double DEG_2_RAD = PI / 180.0;
68 const int FONT_SIZE = 6;
70 const double POWER_FOR_LOG = 10.0;
72 const int MINIMUM_DIALOG_WIDTH_COORDS = 800;
73 const int MINIMUM_HEIGHT = 540;
79 m_btnCartesian (nullptr),
81 m_validatorOriginRadius (nullptr),
84 m_scenePreview (nullptr),
85 m_viewPreview (nullptr),
86 m_modelCoordsBefore (nullptr),
87 m_modelCoordsAfter (nullptr)
89 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::DlgSettingsCoords";
93 MINIMUM_DIALOG_WIDTH_COORDS);
96 DlgSettingsCoords::~DlgSettingsCoords()
98 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::~DlgSettingsCoords";
101 void DlgSettingsCoords::annotateAngles (
const QFont &defaultFont) {
104 for (
int direction = 0; direction < 4; direction++) {
107 CoordUnitsPolarTheta thetaUnits =
static_cast<CoordUnitsPolarTheta
> (m_cmbXThetaUnits->currentData().toInt());
109 switch (thetaUnits) {
110 case COORD_UNITS_POLAR_THETA_DEGREES:
111 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
112 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
113 angle = QString::number (90.0 * direction);
116 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
117 angle = QString::number (90.0 * direction);
118 if (direction == 1) {
120 }
else if (direction == 3) {
125 case COORD_UNITS_POLAR_THETA_GRADIANS:
126 angle = QString::number (100.0 * direction);
129 case COORD_UNITS_POLAR_THETA_RADIANS:
131 static QString radiansUnits [] = {
"0",
"PI / 2",
"PI",
"3 * PI / 2"};
132 ENGAUGE_ASSERT (direction < 4);
133 angle = radiansUnits [direction];
137 case COORD_UNITS_POLAR_THETA_TURNS:
139 static QString turnsUnits [] = {
"0",
"1 / 4",
"1 / 2",
"3 / 4"};
140 ENGAUGE_ASSERT (direction < 4);
141 angle = turnsUnits [direction];
149 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
150 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
154 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
158 x = XCENTER - textAngle->boundingRect().width () / 2.0;
161 x = CARTESIAN_COORD_MIN;
170 y = CARTESIAN_COORD_MIN;
173 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
177 textAngle->setPos (x, y);
181 void DlgSettingsCoords::annotateRadiusAtOrigin(
const QFont &defaultFont) {
183 QGraphicsTextItem *textRadius = m_scenePreview->addText (m_editOriginRadius->text());
184 textRadius->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
185 textRadius->setPos (XCENTER - textRadius->boundingRect().width () / 2.0,
189 void DlgSettingsCoords::boundingRectGraph (
CmdMediator &cmdMediator,
191 QPointF &boundingRectGraphMin,
192 QPointF &boundingRectGraphMax)
const
197 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
210 boundingRectGraphMin = ftor.boundingRectGraphMin (isEmpty);
211 boundingRectGraphMax = ftor.boundingRectGraphMax (isEmpty);
214 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
217 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
219 QLabel *label =
new QLabel(QString (
"%1:").arg (tr (
"Date/Time")));
220 layout->addWidget (label, row, 1);
222 QWidget *widgetCombos =
new QWidget;
223 layout->addWidget (widgetCombos, row++, 2);
224 QHBoxLayout *layoutCombos =
new QHBoxLayout;
225 widgetCombos->setLayout (layoutCombos);
228 m_cmbDate =
new QComboBox;
229 m_cmbDate->setWhatsThis (tr (
"Date format to be used for date values, and date portion of mixed date/time values, "
230 "during input and output.\n\n"
231 "Setting the format to an empty value results in just the time portion appearing in output."));
232 connect (m_cmbDate, SIGNAL (activated (
const QString &)),
this, SLOT (slotDate (
const QString &)));
233 layoutCombos->addWidget (m_cmbDate);
235 m_cmbTime =
new QComboBox;
236 m_cmbTime->setWhatsThis (tr (
"Time format to be used for time values, and time portion of mixed date/time values, "
237 "during input and output.\n\n"
238 "Setting the format to an empty value results in just the date portion appearing in output."));
239 connect (m_cmbTime, SIGNAL (activated (
const QString &)),
this, SLOT (slotTime (
const QString &)));
240 layoutCombos->addWidget (m_cmbTime);
243 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
246 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
248 m_boxCoordsType =
new QGroupBox(tr (
"Coordinates Types"));
249 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
251 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
253 QString polarButtonText = QString(tr (
"Polar") +
" (") + THETA + QString(
", " + tr (
"R") +
")");
255 m_btnCartesian =
new QRadioButton (tr (
"Cartesian (X, Y)"), m_boxCoordsType);
256 m_btnCartesian->setWhatsThis (QString(tr(
"Select cartesian coordinates.\n\n"
257 "The X and Y coordinates will be used")));
258 connect (m_btnCartesian, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
259 layoutGroup->addWidget (m_btnCartesian);
261 m_btnPolar =
new QRadioButton (polarButtonText, m_boxCoordsType);
262 m_btnPolar->setWhatsThis (QString(tr(
"Select polar coordinates.\n\n"
263 "The Theta and R coordinates will be used.\n\n"
264 "Polar coordinates are not allowed with log scale for Theta")));
265 connect (m_btnPolar, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
266 layoutGroup->addWidget (m_btnPolar);
269 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
272 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
274 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
275 layout->addWidget (m_boxXTheta, row, 1, 1, 1);
277 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
278 m_boxXTheta->setLayout (layoutXTheta);
281 QLabel *labelScale =
new QLabel (QString (
"%1:").arg (tr (
"Scale")));
282 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
284 m_xThetaLinear =
new QRadioButton (tr (
"Linear"), m_boxXTheta);
285 m_xThetaLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the X or Theta coordinate")));
286 connect (m_xThetaLinear, SIGNAL (released ()),
this, SLOT (slotXThetaLinear()));
287 layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
289 m_xThetaLog =
new QRadioButton (tr (
"Log"), m_boxXTheta);
290 m_xThetaLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the X or Theta coordinate.\n\n"
291 "Log scale is not allowed if there are negative coordinates.\n\n"
292 "Log scale is not allowed for the Theta coordinate.")));
293 connect (m_xThetaLog, SIGNAL (released ()),
this, SLOT (slotXThetaLog()));
294 layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
296 QLabel *labelThetaUnits =
new QLabel(QString (
"%1:").arg (tr (
"Units")));
297 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
299 m_cmbXThetaUnits =
new QComboBox;
300 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
301 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
304 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
307 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
309 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
310 layout->addWidget (m_boxYRadius, row++, 2, 1, 1);
312 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
313 m_boxYRadius->setLayout (layoutYRadius);
316 QLabel *labelScale =
new QLabel (QString (
"%1:").arg (tr (
"Scale")));
317 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
319 m_yRadiusLinear =
new QRadioButton (tr (
"Linear"), m_boxYRadius);
320 m_yRadiusLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the Y or R coordinate")));
321 connect (m_yRadiusLinear, SIGNAL(released()),
this, SLOT (slotYRadiusLinear()));
322 layoutYRadius->addWidget (m_yRadiusLinear, rowGroup, COLUMN_0);
324 QLabel *labelOriginRadius =
new QLabel(QString (
"%1:").arg (tr (
"Origin radius value")));
325 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
327 m_yRadiusLog =
new QRadioButton (tr (
"Log"), m_boxYRadius);
328 m_yRadiusLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the Y or R coordinate\n\n"
329 "Log scale is not allowed if there are negative coordinates.")));
330 connect (m_yRadiusLog, SIGNAL(released ()),
this, SLOT (slotYRadiusLog ()));
331 layoutYRadius->addWidget (m_yRadiusLog, rowGroup, COLUMN_0);
333 m_editOriginRadius =
new QLineEdit (m_boxYRadius);
334 m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
335 m_editOriginRadius->setWhatsThis (QString(tr(
"Specify radius value at origin.\n\n"
336 "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases "
337 "(like when the radial units are decibels).")));
338 connect (m_editOriginRadius, SIGNAL (textChanged (
const QString &)),
this, SLOT (slotPolarOriginRadius(
const QString &)));
339 layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
341 QLabel *labelUnits =
new QLabel(QString (
"%1:").arg (tr (
"Units")));
342 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
344 m_cmbYRadiusUnits =
new QComboBox;
345 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
346 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
353 void DlgSettingsCoords::createPreview (QGridLayout *layout,
356 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
358 QLabel *labelPreview =
new QLabel (tr (
"Preview"));
359 layout->addWidget (labelPreview, row++, 0, 1, 4);
361 m_scenePreview =
new QGraphicsScene (
this);
363 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
365 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
366 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
367 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
370 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
375 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
377 QWidget *subPanel =
new QWidget ();
379 QGridLayout *layout =
new QGridLayout (subPanel);
380 subPanel->setLayout (layout);
382 layout->setColumnStretch(0, 1);
383 layout->setColumnStretch(1, 0);
384 layout->setColumnStretch(2, 0);
385 layout->setColumnStretch(3, 1);
388 createGroupCoordsType(layout, row);
389 createGroupXTheta (layout, row);
390 createGroupYRadius (layout, row);
391 createDateTime (layout, row);
392 createPreview (layout, row);
397 void DlgSettingsCoords::drawCartesianLinearX ()
399 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
402 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
403 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
404 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
405 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
406 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
408 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
410 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
411 line->setPen(QPen (QBrush (Qt::black),
418 void DlgSettingsCoords::drawCartesianLinearY ()
420 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
423 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
424 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
425 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
426 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
427 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
429 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
431 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
432 line->setPen(QPen (QBrush (Qt::black),
439 void DlgSettingsCoords::drawCartesianLogX ()
441 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
444 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
445 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
447 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
448 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
449 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
450 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
452 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
454 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
455 line->setPen(QPen (QBrush (Qt::black),
462 void DlgSettingsCoords::drawCartesianLogY ()
464 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
467 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
468 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
469 (pow (POWER_FOR_LOG, 1.0) - 1.0);
470 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
471 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
472 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
473 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
475 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
477 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
478 line->setPen(QPen (QBrush (Qt::black),
485 void DlgSettingsCoords::drawPolarLinearRadius ()
487 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
489 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
490 double radius = step * 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::drawPolarLogRadius ()
504 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
506 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
507 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
508 (pow (POWER_FOR_LOG, 1.0) - 1.0);
509 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
510 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
514 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
515 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
517 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
521 void DlgSettingsCoords::drawPolarTheta ()
523 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
526 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
527 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
528 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
529 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
530 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
531 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
532 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
534 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
536 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
537 line->setPen(QPen (QBrush (Qt::black),
546 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
549 cmdMediator ().document(),
550 *m_modelCoordsBefore,
551 *m_modelCoordsAfter);
559 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
565 QPointF boundingRectGraphMin, boundingRectGraphMax;
566 boundingRectGraph (cmdMediator,
568 boundingRectGraphMin,
569 boundingRectGraphMax);
570 bool xThetaGoesNegative = !isEmpty && (boundingRectGraphMin.x() <= 0);
571 bool yRGoesNegative = !isEmpty && (boundingRectGraphMin.y() <= 0);
572 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
573 m_xThetaLog->setEnabled (!xThetaGoesNegative);
574 m_yRadiusLinear->setEnabled (!yRGoesNegative);
575 m_yRadiusLog->setEnabled (!yRGoesNegative);
578 delete m_modelCoordsBefore;
579 delete m_modelCoordsAfter;
587 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
592 m_editOriginRadius->setValidator (m_validatorOriginRadius);
593 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
595 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
596 m_btnCartesian->setChecked (
true);
598 m_btnPolar->setChecked (
true);
605 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
606 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
607 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
608 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
615 void DlgSettingsCoords::loadComboBoxDate()
617 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
621 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
622 QVariant (COORD_UNITS_DATE_SKIP));
623 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
624 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
625 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
626 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
627 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
628 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
630 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
632 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
633 m_cmbDate->setCurrentIndex (index);
636 void DlgSettingsCoords::loadComboBoxTime()
638 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
642 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
643 QVariant (COORD_UNITS_TIME_SKIP));
644 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
645 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
646 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
647 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
649 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
651 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
652 m_cmbTime->setCurrentIndex (index);
655 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
656 CoordUnitsNonPolarTheta coordUnits)
658 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
662 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
663 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
664 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
665 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
666 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
667 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
668 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
669 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
671 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
673 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n"
674 "Date and time values have date and/or time components.\n\n"
675 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
676 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
678 int index = cmb.findData (coordUnits);
679 cmb.setCurrentIndex (index);
682 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
683 CoordUnitsPolarTheta coordUnits)
685 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
689 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
690 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
691 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
692 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
693 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
694 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
695 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
696 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
697 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
698 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
699 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
700 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
701 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
702 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
704 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
706 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n"
707 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are "
708 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n"
709 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
710 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n"
711 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n"
712 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n"
713 "Turns format uses a single real number. One complete revolution is one turn.")));
715 int index = cmb.findData (coordUnits);
716 cmb.setCurrentIndex (index);
719 void DlgSettingsCoords::resetSceneRectangle ()
721 QRect rect (qFloor (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0),
722 qFloor (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0),
723 qFloor (CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP),
724 qFloor (CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP));
726 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
727 itemPerimeter->setVisible(
false);
728 m_scenePreview->addItem (itemPerimeter);
729 m_viewPreview->centerOn (QPointF (0.0, 0.0));
735 setMinimumHeight (MINIMUM_HEIGHT);
739 void DlgSettingsCoords::slotCartesianPolar (
bool)
741 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
743 if (m_btnCartesian->isChecked ()) {
753 void DlgSettingsCoords::slotDate(
const QString &)
755 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
757 CoordUnitsDate coordUnits =
static_cast<CoordUnitsDate
> (m_cmbDate->currentData ().toInt());
763 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
765 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
767 QString numberText = m_editOriginRadius->text();
774 void DlgSettingsCoords::slotTime(
const QString &)
776 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
778 CoordUnitsTime coordUnits =
static_cast<CoordUnitsTime
> (m_cmbTime->currentData ().toInt());
784 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
786 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
788 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
789 CoordUnitsNonPolarTheta coordUnits =
static_cast<CoordUnitsNonPolarTheta
> (m_cmbXThetaUnits->currentData ().toInt ());
792 CoordUnitsPolarTheta coordUnits =
static_cast<CoordUnitsPolarTheta
> (m_cmbXThetaUnits->currentData ().toInt ());
799 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
801 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
803 CoordUnitsNonPolarTheta coordUnits =
static_cast<CoordUnitsNonPolarTheta
> (m_cmbYRadiusUnits->currentData ().toInt ());
804 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
813 void DlgSettingsCoords::slotXThetaLinear()
815 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
822 void DlgSettingsCoords::slotXThetaLog()
824 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
831 void DlgSettingsCoords::slotYRadiusLinear()
833 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
835 delete m_validatorOriginRadius;
843 m_editOriginRadius->setValidator (m_validatorOriginRadius);
850 void DlgSettingsCoords::slotYRadiusLog()
852 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
854 delete m_validatorOriginRadius;
862 m_editOriginRadius->setValidator (m_validatorOriginRadius);
869 void DlgSettingsCoords::updateControls ()
873 QString textOriginRadius = m_editOriginRadius->text();
874 int posOriginRadius = 0;
876 bool goodOriginRadius =
true;
877 if (m_editOriginRadius->isEnabled ()) {
880 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
881 posOriginRadius) == QValidator::Acceptable);
886 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
888 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
889 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
890 if (m_btnCartesian->isChecked()) {
891 m_yRadiusLinear->setEnabled (
true);
892 m_yRadiusLog->setEnabled (
true);
902 int posOriginRadiusOther;
903 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
907 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
908 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
910 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
912 QString captionXTheta = (m_btnCartesian->isChecked () ?
914 THETA) + QString (
" %1")
915 .arg (tr (
"Coordinates"));
916 QString captionYRadius = (m_btnCartesian->isChecked () ?
918 QString (tr (
"R"))) + QString (
" %1")
919 .arg (tr (
"Coordinates"));
921 if (m_boxXTheta->title() != captionXTheta) {
922 m_boxXTheta->setTitle (captionXTheta);
925 if (m_boxYRadius->title () != captionYRadius) {
926 m_boxYRadius->setTitle (captionYRadius);
930 if (m_btnCartesian->isChecked()) {
931 enableDateTime = ((
static_cast<CoordUnitsNonPolarTheta
> (m_cmbXThetaUnits->currentData ().toInt()) == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
932 (
static_cast<CoordUnitsNonPolarTheta
> (m_cmbYRadiusUnits->currentData ().toInt()) == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
934 enableDateTime = (
static_cast<CoordUnitsNonPolarTheta
> (m_cmbYRadiusUnits->currentData ().toInt()) == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
936 m_cmbDate->setEnabled (enableDateTime);
937 m_cmbTime->setEnabled (enableDateTime);
939 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls"
940 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
941 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
942 <<
" originRadius=" << posOriginRadius
943 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
944 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
947 void DlgSettingsCoords::updateCoordUnits()
950 if (m_btnCartesian->isChecked()) {
951 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
953 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
956 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
958 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
963 void DlgSettingsCoords::updatePreview()
965 m_scenePreview->clear();
973 if (m_btnCartesian->isChecked()) {
976 if (m_xThetaLinear->isChecked()) {
977 drawCartesianLinearX ();
979 drawCartesianLogX ();
982 if (m_yRadiusLinear->isChecked()) {
983 drawCartesianLinearY ();
985 drawCartesianLogY ();
992 if (m_yRadiusLinear->isChecked()) {
993 drawPolarLinearRadius ();
995 drawPolarLogRadius ();
999 annotateRadiusAtOrigin (defaultFont);
1000 annotateAngles (defaultFont);
1003 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.
DocumentAxesPointsRequired documentAxesPointsRequired() const
Get method for DocumentAxesPointsRequired.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Transformation transformation() const
Return read-only copy of transformation.
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.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH, int minimumHeightOrZero=0)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
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.
virtual void setSmallDialogs(bool smallDialogs)
If false then dialogs have a minimum size so all controls are visible.
void setCoordUnitsRadius(CoordUnitsNonPolarTheta coordUnits)
Set method for radius units.
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.