diff --git a/kstars/ekos/capture/capture.h b/kstars/ekos/capture/capture.h --- a/kstars/ekos/capture/capture.h +++ b/kstars/ekos/capture/capture.h @@ -20,6 +20,7 @@ #include "indi/inditelescope.h" #include "ekos/auxiliary/filtermanager.h" #include "ekos/scheduler/schedulerjob.h" +#include "ekos/capture/sequencejob.h" #include #include @@ -311,6 +312,8 @@ */ void setSettings(const QJsonObject &settings); + bool isActiveJobAPreview() { if(!activeJob) {return false;}; return activeJob->isPreview(); } + public slots: /** \addtogroup CaptureDBusInterface diff --git a/kstars/fitsviewer/fitshistogram.h b/kstars/fitsviewer/fitshistogram.h --- a/kstars/fitsviewer/fitshistogram.h +++ b/kstars/fitsviewer/fitshistogram.h @@ -52,18 +52,24 @@ protected: void showEvent(QShowEvent *event); + void driftMouseOverLine(QMouseEvent *event); public slots: void applyScale(); - void updateValues(QMouseEvent *event); void updateLimits(double value); void updateSliders(int value); void checkRangeLimit(const QCPRange &range); void resizePlot(); + void toggleHideSaturated(int x); private: template void constructHistogram(); + double sliderScale; + int numDecimals; + double cutMin; + double cutMax; + histogramUI *ui { nullptr }; FITSTab *tab { nullptr }; diff --git a/kstars/fitsviewer/fitshistogram.cpp b/kstars/fitsviewer/fitshistogram.cpp --- a/kstars/fitsviewer/fitshistogram.cpp +++ b/kstars/fitsviewer/fitshistogram.cpp @@ -59,28 +59,31 @@ customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen); customPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen); - r_graph = customPlot->addGraph(); - r_graph->setBrush(QBrush(QColor(170, 40, 80))); - r_graph->setPen(QPen(Qt::red)); - //r_graph->setLineStyle(QCPGraph::lsImpulse); - - connect(ui->buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyScale())); - - connect(customPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(updateValues(QMouseEvent*))); + connect(ui->applyB, &QPushButton::clicked, this, &FITSHistogram::applyScale); connect(ui->minEdit, SIGNAL(valueChanged(double)), this, SLOT(updateLimits(double))); connect(ui->maxEdit, SIGNAL(valueChanged(double)), this, SLOT(updateLimits(double))); connect(ui->minSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliders(int))); connect(ui->maxSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliders(int))); + connect(ui->hideSaturated, &QCheckBox::stateChanged, this, &FITSHistogram::toggleHideSaturated); connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(checkRangeLimit(QCPRange))); + connect(customPlot, &QCustomPlot::mouseMove, this, &FITSHistogram::driftMouseOverLine); + sliderScale = 10; + numDecimals = 0; } void FITSHistogram::showEvent(QShowEvent *event) { Q_UNUSED(event) syncGUI(); } +void FITSHistogram::toggleHideSaturated(int x) +{ + constructHistogram(); + Q_UNUSED(x) +} + void FITSHistogram::constructHistogram() { FITSData *image_data = tab->getView()->getImageData(); @@ -141,7 +144,7 @@ uint32_t samples = fits_w * fits_h; - binCount = sqrt(samples); + binCount = static_cast(sqrt(samples)); intensity.fill(0, binCount); r_frequency.fill(0, binCount); @@ -161,28 +164,28 @@ { for (uint32_t i = 0; i < samples; i += 4) { - r_id = round((buffer[i] - fits_min) / binWidth); + r_id = static_cast(round((buffer[i] - fits_min) / binWidth)); r_frequency[r_id >= binCount ? binCount - 1 : r_id] += 4; } } else { g_frequency.fill(0, binCount); b_frequency.fill(0, binCount); - int g_offset = samples; - int b_offset = samples * 2; + int g_offset = static_cast(samples); + int b_offset = static_cast(samples * 2); for (uint32_t i = 0; i < samples; i += 4) { uint16_t g_id = 0, b_id = 0; - r_id = round((buffer[i] - fits_min) / binWidth); + r_id = static_cast(round((buffer[i] - fits_min) / binWidth)); r_frequency[r_id >= binCount ? binCount - 1 : r_id] += 4; - g_id = round((buffer[i + g_offset] - fits_min) / binWidth); + g_id = static_cast(round((buffer[i + g_offset] - fits_min) / binWidth)); g_frequency[g_id >= binCount ? binCount - 1 : g_id] += 4; - b_id = round((buffer[i + b_offset] - fits_min) / binWidth); + b_id = static_cast(round((buffer[i + b_offset] - fits_min) / binWidth)); b_frequency[b_id >= binCount ? binCount - 1 : b_id] += 4; } } @@ -201,24 +204,24 @@ for (int i = 0; i < binCount; i++) { if (r_frequency[i] > maxFrequency) - maxFrequency = r_frequency[i]; + maxFrequency = static_cast(r_frequency[i]); } } else { for (int i = 0; i < binCount; i++) { if (r_frequency[i] > maxFrequency) - maxFrequency = r_frequency[i]; + maxFrequency = static_cast(r_frequency[i]); if (g_frequency[i] > maxFrequency) - maxFrequency = g_frequency[i]; + maxFrequency = static_cast(g_frequency[i]); if (b_frequency[i] > maxFrequency) - maxFrequency = b_frequency[i]; + maxFrequency = static_cast(b_frequency[i]); } } double median = 0; - int halfCumulative = cumulativeFrequency[binCount - 1] / 2; + int halfCumulative = static_cast(cumulativeFrequency[binCount - 1] / 2); for (int i = 0; i < binCount; i++) { if (cumulativeFrequency[i] >= halfCumulative) @@ -232,7 +235,26 @@ JMIndex = cumulativeFrequency[binCount / 8] / cumulativeFrequency[binCount / 4]; qCDebug(KSTARS_FITS) << "FITHistogram: JMIndex " << JMIndex; - image_data->setMedian(median); + if(ui->hideSaturated->isChecked()) + { + intensity.removeFirst(); + intensity.removeLast(); + r_frequency.removeFirst(); + r_frequency.removeLast(); + if (image_data->channels() > 1) + { + g_frequency.removeFirst(); + g_frequency.removeLast(); + b_frequency.removeFirst(); + b_frequency.removeLast(); + } + } + + image_data->setMedian(median); + if(median<1) + sliderScale=1/median*100; + else + sliderScale=10; } void FITSHistogram::syncGUI() @@ -250,40 +272,60 @@ ui->meanEdit->setText(QString::number(image_data->getMean())); ui->medianEdit->setText(QString::number(image_data->getMedian())); + double median = image_data->getMedian(); + + if(median > 100) + numDecimals=0; + else if(median > 1) + numDecimals=2; + else if(median > .01) + numDecimals=4; + else if(median > .0001) + numDecimals=6; + else + numDecimals=10; + if(!ui->minSlider->isSliderDown()) { - ui->minEdit->setMinimum(fits_min); - ui->minEdit->setMaximum(fits_max - 1); + ui->minEdit->setDecimals(numDecimals); ui->minEdit->setSingleStep(fabs(fits_max - fits_min) / 20.0); + ui->minEdit->setMinimum(fits_min); + ui->minEdit->setMaximum(fits_max - ui->minEdit->singleStep()); //minus one step ui->minEdit->setValue(fits_min); - ui->minSlider->setMinimum(fits_min*10); - ui->minSlider->setMaximum((fits_max - 1)*10); - ui->minSlider->setSingleStep((fabs(fits_max - fits_min) / 20.0)*10); - ui->minSlider->setValue(fits_min*10); + ui->minSlider->setSingleStep(static_cast((fabs(fits_max - fits_min) / 20.0)*sliderScale)); + ui->minSlider->setMinimum(static_cast(fits_min*sliderScale)); + ui->minSlider->setMaximum(static_cast((fits_max)*sliderScale - ui->minSlider->singleStep())); + ui->minSlider->setValue(static_cast(fits_min*sliderScale)); } if(!ui->maxSlider->isSliderDown()) { - ui->maxEdit->setMinimum(fits_min + 1); - ui->maxEdit->setMaximum(fits_max); + ui->maxEdit->setDecimals(numDecimals); ui->maxEdit->setSingleStep(fabs(fits_max - fits_min) / 20.0); + ui->maxEdit->setMinimum(fits_min + ui->maxEdit->singleStep()); + ui->maxEdit->setMaximum(fits_max); ui->maxEdit->setValue(fits_max); + ui->maxSlider->setSingleStep(static_cast((fabs(fits_max - fits_min) / 20.0)*sliderScale)); + ui->maxSlider->setMinimum(static_cast((fits_min)*sliderScale + ui->maxSlider->singleStep())); + ui->maxSlider->setMaximum(static_cast(fits_max*sliderScale)); + ui->maxSlider->setValue(static_cast(fits_max*sliderScale)); - ui->maxSlider->setMinimum((fits_min + 1)*10); - ui->maxSlider->setMaximum(fits_max*10); - ui->maxSlider->setSingleStep((fabs(fits_max - fits_min) / 20.0)*10); - ui->maxSlider->setValue(fits_max*10); } connect(ui->minEdit, SIGNAL(valueChanged(double)), this, SLOT(updateLimits(double))); connect(ui->maxEdit, SIGNAL(valueChanged(double)), this, SLOT(updateLimits(double))); connect(ui->minSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliders(int))); connect(ui->maxSlider, SIGNAL(valueChanged(int)), this, SLOT(updateSliders(int))); + customPlot->clearGraphs(); + r_graph = customPlot->addGraph(); + r_graph->setBrush(QBrush(QColor(170, 40, 80))); + r_graph->setPen(QPen(Qt::red)); r_graph->setData(intensity, r_frequency); + if (image_data->channels() > 1) { g_graph = customPlot->addGraph(); @@ -305,7 +347,7 @@ customPlot->xAxis->setLabel(i18n("Intensity")); customPlot->yAxis->setLabel(i18n("Frequency")); - customPlot->xAxis->setRange(fits_min, fits_max); + customPlot->xAxis->setRange(fits_min - ui->minEdit->singleStep(), fits_max + ui->maxEdit->singleStep()); if (maxFrequency > 0) customPlot->yAxis->rescale(); @@ -499,28 +541,34 @@ { if (sender() == ui->minSlider) { - ui->minEdit->setValue(value/10.0); - if (value/10.0 > ui->maxEdit->value()) - ui->maxEdit->setValue(value/10.0 + 1); + if(value/sliderScale > ui->minEdit->value()) + { + ui->minEdit->setValue(value/sliderScale); + if (value/sliderScale > ui->maxEdit->value()) + ui->maxEdit->setValue(value/sliderScale + ui->maxEdit->singleStep()); + } } else if (sender() == ui->maxSlider) { - ui->maxEdit->setValue(value/10.0); - if (value/10.0 < ui->minEdit->value()) + if(value/sliderScale < ui->maxEdit->value()) { - ui->minEdit->setValue(value/10.0); - ui->maxEdit->setValue(value/10.0 + 1); + ui->maxEdit->setValue(value/sliderScale); + if (value/sliderScale < ui->minEdit->value()) + { + ui->minEdit->setValue(value/sliderScale); + ui->maxEdit->setValue(value/sliderScale + ui->maxEdit->singleStep()); + } } } applyScale(); } void FITSHistogram::checkRangeLimit(const QCPRange &range) { - if (range.lower < fits_min) - customPlot->xAxis->setRangeLower(fits_min); - else if (range.upper > fits_max) - customPlot->xAxis->setRangeUpper(fits_max); + if (range.lower < fits_min - ui->minEdit->singleStep()) + customPlot->xAxis->setRangeLower(fits_min - ui->minEdit->singleStep()); + else if (range.upper > fits_max + ui->maxEdit->singleStep()) + customPlot->xAxis->setRangeUpper(fits_max + ui->maxEdit->singleStep()); } double FITSHistogram::getJMIndex() const @@ -564,30 +612,6 @@ return cumulativeFrequency; } -void FITSHistogram::updateValues(QMouseEvent *event) -{ - int x = event->x(); - - double intensity_key = customPlot->xAxis->pixelToCoord(x); - - if (intensity_key < 0) - return; - - double frequency_val = 0; - - for (int i = 0; i < binCount; i++) - { - if (intensity[i] > intensity_key) - { - frequency_val = r_frequency[i]; - break; - } - } - - ui->intensityEdit->setText(QString::number(intensity_key)); - ui->frequencyEdit->setText(QString::number(frequency_val)); -} - FITSHistogramCommand::FITSHistogramCommand(QWidget *parent, FITSHistogram *inHisto, FITSScale newType, double lmin, double lmax) { @@ -839,16 +863,12 @@ { case FITS_AUTO: return i18n("Auto Scale"); - break; case FITS_LINEAR: return i18n("Linear Scale"); - break; case FITS_LOG: return i18n("Logarithmic Scale"); - break; case FITS_SQRT: return i18n("Square Root Scale"); - break; default: if (type - 1 <= FITSViewer::filterTypes.count()) @@ -858,3 +878,65 @@ return i18n("Unknown"); } + +void FITSHistogram::driftMouseOverLine(QMouseEvent *event) +{ + double intensity = customPlot->xAxis->pixelToCoord(event->localPos().x()); + + if (customPlot->xAxis->range().contains(intensity)) + { + int r_index= r_graph->findBegin(intensity, true); + double r_Frequency = r_graph->dataMainValue(r_index); + + + if(b_graph && g_graph) + { + int g_index= g_graph->findBegin(intensity, true); + double g_Frequency = g_graph->dataMainValue(g_index); + + int b_index= b_graph->findBegin(intensity, true); + double b_Frequency = g_graph->dataMainValue(b_index); + + if( r_Frequency>0.0 || g_Frequency>0.0 || b_Frequency>0.0 ) + { + QToolTip::showText( + event->globalPos(), + i18nc("Histogram tooltip; %1 is intensity; %2 is frequency;", + "" + "" + "" + "" + "" + "
Intensity: %1
R Frequency: %2
G Frequency: %3
B Frequency: %4
", + QString::number(intensity, 'f', numDecimals), + QString::number(r_Frequency, 'f', 0), + QString::number(g_Frequency, 'f', 0), + QString::number(b_Frequency, 'f', 0))); + } + else + QToolTip::hideText(); + + } + else + { + if(r_Frequency>0.0) + { + QToolTip::showText( + event->globalPos(), + i18nc("Histogram tooltip; %1 is intensity; %2 is frequency;", + "" + "" + "" + "
Intensity: %1
R Frequency: %2
", + QString::number(intensity, 'f', numDecimals), + QString::number(r_Frequency, 'f', 0))); + } + else + QToolTip::hideText(); + } + + + + customPlot->replot(); + } +} diff --git a/kstars/fitsviewer/fitshistogramui.ui b/kstars/fitsviewer/fitshistogramui.ui --- a/kstars/fitsviewer/fitshistogramui.ui +++ b/kstars/fitsviewer/fitshistogramui.ui @@ -7,7 +7,7 @@ 0 0 212 - 528 + 437 @@ -35,6 +35,9 @@ true + + 0 + 4 @@ -73,75 +76,18 @@ - - - - - - - Mean: - - - - - - - Intensity: - - - - - - - - - - Min.: - - - - - - - Frequency: - - - - - - - - 0 - 0 - - - - true - - - - - - - - 0 - 0 - - - - true - - - + + 0 + Max: - - + + 0 @@ -153,15 +99,21 @@ - + Median: - - + + + + + + + + 0 @@ -173,6 +125,13 @@ + + + + Mean: + + + @@ -187,6 +146,13 @@ + + + + Min.: + + + @@ -199,6 +165,11 @@ 0 + + + 12 + + Qt::LeftToRight @@ -209,6 +180,21 @@ FITS Scale + + 0 + + + 2 + + + 2 + + + 2 + + + 2 + @@ -230,9 +216,16 @@ - - - QDialogButtonBox::Apply|QDialogButtonBox::Close + + + Apply + + + + + + + Hide Saturation Spike diff --git a/kstars/fitsviewer/fitstab.h b/kstars/fitsviewer/fitstab.h --- a/kstars/fitsviewer/fitstab.h +++ b/kstars/fitsviewer/fitstab.h @@ -27,6 +27,7 @@ #include "ui_statform.h" #include #include +#include #include @@ -47,6 +48,8 @@ explicit FITSTab(FITSViewer *parent); virtual ~FITSTab(); + void clearRecentFITS(); + void selectRecentFITS(int i); void loadFITS(const QUrl &imageURL, FITSMode mode = FITS_NORMAL, FITSScale filter = FITS_NONE, bool silent = true); int saveFITS(const QString &filename); @@ -101,6 +104,8 @@ QPointer histogram; QPointer viewer; + QPointer recentImages; + /// FITS image object std::unique_ptr view; diff --git a/kstars/fitsviewer/fitstab.cpp b/kstars/fitsviewer/fitstab.cpp --- a/kstars/fitsviewer/fitstab.cpp +++ b/kstars/fitsviewer/fitstab.cpp @@ -24,6 +24,7 @@ #include "Options.h" #include "ui_fitsheaderdialog.h" #include "ui_statform.h" +#include "ekos/manager.h" #include #include @@ -85,6 +86,18 @@ previewText = value; } +void FITSTab::selectRecentFITS(int i) +{ + loadFITS(QUrl::fromLocalFile(recentImages->item(i)->text())); +} + +void FITSTab::clearRecentFITS() +{ + disconnect(recentImages, &QListWidget::currentRowChanged, this, &FITSTab::selectRecentFITS); + recentImages->clear(); + connect(recentImages, &QListWidget::currentRowChanged, this, &FITSTab::selectRecentFITS); +} + void FITSTab::loadFITS(const QUrl &imageURL, FITSMode mode, FITSScale filter, bool silent) { if (view.get() == nullptr) @@ -105,6 +118,19 @@ header.setupUi(fitsHeaderDialog); fitsTools->addItem(fitsHeaderDialog,i18n("FITS Header")); + + + QVBoxLayout *recentPanelLayout = new QVBoxLayout(); + QWidget *recentPanel = new QWidget(fitsSplitter); + recentPanel->setLayout(recentPanelLayout); + fitsTools->addItem(recentPanel,i18n("Recent Images")); + recentImages = new QListWidget(recentPanel); + recentPanelLayout->addWidget(recentImages); + QPushButton *clearRecent = new QPushButton(i18n("Clear")); + recentPanelLayout->addWidget(clearRecent); + connect(clearRecent, &QPushButton::pressed, this, &FITSTab::clearRecentFITS); + connect(recentImages, &QListWidget::currentRowChanged, this, &FITSTab::selectRecentFITS); + QScrollArea *scrollFitsPanel = new QScrollArea(fitsSplitter); scrollFitsPanel->setWidgetResizable(true); scrollFitsPanel->setWidget(fitsTools); @@ -142,7 +168,7 @@ image_data->setHistogram(histogram); } - histogramFuture = QtConcurrent::run([&]() {histogram->constructHistogram();}); + histogramFuture = QtConcurrent::run([&]() {histogram->constructHistogram(); evaluateStats();}); if(histogram->isVisible()) histogramFuture.waitForFinished(); @@ -156,7 +182,7 @@ if (viewer->isStarsMarked()) view->toggleStars(true); - evaluateStats(); + loadFITSHeader(); view->updateFrame(); @@ -170,6 +196,25 @@ view->setFilter(filter); view->loadFITS(imageURL.toLocalFile(), silent); + + + if(recentImages->findItems(imageURL.toLocalFile(),Qt::MatchExactly).count()==0) //Don't add it to the list if it is already there + { + if(KStars::Instance()->ekosManager()->captureModule()) //If capture module doesn't exist, it was loaded from "Load Fits" so it should be added + { + //We need to be sure the capture module exists before doing this check. + if(KStars::Instance()->ekosManager()->captureModule()->isActiveJobAPreview()) //If the image is in fact a preview, it should not be added + return; + } + //So now the images was either loaded from "Open File" or in a sequence, so add it. + + + disconnect(recentImages, &QListWidget::currentRowChanged, this, &FITSTab::selectRecentFITS); + recentImages->addItem(imageURL.toLocalFile()); + recentImages->setCurrentRow(recentImages->count()-1); + connect(recentImages, &QListWidget::currentRowChanged, this, &FITSTab::selectRecentFITS); + } + } void FITSTab::modifyFITSState(bool clean) diff --git a/kstars/fitsviewer/fitsview.h b/kstars/fitsviewer/fitsview.h --- a/kstars/fitsviewer/fitsview.h +++ b/kstars/fitsviewer/fitsview.h @@ -288,6 +288,7 @@ void trackingStarSelected(int x, int y); void loaded(); void failed(); + void starProfileWindowClosed(); friend class FITSLabel; }; diff --git a/kstars/fitsviewer/fitsview.cpp b/kstars/fitsviewer/fitsview.cpp --- a/kstars/fitsviewer/fitsview.cpp +++ b/kstars/fitsviewer/fitsview.cpp @@ -87,7 +87,6 @@ { fitsWatcher.waitForFinished(); wcsWatcher.waitForFinished(); - starProfileWidget->deleteLater(); delete (imageData); } @@ -1395,7 +1394,7 @@ { setCursorMode(selectCursor); connect(this, SIGNAL(trackingStarSelected(int,int)), this, SLOT(move3DTrackingBox(int,int))); - if(floatingToolBar && starProfileWidget) + if(starProfileWidget) connect(starProfileWidget, SIGNAL(rejected()) , this, SLOT(toggleStarProfile())); if(starProfileWidget) connect(starProfileWidget, SIGNAL(sampleSizeUpdated(int)) , this, SLOT(resizeTrackingBox(int))); @@ -1408,10 +1407,12 @@ setCursorMode(dragCursor); disconnect(this, SIGNAL(trackingStarSelected(int,int)), this, SLOT(move3DTrackingBox(int,int))); disconnect(starProfileWidget, SIGNAL(sampleSizeUpdated(int)) , this, SLOT(resizeTrackingBox(int))); - if(floatingToolBar) - disconnect(starProfileWidget, SIGNAL(rejected()) , this, SLOT(toggleStarProfile())); + disconnect(starProfileWidget, SIGNAL(rejected()) , this, SLOT(toggleStarProfile())); setTrackingBoxEnabled(false); - starProfileWidget->deleteLater(); + if(starProfileWidget) + starProfileWidget->close(); + starProfileWidget = nullptr; + emit starProfileWindowClosed(); } updateFrame(); } @@ -1435,12 +1436,7 @@ } if(!starProfileWidget) { - //I had to change it to nullptr instead of "this" - //because while it worked before, there was some change in QT - //With their change, if the user hid the viewer, it would come up empty next time! - //Changing it to nullptr fixes the problem - //starProfileWidget = new StarProfileViewer(this); - starProfileWidget = new StarProfileViewer(nullptr); + starProfileWidget = new StarProfileViewer(this); //This is a band-aid to fix a QT bug with createWindowContainer //It will set the cursor of the Window containing the view that called the Star Profile method to the Arrow Cursor @@ -1451,8 +1447,7 @@ superParent->setCursor(Qt::ArrowCursor); //This is the end of the band-aid - if(floatingToolBar) - connect(starProfileWidget, SIGNAL(rejected()) , this, SLOT(toggleStarProfile())); + connect(starProfileWidget, SIGNAL(rejected()) , this, SLOT(toggleStarProfile())); if(mode == FITS_ALIGN || mode == FITS_NORMAL) { starProfileWidget->enableTrackingBox(true); diff --git a/kstars/fitsviewer/fitsviewer.h b/kstars/fitsviewer/fitsviewer.h --- a/kstars/fitsviewer/fitsviewer.h +++ b/kstars/fitsviewer/fitsviewer.h @@ -108,6 +108,7 @@ void toggleObjects(); void togglePixelGrid(); void toggle3DGraph(); + void starProfileButtonOff(); void centerTelescope(); void updateWCSFunctions(); void applyFilter(int ftype); diff --git a/kstars/fitsviewer/fitsviewer.cpp b/kstars/fitsviewer/fitsviewer.cpp --- a/kstars/fitsviewer/fitsviewer.cpp +++ b/kstars/fitsviewer/fitsviewer.cpp @@ -371,6 +371,7 @@ // Connect tab view signals connect(tab->getView(), &FITSView::actionUpdated, this, &FITSViewer::updateAction); connect(tab->getView(), &FITSView::wcsToggled, this, &FITSViewer::updateWCSFunctions); + connect(tab->getView(),&FITSView::starProfileWindowClosed, this, &FITSViewer::starProfileButtonOff); switch (mode) { @@ -527,15 +528,21 @@ actionCollection()->action("fits_debayer")->setEnabled(false); updateStatusBar("", FITS_WCS); - updateButtonStatus("toggle_3D_graph", "View 3D Graph", getCurrentView()->isStarProfileShown()); - updateButtonStatus("view_crosshair", "Cross Hairs", getCurrentView()->isCrosshairShown()); - updateButtonStatus("view_eq_grid", "Equatorial Gridines", getCurrentView()->isEQGridShown()); - updateButtonStatus("view_objects", "Objects in Image", getCurrentView()->areObjectsShown()); - updateButtonStatus("view_pixel_grid", "Pixel Gridines", getCurrentView()->isPixelGridShown()); + connect(view,&FITSView::starProfileWindowClosed, this, &FITSViewer::starProfileButtonOff); + updateButtonStatus("toggle_3D_graph", i18n("View 3D Graph"), getCurrentView()->isStarProfileShown()); + updateButtonStatus("view_crosshair", i18n("Cross Hairs"), getCurrentView()->isCrosshairShown()); + updateButtonStatus("view_eq_grid", i18n("Equatorial Gridines"), getCurrentView()->isEQGridShown()); + updateButtonStatus("view_objects", i18n("Objects in Image"), getCurrentView()->areObjectsShown()); + updateButtonStatus("view_pixel_grid", i18n("Pixel Gridines"), getCurrentView()->isPixelGridShown()); updateScopeButton(); updateWCSFunctions(); } +void FITSViewer::starProfileButtonOff() +{ + updateButtonStatus("toggle_3D_graph", i18n("View 3D Graph"), false); +} + void FITSViewer::openFile() { QUrl fileURL =