• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 4853788370

pending completion
4853788370

push

github

Alexander V. Wolf
Special patch for John Simple

3 of 3 new or added lines in 3 files covered. (100.0%)

14729 of 125046 relevant lines covered (11.78%)

20166.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/gui/LocationDialog.cpp
1
/*
2
 * Stellarium
3
 * Copyright (C) 2008 Guillaume Chereau
4
 * Copyright (C) 2011 Alexander Wolf
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
19
*/
20

21
#include "Dialog.hpp"
22
#include "LandscapeMgr.hpp"
23
#include "LocationDialog.hpp"
24
#include "StelLocationMgr.hpp"
25
#include "StelMovementMgr.hpp"
26
#include "StelObjectMgr.hpp"
27
#include "ui_locationDialogGui.h"
28
#include "StelApp.hpp"
29
#include "StelCore.hpp"
30

31
#include "StelModuleMgr.hpp"
32
#include "SolarSystem.hpp"
33
#include "StelFileMgr.hpp"
34
#include "StelGui.hpp"
35
#include "StelSkyCultureMgr.hpp"
36
#include "StelProgressController.hpp"
37

38
#include <QSettings>
39
#include <QDebug>
40
#include <QFrame>
41
#include <QSortFilterProxyModel>
42
#include <QTimer>
43
#include <QStringListModel>
44
#include <QTimeZone>
45

46
LocationDialog::LocationDialog(QObject* parent)
×
47
        : StelDialog("Location", parent)
48
        , isEditingNew(false)
×
49
        , updateState(CompleteNoUpdates)
×
50
        , networkManager(nullptr)
×
51
        , downloadReply(nullptr)
×
52
        , progressBar(nullptr)
×
53
        , allModel(nullptr)
×
54
        , pickedModel(nullptr)
×
55
        , proxyModel(nullptr)
×
56
#ifdef ENABLE_GPS
57
        , gpsCount(0)
×
58
#endif
59
{
60
        ui = new Ui_locationDialogForm;
×
61
}
×
62

63
LocationDialog::~LocationDialog()
×
64
{
65
        delete ui;
×
66
}
×
67

68
void LocationDialog::retranslate()
×
69
{
70
        if (dialog)
×
71
        {
72
                ui->retranslateUi(dialog);
×
73
                populatePlanetList();
×
74
                populateRegionList(StelApp::getInstance().getCore()->getCurrentLocation().planetName);
×
75
                populateTimeZonesList();
×
76
                populateTooltips();
×
77
        }
78
}
×
79

80
void LocationDialog::styleChanged(const QString &style)
×
81
{
82
        StelDialog::styleChanged(style);
×
83
        // Make the map red if needed
84
        if (dialog)
×
85
                setMapForLocation(StelApp::getInstance().getCore()->getCurrentLocation());
×
86
}
×
87

88
// Initialize the dialog widgets and connect the signals/slots
89
void LocationDialog::createDialogContent()
×
90
{
91
        // We try to directly connect to the observer slots as much as we can
92
        ui->setupUi(dialog);
×
93

94
        StelApp *app = &StelApp::getInstance();
×
95
        connect(app, SIGNAL(languageChanged()), this, SLOT(retranslate()));
×
96
        connect(app, SIGNAL(flagShowDecimalDegreesChanged(bool)), this, SLOT(setDisplayFormatForSpins(bool)));
×
97
        connect(&app->getSkyCultureMgr(), SIGNAL(currentSkyCultureChanged(QString)), this, SLOT(populatePlanetList(QString)));
×
98
        // Init the SpinBox entries
99
        ui->longitudeSpinBox->setPrefixType(AngleSpinBox::Longitude);
×
100
        ui->longitudeSpinBox->setMinimum(-180.0, true);
×
101
        ui->longitudeSpinBox->setMaximum( 180.0, true);
×
102
        ui->longitudeSpinBox->setWrapping(true);
×
103
        ui->latitudeSpinBox->setPrefixType(AngleSpinBox::Latitude);
×
104
        ui->latitudeSpinBox->setMinimum(-90.0, true);
×
105
        ui->latitudeSpinBox->setMaximum( 90.0, true);
×
106
        ui->latitudeSpinBox->setWrapping(false);
×
107
        setDisplayFormatForSpins(app->getFlagShowDecimalDegrees());
×
108

109
        //initialize list model
110
        allModel = new QStringListModel(this);
×
111
        pickedModel = new QStringListModel(this);
×
112
        StelLocationMgr *locMgr=&(StelApp::getInstance().getLocationMgr());
×
113
        connect(locMgr, SIGNAL(locationListChanged()), this, SLOT(reloadLocations()));
×
114
        reloadLocations();
×
115
        proxyModel = new QSortFilterProxyModel(ui->citiesListView);
×
116
        proxyModel->setSourceModel(allModel);
×
117
        proxyModel->sort(0, Qt::AscendingOrder);
×
118
        proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
×
119
        ui->citiesListView->setModel(proxyModel);
×
120

121
        // Kinetic scrolling
122
        kineticScrollingList << ui->citiesListView;
×
123
        StelGui* gui= dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
124
        if (gui)
×
125
        {
126
                enableKineticScrolling(gui->getFlagUseKineticScrolling());
×
127
                connect(gui, SIGNAL(flagUseKineticScrollingChanged(bool)), this, SLOT(enableKineticScrolling(bool)));
×
128
        }
129

130
        populatePlanetList();        
×
131
        populateTimeZonesList();
×
132

133
        connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&)));
×
134
        connect(ui->citiesListView, SIGNAL(clicked(const QModelIndex&)),
×
135
                this, SLOT(setLocationFromList(const QModelIndex&)));
136

137
        // Connect all the QT signals
138
        connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
×
139
        connect(ui->TitleBar, SIGNAL(movedTo(QPoint)), this, SLOT(handleMovedTo(QPoint)));
×
140
        connect(ui->mapWidget, SIGNAL(positionChanged(double, double)), this, SLOT(setLocationFromMap(double, double)));
×
141

142
        connect(ui->addLocationToListPushButton, SIGNAL(clicked()), this, SLOT(addCurrentLocationToList()));
×
143
        connect(ui->deleteLocationFromListPushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentLocationFromList()));
×
144
        connect(ui->resetListPushButton, SIGNAL(clicked()), this, SLOT(resetLocationList()));
×
145
#if (QT_VERSION>=QT_VERSION_CHECK(5,14,0))
146
        connect(ui->regionNameComboBox, SIGNAL(textActivated(const QString &)), this, SLOT(filterSitesByRegion()));
×
147
#else
148
        connect(ui->regionNameComboBox, SIGNAL(activated(const QString &)), this, SLOT(filterSitesByRegion()));
149
#endif
150

151
        StelCore* core = StelApp::getInstance().getCore();
×
152
        const StelLocation& currentLocation = core->getCurrentLocation();
