AstRawDark
Manage your astrophoto dark frames
 All Classes Functions Variables Enumerations Enumerator Pages
dataStore.cpp
1 /*
2  * AstRawDark
3  *
4  * Copyright (C) 2015 - Frédéric CORNU
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "dataStore.h"
21 #include "dto/imageInfo.h"
22 #include "globals.h"
23 #include "commands/signalDispatcher.h"
24 
25 #include <QSettings>
26 #include <QTime>
27 #include <QtConcurrent>
28 
29 
30 #ifndef QT_NO_DEBUG
31 #include <QDebug>
32 #endif
33 
34 DataStore* DataStore::_instance = 0;
35 
36 QString DataStore::_S_DarkDisplayFilter = "";
37 
39 
40  if ( 0 == _instance ) {
41 
42  _instance = new DataStore();
43  }
44 
45  return _instance;
46 }
47 
48 DataStore::DataStore()
49  : _darkListModel(new QStandardItemModel()),
50  _lightsListModel(new QStandardItemModel()),
51  _commandListModel(new QStandardItemModel()),
52  _darkTreeModel(new QStandardItemModel()),
53  _rememberWindowGeometry(false),
54  _scanDarksOnStartup(false),
55  _neededDarks4Matching(0)
56 {
57  QSettings settings;
58 
59  /*
60  * Load values from stored preferences
61  */
62  if ( settings.contains(Globals::SETTINGKEY_DARK_SOURCES) ) {
63 
64  _darkSources = settings.value(Globals::SETTINGKEY_DARK_SOURCES).toStringList();
65  }
66 
67  if ( settings.contains(Globals::SETTINGKEY_WINDOW_GEOMETRY_REMEMBER) ) {
68 
69  _rememberWindowGeometry = settings.value(Globals::SETTINGKEY_WINDOW_GEOMETRY_REMEMBER).toBool();
70  }
71 
72  if ( settings.contains(Globals::SETTINGKEY_SCANDARKS_ON_STARTUP) ) {
73 
74  _scanDarksOnStartup = settings.value(Globals::SETTINGKEY_SCANDARKS_ON_STARTUP).toBool();
75  }
76 
77  /*
78  * Model setup
79  */
80  _commandListModel->setColumnCount(7);
81  _commandListModel->setHorizontalHeaderLabels(QStringList()
82  << tr("N°")
83  << tr("Time")
84  << tr("Status")
85  << tr("Command")
86  << tr("Progress")
87  << tr("Message")
88  << tr("Report"));
89 
90  _darkListModel->setColumnCount(6);
91  _darkListModel->setHorizontalHeaderLabels(QStringList()
92  << tr("Path")
93  << tr("Model")
94  << tr("Exposure\n(sec.)")
95  << tr("ISO")
96  << tr("Date")
97  << tr ("Temperature\n(°C)"));
98 
99  _lightsListModel->setColumnCount(6);
100  _lightsListModel->setHorizontalHeaderLabels(QStringList()
101  << tr("Path")
102  << tr("Model")
103  << tr("Exposure\n(sec.)")
104  << tr("ISO")
105  << tr("Date")
106  << tr ("Temperature\n(°C)"));
107 
108  _darkTreeModel->setColumnCount(1);
109  _darkTreeModel->setHorizontalHeaderLabels(QStringList() << tr("Dark families"));
110 
111  // signaling
114  this,
116 
119  this,
121 
124  this,
126 
129  this,
131 
134  this,
136 
139  this,
141 
144  this,
146 
149  this,
151 
152  connect(this,
156 
157 }
158 
159 void DataStore::populateFrameListModel(QStandardItemModel *model, QList<ImageInfo> frames)
160 {
161  model->setRowCount(0);
162  model->setRowCount(frames.count());
163 
164  int row = 0;
165 
166  foreach (ImageInfo info, frames) {
167 
168  model->setData(model->index(row, 0, QModelIndex()),
169  info.getPath());
170 
171  model->setData(model->index(row, 1, QModelIndex()),
172  info.getModel());
173 
174  model->setData(model->index(row, 2, QModelIndex()),
175  info.getExposure());
176 
177  model->setData(model->index(row, 3, QModelIndex()),
178  info.getIso());
179 
180  model->setData(model->index(row, 4, QModelIndex()),
181  info.getDate());
182 
183  model->setData(model->index(row, 5, QModelIndex()),
185  "":
186  QString::number(info.getTemperature()));
187 
188  ++row;
189 
190  }
191 
192  model->sort(4);
193 }
194 
195 bool DataStore::filterDark(ImageInfo dark)
196 {
197  if ( _S_DarkDisplayFilter.isEmpty() ) {
198 
199  return true;
200  }
201 
202  QStringList filters = _S_DarkDisplayFilter.split('|');
203 
204  QString serial = "";
205  int iso = -1;
206  int expo = -1;
207 
208  switch (filters.count()) {
209 
210  case 3:
211  expo = filters.at(2).toInt();
212  iso = filters.at(1).toInt();
213  serial = filters.at(0);
214 
215  return dark.getCameraSerial() == serial &&
216  dark.getIso() == iso &&
217  dark.getExposure() == expo;
218 
219  break;
220 
221  case 2:
222  iso = filters.at(1).toInt();
223  serial = filters.at(0);
224 
225  return dark.getCameraSerial() == serial &&
226  dark.getIso() == iso;
227 
228  break;
229 
230  case 1:
231  serial = filters.at(0);
232 
233  return dark.getCameraSerial() == serial;
234  break;
235 
236  default:
237  return true;
238  break;
239  }
240 }
241 
242 void DataStore::on_newDarkScanResult(QList<ImageInfo> darks)
243 {
244  _scannedDarks = darks;
245 
246  populateDarkFiltersTreeView(_scannedDarks);
247 
248  filterDarks();
249 }
250 
251 void DataStore::on_newLightsScanResult(QList<ImageInfo> lights)
252 {
253  _scannedLights = lights;
254  populateFrameListModel(_lightsListModel, _scannedLights);
255 }
256 
258 {
259  // warning, commands are inserted at model top
260  updateCommandModelRow(_commandListModel->rowCount() - command->getSerial() -1, command);
261 }
262 
264 {
265  _commandListModel->insertRows(0,1);
266 
267  _commandListModel->setData(_commandListModel->index(0,
268  0,
269  QModelIndex()),
270  command->getSerial()+1); // commands are numbered from 0
271 
272  _commandListModel->setData(_commandListModel->index(0,
273  1,
274  QModelIndex()),
275  QTime::currentTime().toString("hh:mm:ss"));
276 
277 
278  updateCommandModelRow(0, command);
279 }
280 
281 void DataStore::on_newDarkSources(QStringList paths)
282 {
283  _darkSources = paths;
284 
285  QSettings().setValue(Globals::SETTINGKEY_DARK_SOURCES, _darkSources);
286 }
287 
288 void DataStore::updateCommandModelRow(int row, AbstractCommand *command)
289 {
290 
291  static QColor redBackground(255, 200, 200);
292  static QColor yellowBackground(255, 220, 150);
293  static QColor greenBackground(200, 255, 200);
294 
295  if ( AbstractCommand::COMPLETE == command->getStatus() ) {
296 
297  QColor statusBackground;
298 
299  if ( command->hasErrors() ) {
300 
301  statusBackground = redBackground;
302 
303  } else {
304 
305  if ( command->hasWarning() ) {
306 
307  statusBackground = yellowBackground;
308 
309  } else {
310 
311  statusBackground = greenBackground;
312  }
313  }
314 
315  _commandListModel->setData(_commandListModel->index(row,2,QModelIndex()),
316  statusBackground,
317  Qt::BackgroundRole);
318  }
319 
320  _commandListModel->setData(_commandListModel->index(row,2,QModelIndex()),
321  command->getStatusString());
322 
323  _commandListModel->setData(_commandListModel->index(row,3,QModelIndex()),
324  command->getDescription());
325 
326  _commandListModel->setData(_commandListModel->index(row,5,QModelIndex()),
327  command->getProgessMessage());
328 
329  _commandListModel->setData(_commandListModel->index(row,6,QModelIndex()),
330  command->getReportMessages().join('\n'));
331 
332 
333 
334 
335 }
336 
337 void DataStore::populateDarkFiltersTreeView(QList<ImageInfo> imageInfos)
338 {
339  /*
340  * browse all images and break them down according to this hierarchy
341  *
342  * - camera serial
343  * - ISO
344  * - Exposure
345  */
346 
347  QMap< QString, ImageInfo > serialMap;
348 
349  foreach (ImageInfo info, imageInfos) {
350 
351  serialMap.insertMulti(info.getCameraSerial(), info);
352  }
353 
354  foreach (QString serial , serialMap.uniqueKeys()) {
355 
356  QStandardItem* currentSerialItem = new QStandardItem(tr("Camera N°").append(serial));
357 
358  _darkTreeModel->invisibleRootItem()->appendRow(currentSerialItem);
359  _darkTreeModel->setData(_darkTreeModel->indexFromItem(currentSerialItem), serial, Qt::UserRole);
360  _darkTreeModel->setData(_darkTreeModel->indexFromItem(currentSerialItem),
361  tr("%1 Darks").arg(serialMap.values(serial).count()),
362  Qt::ToolTipRole);
363 
364  QMap <int, ImageInfo > isoMap;
365 
366  foreach (ImageInfo info, serialMap.values(serial)) {
367 
368  isoMap.insertMulti(info.getIso(), info);
369  }
370 
371  foreach (int iso, isoMap.uniqueKeys()) {
372 
373  QStandardItem* currentIsoItem = new QStandardItem(QString::number(iso).append(" ISO"));
374 
375  currentSerialItem->appendRow(currentIsoItem);
376  _darkTreeModel->setData(_darkTreeModel->indexFromItem(currentIsoItem),
377  QString(serial).append('|').append(QString::number(iso)),
378  Qt::UserRole);
379  _darkTreeModel->setData(_darkTreeModel->indexFromItem(currentIsoItem),
380  tr("%1 Darks").arg(isoMap.values(iso).count()),
381  Qt::ToolTipRole);
382 
383  QMap<int, ImageInfo> expoMap;
384 
385  foreach (ImageInfo info, isoMap.values(iso)) {
386 
387  expoMap.insertMulti(info.getExposure(), info);
388  }
389 
390  foreach (int expo, expoMap.uniqueKeys()) {
391 
392  QStandardItem* currentExpoItem = new QStandardItem(QString::number(expo).append("\""));
393 
394  currentIsoItem->appendRow(currentExpoItem);
395  _darkTreeModel->setData(
396  _darkTreeModel->indexFromItem(currentExpoItem),
397  QString(serial).append('|')
398  .append(QString::number(iso)).append('|')
399  .append(QString::number(expo)),
400  Qt::UserRole);
401  _darkTreeModel->setData(
402  _darkTreeModel->indexFromItem(currentExpoItem),
403  tr("%1 Darks").arg(expoMap.values(expo).count()),
404  Qt::ToolTipRole);
405  }
406  }
407  }
408 }
409 
411 {
412  _darkListModel->setRowCount(0);
413  _darkTreeModel->setRowCount(0);
414  _S_DarkDisplayFilter = "";
415 }
416 
418 {
419  _lightsListModel->setRowCount(0);
420 }
421 
422 
424 {
425  _rememberWindowGeometry = remember;
426  QSettings().setValue(Globals::SETTINGKEY_WINDOW_GEOMETRY_REMEMBER, _rememberWindowGeometry);
427 }
428 
430 {
431  _scanDarksOnStartup = scan;
432  QSettings().setValue(Globals::SETTINGKEY_SCANDARKS_ON_STARTUP, _scanDarksOnStartup);
433 }
434 
435 void DataStore::filterDarks()
436 {
437  _filteredDarks = QtConcurrent::blockingFiltered(_scannedDarks,
438  &DataStore::filterDark);
439  populateFrameListModel(_darkListModel, _filteredDarks);
440  emit darkListModelChanged();
441 }
442 
443 void DataStore::setDarkDisplayFilter(const QString filter)
444 {
445  _S_DarkDisplayFilter = filter;
446 
447  filterDarks();
448 }
449 
450 void DataStore::setDarkCopyFolderPath(const QString copyFolder) {
451 
452  _darksCopyFolder = copyFolder;
453 }
454 
455 void DataStore::on_matchFound(QList<ImageInfo> matchedDarks) {
456 
457  _matchedDarks = matchedDarks;
458 }