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

Stellarium / stellarium / 6685476185

29 Oct 2023 07:57PM UTC coverage: 11.736% (+0.001%) from 11.735%
6685476185

Pull #3483

github

gzotti
TUI: Add configurable actions for showing dsate/time and object info
Pull Request #3483: TUI fixes

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

14842 of 126463 relevant lines covered (11.74%)

25956.85 hits per line

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

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

20
#include "SatellitesImportDialog.hpp"
21
#include "ui_satellitesImportDialog.h"
22

23
#include "StelApp.hpp"
24
#include "StelGui.hpp"
25
#include "StelModuleMgr.hpp" // for the GETSTELMODULE macro :(
26
#include "StelTranslator.hpp"
27
#include "StelProgressController.hpp"
28

29
#include <QDesktopServices>
30
#include <QFileDialog>
31
#include <QFileInfo>
32
#include <QNetworkReply>
33
#include <QProgressBar>
34
#include <QSortFilterProxyModel>
35
#include <QStandardItemModel>
36
#include <QTemporaryFile>
37
#include <QDir>
38
#include <QStandardPaths>
39

40
SatellitesImportDialog::SatellitesImportDialog()
×
41
        : StelDialog("SatellitesImport")
42
        , isGettingData(false)
×
43
        , numberDownloadsComplete(0)
×
44
        , downloadMgr(nullptr)
×
45
        , progressBar(nullptr)
×
46
        , filterProxyModel(nullptr)
×
47
{
48
        ui = new Ui_satellitesImportDialog;
×
49
        newSatellitesModel = new QStandardItemModel(this);
×
50
}
×
51

52
SatellitesImportDialog::~SatellitesImportDialog()
×
53
{
54
        delete ui;
×
55
        
56
        // Do I need to explicitly delete this?
57
        if (progressBar)
×
58
        {
59
                StelApp::getInstance().removeProgressBar(progressBar);
×
60
                progressBar = nullptr;
×
61
        }
62
        
63
        if (newSatellitesModel)
×
64
        {
65
                newSatellitesModel->clear();
×
66
                delete newSatellitesModel;
×
67
                newSatellitesModel = nullptr;
×
68
        }
69
}
×
70

71
void SatellitesImportDialog::retranslate()
×
72
{
73
        if (dialog)
×
74
        {
75
                ui->retranslateUi(dialog);
×
76
        }
77
}
×
78

79
void SatellitesImportDialog::setVisible(bool visible)
×
80
{
81
        StelDialog::setVisible(visible);
×
82
        if (!isGettingData)
×
83
                getData();
×
84
}
×
85

86
void SatellitesImportDialog::createDialogContent()
×
87
{
88
        ui->setupUi(dialog);
×
89

90
        // Kinetic scrolling
91
        kineticScrollingList << ui->listView;
×
92
        StelGui* gui= dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
93
        if (gui)
×
94
        {
95
                enableKineticScrolling(gui->getFlagUseKineticScrolling());
×
96
                connect(gui, SIGNAL(flagUseKineticScrollingChanged(bool)), this, SLOT(enableKineticScrolling(bool)));
×
97
        }
98

99
        connect(ui->closeStelWindow, SIGNAL(clicked()),
×
100
                this, SLOT(close()));
101
        connect(ui->TitleBar, SIGNAL(movedTo(QPoint)),
×
102
                this, SLOT(handleMovedTo(QPoint)));
103

104
        connect(ui->pushButtonGetData, SIGNAL(clicked()),
×
105
                this, SLOT(getData()));
106
        connect(ui->pushButtonAbort, SIGNAL(clicked()),
×
107
                this, SLOT(abortDownloads()));
108
        connect(ui->pushButtonAdd, SIGNAL(clicked()),
×
109
                this, SLOT(acceptNewSatellites()));
110
        connect(ui->pushButtonDiscard, SIGNAL(clicked()),
×
111
                this, SLOT(discardNewSatellites()));
112
        connect(ui->pushButtonMarkAll, SIGNAL(clicked()),
×
113
                this, SLOT(markAll()));
114
        connect(ui->pushButtonMarkNone, SIGNAL(clicked()),
×
115
                this, SLOT(markNone()));
116
        
117
        filterProxyModel = new QSortFilterProxyModel(this);
×
118
        filterProxyModel->setSourceModel(newSatellitesModel);
×
119
        filterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
×
120
        ui->listView->setModel(filterProxyModel);
×
121
        connect(ui->lineEditSearch, SIGNAL(textChanged(const QString&)),
×
122
                filterProxyModel, SLOT(setFilterFixedString(const QString&)));
×
123
        
124
        reset();
×
125
}
×
126