×
153
        populateRegionList(currentLocation.planetName);
×
154
        bool b = (currentLocation.getID() == core->getDefaultLocationID());
×
155
        QSettings* conf = StelApp::getInstance().getSettings();
×
156
        if (conf->value("init_location/location", "auto").toString() == "auto")
×
157
        {
158
                ui->useIpQueryCheckBox->setChecked(true);
×
159
                b = false;
×
160
        }
161
        updateDefaultLocationControls(b);
×
162

163
        setFieldsFromLocation(currentLocation);
×
164
        if (currentLocation.ianaTimeZone != core->getCurrentTimeZone())
×
165
        {
166
                setTimezone(core->getCurrentTimeZone()); // also sets string customTimeZone and GUI checkbox
×
167
        }
168
        else
169
        {
170
                //ui->timeZoneNameComboBox->setEnabled(false);
171
                // TODO Maybe also:
172
                // StelApp::getInstance().getSettings()->remove("localization/time_zone");
173
        }
174

175
#ifdef ENABLE_GPS
176
#ifdef Q_OS_WIN
177
        ui->gpsToolButton->setText(q_("Get location from GPS or system service"));
178
#else
179
        ui->gpsToolButton->setText(q_("Get location from GPS"));
×
180
#endif
181
        connect(ui->gpsToolButton, SIGNAL(toggled(bool)), this, SLOT(gpsEnableQueryLocation(bool)));
×
182
        ui->gpsToolButton->setStyleSheet(QString("QToolButton{ background: gray; }")); // ? Missing default style?
×
183
        connect(locMgr, SIGNAL(gpsQueryFinished(bool)), this, SLOT(gpsReturn(bool)));
×
184
#else
185
        ui->gpsToolButton->setEnabled(false);
186
        ui->gpsToolButton->hide();
187
#endif
188
        connect(ui->useIpQueryCheckBox, SIGNAL(clicked(bool)), this, SLOT(ipQueryLocation(bool)));
×
189
        connect(ui->useAsDefaultLocationCheckBox, SIGNAL(clicked(bool)), this, SLOT(setDefaultLocation(bool)));
×
190
        connect(ui->pushButtonReturnToDefault, SIGNAL(clicked()), this, SLOT(resetLocationList()));
×
191
        connectBoolProperty(ui->dstCheckBox, "StelCore.flagUseDST");
×
192
        connectBoolProperty(ui->useCustomTimeZoneCheckBox, "StelCore.flagUseCTZ");
×
193
        connect(ui->useCustomTimeZoneCheckBox, SIGNAL(toggled(bool)), ui->timeZoneNameComboBox, SLOT(setEnabled(bool)));
×
194
        ui->timeZoneNameComboBox->setEnabled(core->getUseCustomTimeZone());
×
195
        connect(ui->useCustomTimeZoneCheckBox, SIGNAL(clicked(bool)), this, SLOT(updateTimeZoneControls(bool)));
×
196
        connect(core, SIGNAL(currentTimeZoneChanged(QString)), this, SLOT(setTimezone(QString)));
×
197

198
        connectEditSignals();
×
199

200
        populateTooltips();
×
201

202
        // In case this dialog is called up before going to an "observer", we need to update a few UI elements:
203
        updateFromProgram(core->getCurrentLocation());
×
204
        connect(core, SIGNAL(targetLocationChanged(StelLocation)), this, SLOT(updateFromProgram(StelLocation))); // Fill with actually selected location!
×
205

206
        connect(ui->pushButtonReturnToDefault, &QPushButton::clicked, this, [=]{
×
207
                static StelMovementMgr *mMgr=GETSTELMODULE(StelMovementMgr);
×
208
                static LandscapeMgr *lMgr=GETSTELMODULE(LandscapeMgr);
×
209
                mMgr->setFlagTracking(false);      // break orientation lock
×
210
                this->setLocationUIvisible(true);  // restore UI
×
211
                core->returnToDefaultLocation();
×
212
                mMgr->resetInitViewPos();
×
213
                lMgr->setCurrentLandscapeID(lMgr->getDefaultLandscapeID(), 0.);
×
214
        });
×
215

216
        ui->citySearchLineEdit->setFocus();
×
217

218
        // Set up download manager for checker of updates
219
        //networkManager = StelApp::getInstance().getNetworkAccessManager();
220
        networkManager = new QNetworkAccessManager(this);
×
221
        updateState = CompleteNoUpdates;
×
222
        ui->updateTZFButton->setVisible(locMgr->unknownTimezonesDetected());
×
223
        connect(ui->updateTZFButton, SIGNAL(clicked()), this, SLOT(updateTZF()));
×
224
}
×
225

226
void LocationDialog::setDisplayFormatForSpins(bool flagDecimalDegrees)
×
227
{
228
        int places = 2;
×
229
        AngleSpinBox::DisplayFormat format = AngleSpinBox::DMSSymbols;
×
230
        if (flagDecimalDegrees)
×
231
        {
232
                places = 6;
×
233
                format = AngleSpinBox::DecimalDeg;
×
234
        }
235
        ui->longitudeSpinBox->setDecimals(places);
×
236
        ui->longitudeSpinBox->setDisplayFormat(format);
×
237
        ui->latitudeSpinBox->setDecimals(places);
×
238
        ui->latitudeSpinBox->setDisplayFormat(format);
×
239
}
×
240

241
void LocationDialog::reloadLocations()
×
242
{
243
        allModel->setStringList(StelApp::getInstance().getLocationMgr().getAllMap().keys());
×
244
}
×
245

246
void LocationDialog::populateTooltips()
×
247
{
248
        ui->resetListPushButton->setToolTip(q_("Reset location list to show all known locations"));
×
249
#ifdef Q_OS_WIN
250
        ui->gpsToolButton->setToolTip(QString("<p>%1</p>").arg(q_("Toggle fetching location from GPS or system location service. (Does not change time zone!) When satisfied, toggle off to let other programs access the GPS device.")));
251
#else
252
        ui->gpsToolButton->setToolTip(QString("<p>%1</p>").arg(q_("Toggle fetching GPS location. (Does not change time zone!) When satisfied, toggle off to let other programs access the GPS device.")));
×
253
#endif
254
}
×
255

