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

Stellarium / stellarium / 6685397774

29 Oct 2023 07:37PM UTC coverage: 11.735% (-0.002%) from 11.737%
6685397774

push

github

10110111
Deduplicate title bar implementation

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

14842 of 126472 relevant lines covered (11.74%)

21617.74 hits per line

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

4.73
/src/gui/ObsListDialog.cpp
1
/*
2
 * Stellarium
3
 * Copyright (C) 2020 Jocelyn GIROD
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (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 along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 */
19

20
#include <QDir>
21
#include <QFileDialog>
22
#include <QMessageBox>
23
#include <QUuid>
24

25
#include "StelTranslator.hpp"
26
#include "StelApp.hpp"
27
#include "StelMainView.hpp"
28
#include "StelObjectMgr.hpp"
29
#include "StelModuleMgr.hpp"
30
#include "StelLocationMgr.hpp"
31
#include "LandscapeMgr.hpp"
32
#include "StelFileMgr.hpp"
33
#include "StelPropertyMgr.hpp"
34
#include "StelMovementMgr.hpp"
35
#include "CustomObjectMgr.hpp"
36
#include "LandscapeMgr.hpp"
37
#include "HighlightMgr.hpp"
38
#include "StarMgr.hpp"
39
#include "NebulaMgr.hpp"
40
#include "StelCore.hpp"
41
#include "StelFileMgr.hpp"
42
#include "StelJsonParser.hpp"
43
#include "StelUtils.hpp"
44
#include "ObsListDialog.hpp"
45
#include "LabelMgr.hpp"
46

47
#include "ui_obsListDialog.h"
48

49
ObsListDialog::ObsListDialog(QObject *parent) :
×
50
        StelDialog("ObservingList", parent),
51
        ui(new Ui_obsListDialogForm()),
×
52
        core(StelApp::getInstance().getCore()),
×
53
        objectMgr(GETSTELMODULE(StelObjectMgr)),
×
54
        landscapeMgr(GETSTELMODULE(LandscapeMgr)),
×
55
        labelMgr(GETSTELMODULE(LabelMgr)),
×
56
        itemModel(new QStandardItemModel(0, ColumnCount)),
×
57
        observingListJsonPath(StelFileMgr::findFile("data", static_cast<StelFileMgr::Flags>(StelFileMgr::Directory | StelFileMgr::Writable)) + "/" + JSON_FILE_NAME),
×
58
        bookmarksJsonPath(    StelFileMgr::findFile("data", static_cast<StelFileMgr::Flags>(StelFileMgr::Directory | StelFileMgr::Writable)) + "/" + JSON_BOOKMARKS_FILE_NAME),
×
59
        tainted(false),
×
60
        isEditMode(false),
×
61
        isCreationMode(false)
×
62
{
63
        setObjectName("ObsListDialog");
×
64
        StelApp::getInstance().getStelPropertyManager()->registerObject(this);
×
65
        //Initialize the list of observing lists
66
        setObservingListHeaderNames();
×
67

68
        QSettings* conf  = StelApp::getInstance().getSettings();
×
69
        flagUseJD        = conf->value("bookmarks/useJD", false).toBool();
×
70
        flagUseLandscape = conf->value("bookmarks/useLandscape", false).toBool();
×
71
        flagUseLocation  = conf->value("bookmarks/useLocation", false).toBool();
×
72
        flagUseFov       = conf->value("bookmarks/useFOV", false).toBool();
×
73
}
×
74

75
ObsListDialog::~ObsListDialog() {
×
76
        // Only on exit we may need to write
77
        if (tainted)
×
78
        {
79
                // At this point we have added our lists to the observingLists map. Now update the jsonMap and store to file.
80
                QFile jsonFile(observingListJsonPath);
×
81
                if (!jsonFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
×
82
                        qWarning() << "[ObservingList] bookmarks list can not be saved. A file can not be open for reading and writing:"
×
83
                                   << QDir::toNativeSeparators(observingListJsonPath);
×
84
                        messageBox(q_("Error"), q_("Cannot open observingLists.json to write"));
×
85
                        return;
×
86
                }
87
                // Update the jsonMap and store
88
                jsonMap.insert(KEY_OBSERVING_LISTS, observingLists);
×
89
                jsonFile.resize(0);
×
90
                StelJsonParser::write(jsonMap, &jsonFile);
×
91
                jsonFile.flush();
×
92
                jsonFile.close();
×
93
        }
×
94

95
        delete ui;
×
96
        delete itemModel;
×
97
        ui = nullptr;
×
98
        itemModel = nullptr;
×
99
}
×
100

101
/*
102
 * Initialize the dialog widgets and connect the signals/slots.
103
*/
104
void ObsListDialog::createDialogContent()
×
105
{
106
        ui->setupUi(dialog);
×
107

108
        //Signals and slots
109
        connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
×
110
        connect(ui->titleBar, &TitleBar::closeClicked, this, &StelDialog::close);
×
111

112
        // Standard mode buttons: NewList/EditList/DeleteList
113
        connect(ui->newListButton,        SIGNAL(clicked()), this, SLOT(   newListButtonPressed()));
×
114
        connect(ui->editListButton,       SIGNAL(clicked()), this, SLOT(  editListButtonPressed()));
×
115
        connect(ui->deleteListButton,     SIGNAL(clicked()), this, SLOT(deleteListButtonPressed()));
×
116
        connect(ui->importListButton,     SIGNAL(clicked()), this, SLOT(importListButtonPressed()));
×
117
        connect(ui->exportListButton,     SIGNAL(clicked()), this, SLOT(exportListButtonPressed()));
×
118
        // Mark all objects of currentList in the sky
119
        connect(ui->highlightAllButton,   SIGNAL(clicked()), this, SLOT(highlightAll()));
×
120
        connect(ui->clearHighlightButton, SIGNAL(clicked()), this, SLOT(clearHighlights()));
×
121
        // Edits
122
        connect(ui->addObjectButton,      SIGNAL(clicked()), this, SLOT(   addObjectButtonPressed()));
×
123
        connect(ui->removeObjectButton,   SIGNAL(clicked()), this, SLOT(removeObjectButtonPressed()));
×
124
        connect(ui->saveButton,           SIGNAL(clicked()), this, SLOT(  saveButtonPressed()));
×
125
        connect(ui->cancelButton,         SIGNAL(clicked()), this, SLOT(cancelButtonPressed()));
×
126

127
        connect(ui->defaultListCheckBox, SIGNAL(clicked(bool)), this, SLOT(defaultClicked(bool)));
×
128

129
        // Allow loading one list entry
130
        connect(ui->treeView,           SIGNAL(doubleClicked(QModelIndex)), this, SLOT(selectAndGoToObject(QModelIndex)));
×
131

132
        switchEditMode(false, false); // start with view mode
×
133

134
        connectBoolProperty(ui->jdCheckBox,        "ObsListDialog.flagUseJD");
×
135
        connectBoolProperty(ui->locationCheckBox,  "ObsListDialog.flagUseLocation");
×
136
        connectBoolProperty(ui->landscapeCheckBox, "ObsListDialog.flagUseLandscape");
×
137
        connectBoolProperty(ui->fovCheckBox,       "ObsListDialog.flagUseFov");
×
138

139
        ui->obsListDirEdit->setText(StelFileMgr::getObsListDir());
×
140
        connect(ui->obsListDirEdit, SIGNAL(editingFinished()), this, SLOT(selectObsListDir()));
×
141
        connect(ui->obsListBrowseButton, SIGNAL(clicked()), this, SLOT(browseForObsListDir()));
×
142

143

144
        //obsListCombo settings: A change in the combobox loads the list.
145
        connect(ui->obsListComboBox, SIGNAL(activated(int)), this, SLOT(loadSelectedObservingList(int)));
×
146

147
        ui->treeView->setModel(itemModel);
×
148
        ui->treeView->header()->setSectionsMovable(false);
×
149
        ui->treeView->hideColumn(ColumnUUID);
×
150
        for (int c=ColumnDesignation; c<=ColumnLandscapeID; c++)
×
151
                ui->treeView->header()->setSectionResizeMode(c, QHeaderView::ResizeToContents);
×
152
        ui->treeView->header()->setStretchLastSection(true);
×
153
        //Enable the sort for columns
154
        ui->treeView->setSortingEnabled(true);
×
155

156
        // Load all observing lists from JSON.
157
        // We need to load the global list only once!
158
        QFile jsonFile(observingListJsonPath);
×
159
        if (!jsonFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
×
160
                qWarning() << "[ObservingList] JSON list file can not be opened for reading and writing:"
×
161
                           << QDir::toNativeSeparators(observingListJsonPath);
×
162
                return;
×
163
        }
164
        if (jsonFile.size() > 0) {
×
165
                jsonMap = StelJsonParser::parse(jsonFile.readAll()).toMap();
×
166
                observingLists = jsonMap.value(KEY_OBSERVING_LISTS).toMap();
×
167
        }
168
        else
169
        {
170
                // begin with empty maps
171
                const QString olud=QUuid::createUuid().toString();
×
172
                jsonMap = { {KEY_SHORT_NAME       , SHORT_NAME_VALUE},
173
                            {KEY_VERSION          , FILE_VERSION},
174
                            {KEY_DEFAULT_LIST_OLUD, olud}};
×
175
                observingLists = QMap<QString, QVariant>();
×
176
                // Create one default empty list
177
                // Creation date
178
                const double JD = StelUtils::getJDFromSystem();
×
179
                const QString listCreationDate = StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " ");
×
180
                QVariantMap emptyList = {
181
                        // Name, description, current date for the list, current sorting
182
                        {KEY_NAME,          qc_("new list", "default name for observing list if none is available")},
×
183
                        {KEY_DESCRIPTION,   QString()},
×
184
                        {KEY_SORTING,       QString()},
×
185
                        {KEY_CREATION_DATE, listCreationDate },
186
                        {KEY_LAST_EDIT,     listCreationDate }};
×
187

188
                observingLists.insert(olud, emptyList);
×
189
                jsonMap.insert(KEY_OBSERVING_LISTS, observingLists);
×
190
        }
