]> Devoid-pointer.net GitWeb - anyanka.git/commitdiff
Initial support for saving user data to JSON-formatted files
authorMichal Malý <madcatxster@prifuk.cz>
Tue, 11 Mar 2014 22:22:16 +0000 (23:22 +0100)
committerMichal Malý <madcatxster@prifuk.cz>
Tue, 11 Mar 2014 22:22:16 +0000 (23:22 +0100)
18 files changed:
Anyanka.pro
datafilesloader.h
datamanager.cpp
datamanager.h
gui/mainwindow.cpp
gui/mainwindow.h
gui/mainwindow.ui
integratedpeak.cpp
integratedpeak.h
integrator.cpp
integrator.h
jsonserializable.cpp [new file with mode: 0644]
jsonserializable.h [new file with mode: 0644]
main.cpp
signalcontroller.cpp
signalcontroller.h
singlerundata.cpp
singlerundata.h

index 083393925e3b3a8805f96eb63d1668c0b8b84fc7..23bccc111d2c600a0657aa5817737bcfef9f985b 100644 (file)
@@ -52,7 +52,8 @@ SOURCES += main.cpp\
     csvdatawriterbackend.cpp \
     gui/exportgraphtoimagedialog.cpp \
     imagedrawer.cpp \
-    signaldrawer.cpp
+    signaldrawer.cpp \
+    jsonserializable.cpp
 
 HEADERS  += \
     datafilesloader.h \
@@ -86,7 +87,8 @@ HEADERS  += \
     gui/exportgraphtoimagedialog.h \
     imagedrawer.h \
     signaldrawer.h \
-    enumflags.h
+    enumflags.h \
+    jsonserializable.h
 
 FORMS += \
     gui/mainwindow.ui \
index 7baff76836fd95c70dcb8689570c1a184670faea..513141c2bf844174dbe4dee39ffd419922cbe408 100644 (file)
@@ -39,7 +39,7 @@ public:
     E_FATAL
   };
 
-  explicit DataFilesLoader(QObject* parent = 0);
+  explicit DataFilesLoader(QObject* parent = nullptr);
   ReturnCode loadSingleRun(const QDir& path, std::vector<std::shared_ptr<AGRE_MeasurementInfo>>& dataFiles);
 
 private:
index 11b9ae5d42864c455507fcb38ddf0b13ad2bbaca..0e4061efe4e196ab627a322fffc9df17a5ccaa21 100644 (file)
@@ -25,6 +25,7 @@
 #include "logger.h"
 #include "gui/exportgraphtoimagedialog.h"
 #include "gui/exportrawdatadialog.h"
+#include <QtCore/QJsonDocument>
 #include <QtWidgets/QMessageBox>
 
 #include <QDebug>
@@ -314,6 +315,25 @@ std::shared_ptr<SingleRunData> DataManager::loadSingleRun(QDir& dir)
 
     _c = std::shared_ptr<SignalController>(new SignalController(_s));
 
+    /* Try to read saved user data from JSON file */
+    QFile jsonFile(dir.path() + "/" + "ank_" + QString::fromStdString(_s->descriptiveName()) + ".json");
+    if (jsonFile.exists()) {
+      if (jsonFile.open(QFile::ReadOnly)) {
+        QByteArray bytes = jsonFile.readAll();
+        QJsonDocument jsonDoc = QJsonDocument::fromJson(bytes);
+        QJsonObject jso = jsonDoc.object();
+
+        if (!_c->deserialize(jso)) {
+          llog->log(Logger::Level::WARNING, ME_SENDER_STR, "Failed to deserialize saved user data for " + QString::fromStdString(_s->descriptiveName()));
+          QMessageBox::warning(nullptr, "Load single run", "Saved user data for signal " + QString::fromStdString(_s->descriptiveName()) +
+                                                           "could not have been read properly.");
+        }
+      } else
+        llog->log(Logger::Level::WARNING, ME_SENDER_STR, "Cannot open saved user data file " + QString::fromStdString(_s->descriptiveName()) +
+                                                           " for reading.");
+    } else
+      llog->log(Logger::Level::DEBUG, ME_SENDER_STR, "No user data file for " + QString::fromStdString(_s->descriptiveName()));
+
     sigs[_s->descriptiveName()] = _s;
     ctrls[_s->descriptiveName()] = _c;
   }