256
// Update the widget to make sure it is synchrone if the location is changed programmatically
257
void LocationDialog::updateFromProgram(const StelLocation& newLocation)
×
258
{
259
        if (!dialog)
×
260
                return;
×
261

262
        if (newLocation.name.contains("->")) // avoid extra updates
×
263
                return;
×
264

265
        populateRegionList(newLocation.planetName);
×
266
        StelCore* stelCore = StelApp::getInstance().getCore();
×
267

268
        isEditingNew = false;
×
269

270
        // Check that the use as default check box needs to be updated
271
        // Move to setFieldsFromLocation()? --BM?
272
        const bool b = newLocation.getID() == stelCore->getDefaultLocationID();
×
273
        QSettings* conf = StelApp::getInstance().getSettings();
×
274
        if (conf->value("init_location/location", "auto").toString() != ("auto"))
×
275
        {
276
                updateDefaultLocationControls(b);
×
277
                ui->pushButtonReturnToDefault->setEnabled(!b);
×
278
        }
279

280
        if (newLocation.role!='o')
×
281
                GETSTELMODULE(StelMovementMgr)->setFlagTracking(false);
×
282
        setFieldsFromLocation(newLocation);
×
283
        setLocationUIvisible(newLocation.role!='o'); // hide various detail settings when changing to an "observer"
×
284
}
285

286
void LocationDialog::disconnectEditSignals()
×
287
{
288
        disconnect(ui->longitudeSpinBox, SIGNAL(valueChanged()), this, SLOT(setLocationFromCoords()));
×
289
        disconnect(ui->latitudeSpinBox, SIGNAL(valueChanged()), this, SLOT(setLocationFromCoords()));
×
290
        disconnect(ui->altitudeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setLocationFromCoords(int)));
×
291
        disconnect(ui->planetNameComboBox, SIGNAL(currentIndexChanged(const int)), this, SLOT(moveToAnotherPlanet()));
×
292
        disconnect(ui->regionNameComboBox, SIGNAL(currentIndexChanged(const int)), this, SLOT(reportEdit()));
×
293
        disconnect(ui->timeZoneNameComboBox, SIGNAL(currentIndexChanged(const int)), this, SLOT(saveTimeZone()));
×
294
        disconnect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), this, SLOT(reportEdit()));
×
295
}
×
296

297
void LocationDialog::connectEditSignals()
×
298
{
299
        connect(ui->longitudeSpinBox, SIGNAL(valueChanged()), this, SLOT(setLocationFromCoords()));
×
300
        connect(ui->latitudeSpinBox, SIGNAL(valueChanged()), this, SLOT(setLocationFromCoords()));
×
301
        connect(ui->altitudeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setLocationFromCoords(int)));
×
302
        connect(ui->planetNameComboBox, SIGNAL(currentIndexChanged(const int)), this, SLOT(moveToAnotherPlanet()));
×
303
        connect(ui->regionNameComboBox, SIGNAL(currentIndexChanged(const int)), this, SLOT(reportEdit()));
×
304
        connect(ui->timeZoneNameComboBox, SIGNAL(currentIndexChanged(const int)), this, SLOT(saveTimeZone()));
×
305
        connect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), this, SLOT(reportEdit()));
×
306
}
×
307

308
void LocationDialog::setLocationUIvisible(bool visible)
×
309
{
310
        ui->frame_coordinates->setVisible(visible);
×
311
        ui->regionNameComboBox->setVisible(visible);
×
312
        ui->labelRegion->setVisible(visible);
×
313
        ui->cityNameLineEdit->setVisible(visible);
×
314
        ui->labelName->setVisible(visible);
×
315
        ui->frame_citylist->setVisible(visible);
×
316
        ui->mapWidget->setMarkerVisible(visible);
×
317
        ui->addLocationToListPushButton->setVisible(visible);
×
318
        ui->deleteLocationFromListPushButton->setVisible(visible);
×
319
}
×
320

321
void LocationDialog::setFieldsFromLocation(const StelLocation& loc)
×
322
{
323
        StelCore *core = StelApp::getInstance().getCore();
×
324

325
        // Deactivate edit signals
326
        disconnectEditSignals();
×
327

328
        // When user has activated a custom timezone, we should not change this!
329
        if (core->getUseCustomTimeZone())
×
330
                customTimeZone=core->getCurrentTimeZone();
×
331

332
        ui->cityNameLineEdit->setText(loc.name);
×
333
        ui->longitudeSpinBox->setDegrees(loc.getLongitude(true));
×
334
        ui->latitudeSpinBox->setDegrees(loc.getLatitude(true));
×
335
        ui->altitudeSpinBox->setValue(loc.altitude);
×
336

337
        int idx = ui->planetNameComboBox->findData(loc.planetName, Qt::UserRole, Qt::MatchCaseSensitive);
×
338
        if (idx<0)
×
339
        {
340
                // Use Earth as default
341
                idx = ui->planetNameComboBox->findData(QVariant("Earth"), Qt::UserRole, Qt::MatchCaseSensitive);
×
342
        }
343
        ui->planetNameComboBox->setCurrentIndex(idx);
×
344

345
        idx = ui->regionNameComboBox->findData(loc.region, Qt::UserRole, Qt::MatchCaseSensitive);
×
346
        if (idx<0)
×
347
        {
348
                if (ui->planetNameComboBox->currentData(Qt::UserRole).toString()=="Earth")
×
349
                {
350
                        // Use Western Europe as default on Earth
351
                        idx = ui->regionNameComboBox->findData(QVariant("Western Europe"), Qt::UserRole, Qt::MatchCaseSensitive);
×
352
                }
353
                else
354
                        idx = ui->regionNameComboBox->findData(QVariant(""), Qt::UserRole, Qt::MatchCaseSensitive);
×
355
        }
356
        ui->regionNameComboBox->setCurrentIndex(idx);
×
357

358
        QString tz = loc.ianaTimeZone;
×
359
        if (loc.planetName=="Earth" && tz.isEmpty())
×
360
        {
361
                qDebug() << "setFieldsFromLocation(): Empty loc.ianaTimeZone!";
×
362
                tz = "system_default";
×
363
        }
364
        if (loc.planetName!="Earth") // Check for non-terrestial location...
×
365
                tz = "LMST";
×
366

367
        if (core->getUseCustomTimeZone())
×
368
                tz=customTimeZone;
×
369

370
        idx = ui->timeZoneNameComboBox->findData(tz, Qt::UserRole, Qt::MatchCaseSensitive);
×
371
        if (idx==-1)
×
372
        {
373
                if (loc.planetName=="Earth")
×
374
                        tz = "system_default";
×
375
                else
376
                        tz = "LMST";
×
377
                // Use LMST/system_default as default
378
                idx = ui->timeZoneNameComboBox->findData(tz, Qt::UserRole, Qt::MatchCaseSensitive);
×
379
        }
380
        ui->timeZoneNameComboBox->setCurrentIndex(idx);
×
381
        core->setCurrentTimeZone(tz);
×
382

383
        setMapForLocation(loc);
×
384

385
        ui->deleteLocationFromListPushButton->setEnabled(StelApp::getInstance().getLocationMgr().canDeleteUserLocation(loc.getID()));
×
386

387
        SolarSystem* ssm = GETSTELMODULE(SolarSystem);
×
388
        PlanetP p = ssm->searchByEnglishName(loc.planetName);
×
389
        StelModule* ls = StelApp::getInstance().getModule("LandscapeMgr");
×
390
        if (ls->property("flagEnvironmentAutoEnable").toBool())
×
391
        {
392
                if (loc.planetName != core->getCurrentLocation().planetName)
×
393
                {
394
                        QSettings* conf = StelApp::getInstance().getSettings();
×
395
                        ls->setProperty("atmosphereDisplayed", p->hasAtmosphere() && conf->value("landscape/flag_atmosphere", true).toBool());
×
396
                        ls->setProperty("fogDisplayed", p->hasAtmosphere() && conf->value("landscape/flag_fog", true).toBool());
×
397
                }
398
        }
399

400
        // Reactivate edit signals
401
        connectEditSignals();
×
402
}
×
403

