Git commit cd028a5753ebed609a209567560f1a341747faa4 by Hy Murveit.
Committed on 20/08/2023 at 09:09.
Pushed by murveit into branch 'master'.

Implement refresh button. Avoid adding to status widget when not in main thread.

M  +1    -1    doc/config.docbook
M  +2    -0    kstars/options/opsimageoverlay.cpp
M  +1    -1    kstars/options/opsimageoverlay.ui
M  +30   -29   kstars/skycomponents/imageoverlaycomponent.cpp
M  +4    -1    kstars/skycomponents/imageoverlaycomponent.h

https://invent.kde.org/education/kstars/-/commit/cd028a5753ebed609a209567560f1a341747faa4

diff --git a/doc/config.docbook b/doc/config.docbook
index 9e5b759bf..642900f33 100644
--- a/doc/config.docbook
+++ b/doc/config.docbook
@@ -1192,7 +1192,7 @@ Image overlays are custom images (typically .jpg) that 
are rendered onto the sky
 The <guilabel>Image Overlays</guilabel> page lets you configure whether image 
overlays will be shown on the skymap, and helps you add them to the system. The 
image at the start of this section shows the skymap with image overlays enabled 
and some image overlays loaded.
 </para>
 <para>
-  Each time it starts up, KStars looks for new image overlay images in a 
special directory, parallel to the logs directory, named imageOverlays. On 
Linux this can be found in ~/.local/share/kstars/imageOverlays. The exact 
location for your system can be found by clicking the <guilabel>Overlay 
Directory</guilabel> button near the top of the Image Overlays config page 
shown at the top of this section. To start, add your images to that directory. 
Ideally, for performance reasons these aren't massive files, but probably 
images with widths 1000 or 2000 should be fine. To add additional images in the 
future,  add them to the same directory and restart KStars.
+  Each time it starts up, KStars looks for new image overlay images in a 
special directory, parallel to the logs directory, named imageOverlays. On 
Linux this can be found in ~/.local/share/kstars/imageOverlays. The exact 
location for your system can be found by clicking the <guilabel>Overlay 
Directory</guilabel> button near the top of the Image Overlays config page 
shown at the top of this section. To start, add your images to that directory. 
Ideally, for performance reasons these aren't massive files, but probably 
images with widths 1000 or 2000 should be fine. To add additional images in the 
future,  add them to the same directory and click the refresh button or restart 
KStars. To remove overlays, remove them from the directory and click the 
refresh button or restart KStars.
 </para>
 <para>
 Start KStars once you have images in the imageOverlays directory. If you then 
go to the Image Overlays config page, you should see the new files listed in 
the table. The new images will show their status as "Unprocessed". Only images 
whose status is "OK" are displayed on the SkyMap. That is because KStars needs 
to know the sky location, size, and orientation for these images before it can 
display them. To change the status to OK you need to plate-solve the images or 
add the required information manually--see below.
diff --git a/kstars/options/opsimageoverlay.cpp 
b/kstars/options/opsimageoverlay.cpp
index a5c4679e8..5ff11e864 100644
--- a/kstars/options/opsimageoverlay.cpp
+++ b/kstars/options/opsimageoverlay.cpp
@@ -35,6 +35,8 @@ OpsImageOverlay::OpsImageOverlay() : 
QFrame(KStars::Instance())
                 KStarsData::Instance()->skyComposite()->imageOverlay());
     connect(solveButton, &QPushButton::clicked, overlayComponent, 
&ImageOverlayComponent::startSolving,
             Qt::UniqueConnection);