×
191

192
        // For no regression we must take into account the legacy bookmarks file
193
        QFile jsonBookmarksFile(bookmarksJsonPath);
×
194
        if (jsonBookmarksFile.exists())
×
195
        {
196
                //qDebug() << "Old Bookmarks found: Try if we need to process/import them";
197
                if (!checkIfBookmarksListExists())
×
198
                {
199
                        //qDebug() << "No bookmark list so far. Importing...";
200
                        QHash<QString, observingListItem> bookmarksForImport=loadBookmarksFile(jsonBookmarksFile);
×
201
                        saveBookmarksHashInObservingLists(bookmarksForImport);
×
202
                        jsonMap.insert(KEY_OBSERVING_LISTS, observingLists); // Update the global map
×
203
                }
×
204
                //else
205
                //        qDebug() << "Bookmark list exists. We can skip the import.";
206

207
                jsonFile.resize(0);
×
208
                StelJsonParser::write(jsonMap, &jsonFile);
×
209
                jsonFile.flush();
×
210
                jsonFile.close();
×
211
                tainted=false;
×
212
        }
213
        // Now we certainly have a json file and have parsed everything that exists.
214
        defaultOlud = jsonMap.value(KEY_DEFAULT_LIST_OLUD).toString();
×
215
        loadListNames(); // also populate Combobox and make sure at least some defaultOlud exists.
×
216
        loadDefaultList();
×
217
}
×
218

219
void ObsListDialog::browseForObsListDir()
×
220
{
221
        const QString &oldObsListDir = StelFileMgr::getObsListDir();
×
222
        QString newObsListDir = QFileDialog::getExistingDirectory(&StelMainView::getInstance(), q_("Select observing lists directory"), oldObsListDir, QFileDialog::ShowDirsOnly);
×
223

224
        if (!newObsListDir.isEmpty()) {
×
225
                // remove trailing slash
226
                if (newObsListDir.right(1) == "/")
×
227
                        newObsListDir = newObsListDir.left(newObsListDir.length()-1);
×
228

229
                ui->obsListDirEdit->setText(newObsListDir);
×
230
                selectObsListDir();
×
231
        }
232
}
×
233

234
void ObsListDialog::selectObsListDir()
×
235
{
236
        QString dir = ui->obsListDirEdit->text();
×
237
        try
238
        {
239
                StelFileMgr::setObsListDir(dir);
×
240
                QSettings* conf = StelApp::getInstance().getSettings();
×
241
                conf->setValue("main/observinglists_dir", dir);
×
242
        }
243
        catch (std::runtime_error& e)
×
244
        {
245
                Q_UNUSED(e)
246
                // nop
247
                // this will happen when people are only half way through typing dirs
248
        }
×
249
}
×
250

251
/*
252
 * Check if bookmarks list already exists in observing list file,
253
 * in fact if the file of bookmarks has already be loaded.
254
*/
255
bool ObsListDialog::checkIfBookmarksListExists()
×
256
{
257
        QMapIterator<QString,QVariant>it(observingLists);
×
258
        while(it.hasNext())
×
259
        {
260
                it.next();
×
261
                QVariantMap map = it.value().toMap();
×
262
                QString listName = map.value(KEY_NAME).toString();
×
263

264
                if (BOOKMARKS_LIST_NAME == listName)
×
265
                        return true;
×
266
        }
×
267
        return false;
×
268
}
×
269

270
/*
271
 * Retranslate dialog
272
*/
273
void ObsListDialog::retranslate()
×
274
{
275
        if (dialog)
×
276
        {
277
                ui->retranslateUi(dialog);
×
278
                setObservingListHeaderNames();
×
279
        }
280
}
×
281

282
/*
283
 * Set the header for the observing list table (obsListTreeView)
284
*/
285
void ObsListDialog::setObservingListHeaderNames()
×
286
{
287
        const QStringList headerStrings = {
288
                "UUID",                     // Hidden column
289
                q_("Object designation"),   // English name and/or catalog number
290
                q_("Object name"),          // Localized name
291
                q_("Type"),                 // Localized type description (not just class name)
292
                q_("Right ascension"),      // J2000.0 RA
293
                q_("Declination"),          // J2000.0 DE
294
                q_("Magnitude"),            // visual magnitude
295
                q_("Constellation"),        // IAU constellation code
296
                q_("Date"),                 // date string (if stored)
297
                q_("Location"),             // location (if stored)
298
                q_("Landscape")             // landscape ID (if stored)
299
        };
×
300
        Q_ASSERT(headerStrings.length()==ColumnCount);
×
301
        itemModel->setHorizontalHeaderLabels(headerStrings);
×
302
}
×
303

304
/*
305
 * Add row in the obsListListModel
306
*/
307
void ObsListDialog::addModelRow(const QString &olud, const QString &designation, const QString &nameI18n,
×
308
                                const QString &typeI18n, const QString &ra,
309
                                const QString &dec, const QString &magnitude, const QString &constellation,
310
                                const QString &date, const QString &location, const QString &landscapeID)
311
{
312
        const int number=itemModel->rowCount();
×
313
        QStandardItem *item = nullptr;
×
314

315
        item = new QStandardItem(olud);
×
316
        item->setEditable(false);
×
317
        itemModel->setItem(number, ColumnUUID, item);
×
318

319
        item = new QStandardItem(designation);
×
320
        item->setEditable(false);
×
321
        itemModel->setItem(number, ColumnDesignation, item);
×
322

323
        item = new QStandardItem(nameI18n);
×
324
        item->setEditable(false);
×
325
        itemModel->setItem(number, ColumnNameI18n, item);
×
326

327
        item = new QStandardItem(typeI18n);
×
328
        item->setEditable(false);
×
329
        itemModel->setItem(number, ColumnType, item);
×
330

331
        item = new QStandardItem(ra);
×
332
        item->setEditable(false);
×
333
        itemModel->setItem(number, ColumnRa, item);
×
334

335
        item = new QStandardItem(dec);
×
336
        item->setEditable(false);
×
337
        itemModel->setItem(number, ColumnDec, item);
×
338

339
        item = new QStandardItem(magnitude);
×
340
        item->setEditable(false);
×
341
        itemModel->setItem(number, ColumnMagnitude, item);
×
342

343
        item = new QStandardItem(constellation);
×
344
        item->setEditable(false);
×
345
        itemModel->setItem(number, ColumnConstellation, item);
×
346

347
        item = new QStandardItem(date);
×
348
        item->setEditable(false);
×
349
        itemModel->setItem(number, ColumnDate, item);
×
350

351
        item = new QStandardItem(location);
×
352
        item->setEditable(false);
×
353
        itemModel->setItem(number, ColumnLocation, item);
×
354

355
        item = new QStandardItem(landscapeID);
×
356
        item->setEditable(false);
×
357
        itemModel->setItem(number, ColumnLandscapeID, item);
×
358

359
        for (int i = 0; i < ColumnCount; ++i)
×
360
                ui->treeView->resizeColumnToContents(i);
×
361
}
×
362

363
/*
364
 * Load the lists names from jsonMap,
365
 * Populate the list names into combo box and extract defaultOlud
366
*/
367
void ObsListDialog::loadListNames()
×
368
{
369
        listNames.clear();
×
370
        QVariantMap::iterator i;
×
371
        for (i = observingLists.begin(); i != observingLists.end(); ++i) {
×
372
                if (i.value().canConvert<QVariantMap>())
×
373
                {
374
                        QVariant var = i.value();
×
375
                        QVariantMap data = var.value<QVariantMap>();
×
376
                        QString listName = data.value(KEY_NAME).toString();
×
377
                        listNames.append(listName);
×
378
                }
×
379
        }
380
        listNames.sort(Qt::CaseInsensitive);
×
381
        ui->obsListComboBox->clear();
×
382
        ui->obsListComboBox->addItems(listNames);
×
383

384
        // Now add the item data into the ComboBox
385
        for (i = observingLists.begin(); i != observingLists.end(); ++i) {
×
386
                const QString &listUuid = i.key();
×
387
                if (i.value().canConvert<QVariantMap>()) // if this looks like an actual obsList?
×
388
                {
389
                        QVariant var = i.value();
×
390
                        auto data = var.value<QVariantMap>();
×
391
                        QString listName = data.value(KEY_NAME).toString();
×
392
                        int idx=ui->obsListComboBox->findText(listName);
×
393
                        Q_ASSERT(idx!=-1);
×
394
                        ui->obsListComboBox->setItemData(idx, listUuid);
×
395
                }
×
396
        }
397
        // If defaultOlud list not found, set first list as default.
398
        if (!observingLists.contains(defaultOlud))
×
399
        {
400
                qDebug() << "populateListNameInComboBox: Cannot find defaultListOlud" << defaultOlud << ". Setting to first list.";
×
401
                defaultOlud = observingLists.firstKey();
×
402
                jsonMap.insert(KEY_DEFAULT_LIST_OLUD, defaultOlud);
×
403
                tainted=true;
×
404
        }
405
}
×
406

407
/*
408
 * Load the default list
409
*/
410
void ObsListDialog::loadDefaultList()
×
411
{
412
        if (defaultOlud != "")
×
413
        {
414
                int index = ui->obsListComboBox->findData(defaultOlud);
×
415
                if (index != -1)
×
416
                {
417
                        ui->obsListComboBox->setCurrentIndex(index);
×
418
                        selectedOlud = defaultOlud;
×
419
                }
420
        }
421
        else
422
        {
423
                // If there is no default list we load the current, or the first list in the combo box
424
                int currentIndex = ui->obsListComboBox->currentIndex();
×
425
                if (currentIndex != -1)
×
426
                {
427
                        currentIndex=0;
×
428
                        ui->obsListComboBox->setCurrentIndex(0);
×
429
                }
430
                selectedOlud = ui->obsListComboBox->itemData(currentIndex).toString();
×
431
                defaultOlud = selectedOlud;
×
432
                jsonMap.insert(KEY_DEFAULT_LIST_OLUD, defaultOlud);
×
433
                tainted=true;
×
434
        }
435
        loadSelectedList();
×
436
}
×
437

