#include "logger.h"
#include "gui/exportgraphtoimagedialog.h"
#include "gui/exportrawdatadialog.h"
-#include <QtCore/QJsonDocument>
#include <QtWidgets/QMessageBox>
#include <QDebug>
m_sigNameCodec = QTextCodec::codecForName("ISO-8859-1");
}
+void DataManager::saveUserDataOnExit()
+{
+ for (NameSequencePair& nsp : m_sequences) {
+ const QString seqName = nsp.first;
+ std::shared_ptr<Sequence> seq = nsp.second;
+ SingleRunsMap::const_iterator it = seq->begin();
+
+ while (it != seq->end()) {
+ std::shared_ptr<SingleRunData> sr = it->second;
+ if (sr->userDataModified()) {
+ const QString srName = QString::fromStdString(it->first);
+ int ret = QMessageBox::question(nullptr, "Save changes?" , "User data in sequence " + seqName + ", signal " + srName + " have been modified. "
+ "Would you like to save the changes?", QMessageBox::Yes, QMessageBox::No);
+ if (ret == QMessageBox::Yes)
+ sr->saveUserDataToJSON();
+ }
+ ++it;
+ }
+ }
+}
+
/* Private functions */
void DataManager::generateIntegDataWriteList(DataFileExporter::WriteList& writeList, const std::shared_ptr<SingleRunData> sr, const std::vector<std::string> &keys)
}
}
+bool DataManager::saveSingleRunUserData(std::shared_ptr<SingleRunData> sr)
+{
+ return sr->saveUserDataToJSON();
+}
+
std::string DataManager::signalControllerKey(const QString& main, const QString& resource)
{
return std::string(main.toStdString() + "_" + resource.toStdString());
{
std::vector<std::shared_ptr<AGRE_MeasurementInfo>> dataFiles;
std::shared_ptr<SingleRunData> singleRun;
- std::unordered_map<std::string, std::shared_ptr<Signal>> sigs;
- std::unordered_map<std::string, std::shared_ptr<SignalController>> ctrls;
+ SignalsMap sigs;
+ SignalControllersMap ctrls;
DataFilesLoader::ReturnCode ret;
LocalLoggerPtr llog = Logger::createLocalLog();
llog->setPrintLevel(Logger::Level::WARNING);
_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;
}
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(), dir.absolutePath(), this));
-
+ singleRun->readUserDataFromJSON();
Logger::log(Logger::DEBUG, ME_SENDER_STR, "Single run successfully parsed");
swp->setXUnits(QString::fromStdString(ctrl->signal()->xunitToString()));
swp->setYUnits(QString::fromStdString(ctrl->signal()->yunitToString()));
- /*connect(swp->m_graphView, SIGNAL(crosshairErased()), ctrl.get(), SLOT(onViewCrosshairErased()));
- connect(swp->m_graphView, SIGNAL(crosshairMoved(int,int)), ctrl.get(), SLOT(onViewCrosshairMoved(int,int)));
- connect(swp->m_graphView, SIGNAL(integrated(int,int,int,int)), ctrl.get(), SLOT(onViewIntegrated(int,int,int,int)));
- connect(swp->m_graphView, SIGNAL(redrawNeeded()), ctrl.get(), SLOT(onViewRedrawNeeded()));
- connect(swp->m_graphView, SIGNAL(resized(int,int)), ctrl.get(), SLOT(onViewResized(int,int)));
- connect(swp->m_graphView, SIGNAL(showContextMelnuReq(int,int,QPoint)), ctrl.get(), SLOT(onViewShowContextMenu(int,int,QPoint)));
- connect(swp->m_graphView, SIGNAL(zoomed(int,int,int,int)), ctrl.get(), SLOT(onViewZoomed(int,int,int,int)));
- connect(ctrl.get(), SIGNAL(viewDrawGraph(double*,size_t,double,double)), swp->m_graphView, SLOT(onUpdateGraph(double*,size_t,double,double)));
- connect(ctrl.get(), SIGNAL(viewCtxMenuClosed()), swp->m_graphView, SLOT(onCtxMenuClosed()));
- connect(ctrl.get(), SIGNAL(viewDrawIntegration(int,double,int,double,int,double,QString,QString)), swp->m_graphView,
- SLOT(onDrawIntegration(int,double,int,double,int,double,QString,QString)));
- connect(ctrl.get(), SIGNAL(viewUpdateCurrentValues(double,double)), swp, SLOT(onUpdateCurrentValues(double,double)));
- connect(ctrl.get(), SIGNAL(viewRemoveCurrentValues()), swp, SLOT(onRemoveCurrentValues()));*/
emit addToDashboard(swp);
swp->m_graphView->refresh();
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;
- }
-
+ sr->saveUserDataToJSON();
}
void DataManager::onSequenceSelected(const QString& key)
Q_OBJECT
public:
explicit DataManager(QObject* parent = nullptr);
+ void saveUserDataOnExit();
SequenceSelectorModel* sequenceSelectorModel() { return &m_seqSelModel; }
SingleRunsSelectorModel* singleRunsSelectorModel() { return &m_singleSelModel; }
std::shared_ptr<SingleRunData> loadSingleRun(QDir& dir);
void processDataExport(GeneratorFunc genfunc);
Signal::Resource resourceFromFiletype(AGRE_Filetype filetype);
- std::string signalControllerKey(const QString& main, const QString& resource) ;
+ bool saveSingleRunUserData(std::shared_ptr<SingleRunData> sr);
+ std::string signalControllerKey(const QString& main, const QString& resource);
void showOneSignal(std::shared_ptr<SignalController> ctrl);
Signal::YUnit yunitFromUnitStr(const std::string& unit_str);
int main(int argc, char *argv[])
{
+ int ret;
QApplication a(argc, argv);
#ifndef COMPILER_MSVC11
mWin->show();
- return a.exec();
+ ret = a.exec();
+
+ dMgr->saveUserDataOnExit();
+
+ return ret;
}
{
}
-Sequence::Sequence(std::unordered_map<std::string, std::shared_ptr<SingleRunData>>& singleRuns, QObject* parent) :
+Sequence::Sequence(SingleRunsMap& singleRuns, QObject* parent) :
QObject(parent),
m_selectedRunKey("")
{
#include <vector>
#include <QtCore/QObject>
+typedef std::unordered_map<std::string, std::shared_ptr<SingleRunData>> SingleRunsMap;
+
class Sequence : public QObject
{
Q_OBJECT
public:
explicit Sequence(QObject* parent = nullptr);
- explicit Sequence(std::unordered_map<std::string, std::shared_ptr<SingleRunData>>& singleRuns, QObject* parent = nullptr);
+ explicit Sequence(SingleRunsMap& singleRuns, QObject* parent = nullptr);
int add(const std::string name, std::shared_ptr<SingleRunData> value);
std::vector<std::string> allRunKeys() const;
std::shared_ptr<SingleRunData> at(const std::string& key);
- std::unordered_map<std::string, std::shared_ptr<SingleRunData>>::iterator begin() { return m_singleRuns.begin(); }
- std::unordered_map<std::string, std::shared_ptr<SingleRunData>>::const_iterator cbegin() const { return m_singleRuns.cbegin(); }
- std::unordered_map<std::string, std::shared_ptr<SingleRunData>>::const_iterator cend() const { return m_singleRuns.cend(); }
+ SingleRunsMap::iterator begin() { return m_singleRuns.begin(); }
+ SingleRunsMap::const_iterator cbegin() const { return m_singleRuns.cbegin(); }
+ SingleRunsMap::const_iterator cend() const { return m_singleRuns.cend(); }
std::shared_ptr<SignalController> controller(const std::string& uid);
size_t count() const { return m_singleRuns.size(); }
- std::unordered_map<std::string, std::shared_ptr<SingleRunData>>::iterator end() { return m_singleRuns.end(); }
+ SingleRunsMap::iterator end() { return m_singleRuns.end(); }
void remove(const std::string& key);
std::string selectedRunKey() const { return m_selectedRunKey; }
std::shared_ptr<SingleRunData> selectedRun();
- //int selectedRunIdx() const;
- //int singleRunToIdx(const QString& key) const;
bool setSelectedRun(const std::string& key);
private:
SignalController::SignalController(std::shared_ptr<Signal> signal, QObject* parent) :
QObject(parent),
JSONSerializable(),
- m_signal(signal)
+ m_signal(signal),
+ m_userDataModified(false)
{
m_integrator = std::shared_ptr<Integrator>(new Integrator(signal));
m_integTblModel = new IntegrationTableModel(m_integrator);
Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + " no peak to delete (idx " + QString::number(idx) + ")");
return PeakDrawData();
}
+
+ m_userDataModified = true;
+ emit userDataModified();
return genPeakDrawData(peak);
}
switch (ret) {
case Integrator::ReturnCode::SUCCESS:
+ emit userDataModified();
+ m_userDataModified = true;
return genPeakDrawData(peak);
break;
case Integrator::ReturnCode::E_NO_FIRST_INTERSECT:
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; }
+ bool userDataStatus() const { return m_userDataModified; }
+ void userDataSaved() { m_userDataModified = false; }
const std::shared_ptr<Integrator> cIntegrator() const { return m_integrator; }
double idxToRel(const size_t idx);
IntegrationTableModel* m_integTblModel;
std::shared_ptr<Integrator> m_integrator;
std::shared_ptr<Signal> m_signal;
+ bool m_userDataModified;
GUIViewport m_guiViewport;
signals:
void fillDataList();
+ void userDataModified();
};
#endif // SIGNALCONTROLLER_H
THE SOFTWARE.
*/
+#include "logger.h"
#include "singlerundata.h"
+#include <QtCore/QFile>
+#include <QtCore/QJsonParseError>
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonValue>
+#include <QtWidgets/QMessageBox>
+
+const QString SingleRunData::ME_SENDER_STR("SingleRunData");
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,
+ SignalsMap& sigs, SignalControllersMap& ctrls,
const QString& dirname, const QString& absPath, QObject *parent) :
QObject(parent),
m_absPath(absPath),
m_methodName(methodName),
m_operatorName(operatorName),
m_sampleInfo(sampleInfo),
+ m_userDataModified(false),
m_ctrls(ctrls),
m_signals(sigs),
m_time(time)
{
+ SignalControllersMap::iterator it = ctrls.begin();
+
+ while (it != ctrls.end()) {
+ connect(it->second.get(), SIGNAL(userDataModified()), this, SLOT(onUserDataModified()));
+ ++it;
+ }
}
std::vector<std::string> SingleRunData::allKeys() const
}
}
+void SingleRunData::readUserDataFromJSON()
+{
+ SignalControllersMap::iterator it = m_ctrls.begin();
+
+ while (it != m_ctrls.end()) {
+ std::shared_ptr<SignalController> c = it->second;
+ QString descriptiveName = QString::fromStdString(c->signal()->descriptiveName());
+ QString filename = "ank_" + descriptiveName + ".json";
+ QFile jsonFile(m_absPath + "/" + filename);
+
+ if (jsonFile.exists()) {
+ if (!jsonFile.open(QFile::ReadOnly)) {
+ QString errMsg = "Cannot open user data file " + filename + " for reading.";
+ Logger::log(Logger::Level::WARNING, ME_SENDER_STR, errMsg);
+ QMessageBox::warning(nullptr, "Cannot read user data", errMsg);
+ ++it;
+ continue;
+ }
+
+ QJsonParseError parseErr;
+ QByteArray bytes = jsonFile.readAll();
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(bytes, &parseErr);
+ if (parseErr.error != QJsonParseError::NoError) {
+ QString errMsg = "Cannot parse user data file " + filename + " (" + parseErr.errorString() + ")";
+ Logger::log(Logger::Level::WARNING, ME_SENDER_STR, errMsg);
+ QMessageBox::warning(nullptr, "Cannot read user data" , errMsg);
+ ++it;
+ continue;
+ }
+ QJsonObject jso = jsonDoc.object();
+
+ if (!c->deserialize(jso)) {
+ Logger::log(Logger::Level::WARNING, ME_SENDER_STR, "Failed to deserialize saved user data for " + descriptiveName);
+ QMessageBox::warning(nullptr, "Load single run", "Saved user data for signal " + descriptiveName +
+ "could not have been read properly.");
+ }
+ }
+
+ ++it;
+ }
+}
+
+bool SingleRunData::saveUserDataToJSON()
+{
+ SignalControllersMap::const_iterator cit = m_ctrls.cbegin();
+
+ while (cit != m_ctrls.cend()) {
+ if (!cit->second->userDataStatus()) {
+ ++cit;
+ continue;
+ }
+
+ QJsonValue val = cit->second->serialize();
+ if (!val.isObject()) {
+ Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, __QFUNC__ + " QJsonValue is not an object!");
+ return false;
+ }
+ QJsonDocument doc(val.toObject());
+
+ QString filename("ank_" + QString::fromStdString(cit->first) + ".json");
+ QFile f(m_absPath + "/" + filename);
+ QByteArray bytes = doc.toJson();
+
+ if (!f.open(QFile::WriteOnly)) {
+ QString errMsg = "Cannot open output file " + filename + " for writing (" + f.errorString() + ")";
+ Logger::log(Logger::Level::WARNING, ME_SENDER_STR, errMsg);
+ QMessageBox::warning(nullptr, "Cannot save user data", errMsg);
+ return false;
+ }
+ f.write(bytes.data(), bytes.size());
+
+ qDebug() << val;
+ f.close();
+ cit->second->userDataSaved();
+ ++cit;
+ }
+
+ m_userDataModified = false;
+ return true;
+}
+
std::shared_ptr<Signal> SingleRunData::signalAt(const std::string& key)
{
try {
#include <QtCore/QObject>
#include <QtCore/QTime>
+typedef std::unordered_map<std::string, std::shared_ptr<SignalController>> SignalControllersMap;
+typedef std::unordered_map<std::string, std::shared_ptr<Signal>> SignalsMap;
+
class SingleRunData : public QObject
{
Q_OBJECT
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,
+ SignalsMap& sigs, SignalControllersMap& ctrls,
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; }
+ const SignalControllersMap& 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; }
+ const SignalsMap& allSignals() const { return m_signals; }
std::shared_ptr<SignalController> controllerAt(const std::string& key);
QDate date() const { return m_date; }
QString dirName() const { return m_dirName; }
QString methodName() const { return m_methodName; }
QString operatorName() const { return m_operatorName; }
+ void readUserDataFromJSON();
+ bool saveUserDataToJSON();
QString sampleInfo() const { return m_sampleInfo; }
std::shared_ptr<Signal> signalAt(const std::string& key);
size_t signalCount() const { return m_signals.size(); }
QTime time() const { return m_time; }
+ bool userDataModified() const { return m_userDataModified; }
private:
const QString m_absPath;
const QString m_methodName;
const QString m_operatorName;
const QString m_sampleInfo;
- std::unordered_map<std::string, std::shared_ptr<SignalController>> m_ctrls;
- std::unordered_map<std::string, std::shared_ptr<Signal>> m_signals;
+ bool m_userDataModified;
+ SignalControllersMap m_ctrls;
+ SignalsMap m_signals;
const QTime m_time;
+ static const QString ME_SENDER_STR;
+
signals:
public slots:
+ void onUserDataModified() { m_userDataModified = true; }
};