From ff1df3b1bbd507bc1f2a273fb5b20376831a0adc Mon Sep 17 00:00:00 2001 From: Georg Zotti Date: Tue, 12 Sep 2023 19:34:26 +0200 Subject: [PATCH] Fix observing list import/export (#3207) ObsList fixes - Fix list export (Fix #3206) - Add last-edited date - display newly-loaded list (last when loading multiple lists) - use system time, not simulation time, for list timestamping - export single .sol and complete .ol lists. - import single .sol, complete .ol or .json lists. - SUG: Update about ObsLists --- guide/ch_tour.tex | 15 +++--- src/gui/ObsListDialog.cpp | 98 ++++++++++++++++++++++++--------------- src/gui/ObsListDialog.hpp | 8 +++- src/gui/obsListDialog.ui | 10 ++++ 4 files changed, 85 insertions(+), 46 deletions(-) diff --git a/guide/ch_tour.tex b/guide/ch_tour.tex index b26c7689a955e..c49555b17bb8a 100644 --- a/guide/ch_tour.tex +++ b/guide/ch_tour.tex @@ -298,9 +298,7 @@ \section{Taking Screenshots} \section{Observing Lists (Bookmarks)} \label{sec:tour:bookmarks} -You can store your favourite objects or views in observing lists. This -feature extends the earlier bookmarks feature. - +You can store your favourite objects or views in observing lists. Press \key{Alt+B} or \guibutton[0.75]{2.5}{bt_bookmarks.png} to call up the dialog. A bookmarks file from previous versions will be imported and converted to the new format. You can however create an @@ -319,14 +317,17 @@ \section{Observing Lists (Bookmarks)} to restore. Additionally, the field of view may be relevant. To store these data and later retrieve them, use the respective checkboxes. -You can also export the current list with the according -button, or import such an exported list on another system. Lists are identified with an +You can also export the current list or all lists with the according +button, or import such an exported list on another system. +To export the current list, keep the default \texttt{.sol} file type in the filename dialog. +To export all your lists, use the \texttt{.ol} file type in the filename dialog. +Lists are identified with an Universally Unique Identifier (UUID) which we call OLUD (Observing List Unique Identifier). On importing a list, existing lists with the same OLUD may be replaced after a warning. During editing, storing a list with an existing name is prevented. The list import may however import a list with an existing name as long as the OLUD is different. -To transfer all your lists to another system, copy, rename and import -(or just copy, to replace the existing) the full file \file{observingLists.json} +To transfer all your lists to another system, export them as \texttt{.ol} file, or +copy, rename and import (or just copy, to replace the existing) the full file \file{observingLists.json} from the \file{data/} subdirectory of your user directory (see section~\ref{sec:Directories}). diff --git a/src/gui/ObsListDialog.cpp b/src/gui/ObsListDialog.cpp index c190bf8bdf557..c1e983506ffdb 100644 --- a/src/gui/ObsListDialog.cpp +++ b/src/gui/ObsListDialog.cpp @@ -141,16 +141,8 @@ void ObsListDialog::createDialogContent() ui->treeView->setModel(itemModel); ui->treeView->header()->setSectionsMovable(false); ui->treeView->hideColumn(ColumnUUID); - ui->treeView->header()->setSectionResizeMode(ColumnDesignation, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnNameI18n, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnType, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnRa, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnDec, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnMagnitude, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnConstellation, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnDate, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnLocation, QHeaderView::ResizeToContents); - ui->treeView->header()->setSectionResizeMode(ColumnLandscapeID, QHeaderView::ResizeToContents); + for (int c=ColumnDesignation; c<=ColumnLandscapeID; c++) + ui->treeView->header()->setSectionResizeMode(c, QHeaderView::ResizeToContents); ui->treeView->header()->setStretchLastSection(true); //Enable the sort for columns ui->treeView->setSortingEnabled(true); @@ -177,14 +169,15 @@ void ObsListDialog::createDialogContent() observingLists = QMap(); // Create one default empty list // Creation date - const double JD = core->getJD(); + const double JD = StelUtils::getJDFromSystem(); const QString listCreationDate = StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " "); QVariantMap emptyList = { // Name, description, current date for the list, current sorting {KEY_NAME, qc_("new list", "default name for observing list if none is available")}, {KEY_DESCRIPTION, QString()}, {KEY_SORTING, QString()}, - {KEY_CREATION_DATE, listCreationDate }}; + {KEY_CREATION_DATE, listCreationDate }, + {KEY_LAST_EDIT, listCreationDate }}; observingLists.insert(olud, emptyList); jsonMap.insert(KEY_OBSERVING_LISTS, observingLists); @@ -432,6 +425,7 @@ void ObsListDialog::loadSelectedList() ui->listNameLineEdit->setText(currentListName); ui->descriptionLineEdit->setText(observingListMap.value(KEY_DESCRIPTION).toString()); ui->creationDateLineEdit->setText(observingListMap.value(KEY_CREATION_DATE).toString()); + ui->lastEditLineEdit->setText(observingListMap.value(KEY_LAST_EDIT, observingListMap.value(KEY_CREATION_DATE)).toString()); if (observingListMap.value(KEY_OBJECTS).canConvert()) { @@ -662,7 +656,7 @@ QHash ObsListDialog::loadBookmarksFil /* * Save the bookmarks into observingLists QVariantMap */ -void ObsListDialog::saveBookmarksHashInObservingLists(const QHash &bookmarksHash) +QString ObsListDialog::saveBookmarksHashInObservingLists(const QHash &bookmarksHash) { // Creation date double JD = StelUtils::getJDFromSystem(); // Mark with current system time @@ -672,6 +666,7 @@ void ObsListDialog::saveBookmarksHashInObservingLists(const QHash bookmarksHash=loadBookmarksFile(jsonFile); // Put them to the main list. Note that this may create another list named "bookmarks list", however, with a different OLUD than the existing. - saveBookmarksHashInObservingLists(bookmarksHash); + selectedOlud=saveBookmarksHashInObservingLists(bookmarksHash); } } else @@ -1032,6 +1047,10 @@ void ObsListDialog::importListButtonPressed() jsonFile.flush(); jsonFile.close(); tainted=false; + + // Now we have stored to file, but the program is not aware of the new lists! + loadListNames(); // also populate Combobox and make sure at least some defaultOlud exists. + loadSelectedList(); } catch (std::runtime_error &e) { qWarning() << "[ObservingList Creation/Edition] File format is wrong! Error: " << e.what(); messageBox(q_("Error"), q_("File format is wrong!")); @@ -1094,7 +1113,7 @@ void ObsListDialog::addObjectButtonPressed() if (!selectedObject.isEmpty()) { -// TBD: this test should prevent adding duplicate entries, but fails. Maybe for V23.2! +// TBD: this test should prevent adding duplicate entries, but fails. Maybe for V23.4! // // No duplicate item in the same list // bool is_already_in_list = false; // QHash::iterator i; @@ -1301,6 +1320,8 @@ void ObsListDialog::switchEditMode(bool enableEditMode, bool newList) ui->creationDateLabel->setVisible(!isEditMode); // Creation date: ui->creationDateLineEdit->setVisible(!isEditMode); // + ui->lastEditLabel->setVisible(!isEditMode); // Last edit date: + ui->lastEditLineEdit->setVisible(!isEditMode); // // line with optional store items ui->alsoStoreLabel->setVisible(isEditMode); // Also store @@ -1374,19 +1395,21 @@ void ObsListDialog::setFlagUseFov(bool b) /* * Prepare the currently displayed/edited list for storage - * Returns QVariantList with keys={creation date, description, name, objects, sorting} + * Returns QVariantList with keys={creation date, last edit, description, name, objects, sorting} */ QVariantMap ObsListDialog::prepareCurrentList(QHash &itemHash) { - // Creation date - const double JD = core->getJD(); - const QString listCreationDate = StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " "); + // Edit date + const double JD = StelUtils::getJDFromSystem(); + const QString lastEditDate = StelUtils::julianDayToISO8601String(JD + core->getUTCOffset(JD) / 24.).replace("T", " "); QVariantMap currentList = { // Name, description, current date for the list, current sorting {KEY_NAME, currentListName}, {KEY_DESCRIPTION, ui->descriptionLineEdit->text()}, {KEY_SORTING, sorting}, - {KEY_CREATION_DATE, listCreationDate }}; + {KEY_CREATION_DATE, ui->creationDateLineEdit->text()}, + {KEY_LAST_EDIT, lastEditDate } + }; // List of objects QVariantList listOfObjects; @@ -1465,6 +1488,7 @@ const QString ObsListDialog::SHORT_NAME_VALUE = QStringLiteral("Observ const QString ObsListDialog::KEY_DEFAULT_LIST_OLUD = QStringLiteral("defaultListOlud"); const QString ObsListDialog::KEY_OBSERVING_LISTS = QStringLiteral("observingLists"); const QString ObsListDialog::KEY_CREATION_DATE = QStringLiteral("creation date"); +const QString ObsListDialog::KEY_LAST_EDIT = QStringLiteral("last edit"); const QString ObsListDialog::KEY_BOOKMARKS = QStringLiteral("bookmarks"); const QString ObsListDialog::KEY_NAME = QStringLiteral("name"); const QString ObsListDialog::KEY_NAME_I18N = QStringLiteral("nameI18n"); diff --git a/src/gui/ObsListDialog.hpp b/src/gui/ObsListDialog.hpp index da885026aff2d..2b2ac3652735e 100644 --- a/src/gui/ObsListDialog.hpp +++ b/src/gui/ObsListDialog.hpp @@ -50,6 +50,7 @@ //! "observingLists": { //! "{84744f7b-c353-45b0-8394-69af2a1e0917}": { // List OLUD. This is a unique ID //! "creation date": "2022-09-29 20:05:07", +//! "last edit": "2022-11-29 22:15:38", //! "description": "Bookmarks of previous Stellarium version.", //! "name": "bookmarks list", //! "objects": [ // List is stored alphabetized, but given here in contextualized order for clarity. @@ -75,6 +76,7 @@ //! }, // end of list 84744f7b-... //! "{bd40274c-a321-40c1-a6f3-bc8f11026326}": { // List OLUD of next list. //! "creation date": "2022-12-21 11:12:39", +//! "last edit": "2023-07-29 22:23:38", //! "description": "test of unification", //! "name": "mine_edited", //! "objects": [ @@ -113,7 +115,7 @@ //! Fix a confusion introduced in the 1.* series: //! The ObsList has entries //! - "designation": The catalog number (DSO), HIP number (star), or canonical name (planet). -//! - "nameI18n": translated name for display. Actually this is bad in case of list exchange. +//! - "nameI18n": translated name for display. Actually this is bad design in case of list exchange. //! - "type": As given by ObjectP->getType() or getObjectType()? This was inconsistent. //! FIXES: //! - "designation" used in combination with type as real unique object ID. For DSO, getDSODesignationWIC() must be used. @@ -292,7 +294,8 @@ class ObsListDialog : public StelDialog QVariantMap prepareCurrentList(QHash &itemHash); //! Put the bookmarks in bookmarksHash into observingLists under the listname "bookmarks list". Does not write JSON! - void saveBookmarksHashInObservingLists(const QHash &bookmarksHash); + //! @return OLUD of the imported bookmarks list. + QString saveBookmarksHashInObservingLists(const QHash &bookmarksHash); //! Sort the obsListTreeView by the column name given in parameter void sortObsListTreeViewByColumnName(const QString &columnName); @@ -380,6 +383,7 @@ private slots: static const QString KEY_DEFAULT_LIST_OLUD; static const QString KEY_OBSERVING_LISTS; static const QString KEY_CREATION_DATE; + static const QString KEY_LAST_EDIT; static const QString KEY_BOOKMARKS; static const QString KEY_NAME; static const QString KEY_NAME_I18N; diff --git a/src/gui/obsListDialog.ui b/src/gui/obsListDialog.ui index aac433a244e89..f21022225d81f 100644 --- a/src/gui/obsListDialog.ui +++ b/src/gui/obsListDialog.ui @@ -259,6 +259,16 @@ + + + + Last edit: + + + + + +