438
/*
439
 * Load the selected observing list (selectedOlud) into the dialog.
440
*/
441
void ObsListDialog::loadSelectedList()
×
442
{
443
        // At this point selectedOlud must be set
444
        Q_ASSERT(selectedOlud.length()>0);
×
445

446
        // We must keep selection for the user. It is not enough to store/restore the existingSelection.
447
        // The QList<StelObjectP> objects are apparently volatile. We must retrieve the actual object.
448
        const QList<StelObjectP>&existingSelection = objectMgr->getSelectedObject();
×
449
        QList<StelObjectP> existingSelectionToRestore;
×
450
        if (existingSelection.length()>0)
×
451
        {
452
                existingSelectionToRestore.append(existingSelection.at(0));
×
453
        }
454

455
        // Check or not default list checkbox information
456
        ui->defaultListCheckBox->setChecked(selectedOlud == defaultOlud);
×
457

458
        QVariantMap observingListMap = observingLists.value(selectedOlud).toMap();
×
459
        QVariantList listOfObjects;
×
460

461
        // Display description and creation date
462
        currentListName=observingListMap.value(KEY_NAME).toString();
×
463
        ui->listNameLineEdit->setText(currentListName);
×
464
        ui->descriptionLineEdit->setText(observingListMap.value(KEY_DESCRIPTION).toString());
×
465
        ui->creationDateLineEdit->setText(observingListMap.value(KEY_CREATION_DATE).toString());
×
466
        ui->lastEditLineEdit->setText(observingListMap.value(KEY_LAST_EDIT, observingListMap.value(KEY_CREATION_DATE)).toString());
×
467

468
        if (observingListMap.value(KEY_OBJECTS).canConvert<QVariantList>())
×
469
        {
470
                QVariant data = observingListMap.value(KEY_OBJECTS);
×
471
                listOfObjects = data.value<QVariantList>();
×
472
        }
×
473
        else
474
                qCritical() << "[ObservingList] conversion error";
×
475

476
        // Clear model
477
        itemModel->removeRows(0, itemModel->rowCount()); // don't use clear() here!
×
478
        currentItemCollection.clear();
×
479

480
        if (!listOfObjects.isEmpty())
×
481
        {
482
                for (const QVariant &object: listOfObjects)
×
483
                {
484
                        if (object.canConvert<QVariantMap>())
×
485
                        {
486
                                QVariantMap objectMap = object.value<QVariantMap>();
×
487

488
                                observingListItem item;
×
489
                                const QString objectUUID = QUuid::createUuid().toString();
×
490
                                item.designation = objectMap.value(KEY_DESIGNATION).toString();  // This is the common name or catalog number (with catalog ID)
×
491
                                item.name = objectMap.value(KEY_NAME).toString();          // Preliminary: Do not rely on name in the JSON file. It may have changed in Stellarium's name lists! Retrieve name from the actual object later.
×
492
                                item.nameI18n = objectMap.value(KEY_NAME_I18N).toString(); // Preliminary: Do not rely on translated name in the JSON file. It may be in the wrong language or may have changed in Stellarium's name lists! Retrieve translated name from the actual object later.
×
493
                                item.objClass = objectMap.value(KEY_TYPE).toString();
×
494
                                item.objTypeI18n  = objectMap.value(KEY_OBJECTS_TYPE).toString(); // Preliminary: Do not rely on this translated string! Re-retrieve later
×
495
                                item.ra  = objectMap.value(KEY_RA).toString();
×
496
                                item.dec = objectMap.value(KEY_DEC).toString();
×
497

498
                                if (objectMgr->findAndSelect(item.designation, item.objClass) && !objectMgr->getSelectedObject().isEmpty())
×
499
                                {
500
                                        //qDebug() << "ObsList: found an object of objClass" << item.objClass << "for" << item.designation;
501
                                        const QList<StelObjectP> &selectedObject = objectMgr->getSelectedObject();
×
502
                                        double ra, dec;
503
                                        StelUtils::rectToSphe(&ra, &dec, selectedObject[0]->getJ2000EquatorialPos(core));
×
504

505
                                        if (item.ra.isEmpty())
×
506
                                                item.ra = StelUtils::radToHmsStr(ra, false).trimmed();
×
507
                                        if (item.dec.isEmpty())
×
508
                                                item.dec = StelUtils::radToDmsStr(dec, false).trimmed();
×
509
                                        item.objTypeI18n = selectedObject[0]->getObjectTypeI18n();
×
510
                                        item.name=selectedObject[0]->getEnglishName();
×
511
                                        item.nameI18n=selectedObject[0]->getNameI18n();
×
512
                                }
513
                                else // THEREFORE: repeat the same code with findAndSelect with any type.
514
                                        if (objectMgr->findAndSelect(item.designation) && !objectMgr->getSelectedObject().isEmpty())
×
515
                                {
516
                                        const QList<StelObjectP> &selectedObject = objectMgr->getSelectedObject();
×
517
                                        double ra, dec;
518
                                        StelUtils::rectToSphe(&ra, &dec, selectedObject[0]->getJ2000EquatorialPos(core));
×
519

520
                                        if (item.ra.isEmpty())
×
521
                                                item.ra = StelUtils::radToHmsStr(ra, false).trimmed();
×
522
                                        if (item.dec.isEmpty())
×
523
                                                item.dec = StelUtils::radToDmsStr(dec, false).trimmed();
×
524
                                        //qDebug() << "Changing item.objClass " << item.objClass << "to" << selectedObject[0]->getType();
525
                                        item.objClass = selectedObject[0]->getType();
×
526
                                        item.objTypeI18n = selectedObject[0]->getObjectTypeI18n();
×
527
                                        item.name=selectedObject[0]->getEnglishName();
×
528
                                        item.nameI18n=selectedObject[0]->getNameI18n();
×
529
                                }
530
                                else
531
                                {
532
                                        qWarning() << "[ObservingList] object: " << item.designation << " not found or empty. Cannot set item.objClass !";
×
533
                                        qWarning() << "item.objType given as:" << item.objTypeI18n;
×
534
                                }
535

536
                                item.magnitude = objectMap.value(KEY_MAGNITUDE).toString();
×
537
                                item.constellation = objectMap.value(KEY_CONSTELLATION).toString();
×
538

539
                                // Julian Day / Date
540
                                item.jd = objectMap.value(KEY_JD).toDouble();
×
541
                                QString dateStr;
×
542
                                if (item.jd != 0.)
×
543
                                        dateStr = StelUtils::julianDayToISO8601String(item.jd + core->getUTCOffset(item.jd) / 24.).replace("T", " ");
×
544

545
                                // Location, landscapeID, FoV (may be empty)
546
                                item.location = objectMap.value(KEY_LOCATION).toString();
×
547
                                item.landscapeID = objectMap.value(KEY_LANDSCAPE_ID).toString();
×
548
                                item.fov = objectMap.value(KEY_FOV).toDouble();
×
549

550
                                // Visible flag
551
                                item.isVisibleMarker = objectMap.value(KEY_IS_VISIBLE_MARKER).toBool();
×
552

553
                                QString LocationStr;
×
554
                                if (!item.location.isEmpty())
×
555
                                {
556
                                        StelLocation loc=StelApp::getInstance().getLocationMgr().locationForString(item.location);
×
557
                                        LocationStr=loc.name;
×
558
                                }
×
559

560
                                addModelRow(objectUUID,
×
561
                                            item.designation,
562
                                            item.nameI18n,
563
                                            item.objTypeI18n,
564
                                            item.ra,
565
                                            item.dec,
566
                                            item.magnitude,
567
                                            item.constellation,
568
                                            dateStr,
569
                                            LocationStr,
570
                                            item.landscapeID);
571

572
                                currentItemCollection.insert(objectUUID, item);
×
573
                        }
×
574
                        else
575
                        {
576
                                qCritical() << "[ObservingList] conversion error";
×
577
                                return;
×
578
                        }
579
                }
580
        }
581

582
        // Sorting for the objects list.
583
        QString sortingBy = observingListMap.value(KEY_SORTING).toString();
×
584
        if (!sortingBy.isEmpty())
×
585
                sortObsListTreeViewByColumnName(sortingBy);
×
586

587
        // Restore selection that was active before calling this
588
        if (existingSelectionToRestore.length()>0)
×
589
                objectMgr->setSelectedObject(existingSelectionToRestore, StelModule::ReplaceSelection);
×
590
        else
591
                objectMgr->unSelect();
×
592
}
×
593

