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 if (!m_captureProcess->isActiveJobPreview())
96 {
97 jobRemainingTime->setText(jobCountDown.toString("hh:mm:ss"));
98 sequenceRemainingTime->setText(sequenceCountDown.toString("hh:mm:ss"));
100 }
101 else
102 {
103 jobRemainingTime->setText("--:--:--");
104 sequenceRemainingTime->setText("--:--:--");
105 gr_sequenceRemainingTime->setText("--:--:--");
106 }
107}
108
109void CaptureCountsWidget::reset()
110{
111 // reset graphical view
112 gr_imageProgress->setValue(0);
113 gr_frameLabel->setText("");
114 gr_frameRemainingTime->setText("--:--:--");
115 gr_frameDetailsLabel->setText("");
116 gr_sequenceLabel->setText(i18n("Sequence"));
117 gr_sequenceProgressBar->setValue(0);
118 gr_sequenceRemainingTime->setText("--:--:--");
119 gr_overallLabel->setText(i18n("Overall"));
120 gr_overallProgressBar->setValue(0);
121 gr_overallRemainingTime->setText("--:--:--");
122
123 // reset text view
124 imageProgress->setValue(0);
125 setFrameInfo("");
126 frameRemainingTime->setText("");
127
128 overallRemainingTime->setText("--:--:--");
129 jobRemainingTime->setText("--:--:--");
130 sequenceRemainingTime->setText("--:--:--");
131}
132
133namespace
134{
135QString frameLabel(const QString &type, const QString &filter)
136{
137 if (type == "Light")
138 {
139 if (filter.size() == 0)
140 return type;
141 else
142 return filter;
143 }
144 else if (type == "Flat")
145 {
146 if (filter.size() == 0)
147 return type;
148 else
149 return QString("%1 %2").arg(filter).arg(type);
150 }
151 else
152 return type;
153}
154}
155
156void CaptureCountsWidget::setFrameInfo(const QString frametype, const QString filter, const double exptime, const int xBin,
157 const int yBin, const double gain)
158{
159 if (frametype == "")
160 {
161 frameInfoLabel->setText("");
162 frameDetailsLabel->setText("");
163 gr_frameRemainingTime->setText("");
164 }
165 else
166 {
167 frameInfoLabel->setText(QString("%1").arg(frameLabel(frametype, filter)));
168 gr_frameLabel->setText(frameInfoLabel->text());
169 QString details = "";
170 if (exptime > 0)
171 details.append(QString("%1: %2 sec").arg(i18n("Exposure")).arg(exptime, 0, 'f', exptime < 1 ? 2 : exptime < 5 ? 1 : 0));
172 if (xBin > 0 && yBin > 0)
173 details.append(QString(", bin: %1x%2").arg(xBin).arg(yBin));
174 if (gain >= 0)
175 details.append(QString(", gain: %1").arg(gain, 0, 'f', 1));
176
177 frameDetailsLabel->setText(details);
178 gr_frameDetailsLabel->setText(details);
179 }
180}
181
182void CaptureCountsWidget::updateCaptureStatus(Ekos::CaptureState status, bool isPreview)
183{
184 overallCountDown.setHMS(0, 0, 0);
185 bool infinite_loop = false;
186 int total_remaining_time = 0, total_completed = 0, total_count = 0;
187 double total_percentage = 0;
188 // use this value if no scheduler is running and job name otherwise
189 QString total_label = "Total";
190
191 // determine total number of frames and completed ones - used either for
192 // total numbers if scheduler is not used - and for job figures in the text
193 // display if the scheduler is used
194 double capture_total_percentage = m_captureProcess->getProgressPercentage();
195 int capture_remaining_time = m_captureProcess->getOverallRemainingTime();
197 for (int i = 0; i < m_captureProcess->getJobCount(); i++)
198 {
199 capture_total_count += m_captureProcess->getJobImageCount(i);
200 capture_total_completed += m_captureProcess->getJobImageProgress(i);
201 }
202
203
204 if (m_schedulerModuleState != nullptr && m_schedulerModuleState->activeJob() != nullptr)
205 {
206 total_label = m_schedulerModuleState->activeJob()->getName();
207 // FIXME: accessing the completed count might be one too low due to concurrency of updating the count and this loop
208 total_completed = m_schedulerModuleState->activeJob()->getCompletedCount();
209 total_count = m_schedulerModuleState->activeJob()->getSequenceCount();
210 infinite_loop = (m_schedulerModuleState->activeJob()->getCompletionCondition() == Ekos::FINISH_LOOP);
211 if (total_count > 0)
212 total_percentage = (100 * total_completed) / total_count;
213 if (m_schedulerModuleState->activeJob()->getEstimatedTime() > 0)
214 total_remaining_time = int(m_schedulerModuleState->activeJob()->getEstimatedTime());
215 }
216 else
217 {
220 total_count = capture_total_count;
222 }
223
224 switch (status)
225 {
227 // do nothing
228 break;
230 reset();
231 break;
232 default:
233 if (infinite_loop == true)
234 {
235 overallRemainingTime->setText("--:--:--");
236 gr_overallProgressBar->setValue(0);
237 gr_overallRemainingTime->setText(overallRemainingTime->text());
238 }
239 else
240 {
241 overallCountDown = overallCountDown.addSecs(total_remaining_time);
243 }
244
245 // display overall remainings
246 if (isPreview)
247 overallLabel->setText(QString("%1").arg(total_label));
248 else
249 overallLabel->setText(QString("%1 (%2/%3)")
250 .arg(total_label)
251 .arg(total_completed)
252 .arg(infinite_loop ? QString("-") : QString::number(total_count)));
253 gr_overallLabel->setText(overallLabel->text());
254
255 // update job remaining time if run from the scheduler
256 bool show_job_progress = (m_schedulerModuleState != nullptr && m_schedulerModuleState->activeJob() != nullptr);
257 jobLabel->setVisible(show_job_progress);
260 {
261 jobCountDown.setHMS(0, 0, 0);
262 jobCountDown = jobCountDown.addSecs(m_captureProcess->getOverallRemainingTime());
263 jobLabel->setText(QString("Job (%1/%2)")
266 }
267
268 // update sequence remaining time
269 sequenceCountDown.setHMS(0, 0, 0);
270 sequenceCountDown = sequenceCountDown.addSecs(m_captureProcess->getActiveJobRemainingTime());
271 }
272}
273
274void CaptureCountsWidget::updateJobProgress(Ekos::SequenceJob *job)
275{
276 // display informations about the current active capture
277 if (job->jobType() == SequenceJob::JOBTYPE_PREVIEW)
278 setFrameInfo(i18n("Preview"), job->getCoreProperty(SequenceJob::SJ_Filter).toString(),
279 job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(), job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().x(),
280 job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().y(), job->getCoreProperty(SequenceJob::SJ_Gain).toDouble());
281 else
282 setFrameInfo(CCDFrameTypeNames[job->getFrameType()], job->getCoreProperty(SequenceJob::SJ_Filter).toString(),
283 job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble(), job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().x(),
284 job->getCoreProperty(SequenceJob::SJ_Binning).toPoint().y(), job->getCoreProperty(SequenceJob::SJ_Gain).toDouble());
285
286 // display sequence progress in the graphical view
287 gr_sequenceProgressBar->setRange(0, job->getCoreProperty(SequenceJob::SJ_Count).toInt());
288 gr_sequenceProgressBar->setValue(job->getCompleted());
289 if (job->jobType() == SequenceJob::JOBTYPE_PREVIEW)
290 sequenceLabel->setText(QString("%1").arg(frameLabel(CCDFrameTypeNames[job->getFrameType()],
291 job->getCoreProperty(SequenceJob::SJ_Filter).toString())));
292 else
293 sequenceLabel->setText(QString("%1 (%3/%4)")
294 .arg(frameLabel(CCDFrameTypeNames[job->getFrameType()],
295 job->getCoreProperty(SequenceJob::SJ_Filter).toString()))
296 .arg(job->getCompleted()).arg(job->getCoreProperty(SequenceJob::SJ_Count).toInt()));
297 gr_sequenceLabel->setText(sequenceLabel->text());
298}
299
300void CaptureCountsWidget::setEnabled(bool enabled)
301{
303 overallLabel->setEnabled(enabled);
304 gr_overallLabel->setEnabled(enabled);
305}
Q_SCRIPTABLE bool isActiveJobPreview()
DBUS interface function.
Definition capture.h:211
Q_SCRIPTABLE int getJobCount()
DBUS interface function.
Definition capture.h:219
Q_SCRIPTABLE double getProgressPercentage()
DBUS interface function.
Definition capture.h:203
Q_SCRIPTABLE int getActiveJobRemainingTime()
DBUS interface function.
Definition capture.h:243
Q_SCRIPTABLE int getJobImageCount(int id)
DBUS interface function.
Definition capture.h:287
Q_SCRIPTABLE int getJobImageProgress(int id)
DBUS interface function.
Definition capture.h:278
Q_SCRIPTABLE int getOverallRemainingTime()
DBUS interface function.
Definition capture.h:251
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 Fri May 17 2024 11:48:25 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.