File indexing completed on 2024-04-28 03:43:13
0001 /* 0002 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <sterne-jaeger@openfuture.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "capturecountswidget.h" 0009 #include "Options.h" 0010 #include "ekos/manager.h" 0011 #include "ekos/scheduler/scheduler.h" 0012 #include "ekos/capture/capture.h" 0013 #include "ekos/capture/sequencejob.h" 0014 0015 using Ekos::SequenceJob; 0016 0017 CaptureCountsWidget::CaptureCountsWidget(QWidget *parent) : QWidget(parent) 0018 { 0019 setupUi(this); 0020 // switch between stacked views 0021 connect(switchToGraphicsButton, &QPushButton::clicked, this, [this]() 0022 { 0023 textView->setVisible(false); 0024 graphicalView->setVisible(true); 0025 Options::setUseGraphicalCountsDisplay(true); 0026 }); 0027 connect(switchToTextButton, &QPushButton::clicked, this, [this]() 0028 { 0029 textView->setVisible(true); 0030 graphicalView->setVisible(false); 0031 Options::setUseGraphicalCountsDisplay(false); 0032 }); 0033 0034 // start with the last used view 0035 graphicalView->setVisible(Options::useGraphicalCountsDisplay()); 0036 textView->setVisible(!Options::useGraphicalCountsDisplay()); 0037 0038 // setup graphical view 0039 gr_sequenceProgressBar->setDecimals(0); 0040 gr_overallProgressBar->setDecimals(0); 0041 0042 reset(); 0043 } 0044 0045 void CaptureCountsWidget::updateExposureProgress(Ekos::SequenceJob *job) 0046 { 0047 imageCountDown.setHMS(0, 0, 0); 0048 imageCountDown = imageCountDown.addSecs(int(std::round(job->getExposeLeft()))); 0049 if (imageCountDown.hour() == 23) 0050 imageCountDown.setHMS(0, 0, 0); 0051 0052 imageProgress->setRange(0, int(std::ceil(job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble()))); 0053 imageProgress->setValue(int(std::ceil(job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble() - job->getExposeLeft()))); 0054 gr_imageProgress->setRange(0, int(std::ceil(job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble()))); 0055 gr_imageProgress->setValue(imageProgress->value()); 0056 0057 frameRemainingTime->setText(imageCountDown.toString("hh:mm:ss")); 0058 gr_frameRemainingTime->setText(frameRemainingTime->text()); 0059 } 0060 0061 void CaptureCountsWidget::updateDownloadProgress(double timeLeft) 0062 { 0063 imageCountDown.setHMS(0, 0, 0); 0064 imageCountDown = imageCountDown.addSecs(int(std::ceil(timeLeft))); 0065 frameRemainingTime->setText(imageCountDown.toString("hh:mm:ss")); 0066 } 0067 0068 void CaptureCountsWidget::updateCaptureCountDown(int delta) 0069 { 0070 overallCountDown = overallCountDown.addSecs(delta); 0071 jobCountDown = jobCountDown.addSecs(delta); 0072 sequenceCountDown = sequenceCountDown.addSecs(delta); 0073 0074 // ensure that count downs do not overshoot 0075 if (overallCountDown.hour() == 23) 0076 overallCountDown.setHMS(0, 0, 0); 0077 if (jobCountDown.hour() == 23) 0078 jobCountDown.setHMS(0, 0, 0); 0079 if (sequenceCountDown.hour() == 23) 0080 sequenceCountDown.setHMS(0, 0, 0); 0081 0082 // do not change overall remaining time if scheduler is in endless loop 0083 if (schedulerProcess == nullptr || schedulerProcess->activeJob() == nullptr || 0084 schedulerProcess->activeJob()->getCompletionCondition() != Ekos::FINISH_LOOP) 0085 { 0086 overallRemainingTime->setText(overallCountDown.toString("hh:mm:ss")); 0087 gr_overallRemainingTime->setText(overallRemainingTime->text()); 0088 } 0089 jobRemainingTime->setText(jobCountDown.toString("hh:mm:ss")); 0090 sequenceRemainingTime->setText(sequenceCountDown.toString("hh:mm:ss")); 0091 gr_sequenceRemainingTime->setText(sequenceRemainingTime->text()); 0092 } 0093 0094 void CaptureCountsWidget::reset() 0095 { 0096 // reset graphical view 0097 gr_imageProgress->setValue(0); 0098 gr_frameLabel->setText(""); 0099 gr_frameRemainingTime->setText("--:--:--"); 0100 gr_frameDetailsLabel->setText(""); 0101 gr_sequenceLabel->setText(i18n("Sequence")); 0102 gr_sequenceProgressBar->setValue(0); 0103 gr_sequenceRemainingTime->setText("--:--:--"); 0104 gr_overallLabel->setText(i18n("Overall")); 0105 gr_overallProgressBar->setValue(0); 0106 gr_overallRemainingTime->setText("--:--:--"); 0107 0108 // reset text view 0109 imageProgress->setValue(0); 0110 setFrameInfo(""); 0111 frameRemainingTime->setText(""); 0112 0113 overallRemainingTime->setText("--:--:--"); 0114 jobRemainingTime->setText("--:--:--"); 0115 sequenceRemainingTime->setText("--:--:--"); 0116 } 0117 0118 namespace 0119 { 0120 QString frameLabel(const QString &type, const QString &filter) 0121 { 0122 if (type == "Light") 0123 { 0124 if (filter.size() == 0) 0125 return type; 0126 else 0127 return filter; 0128 } 0129 else if (type == "Flat") 0130 { 0131 if (filter.size() == 0) 0132 return type; 0133 else 0134 return QString("%1 %2").arg(filter).arg(type); 0135 } 0136 else 0137 return type; 0138 } 0139 } 0140 0141 void CaptureCountsWidget::setFrameInfo(const QString frametype, const QString filter, const double exptime, const int xBin, 0142 const int yBin, const double gain) 0143 { 0144 if (frametype == "") 0145 { 0146 frameInfoLabel->setText(""); 0147 frameDetailsLabel->setText(""); 0148 gr_frameRemainingTime->setText(""); 0149 } 0150 else 0151 { 0152 frameInfoLabel->setText(QString("%1").arg(frameLabel(frametype, filter))); 0153 gr_frameLabel->setText(frameInfoLabel->text()); 0154 QString details = ""; 0155 if (exptime > 0) 0156 details.append(QString("%1: %2 sec").arg(i18n("Exposure")).arg(exptime, 0, 'f', exptime < 1 ? 2 : exptime < 5 ? 1 : 0)); 0157 if (xBin > 0 && yBin > 0) 0158 details.append(QString(", bin: %1x%2").arg(xBin).arg(yBin)); 0159 if (gain >= 0) 0160 details.append(QString(", gain: %1").arg(gain, 0, 'f', 1)); 0161 0162 frameDetailsLabel->setText(details); 0163 gr_frameDetailsLabel->setText(details); 0164 } 0165 } 0166 0167 void CaptureCountsWidget::updateCaptureStatus(Ekos::CaptureState status) 0168 { 0169 overallCountDown.setHMS(0, 0, 0); 0170 bool infinite_loop = false; 0171 int total_remaining_time = 0, total_completed = 0, total_count = 0; 0172 double total_percentage = 0; 0173 // use this value if no scheduler is running and job name otherwise 0174 QString total_label = "Total"; 0175 0176 // determine total number of frames and completed ones - used either for 0177 // total numbers if scheduler is not used - and for job figures in the text 0178 // display if the scheduler is used 0179 double capture_total_percentage = captureProcess->getProgressPercentage(); 0180 int capture_remaining_time = captureProcess->getOverallRemainingTime(); 0181 int capture_total_count = 0, capture_total_completed = 0; 0182 for (int i = 0; i < captureProcess->getJobCount(); i++) 0183 { 0184 capture_total_count += captureProcess->getJobImageCount(i); 0185 capture_total_completed += captureProcess->getJobImageProgress(i); 0186 } 0187 0188 0189 if (schedulerProcess != nullptr && schedulerProcess->activeJob() != nullptr) 0190 { 0191 total_label = schedulerProcess->getCurrentJobName(); 0192 // FIXME: accessing the completed count might be one too low due to concurrency of updating the count and this loop 0193 total_completed = schedulerProcess->activeJob()->getCompletedCount(); 0194 total_count = schedulerProcess->activeJob()->getSequenceCount(); 0195 infinite_loop = (schedulerProcess->activeJob()->getCompletionCondition() == Ekos::FINISH_LOOP); 0196 if (total_count > 0) 0197 total_percentage = (100 * total_completed) / total_count; 0198 if (schedulerProcess->activeJob()->getEstimatedTime() > 0) 0199 total_remaining_time = int(schedulerProcess->activeJob()->getEstimatedTime()); 0200 } 0201 else 0202 { 0203 total_percentage = capture_total_percentage; 0204 total_remaining_time = capture_remaining_time; 0205 total_count = capture_total_count; 0206 total_completed = capture_total_completed; 0207 } 0208 0209 switch (status) 0210 { 0211 case Ekos::CAPTURE_IDLE: 0212 // do nothing 0213 break; 0214 case Ekos::CAPTURE_ABORTED: 0215 reset(); 0216 break; 0217 default: 0218 if (infinite_loop == true) 0219 { 0220 overallRemainingTime->setText("--:--:--"); 0221 gr_overallProgressBar->setValue(0); 0222 gr_overallRemainingTime->setText(overallRemainingTime->text()); 0223 } 0224 else 0225 { 0226 overallCountDown = overallCountDown.addSecs(total_remaining_time); 0227 gr_overallProgressBar->setValue(total_percentage); 0228 } 0229 0230 // display overall remainings 0231 overallLabel->setText(QString("%1 (%2/%3)") 0232 .arg(total_label) 0233 .arg(total_completed) 0234 .arg(infinite_loop ? QString("-") : QString::number(total_count))); 0235 gr_overallLabel->setText(overallLabel->text()); 0236 0237 // update job remaining time if run from the scheduler 0238 bool show_job_progress = (schedulerProcess != nullptr && schedulerProcess->activeJob() != nullptr); 0239 jobLabel->setVisible(show_job_progress); 0240 jobRemainingTime->setVisible(show_job_progress); 0241 if (show_job_progress) 0242 { 0243 jobCountDown.setHMS(0, 0, 0); 0244 jobCountDown = jobCountDown.addSecs(captureProcess->getOverallRemainingTime()); 0245 jobLabel->setText(QString("Job (%1/%2)") 0246 .arg(capture_total_completed) 0247 .arg(capture_total_count)); 0248 } 0249 0250 // update sequence remaining time 0251 sequenceCountDown.setHMS(0, 0, 0); 0252 sequenceCountDown = sequenceCountDown.addSecs(captureProcess->getActiveJobRemainingTime()); 0253 } 0254 } 0255 0256 void CaptureCountsWidget::updateJobProgress(Ekos::SequenceJob *job) 0257 { 0258 // display informations about the current active capture 0259 if (job->jobType() == SequenceJob::JOBTYPE_PREVIEW) 0260 setFrameInfo(i18n("Preview"), job->getCoreProperty(SequenceJob::SJ_Filter).toString(), 0261 job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(), job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().x(), 0262 job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().y(), job->getCoreProperty(SequenceJob::SJ_Gain).toDouble()); 0263 else 0264 setFrameInfo(CCDFrameTypeNames[job->getFrameType()], job->getCoreProperty(SequenceJob::SJ_Filter).toString(), 0265 job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(), job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().x(), 0266 job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().y(), job->getCoreProperty(SequenceJob::SJ_Gain).toDouble()); 0267 0268 // display sequence progress in the graphical view 0269 gr_sequenceProgressBar->setRange(0, job->getCoreProperty(SequenceJob::SJ_Count).toInt()); 0270 gr_sequenceProgressBar->setValue(job->getCompleted()); 0271 sequenceLabel->setText(QString("%1 (%3/%4)") 0272 .arg(frameLabel(CCDFrameTypeNames[job->getFrameType()], 0273 job->getCoreProperty(SequenceJob::SJ_Filter).toString())) 0274 .arg(job->getCompleted()).arg(job->getCoreProperty(SequenceJob::SJ_Count).toInt())); 0275 gr_sequenceLabel->setText(sequenceLabel->text()); 0276 } 0277 0278 void CaptureCountsWidget::setEnabled(bool enabled) 0279 { 0280 QWidget::setEnabled(enabled); 0281 overallLabel->setEnabled(enabled); 0282 gr_overallLabel->setEnabled(enabled); 0283 }