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" 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;
81 m_validatorOriginRadius (0),
86 m_modelCoordsBefore (0),
87 m_modelCoordsAfter (0)
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 = (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,
194 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
210 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
213 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
215 QLabel *label =
new QLabel(tr (
"Date/Time:"));
216 layout->addWidget (label, row, 1);
218 QWidget *widgetCombos =
new QWidget;
219 layout->addWidget (widgetCombos, row++, 2);
220 QHBoxLayout *layoutCombos =
new QHBoxLayout;
221 widgetCombos->setLayout (layoutCombos);
224 m_cmbDate =
new QComboBox;
225 m_cmbDate->setWhatsThis (tr (
"Date format to be used for date values, and date portion of mixed date/time values, " 226 "during input and output.\n\n" 227 "Setting the format to an empty value results in just the time portion appearing in output."));
228 connect (m_cmbDate, SIGNAL (activated (
const QString &)),
this, SLOT (slotDate (
const QString &)));
229 layoutCombos->addWidget (m_cmbDate);
231 m_cmbTime =
new QComboBox;
232 m_cmbTime->setWhatsThis (tr (
"Time format to be used for time values, and time portion of mixed date/time values, " 233 "during input and output.\n\n" 234 "Setting the format to an empty value results in just the date portion appearing in output."));
235 connect (m_cmbTime, SIGNAL (activated (
const QString &)),
this, SLOT (slotTime (
const QString &)));
236 layoutCombos->addWidget (m_cmbTime);
239 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
242 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
244 m_boxCoordsType =
new QGroupBox(tr (
"Coordinates Types"));
245 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
247 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
249 QString polarButtonText = QString(tr (
"Polar") +
" (") + THETA + QString(
", " + tr (
"R") +
")");
251 m_btnCartesian =
new QRadioButton (tr (
"Cartesian (X, Y)"), m_boxCoordsType);
252 m_btnCartesian->setWhatsThis (QString(tr(
"Select cartesian coordinates.\n\n" 253 "The X and Y coordinates will be used")));
254 connect (m_btnCartesian, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
255 layoutGroup->addWidget (m_btnCartesian);
257 m_btnPolar =
new QRadioButton (polarButtonText, m_boxCoordsType);
258 m_btnPolar->setWhatsThis (QString(tr(
"Select polar coordinates.\n\n" 259 "The Theta and R coordinates will be used.\n\n" 260 "Polar coordinates are not allowed with log scale for Theta")));
261 connect (m_btnPolar, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
262 layoutGroup->addWidget (m_btnPolar);
265 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
268 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
270 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
271 layout->addWidget (m_boxXTheta, row, 1, 1, 1);
273 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
274 m_boxXTheta->setLayout (layoutXTheta);
277 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
278 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
280 m_xThetaLinear =
new QRadioButton (tr (
"Linear"), m_boxXTheta);
281 m_xThetaLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the X or Theta coordinate")));
282 connect (m_xThetaLinear, SIGNAL (released ()),
this, SLOT (slotXThetaLinear()));
283 layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
285 m_xThetaLog =
new QRadioButton (tr (
"Log"), m_boxXTheta);
286 m_xThetaLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the X or Theta coordinate.\n\n" 287 "Log scale is not allowed if there are negative coordinates.\n\n" 288 "Log scale is not allowed for the Theta coordinate.")));
289 connect (m_xThetaLog, SIGNAL (released ()),
this, SLOT (slotXThetaLog()));
290 layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
292 QLabel *labelThetaUnits =
new QLabel(tr (
"Units:"));
293 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
295 m_cmbXThetaUnits =
new QComboBox;
296 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
297 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
300 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
303 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
305 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
306 layout->addWidget (m_boxYRadius, row++, 2, 1, 1);
308 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
309 m_boxYRadius->setLayout (layoutYRadius);
312 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
313 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
315 m_yRadiusLinear =
new QRadioButton (tr (
"Linear"), m_boxYRadius);
316 m_yRadiusLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the Y or R coordinate")));
317 connect (m_yRadiusLinear, SIGNAL(released()),
this, SLOT (slotYRadiusLinear()));
318 layoutYRadius->addWidget (m_yRadiusLinear, rowGroup, COLUMN_0);
320 QLabel *labelOriginRadius =
new QLabel(tr (
"Origin radius value:"));
321 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
323 m_yRadiusLog =
new QRadioButton (tr (
"Log"), m_boxYRadius);
324 m_yRadiusLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the Y or R coordinate\n\n" 325 "Log scale is not allowed if there are negative coordinates.")));
326 connect (m_yRadiusLog, SIGNAL(released ()),
this, SLOT (slotYRadiusLog ()));
327 layoutYRadius->addWidget (m_yRadiusLog, rowGroup, COLUMN_0);
329 m_editOriginRadius =
new QLineEdit (m_boxYRadius);
330 m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
331 m_editOriginRadius->setWhatsThis (QString(tr(
"Specify radius value at origin.\n\n" 332 "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases " 333 "(like when the radial units are decibels).")));
334 connect (m_editOriginRadius, SIGNAL (textChanged (
const QString &)),
this, SLOT (slotPolarOriginRadius(
const QString &)));
335 layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
337 QLabel *labelUnits =
new QLabel(tr (
"Units:"));
338 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
340 m_cmbYRadiusUnits =
new QComboBox;
341 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
342 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
349 void DlgSettingsCoords::createPreview (QGridLayout *layout,
352 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
354 QLabel *labelPreview =
new QLabel (tr (
"Preview"));
355 layout->addWidget (labelPreview, row++, 0, 1, 4);
357 m_scenePreview =
new QGraphicsScene (
this);
359 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
361 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
362 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
363 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
366 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
371 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
373 QWidget *subPanel =
new QWidget ();
375 QGridLayout *layout =
new QGridLayout (subPanel);
376 subPanel->setLayout (layout);
378 layout->setColumnStretch(0, 1);
379 layout->setColumnStretch(1, 0);
380 layout->setColumnStretch(2, 0);
381 layout->setColumnStretch(3, 1);
384 createGroupCoordsType(layout, row);
385 createGroupXTheta (layout, row);
386 createGroupYRadius (layout, row);
387 createDateTime (layout, row);
388 createPreview (layout, row);
393 void DlgSettingsCoords::drawCartesianLinearX ()
395 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
398 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
399 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
400 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
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 (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
407 line->setPen(QPen (QBrush (Qt::black),
414 void DlgSettingsCoords::drawCartesianLinearY ()
416 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
419 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
420 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
421 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
422 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
423 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
425 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
427 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
428 line->setPen(QPen (QBrush (Qt::black),
435 void DlgSettingsCoords::drawCartesianLogX ()
437 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
440 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
441 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
443 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
444 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
445 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
446 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
448 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
450 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
451 line->setPen(QPen (QBrush (Qt::black),
458 void DlgSettingsCoords::drawCartesianLogY ()
460 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
463 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
464 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
465 (pow (POWER_FOR_LOG, 1.0) - 1.0);
466 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
467 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
468 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
469 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
471 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
473 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
474 line->setPen(QPen (QBrush (Qt::black),
481 void DlgSettingsCoords::drawPolarLinearRadius ()
483 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
485 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
486 double radius = step * POLAR_STEP;
487 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
491 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
492 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
494 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
498 void DlgSettingsCoords::drawPolarLogRadius ()
500 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
502 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
503 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
504 (pow (POWER_FOR_LOG, 1.0) - 1.0);
505 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
506 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
510 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
511 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
513 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
517 void DlgSettingsCoords::drawPolarTheta ()
519 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
522 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
523 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
524 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
525 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
526 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
527 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
528 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
530 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
532 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
533 line->setPen(QPen (QBrush (Qt::black),
542 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
545 cmdMediator ().document(),
546 *m_modelCoordsBefore,
547 *m_modelCoordsAfter);
555 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
561 QRectF rectGraph = boundingRectGraph (cmdMediator,
563 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
564 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
565 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
566 m_xThetaLog->setEnabled (!xThetaGoesNegative);
567 m_yRadiusLinear->setEnabled (!yRGoesNegative);
568 m_yRadiusLog->setEnabled (!yRGoesNegative);
571 if (m_modelCoordsBefore != 0) {
572 delete m_modelCoordsBefore;
574 if (m_modelCoordsAfter != 0) {
575 delete m_modelCoordsAfter;
584 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
589 m_editOriginRadius->setValidator (m_validatorOriginRadius);
590 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
592 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
593 m_btnCartesian->setChecked (
true);
595 m_btnPolar->setChecked (
true);
602 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
603 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
604 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
605 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
612 void DlgSettingsCoords::loadComboBoxDate()
614 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
618 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
619 QVariant (COORD_UNITS_DATE_SKIP));
620 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
621 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
622 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
623 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
624 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
625 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
627 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
629 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
630 m_cmbDate->setCurrentIndex (index);
633 void DlgSettingsCoords::loadComboBoxTime()
635 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
639 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
640 QVariant (COORD_UNITS_TIME_SKIP));
641 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
642 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
643 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
644 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
646 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
648 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
649 m_cmbTime->setCurrentIndex (index);
652 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
653 CoordUnitsNonPolarTheta coordUnits)
655 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
659 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
660 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
661 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
662 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
663 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
664 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
665 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
666 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
668 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
670 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n" 671 "Date and time values have date and/or time components.\n\n" 672 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for " 673 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
675 int index = cmb.findData (coordUnits);
676 cmb.setCurrentIndex (index);
679 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
680 CoordUnitsPolarTheta coordUnits)
682 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
686 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
687 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
688 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
689 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
690 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
691 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
692 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
693 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
694 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
695 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
696 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
697 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
698 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
699 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
701 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
703 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n" 704 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are " 705 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n" 706 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for " 707 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n" 708 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n" 709 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n" 710 "Turns format uses a single real number. One complete revolution is one turn.")));
712 int index = cmb.findData (coordUnits);
713 cmb.setCurrentIndex (index);
716 void DlgSettingsCoords::resetSceneRectangle ()
718 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
719 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
720 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
721 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
723 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
724 itemPerimeter->setVisible(
false);
725 m_scenePreview->addItem (itemPerimeter);
726 m_viewPreview->centerOn (QPointF (0.0, 0.0));
732 setMinimumHeight (MINIMUM_HEIGHT);
736 void DlgSettingsCoords::slotCartesianPolar (
bool)
738 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
740 if (m_btnCartesian->isChecked ()) {
750 void DlgSettingsCoords::slotDate(
const QString &)
752 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
754 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
760 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
762 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
764 QString numberText = m_editOriginRadius->text();
771 void DlgSettingsCoords::slotTime(
const QString &)
773 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
775 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
781 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
783 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
785 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
786 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
789 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
796 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
798 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
800 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
801 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
810 void DlgSettingsCoords::slotXThetaLinear()
812 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
819 void DlgSettingsCoords::slotXThetaLog()
821 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
828 void DlgSettingsCoords::slotYRadiusLinear()
830 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
832 delete m_validatorOriginRadius;
840 m_editOriginRadius->setValidator (m_validatorOriginRadius);
847 void DlgSettingsCoords::slotYRadiusLog()
849 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
851 delete m_validatorOriginRadius;
859 m_editOriginRadius->setValidator (m_validatorOriginRadius);
866 void DlgSettingsCoords::updateControls ()
870 QString textOriginRadius = m_editOriginRadius->text();
871 int posOriginRadius = 0;
873 bool goodOriginRadius =
true;
874 if (m_editOriginRadius->isEnabled ()) {
877 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
878 posOriginRadius) == QValidator::Acceptable);
883 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
885 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
886 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
887 if (m_btnCartesian->isChecked()) {
888 m_yRadiusLinear->setEnabled (
true);
889 m_yRadiusLog->setEnabled (
true);
899 int posOriginRadiusOther;
900 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
904 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
905 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
907 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
909 QString captionXTheta = (m_btnCartesian->isChecked () ?
911 THETA) + QString (
" %1")
912 .arg (tr (
"Coordinates"));
913 QString captionYRadius = (m_btnCartesian->isChecked () ?
915 QString (tr (
"R"))) + QString (
" %1")
916 .arg (tr (
"Coordinates"));
918 if (m_boxXTheta->title() != captionXTheta) {
919 m_boxXTheta->setTitle (captionXTheta);
922 if (m_boxYRadius->title () != captionYRadius) {
923 m_boxYRadius->setTitle (captionYRadius);
927 if (m_btnCartesian->isChecked()) {
928 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
929 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
931 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
933 m_cmbDate->setEnabled (enableDateTime);
934 m_cmbTime->setEnabled (enableDateTime);
936 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls" 937 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
938 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
939 <<
" originRadius=" << posOriginRadius
940 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
941 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
944 void DlgSettingsCoords::updateCoordUnits()
947 if (m_btnCartesian->isChecked()) {
948 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
950 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
953 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
955 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
960 void DlgSettingsCoords::updatePreview()
962 m_scenePreview->clear();
970 if (m_btnCartesian->isChecked()) {
973 if (m_xThetaLinear->isChecked()) {
974 drawCartesianLinearX ();
976 drawCartesianLogX ();
979 if (m_yRadiusLinear->isChecked()) {
980 drawCartesianLinearY ();
982 drawCartesianLogY ();
989 if (m_yRadiusLinear->isChecked()) {
990 drawPolarLinearRadius ();
992 drawPolarLogRadius ();
996 annotateRadiusAtOrigin (defaultFont);
997 annotateAngles (defaultFont);
1000 resetSceneRectangle();
void setCoordUnitsTime(CoordUnitsTime coordUnits)
Set method for time units.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
void setCoordUnitsDate(CoordUnitsDate coordUnits)
Set method for date units.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
void setCoordUnitsY(CoordUnitsNonPolarTheta coordUnits)
Set method for y units.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
void setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)
Set method for x units.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
void setCoordScaleYRadius(CoordScale coordScale)
Set method for linear/log scale on y/radius.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
Abstract validator for all numeric formats.
CoordUnitsTime coordUnitsTime() const
Get method for time format when used.
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.
QRectF boundingRectGraph(bool &isEmpty) const
Graph coordinate bounding rectangle.
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.