594
/*
595
 * Load the bookmarks of bookmarks.json file into observing lists file
596
*/
597
QHash<QString, ObsListDialog::observingListItem> ObsListDialog::loadBookmarksFile(QFile &file)
×
598
{
599
        //qDebug() << "LOADING OLD BOOKMARKS...";
600

601
        QHash<QString, observingListItem> bookmarksItemHash;
×
602

603
        if (!file.open(QIODevice::ReadOnly)) {
×
604
                qWarning() << "[ObservingList] cannot open" << QDir::toNativeSeparators(bookmarksJsonPath);
×
605
        }
606
        else
607
        {
608
                const double currentJD=core->getJDOfLastJDUpdate();// Restore at end
×
609
                const qint64 millis = core->getMilliSecondsOfLastJDUpdate();
×
610

611
                // We must keep selection for the user!
612
                const QList<StelObjectP>&existingSelection = objectMgr->getSelectedObject();
×
613
                QList<StelObjectP> existingSelectionToRestore;
×
614
                if (existingSelection.length()>0)
×
615
                {
616
                        existingSelectionToRestore.append(existingSelection.at(0));
×
617
                }
618

619
                try {
620
                        QVariantMap map = StelJsonParser::parse(file.readAll()).toMap();
×
621
                        file.close();
×
622
                        QVariantMap bookmarksMap = map.value(KEY_BOOKMARKS).toMap();
×
623

624
                        QMapIterator<QString,QVariant>it(bookmarksMap);
×
625
                        while(it.hasNext())
×
626
                        {
627
                                it.next();
×
628

629
                                QVariantMap bookmarkMap = it.value().toMap();
×
630
                                observingListItem item;
×
631

632
                                // Name
633
                                item.designation = bookmarkMap.value(KEY_NAME).toString();
×
634
                                QString nameI18n = bookmarkMap.value(KEY_NAME_I18N).toString();
×
635
                                item.nameI18n = nameI18n.isEmpty() ? DASH : nameI18n;
×
636

637
                                // We need to select the object to add additional information that is not in the Bookmark file
638
                                if (objectMgr->findAndSelect(item.designation) && !objectMgr->getSelectedObject().isEmpty()) {
×
639
                                        const QList<StelObjectP> &selectedObject = objectMgr->getSelectedObject();
×
640

641
                                        item.objClass = selectedObject[0]->getType(); // Assign class name
×
642
                                        item.objTypeI18n = selectedObject[0]->getObjectTypeI18n(); // Assign a detailed object type description
×
643
                                        item.name = selectedObject[0]->getEnglishName();
×
644
                                        item.nameI18n = selectedObject[0]->getNameI18n();
×
645
                                        item.jd = bookmarkMap.value(KEY_JD).toDouble();
×
646
                                        if (item.jd!=0.)
×
647
                                        {
648
                                                core->setJD(item.jd);
×
649
                                                core->update(0.); // Force position updates
×
650
                                        }
651

652
                                        // Ra & Dec - ra and dec are not empty in case of Custom Object
653
                                        item.ra = bookmarkMap.value(KEY_RA).toString();
×
654
                                        item.dec = bookmarkMap.value(KEY_DEC).toString();
×
655
                                        if (item.ra.isEmpty() || item.dec.isEmpty()) {
×
656
                                                double ra, dec;
657
                                                StelUtils::rectToSphe(&ra, &dec, selectedObject[0]->getJ2000EquatorialPos(core));
×
658
                                                item.ra = StelUtils::radToHmsStr(ra, false).trimmed();
×
659
                                                item.dec = StelUtils::radToDmsStr(dec, false).trimmed();
×
660
                                        }
661
                                        item.magnitude = getMagnitude(selectedObject, core);
×
662
                                        // Several data items were not part of the original bookmarks, so we have no entry.
663
                                        const Vec3d posNow = selectedObject[0]->getEquinoxEquatorialPos(core);
×
664
                                        item.constellation = core->getIAUConstellation(posNow);
×
665
                                        item.location = bookmarkMap.value(KEY_LOCATION).toString();
×
666
                                        // No landscape in original bookmarks. Just leave empty.
667
                                        //item.landscapeID = bookmarkData.value(KEY_LANDSCAPE_ID).toString();
668
                                        double bmFov = bookmarkMap.value(KEY_FOV).toDouble();
×
669
                                        if (bmFov>1.e-10) // FoV may look like 3.121251e-310, which is bogus.
×
670
                                                item.fov=bmFov;
×
671
                                        item.isVisibleMarker = bookmarkMap.value(KEY_IS_VISIBLE_MARKER, false).toBool();
×
672

673
                                        bookmarksItemHash.insert(it.key(), item);
×
674
                                }
675
                        }
×
676
                }
×
677
                catch (std::runtime_error &e)
×
678
                {
679
                        qWarning() << "[ObservingList] Load bookmarks in observing list: File format is wrong! Error: " << e.what();
×
680
                }
×
681
                // Restore selection that was active before calling this
682
                if (existingSelectionToRestore.length()>0)
×
683
                        objectMgr->setSelectedObject(existingSelectionToRestore, StelModule::ReplaceSelection);
×
684
                else
685
                        objectMgr->unSelect();
×
686

687
                core->setJD(currentJD);
×
688
                core->setMilliSecondsOfLastJDUpdate(millis); // restore millis.
×
689
                core->update(0); // enforce update to the previous positions
×
690
        }
×
691
        return bookmarksItemHash;
×
692
}
×
693

694
/*
695
 * Save the bookmarks into observingLists QVariantMap
696
*/
697
QString ObsListDialog::saveBookmarksHashInObservingLists(const QHash<QString, observingListItem> &bookmarksHash)
×
698
{
699
        // Creation date
700
        double JD = StelUtils::getJDFromSystem(); // Mark with current system time
×
701
        QString listCreationDate = StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " ");
×
702

703
        QVariantMap bookmarksObsList = {
704
                {KEY_NAME,          BOOKMARKS_LIST_NAME},
705
                {KEY_DESCRIPTION,   BOOKMARKS_LIST_DESCRIPTION},
706
                {KEY_CREATION_DATE, listCreationDate},
707
                {KEY_LAST_EDIT,     listCreationDate},
708
                {KEY_SORTING,       SORTING_BY_NAME}};
×
709

710
        // Add actual list of (former) bookmark entries
711
        QVariantList objects;
×
712
        QHashIterator<QString, observingListItem> it(bookmarksHash);
×
713
        while (it.hasNext())
×
714
        {
715
                it.next();
×
716
                observingListItem item = it.value();
×
717
                objects.push_back(item.toVariantMap());
×
718
        }
×
719
        bookmarksObsList.insert(KEY_OBJECTS, objects);
×
720

721
        QList<QString> keys = bookmarksHash.keys();
×
722
        QString bookmarkListOlud= (keys.empty() ? QUuid::createUuid().toString() : keys.at(0));
×
723

724
        observingLists.insert(bookmarkListOlud, bookmarksObsList);
×
725
        return bookmarkListOlud;
×
726
}
×
727

728
/*
729
 * Select and go to object
730
*/
731
void ObsListDialog::selectAndGoToObject(QModelIndex index)
×
732
{
733
        QStandardItem *selectedItem = itemModel->itemFromIndex(index);
×
734
        int rowNumber = selectedItem->row();
×
735

736
        QStandardItem *uuidItem = itemModel->item(rowNumber, ColumnUUID);
×
737
        QString itemUuid = uuidItem->text();
×
738
        observingListItem item = currentItemCollection.value(itemUuid);
×
739

740
        // Load landscape/location before dealing with the object: It could be a view from another planet!
741
        // We load stored landscape/location if the respective checkbox is checked.
742
        if (getFlagUseLandscape() && !item.landscapeID.isEmpty())
×
743
                GETSTELMODULE(LandscapeMgr)->setCurrentLandscapeID(item.landscapeID, 0);
×
744
        if (getFlagUseLocation() && !item.location.isEmpty())
×
745
        {
746
                StelLocation loc=StelApp::getInstance().getLocationMgr().locationForString(item.location);
×
747
                if (loc.isValid())
×
748
                        core->moveObserverTo(loc);
×
749
                else
750
                        qWarning() << "ObservingLists: Cannot retrieve valid location for" << item.location;
×
751
        }
×
752
        // We also use stored jd only if the checkbox JD is checked.
753
        if (getFlagUseJD() && item.jd != 0.0)
×
754
                core->setJD(item.jd);
×
755

756
        StelMovementMgr *mvmgr = GETSTELMODULE(StelMovementMgr);
×
757
        //objectMgr->unSelect();
758

759
        bool objectFound = objectMgr->findAndSelect(item.designation); // TODO: We should prefer to use findAndSelect(item.designation, item.objClass). But what are the implications for markers?
×
760
        if (!item.ra.isEmpty() && !item.dec.isEmpty() && (!objectFound || item.designation.contains("marker", Qt::CaseInsensitive))) {
×
761
                Vec3d pos;
×
762
                StelUtils::spheToRect(StelUtils::getDecAngle(item.ra.trimmed()), StelUtils::getDecAngle(item.dec.trimmed()), pos);
×
763
                if (item.designation.contains("marker", Qt::CaseInsensitive))
×
764
                {
765
                        // Add a custom object on the sky
766
                        GETSTELMODULE(CustomObjectMgr)->addCustomObject(item.designation, pos, item.isVisibleMarker);
×
767
                        objectFound = objectMgr->findAndSelect(item.designation);
×
768
                }
769
                else
770
                {
771
                        // The unnamed stars
772
                        StelObjectP sobj=nullptr;
×
773
                        const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
×
774
                        double fov = (item.fov > 0.0 ? item.fov : 5.0);
×
775

776
                        mvmgr->zoomTo(fov, 0.0);
×
777
                        mvmgr->moveToJ2000(pos, mvmgr->mountFrameToJ2000(Vec3d(0., 0., 1.)), 0.0);
×
778

779
                        QList<StelObjectP> candidates = GETSTELMODULE(StarMgr)->searchAround(pos, 0.5, core);
×
780
                        if (candidates.empty()) { // The FOV is too big, let's reduce it to see dimmer objects.
×
781
                                mvmgr->zoomTo(0.5 * fov, 0.0);
×
782
                                candidates = GETSTELMODULE(StarMgr)->searchAround(pos, 0.5, core);
×
783
                        }
784

785
                        Vec3d winpos;
×
786
                        prj->project(pos, winpos);
×
787
                        double xpos = winpos[0];
×
788
                        double ypos = winpos[1];
×
789
                        double bestCandDistSq = 1.e6;
×
790
                        for (const auto &obj: candidates)
×
791
                        {
792
                                prj->project(obj->getJ2000EquatorialPos(core), winpos);
×
793
                                double sqrDistance = (xpos - winpos[0]) * (xpos - winpos[0]) + (ypos - winpos[1]) * (ypos - winpos[1]);
×
794
                                if (sqrDistance < bestCandDistSq)
×
795
                                {
796
                                        bestCandDistSq = sqrDistance;
×
797
                                        sobj = obj;
×
798
                                }
799
                        }
800
                        if (sobj)
×
801
                                objectFound = objectMgr->setSelectedObject(sobj);
×
802
                }
×
803
        }
804

805
        if (objectFound) {
×
806
                const QList<StelObjectP> newSelected = objectMgr->getSelectedObject();
×
807
                if (!newSelected.empty())
×
808
                {
809
                        const float amd = mvmgr->getAutoMoveDuration();
×
810
                        mvmgr->moveToObject(newSelected[0], amd);
×
811
                        mvmgr->setFlagTracking(true);
×
812
                        // We load stored FoV if the FoV checkbox is checked.
813
                        if (getFlagUseFov() && item.fov>1e-10) {
×
814
                                GETSTELMODULE(StelMovementMgr)->zoomTo(item.fov, amd);
×
815
                        }
816
                }
817
        }
×
818
}
×
819

