Kstars

capturepreviewwidget.cpp
1 /*
2  SPDX-FileCopyrightText: 2012 Jasem Mutlaq <[email protected]>
3  SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <[email protected]>
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 "Options.h"
14 
15 using Ekos::SequenceJob;
16 
17 CapturePreviewWidget::CapturePreviewWidget(QWidget *parent) : QWidget(parent)
18 {
19  setupUi(this);
20  overlay = new CaptureProcessOverlay();
21  overlay->setVisible(false);
22  // history navigation
23  connect(overlay->historyBackwardButton, &QPushButton::clicked, this, &CapturePreviewWidget::showPreviousFrame);
24  connect(overlay->historyForwardButton, &QPushButton::clicked, this, &CapturePreviewWidget::showNextFrame);
25  // deleting of captured frames
26  connect(overlay->deleteCurrentFrameButton, &QPushButton::clicked, this, &CapturePreviewWidget::deleteCurrentFrame);
27 }
28 
29 void CapturePreviewWidget::shareCaptureProcess(Ekos::Capture *process)
30 {
31  captureProcess = process;
32  captureCountsWidget->shareCaptureProcess(process);
33 
34  if (captureProcess != nullptr)
35  {
36  connect(captureProcess, &Ekos::Capture::newDownloadProgress, captureCountsWidget,
37  &CaptureCountsWidget::updateDownloadProgress);
38  connect(captureProcess, &Ekos::Capture::newExposureProgress, captureCountsWidget,
39  &CaptureCountsWidget::updateExposureProgress);
40  }
41 }
42 
43 void CapturePreviewWidget::shareSchedulerProcess(Ekos::Scheduler *process)
44 {
45  schedulerProcess = process;
46  captureCountsWidget->shareSchedulerProcess(process);
47 }
48 
49 void CapturePreviewWidget::shareMountProcess(Ekos::Mount *process)
50 {
51  mountProcess = process;
52  connect(mountProcess, &Ekos::Mount::newTargetName, this, [this](const QString & name)
53  {
54  m_mountTarget = name;
55  });
56 }
57 
58 void CapturePreviewWidget::updateJobProgress(Ekos::SequenceJob *job, const QSharedPointer<FITSData> &data)
59 {
60  // forward first to the counting widget
61  captureCountsWidget->updateJobProgress(job);
62 
63  // without FITS data, we do nothing
64  if (data == nullptr)
65  return;
66 
67  // cache frame meta data
68  m_currentFrame.frameType = job->getFrameType();
69  if (job->getFrameType() == FRAME_LIGHT)
70  {
71  if (schedulerProcess != nullptr && schedulerProcess->getCurrentJob() != nullptr)
72  m_currentFrame.target = schedulerProcess->getCurrentJob()->getName();
73  else
74  m_currentFrame.target = m_mountTarget;
75  }
76  else
77  m_currentFrame.target = "";
78 
79  m_currentFrame.filterName = job->getCoreProperty(SequenceJob::SJ_Filter).toString();
80  m_currentFrame.exptime = job->getCoreProperty(SequenceJob::SJ_Exposure).toDouble();
81  m_currentFrame.targetdrift = -1.0; // will be updated later
82  m_currentFrame.binning = job->getCoreProperty(SequenceJob::SJ_Binning).toPoint();
83  m_currentFrame.gain = job->getCoreProperty(SequenceJob::SJ_Gain).toDouble();
84  m_currentFrame.offset = job->getCoreProperty(SequenceJob::SJ_Offset).toDouble();
85  m_currentFrame.filename = data->filename();
86  m_currentFrame.width = data->width();
87  m_currentFrame.height = data->height();
88 
89  const auto ISOIndex = job->getCoreProperty(SequenceJob::SJ_Offset).toInt();
90  if (ISOIndex >= 0 && ISOIndex <= captureProcess->captureISOS->count())
91  m_currentFrame.iso = captureProcess->captureISOS->itemText(ISOIndex);
92  else
93  m_currentFrame.iso = "";
94 
95  // load frame
96  if (m_fitsPreview != nullptr && Options::useSummaryPreview())
97  m_fitsPreview->loadData(data);
98 }
99 
100 void CapturePreviewWidget::showNextFrame()
101 {
102  overlay->setEnabled(false);
103  if (overlay->showNextFrame())
104  m_fitsPreview->loadFile(overlay->currentFrame().filename);
105  // Hint: since the FITSView loads in the background, we have to wait for FITSView::load() to enable the layer
106  else
107  overlay->setEnabled(true);
108 }
109 
110 void CapturePreviewWidget::showPreviousFrame()
111 {
112  overlay->setEnabled(false);
113  if (overlay->showPreviousFrame())
114  m_fitsPreview->loadFile(overlay->currentFrame().filename);
115  // Hint: since the FITSView loads in the background, we have to wait for FITSView::load() to enable the layer
116  else
117  overlay->setEnabled(true);
118 }
119 
120 void CapturePreviewWidget::deleteCurrentFrame()
121 {
122  overlay->setEnabled(false);
123  if (overlay->hasFrames() == false)
124  // nothing to delete
125  return;
126 
127  // make sure that the history does not change inbetween
128  int pos = overlay->currentPosition();
129  CaptureProcessOverlay::FrameData current = overlay->getFrame(pos);
130  QFile *file = new QFile(current.filename);
131 
132  // prepare a warning dialog
133  // Delete
134  connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this, pos, file]()
135  {
136  KSMessageBox::Instance()->disconnect(this);
137 
138  if (file->remove() == true)
139  {
140  qCInfo(KSTARS_EKOS_CAPTURE) << overlay->currentFrame().filename << "deleted.";
141  }
142  else
143  {
144  qCWarning(KSTARS_EKOS_CAPTURE) << "Deleting" << overlay->currentFrame().filename << "failed!";
145  // give up
146  overlay->setEnabled(true);
147  return;
148  }
149 
150  // delete it from the history and update the FITS view
151  if (overlay->deleteFrame(pos) && overlay->hasFrames())
152  {
153  m_fitsPreview->loadFile(overlay->currentFrame().filename);
154  // Hint: since the FITSView loads in the background, we have to wait for FITSView::load() to enable the layer
155  }
156  else
157  {
158  m_fitsPreview->clearData();
159  overlay->setEnabled(true);
160  }
161  });
162 
163  // Cancel
164  connect(KSMessageBox::Instance(), &KSMessageBox::rejected, this, [this]()
165  {
166  KSMessageBox::Instance()->disconnect(this);
167  //do nothing
168  overlay->setEnabled(true);
169  });
170 
171  // open the message box
172  QFileInfo fileinfo(current.filename);
173  KSMessageBox::Instance()->warningContinueCancel(i18n("Do you really want to delete %1 from the file system?",
174  fileinfo.fileName()),
175  i18n("Delete %1", fileinfo.fileName()), 15, false, i18n("Delete"));
176 
177 }
178 
179 void CapturePreviewWidget::setSummaryFITSView(SummaryFITSView *view)
180 {
181  m_fitsPreview = view;
182  QVBoxLayout * vlayout = new QVBoxLayout();
183  vlayout->setContentsMargins(0, 0, 0, 0);
184  vlayout->addWidget(view);
185  previewWidget->setLayout(vlayout);
186  previewWidget->setContentsMargins(0, 0, 0, 0);
187 
188  // initialize the FITS data overlay
189  // create vertically info box as overlay
190  QVBoxLayout *layout = new QVBoxLayout(view->processInfoWidget);
191  layout->addWidget(overlay, 0);
192 
193  view->processInfoWidget->setLayout(layout);
194  // react upon signals
195  connect(view, &FITSView::loaded, [&]()
196  {
197  overlay->setEnabled(true);
198  });
199  connect(view, &FITSView::failed, [&]()
200  {
201  overlay->setEnabled(true);
202  });
203 }
204 
205 void CapturePreviewWidget::setEnabled(bool enabled)
206 {
207  // forward to sub widget
208  captureCountsWidget->setEnabled(enabled);
209  QWidget::setEnabled(enabled);
210 }
211 
212 void CapturePreviewWidget::reset()
213 {
214  overlay->setVisible(false);
215  // forward to sub widget
216  captureCountsWidget->reset();
217 }
218 
219 void CapturePreviewWidget::updateCaptureStatus(Ekos::CaptureState status)
220 {
221  captureStatusWidget->setCaptureState(status);
222 
223  // update the data of the overlay
224  if (status == Ekos::CAPTURE_IMAGE_RECEIVED)
225  {
226  overlay->addFrameData(m_currentFrame);
227  overlay->setVisible(true);
228  }
229 
230  // forward to sub widget
231  captureCountsWidget->updateCaptureStatus(status);
232 }
233 
234 void CapturePreviewWidget::updateTargetDistance(double targetDiff)
235 {
236  // forward it to the overlay
237  overlay->updateTargetDistance(targetDiff);
238 }
239 
240 void CapturePreviewWidget::updateCaptureCountDown(int delta)
241 {
242  // forward to sub widget
243  captureCountsWidget->updateCaptureCountDown(delta);
244 }
Supports controlling INDI telescope devices including setting/retrieving mount properties,...
Definition: mount.h:31
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
bool remove()
void clicked(bool checked)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void rejected()
QString i18n(const char *text, const TYPE &arg...)
CaptureState
Capture states.
Definition: ekos.h:91
void setupUi(QWidget *widget)
void setEnabled(bool)
Captures single or sequence of images from a CCD. The capture class support capturing single or multi...
Definition: capture.h:83
void newTargetName(const QString &name)
The mount has finished the slew to a new target.
QString name(StandardShortcut id)
void setContentsMargins(int left, int top, int right, int bottom)
The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs...
Definition: scheduler.h:49
@ CAPTURE_IMAGE_RECEIVED
Definition: ekos.h:101
void accepted()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Aug 15 2022 04:04:00 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.