404
// Update the map for the given location.
405
void LocationDialog::setMapForLocation(const StelLocation& loc)
×
406
{
407
        // Avoids useless processing
408
        if (lastPlanet!=loc.planetName)
×
409
        {
410
                QPixmap pixmap;
×
411
                // Try to set the proper planet map image
412
                if (loc.planetName=="Earth")
×
413
                {
414
                        // Special case for earth, we don't want to see the clouds
415
                        pixmap = QPixmap(":/graphicGui/miscWorldMap.jpg");
×
416
                }
417
                else
418
                {
419
                        SolarSystem* ssm = GETSTELMODULE(SolarSystem);
×
420
                        PlanetP p = ssm->searchByEnglishName(loc.planetName);
×
421
                        if (p)
×
422
                        {
423
                                QString path = StelFileMgr::findFile("textures/"+p->getTextMapName());
×
424
                                if (path.isEmpty())
×
425
                                {
426
                                        qWarning() << "ERROR - could not find planet map for " << loc.planetName;
×
427
                                        return;
×
428
                                }
429
                                pixmap = QPixmap(path);
×
430
                        }
×
431
                }
×
432
                ui->mapWidget->setMap(pixmap);
×
433
                // For caching
434
                lastPlanet = loc.planetName;
×
435
        }
×
436
        ui->mapWidget->setMarkerPos(loc.getLongitude(), loc.getLatitude());
×
437
}
438

439
void LocationDialog::populatePlanetList()
×
440
{
441
        Q_ASSERT(ui->planetNameComboBox);
×
442
        QComboBox* planetsCombo = ui->planetNameComboBox;
×
443
        SolarSystem* ssystem = GETSTELMODULE(SolarSystem);
×
444
        QList<PlanetP> ssList = ssystem->getAllPlanets();
×
445

446
        //Save the current selection to be restored later
447
        planetsCombo->blockSignals(true);
×
448
        int index = planetsCombo->currentIndex();
×
449
        QVariant selectedPlanetId = planetsCombo->itemData(index);
×
450
        planetsCombo->clear();
×
451
        //For each planet, display the localized name and store the original as user
452
        //data. Unfortunately, there's no other way to do this than with a loop.
453
        for (const auto& p : ssList)
×
454
        {
455
                planetsCombo->addItem(p->getNameI18n(), p->getEnglishName());
×
456
        }
457
        //Restore the selection
458
        index = planetsCombo->findData(selectedPlanetId, Qt::UserRole, Qt::MatchCaseSensitive);
×
459
        planetsCombo->setCurrentIndex(index);
×
460
        planetsCombo->model()->sort(0);
×
461
        planetsCombo->blockSignals(false);
×
462
}
×
463

464
void LocationDialog::populateRegionList(const QString& planet)
×
465
{
466
        Q_ASSERT(ui->regionNameComboBox);
×
467

468
        QComboBox* regionCombo = ui->regionNameComboBox;
×
469
        QStringList regionNames(StelApp::getInstance().getLocationMgr().getRegionNames(planet));
×
470

471
        //Save the current selection to be restored later
472
        regionCombo->blockSignals(true);
×
473
        int index = regionCombo->currentIndex();
×
474
        QVariant selectedRegionId = regionCombo->itemData(index);
×
475
        regionCombo->clear();
×
476
        //For each region, display the localized name and store the original as user
477
        //data. Unfortunately, there's no other way to do this than with a loop.
478
        for (const auto& name : qAsConst(regionNames))
×
479
                regionCombo->addItem(q_(name), name);
×
480

481
        regionCombo->addItem(QChar(0x2014), "");
×
482
        //Restore the selection
483
        index = regionCombo->findData(selectedRegionId, Qt::UserRole, Qt::MatchCaseSensitive);
×
484
        regionCombo->setCurrentIndex(index);
×
485
        regionCombo->model()->sort(0);
×
486
        regionCombo->blockSignals(false);
×
487
}
×
488

489
void LocationDialog::populateTimeZonesList()
×
490
{
491
        Q_ASSERT(ui->timeZoneNameComboBox);
×
492

493
        QComboBox* tzCombo = ui->timeZoneNameComboBox;
×
494
        // Return a list of all the known time zone names (from Qt)
495
        QStringList tzNames;
×
496
        auto tzList = QTimeZone::availableTimeZoneIds(); // System dependent set of IANA timezone names.
×
497
        for (const auto& tz : qAsConst(tzList))
×
498
        {
499
                tzNames.append(tz);
×
500
                // Activate this to get a list of known TZ names...
501
                //qDebug() << "Qt/IANA TZ entry from QTimeZone::available: " << tz;
502
        }
503
        tzNames.sort();
×
504

505
        // Special sort for UTC+XX:YY time zones: we want them
506
        // to go from the most negative to the most positive.
507
        const auto utcRegEx = QRegularExpression("^UTC([+-])(\\d\\d):(\\d\\d)$");
×
508
        std::vector<int> utcOffsets;
×
509
        for(int n = 0; n < tzNames.size();)
×
510
        {
511
                const auto match = utcRegEx.match(tzNames[n]);
×
512
                if(match.lastCapturedIndex() != 3)
×
513
                {
514
                        ++n;
×
515
                        continue;
×
516
                }
517
                tzNames.removeAt(n);
×
518
                const int sign = match.captured(1)=="-" ? -1 : 1;
×
519
                const int hour      = match.captured(2).toInt();
×
520
                const int minute    = match.captured(3).toInt();
×
521
                // Encode with a shift by ±1 to distinguish UTC±00:00
522
                utcOffsets.push_back(sign * (100 * hour + minute + 1));
×
523
        }
×
524
        std::sort(utcOffsets.begin(), utcOffsets.end());
×
525
        for(const auto offset : utcOffsets)
×
526
        {
527
                const auto hm = std::abs(offset) - 1;
×
528
                const auto hour   = hm / 100;
×
529
                const auto minute = hm % 100;
×
530
                tzNames.push_back(QString("UTC%1%2:%3").arg(offset > 0 ? "+" : "-")
×
531
                                                                                           .arg(hour  , 2, 10, QChar('0'))
×
532
                                                                                           .arg(minute, 2, 10, QChar('0')));
×
533
        }
534

535
        if(!utcOffsets.empty())
×
536
        {
537
                // If we have UTC offsets, the Etc/GMT±x time zones are not useful. In
538
                // addition, they'd also need re-sorting, so let's just remove them.
539
                for(int n = 0; n < tzNames.size();)
×
540
                {
541
                        if(tzNames[n].startsWith("Etc/GMT"))
×
542
                                tzNames.removeAt(n);
×
543
                        else
544
                                ++n;
×
545
                }
546
        }
547

548
        //Save the current selection to be restored later
549
        tzCombo->blockSignals(true);
×
550
        int index = tzCombo->currentIndex();
×
551
        QVariant selectedTzId = tzCombo->itemData(index);
×
552
        tzCombo->clear();
×
553
        //For each time zone, display the localized name and store the original as user
554
        //data. Unfortunately, there's no other way to do this than with a loop.
555
        for (const auto& name : tzNames)
×
556
        {
557
                tzCombo->addItem(name, name);
×
558
        }
559
        tzCombo->addItem(q_("Local Mean Solar Time"), "LMST");
×
560
        tzCombo->addItem(q_("Local True Solar Time"), "LTST");
×
561
        tzCombo->addItem(q_("System default"), "system_default");
×
562
        //Restore the selection
563
        index = tzCombo->findData(selectedTzId, Qt::UserRole, Qt::MatchCaseSensitive);
×
564
        if (index==-1) // the TZ is not found
×
565
                index=tzCombo->count()-1; // should point to system_default.
×
566

567
        Q_ASSERT(index!=-1);
×
568
        tzCombo->setCurrentIndex(index);
×
569
        tzCombo->blockSignals(false);
×
570
}
×
571