+    connect(refreshB, &QPushButton::clicked, overlayComponent, 
&ImageOverlayComponent::reload,
+            Qt::UniqueConnection);
     connect(kcfg_ShowImageOverlays, &QCheckBox::stateChanged, [](int state)
     {
         Options::setShowImageOverlays(state);
diff --git a/kstars/options/opsimageoverlay.ui 
b/kstars/options/opsimageoverlay.ui
index 4d78bf233..85ca38c8e 100644
--- a/kstars/options/opsimageoverlay.ui
+++ b/kstars/options/opsimageoverlay.ui
@@ -162,7 +162,7 @@
              </size>
             </property>
             <property name="toolTip">
-             <string>Refresh</string>
+              <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Refresh 
from the overlay directory. Add overlays that have been added there, and remove 
overlays that are no longer there.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
             </property>
             <property name="text">
              <string/>
diff --git a/kstars/skycomponents/imageoverlaycomponent.cpp 
b/kstars/skycomponents/imageoverlaycomponent.cpp
index 40eb4205a..bd1fa621e 100644
--- a/kstars/skycomponents/imageoverlaycomponent.cpp
+++ b/kstars/skycomponents/imageoverlaycomponent.cpp
@@ -130,6 +130,7 @@ ImageOverlayComponent::ImageOverlayComponent(SkyComposite 
*parent) : SkyComponen
     dir.mkpath(".");
     m_Directory = dir.absolutePath();
     connect(&m_TryAgainTimer, &QTimer::timeout, this, 
&ImageOverlayComponent::tryAgain, Qt::UniqueConnection);
+    connect(this, &ImageOverlayComponent::updateLog, this, 
&ImageOverlayComponent::updateStatusDisplay, Qt::UniqueConnection);
 
     // Get the latest from the User DB
     loadFromUserDB();
@@ -160,7 +161,7 @@ void ImageOverlayComponent::cellChanged(int row, int col)
         {
             item->setText(dms(overlay.m_RA).toHMSString());
             QString msg = i18n("Bad RA string entered for %1. Reset to 
original value.", overlay.m_Filename);
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
         }
         else
             // Re-format the user-entered value.
@@ -174,7 +175,7 @@ void ImageOverlayComponent::cellChanged(int row, int col)
         {
             item->setText(toDecString(overlay.m_DEC));
             QString msg = i18n("Bad DEC string entered for %1. Reset to 
original value.", overlay.m_Filename);
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
         }
         else
             item->setText(toDecString(decDMS));
@@ -187,7 +188,7 @@ void ImageOverlayComponent::cellChanged(int row, int col)
         {
             item->setText(QString("%1").arg(overlay.m_Orientation, 0, 'f', 2));
             QString msg = i18n("Bad orientation angle string entered for %1. 
Reset to original value.", overlay.m_Filename);
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
         }
     }
     else if (col == ARCSEC_PER_PIXEL_COL)
@@ -198,7 +199,7 @@ void ImageOverlayComponent::cellChanged(int row, int col)
         {
             item->setText(QString("%1").arg(overlay.m_ArcsecPerPixel, 0, 'f', 
2));
             QString msg = i18n("Bad scale angle string entered for %1. Reset 
to original value.", overlay.m_Filename);
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
         }
     }
     connect(m_ImageOverlayTable, &QTableWidget::cellChanged, this, 
&ImageOverlayComponent::cellChanged, Qt::UniqueConnection);
@@ -228,7 +229,7 @@ void ImageOverlayComponent::statusCellChanged(int row)
         if (!raOK || raDMS.Degrees() == 0)
         {
             QString msg = i18n("Cannot set status to OK. Legal non-0 RA value 
required.");
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
             failed = true;
         }
 
@@ -239,7 +240,7 @@ void ImageOverlayComponent::statusCellChanged(int row)
         if (!decOK)
         {
             QString msg = i18n("Cannot set status to OK. Legal non-0 DEC value 
required.");
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
             failed = true;
         }
 
@@ -250,7 +251,7 @@ void ImageOverlayComponent::statusCellChanged(int row)
         if (!angleOK || angle > 360 || angle < -360)
         {
             QString msg = i18n("Cannot set status to OK. Legal orientation 
value required.");
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
             failed = true;
         }
 
@@ -261,7 +262,7 @@ void ImageOverlayComponent::statusCellChanged(int row)
         if (!scaleOK || scale < 0 || scale > 1000)
         {
             QString msg = i18n("Cannot set status to OK. Legal non-0 a-s/px 
value required.");
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
             failed = true;
         }
 
@@ -291,7 +292,7 @@ void ImageOverlayComponent::statusCellChanged(int row)
             }
             saveToUserDB();
             QString msg = i18n("Stored OK status for %1.", 
m_Overlays[row].m_Filename);
-            updateStatusDisplay(msg);
+            emit updateLog(msg);
         }
     }
     connect(m_ImageOverlayTable, &QTableWidget::cellChanged, this, 
&ImageOverlayComponent::cellChanged, Qt::UniqueConnection);
@@ -383,7 +384,7 @@ void ImageOverlayComponent::updateTable()
 {
     // Get the list of files from the image overlay directory.
     QDir directory(m_Directory);
-    updateStatusDisplay(i18n("Updating from directory: %1", m_Directory));
+    emit updateLog(i18n("Updating from directory: %1", m_Directory));
     QStringList images = directory.entryList(QStringList() << "*", 
QDir::Files);
     QSet<QString> imageFiles;
     foreach(QString filename, images)
@@ -432,8 +433,8 @@ void ImageOverlayComponent::updateTable()
             numNew++;
         }
     }
-    updateStatusDisplay(i18n("%1 overlays (%2 new, %3 deleted) %4 solved", 
m_Overlays.size(), numNew, numDeleted,
-                             numAvailable()));
+    emit updateLog(i18n("%1 overlays (%2 new, %3 deleted) %4 solved", 
m_Overlays.size(), numNew, numDeleted,
+                        numAvailable()));
     m_TableGroupBox->setTitle(i18n("Image Overlays.  %1 images, %2 
available.", m_Overlays.size(), numAvailable()));
 
     initializeGui();
@@ -447,13 +448,13 @@ void ImageOverlayComponent::loadAllImageFiles()
 
 void ImageOverlayComponent::loadImageFileLoop()
 {
-    updateStatusDisplay(i18n("Loading image files..."));
+    emit updateLog(i18n("Loading image files..."));
     while (loadImageFile());
     int num = 0;
     for (const auto &o : m_Overlays)
         if (o.m_Img.get() != nullptr)
             num++;
-    updateStatusDisplay(i18n("%1 image files loaded.", num));
+    emit updateLog(i18n("%1 image files loaded.", num));
     // Restore editing for the table.
     m_ImageOverlayTable->setEditTriggers(m_EditTriggers);
     m_Initialized = true;
@@ -593,9 +594,9 @@ void ImageOverlayComponent::solveImage(const QString 
&filename)
     connect(m_Solver.get(), &SolverUtils::done, this, 
&ImageOverlayComponent::solverDone, Qt::UniqueConnection);
 
     if (m_RowsToSolve.size() > 1)
-        updateStatusDisplay(i18n("Solving: %1. %2 in queue.", filename, 
m_RowsToSolve.size()));
+        emit updateLog(i18n("Solving: %1. %2 in queue.", filename, 
m_RowsToSolve.size()));
     else
-        updateStatusDisplay(i18n("Solving: %1.", filename));
+        emit updateLog(i18n("Solving: %1.", filename));
 
     // If the user added some RA/DEC/Scale values to the table, they will be 
used in the solve
     // (but aren't remembered in the DB unless the solve is successful).
@@ -660,12 +661,12 @@ void ImageOverlayComponent::show()
         {
             if (m_Overlays[row].m_Status != ImageOverlay::AVAILABLE)
             {
-                updateStatusDisplay(i18n("Can't show %1. Not plate solved.", 
m_Overlays[row].m_Filename));
+                emit updateLog(i18n("Can't show %1. Not plate solved.", 
m_Overlays[row].m_Filename));
                 return;
             }
             if (m_Overlays[row].m_Img.get() == nullptr)
             {
-                updateStatusDisplay(i18n("Can't show %1. Image not loaded.", 
m_Overlays[row].m_Filename));
+                emit updateLog(i18n("Can't show %1. Image not loaded.", 
m_Overlays[row].m_Filename));
                 return;
             }
             const double ra = m_Overlays[row].m_RA;
@@ -698,7 +699,7 @@ void ImageOverlayComponent::abortSolving()
     m_RowsToSolve.clear();
     if (m_Solver)
         m_Solver->abort();
-    updateStatusDisplay(i18n("Solving aborted."));
+    emit updateLog(i18n("Solving aborted."));
     m_SolveButton->setText(i18n("Solve"));
 }
 
@@ -733,7 +734,7 @@ void ImageOverlayComponent::startSolving()
                 if ((m_Overlays[row].m_Status == ImageOverlay::AVAILABLE) &&
                         !shouldSolveAnyway(m_ImageOverlayTable, row))
                 {
-                    updateStatusDisplay(i18n("Skipping already solved: %1.", 
m_Overlays[row].m_Filename));
+                    emit updateLog(i18n("Skipping already solved: %1.", 
m_Overlays[row].m_Filename));
                     continue;
                 }
                 selectedRows.insert(row);
@@ -752,7 +753,7 @@ void ImageOverlayComponent::startSolving()
         if ((m_Overlays[row].m_Status == ImageOverlay::AVAILABLE) &&
                 !shouldSolveAnyway(m_ImageOverlayTable, row))
         {
-            updateStatusDisplay(i18n("%1 already solved. Skipping.", 
filename));
+            emit updateLog(i18n("%1 already solved. Skipping.", filename));
             m_RowsToSolve.removeFirst();
             if (m_RowsToSolve.size() > 0)
                 startSolving();
@@ -769,10 +770,10 @@ void ImageOverlayComponent::startSolving()
 void ImageOverlayComponent::reload()
 {
     if (!m_Initialized) return;
-    //updateTable();
-    // Problem with reload is it can crash kstars if the image load loop is 
running, or
-    // if something else is messing with m_Overlays. Need mutex protection.
-    updateStatusDisplay(i18n("Reload not yet implemented. Currently you need 
to restart KStars to do this."));
+    m_Initialized = false;
+    emit updateLog(i18n("Reloading. Image overlays temporarily disabled."));
+    updateTable();
+    loadAllImageFiles();
 }
 
 void ImageOverlayComponent::solverDone(bool timedOut, bool success, const 
FITSImage::Solution &solution,
@@ -789,13 +790,13 @@ void ImageOverlayComponent::solverDone(bool timedOut, 
bool success, const FITSIm
     QComboBox *statusItem = 
dynamic_cast<QComboBox*>(m_ImageOverlayTable->cellWidget(solverRow, 
STATUS_COL));
     if (timedOut)
     {
-        updateStatusDisplay(i18n("Solver timed out in %1s", 
QString::number(elapsedSeconds, 'f', 1)));
+        emit updateLog(i18n("Solver timed out in %1s", 
QString::number(elapsedSeconds, 'f', 1)));
         m_Overlays[solverRow].m_Status = ImageOverlay::PLATE_SOLVE_FAILURE;
         
statusItem->setCurrentIndex(static_cast<int>(m_Overlays[solverRow].m_Status));
     }
     else if (!success)
     {
-        updateStatusDisplay(i18n("Solver failed in %1s", 
QString::number(elapsedSeconds, 'f', 1)));
+        emit updateLog(i18n("Solver failed in %1s", 
QString::number(elapsedSeconds, 'f', 1)));
         m_Overlays[solverRow].m_Status = ImageOverlay::PLATE_SOLVE_FAILURE;
         
statusItem->setCurrentIndex(static_cast<int>(m_Overlays[solverRow].m_Status));
     }
@@ -814,7 +815,7 @@ void ImageOverlayComponent::solverDone(bool timedOut, bool 
success, const FITSIm
                            QString::number(solution.dec, 'f', 2),
                            QString::number(solution.pixscale, 'f', 2),
                            QString::number(solution.orientation, 'f', 2));
-        updateStatusDisplay(msg);
+        emit updateLog(msg);
 
         // Store the new values in the table.
         auto overlay = m_Overlays[solverRow];
@@ -840,7 +841,7 @@ void ImageOverlayComponent::solverDone(bool timedOut, bool 
success, const FITSIm
         startSolving();
     else
     {
-        updateStatusDisplay(i18n("Done solving. %1 available.", 
numAvailable()));
+        emit updateLog(i18n("Done solving. %1 available.", numAvailable()));
         m_TableGroupBox->setTitle(i18n("Image Overlays.  %1 images, %2 
available.", m_Overlays.size(), numAvailable()));
     }
 }
diff --git a/kstars/skycomponents/imageoverlaycomponent.h 
b/kstars/skycomponents/imageoverlaycomponent.h
index ea8a37b41..1277a2b8b 100644
--- a/kstars/skycomponents/imageoverlaycomponent.h
+++ b/kstars/skycomponents/imageoverlaycomponent.h
@@ -94,8 +94,12 @@ class ImageOverlayComponent : public QObject, public 
SkyComponent
         return m_Directory;
     };
 
+ signals:
+    void updateLog(const QString &message);
+
 private slots:
     void tryAgain();
+    void updateStatusDisplay(const QString &message);
 
 private:
     void loadFromUserDB();
@@ -104,7 +108,6 @@ private:
     void solverDone(bool timedOut, bool success, const FITSImage::Solution 
&solution, double elapsedSeconds);
     void initializeGui();
     int numAvailable();
-    void updateStatusDisplay(const QString &message);
     void cellChanged(int row, int col);
     void statusCellChanged(int row);
     void selectionChanged();

Reply via email to