19 #include "ui_locationdialog.h"
25 #include <QTextStream>
26 #include <QListWidget>
28 #include <kmessagebox.h>
29 #include <kstandarddirs.h>
37 ui =
new Ui::LocationDialog();
38 ui->setupUi( mainWidget() );
40 ui->MapView->setLocationDialog(
this );
42 setCaption( i18n(
"Set Geographic Location" ) );
43 setButtons( KDialog::Ok|KDialog::Cancel );
45 for (
int i=0; i<25; ++i )
46 ui->TZBox->addItem( KGlobal::locale()->formatNumber( (
double)(i-12) ) );
49 foreach(
const QString& key, data->
getRulebook().keys() ) {
51 ui->DSTRuleBox->addItem( key );
54 connect(
this, SIGNAL( cancelClicked() ),
this, SLOT( reject() ) );
55 connect( ui->CityFilter, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
enqueueFilterCity() ) );
56 connect( ui->ProvinceFilter, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
enqueueFilterCity() ) );
57 connect( ui->CountryFilter, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
enqueueFilterCity() ) );
58 connect( ui->NewCityName, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
nameChanged() ) );
59 connect( ui->NewProvinceName, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
nameChanged() ) );
60 connect( ui->NewCountryName, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
nameChanged() ) );
61 connect( ui->NewLong, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
dataChanged() ) );
62 connect( ui->NewLat, SIGNAL( textChanged(
const QString & ) ),
this, SLOT(
dataChanged() ) );
63 connect( ui->TZBox, SIGNAL( activated(
int) ),
this, SLOT(
dataChanged() ) );
64 connect( ui->DSTRuleBox, SIGNAL( activated(
int) ),
this, SLOT(
dataChanged() ) );
65 connect( ui->GeoBox, SIGNAL( itemSelectionChanged () ),
this, SLOT(
changeCity() ) );
66 connect( ui->AddCityButton, SIGNAL( clicked() ),
this, SLOT(
addCity() ) );
67 connect( ui->ClearFieldsButton, SIGNAL( clicked() ),
this, SLOT(
clearFields() ) );
69 ui->DSTLabel->setText(
"<a href=\"showrules\">" + i18n(
"DST Rule:") +
"</a>" );
70 connect( ui->DSTLabel, SIGNAL( linkActivated(
const QString &) ),
this, SLOT(
showTZRules() ) );
74 ui->AddCityButton->setEnabled(
false );
76 ui->NewCityName->setTrapReturnKey(
true);
77 ui->NewProvinceName->setTrapReturnKey(
true);
78 ui->NewCountryName->setTrapReturnKey(
true);
79 ui->CityFilter->setTrapReturnKey(
true);
80 ui->ProvinceFilter->setTrapReturnKey(
true);
81 ui->CountryFilter->setTrapReturnKey(
true);
85 connect(
this,SIGNAL(okClicked()),
this,SLOT(
slotOk()));
97 ui->GeoBox->addItem( loc->
fullName() );
98 filteredCityList.append( loc );
101 if ( loc->
TZ0() - int( loc->
TZ0() ) && ui->TZBox->findText( KGlobal::locale()->formatNumber( loc->
TZ0() ) ) != -1 ) {
102 for (
int i=0; i < ui->TZBox->count(); ++i ) {
103 if ( ui->TZBox->itemText( i ).toDouble() > loc->
TZ0() ) {
104 ui->TZBox->addItem( KGlobal::locale()->formatNumber( loc->
TZ0() ), i-1 );
112 ui->GeoBox->sortItems();
114 ui->CountLabel->setText( i18np(
"One city matches search criteria",
"%1 cities match search criteria", ui->GeoBox->count()) );
117 ui->GeoBox->setCurrentItem( 0 );
118 for(
int i=0; i < ui->GeoBox->count(); i++ ) {
119 if ( ui->GeoBox->item(i)->text() == data->
geo()->
fullName() ) {
120 ui->GeoBox->setCurrentRow( i );
130 timer =
new QTimer(
this );
131 timer->setSingleShot(
true );
132 connect( timer, SIGNAL( timeout() ),
this, SLOT(
filterCity() ) );
141 while( !filteredCityList.isEmpty() )
142 filteredCityList.takeFirst();
144 nameModified =
false;
145 dataModified =
false;
146 ui->AddCityButton->setEnabled(
false );
155 if ( sc.toLower().startsWith( ui->CityFilter->text().toLower() ) &&
156 sp.toLower().startsWith( ui->ProvinceFilter->text().toLower() ) &&
157 ss.toLower().startsWith( ui->CountryFilter->text().toLower() ) ) {
159 ui->GeoBox->addItem( loc->
fullName() );
160 filteredCityList.append( loc );
164 ui->GeoBox->sortItems();
166 ui->CountLabel->setText( i18np(
"One city matches search criteria",
"%1 cities match search criteria", ui->GeoBox->count()) );
168 if ( ui->GeoBox->count() > 0 )
169 ui->GeoBox->setCurrentItem( ui->GeoBox->item(0) );
171 ui->MapView->repaint();
178 if ( ui->GeoBox->currentItem() ) {
179 for (
int i=0; i < filteredCityList.size(); ++i ) {
181 if ( loc->
fullName() == ui->GeoBox->currentItem()->text()) {
188 ui->MapView->repaint();
191 if ( SelectedCity ) {
193 if ( SelectedCity->
province().isEmpty() )
194 ui->NewProvinceName->setText( QString() );
199 ui->NewLong->showInDegrees( SelectedCity->
lng() );
200 ui->NewLat->showInDegrees( SelectedCity->
lat() );
201 ui->TZBox->setEditText( KGlobal::locale()->formatNumber( SelectedCity->
TZ0() ) );
204 for (
int i=0; i < ui->DSTRuleBox->count(); ++i ) {
207 ui->DSTRuleBox->setCurrentIndex( i );
213 nameModified =
false;
214 dataModified =
false;
215 ui->AddCityButton->setEnabled(
false );
220 if ( !nameModified && !dataModified ) {
221 QString message = i18n(
"This City already exists in the database." );
222 KMessageBox::sorry( 0, message, i18n(
"Error: Duplicate Entry" ) );
226 bool latOk(
false), lngOk(
false), tzOk(
false);
227 dms lat = ui->NewLat->createDms(
true, &latOk );
228 dms lng = ui->NewLong->createDms(
true, &lngOk );
229 QString TimeZoneString = ui->TZBox->lineEdit()->text();
230 TimeZoneString.replace( KGlobal::locale()->decimalSymbol(),
"." );
231 double TZ = TimeZoneString.toDouble( &tzOk );
233 if ( ui->NewCityName->text().isEmpty() || ui->NewCountryName->text().isEmpty() ) {
234 QString message = i18n(
"All fields (except province) must be filled to add this location." );
235 KMessageBox::sorry( 0, message, i18n(
"Fields are Empty" ) );
237 }
else if ( ! latOk || ! lngOk ) {
238 QString message = i18n(
"Could not parse the Latitude/Longitude." );
239 KMessageBox::sorry( 0, message, i18n(
"Bad Coordinates" ) );
242 QString message = i18n(
"Could not parse coordinates." );
243 KMessageBox::sorry( 0, message, i18n(
"Bad Coordinates" ) );
246 if ( !nameModified ) {
247 QString message = i18n(
"Really override original data for this city?" );
248 if ( KMessageBox::questionYesNo( 0, message, i18n(
"Override Existing Data?" ), KGuiItem(i18n(
"Override Data")), KGuiItem(i18n(
"Do Not Override"))) == KMessageBox::No )
256 QString name = ui->NewCityName->text().trimmed();
257 QString province = ui->NewProvinceName->text().trimmed();
258 QString country = ui->NewCountryName->text().trimmed();
261 file.setFileName( KStandardDirs::locateLocal(
"appdata",
"mycities.dat" ) );
263 if ( !file.open( QIODevice::ReadWrite | QIODevice::Append ) ) {
264 QString message = i18n(
"Local cities database could not be opened.\nLocation will not be recorded." );
265 KMessageBox::sorry( 0, message, i18n(
"Could Not Open File" ) );
268 char ltsgn =
'N';
if ( lat.
degree()<0 ) ltsgn =
'S';
269 char lgsgn =
'E';
if ( lng.
degree()<0 ) lgsgn =
'W';
270 QString TZrule = ui->DSTRuleBox->currentText();
272 entry = entry.sprintf(
"%-32s : %-21s : %-21s : %2d : %2d : %2d : %c : %3d : %2d : %2d : %c : %5.1f : %2s\n",
273 name.toLocal8Bit().data(), province.toLocal8Bit().data(), country.toLocal8Bit().data(),
276 TZ, TZrule.toLocal8Bit().data() );
284 ui->NewCityName->text(), ui->NewProvinceName->text(), ui->NewCountryName->text(),
285 TZ, &data->Rulebook[ TZrule ] );
287 data->geoList.append( g );
293 ui->GeoBox->setCurrentItem( 0 );
294 if ( ui->GeoBox->count() ) {
295 for (
int i=0; i<ui->GeoBox->count(); i++ ) {
296 if ( ui->GeoBox->item(i)->text() == g->
fullName() ) {
297 ui->GeoBox->setCurrentRow( i );
313 while ( ! filteredCityList.isEmpty() ) filteredCityList.takeFirst();
316 if ( ( abs( lng -
int( loc->
lng()->
Degrees() ) ) < 3 ) &&
317 ( abs( lat -
int( loc->
lat()->
Degrees() ) ) < 3 ) ) {
319 ui->GeoBox->addItem( loc->
fullName() );
320 filteredCityList.append( loc );
324 ui->GeoBox->sortItems();
325 ui->CountLabel->setText( i18np(
"One city matches search criteria",
"%1 cities match search criteria", ui->GeoBox->count()) );
327 if ( ui->GeoBox->count() > 0 )
328 ui->GeoBox->setCurrentItem( ui->GeoBox->item(0) );
333 bool LocationDialog::checkLongLat() {
334 if ( ui->NewLong->text().isEmpty() || ui->NewLat->text().isEmpty() )
338 double lng = ui->NewLong->createDms(
true, &ok).Degrees();
341 double lat = ui->NewLat->createDms(
true, &ok).Degrees();
345 if( fabs(lng) > 180 || fabs(lat) > 90 )
352 ui->CityFilter->clear();
353 ui->ProvinceFilter->clear();
354 ui->CountryFilter->clear();
355 ui->NewCityName->clear();
356 ui->NewProvinceName->clear();
357 ui->NewCountryName->clear();
358 ui->NewLong->clearFields();
359 ui->NewLat->clearFields();
360 ui->TZBox->lineEdit()->setText( KGlobal::locale()->formatNumber( 0.0 ) );
361 ui->DSTRuleBox->setCurrentIndex( 0 );
363 dataModified =
false;
364 ui->AddCityButton->setEnabled(
false );
365 ui->NewCityName->setFocus();
370 lines.append( i18n(
" Start Date (Start Time) / Revert Date (Revert Time)" ) );
372 lines.append( i18n(
"--: No DST correction" ) );
373 lines.append( i18n(
"AU: last Sun in Oct. (02:00) / last Sun in Mar. (02:00)" ) );
374 lines.append( i18n(
"BZ: 2nd Sun in Oct. (00:00) / 3rd Sun in Feb. (00:00)" ) );
375 lines.append( i18n(
"CH: 2nd Sun in Apr. (00:00) / 2nd Sun in Sep. (00:00)" ) );
376 lines.append( i18n(
"CL: 2nd Sun in Oct. (04:00) / 2nd Sun in Mar. (04:00)" ) );
377 lines.append( i18n(
"CZ: 1st Sun in Oct. (02:45) / 3rd Sun in Mar. (02:45)" ) );
378 lines.append( i18n(
"EE: Last Sun in Mar. (00:00) / Last Sun in Oct. (02:00)" ) );
379 lines.append( i18n(
"EG: Last Fri in Apr. (00:00) / Last Thu in Sep. (00:00)" ) );
380 lines.append( i18n(
"EU: Last Sun in Mar. (01:00) / Last Sun in Oct. (01:00)" ) );
381 lines.append( i18n(
"FK: 1st Sun in Sep. (02:00) / 3rd Sun in Apr. (02:00)" ) );
382 lines.append( i18n(
"HK: 2nd Sun in May (03:30) / 3rd Sun in Oct. (03:30)" ) );
383 lines.append( i18n(
"IQ: Apr 1 (03:00) / Oct. 1 (00:00)" ) );
384 lines.append( i18n(
"IR: Mar 21 (00:00) / Sep. 22 (00:00)" ) );
385 lines.append( i18n(
"JD: Last Thu in Mar. (00:00) / Last Thu in Sep. (00:00)" ) );
386 lines.append( i18n(
"LB: Last Sun in Mar. (00:00) / Last Sun in Oct. (00:00)" ) );
387 lines.append( i18n(
"MX: 1st Sun in May (02:00) / Last Sun in Sep. (02:00)" ) );
388 lines.append( i18n(
"NB: 1st Sun in Sep. (02:00) / 1st Sun in Apr. (02:00)" ) );
389 lines.append( i18n(
"NZ: 1st Sun in Oct. (02:00) / 3rd Sun in Mar. (02:00)" ) );
390 lines.append( i18n(
"PY: 1st Sun in Oct. (00:00) / 1st Sun in Mar. (00:00)" ) );
391 lines.append( i18n(
"RU: Last Sun in Mar. (02:00) / Last Sun in Oct. (02:00)" ) );
392 lines.append( i18n(
"SK: 2nd Sun in May (00:00) / 2nd Sun in Oct. (00:00)" ) );
393 lines.append( i18n(
"SY: Apr. 1 (00:00) / Oct. 1 (00:00)" ) );
394 lines.append( i18n(
"TG: 1st Sun in Nov. (02:00) / Last Sun in Jan. (02:00)" ) );
395 lines.append( i18n(
"TS: 1st Sun in Oct. (02:00) / Last Sun in Mar. (02:00)" ) );
396 lines.append( i18n(
"US: 1st Sun in Apr. (02:00) / Last Sun in Oct. (02:00)" ) );
397 lines.append( i18n(
"ZN: Apr. 1 (01:00) / Oct. 1 (00:00)" ) );
399 QString message = i18n(
"Daylight Saving Time Rules" );
402 QPointer<KDialog> tzd =
new KDialog(
this );
403 tzd->setCaption( message );
404 tzd->setButtons( KDialog::Close );
405 QListWidget *lw =
new QListWidget( tzd );
406 lw->addItems( lines );
411 int w = int( 1.1*lw->visualItemRect( lw->item(0) ).width() );
412 lw->setMinimumWidth( w );
413 tzd->setMainWidget( lw );
427 ui->AddCityButton->setEnabled( !ui->NewCityName->text().isEmpty() &&
428 !ui->NewCountryName->text().isEmpty() &&
439 #include "locationdialog.moc"
void initCityList(void)
Initialize list of cities.
KStarsData is the backbone of KStars.
QString translatedName() const
void enqueueFilterCity()
Filter by city / province / country only after a few milliseconds.
void findCitiesNear(int longitude, int latitude)
Show only cities within 3 degrees of point specified by arguments.
static KStarsData * Instance()
const double & Degrees() const
void changeCity()
When the selected city in the QListBox changes, repaint the MapCanvas so that the crosshairs icon app...
This class provides the information needed to determine whether Daylight Savings Time (DST; a...
void filterCity()
When text is entered in the City/Province/Country Filter KLineEdits, the List of cities is trimmed to...
QString translatedProvince() const
const QMap< QString, TimeZoneRule > & getRulebook()
Return map for daylight saving rules.
Contains all relevant information for specifying a location on Earth: City Name, State/Province name...
bool addCity()
When the "Add new city" QPushButton is clicked, add the manually-entered city information to the user...
~LocationDialog()
Destructor (empty)
QList< GeoLocation * > getGeoList()
An angle, stored as degrees, but expressible in many ways.
LocationDialog(QWidget *parent)
Constructor.
QString translatedCountry() const
bool equals(TimeZoneRule *r)