572
// Create a StelLocation instance from the fields
573
StelLocation LocationDialog::locationFromFields() const
×
574
{
575
        StelLocation loc;
×
576
        int index = ui->planetNameComboBox->currentIndex();
×
577
        if (index < 0)
×
578
        {
579
                qWarning() << "LocationDialog::locationFromFields(): no valid planet name from combo?";
×
580
                loc.planetName = QString("Earth"); //As returned by QComboBox::currentText()
×
581
        }
582
        else
583
                loc.planetName = ui->planetNameComboBox->itemData(index).toString();
×
584
        loc.name = ui->cityNameLineEdit->text().trimmed(); // avoid locations with leading whitespace
×
585
        loc.setLatitude(qBound(-90.0, ui->latitudeSpinBox->valueDegrees(), 90.0));
×
586
        loc.setLongitude(ui->longitudeSpinBox->valueDegrees());
×
587
        loc.altitude = ui->altitudeSpinBox->value();
×
588
        index = ui->regionNameComboBox->currentIndex();
×
589
        if (index < 0)
×
590
        {
591
                qWarning() << "LocationDialog::locationFromFields(): no valid region name from combo?";
×
592
                loc.region = QString();//As returned by QComboBox::currentText()
×
593
        }
594
        else
595
                loc.region = ui->regionNameComboBox->itemData(index).toString();
×
596

597
        index = ui->timeZoneNameComboBox->currentIndex();
×
598
        if (index < 0)
×
599
        {
600
                qWarning() << "LocationDialog::locationFromFields(): no valid timezone name from combo?";
×
601
                loc.ianaTimeZone = QString("UTC"); //Give at least some useful default
×
602
        }
603
        else
604
        {
605
                QString tz=ui->timeZoneNameComboBox->itemData(index).toString();
×
606
                loc.ianaTimeZone = tz;
×
607
        }
×
608
        return loc;
×
609
}
×
610

611
void LocationDialog::setLocationFromList(const QModelIndex& index)
×
612
{
613
        isEditingNew=false;
×
614
        ui->addLocationToListPushButton->setEnabled(false);
×
615
        StelLocation loc = StelApp::getInstance().getLocationMgr().locationForString(index.data().toString());
×
616
        setFieldsFromLocation(loc);
×
617
        StelApp::getInstance().getCore()->moveObserverTo(loc, 0.);
×
618
        // This calls indirectly updateFromProgram()
619
}
×
620

621
void LocationDialog::setLocationFromMap(double longitude, double latitude)
×
622
{
623
        StelCore *core = StelApp::getInstance().getCore();
×
624
        if (core->getUseCustomTimeZone())
×
625
                customTimeZone=core->getCurrentTimeZone();
×
626
        reportEdit();
×
627
        StelLocation loc = locationFromFields();
×
628
        loc.setLatitude(latitude);
×
629
        loc.setLongitude(longitude);
×
630
        loc.name= QString("%1, %2").arg(loc.getLatitude()).arg(loc.getLongitude()); // Force a preliminary name
×
631
        setFieldsFromLocation(loc);
×
632
        core->moveObserverTo(loc, 0.);
×
633
        // Only for locations on Earth: set zone to LMST.
634
        // TODO: Find a way to lookup (lon,lat)->country->timezone.
635

636
        if (core->getUseCustomTimeZone())
×
637
                ui->timeZoneNameComboBox->setCurrentIndex(ui->timeZoneNameComboBox->findData(customTimeZone, Qt::UserRole, Qt::MatchCaseSensitive));
×
638
        else
639
                ui->timeZoneNameComboBox->setCurrentIndex(ui->timeZoneNameComboBox->findData("LMST", Qt::UserRole, Qt::MatchCaseSensitive));
×
640

641
        // Filter location list for nearby sites. I assume Earth locations are better known. With only few locations on other planets in the list, 30 degrees seem OK.
642
        LocationMap results = StelApp::getInstance().getLocationMgr().pickLocationsNearby(loc.planetName, longitude, latitude, loc.planetName=="Earth" ? 5.0f: 30.0f);
×
643
        pickedModel->setStringList(results.keys());
×
644
        proxyModel->setSourceModel(pickedModel);
×
645
        proxyModel->sort(0, Qt::AscendingOrder);
×
646
        ui->citySearchLineEdit->setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F
×
647
}
×
648

