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/ekos.h"
11 #include "ekos/manager.h"
12
CaptureCountsWidget(QWidget * parent)13 CaptureCountsWidget::CaptureCountsWidget(QWidget *parent) : QWidget(parent)
14 {
15 setupUi(this);
16 // switch between stacked views
17 connect(switchToGraphicsButton, &QPushButton::clicked, this, [this]() {textView->setVisible(false); graphicalView->setVisible(true); Options::setUseGraphicalCountsDisplay(true);});
18 connect(switchToTextButton, &QPushButton::clicked, this, [this]() {textView->setVisible(true); graphicalView->setVisible(false);Options::setUseGraphicalCountsDisplay(false);});
19
20 // start with the last used view
21 graphicalView->setVisible(Options::useGraphicalCountsDisplay());
22 textView->setVisible(!Options::useGraphicalCountsDisplay());
23
24 // setup graphical view
25 gr_sequenceProgressBar->setDecimals(0);
26 gr_overallProgressBar->setDecimals(0);
27
28 reset();
29 }
30
updateExposureProgress(Ekos::SequenceJob * job)31 void CaptureCountsWidget::updateExposureProgress(Ekos::SequenceJob *job)
32 {
33 imageCountDown.setHMS(0, 0, 0);
34 imageCountDown = imageCountDown.addSecs(int(std::round(job->getExposeLeft())));
35 if (imageCountDown.hour() == 23)
36 imageCountDown.setHMS(0, 0, 0);
37
38 imageProgress->setRange(0, int(std::ceil(job->getExposure())));
39 imageProgress->setValue(int(std::ceil(job->getExposure() - job->getExposeLeft())));
40 gr_imageProgress->setRange(0, int(std::ceil(job->getExposure())));
41 gr_imageProgress->setValue(imageProgress->value());
42
43 frameRemainingTime->setText(imageCountDown.toString("hh:mm:ss"));
44 gr_frameRemainingTime->setText(frameRemainingTime->text());
45 }
46
updateDownloadProgress(double timeLeft)47 void CaptureCountsWidget::updateDownloadProgress(double timeLeft)
48 {
49 imageCountDown.setHMS(0, 0, 0);
50 imageCountDown = imageCountDown.addSecs(int(std::ceil(timeLeft)));
51 frameRemainingTime->setText(imageCountDown.toString("hh:mm:ss"));
52 }
53
updateCaptureCountDown(int delta)54 void CaptureCountsWidget::updateCaptureCountDown(int delta)
55 {
56 overallCountDown = overallCountDown.addSecs(delta);
57 jobCountDown = jobCountDown.addSecs(delta);
58 sequenceCountDown = sequenceCountDown.addSecs(delta);
59
60 // ensure that count downs do not overshoot
61 if (overallCountDown.hour() == 23)
62 overallCountDown.setHMS(0, 0, 0);
63 if (jobCountDown.hour() == 23)
64 jobCountDown.setHMS(0, 0, 0);
65 if (sequenceCountDown.hour() == 23)
66 sequenceCountDown.setHMS(0, 0, 0);
67
68 // do not change overall remaining time if scheduler is in endless loop
69 if (schedulerProcess == nullptr || schedulerProcess->getCurrentJob() == nullptr ||
70 schedulerProcess->getCurrentJob()->getCompletionCondition() != SchedulerJob::FINISH_LOOP)
71 {
72 overallRemainingTime->setText(overallCountDown.toString("hh:mm:ss"));
73 gr_overallRemainingTime->setText(overallRemainingTime->text());
74 }
75 jobRemainingTime->setText(jobCountDown.toString("hh:mm:ss"));
76 sequenceRemainingTime->setText(sequenceCountDown.toString("hh:mm:ss"));
77 gr_sequenceRemainingTime->setText(sequenceRemainingTime->text());
78 }
79
reset()80 void CaptureCountsWidget::reset()
81 {
82 // reset graphical view
83 gr_imageProgress->setValue(0);
84 gr_frameLabel->setText("");
85 gr_frameRemainingTime->setText("--:--:--");
86 gr_frameDetailsLabel->setText("");
87 gr_sequenceLabel->setText(i18n("Sequence"));
88 gr_sequenceProgressBar->setValue(0);
89 gr_sequenceRemainingTime->setText("--:--:--");
90 gr_overallLabel->setText(i18n("Overall"));
91 gr_overallProgressBar->setValue(0);
92 gr_overallRemainingTime->setText("--:--:--");
93
94 // reset text view
95 imageProgress->setValue(0);
96 setFrameInfo("");
97 frameRemainingTime->setText("");
98
99 overallRemainingTime->setText("--:--:--");
100 jobRemainingTime->setText("--:--:--");
101 sequenceRemainingTime->setText("--:--:--");
102 }
103
setFrameInfo(const QString frametype,const QString filter,const double exptime,const int xBin,const int yBin,const double gain)104 void CaptureCountsWidget::setFrameInfo(const QString frametype, const QString filter, const double exptime, const int xBin, const int yBin, const double gain)
105 {
106 if (frametype == "")
107 {
108 frameInfoLabel->setText("");
109 frameDetailsLabel->setText("");
110 gr_frameRemainingTime->setText("");
111 }
112 else
113 {
114 frameInfoLabel->setText(QString("%1 %2").arg(frametype).arg(filter));
115 gr_frameLabel->setText(frameInfoLabel->text());
116 QString details = "";
117 if (exptime > 0)
118 details.append(QString("%1: %2 sec").arg(i18n("Exposure")).arg(exptime, 0, 'f', exptime < 1 ? 2: exptime < 5 ? 1 : 0));
119 if (xBin > 0 && yBin > 0)
120 details.append(QString(", bin: %1x%2").arg(xBin).arg(yBin));
121 if (gain >= 0)
122 details.append(QString(", gain: %1").arg(gain, 0, 'f', 1));
123
124 frameDetailsLabel->setText(details);
125 gr_frameDetailsLabel->setText(details);
126 }
127 }
128
updateCaptureStatus(Ekos::CaptureState status)129 void CaptureCountsWidget::updateCaptureStatus(Ekos::CaptureState status)
130 {
131 overallCountDown.setHMS(0, 0, 0);
132 bool infinite_loop = false;
133 int total_remaining_time = 0, total_completed = 0, total_count = 0;
134 double total_percentage = 0;
135 // use this value if no scheduler is running and job name otherwise
136 QString total_label = "Total";
137
138 // determine total number of frames and completed ones - used either for
139 // total numbers if scheduler is not used - and for job figures in the text
140 // display if the scheduler is used
141 double capture_total_percentage = captureProcess->getProgressPercentage();
142 int capture_remaining_time = captureProcess->getOverallRemainingTime();
143 int capture_total_count = 0, capture_total_completed = 0;
144 for (int i = 0; i < captureProcess->getJobCount(); i++)
145 {
146 capture_total_count += captureProcess->getJobImageCount(i);
147 capture_total_completed += captureProcess->getJobImageProgress(i);
148 }
149
150
151 if (schedulerProcess != nullptr && schedulerProcess->getCurrentJob() != nullptr)
152 {
153 total_label = schedulerProcess->getCurrentJobName();
154 // FIXME: accessing the completed count might be one too low due to concurrency of updating the count and this loop
155 total_completed = schedulerProcess->getCurrentJob()->getCompletedCount();
156 total_count = schedulerProcess->getCurrentJob()->getSequenceCount();
157 infinite_loop = (schedulerProcess->getCurrentJob()->getCompletionCondition() == SchedulerJob::FINISH_LOOP);
158 if (total_count > 0)
159 total_percentage = (100 * total_completed) / total_count;
160 if (schedulerProcess->getCurrentJob()->getEstimatedTime() > 0)
161 total_remaining_time = int(schedulerProcess->getCurrentJob()->getEstimatedTime());
162 }
163 else
164 {
165 total_percentage = capture_total_percentage;
166 total_remaining_time = capture_remaining_time;
167 total_count = capture_total_count;
168 total_completed = capture_total_completed;
169 }
170
171 switch (status)
172 {
173 case Ekos::CAPTURE_IDLE:
174 // do nothing
175 break;
176 case Ekos::CAPTURE_ABORTED:
177 reset();
178 break;
179 default:
180 if (infinite_loop == true)
181 {
182 overallRemainingTime->setText("--:--:--");
183 gr_overallProgressBar->setValue(0);
184 gr_overallRemainingTime->setText(overallRemainingTime->text());
185 }
186 else
187 {
188 overallCountDown = overallCountDown.addSecs(total_remaining_time);
189 gr_overallProgressBar->setValue(total_percentage);
190 }
191
192 // display overall remainings
193 overallLabel->setText(QString("%1 (%2/%3)")
194 .arg(total_label)
195 .arg(total_completed)
196 .arg(infinite_loop ? QString("-") : QString::number(total_count)));
197 gr_overallLabel->setText(overallLabel->text());
198
199 // update job remaining time if run from the scheduler
200 bool show_job_progress = (schedulerProcess != nullptr && schedulerProcess->getCurrentJob() != nullptr);
201 jobLabel->setVisible(show_job_progress);
202 jobRemainingTime->setVisible(show_job_progress);
203 if (show_job_progress)
204 {
205 jobCountDown.setHMS(0, 0, 0);
206 jobCountDown = jobCountDown.addSecs(captureProcess->getOverallRemainingTime());
207 jobLabel->setText(QString("Job (%1/%2)")
208 .arg(capture_total_completed)
209 .arg(capture_total_count));
210 }
211
212 // update sequence remaining time
213 sequenceCountDown.setHMS(0, 0, 0);
214 sequenceCountDown = sequenceCountDown.addSecs(captureProcess->getActiveJobRemainingTime());
215 }
216 }
217
updateJobProgress(Ekos::SequenceJob * job)218 void CaptureCountsWidget::updateJobProgress(Ekos::SequenceJob *job)
219 {
220 // display informations about the current active capture
221 if (job->isPreview() == true)
222 setFrameInfo(i18n("Preview"), job->getFilterName(), job->getExposure(), job->getXBin(), job->getYBin(), job->getGain());
223 else
224 setFrameInfo(CCDFrameTypeNames[job->getFrameType()], job->getFilterName(), job->getExposure(), job->getXBin(), job->getYBin(), job->getGain());
225
226 // display sequence progress in the graphical view
227 gr_sequenceProgressBar->setRange(0, job->getCount());
228 gr_sequenceProgressBar->setValue(job->getCompleted());
229 sequenceLabel->setText(QString("%1 %2 (%3/%4)")
230 .arg(CCDFrameTypeNames[job->getFrameType()])
231 .arg(job->getFilterName())
232 .arg(job->getCompleted()).arg(job->getCount()));
233 gr_sequenceLabel->setText(sequenceLabel->text());
234 }
235
setEnabled(bool enabled)236 void CaptureCountsWidget::setEnabled(bool enabled)
237 {
238 QWidget::setEnabled(enabled);
239 overallLabel->setEnabled(enabled);
240 gr_overallLabel->setEnabled(enabled);
241 }
242