820
/*
821
 * Method called when a list name is selected in the combobox
822
*/
823
void ObsListDialog::loadSelectedObservingList(int selectedIndex)
×
824
{
825
        //ui->editListButton->setEnabled(true);
826
        //ui->deleteListButton->setEnabled(true);
827
        selectedOlud = ui->obsListComboBox->itemData(selectedIndex).toString();
×
828
        loadSelectedList();
×
829
}
×
830

831
/*
832
 * Slot for button highlightAllButton: show all objects of active list.
833
*/
834
void ObsListDialog::highlightAll()
×
835
{
836
        // We must keep selection for the user. It is not enough to store/restore the existingSelection.
837
        // The QList<StelObjectP> objects are apparently volatile. We must retrieve the actual object.
838
        const QList<StelObjectP>&existingSelection = objectMgr->getSelectedObject();
×
839
        QList<StelObjectP> existingSelectionToRestore;
×
840
        if (existingSelection.length()>0)
×
841
        {
842
                existingSelectionToRestore.append(existingSelection.at(0));
×
843
        }
844

845
        QList<Vec3d> highlights;
×
846
        clearHighlights(); // Enable fool protection
×
847
        const int fontSize = StelApp::getInstance().getScreenFontSize();
×
848
        HighlightMgr *hlMgr = GETSTELMODULE(HighlightMgr);
×
849
        const QString color = hlMgr->getColor().toHtmlColor();
×
850
        float distance = hlMgr->getMarkersSize();
×
851

852
        for (const auto &item: qAsConst(currentItemCollection)) {
×
853
                const QString name = item.designation;
×
854
                const QString raStr = item.ra.trimmed();
×
855
                const QString decStr = item.dec.trimmed();
×
856

857
                Vec3d pos;
×
858
                bool usablePosition;
859
                if (!raStr.isEmpty() && !decStr.isEmpty())
×
860
                {
861
                        StelUtils::spheToRect(StelUtils::getDecAngle(raStr), StelUtils::getDecAngle(decStr), pos);
×
862
                        usablePosition = true;
×
863
                }
864
                else
865
                {
866
                        usablePosition = objectMgr->findAndSelect(name);
×
867
                        if (usablePosition) {
×
868
                                const QList<StelObjectP> &selected = objectMgr->getSelectedObject();
×
869
                                pos = selected[0]->getJ2000EquatorialPos(core);
×
870
                        }
871
                }
872
                if (usablePosition)
×
873
                        highlights.append(pos);
×
874

875
                // Add labels for named highlights (name in top right corner)
876
                if (!raStr.isEmpty() && !decStr.isEmpty()) // We may have a position for a timestamped event
×
877
                        highlightLabelIDs.append(labelMgr->labelEquatorial(name, raStr, decStr, true, fontSize, color, "NE", distance));
×
878
                else
879
                        highlightLabelIDs.append(labelMgr->labelObject(name, name, true, fontSize, color, "NE", distance));
×
880
        }
×
881

882
        hlMgr->fillHighlightList(highlights);
×
883

884
        // Restore selection that was active before calling this
885
        if (existingSelectionToRestore.length()>0)
×
886
                objectMgr->setSelectedObject(existingSelectionToRestore, StelModule::ReplaceSelection);
×
887
        else
888
                objectMgr->unSelect();
×
889
}
×
890

891
/*
892
 * Clear highlights
893
*/
894
void ObsListDialog::clearHighlights()
×
895
{
896
        GETSTELMODULE(HighlightMgr)->cleanHighlightList();
×
897
        // Clear labels
898
        for (int l: highlightLabelIDs) {
×
899
                labelMgr->deleteLabel(l);
×
900
        }
901
        highlightLabelIDs.clear();
×
902
}
×
903

904
/*
905
 * Slot for button newListButton
906
*/
907
void ObsListDialog::newListButtonPressed()
×
908
{
909
        selectedOlud=QUuid::createUuid().toString();
×
910
        itemModel->removeRows(0, itemModel->rowCount()); // don't use clear() here!
×
911
        currentItemCollection.clear();
×
912

913
        //ui->treeView->clearSelection(); ???
914
        switchEditMode(true, true);
×
915

916
        ui->listNameLineEdit->setText(q_("New Observation List"));
×
917
        ui->titleBar->setTitle(q_("Observing list creation mode"));
×
918
}
×
919
/*
920
 * Slot for editButton
921
*/
922
void ObsListDialog::editListButtonPressed()
×
923
{
924
        Q_ASSERT(!selectedOlud.isEmpty());
×
925

926
        if (!selectedOlud.isEmpty())
×
927
        {
928
                switchEditMode(true, false);
×
929

930
                ui->titleBar->setTitle(q_("Observing list editor mode"));
×
931
        }
932
        else
933
        {
934
                qCritical() << "ObsListDialog::editListButtonPressed(): selectedOlud is empty";
×
935
                messageBox(q_("Error"), q_("selectedOlud empty. This is a bug"));
×
936
        }
937
}
×
938

939
/*
940
 * Slot for button obsListExportListButton
941
 */
942
void ObsListDialog::exportListButtonPressed()
×
943
{
944
        static const QString filter = "Stellarium Single Observing List (*.sol);;Stellarium Observing List (*.ol)";
×
945
        const QString destinationDir=StelApp::getInstance().getSettings()->value("main/observinglists_dir", QDir::homePath()).toString();
×
946
        QString selectedFilter = "Stellarium Single Observing List (*.sol)";
×
947
        QString exportListJsonPath = QFileDialog::getSaveFileName(&StelMainView::getInstance(), q_("Export observing list as..."),
×
948
                                                              destinationDir + "/" + JSON_FILE_BASENAME + "_" + currentListName + ".sol", filter, &selectedFilter);
×
949

950
        QFile jsonFile(exportListJsonPath);
×
951
        if (!jsonFile.open(QIODevice::ReadWrite | QIODevice::Text))
×
952
        {
953
                qWarning() << "[ObservingList Creation/Edition] Error exporting observing list. "
×
954
                           << "File cannot be opened for reading and writing:"
×
955
                           << QDir::toNativeSeparators(exportListJsonPath);
×
956
                messageBox(q_("Error"), q_("Cannot export. See logfile for details."));
×
957
                return;
×
958
        }
959

960
        jsonFile.resize(0);
×
961
        QFileInfo fi(exportListJsonPath);
×
962
        if (fi.suffix()=="sol")
×
963
        {
964
                // Prepare a new json-able map
965
                QVariantMap exportJsonMap={
966
                        {KEY_DEFAULT_LIST_OLUD, ""}, // Do not set a default in this list!
967
                        {KEY_SHORT_NAME, SHORT_NAME_VALUE},
968
                        {KEY_VERSION, FILE_VERSION}};
×
969

970
                QVariantMap currentListMap={{selectedOlud, observingLists.value(selectedOlud).toMap()}};
×
971
                //QVariantMap oneListMap={{KEY_OBSERVING_LISTS, currentListMap}};
972
                //exportJsonMap.insert(KEY_OBSERVING_LISTS, oneListMap);
973
                exportJsonMap.insert(KEY_OBSERVING_LISTS, currentListMap);
×
974
                StelJsonParser::write(exportJsonMap, &jsonFile);
×
975
        }
×
976
        else
977
        {
978
                // just export complete map.
979
                StelJsonParser::write(jsonMap, &jsonFile);
×
980
        }
981

982
        jsonFile.flush();
×
983
        jsonFile.close();
×
984
}
×
985

986
/*
987
 * Slot for button obsListImportListButton
988
 */
