Kstars

captureprocessoverlay.cpp
1 /*
2  SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5  */
6 
7 #include "captureprocessoverlay.h"
8 
9 #include "QTime"
10 #include "QFileInfo"
11 
12 CaptureProcessOverlay::CaptureProcessOverlay(QWidget *parent) : QWidget(parent)
13 {
14  setupUi(this);
15  // use white as text color
16  setStyleSheet("color: rgb(255, 255, 255);");
17  connect(updateStatisticsButton, &QPushButton::clicked, [&]
18  {
19  m_captureHistory.updateTargetStatistics();
20  // refresh the display for the current frame
21  updateFrameData();
22  // refresh the statistics display
23  displayTargetStatistics();
24  });
25 }
26 
27 bool CaptureProcessOverlay::addFrameData(FrameData data)
28 {
29  if (m_captureHistory.addFrame(data) == false)
30  return false;
31  // refresh the display for the current frame
32  updateFrameData();
33  // refresh the statistics display
34  displayTargetStatistics();
35  return true;
36 }
37 
38 void CaptureProcessOverlay::updateFrameData()
39 {
40  // nothing to display
41  if (hasFrames() == false)
42  {
43  frameDataWidget->setVisible(false);
44  return;
45  }
46  frameDataWidget->setVisible(true);
47  const FrameData currentFrame = m_captureHistory.currentFrame();
48  frameTypeLabel->setText(QString("%1 %2").arg(CCDFrameTypeNames[currentFrame.frameType]).arg(currentFrame.filterName));
49  exposureValue->setText(QString("%1 sec").arg(currentFrame.exptime, 0, 'f',
50  currentFrame.exptime < 1 ? 2 : currentFrame.exptime < 5 ? 1 : 0));
51  binningValue->setText(QString("%1x%2").arg(currentFrame.binning.x()).arg(currentFrame.binning.y()));
52  filenameValue->setText(currentFrame.filename);
53  geometryValue->setText(QString("%1px x %2px").arg(currentFrame.width).arg(currentFrame.height));
54 
55  bool visible = (currentFrame.gain >= 0);
56  gainLabel->setVisible(visible);
57  gainValue->setVisible(visible);
58  gainValue->setText(QString("%1").arg(currentFrame.gain, 0, 'f', 1));
59 
60  visible = (currentFrame.offset >= 0);
61  offsetLabel->setVisible(visible);
62  offsetValue->setVisible(visible);
63  offsetValue->setText(QString("%1").arg(currentFrame.offset, 0, 'f', 1));
64 
65  visible = (currentFrame.iso != "");
66  isoValue->setVisible(visible);
67  isoValue->setText(QString("ISO %1").arg(currentFrame.iso));
68 
69  visible = (currentFrame.targetdrift >= 0);
70  targetDriftLabel->setVisible(visible);
71  targetDriftValue->setVisible(visible);
72  targetDriftValue->setText(QString("%L1\"").arg(currentFrame.targetdrift, 0, 'f', 1));
73 
74  // determine file creation date
75  QFileInfo fileinfo(currentFrame.filename);
76  const QDateTime lastmodified = fileinfo.lastModified();
77  captureDate->setText(lastmodified.toString("dd.MM.yyyy hh:mm:ss"));
78 
79  // update capture counts
80  if (m_captureHistory.size() > 0)
81  historyCountsLabel->setText(QString("(%1/%2)").arg(m_captureHistory.position() + 1).arg(m_captureHistory.size()));
82  else
83  historyCountsLabel->setText("");
84 
85  // update enabling of the navigation buttons
86  historyBackwardButton->setEnabled(m_captureHistory.size() > 0 && m_captureHistory.position() > 0);
87  historyForwardButton->setEnabled(m_captureHistory.size() > 0 && m_captureHistory.size() - m_captureHistory.position() > 1);
88 }
89 
90 void CaptureProcessOverlay::updateTargetDistance(double targetDiff)
91 {
92  // since the history is read only, we need to delete the last one and add it again.
93  FrameData lastFrame = m_captureHistory.getFrame(m_captureHistory.size()-1);
94  lastFrame.targetdrift = targetDiff;
95  m_captureHistory.deleteFrame(m_captureHistory.size()-1);
96  m_captureHistory.addFrame(lastFrame);
97  updateFrameData();
98 }
99 
100 void CaptureProcessOverlay::displayTargetStatistics()
101 {
102  QString display = "";
103  // iterate over all targets
104  QList<QString> targets = m_captureHistory.statistics.keys();
105  for (QList<QString>::iterator target_it = targets.begin(); target_it != targets.end(); target_it++)
106  {
107  display.append(QString("<p><b><u>%1</u></b><table border=0>").arg(*target_it == "" ? "<it>" + i18n("No target") + "</it>" :
108  *target_it));
109 
110  // iterate over all types of captured frames
111  QList<QPair<CCDFrameType, QString>> keys = m_captureHistory.statistics[*target_it].keys();
112  for (QList<QPair<CCDFrameType, QString>>::iterator key_it = keys.begin(); key_it != keys.end(); key_it++)
113  {
114  // add frame type x filter as header
115  QString frame_type = CCDFrameTypeNames[key_it->first];
116  QString filter = key_it->second;
117 
118  // add statistics per exposure time
119  QList<QPair<int, int>*> counts = m_captureHistory.statistics[*target_it].value(*key_it);
120  for (QList<QPair<int, int>*>::iterator it = counts.begin(); it != counts.end(); it++)
121  {
122  double exptime = (*it)->first / 1000.0;
123  QTime total(0, 0, 0, 0);
124  total = total.addMSecs(int((*it)->first * (*it)->second));
125  display.append(QString("<tr><td><b>%1 %2</b> (%3 x %4 sec):</td><td style=\"text-align: right\">%5</td></tr>")
126  .arg(frame_type).arg(filter)
127  .arg((*it)->second)
128  .arg(exptime, 0, 'f', exptime < 10 ? 2 : 0)
129  .arg(total.toString("hh:mm:ss")));
130  }
131  }
132  display.append("</table></p>");
133  }
134  // display statistics
135  captureStatisticsLabel->setText(display);
136 }
137 
138 bool CaptureProcessOverlay::showNextFrame()
139 {
140  if (m_captureHistory.forward())
141  {
142  updateFrameData();
143  return true;
144  }
145  return false;
146 }
147 
148 bool CaptureProcessOverlay::showPreviousFrame()
149 {
150  if (m_captureHistory.backward())
151  {
152  updateFrameData();
153  return true;
154  }
155  return false;
156 }
157 
158 bool CaptureProcessOverlay::deleteFrame(int pos)
159 {
160  if (m_captureHistory.deleteFrame(pos) == true)
161  {
162  // deleting succeeded, update overlay
163  updateFrameData();
164  displayTargetStatistics();
165  return true;
166  }
167  return false;
168 }
169 
170 bool CaptureProcessOverlay::CaptureHistory::addFrame(CaptureProcessOverlay::FrameData data)
171 {
172  // check if the file already exists in the history
173  for (QList<FrameData>::iterator it = m_history.begin(); it != m_history.end(); it++)
174  if (it->filename == data.filename)
175  // already exists, ignore
176  return false;
177  // history is clean, simply append
178  m_history.append(data);
179  m_position = m_history.size() - 1;
180  countNewFrame(data.target, data.frameType, data.filterName, data.exptime);
181  return true;
182 }
183 
185 {
186  if (m_history.size() != 0 && pos < m_history.size())
187  {
188  m_history.removeAt(pos);
189  // adapt the current position if the deleted frame was deleted before it or itself
190  if (m_position >= pos)
191  m_position -= 1;
192  // ensure staying in range
193  if (m_position < 0 && m_history.size() > 0)
194  m_position = 0;
195  else if (m_position >= m_history.size())
196  m_position = m_history.size() - 1;
197  // update statistics, since one file is missing
198  updateTargetStatistics();
199  return true;
200  }
201  else
202  return false;
203 }
204 
206 {
207  m_position = -1;
208  m_history.clear();
209 }
210 
212 {
213  if (m_position < m_history.size() - 1)
214  {
215  m_position++;
216  return true;
217  }
218  else
219  return false;
220 }
221 
223 {
224  if (m_position > 0)
225  {
226  m_position--;
227  return true;
228  }
229  else
230  return false;
231 }
232 
234 {
235  statistics.clear();
236  QList<FrameData> new_history;
237  // iterate over all entries in the history to update the statistics
238  for (QList<FrameData>::iterator list_it = m_history.begin(); list_it != m_history.end(); list_it++)
239  {
240  // if the corresponding file exists, add it to the statistics
241  if (QFile(list_it->filename).exists())
242  {
243  countNewFrame(list_it->target, list_it->frameType, list_it->filterName, list_it->exptime);
244  new_history.append(*list_it);
245  }
246  }
247  // switch history lists
248  m_history.clear();
249  m_history = new_history;
250 
251  // check if the position is correct, if not move to the last element
252  if (m_position >= m_history.size())
253  m_position = m_history.size() - 1;
254 }
255 
256 void CaptureProcessOverlay::CaptureHistory::countNewFrame(QString target, CCDFrameType frameType, QString filter,
257  double exptime)
258 {
259  // create search key
260  QPair<CCDFrameType, QString> key(frameType, filter);
261  // due to the equality problem with double, we use a milliseconds for exposure time
262  int exptime_r = int(exptime * 1000);
263  // create new target map if missing
264  if (statistics.contains(target) == false)
265  statistics.insert(target, CaptureProcessOverlay::FrameStatistics());
266  // create new filter list if missing
267  if (statistics[target].contains(key) == false)
268  statistics[target].insert(key, QList<QPair<int, int>*>());
269 
270  QPair<int, int>* count = nullptr;
271  QList<QPair<int, int>*> *counts = &statistics[target][key];
272  for (QList<QPair<int, int>*>::iterator it = counts->begin(); it != counts->end(); it++)
273  {
274  // search for matching exposure time
275  if ((*it)->first == exptime_r)
276  {
277  count = *it;
278  break;
279  }
280  }
281  // nothing found, initialize
282  if (count == nullptr)
283  {
284  count = new QPair<int, int>(exptime_r, 0);
285  counts->append(count);
286  }
287  // increase the counter
288  count->second = count->second + 1;
289 }
void append(const T &value)
bool backward()
Move one step backwards in the history.
void clicked(bool checked)
void setStyleSheet(const QString &styleSheet)
bool deleteFrame(int pos)
Delete the current frame and (if possible) the corresponding file.
bool exists() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
int size() const const
QString i18n(const char *text, const TYPE &arg...)
bool addFrame(FrameData data)
Add a newly captured frame to the history.
QFuture< void > filter(Sequence &sequence, KeepFunctor filterFunction)
bool forward()
Move one step forward in the history.
void setupUi(QWidget *widget)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QList::iterator begin()
void updateTargetStatistics()
Iterate over the current target history and add all those where the corresponding file exists.
QString toString(Qt::DateFormat format) const const
QList::iterator end()
T value(int i) const const
QString & append(QChar ch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:49 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.