unix {
LIBS += -ldl
- QMAKE_CXXFLAGS += -std=c++11 -Wall
+ QMAKE_CXXFLAGS += -std=c++11 -Wall -Wextra
}
win32 {
SOURCES += windows_defines.h
datawriterbackend.cpp \
csvdatawriterbackend.cpp \
gui/exportgraphtoimagedialog.cpp \
- graphtoimageexporter.cpp \
imagedrawer.cpp \
signaldrawer.cpp
datawriterbackend.h \
csvdatawriterbackend.h \
gui/exportgraphtoimagedialog.h \
- graphtoimageexporter.h \
imagedrawer.h \
- signaldrawer.h
+ signaldrawer.h \
+ enumflags.h
FORMS += \
gui/mainwindow.ui \
#include "logger.h"
#include "gui/exportgraphtoimagedialog.h"
#include "gui/exportrawdatadialog.h"
-#include <QtGui/QImageWriter>
#include <QtWidgets/QMessageBox>
#include <QDebug>
std::vector<QVariantList> lines;
std::pair<QVariantList, std::vector<QVariantList>> p;
const std::shared_ptr<SignalController> ctrl = sr->controllerAt(key);
- std::shared_ptr<const Integrator> integrator;
+ std::shared_ptr<Integrator> integrator;
+ std::vector<std::shared_ptr<const IntegratedPeak>> allPeaks;
if (ctrl == nullptr)
continue;
+ QString::fromStdString(ctrl->signal()->yunitToString()) + "]" << "width [" + QString::fromStdString(ctrl->signal()->xunitToString()) + "]"
<< "height [" + QString::fromStdString(ctrl->signal()->yunitToString()) + "]";
integrator = ctrl->cIntegrator();
- for (std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator cit = integrator->peaksCBegin();
- cit != integrator->peaksCEnd(); cit++) {
+ /*for (std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator cit = integrator->peaksCBegin();
+ cit != integrator->peaksCEnd(); cit++) {*/
+ allPeaks = integrator->allPeaks();
+ for (std::shared_ptr<const IntegratedPeak> peak : allPeaks) {
QVariantList line;
- line << cit->second->peakTime() << cit->second->auc() << cit->second->width() << cit->second->height();
+ line << peak->peakTime() << peak->auc() << peak->width() << peak->height();
lines.push_back(line);
}
p = std::pair<QVariantList, std::vector<QVariantList>>(header, lines);
void DataManager::onExportGraphToImage()
{
- QImageWriter imageWriter;
- ExportGraphToImageDialog dlg(imageWriter.supportedImageFormats());
+ ExportGraphToImageDialog dlg(ImageDrawer::supportedImageFormats());
std::shared_ptr<SingleRunData> sr;
if (m_activeSequence == nullptr)
}
if (dlg.exec() == QDialog::Accepted) {
- double fromX = 0, toX = 0;
- double fromY = 0, toY = 0;
- int iw, ih;
const std::string key = dlg.selectedSignal().toStdString();
std::shared_ptr<SignalController> ctrl = sr->controllerAt(key);
- std::shared_ptr<Signal> sig;
+ GraphLayers gl = GraphLayers::GRAPH | GraphLayers::SCALE;
if (ctrl == nullptr) {
Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "Invalid key " + QString::fromStdString(key) + " passed to image exporter");
return;
}
- fromX = dlg.fromX();
- toX = dlg.toX();
- fromY = dlg.fromY();
- toY = dlg.toY();
- iw = dlg.imageWidth();
- ih = dlg.imageHeight();
- sig = ctrl->signal();
-
- if (iw < 1) {
- QMessageBox::warning(nullptr, "Error while exporting to image", "Invalid width value");
- return;
- }
- if (ih < 1) {
- QMessageBox::warning(nullptr, "Error while exporting to image", "Invalid width value");
- return;
- }
+
if (dlg.path().length() == 0) {
QMessageBox::warning(nullptr, "Error while exporting to image", "Invalid path");
return;
}
- qDebug() << fromX << fromY << toX << toY;
/*if (data == nullptr) {
QMessageBox::warning(nullptr, "Error while exporting to image", "Cannot generate data to draw. Some values are probably invalid.");
return;
}*/
- ImageDrawer imgDrawer(iw, ih, this);
- connect(ctrl.get(), SIGNAL(viewDrawGraph(double*,size_t,double,double)), &imgDrawer, SLOT(onUpdateGraph(double*,size_t,double,double)));
- connect(ctrl.get(), SIGNAL(viewDrawIntegration(int,double,int,double,int,double,QString,QString)), &imgDrawer, SLOT(onDrawIntegration(int,double,int,double,int,double,QString,QString)));
- //ctrl->onViewResized(iw, ih);
- //ctrl->onViewZoomedByValues(fromX, fromY, toX, toY);
+ if (dlg.includePeaks())
+ gl |= GraphLayers::INTEGRATION;
- QImage result = imgDrawer.pixmap()->toImage();
- imageWriter.setFileName(dlg.path() + "." + dlg.imageFormat());
- imageWriter.setFormat(dlg.imageFormat().toLatin1());
- if (!imageWriter.write(result))
+ ImageDrawer imageDrawer(ctrl);
+ if (!imageDrawer.render(dlg.path() + "." + dlg.imageFormat(), dlg.imageFormat().toLatin1(), dlg.imageWidth(), dlg.imageHeight(), gl))
QMessageBox::critical(nullptr, "Error while exporting to image", "Image could not have been written.");
}
--- /dev/null
+/*
+Copyright (c) 2013, Yuri Yaryshev (aka Lord Odin)
+
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/*
+Usage sample:
+
+#indlude "enum_flags.h"
+
+ENUM_FLAGS(foo_t)
+enum class foo_t
+ {
+ none = 0x00
+ ,a = 0x01
+ ,b = 0x02
+ };
+
+ENUM_FLAGS(foo2_t)
+enum class foo2_t
+ {
+ none = 0x00
+ ,d = 0x01
+ ,e = 0x02
+ };
+
+int _tmain(int argc, _TCHAR* argv[])
+ {
+ if(flags(foo_t::a & foo_t::b)) {};
+ // if(flags(foo2_t::d & foo_t::b)) {}; // Type safety test - won't compile if uncomment
+ };
+
+*/
+
+#ifndef ENUM_FLAGS_H
+#define ENUM_FLAGS_H
+
+/*
+Use this line before header, if you don't want flags(T x) function to be implemented for your enum.
+#define USE_ENUM_FLAGS_FUNCTION 0
+*/
+
+#ifndef USE_ENUM_FLAGS_FUNCTION
+#define USE_ENUM_FLAGS_FUNCTION 1
+#endif
+
+
+#define ENUM_FLAGS_EX_NO_FLAGS_FUNC(T,INT_T) \
+enum class T; \
+inline T operator & (T x, T y) { return static_cast<T> (static_cast<INT_T>(x) & static_cast<INT_T>(y)); }; \
+inline T operator | (T x, T y) { return static_cast<T> (static_cast<INT_T>(x) | static_cast<INT_T>(y)); }; \
+inline T operator ^ (T x, T y) { return static_cast<T> (static_cast<INT_T>(x) ^ static_cast<INT_T>(y)); }; \
+inline T operator ~ (T x) { return static_cast<T> (~static_cast<INT_T>(x)); }; \
+inline T& operator &= (T& x, T y) { x = x & y; return x; }; \
+inline T& operator |= (T& x, T y) { x = x | y; return x; }; \
+inline T& operator ^= (T& x, T y) { x = x ^ y; return x; };
+
+#if(USE_ENUM_FLAGS_FUNCTION)
+
+ #define ENUM_FLAGS_EX(T,INT_T) ENUM_FLAGS_EX_NO_FLAGS_FUNC(T,INT_T) \
+ inline bool flags(T x) { return static_cast<INT_T>(x) != 0;};
+
+#else
+
+ #define ENUM_FLAGS_EX(T,INT_T) ENUM_FLAGS_EX_NO_FLAGS_FUNC(T,INT_T)
+
+#endif
+
+#define ENUM_FLAGS(T) ENUM_FLAGS_EX(T,intptr_t)
+
+#endif //ENUM_FLAGS_H
+++ /dev/null
-#include "graphtoimageexporter.h"
-
-GraphToImageExporter::GraphToImageExporter(QObject* parent) :
- QObject(parent)
-{
-}
-
-GraphToImageExporter::ReturnCode GraphToImageExporter::setParameters(const double fromX, const double fromY, const double toX, const double toY, const int width,
- const int height, const QByteArray format, const QString& filename,
- const std::shared_ptr<SignalController> ctrl)
-{
- uint idx;
-
- if (fromX >= toX)
- return ReturnCode::E_INVALID_BOUNDS;
- if (filename.length() == 0)
- return ReturnCode::E_INVALID_FILENAME;
- if (ctrl == nullptr)
- return ReturnCode::E_NULL_CONTROLLER;
- if (width < 1 || height < 1)
- return ReturnCode::E_INVALID_SIZE;
-
- /* Get from an to indices */
- const std::vector<Signal::TimeValuePair>& tvpairs = ctrl->signal()->values();
- for (idx = 0; idx < tvpairs.size(); idx++) {
- if (tvpairs.at(idx).first >= fromX) {
- m_fromIdx = idx;
- break;
- }
- }
- if (idx == tvpairs.size())
- return ReturnCode::E_INVALID_BOUNDS;
- for (;idx < tvpairs.size(); idx++) {
- if (tvpairs.at(idx).first >= toX) {
- m_toIdx = idx;
- break;
- }
- }
- if (idx == tvpairs.size())
- m_toIdx = idx - 1;
-
-
- //m_data = ctrl->generateDrawData(m_fromIdx, m_toIdx);
- if (m_data == nullptr)
- return ReturnCode::E_NULL_DATA;
-
- return ReturnCode::SUCCESS;
-}
+++ /dev/null
-#ifndef GRAPHTOIMAGEEXPORTER_H
-#define GRAPHTOIMAGEEXPORTER_H
-
-#include "signalcontroller.h"
-#include <QtCore/QObject>
-#include <QtGui/QImageWriter>
-
-class GraphToImageExporter : public QObject
-{
- Q_OBJECT
-public:
- enum class ReturnCode {
- SUCCESS,
- E_INVALID_BOUNDS,
- E_INVALID_FORMAT,
- E_INVALID_FILENAME,
- E_NULL_CONTROLLER,
- E_INVALID_SIZE,
- E_NULL_DATA
- };
-
- explicit GraphToImageExporter(QObject* parent = nullptr);
- ReturnCode setParameters(const double fromX, const double fromY, const double toX, const double toY, const int width, const int height,
- const QByteArray format, const QString& filename, const std::shared_ptr<SignalController> ctrl);
- QList<QByteArray> supportedImageFormats();
-
-private:
- const std::shared_ptr<SignalController> m_ctrl;
- double* m_data;
- QString m_filename;
- double m_fromIdx;
- double m_fromY;
- double m_toIdx;
- double m_toY;
- int m_height;
- int m_width;
- QImageWriter m_writer;
-
-signals:
-
-public slots:
-
-};
-
-#endif // GRAPHTOIMAGEEXPORTER_H
return ui->qcbox_outputFormat->currentText();
}
+bool ExportGraphToImageDialog::includePeaks() const
+{
+ return ui->qck_includeInteg->isChecked();
+}
+
int ExportGraphToImageDialog::imageHeight() const
{
bool ok;
void GraphView::setDefaultZoom()
{
- double range = SignalController::RELATIVE_MAX - SignalController::RELATIVE_MIN;
-
m_relXMax = SignalController::RELATIVE_MAX;
m_relXMin = SignalController::RELATIVE_MIN;
m_relYMax = RELATIVE_Y_MAX_WITH_MARGIN();
#include <QDebug>
-ImageDrawer::ImageDrawer(const int width, const int height, QObject* parent) :
- QObject(parent),
- m_height(height),
- m_width(width)
+ImageDrawer::ImageDrawer(std::shared_ptr<SignalController> controller) :
+ SignalDrawer(controller),
+ m_controller(controller)
{
+ m_imageWriter.setCompression(0);
}
-void ImageDrawer::onUpdateGraph(double* data, size_t len, double min, double max)
+bool ImageDrawer::render(const QString& filename, const QByteArray format, const int width, const int height, const GraphLayers layers)
{
- if (data == nullptr)
- return;
- m_drawDataMin = min;
- m_drawDataMax = max;
+ QImage image;
- //m_pixmap = m_graphDrawer->drawGraph(data, len, m_width, m_height, min, max);
-}
-
-void ImageDrawer::onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakStartX, const double peakStartY,
- const QString& time, const QString& area)
-{
- double xStep = static_cast<double>(m_width);
- double yStep = static_cast<double>(m_height) / (m_drawDataMax - m_drawDataMin);
- int startX = floor(fromX * xStep + 0.5);
- int stopX = floor(toX * xStep + 0.5);
- int startY = floor((m_height - yStep * (fromY - m_drawDataMin)) + 0.5);
- int stopY = floor((m_height - yStep * (toY - m_drawDataMin)) + 0.5);
- int peakX = floor(peakStartX * xStep + 0.5);
- int peakY = floor(m_height - yStep * (peakStartY - m_drawDataMin) + 0.5);
+ setDimensions(width, height);
+ if (!draw(SignalController::RELATIVE_MIN, SignalController::RELATIVE_MIN, SignalController::RELATIVE_MAX, SignalController::RELATIVE_MAX, layers))
+ return false;
- if (m_pixmap == nullptr)
- return;
+ m_imageWriter.setFileName(filename);
+ m_imageWriter.setFormat(format);
+ image = m_pixmap->toImage();
- qDebug() << "drawing peak";
+ return m_imageWriter.write(image);
+}
- //m_graphDrawer->overlayIntegratedPeak(m_pixmap, startX, startY, stopX, stopY, peakX, peakY, time, area);
+QList<QByteArray> ImageDrawer::supportedImageFormats()
+{
+ return QImageWriter::supportedImageFormats();
}
#ifndef IMAGEDRAWER_H
#define IMAGEDRAWER_H
-#include <QtCore/QObject>
+#include "signaldrawer.h"
+#include <QtGui/QImageWriter>
-class ImageDrawer : public QObject
+class ImageDrawer : protected SignalDrawer
{
- Q_OBJECT
public:
- explicit ImageDrawer(const int width, const int height, QObject* parent = nullptr);
- const QPixmap* pixmap() const { return m_pixmap; }
+ explicit ImageDrawer(std::shared_ptr<SignalController> controller);
+ bool render(const QString& filename, const QByteArray format, const int width, const int height, const GraphLayers layers);
-private:
- QPixmap* m_pixmap;
- int m_drawDataMin;
- int m_drawDataMax;
-
- const int m_height;
- const int m_width;
+ static QList<QByteArray> supportedImageFormats();
-signals:
+private:
+ std::shared_ptr<SignalController> m_controller;
+ QImageWriter m_imageWriter;
-public slots:
- void onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakStartX, const double peakStartY,
- const QString& time, const QString& area);
- void onUpdateGraph(double* data, size_t len, double min, double max);
};
*/
#include "integrationtablemodel.h"
+#include "logger.h"
#include <QtCore/QLocale>
+const QString IntegrationTableModel::ME_SENDER_STR("IntegrationTableModel");
+
IntegrationTableModel::IntegrationTableModel(const std::shared_ptr<Integrator> integrator, QObject* parent) :
QAbstractTableModel(parent),
m_integrator(integrator)
if (index.row() >= m_integrator->peakCount())
return QVariant();
- const std::shared_ptr<IntegratedPeak> peak = m_integrator->peakByIdx(index.row());
+ std::shared_ptr<const IntegratedPeak> peak = m_integrator->peakByListIdx(index.row());
+ if (peak == nullptr) {
+ Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "Null pointer to peak");
+ return QVariant();
+ }
switch (role) {
case Qt::DisplayRole:
switch (index.column()) {
return m_integrator->peakCount();
}
+
+void IntegrationTableModel::prepToAdd(const int idx)
+{
+
+ beginInsertRows(QModelIndex(), idx ,idx);
+}
+
+void IntegrationTableModel::addDone()
+{
+ endInsertRows();
+}
+
+void IntegrationTableModel::prepToDelete(const int idx)
+{
+ beginRemoveRows(QModelIndex(), idx, idx);
+}
+
+void IntegrationTableModel::deleteDone()
+{
+ endRemoveRows();
+}
+
class IntegrationTableModel : public QAbstractTableModel
{
+ Q_OBJECT
public:
IntegrationTableModel(const std::shared_ptr<Integrator> integrator, QObject* parent = nullptr);
QVariant data(const QModelIndex& index, int role) const;
- void doneReset() { endResetModel(); }
int columnCount(const QModelIndex& parent) const { Q_UNUSED(parent); return 4; }
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- void prepReset() { beginResetModel(); }
int rowCount(const QModelIndex& parent) const;
private:
const std::shared_ptr<Integrator> m_integrator;
+
+ static const QString ME_SENDER_STR;
+
+public slots:
+ void prepToAdd(const int idx);
+ void prepToDelete(const int idx);
+ void addDone();
+ void deleteDone();
};
#endif // INTEGRATIONTABLEMODEL_H
m_signal(signal)
{}
-std::shared_ptr<IntegratedPeak> Integrator::deletePeak(size_t idx)
+std::shared_ptr<const IntegratedPeak> Integrator::deletePeak(size_t idx)
{
+ size_t ctr = 0;
std::shared_ptr<IntegratedPeak> peak;
- std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::iterator it = m_peaks.begin();
- while (it != m_peaks.end() && it->first <= idx) {
- if (it->first <= idx && it->second->toIdx() > idx) { /* Peak is surrounding the cursor */
- peak = it->second;
- m_peaks.erase(it);
- return peak;
+ m_peaksList.setToFirst();
+ while ((peak = m_peaksList.getCurrent()) != nullptr) {
+ if (peak->fromIdx() <= idx && peak->toIdx() >= idx) { /* Peak is surrounding the cursor */
+ qDebug() << "Deleting peak ctr" << ctr << "auc" << peak->auc();
+ std::shared_ptr<IntegratedPeak> copyPeak = peak;
+ emit deletingPeak(ctr);
+ m_peaksList.removeCurrent();
+ emit peakRemoved();
+ return copyPeak;
}
- it++;
+ m_peaksList.next();
+
+ qDebug() << "Going through peaks to delete, ctr " << ctr << "peak auc" << peak->auc();
+ ctr++;
}
+
return nullptr;
}
+std::vector<std::shared_ptr<const IntegratedPeak>> Integrator::allPeaks()
+{
+ std::shared_ptr<const IntegratedPeak> peak;
+ std::vector<std::shared_ptr<const IntegratedPeak>> allPeaks;
+
+ m_peaksList.setToFirst();
+ while ((peak = m_peaksList.getCurrent()) != nullptr) {
+ allPeaks.push_back(peak);
+ m_peaksList.next();
+ }
+
+ return allPeaks;
+}
+
Integrator::ReturnCode Integrator::integrate(size_t startIdx, size_t stopIdx, double startY, double stopY, std::shared_ptr<IntegratedPeak>& peak)
{
size_t peakValueIdx;
peak = std::shared_ptr<IntegratedPeak>(new IntegratedPeak(peakType, auc, peakValueIdx, m_signal->timeAt(peakValueIdx), m_signal->valueAt(peakValueIdx),
startIntersIdx, stopIntersIdx, m_signal->timeAt(startIntersIdx), m_signal->timeAt(stopIntersIdx),
startYVal, stopYVal));
- m_peaks.insert(std::pair<size_t, std::shared_ptr<IntegratedPeak>>(startIdx, peak));
-
+ emit addingPeak(m_peaksList.count());
+ m_peaksList.append(peak);
+ emit peakAdded();
+ qDebug() << "Peak added, count" << m_peaksList.count();
return ReturnCode::SUCCESS;
}
-const std::shared_ptr<IntegratedPeak> Integrator::peakByIdx(const int idx) const
+std::shared_ptr<const IntegratedPeak> Integrator::peakByListIdx(const size_t idx)
+{
+ if (m_peaksList.count() == 0)
+ return nullptr;
+ if (idx >= m_peaksList.count())
+ return nullptr;
+
+ m_peaksList.setToFirst();
+
+ /*while (ctr++ != idx && (peak = m_peaksList.getCurrent()) != nullptr) {
+ peak = m_peaksList.getCurrent();
+ m_peaksList.next();
+ }*/
+ for (size_t i = 0; i < idx; i++)
+ m_peaksList.next();
+
+ return m_peaksList.getCurrent();
+}
+
+/* Linked list methods */
+Integrator::PeaksLinkedList::PeaksLinkedList() :
+ first(nullptr),
+ current(nullptr),
+ last(nullptr),
+ ctr(0)
+{}
+
+void Integrator::PeaksLinkedList::append(std::shared_ptr<IntegratedPeak> peak)
+{
+ ListItem* item = new ListItem(peak);
+
+ if (first == nullptr) {
+ first = item;
+ item->prev = nullptr;
+ } else {
+ last->next = item;
+ item->prev = last;
+ }
+
+ last = item;
+ ctr++;
+}
+
+std::shared_ptr<IntegratedPeak> Integrator::PeaksLinkedList::getCurrent()
+{
+ if (current == nullptr)
+ return nullptr;
+
+ return current->m_peak;
+}
+
+std::shared_ptr<IntegratedPeak> Integrator::PeaksLinkedList::getFirst()
+{
+ if (first == nullptr)
+ return nullptr;
+
+ return first->m_peak;
+}
+
+void Integrator::PeaksLinkedList::removeCurrent()
{
- std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator it = m_peaks.begin();
- std::advance(it, idx);
+ ListItem* deleteMe;
- return it->second;
+ if (current == nullptr)
+ return;
+
+ if (ctr == 1) {
+ first = nullptr;
+ last = nullptr;
+ } else if (current == first) {
+ first = first->next;
+ if (first != nullptr)
+ first->prev = nullptr;
+ } else if (current == last) {
+ last = current->prev;
+ last->next = nullptr;
+ } else {
+ ListItem* prev = current->prev;
+ prev->next = current->next;
+ }
+
+ deleteMe = current;
+ current = current->next;
+ ctr--;
+ delete deleteMe;
+}
+
+void Integrator::PeaksLinkedList::next()
+{
+ if (current == nullptr)
+ current = first;
+ else
+ current = current->next;
+}
+
+void Integrator::PeaksLinkedList::setToFirst()
+{
+ current = first;
}
};
explicit Integrator(std::shared_ptr<Signal> signal, QObject* parent = nullptr);
- std::shared_ptr<IntegratedPeak> deletePeak(size_t idx);
+ 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);
- const std::shared_ptr<IntegratedPeak> peakByIdx(const int idx) const;
- std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCBegin() const { return m_peaks.cbegin(); }
- std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCEnd() const { return m_peaks.cend(); }
- size_t peakCount() const { return m_peaks.size(); }
+ std::shared_ptr<const IntegratedPeak> peakByListIdx(const size_t idx);
+ //std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCBegin() const { return m_peaks.cbegin(); }
+ //std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator peaksCEnd() const { return m_peaks.cend(); }
+ size_t peakCount() const { return m_peaksList.count(); }
private:
- std::multimap<size_t, std::shared_ptr<IntegratedPeak>> m_peaks;
+ struct ListItem {
+ ListItem(std::shared_ptr<IntegratedPeak> peak) : m_peak(peak), next(nullptr) {}
+ std::shared_ptr<IntegratedPeak> m_peak;
+ ListItem* prev;
+ ListItem* next;
+ };
+ class PeaksLinkedList {
+ public:
+ explicit PeaksLinkedList();
+ void append(std::shared_ptr<IntegratedPeak> peak);
+ size_t count() const { return ctr; }
+ std::shared_ptr<IntegratedPeak> getCurrent();
+ std::shared_ptr<IntegratedPeak> getFirst();
+ void next();
+ void removeCurrent();
+ void setToFirst();
+ private:
+ ListItem* first;
+ ListItem* current;
+ ListItem* last;
+ size_t ctr;
+ };
+
+ PeaksLinkedList m_peaksList;
std::shared_ptr<Signal> m_signal;
static const QString ME_SENDER_STR;
signals:
+ void addingPeak(const int idx);
+ void deletingPeak(const int idx);
+ void peakAdded();
+ void peakRemoved();
public slots:
m_integrator = std::shared_ptr<Integrator>(new Integrator(signal));
m_integTblModel = new IntegrationTableModel(m_integrator);
m_dtblModel = new SignalDataTableModel(signal);
+
+ connect(m_integrator.get(), SIGNAL(addingPeak(int)), m_integTblModel, SLOT(prepToAdd(int)));
+ connect(m_integrator.get(), SIGNAL(peakAdded()), m_integTblModel, SLOT(addDone()));
+ connect(m_integrator.get(), SIGNAL(deletingPeak(int)), m_integTblModel, SLOT(prepToDelete(int)));
+ connect(m_integrator.get(), SIGNAL(peakRemoved()), m_integTblModel, SLOT(deleteDone()));
}
/** Public methods **/
PeakDrawData SignalController::deletePeak(const double x)
{
size_t idx = relToIdx(x);
- std::shared_ptr<IntegratedPeak> peak;
+ std::shared_ptr<const IntegratedPeak> peak;
if (idx > m_signal->count()-1) {
Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, __QFUNC__ + " idx value " + QString::number(idx) + " out of bounds!");
return PeakDrawData();
}
- m_integTblModel->prepReset();
peak = m_integrator->deletePeak(idx);
if (peak == nullptr) {
Logger::log(Logger::Level::DEBUG, ME_SENDER_STR, __QFUNC__ + " no peak to delete (idx " + QString::number(idx) + ")");
- m_integTblModel->doneReset();
return PeakDrawData();
}
- m_integTblModel->doneReset();
return genPeakDrawData(peak);
}
{
std::vector<PeakDrawData> peaks;
size_t fromIdx, toIdx;
- std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator cit = m_integrator->peaksCBegin();
+ std::vector<std::shared_ptr<const IntegratedPeak>> allPeaks;
+ // std::multimap<size_t, std::shared_ptr<IntegratedPeak>>::const_iterator cit = m_integrator->peaksCBegin();
if (toX <= fromX) {
Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " toX is lower than fromX");
return peaks;
}
- while (cit != m_integrator->peaksCEnd()) {
- std::shared_ptr<IntegratedPeak> peak = cit->second;
-
+ allPeaks = m_integrator->allPeaks();
+ for (std::shared_ptr<const IntegratedPeak> peak : allPeaks) {
if (peak->toIdx() < fromIdx || peak->fromIdx() > toIdx) /* Peak is not in view X-wise, skip it */
continue;
peaks.push_back(genPeakDrawData(peak));
- cit++;
}
return peaks;
fromVal = relToValue(fromY);
toVal = relToValue(toY);
- m_integTblModel->prepReset();
ret = m_integrator->integrate(fromIdx, toIdx, fromVal, toVal, peak);
switch (ret) {
case Integrator::ReturnCode::SUCCESS:
- m_integTblModel->doneReset();
return genPeakDrawData(peak);
break;
case Integrator::ReturnCode::E_NO_FIRST_INTERSECT:
/** Private methods **/
-PeakDrawData SignalController::genPeakDrawData(const std::shared_ptr<IntegratedPeak> peak)
+PeakDrawData SignalController::genPeakDrawData(const std::shared_ptr<const IntegratedPeak> peak)
{
return PeakDrawData(idxToRel(peak->fromIdx()), valueToRel(peak->fromY()),
idxToRel(peak->toIdx()), valueToRel(peak->toY()),
size_t relToIdx(const double rel);
double relToValue(const double rel);
- void drawIntegratedPeak(const std::shared_ptr<IntegratedPeak> peak);
- PeakDrawData genPeakDrawData(const std::shared_ptr<IntegratedPeak> peak);
+ void drawIntegratedPeak(const std::shared_ptr<const IntegratedPeak> peak);
+ PeakDrawData genPeakDrawData(const std::shared_ptr<const IntegratedPeak> peak);
static const QString ME_SENDER_STR;
return Constraints(m_relXMin, m_relYMin, m_relXMax, m_relYMax);
}
-bool SignalDrawer::draw(const double fromX, const double fromY, const double toX, const double toY)
+bool SignalDrawer::draw(const double fromX, const double fromY, const double toX, const double toY, const GraphLayers layers)
{
QPixmap* fresh;
bool ret;
fresh = createFreshPixmap();
if (fresh == nullptr)
return false;
- ret = drawGraph(fresh);
- if (!ret) {
- Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw graph");
- restoreRelativeConstraints();
- delete fresh;
- return ret;
+
+ /* Draw the signal itself */
+ if (flags(GraphLayers::GRAPH & layers)) {
+ ret = drawGraph(fresh);
+ if (!ret) {
+ Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw graph");
+ restoreRelativeConstraints();
+ delete fresh;
+ return ret;
+ }
+ }
+
+ /* Draw the scale */
+ if (flags(GraphLayers::SCALE & layers)) {
+ ret = renderScale(SignalController::Axis::VALUE, fresh);
+ ret = renderScale(SignalController::Axis::TIME, fresh);
}
- ret = renderScale(SignalController::Axis::VALUE, fresh);
- ret = renderScale(SignalController::Axis::TIME, fresh);
- ret = drawPeaks(fresh);
- if (!ret) {
- Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw integrated peaks");
- restoreRelativeConstraints();
- delete fresh;
- return ret;
+
+ /* Draw integrated peaks */
+ if (flags(GraphLayers::INTEGRATION & layers)) {
+ ret = drawPeaks(fresh);
+ if (!ret) {
+ Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw integrated peaks");
+ restoreRelativeConstraints();
+ delete fresh;
+ return ret;
+ }
}
renderFresh(fresh);
#ifndef SIGNALDRAWER_H
#define SIGNALDRAWER_H
+#include "enumflags.h"
#include "signalcontroller.h"
#include <QtCore/QLocale>
#include <QtGui/QFont>
const double fromX, fromY, toX, toY;
};
+ENUM_FLAGS(GraphLayers)
+enum class GraphLayers {
+ GRAPH = 0x01,
+ INTEGRATION = 0x02,
+ SCALE = 0x04,
+ ALL = INT_MAX
+};
+
class SignalDrawer
{
public:
- SignalDrawer(std::shared_ptr<SignalController> controller, const Constraints& constraints = Constraints());
+ SignalDrawer(std::shared_ptr<SignalController> controller, const Constraints& constraints = Constraints());
~SignalDrawer();
Constraints currentConstraints();
int dheight() const { return m_height; }
- bool draw(const double fromX, const double fromY, const double toX, const double toY);
+ bool draw(const double fromX, const double fromY, const double toX, const double toY, const GraphLayers layers = GraphLayers::ALL);
bool drawGraph(QPixmap* const target);
bool drawPeaks(QPixmap* const target);
QRect erasePeak(const PeakDrawData& pd);