#include #include #include #include #include #include "latlonbox.h" LatLonBox::LatLonBox(QWidget *parent) : QWidget( parent ), m_layout(0), m_degreesSpin(0), m_minutesSpin(0), m_secondsSpin(0), m_degreesLabel(0), m_minutesLabel(0), m_secondsLabel(0) { m_value = 0; m_layout = new QHBoxLayout; setLayout( m_layout ); m_degreesSpin = new QSpinBox; m_degreesSpin->setMinimum( -180 ); m_degreesSpin->setMaximum( 180 ); m_degreesSpin->show(); m_minutesSpin = new QSpinBox; //minimum value is -1 so we can //reduce the next one over m_minutesSpin->setMinimum( -1 ); m_minutesSpin->setMaximum( 60 ); m_minutesSpin->show(); m_secondsSpin = new QSpinBox; m_secondsSpin->setMinimum( -1 ); m_secondsSpin->setMaximum( 60 ); m_secondsSpin->show(); m_degreesLabel = new QLabel( QString::fromUtf8("\u00b0") ); m_minutesLabel = new QLabel( QString("\'") ); m_secondsLabel = new QLabel( QString("\"") ); m_layout->addWidget( m_degreesSpin ); m_layout->addWidget( m_degreesLabel ); m_layout->addWidget( m_minutesSpin ); m_layout->addWidget( m_minutesLabel ); m_layout->addWidget( m_secondsSpin ); m_layout->addWidget( m_secondsLabel ); connect( m_secondsSpin, SIGNAL( valueChanged( int ) ), this, SLOT( secondsOverflow( ) ) ); connect( m_minutesSpin, SIGNAL( valueChanged( int ) ), this, SLOT( minutesOverflow( ) ) ); connect( m_degreesSpin, SIGNAL( valueChanged( int ) ), this, SLOT( recalculate( ) ) ); } void LatLonBox::secondsOverflow() { if( m_secondsSpin->value() == 60 ) { m_secondsSpin->setValue( 0 ); m_minutesSpin->setValue( m_minutesSpin->value() + 1 ); recalculate(); return; } else if( m_secondsSpin->value() == -1 ) { m_secondsSpin->setValue( 59 ); m_minutesSpin->setValue( m_minutesSpin->value() - 1 ); recalculate(); return; } } void LatLonBox::minutesOverflow() { if( m_minutesSpin->value() == 60 ) { m_minutesSpin->setValue( 0 ); m_degreesSpin->setValue( m_degreesSpin->value() + 1 ); recalculate(); return; } else if( m_minutesSpin->value() == -1 ) { m_minutesSpin->setValue( 59 ); m_degreesSpin->setValue( m_degreesSpin->value() - 1 ); recalculate(); return; } } void LatLonBox::setValue( double newvalue ) { m_value = newvalue; reverseRecalculate(); } void LatLonBox::recalculate() { //we need two because if the degrees is neg, //the mins/secs *subtract* from the value if( m_degreesSpin->value() >= 0 ) { double newvalue = m_degreesSpin->value(); newvalue += m_minutesSpin->value() / 60; newvalue += m_secondsSpin->value() / 3600; if( newvalue != m_value ) { m_value = newvalue; emit valueChanged( m_value ); } } else { double newvalue = m_degreesSpin->value(); newvalue -= m_minutesSpin->value() / 60; newvalue -= m_secondsSpin->value() / 3600; if( newvalue != m_value ) { m_value = newvalue; emit valueChanged( m_value ); } } //you can't have 180*59'59" , only 180. if( m_degreesSpin->value() == 180 || m_degreesSpin->value() == -180 ) { m_minutesSpin->setValue( 0 ); m_secondsSpin->setValue( 0 ); } } void LatLonBox::reverseRecalculate() { int degreesvalue = 0; int minutesvalue = 0; int secondsvalue = 0; if( m_value >= 0 ) { //degreesvalue is the whole degree part degreesvalue = floor( m_value ); //minutesremainder is the fraction of a degree that //is left over double minutesremainder = m_value - degreesvalue; //multipy the fraction of a degree by 60 to //turn it into minutes minutesremainder = minutesremainder * 60; //minutesvalue is the whole minutes part minutesvalue = floor( minutesremainder ); //secondsremainder is the fraction of a minute //that is left over double secondsremainder = minutesremainder - minutesvalue; //multiply the fraction of a minute by 60 to //turn it into seconds secondsvalue = secondsremainder * 60; //now we have all the values, we //put them on the boxes. m_degreesSpin->setValue( degreesvalue ); m_minutesSpin->setValue( minutesvalue ); m_secondsSpin->setValue( secondsvalue ); } else { degreesvalue = ceil( m_value ); double minutesremainder = m_value - degreesvalue; minutesremainder = minutesremainder * 60; minutesvalue = ceil( minutesremainder ); double secondsremainder = minutesremainder - minutesvalue; secondsvalue = secondsremainder * 60; m_degreesSpin->setValue( degreesvalue ); m_minutesSpin->setValue( minutesvalue ); m_secondsSpin->setValue( secondsvalue ); } }