127
void SatellitesImportDialog::getData()
×
128
{
129
        if (isGettingData)
×
130
                return;
×
131
        isGettingData = true;
×
132
        
133
        if (!downloadMgr)
×
134
        {
135
                downloadMgr = StelApp::getInstance().getNetworkAccessManager();
×
136
                connect(downloadMgr, SIGNAL(finished(QNetworkReply*)),
×
137
                        this, SLOT(receiveDownload(QNetworkReply*)));
138
        }
139
        Satellites* satMgr = GETSTELMODULE(Satellites);
×
140
        
141
        if (satMgr->getUpdatesEnabled())
×
142
        {
143
                sourceUrls = satMgr->getTleSources();                
×
144
                qDeleteAll(sourceFiles);
×
145
                sourceFiles.clear();
×
146
                numberDownloadsComplete = 0;
×
147
                
148
                // Reusing some code from Satellites::updateTLEs()
149
                if (progressBar == nullptr)
×
150
                        progressBar = StelApp::getInstance().addProgressBar();
×
151
                progressBar->setValue(0);
×
152
                progressBar->setRange(0, sourceUrls.size());
×
153
                // TRANSLATORS: The full phrase is 'Loading TLE %VALUE%/%MAX%' in progress bar
154
                progressBar->setFormat(QString("%1 %v/%m").arg(q_("Loading TLE")));
×
155
                
156
                ui->pushButtonGetData->setVisible(false);
×
157
                ui->pushButtonAbort->setVisible(true);
×
158
                ui->groupBoxWorking->setTitle(q_("Downloading data..."));
×
159
                displayMessage(q_("Stellarium is downloading satellite data from the update sources. Please wait..."));
×
160
                
161
                for (int i = 0; i < sourceUrls.size(); i++)
×
162
                {
163
                        QString urlData = sourceUrls.at(i);
×
164
                        QUrl url(urlData.remove("1,", Qt::CaseInsensitive));
×
165
                        QNetworkReply* reply = downloadMgr->get(QNetworkRequest(url));
×
166
                        activeDownloads.append(reply);
×
167
                }
×
168
        }
169
        else
170
        {
171
                QStringList sourceFilePaths;
×
172
                // XXX: we should check that there is at least one home location.
173
                QString homeDirPath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).constFirst();
×
174
                sourceFilePaths = QFileDialog::getOpenFileNames(
×
175
                                      nullptr,
176
                                      q_("Select TLE source file(s)..."),
×
177
                                      homeDirPath, "*.*");
×
178
                if (sourceFilePaths.isEmpty())
×
179
                        return;
×
180
                for (auto &filePath : sourceFilePaths)
×
181
                {
182
                        QFileInfo fileInfo(filePath);
×
183
                        if (fileInfo.exists() && fileInfo.isReadable())
×
184
                        {
185
                                QFile* file = new QFile(filePath);
×
186
                                sourceFiles.append(file);
×
187
                        }
188
                }
×
189
                ui->pushButtonGetData->setVisible(false);
×
190
                ui->pushButtonAbort->setVisible(false);
×
191
                ui->groupBoxWorking->setTitle(q_("Processing data..."));
×
192
                displayMessage(q_("Processing data..."));
×
193
                populateList();
×
194
        }
×
195
}
196