649
// Called when the planet name is changed by hand
650
void LocationDialog::moveToAnotherPlanet()
×
651
{
652
        reportEdit();
×
653
        StelLocation loc = locationFromFields();
×
654
        StelCore* stelCore = StelApp::getInstance().getCore();
×
655
        StelModule* lMgr = StelApp::getInstance().getModule("LandscapeMgr");
×
656
        populateRegionList(loc.planetName);
×
657
        if (loc.planetName != stelCore->getCurrentLocation().planetName)
×
658
        {
659
                setFieldsFromLocation(loc);
×
660
                if (lMgr->property("flagLandscapeAutoSelection").toBool())
×
661
                {
662
                        // If we have a landscape for selected planet then set it, otherwise use default landscape
663
                        // Details: https://bugs.launchpad.net/stellarium/+bug/1173254
664
                        if (lMgr->property("allLandscapeNames").toStringList().indexOf(loc.planetName)>0)
×
665
                                lMgr->setProperty("currentLandscapeName", loc.planetName);
×
666
                        else
667
                                lMgr->setProperty("currentLandscapeID", lMgr->property("defaultLandscapeID"));
×
668
                }
669

670
                // populate site list with sites only from that planet, or full list for Earth (faster than removing the ~50 non-Earth positions...).
671
                StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr();
×
672
                if (loc.planetName == "Earth")
×
673
                {
674
                        proxyModel->setSourceModel(allModel);
×
675
                }
676
                else
677
                {
678
                        LocationMap results = locMgr.pickLocationsNearby(loc.planetName, 0.0f, 0.0f, 180.0f);
×
679
                        pickedModel->setStringList(results.keys());
×
680
                        proxyModel->setSourceModel(pickedModel);                        
×
681
                        ui->regionNameComboBox->setCurrentIndex(ui->regionNameComboBox->findData("", Qt::UserRole, Qt::MatchCaseSensitive));
×
682
                        // For 0.19, time zone should not change. When we can work out LMST for other planets, we can accept LMST.
683
                        //if (customTimeZone.isEmpty())  // This is always true!
684
                        //        ui->timeZoneNameComboBox->setCurrentIndex(ui->timeZoneNameComboBox->findData("LMST", Qt::UserRole, Qt::MatchCaseSensitive));
685
                }
×
686
                proxyModel->sort(0, Qt::AscendingOrder);
×
687
                ui->citySearchLineEdit->setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F
×
688
                ui->citySearchLineEdit->setFocus();
×
689

690
                // If we change to an Observer "planet", auto-select and focus on the observed object.
691
                SolarSystem *ss=GETSTELMODULE(SolarSystem);
×
692
                PlanetP planet=nullptr;
×
693
                if (ss)
×
694
                        planet=GETSTELMODULE(SolarSystem)->searchByEnglishName(loc.planetName);
×
695
                if (planet && planet->getPlanetType()==Planet::isObserver)
×
696
                {
697
                        setLocationUIvisible(false);
×
698

699
                        loc.role=QChar('o'); // Mark this ad-hoc location as "observer".
×
700
                        StelObjectMgr *soMgr=GETSTELMODULE(StelObjectMgr);
×
701
                        if (soMgr)
×
702
                        {
703
                                soMgr->findAndSelect(planet->getParent()->getEnglishName());
×
704
                                GETSTELMODULE(StelMovementMgr)->setFlagTracking(true);
×
705
                        }
706
                }
707
                else
708
                {
709
                        GETSTELMODULE(StelMovementMgr)->setFlagTracking(false);
×
710
                        setLocationUIvisible(true);
×
711
                        GETSTELMODULE(StelMovementMgr)->resetInitViewPos();
×
712
                }
713

714
                stelCore->moveObserverTo(loc, 0., 0.);
×
715
        }
×
716
        // Planet transition time also set to null to prevent ugliness when
717
        // "use landscape location" is enabled for that planet's landscape. --BM
718
        // NOTE: I think it also makes sense in the other cases. --BM
719
}
×
720

721
void LocationDialog::setLocationFromCoords(int i)
×
722
{
723
        Q_UNUSED(i)
724
        reportEdit();
×
725
        StelLocation loc = locationFromFields();
×
726
        StelApp::getInstance().getCore()->moveObserverTo(loc, 0.);
×
727
        //Update the position of the map pointer
728
        ui->mapWidget->setMarkerPos(loc.getLongitude(), loc.getLatitude());
×
729
}
×
730

731
void LocationDialog::saveTimeZone()
×
732
{
733
        QString tz = ui->timeZoneNameComboBox->itemData(ui->timeZoneNameComboBox->currentIndex()).toString();
×
734
        StelCore* core = StelApp::getInstance().getCore();
×
735
        core->setCurrentTimeZone(tz);
×
736
        if (core->getUseCustomTimeZone())
×
737
        {
738
                StelApp::getInstance().getSettings()->setValue("localization/time_zone", tz);
×
739
        }
740
}
×
741

742
void LocationDialog::setTimezone(QString tz)
×
743
{
744
        disconnectEditSignals();
×
745

746
        int idx=ui->timeZoneNameComboBox->findData(tz, Qt::UserRole, Qt::MatchCaseSensitive);
×
747
        if (idx>=0)
×
748
        {
749
                ui->timeZoneNameComboBox->setCurrentIndex(idx);
×
750
        }
751
        else
752
        {
753
                qWarning() << "LocationDialog::setTimezone(): invalid name:" << tz;
×
754
        }
755

756
        connectEditSignals();
×
757
}
×
758

759
void LocationDialog::reportEdit()
×
760
{
761
        if (isEditingNew==false)
×
762
        {
763
                // The user starts editing manually a field, this creates automatically a new location
764
                // and allows to save it to the user locations list
765
                isEditingNew=true;
×
766
        }
767

768
        StelLocation loc = locationFromFields();
×
769
        StelLocationMgr& locationMgr = StelApp::getInstance().getLocationMgr();
×
770
        bool canSave = locationMgr.canSaveUserLocation(loc);
×
771
        if (!canSave)
×
772
        {
773
                if (ui->cityNameLineEdit->hasFocus())
×
774
                {
775
                        // The user is editing the location name: don't change it!
776
                        ui->addLocationToListPushButton->setEnabled(false);
×
777
                        ui->deleteLocationFromListPushButton->setEnabled(false);
×
778
                        return;
×
779
                }
780
                else
781
                {
782
                        ui->cityNameLineEdit->setText("");
×
783
                        ui->cityNameLineEdit->selectAll();
×
784
                        loc = locationFromFields();
×
785
                }
786
        }
787
        ui->addLocationToListPushButton->setEnabled(isEditingNew && canSave);
×
788
        ui->deleteLocationFromListPushButton->setEnabled(locationMgr.canDeleteUserLocation(loc.getID()));
×
789
}
×
790

791
// Called when the user clicks on the save button
792
void LocationDialog::addCurrentLocationToList()
×
793
{
794
        const StelLocation& loc = locationFromFields();
×
795
        ui->citySearchLineEdit->setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F
×
796
        StelApp::getInstance().getLocationMgr().saveUserLocation(loc);
×
797
        isEditingNew=false;
×
798
        ui->addLocationToListPushButton->setEnabled(false);
×
799

800
        const QAbstractItemModel* model = ui->citiesListView->model();
×
801
        const QString id = loc.getID();
×
802
        for (int i=0;i<model->rowCount();++i)
×
803
        {
804
                if (model->index(i,0).data()==id)
×
805
                {
806
                        ui->citiesListView->selectionModel()->select(model->index(i,0), QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Rows);
×
807
                        ui->citiesListView->scrollTo(model->index(i,0));
×
808
                        setLocationFromList(model->index(i,0));
×
809
                        disconnectEditSignals();
×
810
                        ui->citySearchLineEdit->setFocus();
×
811
                        connectEditSignals();
×
812
                        break;
×
813
                }
814
        }
815
}
×
816

