Git commit 993692eaaa76820d33dc8291892b54e89a4298ff by Jasem Mutlaq, on behalf of Akarsh Simha. Committed on 13/03/2022 at 09:48. Pushed by mutlaqja into branch 'master'.
Make some usability improvements, especially in the Find Dialog This MR: * Makes some error / warning messages more clear * Reformats the internet search button in the find dialog * Reformats the major and minor axis display in the popup menu for DSOs * Updates the docs on the popup menu * Fixes a bug in the find dialog with object names (eg: NGC 1) which are substrings of many entries in the database (eg: NGC 100, NGC 1201, ...). This also fixes a bug where some objects in the observing wishlist would get incorrectly substituted by other objects! * Prevents the user from searching the internet for an object that already is in the KStars database * More proactively enables/disables the "OK" and "Internet Search" buttons depending on the situation * Highlights the "Internet Search" button and the "OK" button depending on which action will be defaulted to by hitting Enter in the text entry M +6 -4 doc/commands.docbook M +16 -16 kstars/catalogsdb/catalogsdb.cpp M +28 -8 kstars/dialogs/finddialog.cpp M +3 -0 kstars/dialogs/finddialog.h M +1 -1 kstars/dialogs/finddialog.ui M +5 -1 kstars/kspopupmenu.cpp M +15 -14 kstars/skyqpainter.cpp M +2 -2 kstars/tools/observinglist.cpp https://invent.kde.org/education/kstars/commit/993692eaaa76820d33dc8291892b54e89a4298ff diff --git a/doc/commands.docbook b/doc/commands.docbook index efcc71a0b..f36051a21 100644 --- a/doc/commands.docbook +++ b/doc/commands.docbook @@ -1006,10 +1006,12 @@ the relevant object type [in brackets].</para> <variablelist> <varlistentry> <term>[All]</term> -<listitem><para> -Identification and type: The top one to three lines are devoted to the -name(s) of the object, and its type. For stars, the Spectral Type -is also shown here. +<listitem><para> Identification and quick info: The top several lines +are devoted to the name(s) of the object, its type and the +constellation in which it lies. The magnitude is shown with the +superscript 'm' if it is available. For stars, the Spectral Type is +also shown here. For deep-sky objects, the dimensions, if known, are +shown in arcminutes (eg: 6'×3') and the source catalog is also shown. </para></listitem> </varlistentry> diff --git a/kstars/catalogsdb/catalogsdb.cpp b/kstars/catalogsdb/catalogsdb.cpp index cc7fae82b..02958d8b1 100644 --- a/kstars/catalogsdb/catalogsdb.cpp +++ b/kstars/catalogsdb/catalogsdb.cpp @@ -484,30 +484,30 @@ CatalogObjectList DBManager::fetch_objects(QSqlQuery &query) const } CatalogObjectList DBManager::find_objects_by_name(const QString &name, const int limit, - const bool exactMatchOnly) + const bool exactMatchOnly) { QMutexLocker _{ &m_mutex }; + // limit < 0 is a sentinel value for unlimited + if (limit == 0) + return CatalogObjectList(); + // search for an exact match first - if (limit == 1) - { - m_q_obj_by_name_exact.bindValue(":name", name); - const auto &objs = fetch_objects(m_q_obj_by_name_exact); + m_q_obj_by_name_exact.bindValue(":name", name); + CatalogObjectList objs { fetch_objects(m_q_obj_by_name_exact) }; - if (objs.size() > 0) - { - return objs; - } - if (exactMatchOnly) - { - return CatalogObjectList(); - } - } + if ((limit == 1 && objs.size() > 0) || exactMatchOnly) + return objs; + + Q_ASSERT(objs.size() <= 1); m_q_obj_by_name.bindValue(":name", name); - m_q_obj_by_name.bindValue(":limit", limit); + m_q_obj_by_name.bindValue(":limit", int(limit - objs.size())); + + CatalogObjectList moreObjects = fetch_objects(m_q_obj_by_name); + moreObjects.splice(moreObjects.begin(), objs); + return moreObjects; - return fetch_objects(m_q_obj_by_name); } CatalogObjectList DBManager::find_objects_by_name(const int catalog_id, diff --git a/kstars/dialogs/finddialog.cpp b/kstars/dialogs/finddialog.cpp index bf68766d4..d3eaa1d15 100644 --- a/kstars/dialogs/finddialog.cpp +++ b/kstars/dialogs/finddialog.cpp @@ -80,6 +80,7 @@ FindDialog::FindDialog(QWidget *parent) connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); okB = buttonBox->button(QDialogButtonBox::Ok); + okB->setEnabled(false); QPushButton *detailB = new QPushButton(i18n("Details...")); buttonBox->addButton(detailB, QDialogButtonBox::ActionRole); @@ -134,6 +135,7 @@ FindDialog::FindDialog(QWidget *parent) connect(ui->SearchBox, &QLineEdit::returnPressed, this, &FindDialog::slotOk); connect(ui->FilterType, &QComboBox::currentTextChanged, this, &FindDialog::enqueueSearch); connect(ui->SearchList, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotOk())); + connect(ui->SearchList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FindDialog::slotUpdateButtons); // Set focus to object name edit ui->SearchBox->setFocus(); @@ -214,8 +216,6 @@ void FindDialog::initSelection() ui->SearchList->selectionModel()->select(selectItem, QItemSelectionModel::ClearAndSelect); ui->SearchList->scrollTo(selectItem); ui->SearchList->setCurrentIndex(selectItem); - - okB->setEnabled(true); } } @@ -293,6 +293,7 @@ void FindDialog::filterByType() void FindDialog::filterList() { QString SearchText = processSearchText(); + bool exactMatchExists = !(m_manager.find_objects_by_name(SearchText, 1, true).empty()); const auto &objs = m_manager.find_objects_by_name(SearchText, 10); for (const auto &obj : objs) { @@ -301,10 +302,12 @@ void FindDialog::filterList() } sortModel->setFilterFixedString(SearchText); - ui->InternetSearchButton->setText(i18n("or search the Internet for %1", SearchText)); + ui->InternetSearchButton->setText(i18n("Search the Internet for %1", SearchText.isEmpty() ? i18nc("no text to search for", + "(nothing)") : SearchText)); filterByType(); initSelection(); + bool enableInternetSearch = (!exactMatchExists) && (ui->FilterType->currentIndex() == 0); //Select the first item in the list that begins with the filter string if (!SearchText.isEmpty()) { @@ -323,17 +326,30 @@ void FindDialog::filterList() selectItem, QItemSelectionModel::ClearAndSelect); ui->SearchList->scrollTo(selectItem); ui->SearchList->setCurrentIndex(selectItem); - - okB->setEnabled(true); } } - ui->InternetSearchButton->setEnabled(!mItems.contains( - SearchText)); // Disable searching the internet when an exact match for SearchText exists in KStars + ui->InternetSearchButton->setEnabled(enableInternetSearch && !mItems.contains( + SearchText, Qt::CaseInsensitive)); // Disable searching the internet when an exact match for SearchText exists in KStars } else ui->InternetSearchButton->setEnabled(false); listFiltered = true; + slotUpdateButtons(); +} + +void FindDialog::slotUpdateButtons() +{ + okB->setEnabled(ui->SearchList->selectionModel()->hasSelection()); + + if (okB->isEnabled()) + { + okB->setDefault(true); + } + else if (ui->InternetSearchButton->isEnabled()) + { + ui->InternetSearchButton->setDefault(true); + } } SkyObject *FindDialog::selectedObject() const @@ -392,13 +408,17 @@ QString FindDialog::processSearchText(QString searchText) void FindDialog::slotOk() { //If no valid object selected, show a sorry-box. Otherwise, emit accept() + if (ui->SearchBox->text().isEmpty()) + { + return; + } SkyObject *selObj; if (!listFiltered) { filterList(); } selObj = selectedObject(); - finishProcessing(selObj, Options::resolveNamesOnline()); + finishProcessing(selObj, Options::resolveNamesOnline() && ui->InternetSearchButton->isEnabled()); } void FindDialog::slotResolve() diff --git a/kstars/dialogs/finddialog.h b/kstars/dialogs/finddialog.h index c688643d2..b05827748 100644 --- a/kstars/dialogs/finddialog.h +++ b/kstars/dialogs/finddialog.h @@ -107,6 +107,9 @@ class FindDialog : public QDialog void slotDetails(); + /** Enable/disable the OK button, and set the default button */ + void slotUpdateButtons(); + protected: /** * Process Keystrokes. The Up and Down arrow keys are used to select the diff --git a/kstars/dialogs/finddialog.ui b/kstars/dialogs/finddialog.ui index 9b0f8eacb..f1274d338 100644 --- a/kstars/dialogs/finddialog.ui +++ b/kstars/dialogs/finddialog.ui @@ -167,7 +167,7 @@ <item> <widget class="QPushButton" name="InternetSearchButton"> <property name="text"> - <string>or search Internet for (nothing)</string> + <string>Search the Internet for (nothing)</string> </property> </widget> </item> diff --git a/kstars/kspopupmenu.cpp b/kstars/kspopupmenu.cpp index b2b3ac76c..a598b6492 100644 --- a/kstars/kspopupmenu.cpp +++ b/kstars/kspopupmenu.cpp @@ -235,7 +235,11 @@ void KSPopupMenu::createCatalogObjectMenu(CatalogObject *obj) .arg(obj->getCatalog().name); if (obj->a() > 0) - info += QString("<br>[a=%1′, b=%2′]").arg(obj->a()).arg(obj->b()); + { + float a = obj->a(); + float b = obj->b() > 0 ? obj->b() : obj->a(); // Assume circular if a != 0 but b == 0 + info += QString("<br>%1′×%2′").arg(a).arg(b); + } initPopupMenu(obj, name, typeName, info); addLinksToMenu(obj); diff --git a/kstars/skyqpainter.cpp b/kstars/skyqpainter.cpp index 2be8079a0..a4f254c42 100644 --- a/kstars/skyqpainter.cpp +++ b/kstars/skyqpainter.cpp @@ -20,6 +20,7 @@ #include "skycomponents/skymapcomposite.h" #include "skycomponents/solarsystemcomposite.h" #include "skycomponents/earthshadowcomponent.h" +#include "skyobjects/skyobject.h" #include "skyobjects/constellationsart.h" #include "skyobjects/catalogobject.h" #include "skyobjects/ksasteroid.h" @@ -802,19 +803,19 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl }; } - switch (type) + switch ((SkyObject::TYPE)type) { - case 0: - case 1: //catalog star + case SkyObject::STAR: + case SkyObject::CATALOG_STAR: //catalog star //Some NGC/IC objects are stars...changed their type to 1 (was double star) if (size < 2.) size = 2.; lambdaDrawEllipse(x - size / 2., y - size / 2., size, size); break; - case 2: //Planet + case SkyObject::PLANET: //Planet break; - case 3: //Open cluster; draw circle of points - case 13: // Asterism + case SkyObject::OPEN_CLUSTER: //Open cluster; draw circle of points + case SkyObject::ASTERISM: // Asterism { tempBrush = brush(); color = pen().color().name(); @@ -838,7 +839,7 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl setBrush(tempBrush); break; } - case 4: //Globular Cluster + case SkyObject::GLOBULAR_CLUSTER: //Globular Cluster if (size < 2.) size = 2.; save(); @@ -850,8 +851,8 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl restore(); //reset coordinate system break; - case 5: //Gaseous Nebula - case 15: // Dark Nebula + case SkyObject::GASEOUS_NEBULA: //Gaseous Nebula + case SkyObject::DARK_NEBULA: // Dark Nebula save(); translate(x, y); rotate(positionAngle); //rotate the coordinate system @@ -862,7 +863,7 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl lambdaDrawLine(dx1, dy2, dx1, dy1); restore(); //reset coordinate system break; - case 6: //Planetary Nebula + case SkyObject::PLANETARY_NEBULA: //Planetary Nebula if (size < 2.) size = 2.; save(); @@ -876,7 +877,7 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl lambdaDrawLine(dx2, 0., dx2 + size / 2., 0.); restore(); //reset coordinate system break; - case 7: //Supernova remnant // FIXME: Why is SNR drawn different from a gaseous nebula? + case SkyObject::SUPERNOVA_REMNANT: //Supernova remnant // FIXME: Why is SNR drawn different from a gaseous nebula? save(); translate(x, y); rotate(positionAngle); //rotate the coordinate system @@ -887,8 +888,8 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl lambdaDrawLine(dx1, 0., 0., dy1); restore(); //reset coordinate system break; - case 8: //Galaxy - case 16: // Quasar + case SkyObject::GALAXY: //Galaxy + case SkyObject::QUASAR: // Quasar color = pen().color().name(); if (size < 1. && zoom > 20 * MINZOOM) size = 3.; //force ellipse above zoomFactor 20 @@ -907,7 +908,7 @@ void SkyQPainter::drawDeepSkySymbol(const QPointF &pos, int type, float size, fl drawPoint(QPointF(x, y)); } break; - case 14: // Galaxy cluster - draw a dashed circle + case SkyObject::GALAXY_CLUSTER: // Galaxy cluster - draw a dashed circle { tempBrush = brush(); setBrush(QBrush()); diff --git a/kstars/tools/observinglist.cpp b/kstars/tools/observinglist.cpp index 0afd40ac8..b2aca6041 100644 --- a/kstars/tools/observinglist.cpp +++ b/kstars/tools/observinglist.cpp @@ -255,7 +255,7 @@ void ObservingList::slotAddObject(const SkyObject *_obj, bool session, bool upda if (finalObjectName.isEmpty()) { - KSNotification::sorry(i18n("Unnamed stars are not supported in the observing lists")); + KSNotification::sorry(i18n("Stars and objects whose names KStars does not know are not supported in the observing lists")); return; } @@ -539,7 +539,7 @@ void ObservingList::slotNewSelection() //Change the m_currentImageFileName, DSS/SDSS Url to correspond to the new object setCurrentImage(o.data()); ui->SearchImage->setEnabled(true); - if (newName != i18n("star")) + if (currentObject()->hasName()) { //Display the current object's user notes in the NotesEdit //First, save the last object's user log to disk, if necessary