@@ -356,7 +376,7 @@ std::shared_ptr<SingleRunData> DataManager::loadSingleRun(QDir& dir)
   }
 
   singleRun = std::shared_ptr<SingleRunData>(new SingleRunData(methodNames.at(0), operatorNames.at(0), sampleInfos.at(0), dates.at(0), times.at(0), sigs, ctrls,
-                                                               dir.dirName(), this));
+                                                               dir.dirName(), dir.absolutePath(), this));
 
 
   Logger::log(Logger::DEBUG, ME_SENDER_STR, "Single run successfully parsed");
@@ -555,6 +575,33 @@ void DataManager::onLoadSingleRun(const QString& str)
   emit setActiveSequenceIndex(0);
 }
 
+void DataManager::onSaveChanges()
+{
+  std::shared_ptr<SingleRunData> sr = m_activeSequence->selectedRun();
+  std::unordered_map<std::string, std::shared_ptr<SignalController>>::const_iterator cit;
+
+  if (m_activeSequence == nullptr)
+    return;
+
+  const std::unordered_map<std::string, std::shared_ptr<SignalController>>& ctrls = sr->allControllers();
+  cit = ctrls.cbegin();
+
+  while (cit != ctrls.cend()) {
+    QJsonValue val = cit->second->serialize();
+    QJsonDocument doc(val.toObject());
+    QFile f(sr->absPath() + "/" + "ank_" + QString::fromStdString(cit->first) + ".json");
+    QByteArray bytes = doc.toJson();
+
+    f.open(QFile::WriteOnly);
+    f.write(bytes.data(), bytes.size());
+
+    qDebug() << val;
+    f.close();
+    ++cit;
+  }
+
+}
+
 void DataManager::onSequenceSelected(const QString& key)
 {
   if (m_sequenceRejected) {
index 1e5bc3c0828dc342631eacbdc79c7567b847e928..0775feb009f3745c60f71e9b55196ab502085968 100644 (file)
@@ -95,6 +95,7 @@ public slots:
   void onExportRawData();
   void onLoadSequence(const QString& dir);
   void onLoadSingleRun(const QString& dir);
+  void onSaveChanges();
   void onSequenceSelected(const QString& key);
   void onSingleRunSelected(const QString& key);
 
index 43fd34f701981bbe2770866897a09ab59f4bcd8f..68d6d7fb69e924d469c74f332f9905c50f98809a 100644 (file)
@@ -70,6 +70,7 @@ void MainWindow::connectActions()
   /* DATA menu */
   connect(ui->actionLoad_single_run, SIGNAL(triggered()), this, SLOT(onLoadSingleRun()));
   connect(ui->actionLoad_sequence, SIGNAL(triggered()), this, SLOT(onLoadSequence()));
+  connect(ui->actionSave_changes, SIGNAL(triggered()), this, SLOT(onSaveChanges()));
   /* EXPORT menu */
   connect(ui->actionRaw_values, SIGNAL(triggered()), this, SLOT(onExportRawData()));
   connect(ui->actionIntegration_results, SIGNAL(triggered()), this, SLOT(onExportPeaks()));
index 1e9d3914763d767068b314d60eeb5aeed3c36c10..f181d2dc844aad7ee7df0a69e98e63890e626eda 100644 (file)
@@ -76,6 +76,7 @@ private slots:
   void onIntegrateSelected();
   void onLoadSequence();
   void onLoadSingleRun();
+  void onSaveChanges() { emit saveChanges(); }
   void onSequenceSelected(const QString& str);
   void onSingleRunSelected(const QString& str);
   void onSWFullSizeToggle();
@@ -88,6 +89,7 @@ signals:
   void exportRawData();
   void loadSequence(const QString& dir);
   void loadSingleRun(const QString& dir);
+  void saveChanges();
   void sequenceSelected(const QString& str);
   void singleRunSelected(const QString& str);
 };
index f63e23a05d423def34ef969b2e1bae7bedfb8d1f..2748af23888021152ea1cccdbf06a79ea3f6ddcb 100644 (file)
     </property>
     <addaction name="actionLoad_single_run"/>
     <addaction name="actionLoad_sequence"/>
+    <addaction name="separator"/>
+    <addaction name="actionSave_changes"/>
    </widget>
    <widget class="QMenu" name="menuHelp">
     <property name="title">
     <string>Graph as image</string>
    </property>
   </action>
+  <action name="actionSave_changes">
+   <property name="text">
+    <string>Save changes</string>
+   </property>
+  </action>
  </widget>
  <resources/>
  <connections/>
index 64ae1daee832fb7e27c34c445567407e8e7dee21..26444915bae46e4f7f7242f7b545f630c8b114d9 100644 (file)
 */
 
 #include "integratedpeak.h"
+#include <QtCore/QJsonObject>
 
-IntegratedPeak::IntegratedPeak(IntegratedPeak::Type type, double auc, size_t peakIdx, double peakTime, double peakVal,
+const QString IntegratedPeak::KEY_AUC("auc");
+const QString IntegratedPeak::KEY_FROMIDX("fromIdx");
+const QString IntegratedPeak::KEY_FROMTIME("fromTime");
+const QString IntegratedPeak::KEY_FROMY("fromY");
+const QString IntegratedPeak::KEY_PEAKIDX("peakIdx");
+const QString IntegratedPeak::KEY_PEAKTIME("peakTime");
+const QString IntegratedPeak::KEY_PEAKY("peakY");
+const QString IntegratedPeak::KEY_TOIDX("toIdx");
+const QString IntegratedPeak::KEY_TOTIME("toTime");
+const QString IntegratedPeak::KEY_TOY("toY");
+const QString IntegratedPeak::KEY_TYPE("type");
+
+IntegratedPeak::IntegratedPeak(IntegratedPeak::Type type, double auc, size_t peakIdx, double peakTime, double peakY,
                                size_t fromIdx, size_t toIdx, double fromTime, double toTime, double fromY, double toY, QObject* parent) :
   QObject(parent),
+  JSONSerializable(),
   m_auc(auc),
   m_fromIdx(fromIdx),
   m_fromTime(fromTime),
   m_fromY(fromY),
   m_peakIdx(peakIdx),
   m_peakTime(peakTime),
-  m_peakVal(peakVal),
+  m_peakY(peakY),
   m_toIdx(toIdx),
   m_toTime(toTime),
   m_toY(toY),
@@ -44,7 +58,81 @@ double IntegratedPeak::baselineSlope() const
   return (m_toY - m_fromY) / (m_toIdx - m_fromIdx);
 }
 
+bool IntegratedPeak::deserialize(const QJsonValue& value)
+{
+  QJsonObject jso;
+  QString type;
+
+  if (!value.isObject())
+    return false;
+
+  jso = value.toObject();
+
+  if (!jso.contains(KEY_AUC))
+    return false;
+  m_auc = jso.value(KEY_AUC).toDouble();
+  if (!jso.contains(KEY_FROMIDX))
+    return false;
+  m_fromIdx = jso.value(KEY_FROMIDX).toDouble();
+  if (!jso.contains(KEY_FROMTIME))
+    return false;
+  m_fromTime = jso.value(KEY_FROMTIME).toDouble();
+  if (!jso.contains(KEY_FROMY))
+    return false;
+  m_fromY = jso.value(KEY_FROMY).toDouble();
+
+  if (!jso.contains(KEY_PEAKIDX))
+    return false;
+  m_peakIdx = jso.value(KEY_PEAKIDX).toDouble();
+  if (!jso.contains(KEY_PEAKTIME))
+    return false;
+  m_peakTime = jso.value(KEY_PEAKTIME).toDouble();
+  if (!jso.contains(KEY_PEAKY))
+    return false;
+  m_peakY = jso.value(KEY_PEAKY).toDouble();
+
+  if (!jso.contains(KEY_TOIDX))
+    return false;
+  m_toIdx = jso.value(KEY_TOIDX).toDouble();
+  if (!jso.contains(KEY_TOTIME))
+    return false;
+  m_toTime = jso.value(KEY_TOTIME).toDouble();
+  if (!jso.contains(KEY_TOY))
+    return false;
+  m_toY = jso.value(KEY_TOY).toDouble();
+
+  if (!jso.contains(KEY_TYPE))
+    return false;
+  type = jso.value(KEY_TYPE).toString();
+  if (type.compare("PEAK") == 0)
+    m_type = Type::PEAK;
+  else
+    m_type = Type::VALLEY;
+
+  return true;
+}
+
 double IntegratedPeak::height() const
 {
-  return fabs(m_peakVal - (baselineSlope() * (m_peakIdx - m_fromIdx) + m_fromY));
+  return fabs(m_peakY - (baselineSlope() * (m_peakIdx - m_fromIdx) + m_fromY));
+}
+
+QJsonValue IntegratedPeak::serialize() const
+{
+  QJsonObject jso;
+  QString type = (m_type == Type::PEAK) ? "PEAK" : "VALLEY";
+
+  jso.insert(KEY_AUC, QJsonValue(m_auc));
+  jso.insert(KEY_FROMIDX, QJsonValue(static_cast<qint64>(m_fromIdx)));
+  jso.insert(KEY_FROMTIME, QJsonValue(m_fromTime));
+  jso.insert(KEY_FROMY, QJsonValue(m_fromY));
+  jso.insert(KEY_PEAKIDX, QJsonValue(static_cast<qint64>(m_peakIdx)));
+  jso.insert(KEY_PEAKTIME, QJsonValue(m_peakTime));
+  jso.insert(KEY_PEAKY, QJsonValue(m_peakY));
+  jso.insert(KEY_TOIDX, QJsonValue(static_cast<qint64>(m_toIdx)));
+  jso.insert(KEY_TOTIME, QJsonValue(m_toTime));
+  jso.insert(KEY_TOY, QJsonValue(m_toY));
+  jso.insert(KEY_TYPE, QJsonValue(type));
+
+  return jso;
 }
index 7db458d261dcdf1afe6292896e751bba28ec1eb5..89228e345d06cb40d55af8d46232cca72eda8201 100644 (file)
 #ifndef INTEGRATEDPEAK_H
 #define INTEGRATEDPEAK_H
 
+#include "jsonserializable.h"
 #include <QtCore/QObject>
 
-class IntegratedPeak : public QObject
+class IntegratedPeak : public QObject, public JSONSerializable
 {
   Q_OBJECT
 public:
   enum class Type {
+    INVALID,
     PEAK,
     VALLEY
   };
 
-  explicit IntegratedPeak(Type type, double auc, size_t peakIdx, double peakTime, double peakVal, size_t fromIdx, size_t toIdx, double fromTime, double toTime,
+  explicit IntegratedPeak() : m_type(Type::INVALID) {}
+  explicit IntegratedPeak(Type type, double auc, size_t peakIdx, double peakTime, double peakY, size_t fromIdx, size_t toIdx, double fromTime, double toTime,
                           double fromY, double toY, QObject* parent = nullptr);
   double auc() const { return m_auc; }
   double baselineSlope() const;
@@ -45,24 +48,41 @@ public:
   double height() const;
   size_t peakIdx() const { return m_peakIdx; }
   double peakTime() const { return m_peakTime; }
+  double peakY() const { return m_peakY; }
   size_t toIdx() const { return m_toIdx; }
   double toTime() const { return m_toTime; }
   double toY() const { return m_toY; }
   Type type() const { return m_type; }
   double width() const { return m_toTime - m_fromTime; }
 
+  virtual bool deserialize(const QJsonValue& value);
+  virtual QJsonValue serialize() const;
+
 private:
-  const double m_auc;
-  const size_t m_fromIdx;
-  const double m_fromTime;
-  const double m_fromY;
-  const size_t m_peakIdx;
-  const double m_peakTime;
-  const double m_peakVal;
-  const size_t m_toIdx;
-  const double m_toTime;
-  const double m_toY;
-  const Type m_type;
+  double m_auc;
+  size_t m_fromIdx;
+  double m_fromTime;
+  double m_fromY;
+  size_t m_peakIdx;
+  double m_peakTime;
+  double m_peakY;
+  size_t m_toIdx;
+  double m_toTime;
+  double m_toY;
+  Type m_type;
+
+  static const QString KEY_AUC;
+  static const QString KEY_FROMIDX;
+  static const QString KEY_FROMTIME;
+  static const QString KEY_FROMY;
+  static const QString KEY_PEAKIDX;
+  static const QString KEY_PEAKTIME;
+  static const QString KEY_PEAKY;
+  static const QString KEY_TOIDX;
+  static const QString KEY_TOTIME;
+  static const QString KEY_TOY;
+  static const QString KEY_TYPE;
+
 
 public slots:
 signals:
index 6c376121436ba245932a32f7b06784ac3130d333..6aa8ed06703214f4d3093761b529856db5831858 100644 (file)
@@ -32,6 +32,13 @@ Integrator::Integrator(std::shared_ptr<Signal> signal, QObject* parent) :
   m_signal(signal)
 {}
 
+void Integrator::addPeak(std::shared_ptr<IntegratedPeak> peak)
+{
+  emit addingPeak(m_peaksList.count());
+  m_peaksList.append(peak);
+  emit peakAdded();
+}
+
 std::shared_ptr<const IntegratedPeak> Integrator::deletePeak(size_t idx)
 {
   size_t ctr = 0;
index 6522da2db60ea667721478d65c569bda2746c70e..b170f6989b888a3fa151691e93216ed6696e1c98 100644 (file)
@@ -43,6 +43,7 @@ public:
   };
 
   explicit Integrator(std::shared_ptr<Signal> signal, QObject* parent = nullptr);
+  void addPeak(std::shared_ptr<IntegratedPeak> peak);
   std::shared_ptr<const IntegratedPeak> deletePeak(size_t idx);
   std::vector<std::shared_ptr<const IntegratedPeak>> allPeaks();
   ReturnCode integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, std::shared_ptr<IntegratedPeak>& peak);
diff --git a/jsonserializable.cpp b/jsonserializable.cpp
new file mode 100644 (file)
index 0000000..9105edc
--- /dev/null
@@ -0,0 +1,5 @@
+#include "jsonserializable.h"
+
+JSONSerializable::JSONSerializable()
+{
+}
diff --git a/jsonserializable.h b/jsonserializable.h
new file mode 100644 (file)
index 0000000..1a40121
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef JSONSERIALIZABLE_H
+#define JSONSERIALIZABLE_H
+
+#include <QtCore/QJsonValue>
+
+class JSONSerializable
+{
+public:
+  JSONSerializable();
+  virtual QJsonValue serialize() const = 0;
+  virtual bool deserialize(const QJsonValue& value) = 0;
+};
+
+#endif // JSONSERIALIZABLE_H
index 3d0bfaa20a5f865a0ea14f2deed06718bc24dd50..fe29bd1a27cd879e986a2df3705664817f7e03aa 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -72,6 +72,7 @@ int main(int argc, char *argv[])
   QObject::connect(mWin.get(), SIGNAL(exportGraphToImage()),dMgr.get(), SLOT(onExportGraphToImage()));
   QObject::connect(mWin.get(), SIGNAL(exportPeaks()), dMgr.get(), SLOT(onExportPeaks()));
   QObject::connect(mWin.get(), SIGNAL(exportRawData()), dMgr.get(), SLOT(onExportRawData()));
+  QObject::connect(mWin.get(), SIGNAL(saveChanges()), dMgr.get(), SLOT(onSaveChanges()));
   QObject::connect(mWin.get(), SIGNAL(loadSingleRun(QString)), dMgr.get(), SLOT(onLoadSingleRun(QString)));
   QObject::connect(mWin.get(), SIGNAL(loadSequence(QString)), dMgr.get(), SLOT(onLoadSequence(QString)));
   QObject::connect(mWin.get(), SIGNAL(sequenceSelected(QString)), dMgr.get(), SLOT(onSequenceSelected(QString)));
index 88f685ca1b18c7af56c84efcab32f3fa84b65dc8..ce2fd6d55384b705970cb1face4ee5c65218770e 100644 (file)
 #include "logger.h"
 #include <cfloat>
 #include <utility>
-
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonObject>
 #include <QDebug>
 
 const double SignalController::RELATIVE_MAX = 100.0;
 const double SignalController::RELATIVE_MIN = 0.0;
 const QString SignalController::ME_SENDER_STR("SignalController");
 
+const QString SignalController::KEY_PEAKS("peaks");
+
 SignalController::SignalController(std::shared_ptr<Signal> signal, QObject* parent) :
   QObject(parent),
+  JSONSerializable(),
   m_signal(signal)
 {
   m_integrator = std::shared_ptr<Integrator>(new Integrator(signal));
@@ -66,6 +70,33 @@ PeakDrawData SignalController::deletePeak(const double x)
   return genPeakDrawData(peak);
 }
 
+bool SignalController::deserialize(const QJsonValue& value)
+{
+  QJsonObject jso;
+  QJsonArray jsPeakArray;
+
+  if (!value.isObject()) {
+    Logger::log(Logger::Level::WARNING, ME_SENDER_STR, "JSON value is notan object");
+    return false;
+  }
+  jso = value.toObject();
+
+  /* Add peaks */
+  if (!jso.contains(KEY_PEAKS)) {
+    Logger::log(Logger::Level::WARNING, ME_SENDER_STR, "JSON object does not contain \"peaks\" array");
+    return false;
+  }
+  jsPeakArray = jso.value(KEY_PEAKS).toArray();
+  for (QJsonValueRef ref : jsPeakArray) {
+    std::shared_ptr<IntegratedPeak> peak(new IntegratedPeak());
+
+    peak->deserialize(ref);
+    m_integrator->addPeak(peak);
+  }
+
+  return true;
+}
+
 std::shared_ptr<GraphDrawData> SignalController::getGraphDrawData(const double fromX, const double toX)
 {
   size_t fromIdx, toIdx;
@@ -215,6 +246,20 @@ PeakDrawData SignalController::integratePeak(const double fromX, const double fr
   return PeakDrawData();
 }
 
+QJsonValue SignalController::serialize() const
+{
+  QJsonObject jso;
+  QJsonArray jsPeakArray;
+
+  for (std::shared_ptr<const IntegratedPeak> peak : m_integrator->allPeaks()) {
+    QJsonValue val = peak->serialize();
+    jsPeakArray.append(val);
+  }
+
+  jso.insert("peaks", jsPeakArray);
+  return jso;
+}
+
 /** Private methods **/
 
 PeakDrawData SignalController::genPeakDrawData(const std::shared_ptr<const IntegratedPeak> peak)
index 139ba9c16bee03940d4b12f85c5040c7f9a2eb9c..e4b9b3d430c6f56a88c6c01e6ae370a9c0baebe1 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "integrationtablemodel.h"
 #include "integrator.h"
+#include "jsonserializable.h"
 #include "signal.h"
 #include "signaldatatablemodel.h"
 #include <memory>
@@ -82,7 +83,7 @@ struct RulerDrawData {
   const double relStep;
 };
 
-class SignalController : public QObject
+class SignalController : public QObject, public JSONSerializable
 {
   Q_OBJECT
 public:
@@ -92,6 +93,7 @@ public:
   ~SignalController();
    SignalDataTableModel* dataTableModel() { return m_dtblModel; }
   PeakDrawData deletePeak(const double x);
+  virtual bool deserialize(const QJsonValue& value);
   Signal::TimeValuePair getXYValues(const double x);
   std::shared_ptr<GraphDrawData> getGraphDrawData(const double fromX, const double toX);
   std::vector<PeakDrawData> getPeaksDrawData(const double fromX, const double fromY, const double toX, const double toY);
@@ -104,6 +106,7 @@ public:
   PeakDrawData integratePeak(const double fromX, const double fromY, const double toX, const double toY);
   IntegrationTableModel* integrationTableModel() { return m_integTblModel;}
   void setGUIViewport(const double fromX, const double fromY, const double toX, const double toY);
+  virtual QJsonValue serialize() const;
   const std::shared_ptr<Signal> signal() const { return m_signal; }
   const std::shared_ptr<Integrator> cIntegrator() const { return m_integrator; }
 
@@ -131,6 +134,8 @@ private:
 
   static const QString ME_SENDER_STR;
 
+  static const QString KEY_PEAKS;
+
 public slots:
 
 signals:
index 4c70828f2f9766bda3c90b5e5ac7e559033c6f51..0b39ff879edc8ea9a9dce4a3889d98192bbfc291 100644 (file)
@@ -24,8 +24,9 @@
 
 SingleRunData::SingleRunData(const QString& methodName, const QString& operatorName, const QString& sampleInfo, const QDate date, const QTime time,
                              std::unordered_map<std::string, std::shared_ptr<Signal>>& sigs, std::unordered_map<std::string, std::shared_ptr<SignalController>>& ctrls,
-                             const QString& dirname, QObject *parent) :
+                             const QString& dirname, const QString& absPath, QObject *parent) :
   QObject(parent),
+  m_absPath(absPath),
   m_date(date),
   m_dirName(dirname),
   m_methodName(methodName),
index c3d96cb349408496c5bd7fa9cf2854c7b4d11c91..b0f1c1d08f981124af14321d004e66b1735ef6d8 100644 (file)
@@ -37,7 +37,8 @@ class SingleRunData : public QObject
 public:
   explicit SingleRunData(const QString& methodName, const QString& operatorName, const QString& sampleInfo, const QDate date, const QTime time,
                          std::unordered_map<std::string, std::shared_ptr<Signal>>& sigs, std::unordered_map<std::string, std::shared_ptr<SignalController>>& ctrls,
-                         const QString& dirname, QObject* parent = nullptr);
+                         const QString& dirname, const QString& absPath, QObject* parent = nullptr);
+  QString absPath() const { return m_absPath; }
   const std::unordered_map<std::string, std::shared_ptr<SignalController>>& allControllers() const { return m_ctrls; }
   std::vector<std::string> allKeys() const;
   const std::unordered_map<std::string, std::shared_ptr<Signal>>& allSignals() const { return m_signals; }
@@ -52,6 +53,7 @@ public:
   QTime time() const { return m_time; }
 
 private:
+  const QString m_absPath;
   const QDate m_date;
   const QString m_dirName;
   const QString m_methodName;