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;
79 m_validatorOriginRadius (0),
84 m_modelCoordsBefore (0),
85 m_modelCoordsAfter (0)
87 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::DlgSettingsCoords";
91 MINIMUM_DIALOG_WIDTH_COORDS);
94 DlgSettingsCoords::~DlgSettingsCoords()
96 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::~DlgSettingsCoords";
99 void DlgSettingsCoords::annotateAngles (
const QFont &defaultFont) {
102 for (
int direction = 0; direction < 4; direction++) {
105 CoordUnitsPolarTheta thetaUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData().toInt();
107 switch (thetaUnits) {
108 case COORD_UNITS_POLAR_THETA_DEGREES:
109 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES:
110 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS:
111 angle = QString::number (90.0 * direction);
114 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
115 angle = QString::number (90.0 * direction);
116 if (direction == 1) {
118 }
else if (direction == 3) {
123 case COORD_UNITS_POLAR_THETA_GRADIANS:
124 angle = QString::number (100.0 * direction);
127 case COORD_UNITS_POLAR_THETA_RADIANS:
129 static QString radiansUnits [] = {
"0",
"PI / 2",
"PI",
"3 * PI / 2"};
130 ENGAUGE_ASSERT (direction < 4);
131 angle = radiansUnits [direction];
135 case COORD_UNITS_POLAR_THETA_TURNS:
137 static QString turnsUnits [] = {
"0",
"1 / 4",
"1 / 2",
"3 / 4"};
138 ENGAUGE_ASSERT (direction < 4);
139 angle = turnsUnits [direction];
147 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
148 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
152 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
156 x = XCENTER - textAngle->boundingRect().width () / 2.0;
159 x = CARTESIAN_COORD_MIN;
168 y = CARTESIAN_COORD_MIN;
171 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
175 textAngle->setPos (x, y);
179 void DlgSettingsCoords::annotateRadiusAtOrigin(
const QFont &defaultFont) {
181 QGraphicsTextItem *textRadius = m_scenePreview->addText (m_editOriginRadius->text());
182 textRadius->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
183 textRadius->setPos (XCENTER - textRadius->boundingRect().width () / 2.0,
187 QRectF DlgSettingsCoords::boundingRectGraph (
CmdMediator &cmdMediator,
192 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
205 return ftor.boundingRectGraph(isEmpty);
208 void DlgSettingsCoords::createDateTime (QGridLayout *layout,
211 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createDateTime";
213 QLabel *label =
new QLabel(tr (
"Date/Time:"));
214 layout->addWidget (label, row, 1);
216 QWidget *widgetCombos =
new QWidget;
217 layout->addWidget (widgetCombos, row++, 2);
218 QHBoxLayout *layoutCombos =
new QHBoxLayout;
219 widgetCombos->setLayout (layoutCombos);
222 m_cmbDate =
new QComboBox;
223 m_cmbDate->setWhatsThis (tr (
"Date format to be used for date values, and date portion of mixed date/time values, "
224 "during input and output.\n\n"
225 "Setting the format to an empty value results in just the time portion appearing in output."));
226 connect (m_cmbDate, SIGNAL (activated (
const QString &)),
this, SLOT (slotDate (
const QString &)));
227 layoutCombos->addWidget (m_cmbDate);
229 m_cmbTime =
new QComboBox;
230 m_cmbTime->setWhatsThis (tr (
"Time format to be used for time values, and time portion of mixed date/time values, "
231 "during input and output.\n\n"
232 "Setting the format to an empty value results in just the date portion appearing in output."));
233 connect (m_cmbTime, SIGNAL (activated (
const QString &)),
this, SLOT (slotTime (
const QString &)));
234 layoutCombos->addWidget (m_cmbTime);
237 void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
240 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupCoordsType";
242 m_boxCoordsType =
new QGroupBox(tr (
"Coordinates Types"));
243 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
245 QVBoxLayout *layoutGroup =
new QVBoxLayout (m_boxCoordsType);
247 QString polarButtonText = QString(tr (
"Polar") +
" (") + THETA + QString(
", " + tr (
"R") +
")");
249 m_btnCartesian =
new QRadioButton (tr (
"Cartesian (X, Y)"), m_boxCoordsType);
250 m_btnCartesian->setWhatsThis (QString(tr(
"Select cartesian coordinates.\n\n"
251 "The X and Y coordinates will be used")));
252 connect (m_btnCartesian, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
253 layoutGroup->addWidget (m_btnCartesian);
255 m_btnPolar =
new QRadioButton (polarButtonText, m_boxCoordsType);
256 m_btnPolar->setWhatsThis (QString(tr(
"Select polar coordinates.\n\n"
257 "The Theta and R coordinates will be used.\n\n"
258 "Polar coordinates are not allowed with log scale for Theta")));
259 connect (m_btnPolar, SIGNAL (toggled(
bool)),
this, SLOT (slotCartesianPolar (
bool)));
260 layoutGroup->addWidget (m_btnPolar);
263 void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
266 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupXTheta";
268 m_boxXTheta =
new QGroupBox(OVERRIDDEN_VALUE);
269 layout->addWidget (m_boxXTheta, row, 1, 1, 1);
271 QGridLayout *layoutXTheta =
new QGridLayout (m_boxXTheta);
272 m_boxXTheta->setLayout (layoutXTheta);
275 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
276 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
278 m_xThetaLinear =
new QRadioButton (tr (
"Linear"), m_boxXTheta);
279 m_xThetaLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the X or Theta coordinate")));
280 connect (m_xThetaLinear, SIGNAL (released ()),
this, SLOT (slotXThetaLinear()));
281 layoutXTheta->addWidget (m_xThetaLinear, rowGroup++, COLUMN_0);
283 m_xThetaLog =
new QRadioButton (tr (
"Log"), m_boxXTheta);
284 m_xThetaLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the X or Theta coordinate.\n\n"
285 "Log scale is not allowed if there are negative coordinates.\n\n"
286 "Log scale is not allowed for the Theta coordinate.")));
287 connect (m_xThetaLog, SIGNAL (released ()),
this, SLOT (slotXThetaLog()));
288 layoutXTheta->addWidget (m_xThetaLog, rowGroup++, COLUMN_0);
290 QLabel *labelThetaUnits =
new QLabel(tr (
"Units:"));
291 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
293 m_cmbXThetaUnits =
new QComboBox;
294 connect (m_cmbXThetaUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsXTheta(
const QString &)));
295 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
298 void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
301 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createGroupYRadius";
303 m_boxYRadius =
new QGroupBox (OVERRIDDEN_VALUE);
304 layout->addWidget (m_boxYRadius, row++, 2, 1, 1);
306 QGridLayout *layoutYRadius =
new QGridLayout (m_boxYRadius);
307 m_boxYRadius->setLayout (layoutYRadius);
310 QLabel *labelScale =
new QLabel (tr (
"Scale:"));
311 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
313 m_yRadiusLinear =
new QRadioButton (tr (
"Linear"), m_boxYRadius);
314 m_yRadiusLinear->setWhatsThis (QString(tr(
"Specifies linear scale for the Y or R coordinate")));
315 connect (m_yRadiusLinear, SIGNAL(released()),
this, SLOT (slotYRadiusLinear()));
316 layoutYRadius->addWidget (m_yRadiusLinear, rowGroup, COLUMN_0);
318 QLabel *labelOriginRadius =
new QLabel(tr (
"Origin radius value:"));
319 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
321 m_yRadiusLog =
new QRadioButton (tr (
"Log"), m_boxYRadius);
322 m_yRadiusLog->setWhatsThis (QString(tr(
"Specifies logarithmic scale for the Y or R coordinate\n\n"
323 "Log scale is not allowed if there are negative coordinates.")));
324 connect (m_yRadiusLog, SIGNAL(released ()),
this, SLOT (slotYRadiusLog ()));
325 layoutYRadius->addWidget (m_yRadiusLog, rowGroup, COLUMN_0);
327 m_editOriginRadius =
new QLineEdit (m_boxYRadius);
328 m_editOriginRadius->setMaximumWidth (MAX_WIDTH_EDIT_ORIGIN_RADIUS);
329 m_editOriginRadius->setWhatsThis (QString(tr(
"Specify radius value at origin.\n\n"
330 "Normally the radius at the origin is 0, but a nonzero value may be applied in other cases "
331 "(like when the radial units are decibels).")));
332 connect (m_editOriginRadius, SIGNAL (textChanged (
const QString &)),
this, SLOT (slotPolarOriginRadius(
const QString &)));
333 layoutYRadius->addWidget (m_editOriginRadius, rowGroup++, COLUMN_1);
335 QLabel *labelUnits =
new QLabel(tr (
"Units:"));
336 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
338 m_cmbYRadiusUnits =
new QComboBox;
339 connect (m_cmbYRadiusUnits, SIGNAL (activated (
const QString &)),
this, SLOT (slotUnitsYRadius(
const QString &)));
340 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
347 void DlgSettingsCoords::createPreview (QGridLayout *layout,
350 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createPreview";
352 QLabel *labelPreview =
new QLabel (tr (
"Preview"));
353 layout->addWidget (labelPreview, row++, 0, 1, 4);
355 m_scenePreview =
new QGraphicsScene (
this);
357 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
359 m_viewPreview->setWhatsThis (tr (
"Preview window that shows how current settings affect the coordinate system."));
360 m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
361 m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
364 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
369 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::createSubPanel";
371 QWidget *subPanel =
new QWidget ();
372 QGridLayout *layout =
new QGridLayout (subPanel);
373 subPanel->setLayout (layout);
375 layout->setColumnStretch(0, 1);
376 layout->setColumnStretch(1, 0);
377 layout->setColumnStretch(2, 0);
378 layout->setColumnStretch(3, 1);
381 createGroupCoordsType(layout, row);
382 createGroupXTheta (layout, row);
383 createGroupYRadius (layout, row);
384 createDateTime (layout, row);
385 createPreview (layout, row);
390 void DlgSettingsCoords::drawCartesianLinearX ()
392 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearX";
395 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
396 double x = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
397 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
398 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
399 line->setPen(QPen (QBrush ((isHighlighted ? Qt::gray : Qt::lightGray)),
401 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
403 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
404 line->setPen(QPen (QBrush (Qt::black),
411 void DlgSettingsCoords::drawCartesianLinearY ()
413 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLinearY";
416 for (
int step = NUM_COORD_STEPS - 1; step >= 0; step--) {
417 double y = CARTESIAN_COORD_MIN + step * CARTESIAN_COORD_STEP;
418 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
419 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
420 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
422 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
424 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
425 line->setPen(QPen (QBrush (Qt::black),
432 void DlgSettingsCoords::drawCartesianLogX ()
434 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogX";
437 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
438 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
440 double x = (1.0 - s) * CARTESIAN_COORD_MIN + s * CARTESIAN_COORD_MAX;
441 QGraphicsLineItem *line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
442 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
443 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
445 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
447 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
448 line->setPen(QPen (QBrush (Qt::black),
455 void DlgSettingsCoords::drawCartesianLogY ()
457 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawCartesianLogY";
460 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
461 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
462 (pow (POWER_FOR_LOG, 1.0) - 1.0);
463 double y = (1.0 - s) * CARTESIAN_COORD_MAX + s * CARTESIAN_COORD_MIN;
464 QGraphicsLineItem *line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
465 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
466 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
468 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
470 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
471 line->setPen(QPen (QBrush (Qt::black),
478 void DlgSettingsCoords::drawPolarLinearRadius ()
480 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLinearRadius";
482 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
483 double radius = step * POLAR_STEP;
484 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
488 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
489 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
491 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
495 void DlgSettingsCoords::drawPolarLogRadius ()
497 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarLogRadius";
499 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
500 double s = (pow (POWER_FOR_LOG, step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
501 (pow (POWER_FOR_LOG, 1.0) - 1.0);
502 double radius = (s * (NUM_COORD_STEPS - 1.0)) * POLAR_STEP;
503 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
507 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
508 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
510 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
514 void DlgSettingsCoords::drawPolarTheta ()
516 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::drawPolarTheta";
519 for (
int step = 0; step < NUM_COORD_STEPS; step++) {
520 double theta = POLAR_THETA_MIN + step * POLAR_THETA_STEP;
521 double x = POLAR_RADIUS * cos (theta * DEG_2_RAD);
522 double y = POLAR_RADIUS * sin (theta * DEG_2_RAD);
523 QGraphicsLineItem *line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
524 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
525 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
527 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
529 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
530 line->setPen(QPen (QBrush (Qt::black),
539 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::handleOk";
542 cmdMediator ().document(),
543 *m_modelCoordsBefore,
544 *m_modelCoordsAfter);
552 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::load";
558 QRectF rectGraph = boundingRectGraph (cmdMediator,
560 bool xThetaGoesNegative = !isEmpty && (rectGraph.x() <= 0);
561 bool yRGoesNegative = !isEmpty && (rectGraph.y() <= 0);
562 m_xThetaLinear->setEnabled (!xThetaGoesNegative);
563 m_xThetaLog->setEnabled (!xThetaGoesNegative);
564 m_yRadiusLinear->setEnabled (!yRGoesNegative);
565 m_yRadiusLog->setEnabled (!yRGoesNegative);
568 if (m_modelCoordsBefore != 0) {
569 delete m_modelCoordsBefore;
571 if (m_modelCoordsAfter != 0) {
572 delete m_modelCoordsAfter;
581 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->
coordScaleYRadius(),
586 m_editOriginRadius->setValidator (m_validatorOriginRadius);
587 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->
originRadius ()));
589 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
590 m_btnCartesian->setChecked (
true);
592 m_btnPolar->setChecked (
true);
599 m_xThetaLinear->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LINEAR);
600 m_xThetaLog->setChecked (m_modelCoordsAfter->
coordScaleXTheta() == COORD_SCALE_LOG);
601 m_yRadiusLinear->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LINEAR);
602 m_yRadiusLog->setChecked (m_modelCoordsAfter->
coordScaleYRadius() == COORD_SCALE_LOG);
609 void DlgSettingsCoords::loadComboBoxDate()
611 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxDate";
615 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_SKIP),
616 QVariant (COORD_UNITS_DATE_SKIP));
617 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_MONTH_DAY_YEAR),
618 QVariant (COORD_UNITS_DATE_MONTH_DAY_YEAR));
619 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_DAY_MONTH_YEAR),
620 QVariant (COORD_UNITS_DATE_DAY_MONTH_YEAR));
621 m_cmbDate->addItem (coordUnitsDateToString (COORD_UNITS_DATE_YEAR_MONTH_DAY),
622 QVariant (COORD_UNITS_DATE_YEAR_MONTH_DAY));
624 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
626 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->
coordUnitsDate()));
627 m_cmbDate->setCurrentIndex (index);
630 void DlgSettingsCoords::loadComboBoxTime()
632 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxTime";
636 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_SKIP),
637 QVariant (COORD_UNITS_TIME_SKIP));
638 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE),
639 QVariant (COORD_UNITS_TIME_HOUR_MINUTE));
640 m_cmbTime->addItem (coordUnitsTimeToString (COORD_UNITS_TIME_HOUR_MINUTE_SECOND),
641 QVariant (COORD_UNITS_TIME_HOUR_MINUTE_SECOND));
643 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
645 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->
coordUnitsTime()));
646 m_cmbTime->setCurrentIndex (index);
649 void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
650 CoordUnitsNonPolarTheta coordUnits)
652 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsNonPolar";
656 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_NUMBER),
657 QVariant (COORD_UNITS_NON_POLAR_THETA_NUMBER));
658 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DATE_TIME),
659 QVariant (COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
660 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS),
661 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS));
662 cmb.addItem (coordUnitsNonPolarThetaToString (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
663 QVariant (COORD_UNITS_NON_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
665 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
667 cmb.setWhatsThis (QString (tr (
"Numbers have the simplest and most general format.\n\n"
668 "Date and time values have date and/or time components.\n\n"
669 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
670 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.")));
672 int index = cmb.findData (coordUnits);
673 cmb.setCurrentIndex (index);
676 void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
677 CoordUnitsPolarTheta coordUnits)
679 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::loadComboBoxUnitsPolar";
683 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES),
684 QVariant (COORD_UNITS_POLAR_THETA_DEGREES));
685 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES),
686 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES));
687 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS),
688 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS));
689 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW),
690 QVariant (COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW));
691 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_GRADIANS),
692 QVariant (COORD_UNITS_POLAR_THETA_GRADIANS));
693 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_RADIANS),
694 QVariant (COORD_UNITS_POLAR_THETA_RADIANS));
695 cmb.addItem (coordUnitsPolarThetaToString (COORD_UNITS_POLAR_THETA_TURNS),
696 QVariant (COORD_UNITS_POLAR_THETA_TURNS));
698 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
700 cmb.setWhatsThis (QString (tr (
"Degrees (DDD.DDDDD) format uses a single real number. One complete revolution is 360 degrees.\n\n"
701 "Degrees Minutes (DDD MM.MMM) format uses one integer number for degrees, and a real number for minutes. There are "
702 "60 minutes per degree. During input, a space must be inserted between the two numbers.\n\n"
703 "Degrees Minutes Seconds (DDD MM SS.S) format uses two integer number for degrees and minutes, and a real number for "
704 "seconds. There are 60 seconds per minute. During input, spaces must be inserted between the three numbers.\n\n"
705 "Gradians format uses a single real number. One complete revolution is 400 gradians.\n\n"
706 "Radians format uses a single real number. One complete revolution is 2*pi radians.\n\n"
707 "Turns format uses a single real number. One complete revolution is one turn.")));
709 int index = cmb.findData (coordUnits);
710 cmb.setCurrentIndex (index);
713 void DlgSettingsCoords::resetSceneRectangle ()
715 QRect rect (CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
716 CARTESIAN_COORD_MIN - CARTESIAN_COORD_STEP / 2.0,
717 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP,
718 CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN + CARTESIAN_COORD_STEP);
720 QGraphicsRectItem *itemPerimeter =
new QGraphicsRectItem(rect);
721 itemPerimeter->setVisible(
false);
722 m_scenePreview->addItem (itemPerimeter);
723 m_viewPreview->centerOn (QPointF (0.0, 0.0));
726 void DlgSettingsCoords::slotCartesianPolar (
bool)
728 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotCartesian";
730 if (m_btnCartesian->isChecked ()) {
740 void DlgSettingsCoords::slotDate(
const QString &)
742 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotDate";
744 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
750 void DlgSettingsCoords::slotPolarOriginRadius(
const QString &)
752 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotPolarOriginRadius";
754 QString numberText = m_editOriginRadius->text();
761 void DlgSettingsCoords::slotTime(
const QString &)
763 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotTime";
765 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
771 void DlgSettingsCoords::slotUnitsXTheta(
const QString &)
773 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsXTheta";
775 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
776 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
779 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
786 void DlgSettingsCoords::slotUnitsYRadius(
const QString &)
788 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotUnitsYRadius";
790 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
791 if (m_modelCoordsAfter->
coordsType() == COORDS_TYPE_CARTESIAN) {
800 void DlgSettingsCoords::slotXThetaLinear()
802 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLinear";
809 void DlgSettingsCoords::slotXThetaLog()
811 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotXThetaLog";
818 void DlgSettingsCoords::slotYRadiusLinear()
820 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLinear";
822 delete m_validatorOriginRadius;
830 m_editOriginRadius->setValidator (m_validatorOriginRadius);
837 void DlgSettingsCoords::slotYRadiusLog()
839 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::slotYRadiusLog";
841 delete m_validatorOriginRadius;
849 m_editOriginRadius->setValidator (m_validatorOriginRadius);
856 void DlgSettingsCoords::updateControls ()
860 QString textOriginRadius = m_editOriginRadius->text();
861 int posOriginRadius = 0;
863 bool goodOriginRadius =
true;
864 if (m_editOriginRadius->isEnabled ()) {
867 goodOriginRadius = (m_validatorOriginRadius->
validate (textOriginRadius,
868 posOriginRadius) == QValidator::Acceptable);
873 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
875 m_xThetaLinear->setEnabled (!m_btnPolar->isChecked ());
876 m_xThetaLog->setEnabled (!m_btnPolar->isChecked ());
877 if (m_btnCartesian->isChecked()) {
878 m_yRadiusLinear->setEnabled (
true);
879 m_yRadiusLog->setEnabled (
true);
889 int posOriginRadiusOther;
890 bool goodOriginRadiusOther = (dlg->
validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
894 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
895 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
897 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
899 QString captionXTheta = (m_btnCartesian->isChecked () ?
901 THETA) + QString (
" %1")
902 .arg (tr (
"Coordinates"));
903 QString captionYRadius = (m_btnCartesian->isChecked () ?
905 QString (tr (
"R"))) + QString (
" %1")
906 .arg (tr (
"Coordinates"));
908 if (m_boxXTheta->title() != captionXTheta) {
909 m_boxXTheta->setTitle (captionXTheta);
912 if (m_boxYRadius->title () != captionYRadius) {
913 m_boxYRadius->setTitle (captionYRadius);
917 if (m_btnCartesian->isChecked()) {
918 enableDateTime = (((CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME) ||
919 ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME));
921 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
923 m_cmbDate->setEnabled (enableDateTime);
924 m_cmbTime->setEnabled (enableDateTime);
926 LOG4CPP_INFO_S ((*mainCat)) <<
"DlgSettingsCoords::updateControls"
927 <<
" textOriginRadius=" << textOriginRadius.toLatin1().data()
928 <<
" goodOriginRadius=" << (goodOriginRadius ?
"true" :
"false")
929 <<
" originRadius=" << posOriginRadius
930 <<
" btnPolarChecked=" << (m_btnPolar->isChecked() ?
"true" :
"false")
931 <<
" enableDateTime=" << (enableDateTime ?
"true" :
"false");
934 void DlgSettingsCoords::updateCoordUnits()
937 if (m_btnCartesian->isChecked()) {
938 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
940 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
943 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
945 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
950 void DlgSettingsCoords::updatePreview()
952 m_scenePreview->clear();
960 if (m_btnCartesian->isChecked()) {
963 if (m_xThetaLinear->isChecked()) {
964 drawCartesianLinearX ();
966 drawCartesianLogX ();
969 if (m_yRadiusLinear->isChecked()) {
970 drawCartesianLinearY ();
972 drawCartesianLogY ();
979 if (m_yRadiusLinear->isChecked()) {
980 drawPolarLinearRadius ();
982 drawPolarLogRadius ();
986 annotateRadiusAtOrigin (defaultFont);
987 annotateAngles (defaultFont);
990 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.
void setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)
Set method for x units.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
void setCoordScaleYRadius(CoordScale coordScale)
Set method for linear/log scale on y/radius.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
Abstract validator for all numeric formats.
CoordUnitsTime coordUnitsTime() const
Get method for time format when used.
Command for DlgSettingsCoords.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window...
CoordUnitsNonPolarTheta coordUnitsY() const
Get method for x units.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
void setCoordUnitsTheta(CoordUnitsPolarTheta coordUnits)
Set method for theta units.
CoordsType coordsType() const
Get method for coordinates type.
CoordUnitsNonPolarTheta coordUnitsX() const
Get method for x units.
Model for DlgSettingsCoords and CmdSettingsCoords.
void setOriginRadius(double originRadius)
Set method for origin radius in polar mode.
CoordUnitsDate coordUnitsDate() const
Get method for date format when used.
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.
void finishPanel(QWidget *subPanel, int minimumWidth=MINIMUM_DIALOG_WIDTH)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
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.