197
void SatellitesImportDialog::receiveDownload(QNetworkReply* networkReply)
×
198
{
199
        Q_ASSERT(networkReply);
×
200
        
201
        // First, check if this one is one of ours
202
        QString url = networkReply->request().url().toString();
×
203
        if (!activeDownloads.contains(networkReply))
×
204
        {
205
                qDebug() << "Satellites: Received URL not in the source list:" << url;
×
206
                return;
×
207
        }
208
        
209
        // An error is a completed download, isn't it?
210
        activeDownloads.removeAll(networkReply);
×
211
        numberDownloadsComplete++;
×
212
        if (progressBar)
×
213
                progressBar->setValue(numberDownloadsComplete);
×
214
        
215
        // Then, see if there was an error...
216
        if (networkReply->error() != QNetworkReply::NoError || networkReply->bytesAvailable()==0)
×
217
        {
218
                qWarning() << "Satellites: failed to download " << url
×
219
                           << networkReply->errorString();
×
220
                return;
×
221
        }
222
        
223
        QTemporaryFile* tmpFile = new QTemporaryFile();
×
224
        if (tmpFile->open())
×
225
        {
226
                tmpFile->write(networkReply->readAll());
×
227
                tmpFile->close();
×
228
                sourceFiles.append(tmpFile);
×
229
        }
230
        else
231
        {
232
                qWarning() << "Satellites: could not save to file" << url;
×
233
        }
234
        
235
        if (numberDownloadsComplete >= sourceUrls.count())
×
236
        {
237
                if (progressBar)
×
238
                {
239
                        StelApp::getInstance().removeProgressBar(progressBar);
×
240
                        progressBar = nullptr;
×
241
                }
242
                
243
                if (sourceFiles.isEmpty())
×
244
                {
245
                        reset();
×
246
                        displayMessage(q_("No data could be downloaded. Try again later."));
×
247
                }
248
                else
249
                {
250
                        ui->pushButtonAbort->setVisible(false);
×
251
                        ui->groupBoxWorking->setTitle(q_("Processing data..."));
×
252
                        displayMessage(q_("Processing data..."));
×
253
                        populateList();
×
254
                }
255
        }
256
        
257
        networkReply->deleteLater();
×
258
}
×
259

260
void SatellitesImportDialog::abortDownloads()
×
261
{
262
        for (int i = 0; i < activeDownloads.count(); i++)
×
263
        {
264
                activeDownloads[i]->abort();
×
265
                activeDownloads[i]->deleteLater();
×
266
        }
267
        reset();
×
268
        displayMessage(q_("Download aborted."));
×
269
}
×
270

271
void SatellitesImportDialog::acceptNewSatellites()
×
272
{
273
        TleDataList satellitesToAdd;
×
274
        for (int row = 0; row < newSatellitesModel->rowCount(); row++)
×
275
        {
276
                QStandardItem* item = newSatellitesModel->item(row);
×
277
                if (item->checkState() == Qt::Checked)
×
278
                {
279
                        QString id = item->data(Qt::UserRole).toString();
×
280
                        satellitesToAdd.append(newSatellites.value(id));
×
281
                }
×
282
        }
283
        emit satellitesAccepted(satellitesToAdd);
×
284
        reset();
×
285
        close();
×
286
}
×
287

288
void SatellitesImportDialog::discardNewSatellites()
×
289
{
290
        reset();
×
291
        close();
×
292
}
×
293

294
void SatellitesImportDialog::markAll()
×
295
{
296
        setCheckState(Qt::Checked);
×
297
}
×
298

299
void SatellitesImportDialog::markNone()
×
300
{
301
        setCheckState(Qt::Unchecked);
×
302
}
×
303

