diff --git a/snapshotmanager.cpp b/snapshotmanager.cpp new file mode 100644 --- /dev/null +++ b/snapshotmanager.cpp @@ -0,0 +1,198 @@ +/* + Copyright © 2015 Hasan Yavuz Özderya + + This file is part of serialplot. + + serialplot is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + serialplot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with serialplot. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "snapshotmanager.h" + +SnapshotManager::SnapshotManager(QMainWindow* mainWindow, + QList* channelBuffers) : + _menu("Snapshots"), + _takeSnapshotAction("Take Snapshot", this), + loadSnapshotAction("Load Snapshots", this), + clearAction("Clear Snapshots", this) +{ + _mainWindow = mainWindow; + _channelBuffers = channelBuffers; + + _takeSnapshotAction.setToolTip("Take a snapshot of current plot (F5)"); + _takeSnapshotAction.setShortcut(QKeySequence("F5")); + loadSnapshotAction.setToolTip("Load snapshots from CSV files"); + clearAction.setToolTip("Delete all snapshots"); + connect(&_takeSnapshotAction, SIGNAL(triggered(bool)), + this, SLOT(takeSnapshot())); + connect(&clearAction, SIGNAL(triggered(bool)), + this, SLOT(clearSnapshots())); + connect(&loadSnapshotAction, SIGNAL(triggered(bool)), + this, SLOT(loadSnapshots())); + + updateMenu(); +} + +SnapshotManager::~SnapshotManager() +{ + for (auto snapshot : snapshots) + { + delete snapshot; + } +} + +void SnapshotManager::takeSnapshot() +{ + QString name = QTime::currentTime().toString("'Snapshot ['HH:mm:ss']'"); + auto snapshot = new Snapshot(_mainWindow, name); + + unsigned numOfChannels = _channelBuffers->size(); + unsigned numOfSamples = _channelBuffers->at(0)->size(); + + for (unsigned ci = 0; ci < numOfChannels; ci++) + { + snapshot->data.append(QVector(numOfSamples)); + for (unsigned i = 0; i < numOfSamples; i++) + { + snapshot->data[ci][i] = _channelBuffers->at(ci)->sample(i); + } + } + + addSnapshot(snapshot); +} + +void SnapshotManager::addSnapshot(Snapshot* snapshot, bool update_menu) +{ + snapshots.append(snapshot); + QObject::connect(snapshot, &Snapshot::deleteRequested, + this, &SnapshotManager::deleteSnapshot); + if (update_menu) updateMenu(); +} + +void SnapshotManager::updateMenu() +{ + _menu.clear(); + _menu.addAction(&_takeSnapshotAction); + _menu.addAction(&loadSnapshotAction); + if (snapshots.size()) + { + _menu.addSeparator(); + for (auto ss : snapshots) + { + _menu.addAction(ss->showAction()); + } + _menu.addSeparator(); + _menu.addAction(&clearAction); + } +} + +void SnapshotManager::clearSnapshots() +{ + for (auto snapshot : snapshots) + { + delete snapshot; + } + snapshots.clear(); + updateMenu(); +} + +void SnapshotManager::deleteSnapshot(Snapshot* snapshot) +{ + snapshots.removeOne(snapshot); + snapshot->deleteLater(); // regular delete causes a crash when triggered from menu + updateMenu(); +} + +void SnapshotManager::loadSnapshots() +{ + auto files = QFileDialog::getOpenFileNames(_mainWindow, tr("Load CSV File")); + + for (auto f : files) + { + if (!f.isNull()) loadSnapshotFromFile(f); + } + + updateMenu(); +} + +void SnapshotManager::loadSnapshotFromFile(QString fileName) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + qCritical() << "Couldn't open file: " << fileName; + qCritical() << file.errorString(); + return; + } + + // read first row as headlines and determine number of channels + auto headLine = QString(file.readLine()); + unsigned numOfChannels = headLine.split(',').size(); + + // read data + QVector> data(numOfChannels); + unsigned lineNum = 1; + while (file.canReadLine()) + { + // parse line + auto line = QString(file.readLine()); + auto split = line.split(','); + + if (split.size() != (int) numOfChannels) + { + qCritical() << "Parsing error at line " << lineNum + << ": number of columns is not consistent."; + return; + } + + for (unsigned ci = 0; ci < numOfChannels; ci++) + { + // parse column + bool ok; + double y = split[ci].toDouble(&ok); + if (!ok) + { + qCritical() << "Parsing error at line " << lineNum + << ", column " << ci + << ": can't convert \"" << split[ci] + << "\" to double."; + return; + } + data[ci].append(QPointF(lineNum-1, y)); + } + lineNum++; + } + + auto snapshot = new Snapshot(_mainWindow, QFileInfo(fileName).baseName()); + snapshot->data = data; + + addSnapshot(snapshot, false); +} + +QMenu* SnapshotManager::menu() +{ + return &_menu; +} + +QAction* SnapshotManager::takeSnapshotAction() +{ + return &_takeSnapshotAction; +}