989
void ObsListDialog::importListButtonPressed()
×
990
{
991
        static const QString filter = "Stellarium Single Observing List (*.sol);;Stellarium Observing List (*.ol);;Stellarium Legacy JSON Observing List or Bookmarks (*.json)";
×
992
        const QString destinationDir=StelApp::getInstance().getSettings()->value("main/observinglists_dir", QDir::homePath()).toString();
×
993
        QString fileToImportJsonPath = QFileDialog::getOpenFileName(&StelMainView::getInstance(), q_("Import observing list"),
×
994
                                                                    destinationDir,
995
                                                                    filter);
×
996
        QVariantMap map;
×
997
        QFile jsonFile(fileToImportJsonPath);
×
998
        if (!jsonFile.open(QIODevice::ReadOnly))
×
999
        {
1000
                qWarning() << "[ObservingList Import] cannot open"
×
1001
                           << QDir::toNativeSeparators(jsonFile.fileName());
×
1002
                messageBox(q_("Error"), q_("Cannot open selected file for import"));
×
1003
                return;
×
1004
        }
1005
        else
1006
        {
1007
                try {
1008
                        map = StelJsonParser::parse(jsonFile.readAll()).toMap();
×
1009
                        jsonFile.close();
×
1010

1011
                        if (map.contains(KEY_OBSERVING_LISTS))
×
1012
                        {
1013
                                // Case of observingList import: Import all lists from that file! A .sol only has one list but is else structured identically.
1014
                                const QVariantMap observingListMapToImport = map.value(KEY_OBSERVING_LISTS).toMap();
×
1015
                                if (observingListMapToImport.isEmpty())
×
1016
                                {
1017
                                        qWarning() << "[ObservingList Creation/Edition import] empty list:" << fileToImportJsonPath;
×
1018
                                        messageBox(q_("Error"), q_("Empty list."));
×
1019
                                        return;
×
1020
                                }
1021
                                else
1022
                                {
1023
                                        QVariantMap::const_iterator it;
×
1024
                                        for (it = observingListMapToImport.begin(); it != observingListMapToImport.end(); it++) {
×
1025
                                                if (it.value().canConvert<QVariantMap>())
×
1026
                                                {
1027
                                                        // check here to avoid overwriting of existing lists
1028
                                                        bool overwrite=true;
×
1029
                                                        if (observingLists.contains(it.key())) // Same OLUD?
×
1030
                                                        {
1031
                                                                QVariantMap importedMap=it.value().toMap(); // This is a map of {{UUID, QMap},...}
×
1032
                                                                QString importedName=importedMap.value(KEY_NAME).toString();
×
1033
                                                                QString importedDate=importedMap.value(KEY_CREATION_DATE).toString();
×
1034
                                                                QString importedLastEditDate=importedMap.value(KEY_LAST_EDIT, importedMap.value(KEY_CREATION_DATE)).toString();
×
1035
                                                                qDebug() << "Imported Map named:" << importedName << "created" << importedDate << "changed" << importedLastEditDate << ":" << importedMap;
×
1036
                                                                QVariantMap existingMap=observingLists.value(it.key()).toMap();
×
1037
                                                                QString existingName=existingMap.value(KEY_NAME).toString();
×
1038
                                                                QString existingDate=existingMap.value(KEY_CREATION_DATE).toString();
×
1039
                                                                QString existingLastEdit=existingMap.value(KEY_LAST_EDIT, existingMap.value(KEY_CREATION_DATE)).toString();
×
1040
                                                                QString message=QString(q_("A list named '%1', created %2 and last modified %3 would overwrite your existing list '%4', dated %5 and last modified %6. Accept?")).arg(importedName, importedDate, importedLastEditDate, existingName, existingDate, existingLastEdit);
×
1041
                                                                overwrite=askConfirmation(message);
×
1042
                                                        }
×
1043
                                                        if (overwrite)
×
1044
                                                        {
1045
                                                                observingLists.insert(it.key(), it.value());
×
1046
                                                                selectedOlud=it.key();
×
1047
                                                        }
1048
                                                }
1049
                                        }
1050
                                }
1051
                        }
×
1052
                        else if (map.contains(KEY_BOOKMARKS))
×
1053
                        {
1054
                                // Case of legacy bookmarks import
1055
                                QVariantMap bookmarksListMap = map.value(KEY_BOOKMARKS).toMap();
×
1056
                                if (bookmarksListMap.isEmpty())
×
1057
                                {
1058
                                        qWarning() << "[ObservingList Creation/Edition import] the file is empty or doesn't contain legacy bookmarks.";
×
1059
                                        messageBox(q_("Error"), q_("The file is empty or doesn't contain legacy bookmarks."));
×
1060
                                        return;
×
1061
                                }
1062
                                else
1063
                                {
1064
                                        QHash<QString, ObsListDialog::observingListItem> bookmarksHash=loadBookmarksFile(jsonFile);
×
1065
                                        // Put them to the main list. Note that this may create another list named "bookmarks list", however, with a different OLUD than the existing.
1066
                                        selectedOlud=saveBookmarksHashInObservingLists(bookmarksHash);
×
1067
                                }
×
1068
                        }
×
1069
                        else
1070
                        {
1071
                                messageBox(q_("Error"), q_("File does not contain observing lists or legacy bookmarks"));
×
1072
                                return;
×
1073
                        }
1074

1075
                        // At this point we have added our lists to the observingLists map. Now update the jsonMap and store to file.
1076
                        QFile jsonFile(observingListJsonPath);
×
1077
                        if (!jsonFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
×
1078
                                qWarning() << "[ObservingList] bookmarks list can not be saved. A file can not be open for reading and writing:"
×
1079
                                           << QDir::toNativeSeparators(observingListJsonPath);
×
1080
                                messageBox(q_("Error"), q_("Cannot open observingLists.json to write"));
×
1081
                                return;
×
1082
                        }
1083
                        // Update the jsonMap and store
1084
                        jsonMap.insert(KEY_OBSERVING_LISTS, observingLists);
×
1085
                        jsonFile.resize(0);
×
1086
                        StelJsonParser::write(jsonMap, &jsonFile);
×
1087
                        jsonFile.flush();
×
1088
                        jsonFile.close();
×
1089
                        tainted=false;
×
1090

1091
                        // Now we have stored to file, but the program is not aware of the new lists!
1092
                        loadListNames(); // also populate Combobox and make sure at least some defaultOlud exists.
×
1093
                        loadSelectedList();
×
1094
                } catch (std::runtime_error &e) {
×
1095
                        qWarning() << "[ObservingList Creation/Edition] File format is wrong! Error: " << e.what();
×
1096
                        messageBox(q_("Error"), q_("File format is wrong!"));
×
1097
                        return;
×
1098
                }
×
1099
        }
1100
}
×
1101

1102
/*
1103
 * Delete the currently selected list. There must be at least one list.
1104
*/
1105
void ObsListDialog::deleteListButtonPressed()
×
1106
{
1107
        if (observingLists.count()>1 && (selectedOlud!=defaultOlud) && askConfirmation())
×
1108
        {
1109
                QFile jsonFile(observingListJsonPath);
×
1110
                if (!jsonFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
×
1111
                        qWarning() << "[ObservingList] bookmarks list can not be saved. A file can not be open for reading and writing:"
×
1112
                                   << QDir::toNativeSeparators(observingListJsonPath);
×
1113
                        messageBox(q_("Error"), q_("Cannot open JSON output file. Will not delete."));
×
1114
                        return;
×
1115
                }
1116

1117
                observingLists.remove(selectedOlud);
×
1118
                currentItemCollection.clear();
×
1119

1120
                selectedOlud=defaultOlud;
×
1121
                // Update the jsonMap and store
1122
                jsonMap.insert(KEY_OBSERVING_LISTS, observingLists);
×
1123
                jsonFile.resize(0);
×
1124
                StelJsonParser::write(jsonMap, &jsonFile);
×
1125
                jsonFile.flush();
×
1126
                jsonFile.close();
×
1127
                tainted=false;
×
1128

1129
                // Clean up UI
1130
                clearHighlights();
×
1131
                loadListNames();
×
1132
                loadSelectedList();
×
1133
        }
×
1134
        else
1135
        {
1136
                qDebug() << "deleteButtonPressed: You cannot delete the default or the last list.";
×
1137
                messageBox(q_("Information"), q_("You cannot delete the default or the last list."));
×
1138
        }
1139
}
1140

1141
/*
1142
 * Slot for addObjectButton.
1143
 * Save selected object into the list of observed objects.
1144
 */
1145
void ObsListDialog::addObjectButtonPressed()
×
1146
{
1147
        const double JD = core->getJD();
×
1148
        const double fov = (ui->fovCheckBox->isChecked() ? GETSTELMODULE(StelMovementMgr)->getCurrentFov() : -1.0);
×
1149
        const QString Location = core->getCurrentLocation().serializeToLine(); // store completely
×
1150
        const QString landscapeID=GETSTELMODULE(LandscapeMgr)->getCurrentLandscapeID();
×
1151

1152
        const QList<StelObjectP> &selectedObject = objectMgr->getSelectedObject();
×
1153

1154
        if (!selectedObject.isEmpty())
×
1155
        {
1156
// TBD: this test should prevent adding duplicate entries, but fails. Maybe for V23.4!
1157
//                // No duplicate item in the same list
1158
//                bool is_already_in_list = false;
1159
//                QHash<QString, observingListItem>::iterator i;
1160
//                for (i = observingListItemCollection.begin(); i != observingListItemCollection.end(); i++)
1161
//                {
1162
//                        if ((i.value().name.compare(selectedObject[0]->getEnglishName()) == 0) &&
1163
//                                (ui->obsListJDCheckBox->isChecked()        && i.value().jd == JD) &&
1164
//                                (ui->obsListFovCheckBox->isChecked()       && i.value().fov == fov) &&
1165
//                                (ui->obsListLandscapeCheckBox->isChecked() && i.value().landscapeID == landscapeID) &&
1166
//                                (ui->obsListLocationCheckBox->isChecked()  && i.value().location == Location))
1167
//                        {
1168
//                                is_already_in_list = true;
1169
//                                break;
1170
//                        }
1171
//                }
1172
//
1173
//                if (!is_already_in_list)
1174
//                {
1175
                        observingListItem item;
×
1176

1177
                        const QString objectUUID = QUuid::createUuid().toString();
×
1178

1179
                        // Object name (designation) and object name I18n
1180
                        if (selectedObject[0]->getType() == "Nebula")
×
1181
                                item.designation = GETSTELMODULE(NebulaMgr)->getLatestSelectedDSODesignationWIC(); // Store most common catalog ID as of our catalog sequence, even if catalog is not active
×
1182
                        else
1183
                                item.designation = selectedObject[0]->getEnglishName();
×
1184
                        item.name = selectedObject[0]->getEnglishName();
×
1185
                        item.nameI18n = selectedObject[0]->getNameI18n();
×
1186
                        if(item.nameI18n.isEmpty())
×
1187
                                item.nameI18n = DASH;
×
1188
                        // Check if the object name is empty.
1189
                        if (item.designation.isEmpty())
×
1190
                        {
1191
                                item.designation = "Unnamed object";
×
1192
                                if (item.nameI18n.isEmpty()) {
×
1193
                                        item.nameI18n = q_("Unnamed object");
×
1194
                                }
1195
                        }
1196
                        // Type, Object Type
1197
                        item.objClass = selectedObject[0]->getType();
×
1198
                        item.objTypeI18n = selectedObject[0]->getObjectTypeI18n();
×
1199

1200
                        // Ra & Dec
1201
                        if (ui->coordinatesCheckBox->isChecked() || (item.objClass == "Planet" && getFlagUseJD()) || item.objClass == CUSTOM_OBJECT || item.designation.isEmpty()) {
×
1202
                                double ra, dec;
1203
                                StelUtils::rectToSphe(&ra, &dec, selectedObject[0]->getJ2000EquatorialPos(core));
×
1204
                                item.ra  = StelUtils::radToHmsStr(ra,  false).trimmed();
×
1205
                                item.dec = StelUtils::radToDmsStr(dec, false).trimmed();
×
1206
                        }
1207
                        item.isVisibleMarker=!item.designation.contains("marker", Qt::CaseInsensitive);
×
1208
                        item.magnitude = getMagnitude(selectedObject, core);
×
1209

1210
                        // Constellation
1211
                        const Vec3d posNow = selectedObject[0]->getEquinoxEquatorialPos(core);
×
1212
                        item.constellation = core->getIAUConstellation(posNow);
×
1213

1214
                        // Optional: JD, Location, landscape, fov
1215
                        if (getFlagUseJD())
×
1216
                                item.jd = JD;
×
1217
                        if (getFlagUseLocation())
×
1218
                                item.location = Location;
×
1219
                        if (getFlagUseLandscape())
×
1220
                                item.landscapeID = landscapeID;
×
1221
                        if (getFlagUseFov() && (fov > 1.e-6))
×
1222
                                item.fov = fov;
×
1223

1224
                        currentItemCollection.insert(objectUUID, item);
×
1225
                        tainted=true;
×
1226

1227
                        // Add object in row model
1228
                        StelLocation loc=StelLocation::createFromLine(Location);
×
1229
                        addModelRow(objectUUID,
×
1230
                                    item.designation,
1231
                                    item.nameI18n,
1232
                                    item.objTypeI18n,
1233
                                    item.ra,
1234
                                    item.dec,
1235
                                    item.magnitude,
1236
                                    item.constellation,
1237
                                    ui->jdCheckBox->isChecked() ? StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " ") : "",
×
1238
                                    ui->locationCheckBox->isChecked() ? loc.name : "",
×
1239
                                    item.landscapeID);
1240
//                }
1241
        }