304
void SatellitesImportDialog::reset()
×
305
{
306
        // Assuming that everything that needs to be stopped is stopped
307
        isGettingData = false;
×
308
        ui->stackedWidget->setCurrentIndex(0);
×
309
        ui->pushButtonGetData->setVisible(true);
×
310
        ui->pushButtonAbort->setVisible(false);
×
311
        ui->labelMessage->setVisible(false);
×
312
        ui->labelMessage->clear();
×
313
        ui->groupBoxWorking->setTitle(q_("Get data"));
×
314
        newSatellitesModel->clear();
×
315
        ui->lineEditSearch->clear();
×
316
        
317
        newSatellites.clear();
×
318
        sourceUrls.clear();
×
319
        
320
        qDeleteAll(activeDownloads);
×
321
        activeDownloads.clear();
×
322
        
323
        qDeleteAll(sourceFiles);
×
324
        sourceFiles.clear();
×
325
        
326
        numberDownloadsComplete = 0;
×
327
        if (progressBar)
×
328
        {
329
                StelApp::getInstance().removeProgressBar(progressBar);
×
330
                progressBar = nullptr;
×
331
        }
332
}
×
333

334
void SatellitesImportDialog::populateList()
×
335
{
336
        newSatellites.clear();
×
337
        newSatellitesModel->clear();
×
338
        Satellites* satMgr = GETSTELMODULE(Satellites);
×
339
        
340
        // Load ALL two-line element sets...
341
        for (int f = 0; f < sourceFiles.count(); f++)
×
342
        {
343
                bool open = false;
×
344
                QTemporaryFile* tempFile = dynamic_cast<QTemporaryFile*>(sourceFiles[f]);
×
345
                if (tempFile)
×
346
                        open = tempFile->open();
×
347
                else
348
                        open = sourceFiles[f]->open(QFile::ReadOnly);
×
349
                if (open)
×
350
                {
351
                        satMgr->parseTleFile(*sourceFiles[f], newSatellites);
×
352
                        sourceFiles[f]->close();
×
353
                }
354
                else
355
                {
356
                        qDebug() << "Satellites: cannot open file"
×
357
                                 << QDir::toNativeSeparators(sourceFiles[f]->fileName());
×
358
                }
359
        }
360
        // Clear the disk...
361
        qDeleteAll(sourceFiles);
×
362
        sourceFiles.clear();
×
363
        
364
        QStringList existingIDs = satMgr->listAllIds();
×
365
        QHashIterator<QString,TleData> i(newSatellites);
×
366
        while (i.hasNext())
×
367
        {
368
                i.next();
×
369
                
370
                // Skip duplicates
371
                if (existingIDs.contains(i.key()))
×
372
                        continue;
×
373
                
374
                TleData tle = i.value();                
×
375
                QStandardItem* newItem = new QStandardItem(QString("%1 (NORAD %2)").arg(tle.name, tle.id)); // Available to search via NORAD number
×
376
                newItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
×
377
                newItem->setCheckState(Qt::Unchecked);
×
378
                newItem->setData(tle.id, Qt::UserRole);                
×
379
                newItem->setToolTip(QString(q_("Catalog Number: %1")).arg(tle.id));
×
380
                newSatellitesModel->appendRow(newItem);
×
381
        }
×
382
        existingIDs.clear();
×
383
        newSatellitesModel->sort(0);
×
384
        ui->listView->scrollToTop();
×
385
        ui->stackedWidget->setCurrentIndex(1);
×
386
}
×
387

388
void SatellitesImportDialog::displayMessage(const QString& message)
×
389
{
390
        if (message.isEmpty())
×
391
                return;
×
392
        
393
        ui->labelMessage->setText(message);
×
394
        ui->labelMessage->setVisible(true);
×
395
}
396

397
void SatellitesImportDialog::setCheckState(Qt::CheckState state)
×
398
{
399
        Q_ASSERT(filterProxyModel);
×
400
        
401
        int rowCount = filterProxyModel->rowCount();
×
402
        if (rowCount < 1)
×
403
                return;
×
404

405
        for (int row = 0; row < rowCount; row++)
×
406
        {
407
                QModelIndex proxyIndex = filterProxyModel->index(row, 0);
×
408
                QModelIndex index = filterProxyModel->mapToSource(proxyIndex);
×
409
                QStandardItem * item = newSatellitesModel->itemFromIndex(index);
×
410
                if (item)
×
411
                {
412
                        item->setCheckState(state);
×
413
                }
414
        }
415
}
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