817
// Called when the user wants to use the current location as default
818
void LocationDialog::setDefaultLocation(bool state)
×
819
{
820
        if (state)
×
821
        {
822
                StelCore* core = StelApp::getInstance().getCore();
×
823
                QString currentLocationId = core->getCurrentLocation().getID();
×
824
                core->setDefaultLocationID(currentLocationId);
×
825

826
                // Why this code even exists? After the previous code, this should always
827
                // be true, except if setting the default location somehow fails. --BM
828
                bool isDefault = (currentLocationId == core->getDefaultLocationID());
×
829
                disconnectEditSignals();
×
830
                updateDefaultLocationControls(isDefault);
×
831
                ui->pushButtonReturnToDefault->setEnabled(!isDefault);
×
832
                ui->useIpQueryCheckBox->setChecked(!state);
×
833
                ui->citySearchLineEdit->setFocus();
×
834
                connectEditSignals();
×
835
        }
×
836
}
×
837

838
// Called when the user clicks on the delete button
839
void LocationDialog::deleteCurrentLocationFromList()
×
840
{
841
        const StelLocation& loc = locationFromFields();
×
842
        StelApp::getInstance().getLocationMgr().deleteUserLocation(loc.getID());
×
843
}
×
844

845
void LocationDialog::updateDefaultLocationControls(bool currentIsDefault)
×
846
{
847
        ui->useAsDefaultLocationCheckBox->setChecked(currentIsDefault);
×
848
        ui->useAsDefaultLocationCheckBox->setEnabled(!currentIsDefault);
×
849
}
×
850

851
void LocationDialog::updateTimeZoneControls(bool useCustomTimeZone)
×
852
{
853
        StelCore* core = StelApp::getInstance().getCore();
×
854
        core->setUseCustomTimeZone(useCustomTimeZone);
×
855

856
        if (useCustomTimeZone)
×
857
        {
858
                saveTimeZone();
×
859
        }
860
        else
861
        {
862
                StelLocation loc = core->getCurrentLocation();
×
863
                QString tz = loc.ianaTimeZone;
×
864
                if (loc.planetName=="Earth" && tz.isEmpty())
×
865
                        tz = "system_default";
×
866
                int idx = ui->timeZoneNameComboBox->findData(tz, Qt::UserRole, Qt::MatchCaseSensitive);
×
867
                if (idx==-1)
×
868
                {
869
                        QString defTZ = "LMST";
×
870
                        if (loc.planetName=="Earth")
×
871
                                defTZ = "system_default";
×
872
                        // Use LMST/system_default as default
873
                        idx = ui->timeZoneNameComboBox->findData(defTZ, Qt::UserRole, Qt::MatchCaseSensitive);
×
874
                }
×
875
                ui->timeZoneNameComboBox->setCurrentIndex(idx);
×
876
                StelApp::getInstance().getSettings()->remove("localization/time_zone");
×
877
                core->setUseCustomTimeZone(false);
×
878
        }
×
879
}
×
880

881
// called when the user clicks on the IP Query button
882
void LocationDialog::ipQueryLocation(bool state)
×
883
{
884
        disconnectEditSignals();
×
885
        resetLocationList(); // in case we are on Moon/Mars, we must get list back to show all (earth) locations...
×
886
        StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr();
×
887
        locMgr.locationFromIP(); // This just triggers asynchronous lookup.
×
888
        // NOTE: These steps seem to assume IP lookup is successful!
889
        ui->useAsDefaultLocationCheckBox->setChecked(!state);
×
890
        ui->pushButtonReturnToDefault->setEnabled(!state);
×
891
        updateTimeZoneControls(!state);
×
892
        connectEditSignals();
×
893
        ui->citySearchLineEdit->setFocus();
×
894
        QSettings* conf = StelApp::getInstance().getSettings();
×
895
        if (state)
×
896
                conf->setValue("init_location/location", "auto");
×
897
        else
898
                conf->setValue("init_location/location", StelApp::getInstance().getCore()->getCurrentLocation().getID());
×
899
}
×
900

901
#ifdef ENABLE_GPS
902
// called when the user toggles the GPS Query button. Use gpsd or Qt's NMEA reader.
903
void LocationDialog::gpsEnableQueryLocation(bool running)
×
904
{
905
        if (running)
×
906
        {
907
                disconnectEditSignals();
×
908
                gpsCount=0;
×
909
                ui->gpsToolButton->setText(q_("GPS listening..."));
×
910
                StelApp::getInstance().getLocationMgr().locationFromGPS(3000);
×
911
        }
912
        else
913
        {
914
                // (edit signals restored by gpsReturn())
915
                StelApp::getInstance().getLocationMgr().locationFromGPS(0);
×
916
                ui->gpsToolButton->setText(q_("GPS disconnecting..."));
×
917
                QTimer::singleShot(1500, this, SLOT(resetGPSbuttonLabel()));
×
918
        }
919
}
×
920

921
void LocationDialog::gpsReturn(bool success)
×
922
{
923
        if (success)
×
924
        {
925
                StelCore* core = StelApp::getInstance().getCore();
×
926

927
                gpsCount++;
×
928
                ui->useAsDefaultLocationCheckBox->setChecked(false);
×
929
                ui->pushButtonReturnToDefault->setEnabled(true);
×
930
                //ui->useCustomTimeZoneCheckBox->setChecked(true); // done by updateTimeZoneControls(true) below.
931
                ui->useIpQueryCheckBox->setChecked(false); // Disable IP query option when GPS is used!
×
932
                resetLocationList(); // in case we come back from Moon/Mars, we must get list back to show all (earth) locations...
×
933
                updateTimeZoneControls(true);
×
934
                StelLocation loc=core->getCurrentLocation();
×
935
                setFieldsFromLocation(loc);
×
936
                if (loc.altitude==0) // give feedback of fix quality.
×
937
                {
938
                        ui->gpsToolButton->setText(QString("%1 %2").arg(q_("2D location fix")).arg(gpsCount));
×
939
                        ui->gpsToolButton->setStyleSheet(QString("QToolButton{ background: yellow; }"));
×
940
                }
941
                else
942
                {
943
                        ui->gpsToolButton->setText(QString("%1 %2").arg(q_("3D location fix")).arg(gpsCount));
×
944
                        ui->gpsToolButton->setStyleSheet(QString("QToolButton{ background: green; }"));
×
945
                }
946
                QSettings* conf = StelApp::getInstance().getSettings();
×
947
                conf->setValue("init_location/location", loc.getID());
×
948
                conf->setValue("init_location/last_location", QString("%1, %2, %3").arg(loc.getLatitude()).arg(loc.getLongitude()).arg(loc.altitude));
×
949
        }
×
950
        else
951
        {
952
                ui->gpsToolButton->setText(q_("GPS:FAILED"));
×
953
                ui->gpsToolButton->setStyleSheet(QString("QToolButton{ background: red; }"));
×
954
                // Use QTimer to reset the labels after 2 seconds.
955
                QTimer::singleShot(2000, this, SLOT(resetGPSbuttonLabel()));
×
956
        }
957
        connectEditSignals();
×
958
        ui->citySearchLineEdit->setFocus();
×
959
}
×
960