×
1242
        else
1243
                qWarning() << "Selected object is empty!";
×
1244
}
×
1245

1246
/*
1247
 * Slot for button obsListRemoveObjectButton
1248
 */
1249
void ObsListDialog::removeObjectButtonPressed()
×
1250
{
1251
        Q_ASSERT(isEditMode);
×
1252

1253
        int number = ui->treeView->currentIndex().row();
×
1254
        QString uuid = itemModel->index(number, ColumnUUID).data().toString();
×
1255
        itemModel->removeRow(number);
×
1256
        currentItemCollection.remove(uuid);
×
1257
        tainted=true;
×
1258
}
×
1259

1260
/*
1261
 * Slot for saveButton
1262
 */
1263
void ObsListDialog::saveButtonPressed()
×
1264
{
1265
        Q_ASSERT(isEditMode);
×
1266
        if (!isEditMode)
×
1267
        {
1268
                qCritical() << "CALLING ERROR: saveButtonPressed() while not in edit mode.";
×
1269
                return;
×
1270
        }
1271

1272
        // we have a valid selectedListOlud. In addition, the list must have a human-readable name.
1273
        QString listName = ui->listNameLineEdit->text().trimmed();
×
1274
        if (listName.length()==0)
×
1275
        {
1276
                messageBox(q_("Error"), q_("Empty name"));
×
1277
                return;
×
1278
        }
1279
        if (listNames.contains(listName) && isCreationMode)
×
1280
        {
1281
                messageBox(q_("Error"), q_("List name already exists"));
×
1282
                return;
×
1283
        }
1284

1285
        // Last chance to detect any change: Just list name changed?
1286
        if (currentListName!=listName)
×
1287
                tainted=true;
×
1288

1289
        if (!tainted)
×
1290
                return;
×
1291

1292
        //OK, we save this and keep it as current list.
1293
        currentListName=listName;
×
1294

1295
        QFile jsonFile(observingListJsonPath);
×
1296
        if (!jsonFile.open(QIODevice::ReadWrite | QIODevice::Text))
×
1297
        {
1298
                qWarning() << "[ObservingList Save] Error saving observing list. "
×
1299
                           << "File cannot be opened for reading and writing:"
×
1300
                           << QDir::toNativeSeparators(observingListJsonPath);
×
1301
                return;
×
1302
        }
1303

1304
        QVariantMap currentList=prepareCurrentList(currentItemCollection);
×
1305
        observingLists.insert(selectedOlud, currentList);
×
1306
        jsonMap.insert(KEY_OBSERVING_LISTS, observingLists);
×
1307

1308
        jsonFile.resize(0);
×
1309
        StelJsonParser::write(jsonMap, &jsonFile);
×
1310
        jsonFile.flush();
×
1311
        jsonFile.close();
×
1312

1313
        tainted=false;
×
1314
        switchEditMode(false, false); // Set GUI to normal mode
×
1315
        loadListNames(); // reload Combobox
×
1316
        loadSelectedList();
×
1317
}
×
1318

1319
/*
1320
 * Slot for cancelButton
1321
 */
1322
void ObsListDialog::cancelButtonPressed()
×
1323
{
1324
        Q_ASSERT(isEditMode);
×
1325
        if (!isEditMode)
×
1326
        {
1327
                qCritical() << "CALLING ERROR: cancelButtonPressed() while not in edit mode.";
×
1328
                return;
×
1329
        }
1330
        // Depending on creation or regular edit mode, delete current list and load default, or reload current list,
1331
        if (isCreationMode)
×
1332
                loadDefaultList();
×
1333
        else
1334
                loadSelectedList();
×
1335

1336
        // then close editing mode and set GUI to normal mode
1337
        switchEditMode(false, false);
×
1338
}
1339

1340
void ObsListDialog::switchEditMode(bool enableEditMode, bool newList)
×
1341
{
1342
                isEditMode=enableEditMode;
×
1343
                isCreationMode=newList;
×
1344
                // The Layout classes have no setVisible(bool), we must configure individual buttons! :-(
1345

1346
                ui->titleBar->setTitle(q_("Observing lists"));
×
1347
                //ui->horizontalLayoutCombo->setEnabled(!isEditMode);     // disable list selection
1348
                ui->obsListComboLabel->setVisible(!isEditMode);
×
1349
                ui->obsListComboBox->setVisible(!isEditMode);
×
1350

1351
                // horizontalLayoutLineEdit_1: labelListName, nameOfListLIneEdit
1352
                //ui->horizontalLayout_Name->setEnabled(isEditMode);  // enable list name editing
1353
                ui->listNameLabel->setVisible(isEditMode);
×
1354
                //ui->horizontalSpacer_listName->sizePolicy().setHeightForWidth(isEditMode);// ->setVisible(isEditMode);
1355
                //qDebug() << "Spacer geometry, policy:" << ui->horizontalSpacer_listName->geometry() << ui->horizontalSpacer_listName->sizePolicy();
1356
                ui->listNameLineEdit->setVisible(isEditMode);
×
1357
                ui->listNameLineEdit->setText(currentListName);
×
1358

1359
                ui->descriptionLineEdit->setEnabled(isEditMode);    // (activate description line)
×
1360

1361
                ui->creationDateLabel->setVisible(!isEditMode);         // Creation date:
×
1362
                ui->creationDateLineEdit->setVisible(!isEditMode);      //
×
1363
                ui->lastEditLabel->setVisible(!isEditMode);             // Last edit date:
×
1364
                ui->lastEditLineEdit->setVisible(!isEditMode);          //
×
1365

1366
                // line with optional store items
1367
                ui->alsoStoreLabel->setVisible(isEditMode);            // Also store
×
1368
                ui->coordinatesCheckBox->setVisible(isEditMode);// hide "Coordinates"
×
1369
                ui->alsoLoadLabel->setVisible(!isEditMode);  // Also load
×
1370

1371
                //ui->horizontalLayoutButtons->setEnabled(!isEditMode);   // Highlight/Clear/NewList/EditList/DeleteList/ExportList/ImportList
1372
                ui->highlightAllButton->setVisible(!isEditMode);
×
1373
                ui->clearHighlightButton->setVisible(!isEditMode);
×
1374
                ui->newListButton->setVisible(!isEditMode);
×
1375
                ui->editListButton->setVisible(!isEditMode);
×
1376
                ui->deleteListButton->setVisible(!isEditMode);
×
1377
                ui->exportListButton->setVisible(!isEditMode);
×
1378
                ui->importListButton->setVisible(!isEditMode);
×
1379

1380
                //ui->horizontalLayoutButtons_1->setEnabled(isEditMode); // Add/Remove/Export/Import
1381
                ui->addObjectButton->setVisible(isEditMode);
×
1382
                ui->removeObjectButton->setVisible(isEditMode);
×
1383
                ui->saveButton->setVisible(isEditMode);
×
1384
                ui->cancelButton->setVisible(isEditMode);
×
1385
}
×
1386

1387
/*
1388
 * Sort the treeView by the column name given in parameter
1389
*/
1390
void ObsListDialog::sortObsListTreeViewByColumnName(const QString &columnName)
×
1391
{
1392
        static const QMap<QString,int>map={
1393
                {SORTING_BY_NAME,          ColumnDesignation},
×
1394
                {SORTING_BY_NAMEI18N,      ColumnNameI18n},
×
1395
                {SORTING_BY_TYPE,          ColumnType},
×
1396
                {SORTING_BY_RA,            ColumnRa},
×
1397
                {SORTING_BY_DEC,           ColumnDec},
×
1398
                {SORTING_BY_MAGNITUDE,     ColumnMagnitude},
×
1399
                {SORTING_BY_CONSTELLATION, ColumnConstellation},
×
1400
                {SORTING_BY_DATE,          ColumnDate},
×
1401
                {SORTING_BY_LOCATION,      ColumnLocation},
×
1402
                {SORTING_BY_LANDSCAPE_ID,  ColumnLandscapeID}
×
1403
        };
×
1404
        itemModel->sort(map.value(columnName), Qt::AscendingOrder);
×
1405
}
×
1406

