13 #include "ui_LatLonEdit.h"
38 class LatLonEditPrivate;
40 class AbstractInputHandler
43 AbstractInputHandler(LatLonEditPrivate *ui) : m_ui(ui) {}
45 virtual ~AbstractInputHandler() {}
48 virtual void setupUi() = 0;
49 virtual void setupMinMax(
Dimension dimension) = 0;
50 virtual void setValue(qreal value) = 0;
51 virtual void handleIntEditChange() = 0;
52 virtual void handleUIntEditChange() = 0;
53 virtual void handleFloatEditChange() = 0;
54 virtual qreal calculateValue()
const = 0;
57 LatLonEditPrivate *
const m_ui;
60 class DecimalInputHandler :
public AbstractInputHandler
63 DecimalInputHandler(LatLonEditPrivate *ui) : AbstractInputHandler(ui) {}
65 virtual void setupUi();
66 virtual void setupMinMax(
Dimension dimension);
67 virtual void setValue(qreal value);
68 virtual void handleIntEditChange();
69 virtual void handleUIntEditChange();
70 virtual void handleFloatEditChange();
71 virtual qreal calculateValue()
const;
74 class DMSInputHandler :
public AbstractInputHandler
77 DMSInputHandler(LatLonEditPrivate *ui) : AbstractInputHandler(ui) {}
79 virtual void setupUi();
80 virtual void setupMinMax(
Dimension dimension);
81 virtual void setValue(qreal value);
82 virtual void handleIntEditChange();
83 virtual void handleUIntEditChange();
84 virtual void handleFloatEditChange();
85 virtual qreal calculateValue()
const;
88 class DMInputHandler :
public AbstractInputHandler
91 DMInputHandler(LatLonEditPrivate *ui) : AbstractInputHandler(ui) {}
93 virtual void setupUi();
94 virtual void setupMinMax(
Dimension dimension);
95 virtual void setValue(qreal value);
96 virtual void handleIntEditChange();
97 virtual void handleUIntEditChange();
98 virtual void handleFloatEditChange();
100 virtual qreal calculateValue()
const;
103 class LatLonEditPrivate :
public Ui::LatLonEditPrivate
105 friend class DecimalInputHandler;
106 friend class DMSInputHandler;
107 friend class DMInputHandler;
113 AbstractInputHandler *m_inputHandler;
122 ~LatLonEditPrivate();
134 void DecimalInputHandler::setupUi()
137 m_ui->m_floatValueEditor->setDecimals(5);
139 m_ui->m_intValueEditor->hide();
140 m_ui->m_uintValueEditor->hide();
143 void DecimalInputHandler::setupMinMax(
Dimension dimension)
145 const qreal maxValue = (dimension ==
Longitude) ? 180.0 : 90.0;
147 m_ui->m_floatValueEditor->setMinimum(-maxValue);
148 m_ui->m_floatValueEditor->setMaximum( maxValue);
151 void DecimalInputHandler::setValue(qreal value)
155 m_ui->m_floatValueEditor->setValue(value);
158 void DecimalInputHandler::handleIntEditChange()
163 void DecimalInputHandler::handleUIntEditChange()
168 void DecimalInputHandler::handleFloatEditChange()
173 qreal DecimalInputHandler::calculateValue()
const
175 qreal value = m_ui->m_floatValueEditor->value();
184 void DMSInputHandler::setupUi()
188 m_ui->m_floatValueEditor->setDecimals(2);
190 m_ui->m_intValueEditor->show();
191 m_ui->m_uintValueEditor->show();
194 void DMSInputHandler::setupMinMax(
Dimension dimension)
196 const int maxValue = (dimension ==
Longitude) ? 180 : 90;
198 m_ui->m_intValueEditor->setMinimum(-maxValue);
199 m_ui->m_intValueEditor->setMaximum( maxValue);
202 void DMSInputHandler::setValue(qreal value)
204 value = qAbs( value );
206 int degValue = (int) value;
208 qreal minFValue = 60 * (value - degValue);
209 int minValue = (int) minFValue;
210 qreal secFValue = 60 * (minFValue - minValue);
212 int secValue = qRound(secFValue);
222 m_ui->m_intValueEditor->setValue( degValue );
223 m_ui->m_uintValueEditor->setValue( minValue );
224 m_ui->m_floatValueEditor->setValue( secFValue );
227 void DMSInputHandler::handleIntEditChange()
229 const int degValue = m_ui->m_intValueEditor->value();
230 const int minDegValue = m_ui->m_intValueEditor->minimum();
231 const int maxDegValue = m_ui->m_intValueEditor->maximum();
233 if (degValue <= minDegValue || maxDegValue <= degValue) {
234 m_ui->m_uintValueEditor->setValue( 0 );
235 m_ui->m_floatValueEditor->setValue( 0.0 );
239 void DMSInputHandler::handleUIntEditChange()
241 const int degValue = m_ui->m_intValueEditor->value();
242 const int minValue = m_ui->m_uintValueEditor->value();
246 m_ui->m_uintValueEditor->setValue( 59 );
247 const int degDec = (degValue > 0) ? 1 : -1;
248 m_ui->m_intValueEditor->setValue( degValue - degDec );
251 m_ui->m_uintValueEditor->setValue( 1 );
254 const int minDegValue = m_ui->m_intValueEditor->minimum();
255 const int maxDegValue = m_ui->m_intValueEditor->maximum();
257 if (degValue <= minDegValue || maxDegValue <= degValue) {
259 m_ui->m_uintValueEditor->setValue( 0 );
261 }
else if (minValue >= 60) {
262 m_ui->m_uintValueEditor->setValue( 0 );
264 if (minDegValue+1 == degValue || degValue == maxDegValue-1) {
266 m_ui->m_floatValueEditor->setValue( 0.0 );
268 const int degInc = (degValue > 0) ? 1 : -1;
269 m_ui->m_intValueEditor->setValue( degValue + degInc );
274 void DMSInputHandler::handleFloatEditChange()
276 const int degValue = m_ui->m_intValueEditor->value();
277 const int minValue = m_ui->m_uintValueEditor->value();
278 const qreal secValue = m_ui->m_floatValueEditor->value();
280 if (secValue < 0.0) {
281 const qreal secDiff = -secValue;
282 if (degValue == 0 && minValue == 0) {
284 m_ui->m_floatValueEditor->setValue( secDiff );
286 m_ui->m_floatValueEditor->setValue( 60.0 - secDiff );
288 m_ui->m_uintValueEditor->setValue( minValue - 1 );
290 m_ui->m_uintValueEditor->setValue( 59 );
291 const int degDec = (degValue > 0) ? 1 : -1;
292 m_ui->m_intValueEditor->setValue( degValue - degDec );
296 const int minDegValue = m_ui->m_intValueEditor->minimum();
297 const int maxDegValue = m_ui->m_intValueEditor->maximum();
299 if (degValue <= minDegValue || maxDegValue <= degValue) {
301 m_ui->m_floatValueEditor->setValue( 0.0 );
303 }
else if (secValue >= 60.0) {
304 qreal newSec = secValue - 60.0;
306 if (minValue == 59) {
307 m_ui->m_uintValueEditor->setValue( 0 );
309 if (minDegValue+1 == degValue || degValue == maxDegValue-1) {
313 const int degInc = (degValue > 0) ? 1 : -1;
314 m_ui->m_intValueEditor->setValue( degValue + degInc );
316 m_ui->m_uintValueEditor->setValue( minValue + 1 );
318 m_ui->m_floatValueEditor->setValue( newSec );
323 qreal DMSInputHandler::calculateValue()
const
325 const bool isNegativeDeg = ( m_ui->m_intValueEditor->value() < 0 );
327 const qreal deg = (qreal)(qAbs(m_ui->m_intValueEditor->value()));
328 const qreal min = (qreal)(m_ui->m_uintValueEditor->value()) / 60.0;
329 const qreal sec = m_ui->m_floatValueEditor->value() / 3600.0;
331 qreal value = deg + min + sec;
343 void DMInputHandler::setupUi()
346 m_ui->m_floatValueEditor->setDecimals(2);
348 m_ui->m_intValueEditor->show();
349 m_ui->m_uintValueEditor->hide();
352 void DMInputHandler::setupMinMax(
Dimension dimension)
354 const int maxValue = (dimension ==
Longitude) ? 180 : 90;
356 m_ui->m_intValueEditor->setMinimum(-maxValue);
357 m_ui->m_intValueEditor->setMaximum( maxValue);
360 void DMInputHandler::setValue(qreal value)
364 int degValue = (int)value;
366 qreal minFValue = 60 * (value - degValue);
368 int minValue = qRound( minFValue );
374 m_ui->m_intValueEditor->setValue( degValue );
375 m_ui->m_floatValueEditor->setValue( minFValue );
378 void DMInputHandler::handleIntEditChange()
380 const int degValue = m_ui->m_intValueEditor->value();
381 const int minDegValue = m_ui->m_intValueEditor->minimum();
382 const int maxDegValue = m_ui->m_intValueEditor->maximum();
384 if (degValue <= minDegValue || maxDegValue <= degValue) {
385 m_ui->m_floatValueEditor->setValue( 0.0 );
389 void DMInputHandler::handleUIntEditChange()
394 void DMInputHandler::handleFloatEditChange()
396 const int degValue = m_ui->m_intValueEditor->value();
397 const qreal minValue = m_ui->m_floatValueEditor->value();
399 if (minValue < 0.0) {
400 const qreal minDiff = -minValue;
403 m_ui->m_floatValueEditor->setValue( minDiff );
405 m_ui->m_floatValueEditor->setValue( 60.0 - minDiff );
406 m_ui->m_intValueEditor->setValue( degValue - 1 );
409 const int minDegValue = m_ui->m_intValueEditor->minimum();
410 const int maxDegValue = m_ui->m_intValueEditor->maximum();
412 if (degValue <= minDegValue || maxDegValue <= degValue) {
414 m_ui->m_floatValueEditor->setValue( 0.0 );
416 }
else if (minValue >= 60.0) {
417 qreal newMin = minValue - 60.0;
419 if (minDegValue+1 == degValue || degValue == maxDegValue-1) {
423 m_ui->m_intValueEditor->setValue( degValue + 1 );
425 m_ui->m_floatValueEditor->setValue( newMin );
430 qreal DMInputHandler::calculateValue()
const
432 const bool isNegativeDeg = ( m_ui->m_intValueEditor->value() < 0 );
434 const qreal deg = (qreal)(qAbs(m_ui->m_intValueEditor->value()));
435 const qreal min = m_ui->m_floatValueEditor->value() / 60.0;
437 qreal value = deg + min;
450 LatLonEditPrivate::LatLonEditPrivate()
454 , m_inputHandler(new DMSInputHandler(this))
458 LatLonEditPrivate::~LatLonEditPrivate()
460 delete m_inputHandler;
463 void LatLonEditPrivate::init(
QWidget* parent) { setupUi(parent); }
468 using namespace Marble;
471 :
QWidget( parent ), d(new LatLonEditPrivate())
477 connect(d->m_intValueEditor, SIGNAL(
valueChanged(
int)),
this, SLOT(checkIntValueOverflow()));
478 connect(d->m_uintValueEditor, SIGNAL(
valueChanged(
int)),
this, SLOT(checkUIntValueOverflow()));
479 connect(d->m_floatValueEditor, SIGNAL(
valueChanged(
double)),
this, SLOT(checkFloatValueOverflow()));
481 connect(d->m_sign, SIGNAL(currentIndexChanged(
int)),
482 this, SLOT(onSignChanged()));
497 return d->m_notation;
500 void LatLonEdit::onSignChanged()
507 if (d->m_value < 0.0) {
511 if (d->m_value > 0.0) {
523 d->m_updating =
true;
525 d->m_inputHandler->setupMinMax(dimension);
533 d->m_sign->addItem(
tr(
"E",
"East, the direction" ) );
534 d->m_sign->addItem(
tr(
"W",
"West, the direction" ) );
537 d->m_sign->addItem(
tr(
"N",
"North, the direction" ) );
538 d->m_sign->addItem(
tr(
"S",
"South, the direction" ) );
543 d->m_updating =
false;
551 delete d->m_inputHandler;
555 d->m_inputHandler =
new DecimalInputHandler(d);
558 d->m_inputHandler =
new DMSInputHandler(d);
561 d->m_inputHandler =
new DMInputHandler(d);
572 d->m_inputHandler->setupUi();
573 d->m_inputHandler->setupMinMax(d->m_dimension);
574 d->m_inputHandler->setValue(d->m_value);
577 void LatLonEdit::checkFloatValueOverflow()
582 d->m_updating =
true;
584 d->m_inputHandler->handleFloatEditChange();
586 d->m_updating =
false;
592 void LatLonEdit::checkUIntValueOverflow()
597 d->m_updating =
true;
599 d->m_inputHandler->handleUIntEditChange();
601 d->m_updating =
false;
606 void LatLonEdit::checkIntValueOverflow()
611 d->m_updating =
true;
613 d->m_inputHandler->handleIntEditChange();
615 d->m_updating =
false;
623 const qreal maxValue = (d->m_dimension ==
Longitude) ? 180.0 : 90.0;
625 if (value > maxValue) {
628 const qreal minValue = -maxValue;
629 if (value < minValue) {
635 if( value == d->m_value ) {
645 d->m_updating =
true;
647 d->m_inputHandler->setValue(value);
649 const bool isNegative = (value < 0.0);
652 d->m_updating =
false;
655 void LatLonEdit::recalculate()
657 d->m_value = d->m_inputHandler->calculateValue();
663 #include "LatLonEdit.moc"
void setValue(qreal newvalue)
A 3d point representation.
GeoDataCoordinates::Notation notation() const
"Decimal" notation (base-10)
Dimension dimension() const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString trUtf8(const char *sourceText, const char *disambiguation, int n)
static void switchSign(QComboBox *sign)
Notation
enum used to specify the notation / numerical system
Dimension
This enum is used to choose the dimension.
LatLonEdit(QWidget *parent=0, Dimension dimension=Longitude, GeoDataCoordinates::Notation notation=GeoDataCoordinates::DMS)
void valueChanged(qreal value)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
"Sexagesimal DMS" notation (base-60)
"Sexagesimal DM" notation (base-60)
void setDimension(Dimension dimension)
void setNotation(GeoDataCoordinates::Notation notation)
< "RA and DEC" notation (used for astronomical sky coordinates)