961
void LocationDialog::resetGPSbuttonLabel()
×
962
{
963
        ui->gpsToolButton->setChecked(false);
×
964
#ifdef Q_OS_WIN
965
        ui->gpsToolButton->setText(q_("Get location from GPS or system service"));
966
#else
967
        ui->gpsToolButton->setText(q_("Get location from GPS"));
×
968
#endif
969
        ui->gpsToolButton->setStyleSheet(QString("QToolButton{ background: gray; }"));
×
970
}
×
971
#endif
972

973
// called when user clicks "reset list"
974
void LocationDialog::resetLocationList()
×
975
{
976
        //reset search before setting model, prevents unnecessary search in full list
977
        ui->citySearchLineEdit->setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F
×
978
        ui->citySearchLineEdit->setFocus();
×
979
        proxyModel->setSourceModel(allModel);
×
980
        proxyModel->sort(0, Qt::AscendingOrder);
×
981
}
×
982

983
// called when user clicks in the country combobox and selects a country. The locations in the list are updated to select only sites in that country.
984
void LocationDialog::filterSitesByRegion()
×
985
{
986
        QString region=ui->regionNameComboBox->currentData(Qt::UserRole).toString();
×
987
        StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr();
×
988

989
        LocationMap results = locMgr.pickLocationsInRegion(region);
×
990
        pickedModel->setStringList(results.keys());
×
991
        proxyModel->setSourceModel(pickedModel);
×
992
        proxyModel->sort(0, Qt::AscendingOrder);
×
993
        ui->citySearchLineEdit->setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F
×
994
        ui->citySearchLineEdit->setFocus();
×
995
}
×
996

997
void LocationDialog::updateTZF()
×
998
{
999
        if (updateState==LocationDialog::Updating)
×
1000
        {
1001
                qWarning() << "Already updating...  will not start again until current update is complete.";
×
1002
                return;
×
1003
        }
1004

1005
        if (progressBar == Q_NULLPTR)
×
1006
                progressBar = StelApp::getInstance().addProgressBar();
×
1007
        progressBar->setValue(0);
×
1008
        progressBar->setRange(0, 0);
×
1009

1010
        qDebug() << "Updating timezone fixes...";
×
1011

1012
        QSettings* conf = StelApp::getInstance().getSettings();
×
1013
        QUrl URL(conf->value("main/timezone_url", "https://www.stellarium.org/files/timezone.tab").toString());
×
1014
        connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadComplete(QNetworkReply*)));
×
1015
        QNetworkRequest request;
×
1016
        request.setUrl(URL);
×
1017
        request.setRawHeader("User-Agent", StelUtils::getUserAgentString().toUtf8());
×
1018
#if (QT_VERSION<QT_VERSION_CHECK(6,0,0))
1019
        request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
×
1020
#endif
1021
        downloadReply = networkManager->get(request);
×
1022
        connect(downloadReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDownloadProgress(qint64,qint64)));
×
1023

1024
        updateState = LocationDialog::Updating;
×
1025
}
×
1026

1027
void LocationDialog::downloadComplete(QNetworkReply *reply)
×
1028
{
1029
        if (reply == nullptr)
×
1030
                return;
×
1031

1032
        disconnect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadComplete(QNetworkReply*)));
×
1033

1034
        if (reply->error() || reply->bytesAvailable()==0)
×
1035
        {
1036
                qWarning() << "Error: While trying to access"
×
1037
                           << reply->url().toString()
×
1038
                           << "the following error occurred:"
×
1039
                           << reply->errorString();
×
1040

1041
                updateState = LocationDialog::DownloadError;
×
1042
        }
1043
        else
1044
        {
1045
                QByteArray data = reply->readAll();
×
1046
                if (QString(data).endsWith(":EOF")) // Qt5-compatible check
×
1047
                {
1048
                        QString tzfFilePath = StelFileMgr::findFile(StelLocationMgr::getTZFFileName());
×
1049
                        QFile tzfFile(tzfFilePath);
×
1050
                        if (tzfFile.exists())
×
1051
                                tzfFile.remove();
×
1052

1053
                        if (tzfFile.open(QIODevice::WriteOnly | QIODevice::Text))
×
1054
                        {
1055
                                tzfFile.write(data);
×
1056
                                tzfFile.close();
×
1057
                        }
1058
                        qWarning() << "Updating timezone fixes are complete... The new data will be apply on next startup.";
×
1059
                        updateState = LocationDialog::CompleteUpdates;
×
1060
                }
×
1061
                else
1062
                {
1063
                        qWarning() << "Downloaded timezone fixes are not completed, restore the data!";
×
1064
                        updateState = LocationDialog::OtherError;
×
1065
                }
1066
        }
×
1067

1068
        deleteDownloadProgressBar();
×
1069

1070
        reply->deleteLater();
×
1071
        downloadReply = nullptr;
×
1072
        emit updateTZFComplete();
×
1073
}
1074

1075
void LocationDialog::updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
×
1076
{
1077
        if (progressBar == Q_NULLPTR)
×
1078
                return;
×
1079

1080
        int currentValue = 0;
×
1081
        int endValue = 0;
×
1082

1083
        if (bytesTotal > -1 && bytesReceived <= bytesTotal)
×
1084
        {
1085
                //Round to the greatest possible derived unit
1086
                while (bytesTotal > 1024)
×
1087
                {
1088
                        bytesReceived /= 1024;
×
1089
                        bytesTotal    /= 1024;
×
1090
                }
1091
                currentValue = static_cast<int>(bytesReceived);
×
1092
                endValue = static_cast<int>(bytesTotal);
×
1093
        }
1094

1095
        progressBar->setValue(currentValue);
×
1096
        progressBar->setRange(0, endValue);
×
1097
}
1098

1099
void LocationDialog::deleteDownloadProgressBar()
×
1100
{
1101
        disconnect(this, SLOT(updateDownloadProgress(qint64,qint64)));
×
1102

1103
        if (progressBar)
×
1104
        {
1105
                StelApp::getInstance().removeProgressBar(progressBar);
×
1106
                progressBar = Q_NULLPTR;
×
1107
        }
1108
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc