7#include "ui_LatLonEdit.h"
9#include "MarbleDebug.h"
26 PositiveSphereIndex = 0,
27 NegativeSphereIndex = 1
30class LatLonEditPrivate;
32class AbstractInputHandler
35 explicit AbstractInputHandler(LatLonEditPrivate *ui)
41 virtual ~AbstractInputHandler() =
default;
44 virtual void setupUi() = 0;
45 virtual void setupMinMax(LatLonEdit::Dimension dimension) = 0;
46 virtual void setValue(qreal value) = 0;
47 virtual void handleIntEditChange() = 0;
48 virtual void handleUIntEditChange() = 0;
49 virtual void handleFloatEditChange() = 0;
50 virtual qreal calculateValue()
const = 0;
53 LatLonEditPrivate *
const m_ui;
56class DecimalInputHandler :
public AbstractInputHandler
59 explicit DecimalInputHandler(LatLonEditPrivate *ui)
60 : AbstractInputHandler(ui)
65 void setupUi()
override;
66 void setupMinMax(LatLonEdit::Dimension dimension)
override;
67 void setValue(qreal value)
override;
68 void handleIntEditChange()
override;
69 void handleUIntEditChange()
override;
70 void handleFloatEditChange()
override;
71 qreal calculateValue()
const override;
74class DMSInputHandler :
public AbstractInputHandler
77 explicit DMSInputHandler(LatLonEditPrivate *ui)
78 : AbstractInputHandler(ui)
83 void setupUi()
override;
84 void setupMinMax(LatLonEdit::Dimension dimension)
override;
85 void setValue(qreal value)
override;
86 void handleIntEditChange()
override;
87 void handleUIntEditChange()
override;
88 void handleFloatEditChange()
override;
89 qreal calculateValue()
const override;
92class DMInputHandler :
public AbstractInputHandler
95 explicit DMInputHandler(LatLonEditPrivate *ui)
96 : AbstractInputHandler(ui)
101 void setupUi()
override;
102 void setupMinMax(LatLonEdit::Dimension dimension)
override;
103 void setValue(qreal value)
override;
104 void handleIntEditChange()
override;
105 void handleUIntEditChange()
override;
106 void handleFloatEditChange()
override;
108 qreal calculateValue()
const override;
111class LatLonEditPrivate :
public Ui::LatLonEditPrivate
113 friend class DecimalInputHandler;
114 friend class DMSInputHandler;
115 friend class DMInputHandler;
118 LatLonEdit::Dimension m_dimension;
121 AbstractInputHandler *m_inputHandler;
130 ~LatLonEditPrivate();
136 const bool isNegativeSphere = (sign->
currentIndex() == NegativeSphereIndex);
137 sign->
setCurrentIndex(isNegativeSphere ? PositiveSphereIndex : NegativeSphereIndex);
140void DecimalInputHandler::setupUi()
143 m_ui->m_floatValueEditor->setDecimals(5);
145 m_ui->m_intValueEditor->hide();
146 m_ui->m_uintValueEditor->hide();
149void DecimalInputHandler::setupMinMax(LatLonEdit::Dimension dimension)
151 const qreal maxValue = (dimension == LatLonEdit::Longitude) ? 180.0 : 90.0;
153 m_ui->m_floatValueEditor->setMinimum(-maxValue);
154 m_ui->m_floatValueEditor->setMaximum(maxValue);
157void DecimalInputHandler::setValue(qreal value)
161 m_ui->m_floatValueEditor->setValue(value);
164void DecimalInputHandler::handleIntEditChange()
169void DecimalInputHandler::handleUIntEditChange()
174void DecimalInputHandler::handleFloatEditChange()
179qreal DecimalInputHandler::calculateValue()
const
181 qreal value = m_ui->m_floatValueEditor->value();
183 if (m_ui->m_sign->currentIndex() == NegativeSphereIndex) {
190void DMSInputHandler::setupUi()
194 m_ui->m_floatValueEditor->setDecimals(2);
196 m_ui->m_intValueEditor->show();
197 m_ui->m_uintValueEditor->show();
200void DMSInputHandler::setupMinMax(LatLonEdit::Dimension dimension)
202 const int maxValue = (dimension == LatLonEdit::Longitude) ? 180 : 90;
204 m_ui->m_intValueEditor->setMinimum(-maxValue);
205 m_ui->m_intValueEditor->setMaximum(maxValue);
208void DMSInputHandler::setValue(qreal value)
212 int degValue = (int)value;
214 qreal minFValue = 60 * (value - degValue);
215 int minValue = (int)minFValue;
216 qreal secFValue = 60 * (minFValue - minValue);
218 int secValue = qRound(secFValue);
228 m_ui->m_intValueEditor->setValue(degValue);
229 m_ui->m_uintValueEditor->setValue(minValue);
230 m_ui->m_floatValueEditor->setValue(secFValue);
233void DMSInputHandler::handleIntEditChange()
235 const int degValue = m_ui->m_intValueEditor->value();
236 const int minDegValue = m_ui->m_intValueEditor->minimum();
237 const int maxDegValue = m_ui->m_intValueEditor->maximum();
239 if (degValue <= minDegValue || maxDegValue <= degValue) {
240 m_ui->m_uintValueEditor->setValue(0);
241 m_ui->m_floatValueEditor->setValue(0.0);
245void DMSInputHandler::handleUIntEditChange()
247 const int degValue = m_ui->m_intValueEditor->value();
248 const int minValue = m_ui->m_uintValueEditor->value();
252 m_ui->m_uintValueEditor->setValue(59);
253 const int degDec = (degValue > 0) ? 1 : -1;
254 m_ui->m_intValueEditor->setValue(degValue - degDec);
256 switchSign(m_ui->m_sign);
257 m_ui->m_uintValueEditor->setValue(1);
260 const int minDegValue = m_ui->m_intValueEditor->minimum();
261 const int maxDegValue = m_ui->m_intValueEditor->maximum();
263 if (degValue <= minDegValue || maxDegValue <= degValue) {
265 m_ui->m_uintValueEditor->setValue(0);
267 }
else if (minValue >= 60) {
268 m_ui->m_uintValueEditor->setValue(0);
270 if (minDegValue + 1 == degValue || degValue == maxDegValue - 1) {
272 m_ui->m_floatValueEditor->setValue(0.0);
274 const int degInc = (degValue > 0) ? 1 : -1;
275 m_ui->m_intValueEditor->setValue(degValue + degInc);
280void DMSInputHandler::handleFloatEditChange()
282 const int degValue = m_ui->m_intValueEditor->value();
283 const int minValue = m_ui->m_uintValueEditor->value();
284 const qreal secValue = m_ui->m_floatValueEditor->value();
286 if (secValue < 0.0) {
287 const qreal secDiff = -secValue;
288 if (degValue == 0 && minValue == 0) {
289 switchSign(m_ui->m_sign);
290 m_ui->m_floatValueEditor->setValue(secDiff);
292 m_ui->m_floatValueEditor->setValue(60.0 - secDiff);
294 m_ui->m_uintValueEditor->setValue(minValue - 1);
296 m_ui->m_uintValueEditor->setValue(59);
297 const int degDec = (degValue > 0) ? 1 : -1;
298 m_ui->m_intValueEditor->setValue(degValue - degDec);
302 const int minDegValue = m_ui->m_intValueEditor->minimum();
303 const int maxDegValue = m_ui->m_intValueEditor->maximum();
305 if (degValue <= minDegValue || maxDegValue <= degValue) {
307 m_ui->m_floatValueEditor->setValue(0.0);
309 }
else if (secValue >= 60.0) {
310 qreal newSec = secValue - 60.0;
312 if (minValue == 59) {
313 m_ui->m_uintValueEditor->setValue(0);
315 if (minDegValue + 1 == degValue || degValue == maxDegValue - 1) {
319 const int degInc = (degValue > 0) ? 1 : -1;
320 m_ui->m_intValueEditor->setValue(degValue + degInc);
322 m_ui->m_uintValueEditor->setValue(minValue + 1);
324 m_ui->m_floatValueEditor->setValue(newSec);
329qreal DMSInputHandler::calculateValue()
const
331 const bool isNegativeDeg = (m_ui->m_intValueEditor->value() < 0);
333 const qreal deg = (qreal)(qAbs(m_ui->m_intValueEditor->value()));
334 const qreal min = (qreal)(m_ui->m_uintValueEditor->value()) / 60.0;
335 const qreal sec = m_ui->m_floatValueEditor->value() / 3600.0;
337 qreal value = deg + min + sec;
342 if (m_ui->m_sign->currentIndex() == NegativeSphereIndex) {
349void DMInputHandler::setupUi()
352 m_ui->m_floatValueEditor->setDecimals(2);
354 m_ui->m_intValueEditor->show();
355 m_ui->m_uintValueEditor->hide();
358void DMInputHandler::setupMinMax(LatLonEdit::Dimension dimension)
360 const int maxValue = (dimension == LatLonEdit::Longitude) ? 180 : 90;
362 m_ui->m_intValueEditor->setMinimum(-maxValue);
363 m_ui->m_intValueEditor->setMaximum(maxValue);
366void DMInputHandler::setValue(qreal value)
370 int degValue = (int)value;
372 qreal minFValue = 60 * (value - degValue);
374 int minValue = qRound(minFValue);
380 m_ui->m_intValueEditor->setValue(degValue);
381 m_ui->m_floatValueEditor->setValue(minFValue);
384void DMInputHandler::handleIntEditChange()
386 const int degValue = m_ui->m_intValueEditor->value();
387 const int minDegValue = m_ui->m_intValueEditor->minimum();
388 const int maxDegValue = m_ui->m_intValueEditor->maximum();
390 if (degValue <= minDegValue || maxDegValue <= degValue) {
391 m_ui->m_floatValueEditor->setValue(0.0);
395void DMInputHandler::handleUIntEditChange()
400void DMInputHandler::handleFloatEditChange()
402 const int degValue = m_ui->m_intValueEditor->value();
403 const qreal minValue = m_ui->m_floatValueEditor->value();
405 if (minValue < 0.0) {
406 const qreal minDiff = -minValue;
408 switchSign(m_ui->m_sign);
409 m_ui->m_floatValueEditor->setValue(minDiff);
411 m_ui->m_floatValueEditor->setValue(60.0 - minDiff);
412 m_ui->m_intValueEditor->setValue(degValue - 1);
415 const int minDegValue = m_ui->m_intValueEditor->minimum();
416 const int maxDegValue = m_ui->m_intValueEditor->maximum();
418 if (degValue <= minDegValue || maxDegValue <= degValue) {
420 m_ui->m_floatValueEditor->setValue(0.0);
422 }
else if (minValue >= 60.0) {
423 qreal newMin = minValue - 60.0;
425 if (minDegValue + 1 == degValue || degValue == maxDegValue - 1) {
429 m_ui->m_intValueEditor->setValue(degValue + 1);
431 m_ui->m_floatValueEditor->setValue(newMin);
436qreal DMInputHandler::calculateValue()
const
438 const bool isNegativeDeg = (m_ui->m_intValueEditor->value() < 0);
440 const qreal deg = (qreal)(qAbs(m_ui->m_intValueEditor->value()));
441 const qreal min = m_ui->m_floatValueEditor->value() / 60.0;
443 qreal value = deg + min;
448 if (m_ui->m_sign->currentIndex() == NegativeSphereIndex) {
455LatLonEditPrivate::LatLonEditPrivate()
456 : m_dimension(LatLonEdit::Latitude)
459 , m_inputHandler(new DMSInputHandler(this))
464LatLonEditPrivate::~LatLonEditPrivate()
466 delete m_inputHandler;
469void LatLonEditPrivate::init(
QWidget *parent)
480 , d(new LatLonEditPrivate())
483 setDimension(dimension);
484 setNotation(notation);
493LatLonEdit::~LatLonEdit()
498qreal LatLonEdit::value()
const
505 return d->m_notation;
508void LatLonEdit::onSignChanged()
514 if (d->m_sign->currentIndex() == PositiveSphereIndex) {
515 if (d->m_value < 0.0) {
519 if (d->m_value > 0.0) {
524 Q_EMIT valueChanged(d->m_value);
527void LatLonEdit::setDimension(Dimension dimension)
529 d->m_dimension = dimension;
531 d->m_updating =
true;
533 d->m_inputHandler->setupMinMax(dimension);
541 d->m_sign->addItem(
tr(
"E",
"East, the direction"));
542 d->m_sign->addItem(
tr(
"W",
"West, the direction"));
545 d->m_sign->addItem(
tr(
"N",
"North, the direction"));
546 d->m_sign->addItem(
tr(
"S",
"South, the direction"));
551 d->m_updating =
false;
559 delete d->m_inputHandler;
560 d->m_inputHandler =
nullptr;
564 d->m_inputHandler =
new DecimalInputHandler(d);
567 d->m_inputHandler =
new DMSInputHandler(d);
570 d->m_inputHandler =
new DMInputHandler(d);
572 case GeoDataCoordinates::UTM:
580 if (!d->m_inputHandler) {
583 d->m_inputHandler =
new DecimalInputHandler(d);
586 d->m_notation = notation;
587 d->m_inputHandler->setupUi();
588 d->m_inputHandler->setupMinMax(d->m_dimension);
589 d->m_inputHandler->setValue(d->m_value);
592void LatLonEdit::checkFloatValueOverflow()
597 d->m_updating =
true;
599 d->m_inputHandler->handleFloatEditChange();
601 d->m_updating =
false;
606void LatLonEdit::checkUIntValueOverflow()
611 d->m_updating =
true;
613 d->m_inputHandler->handleUIntEditChange();
615 d->m_updating =
false;
620void LatLonEdit::checkIntValueOverflow()
625 d->m_updating =
true;
627 d->m_inputHandler->handleIntEditChange();
629 d->m_updating =
false;
634void LatLonEdit::setValue(qreal value)
637 const qreal maxValue = (d->m_dimension == Longitude) ? 180.0 : 90.0;
639 if (value > maxValue) {
642 const qreal minValue = -maxValue;
643 if (value < minValue) {
649 if (value == d->m_value) {
659 d->m_updating =
true;
661 d->m_inputHandler->setValue(value);
663 const bool isNegative = (value < 0.0);
664 d->m_sign->setCurrentIndex(isNegative ? NegativeSphereIndex : PositiveSphereIndex);
666 d->m_updating =
false;
669void LatLonEdit::recalculate()
671 d->m_value = d->m_inputHandler->calculateValue();
673 Q_EMIT valueChanged(d->m_value);
676#include "moc_LatLonEdit.cpp"
A 3d point representation.
Notation
enum used to specify the notation / numerical system
@ Astro
< "RA and DEC" notation (used for astronomical sky coordinates)
@ DM
"Sexagesimal DM" notation (base-60)
@ DMS
"Sexagesimal DMS" notation (base-60)
@ Decimal
"Decimal" notation (base-10)
Binds a QML item to a specific geodetic location in screen coordinates.
void currentIndexChanged(int index)
void valueChanged(double d)
QString tr(const char *sourceText, const char *disambiguation, int n)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)