Kstars

capturepreviewwidget.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 "capturepreviewwidget.h"
9#include "sequencejob.h"
10#include <ekos_capture_debug.h>
11#include "ksutils.h"
12#include "ksmessagebox.h"
13#include "ekos/mount/mount.h"
14#include "Options.h"
15#include "capture.h"
16#include "sequencejob.h"
17#include "fitsviewer/fitsdata.h"
18#include "fitsviewer/summaryfitsview.h"
19#include "ekos/scheduler/schedulerjob.h"
20#include "ekos/scheduler/schedulermodulestate.h"
21
22using Ekos::SequenceJob;
23
24CapturePreviewWidget::CapturePreviewWidget(QWidget *parent) : QWidget(parent)
25{
26 setupUi(this);
27 m_overlay = new CaptureProcessOverlay();
28 m_overlay->setVisible(false);
29 // history navigation
30 connect(m_overlay->historyBackwardButton, &QPushButton::clicked, this, &CapturePreviewWidget::showPreviousFrame);
31 connect(m_overlay->historyForwardButton, &QPushButton::clicked, this, &CapturePreviewWidget::showNextFrame);
32 // deleting of captured frames
33 connect(m_overlay->deleteCurrentFrameButton, &QPushButton::clicked, this, &CapturePreviewWidget::deleteCurrentFrame);
34}
35
36void CapturePreviewWidget::shareCaptureModule(Ekos::Capture *module)
37{
38 m_captureModule = module;
39 captureCountsWidget->shareCaptureProcess(module);
40
41 if (m_captureModule != nullptr)
42 {
43 connect(m_captureModule, &Ekos::Capture::newDownloadProgress, captureCountsWidget,
44 &CaptureCountsWidget::updateDownloadProgress);
45 connect(m_captureModule, &Ekos::Capture::newExposureProgress, captureCountsWidget,
46 &CaptureCountsWidget::updateExposureProgress);
47 connect(m_captureModule, &Ekos::Capture::captureTarget, this, &CapturePreviewWidget::setTargetName);
48 }
49}
50
51void CapturePreviewWidget::shareSchedulerModuleState(QSharedPointer<Ekos::SchedulerModuleState> state)
52{
53 m_schedulerModuleState = state;
54 captureCountsWidget->shareSchedulerState(state);
55}
56
57void CapturePreviewWidget::shareMountModule(Ekos::Mount *module)
58{
59 m_mountModule = module;
60 connect(m_mountModule, &Ekos::Mount::newTargetName, this, &CapturePreviewWidget::setTargetName);
61}
62
63void CapturePreviewWidget::updateJobProgress(Ekos::SequenceJob *job, const QSharedPointer<FITSData> &data)
64{
65 // forward first to the counting widget
66 captureCountsWidget->updateJobProgress(job);
67
68 // without FITS data, we do nothing
69 if (data == nullptr)
70 return;
71
72 // cache frame meta data
73 m_currentFrame.frameType = job->getFrameType();
74 if (job->getFrameType() == FRAME_LIGHT)
75 {
76 if (m_schedulerModuleState != nullptr && m_schedulerModuleState->activeJob() != nullptr)
77 m_currentFrame.target = m_schedulerModuleState->activeJob()->getName();
78 else
79 m_currentFrame.target = m_mountTarget;
80 }
81 else
82 m_currentFrame.target = "";
83
84 m_currentFrame.filterName = job->getCoreProperty(SequenceJob::SJ_Filter).toString();
85 m_currentFrame.exptime = job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble();
86 m_currentFrame.targetdrift = -1.0; // will be updated later
87 m_currentFrame.binning = job->getCoreProperty(SequenceJob::SJ_Binning).toPoint();
88 m_currentFrame.gain = job->getCoreProperty(SequenceJob::SJ_Gain).toDouble();
89 m_currentFrame.offset = job->getCoreProperty(SequenceJob::SJ_Offset).toDouble();
90 m_currentFrame.filename = data->filename();
91 m_currentFrame.width = data->width();
92 m_currentFrame.height = data->height();
93
94 const auto ISOIndex = job->getCoreProperty(SequenceJob::SJ_Offset).toInt();
95 if (ISOIndex >= 0 && ISOIndex <= m_captureModule->cameraUI->captureISOS->count())
96 m_currentFrame.iso = m_captureModule->cameraUI->captureISOS->itemText(ISOIndex);
97 else
98 m_currentFrame.iso = "";
99
100 // add it to the overlay
101 m_overlay->addFrameData(m_currentFrame);
102 m_overlay->setVisible(true);
103
104 // load frame
105 if (m_fitsPreview != nullptr && Options::useSummaryPreview())
106 m_fitsPreview->loadData(data);
107}
108
109void CapturePreviewWidget::showNextFrame()
110{
111 m_overlay->setEnabled(false);
112 if (m_overlay->showNextFrame())
113 m_fitsPreview->loadFile(m_overlay->currentFrame().filename);
114 // Hint: since the FITSView loads in the background, we have to wait for FITSView::load() to enable the layer
115 else
116 m_overlay->setEnabled(true);
117}
118
119void CapturePreviewWidget::showPreviousFrame()
120{
121 m_overlay->setEnabled(false);
122 if (m_overlay->showPreviousFrame())
123 m_fitsPreview->loadFile(m_overlay->currentFrame().filename);
124 // Hint: since the FITSView loads in the background, we have to wait for FITSView::load() to enable the layer
125 else
126 m_overlay->setEnabled(true);
127}
128
129void CapturePreviewWidget::deleteCurrentFrame()
130{
131 m_overlay->setEnabled(false);
132 if (m_overlay->hasFrames() == false)
133 // nothing to delete
134 return;
135
136 // make sure that the history does not change inbetween
137 int pos = m_overlay->currentPosition();
138 CaptureProcessOverlay::FrameData current = m_overlay->getFrame(pos);
139 QFile *file = new QFile(current.filename);
140
141 // prepare a warning dialog
142 // move to trash or delete permanently
143 QCheckBox *permanentlyDeleteCB = new QCheckBox(i18n("Delete directly, do not move to trash."));
144 permanentlyDeleteCB->setChecked(m_permanentlyDelete);
145 KSMessageBox::Instance()->setCheckBox(permanentlyDeleteCB);
146 connect(permanentlyDeleteCB, &QCheckBox::toggled, this, [this](bool checked)
147 {
148 this->m_permanentlyDelete = checked;
149 });
150 // Delete
151 connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this, pos, file]()
152 {
153 KSMessageBox::Instance()->disconnect(this);
154 bool success = false;
155 if (this->m_permanentlyDelete == false && (success = file->moveToTrash()))
156 {
157 qCInfo(KSTARS_EKOS_CAPTURE) << m_overlay->currentFrame().filename << "moved to Trash.";
158 }
159 else if (this->m_permanentlyDelete && (success = file->remove()))
160 {
161 qCInfo(KSTARS_EKOS_CAPTURE) << m_overlay->currentFrame().filename << "deleted.";
162 }
163
164 if (success)
165 {
166 // delete it from the history and update the FITS view
167 if (m_overlay->deleteFrame(pos) && m_overlay->hasFrames())
168 {
169 m_fitsPreview->loadFile(m_overlay->currentFrame().filename);
170 // Hint: since the FITSView loads in the background, we have to wait for FITSView::load() to enable the layer
171 }
172 else
173 {
174 m_fitsPreview->clearData();
175 m_overlay->setEnabled(true);
176 }
177 }
178 else
179 {
180 qCWarning(KSTARS_EKOS_CAPTURE) << "Deleting" << m_overlay->currentFrame().filename << "failed!";
181 // give up
182 m_overlay->setEnabled(true);
183 }
184 // clear the check box
185 KSMessageBox::Instance()->setCheckBox(nullptr);
186 });
187
188 // Cancel
189 connect(KSMessageBox::Instance(), &KSMessageBox::rejected, this, [this]()
190 {
191 KSMessageBox::Instance()->disconnect(this);
192 // clear the check box
193 KSMessageBox::Instance()->setCheckBox(nullptr);
194 //do nothing
195 m_overlay->setEnabled(true);
196 });
197
198 // open the message box
199 QFileInfo fileinfo(current.filename);
200 KSMessageBox::Instance()->warningContinueCancel(i18n("Do you really want to delete %1 from the file system?",
201 fileinfo.fileName()),
202 i18n("Delete %1", fileinfo.fileName()), 0, false, i18n("Delete"));
203
204}
205
206void CapturePreviewWidget::setSummaryFITSView(SummaryFITSView *view)
207{
208 m_fitsPreview = view;
210 vlayout->setContentsMargins(0, 0, 0, 0);
211 vlayout->addWidget(view);
212 previewWidget->setLayout(vlayout);
213 previewWidget->setContentsMargins(0, 0, 0, 0);
214
215 // initialize the FITS data overlay
216 // create vertically info box as overlay
217 QVBoxLayout *layout = new QVBoxLayout(view->processInfoWidget);
218 layout->addWidget(m_overlay, 0);
219
220 view->processInfoWidget->setLayout(layout);
221 // react upon signals
222 connect(view, &FITSView::loaded, [&]()
223 {
224 m_overlay->setEnabled(true);
225 });
226 connect(view, &FITSView::failed, [&]()
227 {
228 m_overlay->setEnabled(true);
229 });
230}
231
232void CapturePreviewWidget::setEnabled(bool enabled)
233{
234 // forward to sub widget
235 captureCountsWidget->setEnabled(enabled);
237}
238
239void CapturePreviewWidget::reset()
240{
241 m_overlay->setVisible(false);
242 // forward to sub widget
243 captureCountsWidget->reset();
244}
245
246void CapturePreviewWidget::updateCaptureStatus(Ekos::CaptureState status, bool isPreview)
247{
248 // forward to sub widgets
249 captureStatusWidget->setCaptureState(status);
250 captureCountsWidget->updateCaptureStatus(status, isPreview);
251}
252
253void CapturePreviewWidget::updateTargetDistance(double targetDiff)
254{
255 // forward it to the overlay
256 m_overlay->updateTargetDistance(targetDiff);
257}
258
259void CapturePreviewWidget::updateCaptureCountDown(int delta)
260{
261 // forward to sub widget
262 captureCountsWidget->updateCaptureCountDown(delta);
263}
264
265void CapturePreviewWidget::setTargetName(QString name)
266{
267 targetLabel->setVisible(!name.isEmpty());
268 mountTarget->setVisible(!name.isEmpty());
269 mountTarget->setText(name);
270 m_mountTarget = name;
271 m_currentFrame.target = name;
272}
273
Captures single or sequence of images from a CCD.
Definition capture.h:92
Supports controlling INDI telescope devices including setting/retrieving mount properties,...
Definition mount.h:33
void newTargetName(const QString &name)
The mount has finished the slew to a new target.
QString i18n(const char *text, const TYPE &arg...)
CaptureState
Capture states.
Definition ekos.h:92
QString name(StandardAction id)
void clicked(bool checked)
void toggled(bool checked)
void accepted()
void rejected()
bool moveToTrash()
bool remove()
void addWidget(QWidget *w)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
QPoint toPoint() const const
QString toString() const const
void setEnabled(bool)
QLayout * layout() const const
void setLayout(QLayout *layout)
virtual void setVisible(bool visible)
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.