Engauge Digitizer 2
Loading...
Searching...
No Matches
DlgSettingsCoords.cpp
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
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"
17#include "Logger.h"
18#include "MainWindow.h"
19#include <math.h>
20#include <QComboBox>
21#include <QDebug>
22#include <QDoubleValidator>
23#include <QGraphicsRectItem>
24#include <QGridLayout>
25#include <QGroupBox>
26#include <QGraphicsScene>
27#include <QLabel>
28#include <QLineEdit>
29#include <QPalette>
30#include <QRadioButton>
31#include <QStackedWidget>
32#include <QVBoxLayout>
33#include "Transformation.h"
34#include "ViewPreview.h"
35
36const QString OVERRIDDEN_VALUE(""); // Values are overridden in updateControls
37
38const int COLUMN_0 = 0;
39const int COLUMN_1 = 1;
40
41const int STEPS_PER_CYCLE = 4; // Repeat STEPS_PER_CYLE-1 unhighlighted steps plus 1 highlighted step in each cycle
42const int STEPS_CYCLE_COUNT = 4; // Repeat one highlighted step + STEPS_UNHIGHLIGHTED_PER_HIGHLIGHTED steps this many times
43const int NUM_COORD_STEPS = 1 + STEPS_PER_CYCLE * STEPS_CYCLE_COUNT;
44
45const int MAX_WIDTH_EDIT_ORIGIN_RADIUS = 140;
46
47const int CARTESIAN_COORD_MAX = 100;
48const int CARTESIAN_COORD_MIN = -100;
49const double CARTESIAN_COORD_STEP = (CARTESIAN_COORD_MAX - CARTESIAN_COORD_MIN) / (NUM_COORD_STEPS - 1.0);
50
51const int POLAR_RADIUS = CARTESIAN_COORD_MAX;
52const double POLAR_STEP = POLAR_RADIUS / (NUM_COORD_STEPS - 1.0);
53
54const int POLAR_THETA_MAX = 360;
55const int POLAR_THETA_MIN = 0;
56const double POLAR_THETA_STEP = (POLAR_THETA_MAX - POLAR_THETA_MIN) / (NUM_COORD_STEPS - 1.0);
57
58const double XCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
59const double YCENTER = (CARTESIAN_COORD_MIN + CARTESIAN_COORD_MAX) / 2.0;
60
61const double LINE_WIDTH_THIN = 0.0;
62const double LINE_WIDTH_THICK = 2.0;
63
64const double PI = 3.1415926535;
65const double DEG_2_RAD = PI / 180.0;
66
67const int FONT_SIZE = 6;
68
69const double POWER_FOR_LOG = 10.0; // Need a larger power (certainly more than e) to make log gradient obvious
70
72 DlgSettingsAbstractBase (tr ("Coordinates"),
73 "DlgSettingsCoords",
74 mainWindow),
75 m_btnCartesian (0),
76 m_btnPolar (0),
77 m_validatorOriginRadius (0),
78 m_cmbDate (0),
79 m_cmbTime (0),
80 m_scenePreview (0),
81 m_viewPreview (0),
82 m_modelCoordsBefore (0),
83 m_modelCoordsAfter (0)
84{
85 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::DlgSettingsCoords";
86
87 QWidget *subPanel = createSubPanel ();
88 finishPanel (subPanel);
89}
90
91DlgSettingsCoords::~DlgSettingsCoords()
92{
93 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::~DlgSettingsCoords";
94}
95
96void DlgSettingsCoords::annotateAngles (const QFont &defaultFont) {
97
98 // 0=+x, 1=+y, 2=-x, 3=-y
99 for (int direction = 0; direction < 4; direction++) {
100
101 QString angle;
102 CoordUnitsPolarTheta thetaUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData().toInt();
103
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);
109 break;
110
111 case COORD_UNITS_POLAR_THETA_DEGREES_MINUTES_SECONDS_NSEW:
112 angle = QString::number (90.0 * direction);
113 if (direction == 1) {
114 angle = "90E";
115 } else if (direction == 3) {
116 angle = "90W";
117 }
118 break;
119
120 case COORD_UNITS_POLAR_THETA_GRADIANS:
121 angle = QString::number (100.0 * direction);
122 break;
123
124 case COORD_UNITS_POLAR_THETA_RADIANS:
125 {
126 static QString radiansUnits [] = {"0", "PI / 2", "PI", "3 * PI / 2"};
127 ENGAUGE_ASSERT (direction < 4);
128 angle = radiansUnits [direction];
129 }
130 break;
131
132 case COORD_UNITS_POLAR_THETA_TURNS:
133 {
134 static QString turnsUnits [] = {"0", "1 / 4", "1 / 2", "3 / 4"};
135 ENGAUGE_ASSERT (direction < 4);
136 angle = turnsUnits [direction];
137 }
138 break;
139
140 default:
141 break;
142 }
143
144 QGraphicsTextItem *textAngle = m_scenePreview->addText (angle);
145 textAngle->setFont (QFont (defaultFont.defaultFamily(), FONT_SIZE));
146 double x = 0, y = 0; // Initialized to prevent compiler warning
147 switch (direction) {
148 case 0:
149 x = CARTESIAN_COORD_MAX - textAngle->boundingRect().width ();
150 break;
151 case 1:
152 case 3:
153 x = XCENTER - textAngle->boundingRect().width () / 2.0;
154 break;
155 case 2:
156 x = CARTESIAN_COORD_MIN;
157 break;
158 }
159 switch (direction) {
160 case 0:
161 case 2:
162 y = YCENTER;
163 break;
164 case 1:
165 y = CARTESIAN_COORD_MIN;
166 break;
167 case 3:
168 y = CARTESIAN_COORD_MAX - textAngle->boundingRect().height ();
169 break;
170 }
171
172 textAngle->setPos (x, y);
173 }
174}
175
176void DlgSettingsCoords::annotateRadiusAtOrigin(const QFont &defaultFont) {
177
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,
181 YCENTER);
182}
183
184QRectF DlgSettingsCoords::boundingRectGraph (CmdMediator &cmdMediator,
185 bool &isEmpty) const
186{
187 CallbackBoundingRects ftor (mainWindow().transformation());
188
189 Functor2wRet<const QString &, const Point&, CallbackSearchReturn> ftorWithCallback = functor_ret (ftor,
191
192 // There may or may one, two or three axis points. Even if all three are not defined (so
193 // transformation is not defined), we can still get coordinates if there are one or two
195
196 // If the transformation is not defined, then there are no graph coordinates to extract
197 // from the graph curves (and probably trigger an assert)
198 if (mainWindow().transformIsDefined()) {
200 }
201
202 return ftor.boundingRectGraph(isEmpty);
203}
204
205void DlgSettingsCoords::createDateTime (QGridLayout *layout,
206 int &row)
207{
208 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createDateTime";
209
210 QLabel *label = new QLabel(tr ("Date/Time:"));
211 layout->addWidget (label, row, 1);
212
213 QWidget *widgetCombos = new QWidget;
214 layout->addWidget (widgetCombos, row++, 2);
215 QHBoxLayout *layoutCombos = new QHBoxLayout;
216 widgetCombos->setLayout (layoutCombos);
217
218 // Put date and time comboboxes into same widget
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);
225
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);
232}
233
234void DlgSettingsCoords::createGroupCoordsType (QGridLayout *layout,
235 int &row)
236{
237 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createGroupCoordsType";
238
239 m_boxCoordsType = new QGroupBox(tr ("Coordinates Types"));
240 layout->addWidget (m_boxCoordsType, row++, 1, 1, 2);
241
242 QVBoxLayout *layoutGroup = new QVBoxLayout (m_boxCoordsType);
243
244 QString polarButtonText = QString(tr ("Polar") + " (") + THETA + QString(", " + tr ("R") + ")");
245
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);
251
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);
258}
259
260void DlgSettingsCoords::createGroupXTheta (QGridLayout *layout,
261 int &row)
262{
263 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createGroupXTheta";
264
265 m_boxXTheta = new QGroupBox(OVERRIDDEN_VALUE);
266 layout->addWidget (m_boxXTheta, row++, 1, 1, 2);
267
268 QGridLayout *layoutXTheta = new QGridLayout (m_boxXTheta);
269 m_boxXTheta->setLayout (layoutXTheta);
270 int rowGroup = 0;
271
272 QLabel *labelScale = new QLabel (tr ("Scale:"));
273 layoutXTheta->addWidget (labelScale, rowGroup++, COLUMN_0);
274
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);
279
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);
286
287 QLabel *labelThetaUnits = new QLabel(tr ("Units:"));
288 layoutXTheta->addWidget (labelThetaUnits, rowGroup++, COLUMN_0);
289
290 m_cmbXThetaUnits = new QComboBox;
291 connect (m_cmbXThetaUnits, SIGNAL (activated (const QString &)), this, SLOT (slotUnitsXTheta(const QString &))); // activated() ignores code changes
292 layoutXTheta->addWidget (m_cmbXThetaUnits, rowGroup++, COLUMN_0, 1, 2);
293}
294
295void DlgSettingsCoords::createGroupYRadius (QGridLayout *layout,
296 int &row)
297{
298 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createGroupYRadius";
299
300 m_boxYRadius = new QGroupBox (OVERRIDDEN_VALUE);
301 layout->addWidget (m_boxYRadius, row++, 1, 1, 2);
302
303 QGridLayout *layoutYRadius = new QGridLayout (m_boxYRadius);
304 m_boxYRadius->setLayout (layoutYRadius);
305 int rowGroup = 0;
306
307 QLabel *labelScale = new QLabel (tr ("Scale:"));
308 layoutYRadius->addWidget (labelScale, rowGroup++, COLUMN_0);
309
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);
314
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);
320
321 QLabel *labelUnits = new QLabel(tr ("Units:"));
322 layoutYRadius->addWidget (labelUnits, rowGroup++, COLUMN_0);
323
324 m_cmbYRadiusUnits = new QComboBox;
325 connect (m_cmbYRadiusUnits, SIGNAL (activated (const QString &)), this, SLOT (slotUnitsYRadius(const QString &))); // activated() ignores code changes
326 layoutYRadius->addWidget (m_cmbYRadiusUnits, rowGroup++, COLUMN_0, 1, 2);
327
328 rowGroup = 0;
329 QLabel *labelOriginRadius = new QLabel(tr ("Origin radius value:"));
330 layoutYRadius->addWidget (labelOriginRadius, rowGroup++, COLUMN_1);
331
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);
339}
340
341void DlgSettingsCoords::createOptionalSaveDefault (QHBoxLayout * /* layout */)
342{
343}
344
345void DlgSettingsCoords::createPreview (QGridLayout *layout,
346 int &row)
347{
348 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createPreview";
349
350 QLabel *labelPreview = new QLabel (tr ("Preview"));
351 layout->addWidget (labelPreview, row++, 0, 1, 4);
352
353 m_scenePreview = new QGraphicsScene (this);
354 m_viewPreview = new ViewPreview (m_scenePreview,
355 ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
356 this);
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);
360 m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
361
362 layout->addWidget (m_viewPreview, row++, 0, 1, 4);
363}
364
366{
367 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::createSubPanel";
368
369 QWidget *subPanel = new QWidget ();
370 QGridLayout *layout = new QGridLayout (subPanel);
371 subPanel->setLayout (layout);
372
373 layout->setColumnStretch(0, 1); // Empty first column
374 layout->setColumnStretch(1, 0); // Labels
375 layout->setColumnStretch(2, 0); // User controls
376 layout->setColumnStretch(3, 1); // Empty last column
377
378 int row = 0;
379 createGroupCoordsType(layout, row);
380 createGroupXTheta (layout, row);
381 createGroupYRadius (layout, row);
382 createDateTime (layout, row);
383 createPreview (layout, row);
384
385 return subPanel;
386}
387
388void DlgSettingsCoords::drawCartesianLinearX ()
389{
390 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLinearX";
391
392 bool isAxis = true;
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)),
398 LINE_WIDTH_THIN,
399 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
400 if (isAxis) {
401 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
402 line->setPen(QPen (QBrush (Qt::black),
403 LINE_WIDTH_THICK));
404 }
405 isAxis = false;
406 }
407}
408
409void DlgSettingsCoords::drawCartesianLinearY ()
410{
411 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLinearY";
412
413 bool isAxis = true;
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),
419 LINE_WIDTH_THIN,
420 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
421 if (isAxis) {
422 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
423 line->setPen(QPen (QBrush (Qt::black),
424 LINE_WIDTH_THICK));
425 }
426 isAxis = false;
427 }
428}
429
430void DlgSettingsCoords::drawCartesianLogX ()
431{
432 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLogX";
433
434 bool isAxis = true;
435 for (int step = 0; step < NUM_COORD_STEPS; step++) {
436 double s = (exp (step / (NUM_COORD_STEPS - 1.0)) - 1.0) /
437 (exp (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),
442 LINE_WIDTH_THIN,
443 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
444 if (isAxis) {
445 line = m_scenePreview->addLine (x, CARTESIAN_COORD_MIN, x, CARTESIAN_COORD_MAX);
446 line->setPen(QPen (QBrush (Qt::black),
447 LINE_WIDTH_THICK));
448 }
449 isAxis = false;
450 }
451}
452
453void DlgSettingsCoords::drawCartesianLogY ()
454{
455 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawCartesianLogY";
456
457 bool isAxis = true;
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; // Invert y coordinate (min<->max)
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),
465 LINE_WIDTH_THIN,
466 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
467 if (isAxis) {
468 line = m_scenePreview->addLine (CARTESIAN_COORD_MIN, y, CARTESIAN_COORD_MAX, y);
469 line->setPen(QPen (QBrush (Qt::black),
470 LINE_WIDTH_THICK));
471 }
472 isAxis = false;
473 }
474}
475
476void DlgSettingsCoords::drawPolarLinearRadius ()
477{
478 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawPolarLinearRadius";
479
480 for (int step = 0; step < NUM_COORD_STEPS; step++) {
481 double radius = step * POLAR_STEP;
482 QGraphicsEllipseItem *line = m_scenePreview->addEllipse (XCENTER - radius,
483 YCENTER - radius,
484 2.0 * radius,
485 2.0 * radius);
486 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
487 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
488 LINE_WIDTH_THIN,
489 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
490 }
491}
492
493void DlgSettingsCoords::drawPolarLogRadius ()
494{
495 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawPolarLogRadius";
496
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,
502 YCENTER - radius,
503 2.0 * radius,
504 2.0 * radius);
505 bool isHighlighted = (step % STEPS_PER_CYCLE == 0);
506 line->setPen(QPen (QBrush (isHighlighted ? Qt::gray : Qt::lightGray),
507 LINE_WIDTH_THIN,
508 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
509 }
510}
511
512void DlgSettingsCoords::drawPolarTheta ()
513{
514 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::drawPolarTheta";
515
516 bool isAxis = true;
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),
524 LINE_WIDTH_THIN,
525 (isHighlighted ? Qt::SolidLine : Qt::DashLine)));
526 if (isAxis) {
527 line = m_scenePreview->addLine (XCENTER, YCENTER, XCENTER + x, YCENTER + y);
528 line->setPen(QPen (QBrush (Qt::black),
529 LINE_WIDTH_THICK));
530 }
531 isAxis = false;
532 }
533}
534
536{
537 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::handleOk";
538
540 cmdMediator ().document(),
541 *m_modelCoordsBefore,
542 *m_modelCoordsAfter);
543 cmdMediator ().push (cmd);
544
545 hide ();
546}
547
549{
550 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::load";
551
553
554 // Remove if coordinates are log so later constraints can be applied
555 bool isEmpty;
556 QRectF rectGraph = boundingRectGraph (cmdMediator,
557 isEmpty);
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);
564
565 // Flush old data
566 if (m_modelCoordsBefore != 0) {
567 delete m_modelCoordsBefore;
568 }
569 if (m_modelCoordsAfter != 0) {
570 delete m_modelCoordsAfter;
571 }
572
573 // Save new data
574 m_modelCoordsBefore = new DocumentModelCoords (cmdMediator.document().modelCoords());
575 m_modelCoordsAfter = new DocumentModelCoords (cmdMediator.document().modelCoords());
576
577 // Populate controls
578 DlgValidatorFactory dlgValidatorFactory;
579 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (m_modelCoordsAfter->coordScaleYRadius(),
580 m_modelCoordsAfter->coordUnitsRadius(),
581 m_modelCoordsAfter->coordUnitsDate(),
582 m_modelCoordsAfter->coordUnitsTime(),
583 mainWindow().modelMainWindow().locale());
584 m_editOriginRadius->setValidator (m_validatorOriginRadius); // Set before call to setText so validator is defined in updateControls
585 m_editOriginRadius->setText (QString::number (m_modelCoordsAfter->originRadius ()));
586
587 if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
588 m_btnCartesian->setChecked (true);
589 } else {
590 m_btnPolar->setChecked (true);
591 }
592
593 updateCoordUnits(); // Call after checking m_btnCartesian or m_btnPolar
594 loadComboBoxDate();
595 loadComboBoxTime ();
596
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);
601
602 updateControls (); // Probably redundant due to the setChecked just above
603 enableOk (false); // Disable Ok button since there not yet any changes
604 updatePreview();
605}
606
607void DlgSettingsCoords::loadComboBoxDate()
608{
609 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxDate";
610
611 m_cmbDate->clear ();
612
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));
621
622 ENGAUGE_ASSERT (m_cmbDate->count() == NUM_COORD_UNITS_DATE);
623
624 int index = m_cmbDate->findData (QVariant (m_modelCoordsAfter->coordUnitsDate()));
625 m_cmbDate->setCurrentIndex (index);
626}
627
628void DlgSettingsCoords::loadComboBoxTime()
629{
630 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxTime";
631
632 m_cmbTime->clear ();
633
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));
640
641 ENGAUGE_ASSERT (m_cmbTime->count() == NUM_COORD_UNITS_TIME);
642
643 int index = m_cmbTime->findData (QVariant (m_modelCoordsAfter->coordUnitsTime()));
644 m_cmbTime->setCurrentIndex (index);
645}
646
647void DlgSettingsCoords::loadComboBoxUnitsNonPolar (QComboBox &cmb,
648 CoordUnitsNonPolarTheta coordUnits)
649{
650 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxUnitsNonPolar";
651
652 cmb.clear();
653
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));
662
663 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_NON_POLAR_THETA);
664
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.")));
669
670 int index = cmb.findData (coordUnits);
671 cmb.setCurrentIndex (index);
672}
673
674void DlgSettingsCoords::loadComboBoxUnitsPolar (QComboBox &cmb,
675 CoordUnitsPolarTheta coordUnits)
676{
677 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::loadComboBoxUnitsPolar";
678
679 cmb.clear();
680
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));
695
696 ENGAUGE_ASSERT (cmb.count() == NUM_COORD_UNITS_POLAR_THETA);
697
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.")));
706
707 int index = cmb.findData (coordUnits);
708 cmb.setCurrentIndex (index);
709}
710
711void DlgSettingsCoords::resetSceneRectangle ()
712{
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);
717
718 QGraphicsRectItem *itemPerimeter = new QGraphicsRectItem(rect);
719 itemPerimeter->setVisible(false);
720 m_scenePreview->addItem (itemPerimeter);
721 m_viewPreview->centerOn (QPointF (0.0, 0.0));
722}
723
724void DlgSettingsCoords::slotCartesianPolar (bool)
725{
726 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotCartesian";
727
728 if (m_btnCartesian->isChecked ()) {
729 m_modelCoordsAfter->setCoordsType (COORDS_TYPE_CARTESIAN);
730 } else {
731 m_modelCoordsAfter->setCoordsType(COORDS_TYPE_POLAR);
732 }
733 updateCoordUnits();
734 updateControls();
735 updatePreview();
736}
737
738void DlgSettingsCoords::slotDate(const QString &)
739{
740 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotDate";
741
742 CoordUnitsDate coordUnits = (CoordUnitsDate) m_cmbDate->currentData ().toInt();
743 m_modelCoordsAfter->setCoordUnitsDate(coordUnits);
744 updateControls();
745 updatePreview();
746}
747
748void DlgSettingsCoords::slotPolarOriginRadius(const QString &)
749{
750 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotPolarOriginRadius";
751
752 QString numberText = m_editOriginRadius->text();
753
754 m_modelCoordsAfter->setOriginRadius(numberText.toDouble ());
755 updateControls();
756 updatePreview();
757}
758
759void DlgSettingsCoords::slotTime(const QString &)
760{
761 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotTime";
762
763 CoordUnitsTime coordUnits = (CoordUnitsTime) m_cmbTime->currentData ().toInt();
764 m_modelCoordsAfter->setCoordUnitsTime(coordUnits);
765 updateControls();
766 updatePreview();
767}
768
769void DlgSettingsCoords::slotUnitsXTheta(const QString &)
770{
771 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotUnitsXTheta";
772
773 if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
774 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
775 m_modelCoordsAfter->setCoordUnitsX(coordUnits);
776 } else {
777 CoordUnitsPolarTheta coordUnits = (CoordUnitsPolarTheta) m_cmbXThetaUnits->currentData ().toInt ();
778 m_modelCoordsAfter->setCoordUnitsTheta(coordUnits);
779 }
780 updateControls ();
781 updatePreview();
782}
783
784void DlgSettingsCoords::slotUnitsYRadius(const QString &)
785{
786 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotUnitsYRadius";
787
788 CoordUnitsNonPolarTheta coordUnits = (CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt ();
789 if (m_modelCoordsAfter->coordsType() == COORDS_TYPE_CARTESIAN) {
790 m_modelCoordsAfter->setCoordUnitsY(coordUnits);
791 } else {
792 m_modelCoordsAfter->setCoordUnitsRadius(coordUnits);
793 }
794 updateControls ();
795 updatePreview();
796}
797
798void DlgSettingsCoords::slotXThetaLinear()
799{
800 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotXThetaLinear";
801
802 m_modelCoordsAfter->setCoordScaleXTheta(COORD_SCALE_LINEAR);
803 updateControls ();
804 updatePreview();
805}
806
807void DlgSettingsCoords::slotXThetaLog()
808{
809 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotXThetaLog";
810
811 m_modelCoordsAfter->setCoordScaleXTheta(COORD_SCALE_LOG);
812 updateControls ();
813 updatePreview();
814}
815
816void DlgSettingsCoords::slotYRadiusLinear()
817{
818 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotYRadiusLinear";
819
820 delete m_validatorOriginRadius;
821
822 DlgValidatorFactory dlgValidatorFactory;
823 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (COORD_SCALE_LINEAR,
824 m_modelCoordsAfter->coordUnitsRadius(),
825 m_modelCoordsAfter->coordUnitsDate(),
826 m_modelCoordsAfter->coordUnitsTime(),
827 mainWindow().modelMainWindow().locale());
828 m_editOriginRadius->setValidator (m_validatorOriginRadius);
829
830 m_modelCoordsAfter->setCoordScaleYRadius((COORD_SCALE_LINEAR));
831 updateControls ();
832 updatePreview();
833}
834
835void DlgSettingsCoords::slotYRadiusLog()
836{
837 LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsCoords::slotYRadiusLog";
838
839 delete m_validatorOriginRadius;
840
841 DlgValidatorFactory dlgValidatorFactory;
842 m_validatorOriginRadius = dlgValidatorFactory.createWithNonPolar (COORD_SCALE_LOG,
843 m_modelCoordsAfter->coordUnitsRadius(),
844 m_modelCoordsAfter->coordUnitsDate(),
845 m_modelCoordsAfter->coordUnitsTime(),
846 mainWindow().modelMainWindow().locale());
847 m_editOriginRadius->setValidator (m_validatorOriginRadius);
848
849 m_modelCoordsAfter->setCoordScaleYRadius(COORD_SCALE_LOG);
850 updateControls ();
851 updatePreview();
852}
853
854void DlgSettingsCoords::updateControls ()
855{
856 // LOG4CPP_INFO_S is below
857
858 QString textOriginRadius = m_editOriginRadius->text();
859 int posOriginRadius = 0;
860
861 bool goodOriginRadius = true; // Cartesian coordinates do not use origin radius
862 if (m_editOriginRadius->isEnabled ()) {
863
864 // Origin radius must be greater than zero
865 goodOriginRadius = (m_validatorOriginRadius->validate (textOriginRadius,
866 posOriginRadius) == QValidator::Acceptable);
867 }
868
869 enableOk (goodOriginRadius);
870
871 m_boxCoordsType->setEnabled (!m_xThetaLog->isChecked ());
872
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);
878 } else {
879
880 // Use temporary validator to see if current origin radius would be correct in OTHER linear/log mode
881 DlgValidatorFactory dlgValidatorFactory;
882 DlgValidatorAbstract *dlg = dlgValidatorFactory.createWithNonPolar (m_yRadiusLinear->isChecked () ? COORD_SCALE_LOG : COORD_SCALE_LINEAR,
883 m_modelCoordsAfter->coordUnitsRadius(),
884 m_modelCoordsAfter->coordUnitsDate(),
885 m_modelCoordsAfter->coordUnitsTime(),
886 mainWindow().modelMainWindow().locale());
887 int posOriginRadiusOther;
888 bool goodOriginRadiusOther = (dlg->validate (textOriginRadius, posOriginRadiusOther) == QValidator::Acceptable);
889
890 delete dlg; // Deallocate
891
892 m_yRadiusLinear->setEnabled (goodOriginRadius && goodOriginRadiusOther);
893 m_yRadiusLog->setEnabled (goodOriginRadius && goodOriginRadiusOther);
894 }
895 m_editOriginRadius->setEnabled (m_btnPolar->isChecked ());
896
897 QString captionXTheta = (m_btnCartesian->isChecked () ?
898 QString (tr ("X")) :
899 THETA) + QString (" %1")
900 .arg (tr ("Coordinates"));
901 QString captionYRadius = (m_btnCartesian->isChecked () ?
902 QString (tr ("Y")) :
903 QString (tr ("R"))) + QString (" %1")
904 .arg (tr ("Coordinates"));
905
906 if (m_boxXTheta->title() != captionXTheta) {
907 m_boxXTheta->setTitle (captionXTheta);
908 }
909
910 if (m_boxYRadius->title () != captionYRadius) {
911 m_boxYRadius->setTitle (captionYRadius);
912 }
913
914 bool enableDateTime;
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));
918 } else {
919 enableDateTime = ((CoordUnitsNonPolarTheta) m_cmbYRadiusUnits->currentData ().toInt() == COORD_UNITS_NON_POLAR_THETA_DATE_TIME);
920 }
921 m_cmbDate->setEnabled (enableDateTime);
922 m_cmbTime->setEnabled (enableDateTime);
923
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");
930}
931
932void DlgSettingsCoords::updateCoordUnits()
933{
934 // X and Y units
935 if (m_btnCartesian->isChecked()) {
936 loadComboBoxUnitsNonPolar (*m_cmbXThetaUnits,
937 m_modelCoordsAfter->coordUnitsX());
938 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
939 m_modelCoordsAfter->coordUnitsY());
940 } else {
941 loadComboBoxUnitsPolar (*m_cmbXThetaUnits,
942 m_modelCoordsAfter->coordUnitsTheta());
943 loadComboBoxUnitsNonPolar (*m_cmbYRadiusUnits,
944 m_modelCoordsAfter->coordUnitsRadius());
945 }
946}
947
948void DlgSettingsCoords::updatePreview()
949{
950 m_scenePreview->clear();
951
952 // General approach
953 // 1) Axis lines are extra thick, but since they sometimes disappear as the preview window is rescaled, we keep the
954 // constant-pixel line under each axis line
955 // 2) Every STEPS_UNHIGHLIGHTED_PER_HIGHLIGHTED out of STEPS_UNHIGHLIGHTED_PER_HIGHLIGHTED+1 lines are dashed to make
956 // them more subtle
957
958 if (m_btnCartesian->isChecked()) {
959
960 // Cartesian
961 if (m_xThetaLinear->isChecked()) {
962 drawCartesianLinearX ();
963 } else {
964 drawCartesianLogX ();
965 }
966
967 if (m_yRadiusLinear->isChecked()) {
968 drawCartesianLinearY ();
969 } else {
970 drawCartesianLogY ();
971 }
972
973 } else {
974
975 // Polar
976 drawPolarTheta ();
977 if (m_yRadiusLinear->isChecked()) {
978 drawPolarLinearRadius ();
979 } else {
980 drawPolarLogRadius ();
981 }
982
983 QFont defaultFont;
984 annotateRadiusAtOrigin (defaultFont);
985 annotateAngles (defaultFont);
986 }
987
988 resetSceneRectangle();
989}
Callback for computing the bounding rectangles of the screen and graph coordinates of the points in t...
CallbackSearchReturn callback(const QString &curveName, const Point &point)
Callback method.
Command queue stack.
Definition CmdMediator.h:24
void iterateThroughCurvesPointsGraphs(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for all the graphs curves.
void iterateThroughCurvePointsAxes(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback)
See Curve::iterateThroughCurvePoints, for the single axes curve.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Command for DlgSettingsCoords.
Abstract base class for all Settings dialogs.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
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.
MainWindow & mainWindow()
Get method for MainWindow.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
DlgSettingsCoords(MainWindow &mainWindow)
Single constructor.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
virtual void handleOk()
Process slotOk.
Abstract validator for all numeric formats.
virtual QValidator::State validate(QString &input, int &pos) const =0
Validate according to the numeric format specific to the leaf class.
Validator factory.
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,...
Model for DlgSettingsCoords and CmdSettingsCoords.
CoordScale coordScaleYRadius() const
Get method for linear/log scale on y/radius.
void setCoordUnitsY(CoordUnitsNonPolarTheta coordUnits)
Set method for y units.
void setOriginRadius(double originRadius)
Set method for origin radius in polar mode.
CoordUnitsNonPolarTheta coordUnitsRadius() const
Get method for radius units.
void setCoordUnitsX(CoordUnitsNonPolarTheta coordUnits)
Set method for x units.
CoordUnitsPolarTheta coordUnitsTheta() const
Get method for theta unit.
void setCoordUnitsRadius(CoordUnitsNonPolarTheta coordUnits)
Set method for radius units.
CoordScale coordScaleXTheta() const
Get method for linear/log scale on x/theta.
CoordUnitsNonPolarTheta coordUnitsY() const
Get method for x units.
CoordUnitsTime coordUnitsTime() const
Get method for time format when used.
CoordUnitsNonPolarTheta coordUnitsX() const
Get method for x units.
void setCoordUnitsDate(CoordUnitsDate coordUnits)
Set method for date units.
void setCoordsType(CoordsType coordsType)
Set method for coordinates type.
CoordsType coordsType() const
Get method for coordinates type.
void setCoordScaleXTheta(CoordScale coordScale)
Set method for linear/log scale on x/theta.
void setCoordUnitsTime(CoordUnitsTime coordUnits)
Set method for time units.
void setCoordScaleYRadius(CoordScale coordScale)
Set method for linear/log scale on y/radius.
double originRadius() const
Get method for origin radius in polar mode.
CoordUnitsDate coordUnitsDate() const
Get method for date format when used.
void setCoordUnitsTheta(CoordUnitsPolarTheta coordUnits)
Set method for theta units.
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition Document.cpp:611
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:78
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window,...
Definition ViewPreview.h:15