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> 30 #include <QRadioButton> 31 #include <QStackedWidget> 32 #include <QVBoxLayout> 33 #include "Transformation.h" 34 #include "ViewPreview.h" 36 const QString OVERRIDDEN_VALUE(
"");
38 const int COLUMN_0 = 0;
39 const int COLUMN_1 = 1;
41 const int STEPS_PER_CYCLE = 4;
42 const int STEPS_CYCLE_COUNT = 4;
43 const int NUM_COORD_STEPS = 1 + STEPS_PER_CYCLE * STEPS_CYCLE_COUNT;
45 const int MAX_WIDTH_EDIT_ORIGIN_RADIUS = 140;
47 const int CARTESIAN_COORD_MAX = 100;
48 const int CARTESIAN_COORD_MIN = -100;
49 const double CARTESIAN_COORD_STEP = (CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN) / (NUM_COORD_STEPS - 1.0);
51 const int POLAR_RADIUS = CARTESIAN_COORD_MAX;
52 const double POLAR_STEP = POLAR_RADIUS / (NUM_COORD_STEPS - 1.0);
54 const int POLAR_THETA_MAX = 360;
55 const int POLAR_THETA_MIN = 0;
56 const double POLAR_THETA_STEP = (POLAR_THETA_MAX - POLAR_THETA_MIN) / (NUM_COORD_STEPS - 1.0);
58 const double XCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
59 const double YCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
61 const double LINE_WIDTH_THIN = 0.0;
62 const double LINE_WIDTH_THICK = 2.0;
64 const double PI = 3.1415926535;
65 const double DEG_2_RAD = PI / 180.0;
67 const int FONT_SIZE = 6;
69 const double POWER_FOR_LOG = 10.0;
71 const int MINIMUM_DIALOG_WIDTH_COORDS = 800;
72 const int MINIMUM_HEIGHT = 540;
80 m_validatorOriginRadius (0),
85 m_modelCoordsBefore (0),
86 m_modelCoordsAfter (0)
88 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::DlgSettingsCoords";
92 MINIMUM_DIALOG_WIDTH_COORDS);
95 DlgSettingsCoords::~DlgSettingsCoords()
97 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::~DlgSettingsCoords";
100 void DlgSettingsCoords::annotateAngles (
const QFont &defaultFont) {
103 for (
int direction = 0; direction < 4; direction++) {
106 CoordUnitsPolarTheta thetaUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData().toInt();
108 switch (thetaUnits) {
109 case COORD_UNITS_POLAR_THETA_DEGREES:
110 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
111 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
112 angle = QString::number (90.0 * direction);
115 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
116 angle = QString::number (90.0 * direction);
117 if (direction == 1) {
119 }
else if (direction == 3) {
124 case COORD_UNITS_POLAR_THETA_GRADIANS:
125 angle = QString::number (100.0 * direction);
128 case COORD_UNITS_POLAR_THETA_RADIANS:
130 static QString radiansUnits [] = {
"0",
"PI / 2",
"PI",
"3 * PI / 2"};
131 ENGAUGE_ASSERT (direction < 4);
132 angle = radiansUnits [direction];
136 case COORD_UNITS_POLAR_THETA_TURNS:
138 static QString turnsUnits [] = {
"0",
"1 / 4",
"1 / 2",
"3 / 4"};
139 ENGAUGE_ASSERT (direction < 4);
140 angle = turnsUnits [direction];
148 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
149 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
153 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
157 x = XCENTER - textAngle->boundingRect().width () / 2.0;
160 x = CARTESIAN_COORD_MIN;
169 y = CARTESIAN_COORD_MIN;
172 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
176 textAngle->setPos (x, y);
180 void DlgSettingsCoords::annotateRadiusAtOrigin(
const QFont &defaultFont) {
182 QGraphicsTextItem *textRadius = m_scenePreview->addText (m_editOriginRadius->text());
183 textRadius->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
184 textRadius->setPos (XCENTER - textRadius->boundingRect().width () / 2.0,
193 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
209 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
212 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
214 QLabel *label =
new QLabel(tr (
"Date/Time:"));
215 layout->addWidget (label, row, 1);
217 QWidget *widgetCombos =
new QWidget;
218 layout->addWidget (widgetCombos, row++, 2);
219 QHBoxLayout *layoutCombos =
new QHBoxLayout;
220 widgetCombos->setLayout (layoutCombos);
223 m_cmbDate =
new QComboBox;
224 m_cmbDate->setWhatsThis (tr (
"Date format to be used for date values, and date portion of mixed date/time values, " 225 "during input and output.\n\n" 226 "Setting the format to an empty value results in just the time portion appearing in output."));
227 connect (m_cmbDate, SIGNAL (activated (
const QString &)),
this, SLOT (slotDate (
const QString &)));
228 layoutCombos->addWidget (m_cmbDate);
230 m_cmbTime =
new QComboBox;
231 m_cmbTime->setWhatsThis (tr (
"Time format to be used for time values, and time portion of mixed date/time values, " 232 "during input and output.\n\n" 233 "Setting the format to an empty value results in just the date portion appearing in output."));
234 connect (m_cmbTime, SIGNAL (activated (
const QString &)),
this, SLOT (slotTime (
const QString &)));
235 layoutCombos->addWidget (m_cmbTime);
238 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
241 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
243 m_boxCoordsType =
new QGroupBox(tr (
"Coordinates Types"));
244 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
246 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
248 QString polarButtonText = QString(tr (
"Polar") +
" (") + THETA + QString(
", " + tr (
"R") +
")");
250 m_btnCartesian =
new QRadioButton (tr (
"Cartesian (X, Y)"), m_boxCoordsType);
251 m_btnCartesian->setWhatsThis (QString(tr(
"Select cartesian coordinates.\n\n" 252 "The X and Y coordinates will be used")));
253 connect (m_btnCartesian, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
254 layoutGroup->addWidget (m_btnCartesian);
256 m_btnPolar =
new QRadioButton (polarButtonText, m_boxCoordsType);
257 m_btnPolar->setWhatsThis (QString(tr(
"Select polar coordinates.\n\n" 258 "The Theta and R coordinates will be used.\n\n" 259 "Polar coordinates are not allowed with log scale for Theta")));
260 connect (m_btnPolar, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
261 layoutGroup->addWidget (m_btnPolar);
264 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
267 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
269 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
270 layout->addWidget (m_boxXTheta, row, 1, 1, 1);
272 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
273 m_boxXTheta->setLayout (layoutXTheta);
276 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
277 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
279 m_xThetaLinear =
new QRadioButton (tr (
"Linear"), m_boxXTheta);
280 m_xThetaLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the X or Theta coordinate")));
281 connect (m_xThetaLinear, SIGNAL (released ()),
this, SLOT (slotXThetaLinear()));
282 layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
284 m_xThetaLog =
new QRadioButton (tr (
"Log"), m_boxXTheta);
285 m_xThetaLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the X or Theta coordinate.\n\n" 286 "Log scale is not allowed if there are negative coordinates.\n\n" 287 "Log scale is not allowed for the Theta coordinate.")));
288 connect (m_xThetaLog, SIGNAL (released ()),
this, SLOT (slotXThetaLog()));
289 layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
291 QLabel *labelThetaUnits =
new QLabel(tr (
"Units:"));
292 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
294 m_cmbXThetaUnits =
new QComboBox;
295 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
296 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
299 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
302 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
304 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
305 layout->addWidget (m_boxYRadius, row++, 2, 1, 1);
307 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
308 m_boxYRadius->setLayout (layoutYRadius);
311 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
312 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
314 m_yRadiusLinear =
new QRadioButton (tr (
"Linear"), m_boxYRadius);
315 m_yRadiusLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the Y or R coordinate")));
316 connect (m_yRadiusLinear, SIGNAL(released()),
this, SLOT (slotYRadiusLinear()));
317 layoutYRadius->addWidget (m_yRadiusLinear, rowGroup, COLUMN_0);
319 QLabel *labelOriginRadius =
new QLabel(tr (
"Origin radius value:"));
320 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
322 m_yRadiusLog =
new QRadioButton (tr (
"Log"), m_boxYRadius);
323 m_yRadiusLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the Y or R coordinate\n\n" 324 "Log scale is not allowed if there are negative coordinates.")));
325 connect (m_yRadiusLog, SIGNAL(released ()),
this, SLOT (slotYRadiusLog ()));
326 layoutYRadius->addWidget (m_yRadiusLog, rowGroup, COLUMN_0);
328 m_editOriginRadius =
new QLineEdit (m_boxYRadius);
329 m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
330 m_editOriginRadius->setWhatsThis (QString(tr(
"Specify radius value at origin.\n\n" 331 "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases " 332 "(like when the radial units are decibels).")));
333 connect (m_editOriginRadius, SIGNAL (textChanged (
const QString &)),
this, SLOT (slotPolarOriginRadius(
const QString &)));
334 layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
336 QLabel *labelUnits =
new QLabel(tr (
"Units:"));
337 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
339 m_cmbYRadiusUnits =
new QComboBox;
340 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
341 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
348 void DlgSettingsCoords::createPreview (QGridLayout *layout,
351 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
353 QLabel *labelPreview =
new QLabel (tr (
"Preview"));
354 layout->addWidget (labelPreview, row++, 0, 1, 4);
356 m_scenePreview =
new QGraphicsScene (
this);
358 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
360 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
361 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
362 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
365 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
370 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
372 QWidget *subPanel =
new QWidget ();
374 QGridLayout *layout =
new QGridLayout (subPanel);
375 subPanel->setLayout (layout);
377 layout->setColumnStretch(0, 1);
378 layout->setColumnStretch(1, 0);
379 layout->setColumnStretch(2, 0);
380 layout->setColumnStretch(3, 1);
383 createGroupCoordsType(layout, row);
384 createGroupXTheta (layout, row);
385 createGroupYRadius (layout, row);
386 createDateTime (layout, row);
387 createPreview (layout, row);
392 void DlgSettingsCoords::drawCartesianLinearX ()
394 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
397 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
398 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
399 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
400 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
401 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
403 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
405 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
406 line->setPen(QPen (QBrush (Qt::black),
413 void DlgSettingsCoords::drawCartesianLinearY ()
415 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
418 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
419 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
420 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
421 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
422 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
424 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
426 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
427 line->setPen(QPen (QBrush (Qt::black),
434 void DlgSettingsCoords::drawCartesianLogX ()
436 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
439 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
440 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
442 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
443 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
444 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
445 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
447 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
449 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
450 line->setPen(QPen (QBrush (Qt::black),
457 void DlgSettingsCoords::drawCartesianLogY ()
459 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
462 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
463 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
464 (pow (POWER_FOR_LOG, 1.0) - 1.0);
465 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
466 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
467 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
468 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
470 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
472 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
473 line->setPen(QPen (QBrush (Qt::black),
480 void DlgSettingsCoords::drawPolarLinearRadius ()
482 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
484 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
485 double radius = step * POLAR_STEP;
486 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
490 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
491 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
493 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
497 void DlgSettingsCoords::drawPolarLogRadius ()
499 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
501 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
502 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
503 (pow (POWER_FOR_LOG, 1.0) - 1.0);
504 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
505 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
509 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
510 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
512 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
516 void DlgSettingsCoords::drawPolarTheta ()
518 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
521 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
522 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
523 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
524 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
525 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
526 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
527 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
529 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
531 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
532 line->setPen(QPen (QBrush (Qt::black),
541 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
544 cmdMediator ().document(),
545 *m_modelCoordsBefore,
546 *m_modelCoordsAfter);
554 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
560 QRectF rectGraph = boundingRectGraph (cmdMediator,
562 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
563 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
564 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
565 m_xThetaLog->setEnabled (!xThetaGoesNegative);
566 m_yRadiusLinear->setEnabled (!yRGoesNegative);
567 m_yRadiusLog->setEnabled (!yRGoesNegative);
570 if (m_modelCoordsBefore != 0) {
571 delete m_modelCoordsBefore;
573 if (m_modelCoordsAfter != 0) {
574 delete m_modelCoordsAfter;
583 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
588 m_editOriginRadius->setValidator (m_validatorOriginRadius);
589 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
591 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
592 m_btnCartesian->setChecked (
true);
594 m_btnPolar->setChecked (
true);
601 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
602 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
603 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
604 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
611 void DlgSettingsCoords::loadComboBoxDate()
613 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
617 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
618 QVariant (COORD_UNITS_DATE_SKIP));
619 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
620 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
621 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
622 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
623 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
624 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
626 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
628 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
629 m_cmbDate->setCurrentIndex (index);
632 void DlgSettingsCoords::loadComboBoxTime()
634 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
638 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
639 QVariant (COORD_UNITS_TIME_SKIP));
640 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
641 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
642 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
643 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
645 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
647 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
648 m_cmbTime->setCurrentIndex (index);
651 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
652 CoordUnitsNonPolarTheta coordUnits)
654 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
658 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
659 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
660 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
661 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
662 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
663 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
664 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
665 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
667 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
669 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n" 670 "Date and time values have date and/or time components.\n\n" 671 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for " 672 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
674 int index = cmb.findData (coordUnits);
675 cmb.setCurrentIndex (index);
678 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
679 CoordUnitsPolarTheta coordUnits)
681 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
685 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
686 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
687 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
688 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
689 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
690 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
691 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
692 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
693 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
694 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
695 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
696 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
697 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
698 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
700 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
702 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n" 703 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are " 704 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n" 705 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for " 706 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n" 707 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n" 708 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n" 709 "Turns format uses a single real number. One complete revolution is one turn.")));
711 int index = cmb.findData (coordUnits);
712 cmb.setCurrentIndex (index);
715 void DlgSettingsCoords::resetSceneRectangle ()
717 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
718 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
719 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
720 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
722 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
723 itemPerimeter->setVisible(
false);
724 m_scenePreview->addItem (itemPerimeter);
725 m_viewPreview->centerOn (QPointF (0.0, 0.0));
731 setMinimumHeight (MINIMUM_HEIGHT);
735 void DlgSettingsCoords::slotCartesianPolar (
bool)
737 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
739 if (m_btnCartesian->isChecked ()) {
749 void DlgSettingsCoords::slotDate(
const QString &)
751 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
753 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
759 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
761 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
763 QString numberText = m_editOriginRadius->text();
770 void DlgSettingsCoords::slotTime(
const QString &)
772 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
774 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
780 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
782 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
784 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
785 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
788 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
795 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
797 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
799 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
800 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
809 void DlgSettingsCoords::slotXThetaLinear()
811 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
818 void DlgSettingsCoords::slotXThetaLog()
820 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
827 void DlgSettingsCoords::slotYRadiusLinear()
829 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
831 delete m_validatorOriginRadius;
839 m_editOriginRadius->setValidator (m_validatorOriginRadius);
846 void DlgSettingsCoords::slotYRadiusLog()
848 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
850 delete m_validatorOriginRadius;
858 m_editOriginRadius->setValidator (m_validatorOriginRadius);
865 void DlgSettingsCoords::updateControls ()
869 QString textOriginRadius = m_editOriginRadius->text();
870 int posOriginRadius = 0;
872 bool goodOriginRadius =
true;
873 if (m_editOriginRadius->isEnabled ()) {
876 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
877 posOriginRadius) == QValidator::Acceptable);
882 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
884 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
885 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
886 if (m_btnCartesian->isChecked()) {
887 m_yRadiusLinear->setEnabled (
true);
888 m_yRadiusLog->setEnabled (
true);
898 int posOriginRadiusOther;
899 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
903 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
904 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
906 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
908 QString captionXTheta = (m_btnCartesian->isChecked () ?
910 THETA) + QString (
" %1")
911 .arg (tr (
"Coordinates"));
912 QString captionYRadius = (m_btnCartesian->isChecked () ?
914 QString (tr (
"R"))) + QString (
" %1")
915 .arg (tr (
"Coordinates"));
917 if (m_boxXTheta->title() != captionXTheta) {
918 m_boxXTheta->setTitle (captionXTheta);
921 if (m_boxYRadius->title () != captionYRadius) {
922 m_boxYRadius->setTitle (captionYRadius);
926 if (m_btnCartesian->isChecked()) {
927 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
928 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
930 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
932 m_cmbDate->setEnabled (enableDateTime);
933 m_cmbTime->setEnabled (enableDateTime);
935 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls" 936 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
937 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
938 <<
" originRadius=" << posOriginRadius
939 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
940 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
943 void DlgSettingsCoords::updateCoordUnits()
946 if (m_btnCartesian->isChecked()) {
947 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
949 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
952 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
954 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
959 void DlgSettingsCoords::updatePreview()
961 m_scenePreview->clear();
969 if (m_btnCartesian->isChecked()) {
972 if (m_xThetaLinear->isChecked()) {
973 drawCartesianLinearX ();
975 drawCartesianLogX ();
978 if (m_yRadiusLinear->isChecked()) {
979 drawCartesianLinearY ();
981 drawCartesianLogY ();
988 if (m_yRadiusLinear->isChecked()) {
989 drawPolarLinearRadius ();
991 drawPolarLogRadius ();
995 annotateRadiusAtOrigin (defaultFont);
996 annotateAngles (defaultFont);
999 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.
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
void setCoordUnitsY(CoordUnitsNonPolarTheta coordUnits)
Set method for y units.
void setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)
Set method for x units.
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...
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
void setCoordScaleYRadius(CoordScale coordScale)
Set method for linear/log scale on y/radius.
CoordUnitsNonPolarTheta coordUnitsY() const
Get method for x units.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
CoordUnitsPolarTheta coordUnitsTheta() const
Get method for theta unit.
Abstract validator for all numeric formats.
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...
CoordUnitsTime coordUnitsTime() const
Get method for time format when used.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
void setCoordUnitsTheta(CoordUnitsPolarTheta coordUnits)
Set method for theta units.
CoordUnitsDate coordUnitsDate() const
Get method for date format when used.
Model for DlgSettingsCoords and CmdSettingsCoords.
void setOriginRadius(double originRadius)
Set method for origin radius in polar mode.
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.
MainWindowModel modelMainWindow() const
Get method for main window model.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
QLocale locale() const
Get method for locale.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
CoordsType coordsType() const
Get method for coordinates type.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
QRectF boundingRectGraph(bool &isEmpty) const
Graph coordinate bounding rectangle.
Abstract base class for all Settings dialogs.
CoordUnitsNonPolarTheta coordUnitsX() const
Get method for x units.
double originRadius() const
Get method for origin radius in polar mode.
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
MainWindow & mainWindow()
Get method for MainWindow.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
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.
void setCoordsType(CoordsType coordsType)
Set method for coordinates type.