File indexing completed on 2024-04-28 03:43:16
0001 /* 0002 SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <sterne-jaeger@openfuture.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "captureprocessoverlay.h" 0008 #include "QTime" 0009 #include "QFileInfo" 0010 0011 CaptureProcessOverlay::CaptureProcessOverlay(QWidget *parent) : QWidget(parent) 0012 { 0013 setupUi(this); 0014 // use white as text color 0015 setStyleSheet("color: rgb(255, 255, 255);"); 0016 connect(updateStatisticsButton, &QPushButton::clicked, [&] 0017 { 0018 m_captureHistory.updateTargetStatistics(); 0019 // refresh the display for the current frame 0020 updateFrameData(); 0021 // refresh the statistics display 0022 displayTargetStatistics(); 0023 }); 0024 } 0025 0026 bool CaptureProcessOverlay::addFrameData(FrameData data) 0027 { 0028 if (m_captureHistory.addFrame(data) == false) 0029 return false; 0030 // refresh the display for the current frame 0031 updateFrameData(); 0032 // refresh the statistics display 0033 displayTargetStatistics(); 0034 return true; 0035 } 0036 0037 void CaptureProcessOverlay::updateFrameData() 0038 { 0039 // nothing to display 0040 if (hasFrames() == false) 0041 { 0042 frameDataWidget->setVisible(false); 0043 return; 0044 } 0045 frameDataWidget->setVisible(true); 0046 const FrameData currentFrame = m_captureHistory.currentFrame(); 0047 frameTypeLabel->setText(QString("%1 %2").arg(CCDFrameTypeNames[currentFrame.frameType]).arg(currentFrame.filterName)); 0048 exposureValue->setText(QString("%1 sec").arg(currentFrame.exptime, 0, 'f', 0049 currentFrame.exptime < 1 ? 2 : currentFrame.exptime < 5 ? 1 : 0)); 0050 binningValue->setText(QString("%1x%2").arg(currentFrame.binning.x()).arg(currentFrame.binning.y())); 0051 filenameValue->setText(currentFrame.filename); 0052 geometryValue->setText(QString("%1px x %2px").arg(currentFrame.width).arg(currentFrame.height)); 0053 0054 bool visible = (currentFrame.gain >= 0); 0055 gainLabel->setVisible(visible); 0056 gainValue->setVisible(visible); 0057 gainValue->setText(QString("%1").arg(currentFrame.gain, 0, 'f', 1)); 0058 0059 visible = (currentFrame.offset >= 0); 0060 offsetLabel->setVisible(visible); 0061 offsetValue->setVisible(visible); 0062 offsetValue->setText(QString("%1").arg(currentFrame.offset, 0, 'f', 1)); 0063 0064 visible = (currentFrame.iso != ""); 0065 isoValue->setVisible(visible); 0066 isoValue->setText(QString("ISO %1").arg(currentFrame.iso)); 0067 0068 visible = (currentFrame.targetdrift >= 0); 0069 targetDriftLabel->setVisible(visible); 0070 targetDriftValue->setVisible(visible); 0071 targetDriftValue->setText(QString("%L1\"").arg(currentFrame.targetdrift, 0, 'f', 1)); 0072 0073 // determine file creation date 0074 QFileInfo fileinfo(currentFrame.filename); 0075 const QDateTime lastmodified = fileinfo.lastModified(); 0076 captureDate->setText(lastmodified.toString("dd.MM.yyyy hh:mm:ss")); 0077 0078 // update capture counts 0079 if (m_captureHistory.size() > 0) 0080 historyCountsLabel->setText(QString("(%1/%2)").arg(m_captureHistory.position() + 1).arg(m_captureHistory.size())); 0081 else 0082 historyCountsLabel->setText(""); 0083 0084 // update enabling of the navigation buttons 0085 historyBackwardButton->setEnabled(m_captureHistory.size() > 0 && m_captureHistory.position() > 0); 0086 historyForwardButton->setEnabled(m_captureHistory.size() > 0 && m_captureHistory.size() - m_captureHistory.position() > 1); 0087 } 0088 0089 void CaptureProcessOverlay::updateTargetDistance(double targetDiff) 0090 { 0091 // since the history is read only, we need to delete the last one and add it again. 0092 FrameData lastFrame = m_captureHistory.getFrame(m_captureHistory.size() - 1); 0093 lastFrame.targetdrift = targetDiff; 0094 m_captureHistory.deleteFrame(m_captureHistory.size() - 1); 0095 m_captureHistory.addFrame(lastFrame); 0096 updateFrameData(); 0097 } 0098 0099 void CaptureProcessOverlay::displayTargetStatistics() 0100 { 0101 QString display = ""; 0102 // iterate over all targets 0103 QList<QString> targets = m_captureHistory.statistics.keys(); 0104 for (QList<QString>::iterator target_it = targets.begin(); target_it != targets.end(); target_it++) 0105 { 0106 display.append(QString("<p><b><u>%1</u></b><table border=0>").arg(*target_it == "" ? "<it>" + i18n("No target") + "</it>" : 0107 *target_it)); 0108 0109 // iterate over all types of captured frames 0110 QList<QPair<CCDFrameType, QString>> keys = m_captureHistory.statistics[*target_it].keys(); 0111 for (QList<QPair<CCDFrameType, QString>>::iterator key_it = keys.begin(); key_it != keys.end(); key_it++) 0112 { 0113 // add frame type x filter as header 0114 QString frame_type = CCDFrameTypeNames[key_it->first]; 0115 QString filter = key_it->second; 0116 0117 // add statistics per exposure time 0118 QList<QPair<int, int>*> counts = m_captureHistory.statistics[*target_it].value(*key_it); 0119 for (QList<QPair<int, int>*>::iterator it = counts.begin(); it != counts.end(); it++) 0120 { 0121 double exptime = (*it)->first / 1000.0; 0122 QTime total(0, 0, 0, 0); 0123 total = total.addMSecs(int((*it)->first * (*it)->second)); 0124 display.append(QString("<tr><td><b>%1 %2</b> (%3 x %4 sec):</td><td style=\"text-align: right\">%5</td></tr>") 0125 .arg(frame_type).arg(filter) 0126 .arg((*it)->second) 0127 .arg(exptime, 0, 'f', exptime < 10 ? 2 : 0) 0128 .arg(total.toString("hh:mm:ss"))); 0129 } 0130 } 0131 display.append("</table></p>"); 0132 } 0133 // display statistics 0134 captureStatisticsLabel->setText(display); 0135 } 0136 0137 bool CaptureProcessOverlay::showNextFrame() 0138 { 0139 if (m_captureHistory.forward()) 0140 { 0141 updateFrameData(); 0142 return true; 0143 } 0144 return false; 0145 } 0146 0147 bool CaptureProcessOverlay::showPreviousFrame() 0148 { 0149 if (m_captureHistory.backward()) 0150 { 0151 updateFrameData(); 0152 return true; 0153 } 0154 return false; 0155 } 0156 0157 bool CaptureProcessOverlay::deleteFrame(int pos) 0158 { 0159 if (m_captureHistory.deleteFrame(pos) == true) 0160 { 0161 // deleting succeeded, update overlay 0162 updateFrameData(); 0163 displayTargetStatistics(); 0164 return true; 0165 } 0166 return false; 0167 } 0168 0169 bool CaptureProcessOverlay::CaptureHistory::addFrame(CaptureProcessOverlay::FrameData data) 0170 { 0171 // check if the file already exists in the history 0172 for (QList<FrameData>::iterator it = m_history.begin(); it != m_history.end(); it++) 0173 if (it->filename == data.filename) 0174 // already exists, ignore 0175 return false; 0176 // history is clean, simply append 0177 m_history.append(data); 0178 m_position = m_history.size() - 1; 0179 countNewFrame(data.target, data.frameType, data.filterName, data.exptime); 0180 return true; 0181 } 0182 0183 bool CaptureProcessOverlay::CaptureHistory::deleteFrame(int pos) 0184 { 0185 if (m_history.size() != 0 && pos < m_history.size()) 0186 { 0187 m_history.removeAt(pos); 0188 // adapt the current position if the deleted frame was deleted before it or itself 0189 if (m_position >= pos) 0190 m_position -= 1; 0191 // ensure staying in range 0192 if (m_position < 0 && m_history.size() > 0) 0193 m_position = 0; 0194 else if (m_position >= m_history.size()) 0195 m_position = m_history.size() - 1; 0196 // update statistics, since one file is missing 0197 updateTargetStatistics(); 0198 return true; 0199 } 0200 else 0201 return false; 0202 } 0203 0204 void CaptureProcessOverlay::CaptureHistory::reset() 0205 { 0206 m_position = -1; 0207 m_history.clear(); 0208 } 0209 0210 bool CaptureProcessOverlay::CaptureHistory::forward() 0211 { 0212 if (m_position < m_history.size() - 1) 0213 { 0214 m_position++; 0215 return true; 0216 } 0217 else 0218 return false; 0219 } 0220 0221 bool CaptureProcessOverlay::CaptureHistory::backward() 0222 { 0223 if (m_position > 0) 0224 { 0225 m_position--; 0226 return true; 0227 } 0228 else 0229 return false; 0230 } 0231 0232 void CaptureProcessOverlay::CaptureHistory::updateTargetStatistics() 0233 { 0234 statistics.clear(); 0235 QList<FrameData> new_history; 0236 // iterate over all entries in the history to update the statistics 0237 for (QList<FrameData>::iterator list_it = m_history.begin(); list_it != m_history.end(); list_it++) 0238 { 0239 // if the corresponding file exists, add it to the statistics 0240 if (QFile(list_it->filename).exists()) 0241 { 0242 countNewFrame(list_it->target, list_it->frameType, list_it->filterName, list_it->exptime); 0243 new_history.append(*list_it); 0244 } 0245 } 0246 // switch history lists 0247 m_history.clear(); 0248 m_history = new_history; 0249 0250 // check if the position is correct, if not move to the last element 0251 if (m_position >= m_history.size()) 0252 m_position = m_history.size() - 1; 0253 } 0254 0255 void CaptureProcessOverlay::CaptureHistory::countNewFrame(QString target, CCDFrameType frameType, QString filter, 0256 double exptime) 0257 { 0258 // create search key 0259 QPair<CCDFrameType, QString> key(frameType, filter); 0260 // due to the equality problem with double, we use a milliseconds for exposure time 0261 int exptime_r = int(exptime * 1000); 0262 // create new target map if missing 0263 if (statistics.contains(target) == false) 0264 statistics.insert(target, CaptureProcessOverlay::FrameStatistics()); 0265 // create new filter list if missing 0266 if (statistics[target].contains(key) == false) 0267 statistics[target].insert(key, QList<QPair<int, int>*>()); 0268 0269 QPair<int, int>* count = nullptr; 0270 QList<QPair<int, int>*> *counts = &statistics[target][key]; 0271 for (QList<QPair<int, int>*>::iterator it = counts->begin(); it != counts->end(); it++) 0272 { 0273 // search for matching exposure time 0274 if ((*it)->first == exptime_r) 0275 { 0276 count = *it; 0277 break; 0278 } 0279 } 0280 // nothing found, initialize 0281 if (count == nullptr) 0282 { 0283 count = new QPair<int, int>(exptime_r, 0); 0284 counts->append(count); 0285 } 0286 // increase the counter 0287 count->second = count->second + 1; 0288 }