[education/kstars] /: Make some usability improvements, especially in the Find Dialog

Jasem Mutlaq null at kde.org
Sun Mar 13 09:48:59 GMT 2022


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


More information about the kde-doc-english mailing list