Kstars

capturecountswidget.cpp
1/*
2 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
3 SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "capturecountswidget.h"
9#include "Options.h"
10#include "ekos/manager.h"
11#include "ekos/scheduler/schedulerjob.h"
12#include "ekos/scheduler/schedulermodulestate.h"
13#include "ekos/capture/capture.h"
14#include "ekos/capture/sequencejob.h"
15
16using Ekos::SequenceJob;
17
18CaptureCountsWidget::CaptureCountsWidget(QWidget *parent) : QWidget(parent)
19{
20 setupUi(this);
21 // switch between stacked views
23 {
24 textView->setVisible(false);
25 graphicalView->setVisible(true);
26 Options::setUseGraphicalCountsDisplay(true);
27 });
29 {
30 textView->setVisible(true);
31 graphicalView->setVisible(false);
32 Options::setUseGraphicalCountsDisplay(false);
33 });
34
35 // start with the last used view
36 graphicalView->setVisible(Options::useGraphicalCountsDisplay());
37 textView->setVisible(!Options::useGraphicalCountsDisplay());
38
39 // setup graphical view
40 gr_sequenceProgressBar->setDecimals(0);
41 gr_overallProgressBar->setDecimals(0);
42
43 reset();
44}
45
46void CaptureCountsWidget::updateExposureProgress(Ekos::SequenceJob *job)
47{
48 imageCountDown.setHMS(0, 0, 0);
49 imageCountDown = imageCountDown.addSecs(int(std::round(job->getExposeLeft())));
50 if (imageCountDown.hour() == 23)
51 imageCountDown.setHMS(0, 0, 0);
52
53 imageProgress->setRange(0, int(std::ceil(job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble())));
54 imageProgress->setValue(int(std::ceil(job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble() - job->getExposeLeft())));
55 gr_imageProgress->setRange(0, int(std::ceil(job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble())));
56 gr_imageProgress->setValue(imageProgress->value());
57
58 frameRemainingTime->setText(imageCountDown.toString("hh:mm:ss"));
60}
61
62void CaptureCountsWidget::updateDownloadProgress(double timeLeft)
63{
64 imageCountDown.setHMS(0, 0, 0);
65 imageCountDown = imageCountDown.addSecs(int(std::ceil(timeLeft)));
66 frameRemainingTime->setText(imageCountDown.toString("hh:mm:ss"));
67}
68
69void CaptureCountsWidget::shareSchedulerState(QSharedPointer<Ekos::SchedulerModuleState> state)
70{
71 m_schedulerModuleState = state;
72}
73
74void CaptureCountsWidget::updateCaptureCountDown(int delta)
75{
76 overallCountDown = overallCountDown.addSecs(delta);
77 jobCountDown = jobCountDown.addSecs(delta);
78 sequenceCountDown = sequenceCountDown.addSecs(delta);
79
80 // ensure that count downs do not overshoot
81 if (overallCountDown.hour() == 23)
82 overallCountDown.setHMS(0, 0, 0);
83 if (jobCountDown.hour() == 23)
84 jobCountDown.setHMS(0, 0, 0);
85 if (sequenceCountDown.hour() == 23)
86 sequenceCountDown.setHMS(0, 0, 0);
87
88 // do not change overall remaining time if scheduler is in endless loop
89 if (m_schedulerModuleState == nullptr || m_schedulerModuleState->activeJob() == nullptr ||
90 m_schedulerModuleState->activeJob()->getCompletionCondition() != Ekos::FINISH_LOOP)
91 {
92 overallRemainingTime->setText(overallCountDown.toString("hh:mm:ss"));
93 gr_overallRemainingTime->setText(overallRemainingTime->text());
94 }
95 jobRemainingTime->setText(jobCountDown.toString("hh:mm:ss"));
96 sequenceRemainingTime->setText(sequenceCountDown.toString("hh:mm:ss"));
98}
99
100void CaptureCountsWidget::reset()
101{
102 // reset graphical view
103 gr_imageProgress->setValue(0);
104 gr_frameLabel->setText("");
105 gr_frameRemainingTime->setText("--:--:--");
106 gr_frameDetailsLabel->setText("");
107 gr_sequenceLabel->setText(i18n("Sequence"));
108 gr_sequenceProgressBar->setValue(0);
109 gr_sequenceRemainingTime->setText("--:--:--");
110 gr_overallLabel->setText(i18n("Overall"));
111 gr_overallProgressBar->setValue(0);
112 gr_overallRemainingTime->setText("--:--:--");
113
114 // reset text view
115 imageProgress->setValue(0);
116 setFrameInfo("");
117 frameRemainingTime->setText("");
118
119 overallRemainingTime->setText("--:--:--");
120 jobRemainingTime->setText("--:--:--");
121 sequenceRemainingTime->setText("--:--:--");
122}
123
124namespace
125{
126QString frameLabel(const QString &type, const QString &filter)
127{
128 if (type == "Light")
129 {
130 if (filter.size() == 0)
131 return type;
132 else
133 return filter;
134 }
135 else if (type == "Flat")
136 {
137 if (filter.size() == 0)
138 return type;
139 else
140 return QString("%1 %2").arg(filter).arg(type);
141 }
142 else
143 return type;
144}
145}
146
147void CaptureCountsWidget::setFrameInfo(const QString frametype, const QString filter, const double exptime, const int xBin,
148 const int yBin, const double gain)
149{
150 if (frametype == "")
151 {
152 frameInfoLabel->setText("");
153 frameDetailsLabel->setText("");
154 gr_frameRemainingTime->setText("");
155 }
156 else
157 {
158 frameInfoLabel->setText(QString("%1").arg(frameLabel(frametype, filter)));
159 gr_frameLabel->setText(frameInfoLabel->text());
160 QString details = "";
161 if (exptime > 0)
162 details.append(QString("%1: %2 sec").arg(i18n("Exposure")).arg(exptime, 0, 'f', exptime < 1 ? 2 : exptime < 5 ? 1 : 0));
163 if (xBin > 0 && yBin > 0)
164 details.append(QString(", bin: %1x%2").arg(xBin).arg(yBin));
165 if (gain >= 0)
166 details.append(QString(", gain: %1").arg(gain, 0, 'f', 1));
167
168 frameDetailsLabel->setText(details);
169 gr_frameDetailsLabel->setText(details);
170 }
171}
172
173void CaptureCountsWidget::updateCaptureStatus(Ekos::CaptureState status)
174{
175 overallCountDown.setHMS(0, 0, 0);
176 bool infinite_loop = false;
177 int total_remaining_time = 0, total_completed = 0, total_count = 0;
178 double total_percentage = 0;
179 // use this value if no scheduler is running and job name otherwise
180 QString total_label = "Total";
181
182 // determine total number of frames and completed ones - used either for
183 // total numbers if scheduler is not used - and for job figures in the text
184 // display if the scheduler is used
185 double capture_total_percentage = m_captureProcess->getProgressPercentage();
186 int capture_remaining_time = m_captureProcess->getOverallRemainingTime();
188 for (int i = 0; i < m_captureProcess->getJobCount(); i++)
189 {
190 capture_total_count += m_captureProcess->getJobImageCount(i);
191 capture_total_completed += m_captureProcess->getJobImageProgress(i);
192 }
193
194
195 if (m_schedulerModuleState != nullptr && m_schedulerModuleState->activeJob() != nullptr)
196 {
197 total_label = m_schedulerModuleState->activeJob()->getName();
198 // FIXME: accessing the completed count might be one too low due to concurrency of updating the count and this loop
199 total_completed = m_schedulerModuleState->activeJob()->getCompletedCount();
200 total_count = m_schedulerModuleState->activeJob()->getSequenceCount();
201 infinite_loop = (m_schedulerModuleState->activeJob()->getCompletionCondition() == Ekos::FINISH_LOOP);
202 if (total_count > 0)
203 total_percentage = (100 * total_completed) / total_count;
204 if (m_schedulerModuleState->activeJob()->getEstimatedTime() > 0)
205 total_remaining_time = int(m_schedulerModuleState->activeJob()->getEstimatedTime());
206 }
207 else
208 {
211 total_count = capture_total_count;
213 }
214
215 switch (status)
216 {
218 // do nothing
219 break;
221 reset();
222 break;
223 default:
224 if (infinite_loop == true)
225 {
226 overallRemainingTime->setText("--:--:--");
227 gr_overallProgressBar->setValue(0);
228 gr_overallRemainingTime->setText(overallRemainingTime->text());
229 }
230 else
231 {
232 overallCountDown = overallCountDown.addSecs(total_remaining_time);
234 }
235
236 // display overall remainings
237 overallLabel->setText(QString("%1 (%2/%3)")
238 .arg(total_label)
239 .arg(total_completed)
240 .arg(infinite_loop ? QString("-") : QString::number(total_count)));
241 gr_overallLabel->setText(overallLabel->text());
242
243 // update job remaining time if run from the scheduler
244 bool show_job_progress = (m_schedulerModuleState != nullptr && m_schedulerModuleState->activeJob() != nullptr);
245 jobLabel->setVisible(show_job_progress);
248 {
249 jobCountDown.setHMS(0, 0, 0);
250 jobCountDown = jobCountDown.addSecs(m_captureProcess->getOverallRemainingTime());
251 jobLabel->setText(QString("Job (%1/%2)")
254 }
255
256 // update sequence remaining time
257 sequenceCountDown.setHMS(0, 0, 0);
258 sequenceCountDown = sequenceCountDown.addSecs(m_captureProcess->getActiveJobRemainingTime());
259 }
260}
261
262void CaptureCountsWidget::updateJobProgress(Ekos::SequenceJob *job)
263{
264 // display informations about the current active capture
265 if (job->jobType() == SequenceJob::JOBTYPE_PREVIEW)
266 setFrameInfo(i18n("Preview"), job->getCoreProperty(SequenceJob::SJ_Filter).toString(),
267 job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(), job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().x(),
268 job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().y(), job->getCoreProperty(SequenceJob::SJ_Gain).toDouble());
269 else
270 setFrameInfo(CCDFrameTypeNames[job->getFrameType()], job->getCoreProperty(SequenceJob::SJ_Filter).toString(),
271 job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(), job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().x(),
272 job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().y(), job->getCoreProperty(SequenceJob::SJ_Gain).toDouble());
273
274 // display sequence progress in the graphical view
275 gr_sequenceProgressBar->setRange(0, job->getCoreProperty(SequenceJob::SJ_Count).toInt());
276 gr_sequenceProgressBar->setValue(job->getCompleted());
277 sequenceLabel->setText(QString("%1 (%3/%4)")
278 .arg(frameLabel(CCDFrameTypeNames[job->getFrameType()],
279 job->getCoreProperty(SequenceJob::SJ_Filter).toString()))
280 .arg(job->getCompleted()).arg(job->getCoreProperty(SequenceJob::SJ_Count).toInt()));
281 gr_sequenceLabel->setText(sequenceLabel->text());
282}
283
284void CaptureCountsWidget::setEnabled(bool enabled)
285{
287 overallLabel->setEnabled(enabled);
288 gr_overallLabel->setEnabled(enabled);
289}
Q_SCRIPTABLE int getJobCount()
DBUS interface function.
Definition capture.h:210
Q_SCRIPTABLE double getProgressPercentage()
DBUS interface function.
Definition capture.h:202
Q_SCRIPTABLE int getActiveJobRemainingTime()
DBUS interface function.
Definition capture.h:234
Q_SCRIPTABLE int getJobImageCount(int id)
DBUS interface function.
Definition capture.h:278
Q_SCRIPTABLE int getJobImageProgress(int id)
DBUS interface function.
Definition capture.h:269
Q_SCRIPTABLE int getOverallRemainingTime()
DBUS interface function.
Definition capture.h:242
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
CaptureState
Capture states.
Definition ekos.h:92
@ CAPTURE_ABORTED
Definition ekos.h:99
@ CAPTURE_IDLE
Definition ekos.h:93
KIOCORE_EXPORT QString number(KIO::filesize_t size)
KGuiItem reset()
void clicked(bool checked)
int x() const const
int y() const const
QString & append(QChar ch)
QString arg(Args &&... args) const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QTime addSecs(int s) const const
int hour() const const
bool setHMS(int h, int m, int s, int ms)
QString toString(QStringView format) const const
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
QPoint toPoint() const const
QString toString() const const
void setEnabled(bool)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:02 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.