1407
void ObsListDialog::setFlagUseJD(bool b)
×
1408
{
1409
        QSettings* conf = StelApp::getInstance().getSettings();
×
1410
        flagUseJD=b;
×
1411
        conf->setValue("bookmarks/useJD", b);
×
1412
        emit flagUseJDChanged(b);
×
1413
}
×
1414
void ObsListDialog::setFlagUseLandscape(bool b)
×
1415
{
1416
        QSettings* conf = StelApp::getInstance().getSettings();
×
1417
        flagUseLandscape=b;
×
1418
        conf->setValue("bookmarks/useLandscape", b);
×
1419
        emit flagUseLandscapeChanged(b);
×
1420
}
×
1421
void ObsListDialog::setFlagUseLocation(bool b)
×
1422
{
1423
        QSettings* conf = StelApp::getInstance().getSettings();
×
1424
        flagUseLocation=b;
×
1425
        conf->setValue("bookmarks/useLocation", b);
×
1426
        emit flagUseLocationChanged(b);
×
1427
}
×
1428
void ObsListDialog::setFlagUseFov(bool b)
×
1429
{
1430
        QSettings* conf = StelApp::getInstance().getSettings();
×
1431
        flagUseFov=b;
×
1432
        conf->setValue("bookmarks/useFOV", b);
×
1433
        emit flagUseFovChanged(b);
×
1434
}
×
1435

1436
/*
1437
 * Prepare the currently displayed/edited list for storage
1438
 * Returns QVariantList with keys={creation date, last edit, description, name, objects, sorting}
1439
 */
1440
QVariantMap ObsListDialog::prepareCurrentList(QHash<QString, observingListItem> &itemHash)
×
1441
{
1442
        // Edit date
1443
        const double JD = StelUtils::getJDFromSystem();
×
1444
        const QString lastEditDate = StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " ");
×
1445
        QVariantMap currentList = {
1446
                // Name, description, current date for the list, current sorting
1447
                {KEY_NAME,          currentListName},
×
1448
                {KEY_DESCRIPTION,   ui->descriptionLineEdit->text()},
×
1449
                {KEY_SORTING,       sorting},
×
1450
                {KEY_CREATION_DATE, ui->creationDateLineEdit->text()},
×
1451
                {KEY_LAST_EDIT,     lastEditDate }
1452
        };
×
1453

1454
        // List of objects
1455
        QVariantList listOfObjects;
×
1456
        QHashIterator<QString, observingListItem> i(itemHash);
×
1457
        while (i.hasNext())
×
1458
        {
1459
                i.next();
×
1460
                observingListItem item = i.value();
×
1461
                listOfObjects.push_back(item.toVariantMap());
×
1462
        }
×
1463
        currentList.insert(KEY_OBJECTS, listOfObjects);
×
1464

1465
        return currentList;
×
1466
}
×
1467

1468
/*
1469
 * Slot for obsListCreationEditionTreeView header
1470
 */
1471
void ObsListDialog::headerClicked(int index)
×
1472
{
1473
        static const QMap<int,QString> map={
1474
                {ColumnDesignation,   SORTING_BY_NAME},
×
1475
                {ColumnNameI18n,      SORTING_BY_NAMEI18N},
×
1476
                {ColumnType,          SORTING_BY_TYPE},
×
1477
                {ColumnRa,            SORTING_BY_RA},
×
1478
                {ColumnDec,           SORTING_BY_DEC},
×
1479
                {ColumnMagnitude,     SORTING_BY_MAGNITUDE},
×
1480
                {ColumnConstellation, SORTING_BY_CONSTELLATION},
×
1481
                {ColumnDate,          SORTING_BY_DATE},
×
1482
                {ColumnLocation,      SORTING_BY_LOCATION},
×
1483
                {ColumnLandscapeID,   SORTING_BY_LANDSCAPE_ID}};
×
1484
        sorting=map.value(index, "");
×
1485
        //qDebug() << "Sorting = " << sorting;
1486
}
×
1487

1488
// Get the magnitude from selected object (or a dash if unavailable)
1489
QString ObsListDialog::getMagnitude(const QList<StelObjectP> &selectedObject, StelCore *core)
×
1490
{
1491
        if (!core)
×
1492
                return DASH;
×
1493

1494
        QString objectMagnitudeStr(DASH);
×
1495
        const float objectMagnitude = selectedObject[0]->getVMagnitude(core);
×
1496
        if (objectMagnitude > 98.f)
×
1497
        {
1498
                if (QString::compare(selectedObject[0]->getType(), "Nebula", Qt::CaseSensitive) == 0)
×
1499
                {
1500
                        auto &r_nebula = dynamic_cast<Nebula &>(*selectedObject[0]);
×
1501
                        const float mB = r_nebula.getBMagnitude(core);
×
1502
                        if (mB < 98.f)
×
1503
                                objectMagnitudeStr = QString::number(mB);
×
1504
                }
1505
        }
1506
        else
1507
                objectMagnitudeStr = QString::number(objectMagnitude, 'f', 2);
×
1508

1509
        return objectMagnitudeStr;
×
1510
}
×
1511

1512
void ObsListDialog::defaultClicked(bool b)
×
1513
{
1514
        defaultOlud = (b ? selectedOlud : "");
×
1515
        jsonMap.insert(KEY_DEFAULT_LIST_OLUD, defaultOlud);
×
1516
        tainted=true;
×
1517
}
×
1518

1519
const QString ObsListDialog::JSON_FILE_NAME     = QStringLiteral("observingList.json");
15✔
1520
const QString ObsListDialog::JSON_FILE_BASENAME = QStringLiteral("observingList");
15✔
1521
const QString ObsListDialog::FILE_VERSION       = QStringLiteral("2.1");
15✔
1522

1523
const QString ObsListDialog::JSON_BOOKMARKS_FILE_NAME   = QStringLiteral("bookmarks.json");
15✔
1524
const QString ObsListDialog::BOOKMARKS_LIST_NAME        = QStringLiteral("bookmarks list");
15✔
1525
const QString ObsListDialog::BOOKMARKS_LIST_DESCRIPTION = QStringLiteral("Bookmarks of previous Stellarium version.");
15✔
1526
const QString ObsListDialog::SHORT_NAME_VALUE           = QStringLiteral("Observing list for Stellarium");
15✔
1527

1528
const QString ObsListDialog::KEY_DEFAULT_LIST_OLUD = QStringLiteral("defaultListOlud");
15✔
1529
const QString ObsListDialog::KEY_OBSERVING_LISTS   = QStringLiteral("observingLists");
15✔
1530
const QString ObsListDialog::KEY_CREATION_DATE     = QStringLiteral("creation date");
15✔
1531
const QString ObsListDialog::KEY_LAST_EDIT         = QStringLiteral("last edit");
15✔
1532
const QString ObsListDialog::KEY_BOOKMARKS         = QStringLiteral("bookmarks");
15✔
1533
const QString ObsListDialog::KEY_NAME              = QStringLiteral("name");
15✔
1534
const QString ObsListDialog::KEY_NAME_I18N         = QStringLiteral("nameI18n");
15✔
1535
const QString ObsListDialog::KEY_JD                = QStringLiteral("jd");
15✔
1536
const QString ObsListDialog::KEY_RA                = QStringLiteral("ra");
15✔
1537
const QString ObsListDialog::KEY_DEC               = QStringLiteral("dec");
15✔
1538
const QString ObsListDialog::KEY_FOV               = QStringLiteral("fov");
15✔
1539
const QString ObsListDialog::KEY_DESCRIPTION       = QStringLiteral("description");
15✔
1540
const QString ObsListDialog::KEY_LANDSCAPE_ID      = QStringLiteral("landscapeID");
15✔
1541
const QString ObsListDialog::KEY_OBJECTS           = QStringLiteral("objects");
15✔
1542
const QString ObsListDialog::KEY_OBJECTS_TYPE      = QStringLiteral("objtype");
15✔
1543
const QString ObsListDialog::KEY_TYPE              = QStringLiteral("type");
15✔
1544
const QString ObsListDialog::KEY_DESIGNATION       = QStringLiteral("designation");
15✔
1545
const QString ObsListDialog::KEY_SORTING           = QStringLiteral("sorting");
15✔
1546
const QString ObsListDialog::KEY_LOCATION          = QStringLiteral("location");
15✔
1547
const QString ObsListDialog::KEY_MAGNITUDE         = QStringLiteral("magnitude");
15✔
1548
const QString ObsListDialog::KEY_CONSTELLATION     = QStringLiteral("constellation");
15✔
1549
const QString ObsListDialog::KEY_VERSION           = QStringLiteral("version");
15✔
1550
const QString ObsListDialog::KEY_SHORT_NAME        = QStringLiteral("shortName");
15✔
1551
const QString ObsListDialog::KEY_IS_VISIBLE_MARKER = QStringLiteral("isVisibleMarker");
15✔
1552

1553
const QString ObsListDialog::SORTING_BY_NAME          = QStringLiteral("name");
15✔
1554
const QString ObsListDialog::SORTING_BY_NAMEI18N      = QStringLiteral("nameI18n");
15✔
1555
const QString ObsListDialog::SORTING_BY_TYPE          = QStringLiteral("type");
15✔
1556
const QString ObsListDialog::SORTING_BY_RA            = QStringLiteral("right ascension");
15✔
1557
const QString ObsListDialog::SORTING_BY_DEC           = QStringLiteral("declination");
15✔
1558
const QString ObsListDialog::SORTING_BY_MAGNITUDE     = QStringLiteral("magnitude");
15✔
1559
const QString ObsListDialog::SORTING_BY_CONSTELLATION = QStringLiteral("constellation");
15✔
1560
const QString ObsListDialog::SORTING_BY_DATE          = QStringLiteral("date");
15✔
1561
const QString ObsListDialog::SORTING_BY_LOCATION      = QStringLiteral("location");
15✔
1562
const QString ObsListDialog::SORTING_BY_LANDSCAPE_ID  = QStringLiteral("landscapeID");
15✔
1563

1564
const QString ObsListDialog::CUSTOM_OBJECT = QStringLiteral("CustomObject");
15✔
1565

1566
const QString ObsListDialog::DASH = QString(QChar(0x2014));
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