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;
77 m_validatorOriginRadius (0),
82 m_modelCoordsBefore (0),
83 m_modelCoordsAfter (0)
85 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::DlgSettingsCoords";
91 DlgSettingsCoords::~DlgSettingsCoords()
93 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::~DlgSettingsCoords";
96 void DlgSettingsCoords::annotateAngles (
const QFont &defaultFont) {
99 for (
int direction = 0; direction < 4; direction++) {
102 CoordUnitsPolarTheta thetaUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData().toInt();
104 switch (thetaUnits) {
105 case COORD_UNITS_POLAR_THETA_DEGREES:
106 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
107 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
108 angle = QString::number (90.0 * direction);
111 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
112 angle = QString::number (90.0 * direction);
113 if (direction == 1) {
115 }
else if (direction == 3) {
120 case COORD_UNITS_POLAR_THETA_GRADIANS:
121 angle = QString::number (100.0 * direction);
124 case COORD_UNITS_POLAR_THETA_RADIANS:
126 static QString radiansUnits [] = {
"0",
"PI / 2",
"PI",
"3 * PI / 2"};
127 ENGAUGE_ASSERT (direction < 4);
128 angle = radiansUnits [direction];
132 case COORD_UNITS_POLAR_THETA_TURNS:
134 static QString turnsUnits [] = {
"0",
"1 / 4",
"1 / 2",
"3 / 4"};
135 ENGAUGE_ASSERT (direction < 4);
136 angle = turnsUnits [direction];
144 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
145 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
149 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
153 x = XCENTER - textAngle->boundingRect().width () / 2.0;
156 x = CARTESIAN_COORD_MIN;
165 y = CARTESIAN_COORD_MIN;
168 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
172 textAngle->setPos (x, y);
176 void DlgSettingsCoords::annotateRadiusAtOrigin(
const QFont &defaultFont) {
178 QGraphicsTextItem *textRadius = m_scenePreview->addText (m_editOriginRadius->text());
179 textRadius->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
180 textRadius->setPos (XCENTER - textRadius->boundingRect().width () / 2.0,
189 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
205 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
208 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
210 QLabel *label =
new QLabel(tr (
"Date/Time:"));
211 layout->addWidget (label, row, 1);
213 QWidget *widgetCombos =
new QWidget;
214 layout->addWidget (widgetCombos, row++, 2);
215 QHBoxLayout *layoutCombos =
new QHBoxLayout;
216 widgetCombos->setLayout (layoutCombos);
219 m_cmbDate =
new QComboBox;
220 m_cmbDate->setWhatsThis (tr (
"Date format to be used for date values, and date portion of mixed date/time values, " 221 "during input and output.\n\n" 222 "Setting the format to an empty value results in just the time portion appearing in output."));
223 connect (m_cmbDate, SIGNAL (activated (
const QString &)),
this, SLOT (slotDate (
const QString &)));
224 layoutCombos->addWidget (m_cmbDate);
226 m_cmbTime =
new QComboBox;
227 m_cmbTime->setWhatsThis (tr (
"Time format to be used for time values, and time portion of mixed date/time values, " 228 "during input and output.\n\n" 229 "Setting the format to an empty value results in just the date portion appearing in output."));
230 connect (m_cmbTime, SIGNAL (activated (
const QString &)),
this, SLOT (slotTime (
const QString &)));
231 layoutCombos->addWidget (m_cmbTime);
234 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
237 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
239 m_boxCoordsType =
new QGroupBox(tr (
"Coordinates Types"));
240 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
242 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
244 QString polarButtonText = QString(tr (
"Polar") +
" (") + THETA + QString(
", " + tr (
"R") +
")");
246 m_btnCartesian =
new QRadioButton (tr (
"Cartesian (X, Y)"), m_boxCoordsType);
247 m_btnCartesian->setWhatsThis (QString(tr(
"Select cartesian coordinates.\n\n" 248 "The X and Y coordinates will be used")));
249 connect (m_btnCartesian, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
250 layoutGroup->addWidget (m_btnCartesian);
252 m_btnPolar =
new QRadioButton (polarButtonText, m_boxCoordsType);
253 m_btnPolar->setWhatsThis (QString(tr(
"Select polar coordinates.\n\n" 254 "The Theta and R coordinates will be used.\n\n" 255 "Polar coordinates are not allowed with log scale for Theta")));
256 connect (m_btnPolar, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
257 layoutGroup->addWidget (m_btnPolar);
260 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
263 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
265 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
266 layout->addWidget (m_boxXTheta, row++, 1, 1, 2);
268 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
269 m_boxXTheta->setLayout (layoutXTheta);
272 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
273 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
275 m_xThetaLinear =
new QRadioButton (tr (
"Linear"), m_boxXTheta);
276 m_xThetaLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the X or Theta coordinate")));
277 connect (m_xThetaLinear, SIGNAL (released ()),
this, SLOT (slotXThetaLinear()));
278 layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
280 m_xThetaLog =
new QRadioButton (tr (
"Log"), m_boxXTheta);
281 m_xThetaLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the X or Theta coordinate.\n\n" 282 "Log scale is not allowed if there are negative coordinates.\n\n" 283 "Log scale is not allowed for the Theta coordinate.")));
284 connect (m_xThetaLog, SIGNAL (released ()),
this, SLOT (slotXThetaLog()));
285 layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
287 QLabel *labelThetaUnits =
new QLabel(tr (
"Units:"));
288 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
290 m_cmbXThetaUnits =
new QComboBox;
291 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
292 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
295 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
298 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
300 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
301 layout->addWidget (m_boxYRadius, row++, 1, 1, 2);
303 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
304 m_boxYRadius->setLayout (layoutYRadius);
307 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
308 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
310 m_yRadiusLinear =
new QRadioButton (tr (
"Linear"), m_boxYRadius);
311 m_yRadiusLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the Y or R coordinate")));
312 connect (m_yRadiusLinear, SIGNAL(released()),
this, SLOT (slotYRadiusLinear()));
313 layoutYRadius->addWidget (m_yRadiusLinear, rowGroup++, COLUMN_0);
315 m_yRadiusLog =
new QRadioButton (tr (
"Log"), m_boxYRadius);
316 m_yRadiusLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the Y or R coordinate\n\n" 317 "Log scale is not allowed if there are negative coordinates.")));
318 connect (m_yRadiusLog, SIGNAL(released ()),
this, SLOT (slotYRadiusLog ()));
319 layoutYRadius->addWidget (m_yRadiusLog, rowGroup++, COLUMN_0);
321 QLabel *labelUnits =
new QLabel(tr (
"Units:"));
322 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
324 m_cmbYRadiusUnits =
new QComboBox;
325 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
326 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
329 QLabel *labelOriginRadius =
new QLabel(tr (
"Origin radius value:"));
330 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
332 m_editOriginRadius =
new QLineEdit (m_boxYRadius);
333 m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
334 m_editOriginRadius->setWhatsThis (QString(tr(
"Specify radius value at origin.\n\n" 335 "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases " 336 "(like when the radial units are decibels).")));
337 connect (m_editOriginRadius, SIGNAL (textChanged (
const QString &)),
this, SLOT (slotPolarOriginRadius(
const QString &)));
338 layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
345 void DlgSettingsCoords::createPreview (QGridLayout *layout,
348 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
350 QLabel *labelPreview =
new QLabel (tr (
"Preview"));
351 layout->addWidget (labelPreview, row++, 0, 1, 4);
353 m_scenePreview =
new QGraphicsScene (
this);
355 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
357 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
358 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
359 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
362 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
367 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
369 QWidget *subPanel =
new QWidget ();
370 QGridLayout *layout =
new QGridLayout (subPanel);
371 subPanel->setLayout (layout);
373 layout->setColumnStretch(0, 1);
374 layout->setColumnStretch(1, 0);
375 layout->setColumnStretch(2, 0);
376 layout->setColumnStretch(3, 1);
379 createGroupCoordsType(layout, row);
380 createGroupXTheta (layout, row);
381 createGroupYRadius (layout, row);
382 createDateTime (layout, row);
383 createPreview (layout, row);
388 void DlgSettingsCoords::drawCartesianLinearX ()
390 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
393 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
394 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
395 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
396 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
397 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
399 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
401 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
402 line->setPen(QPen (QBrush (Qt::black),
409 void DlgSettingsCoords::drawCartesianLinearY ()
411 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
414 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
415 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
416 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
417 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
418 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
420 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
422 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
423 line->setPen(QPen (QBrush (Qt::black),
430 void DlgSettingsCoords::drawCartesianLogX ()
432 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
435 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
436 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
438 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
439 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
440 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
441 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
443 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
445 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
446 line->setPen(QPen (QBrush (Qt::black),
453 void DlgSettingsCoords::drawCartesianLogY ()
455 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
458 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
459 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
460 (pow (POWER_FOR_LOG, 1.0) - 1.0);
461 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
462 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
463 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
464 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
466 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
468 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
469 line->setPen(QPen (QBrush (Qt::black),
476 void DlgSettingsCoords::drawPolarLinearRadius ()
478 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
480 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
481 double radius = step * POLAR_STEP;
482 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
486 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
487 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
489 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
493 void DlgSettingsCoords::drawPolarLogRadius ()
495 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
497 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
498 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
499 (pow (POWER_FOR_LOG, 1.0) - 1.0);
500 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
501 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
505 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
506 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
508 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
512 void DlgSettingsCoords::drawPolarTheta ()
514 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
517 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
518 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
519 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
520 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
521 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
522 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
523 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
525 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
527 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
528 line->setPen(QPen (QBrush (Qt::black),
537 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
540 cmdMediator ().document(),
541 *m_modelCoordsBefore,
542 *m_modelCoordsAfter);
550 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
556 QRectF rectGraph = boundingRectGraph (cmdMediator,
558 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
559 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
560 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
561 m_xThetaLog->setEnabled (!xThetaGoesNegative);
562 m_yRadiusLinear->setEnabled (!yRGoesNegative);
563 m_yRadiusLog->setEnabled (!yRGoesNegative);
566 if (m_modelCoordsBefore != 0) {
567 delete m_modelCoordsBefore;
569 if (m_modelCoordsAfter != 0) {
570 delete m_modelCoordsAfter;
579 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
584 m_editOriginRadius->setValidator (m_validatorOriginRadius);
585 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
587 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
588 m_btnCartesian->setChecked (
true);
590 m_btnPolar->setChecked (
true);
597 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
598 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
599 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
600 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
607 void DlgSettingsCoords::loadComboBoxDate()
609 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
613 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
614 QVariant (COORD_UNITS_DATE_SKIP));
615 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
616 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
617 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
618 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
619 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
620 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
622 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
624 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
625 m_cmbDate->setCurrentIndex (index);
628 void DlgSettingsCoords::loadComboBoxTime()
630 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
634 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
635 QVariant (COORD_UNITS_TIME_SKIP));
636 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
637 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
638 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
639 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
641 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
643 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
644 m_cmbTime->setCurrentIndex (index);
647 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
648 CoordUnitsNonPolarTheta coordUnits)
650 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
654 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
655 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
656 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
657 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
658 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
659 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
660 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
661 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
663 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
665 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n" 666 "Date and time values have date and/or time components.\n\n" 667 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for " 668 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
670 int index = cmb.findData (coordUnits);
671 cmb.setCurrentIndex (index);
674 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
675 CoordUnitsPolarTheta coordUnits)
677 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
681 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
682 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
683 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
684 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
685 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
686 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
687 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
688 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
689 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
690 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
691 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
692 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
693 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
694 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
696 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
698 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n" 699 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are " 700 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n" 701 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for " 702 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n" 703 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n" 704 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n" 705 "Turns format uses a single real number. One complete revolution is one turn.")));
707 int index = cmb.findData (coordUnits);
708 cmb.setCurrentIndex (index);
711 void DlgSettingsCoords::resetSceneRectangle ()
713 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
714 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
715 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
716 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
718 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
719 itemPerimeter->setVisible(
false);
720 m_scenePreview->addItem (itemPerimeter);
721 m_viewPreview->centerOn (QPointF (0.0, 0.0));
724 void DlgSettingsCoords::slotCartesianPolar (
bool)
726 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
728 if (m_btnCartesian->isChecked ()) {
738 void DlgSettingsCoords::slotDate(
const QString &)
740 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
742 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
748 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
750 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
752 QString numberText = m_editOriginRadius->text();
759 void DlgSettingsCoords::slotTime(
const QString &)
761 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
763 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
769 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
771 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
773 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
774 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
777 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
784 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
786 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
788 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
789 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
798 void DlgSettingsCoords::slotXThetaLinear()
800 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
807 void DlgSettingsCoords::slotXThetaLog()
809 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
816 void DlgSettingsCoords::slotYRadiusLinear()
818 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
820 delete m_validatorOriginRadius;
828 m_editOriginRadius->setValidator (m_validatorOriginRadius);
835 void DlgSettingsCoords::slotYRadiusLog()
837 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
839 delete m_validatorOriginRadius;
847 m_editOriginRadius->setValidator (m_validatorOriginRadius);
854 void DlgSettingsCoords::updateControls ()
858 QString textOriginRadius = m_editOriginRadius->text();
859 int posOriginRadius = 0;
861 bool goodOriginRadius =
true;
862 if (m_editOriginRadius->isEnabled ()) {
865 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
866 posOriginRadius) == QValidator::Acceptable);
871 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
873 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
874 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
875 if (m_btnCartesian->isChecked()) {
876 m_yRadiusLinear->setEnabled (
true);
877 m_yRadiusLog->setEnabled (
true);
887 int posOriginRadiusOther;
888 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
892 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
893 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
895 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
897 QString captionXTheta = (m_btnCartesian->isChecked () ?
899 THETA) + QString (
" %1")
900 .arg (tr (
"Coordinates"));
901 QString captionYRadius = (m_btnCartesian->isChecked () ?
903 QString (tr (
"R"))) + QString (
" %1")
904 .arg (tr (
"Coordinates"));
906 if (m_boxXTheta->title() != captionXTheta) {
907 m_boxXTheta->setTitle (captionXTheta);
910 if (m_boxYRadius->title () != captionYRadius) {
911 m_boxYRadius->setTitle (captionYRadius);
915 if (m_btnCartesian->isChecked()) {
916 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
917 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
919 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
921 m_cmbDate->setEnabled (enableDateTime);
922 m_cmbTime->setEnabled (enableDateTime);
924 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls" 925 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
926 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
927 <<
" originRadius=" << posOriginRadius
928 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
929 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
932 void DlgSettingsCoords::updateCoordUnits()
935 if (m_btnCartesian->isChecked()) {
936 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
938 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
941 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
943 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
948 void DlgSettingsCoords::updatePreview()
950 m_scenePreview->clear();
958 if (m_btnCartesian->isChecked()) {
961 if (m_xThetaLinear->isChecked()) {
962 drawCartesianLinearX ();
964 drawCartesianLogX ();
967 if (m_yRadiusLinear->isChecked()) {
968 drawCartesianLinearY ();
970 drawCartesianLogY ();
977 if (m_yRadiusLinear->isChecked()) {
978 drawPolarLinearRadius ();
980 drawPolarLogRadius ();
984 annotateRadiusAtOrigin (defaultFont);
985 annotateAngles (defaultFont);
988 resetSceneRectangle();
void setCoordUnitsTime(CoordUnitsTime coordUnits)
Set method for time units.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
void setCoordUnitsDate(CoordUnitsDate coordUnits)
Set method for date units.
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
void setCoordUnitsY(CoordUnitsNonPolarTheta coordUnits)
Set method for y units.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
void setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)
Set method for x units.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
void setCoordScaleYRadius(CoordScale coordScale)
Set method for linear/log scale on y/radius.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
Abstract validator for all numeric formats.
CoordUnitsTime coordUnitsTime() const
Get method for time format when used.
Command for DlgSettingsCoords.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window...
CoordUnitsNonPolarTheta coordUnitsY() const
Get method for x units.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
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.
void setCoordUnitsRadius(CoordUnitsNonPolarTheta coordUnits)
Set method for radius units.
void finishPanel(QWidget *subPanel)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
DlgValidatorAbstract * createWithNonPolar(CoordScale coordScale, CoordUnitsNonPolarTheta coordUnits, CoordUnitsDate coordUnitsDate, CoordUnitsTime coordUnitsTime, const QLocale &locale) const
Factory method for generating validators when cartesian/polar case handling is handled externally...
Abstract base class for all Settings dialogs.
QLocale locale() const
Get method for locale.
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
MainWindow & mainWindow()
Get method for MainWindow.
virtual void handleOk()
Process slotOk.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
MainWindowModel modelMainWindow() const
Get method for main window model.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void setCoordScaleXTheta(CoordScale coordScale)
Set method for linear/log scale on x/theta.
DlgSettingsCoords(MainWindow &mainWindow)
Single constructor.
CoordUnitsPolarTheta coordUnitsTheta() const
Get method for theta unit.
void setCoordsType(CoordsType coordsType)
Set method for coordinates type.