]> Devoid-pointer.net GitWeb - anyanka.git/commitdiff
Add possibility to export graphs to images.
authorMichal Malý <madcatxster@prifuk.cz>
Fri, 13 Dec 2013 22:19:03 +0000 (23:19 +0100)
committerMichal Malý <madcatxster@prifuk.cz>
Fri, 13 Dec 2013 22:19:03 +0000 (23:19 +0100)
14 files changed:
Anyanka.pro
datamanager.cpp
datamanager.h
graphdrawer.cpp
gui/exportgraphtoimagedialog.cpp [new file with mode: 0644]
gui/exportgraphtoimagedialog.h [new file with mode: 0644]
gui/exportgraphtoimagedialog.ui [new file with mode: 0644]
gui/mainwindow.cpp
gui/mainwindow.h
main.cpp
signal.h
signalcontroller.cpp
signalcontroller.h
singlerundata.h

index 76443c8d0c379ff968323a6674c3804996328097..d17c3ff6708616e111dda5de9dafa526cd3ac8a8 100644 (file)
@@ -50,7 +50,8 @@ SOURCES += main.cpp\
     datafileexporter.cpp \
     datawriterbackend.cpp \
     csvdatawriterbackend.cpp \
-    graphdrawer.cpp
+    graphdrawer.cpp \
+    gui/exportgraphtoimagedialog.cpp
 
 HEADERS  += \
     datafilesloader.h \
@@ -81,13 +82,15 @@ HEADERS  += \
     datafileexporter.h \
     datawriterbackend.h \
     csvdatawriterbackend.h \
-    graphdrawer.h
+    graphdrawer.h \
+    gui/exportgraphtoimagedialog.h
 
 FORMS += \
     gui/mainwindow.ui \
     gui/signalview.ui \
     gui/aboutanyanka.ui \
-    gui/exportrawdatadialog.ui
+    gui/exportrawdatadialog.ui \
+    gui/exportgraphtoimagedialog.ui
 
 RESOURCES += \
     imgresources.qrc
index d00e0826facada194ba6e431d588836a73e87d50..09957a9ebd06e720800ece8e9ecfcb49301e03c0 100644 (file)
@@ -22,7 +22,9 @@
 
 #include "datamanager.h"
 #include "logger.h"
+#include "gui/exportgraphtoimagedialog.h"
 #include "gui/exportrawdatadialog.h"
+#include <QtGui/QImageWriter>
 #include <QtWidgets/QMessageBox>
 
 #include <QDebug>
@@ -370,6 +372,99 @@ void DataManager::showOneSignal(std::shared_ptr<SignalController> ctrl)
 
 /* Public slots */
 
+void DataManager::onExportGraphToImage()
+{
+  QImageWriter imageWriter;
+  ExportGraphToImageDialog dlg(imageWriter.supportedImageFormats());
+  std::shared_ptr<SingleRunData> sr;
+
+  if (m_activeSequence == nullptr)
+    return;
+  sr = m_activeSequence->selectedRun();
+  if (sr == nullptr)
+    return;
+
+  for (const std::pair<std::string, std::shared_ptr<SignalController>>& p : sr->allControllers())
+    dlg.addSignal(p.second->currentStartX(), p.second->currentStartY(), p.second->currentStopX(), p.second->currentStopY(), p.first);
+
+  if (dlg.exec() == QDialog::Accepted) {
+    GraphDrawer drawer;
+    double* data;
+    size_t fromIdx, toIdx;
+    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;
+
+    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;
+
+    /* Get from an to indices */
+    const std::vector<Signal::TimeValuePair>& tvpairs = sig->values();
+    uint idx;
+    for (idx = 0; idx < tvpairs.size(); idx++) {
+      if (tvpairs.at(idx).first >= fromX) {
+        fromIdx = idx;
+        break;
+      }
+    }
+    if (idx == tvpairs.size()) {
+      QMessageBox::warning(nullptr, "Error while exporting to image", "Value \"From X\" is higher than the range of the dataset.");
+      return;
+    }
+    for (;idx < tvpairs.size(); idx++) {
+      if (tvpairs.at(idx).first >= toX) {
+        toIdx = idx;
+        break;
+      }
+    }
+    if (idx == tvpairs.size())
+      toIdx = idx - 1;
+
+    qDebug() << "fromIdx" << fromIdx << "toIdx" << toIdx << "size" << tvpairs.size();
+    data = ctrl->generateDrawData(fromIdx, toIdx);
+    if (data == nullptr) {
+      QMessageBox::warning(nullptr, "Error while exporting to image", "Cannot generate data to draw. Some values are probably invalid.");
+      return;
+    }
+
+    QPixmap* pixmap = drawer.drawGraph(data, toIdx - fromIdx, iw, ih, fromY, toY);
+    QImage result = pixmap->toImage();
+    imageWriter.setFileName(dlg.path() + "." + dlg.imageFormat());
+    imageWriter.setFormat(dlg.imageFormat().toLatin1());
+    if (!imageWriter.write(result))
+      QMessageBox::critical(nullptr, "Error while exporting to image", "Image could not have been written.");
+
+    delete pixmap;
+    delete data;
+  }
+}
+
 void DataManager::onExportPeaks()
 {
   if (m_activeSequence == nullptr)
index 93be0beac3acc2ae3f8228e4512196e1cdaea594..ff16b0ef0468daea58848adaef1caaecce40a60b 100644 (file)
@@ -86,6 +86,7 @@ signals:
   void setSingleRunInfo(const QString& method, const QString& operatorname, const QString& sample, const QString& datetime);
 
 public slots:
+  void onExportGraphToImage();
   void onExportPeaks();
   void onExportRawData();
   void onLoadSequence(const QString& dir);
index 86142c5e31bc1ffac8e3efb27ce4b5b95c58135e..44c0ed86448bcdd1fdc1b9c66e5b4088d603af92 100644 (file)
@@ -33,7 +33,6 @@ QPixmap* GraphDrawer::drawGraph(const double* const data, const size_t len, size
     int toY = h - yStep * (data[i] - min);
     p.drawLine(fromX, fromY, toX, toY);
 
-    qDebug() << "fromX" << fromX << "fromY" << fromY << "toX" << toX << "toY" << toY;
     fromX = toX;
     fromY = toY;
   }
diff --git a/gui/exportgraphtoimagedialog.cpp b/gui/exportgraphtoimagedialog.cpp
new file mode 100644 (file)
index 0000000..eea1c1d
--- /dev/null
@@ -0,0 +1,172 @@
+#include "exportgraphtoimagedialog.h"
+#include "ui_exportgraphtoimagedialog.h"
+#include <QtCore/QLocale>
+#include <QtWidgets/QFileDialog>
+
+/* Public functions */
+
+ExportGraphToImageDialog::ExportGraphToImageDialog(QList<QByteArray> formats, QWidget *parent) :
+  QDialog(parent),
+  m_curKey(""),
+  ui(new Ui::ExportGraphToImageDialog)
+{
+  ui->setupUi(this);
+
+  for (const QByteArray ba : formats)
+    ui->qcbox_outputFormat->addItem(QString::fromLatin1(ba));
+
+  connect(ui->qpb_browse, SIGNAL(clicked()), this, SLOT(onBrowseClicked()));
+  connect(ui->qpb_cancel, SIGNAL(clicked()), this, SLOT(reject()));
+  connect(ui->qpb_ok, SIGNAL(clicked()), this, SLOT(checkAndAccept()));
+  connect(ui->qcbox_signal, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeBounds(QString)));
+}
+
+void ExportGraphToImageDialog::addSignal(const double fromX, const double fromY, const double toX, const double toY, const std::string& key)
+{
+  m_signalKeys.push_back(key);
+  m_bounds[key] = Bounds(fromX, fromY, toX, toY);
+
+  ui->qcbox_signal->addItem(QString::fromStdString(key));
+}
+
+double ExportGraphToImageDialog::fromX() const
+{
+  try {
+    return std::get<0>(m_bounds.at(m_curKey));
+  } catch (std::out_of_range&) {
+    return 0;
+  }
+}
+
+double ExportGraphToImageDialog::fromY() const
+{
+  try {
+    return std::get<1>(m_bounds.at(m_curKey));
+  } catch (std::out_of_range&) {
+    return 0;
+  }
+}
+
+QString ExportGraphToImageDialog::imageFormat() const
+{
+  return ui->qcbox_outputFormat->currentText();
+}
+
+int ExportGraphToImageDialog::imageHeight() const
+{
+  bool ok;
+  double h = ui->qle_height->text().toInt(&ok);
+  if (!ok) return 0;
+  return h;
+}
+
+QString ExportGraphToImageDialog::path() const
+{
+  return ui->qle_destPath->text();
+}
+
+QString ExportGraphToImageDialog::selectedSignal() const
+{
+  return ui->qcbox_signal->currentText();
+}
+
+double ExportGraphToImageDialog::toX() const
+{
+  try {
+    return std::get<2>(m_bounds.at(m_curKey));
+  } catch (std::out_of_range&) {
+    return 0;
+  }
+}
+
+double ExportGraphToImageDialog::toY() const
+{
+  try {
+    return std::get<3>(m_bounds.at(m_curKey));
+  } catch (std::out_of_range&) {
+    return 0;
+  }
+}
+
+int ExportGraphToImageDialog::imageWidth() const
+{
+  bool ok;
+  double w = ui->qle_width->text().toInt(&ok);
+
+  if (!ok) return 0;
+  return w;
+}
+
+/* Private slots */
+
+void ExportGraphToImageDialog::changeBounds(const QString& key)
+{
+  QLocale l = QLocale::system();
+  Bounds oldBounds, newBounds;
+  std::string skey = key.toStdString();
+  double fX, fY, tX, tY;
+  bool ok;
+
+  try {
+    oldBounds = m_bounds.at(m_curKey);
+
+    fX = ui->qle_fromX->text().toDouble(&ok);
+    if (ok) std::get<0>(oldBounds) = fX;
+    fY = ui->qle_fromY->text().toDouble(&ok);
+    if (ok) std::get<1>(oldBounds) = fY;
+    tX = ui->qle_toX->text().toDouble(&ok);
+    if (ok) std::get<2>(oldBounds) = tX;
+    tY = ui->qle_toY->text().toDouble(&ok);
+    if (ok) std::get<3>(oldBounds) = tY;
+
+    m_bounds[m_curKey] = oldBounds;
+  } catch (std::out_of_range&) {
+  }
+
+  try {
+    newBounds = m_bounds.at(skey);
+
+    ui->qle_fromX->setText(l.toString(std::get<0>(newBounds)));
+    ui->qle_fromY->setText(l.toString(std::get<1>(newBounds)));
+    ui->qle_toX->setText(l.toString(std::get<2>(newBounds)));
+    ui->qle_toY->setText(l.toString(std::get<3>(newBounds)));
+    m_curKey = skey;
+  } catch (std::out_of_range&) {
+  }
+}
+
+void ExportGraphToImageDialog::checkAndAccept()
+{
+  try {
+    double fX, fY, tX, tY;
+    bool ok;
+    const std::string key = ui->qcbox_signal->currentText().toStdString();
+    Bounds b = m_bounds.at(key);
+
+    fX = ui->qle_fromX->text().toDouble(&ok);
+    if (ok) std::get<0>(b) = fX;
+    fY = ui->qle_fromY->text().toDouble(&ok);
+    if (ok) std::get<1>(b) = fY;
+    tX = ui->qle_toX->text().toDouble(&ok);
+    if (ok) std::get<2>(b) = tX;
+    tY = ui->qle_toY->text().toDouble(&ok);
+    if (ok) std::get<3>(b) = tY;
+
+    m_bounds[key] = b;
+  } catch (std::out_of_range&) {
+  }
+
+  accept();
+}
+
+void ExportGraphToImageDialog::onBrowseClicked()
+{
+  QFileDialog fdlg(this, "Pick destination", QString());
+  if (fdlg.exec() == QDialog::Accepted)
+    ui->qle_destPath->setText(fdlg.selectedFiles()[0]);
+}
+
+ExportGraphToImageDialog::~ExportGraphToImageDialog()
+{
+  delete ui;
+}
diff --git a/gui/exportgraphtoimagedialog.h b/gui/exportgraphtoimagedialog.h
new file mode 100644 (file)
index 0000000..ff9d087
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef EXPORTGRAPHTOIMAGEDIALOG_H
+#define EXPORTGRAPHTOIMAGEDIALOG_H
+
+#include <unordered_map>
+#include <QtWidgets/QDialog>
+
+namespace Ui {
+  class ExportGraphToImageDialog;
+}
+
+class ExportGraphToImageDialog : public QDialog
+{
+  Q_OBJECT
+
+  typedef std::tuple<double, double, double, double> Bounds;
+
+public:
+  explicit ExportGraphToImageDialog(QList<QByteArray> formats, QWidget* parent = nullptr);
+  ~ExportGraphToImageDialog();
+  void addSignal(const double fromX, const double fromY, const double toX, const double toY, const std::string& key);
+  double fromX() const;
+  double fromY() const;
+  QString imageFormat() const;
+  int imageHeight() const;
+  QString path() const;
+  QString selectedSignal() const;
+  double toX() const;
+  double toY() const;
+  int imageWidth() const;
+
+private:
+  std::unordered_map<std::string, Bounds> m_bounds;
+  std::string m_curKey;
+  std::vector<std::string> m_signalKeys;
+
+  Ui::ExportGraphToImageDialog *ui;
+
+private slots:
+  void checkAndAccept();
+  void changeBounds(const QString& key);
+  void onBrowseClicked();
+
+};
+
+#endif // EXPORTGRAPHTOIMAGEDIALOG_H
diff --git a/gui/exportgraphtoimagedialog.ui b/gui/exportgraphtoimagedialog.ui
new file mode 100644 (file)
index 0000000..4540eb2
--- /dev/null
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ExportGraphToImageDialog</class>
+ <widget class="QDialog" name="ExportGraphToImageDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Export graph to image</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="topMargin">
+    <number>3</number>
+   </property>
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="1" column="1">
+      <widget class="QComboBox" name="qcbox_signal">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="0">
+      <widget class="QLabel" name="ql_destination">
+       <property name="text">
+        <string>Destination:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="ql_signal">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Signal:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="qle_destPath"/>
+     </item>
+     <item row="0" column="2">
+      <widget class="QPushButton" name="qpb_browse">
+       <property name="text">
+        <string>Browse</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="ql_outputFormat">
+       <property name="text">
+        <string>Output format:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QComboBox" name="qcbox_outputFormat"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QGridLayout" name="gridLayout_3">
+     <item row="0" column="0">
+      <widget class="QLabel" name="ql_width">
+       <property name="text">
+        <string>Width:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="qle_width">
+       <property name="text">
+        <string>1000</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QLabel" name="ql_height">
+       <property name="text">
+        <string>Height:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="3">
+      <widget class="QLineEdit" name="qle_height">
+       <property name="text">
+        <string>1000</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="Line" name="line">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QGridLayout" name="gridLayout_2">
+     <item row="0" column="3">
+      <widget class="QLineEdit" name="qle_toX">
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="0">
+      <widget class="QLabel" name="ql_fromX">
+       <property name="text">
+        <string>From X:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QLabel" name="ql_toX">
+       <property name="text">
+        <string>To X:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="qle_fromX">
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="ql_fromY">
+       <property name="text">
+        <string>From Y:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="qle_fromY">
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2">
+      <widget class="QLabel" name="ql_toY">
+       <property name="text">
+        <string>To Y:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="3">
+      <widget class="QLineEdit" name="qle_toY">
+       <property name="alignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="sizeConstraint">
+      <enum>QLayout::SetMinimumSize</enum>
+     </property>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>1</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="qpb_ok">
+       <property name="text">
+        <string>OK</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="qpb_cancel">
+       <property name="text">
+        <string>Cancel</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index 53210bba39b6cf7d2ac70b5273329b95ef8ab0b0..43fd34f701981bbe2770866897a09ab59f4bcd8f 100644 (file)
@@ -73,6 +73,7 @@ void MainWindow::connectActions()
   /* EXPORT menu */
   connect(ui->actionRaw_values, SIGNAL(triggered()), this, SLOT(onExportRawData()));
   connect(ui->actionIntegration_results, SIGNAL(triggered()), this, SLOT(onExportPeaks()));
+  connect(ui->actionGraph_as_image, SIGNAL(triggered()), this, SLOT(onExportGraphToImage()));
   /* HELP menu */
   connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(onAboutAnyanka()));
   /* RUN/SEQ cboxes*/
index e3c42a471e19a1f34586f6f465071efcba3e16dd..663416b11e2397fe84cac7a80ec660af3f8748a1 100644 (file)
@@ -69,6 +69,7 @@ public slots:
 
 private slots:
   void onAboutAnyanka();
+  void onExportGraphToImage() { emit exportGraphToImage(); }
   void onExportPeaks() { emit exportPeaks(); }
   void onExportRawData() { emit exportRawData(); }
   void onIntegrateSelected();
@@ -81,6 +82,7 @@ private slots:
 
 signals:
   void controlModeChanged(GraphControlModes mode);
+  void exportGraphToImage();
   void exportPeaks();
   void exportRawData();
   void loadSequence(const QString& dir);
index 446ddf59690eda2a48a3f5f7149b0261fd306723..3d0bfaa20a5f865a0ea14f2deed06718bc24dd50 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -69,6 +69,7 @@ int main(int argc, char *argv[])
   QObject::connect(dMgr.get(), SIGNAL(setActiveSequenceIndex(int)), mWin.get(), SLOT(onSetActiveSequenceIndex(int)));
   QObject::connect(dMgr.get(), SIGNAL(setActiveSingleRunKey(std::string)), mWin.get(), SLOT(onSetActiveSingleRunKey(std::string)));
   QObject::connect(dMgr.get(), SIGNAL(setSingleRunInfo(QString,QString,QString,QString)), mWin.get(), SLOT(onSetSingleRunInfo(QString,QString,QString,QString)));
+  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(loadSingleRun(QString)), dMgr.get(), SLOT(onLoadSingleRun(QString)));
index 09a8d4fb060e53869e9fd7e1e3c88d319087d62b..f9bb4b979c8d7617abf885884d3d5affa3ca46bb 100644 (file)
--- a/signal.h
+++ b/signal.h
@@ -65,7 +65,6 @@ public:
   std::string resourceToString() const;
   double timeAt(const size_t idx) const;
   double samplingRate() const { return m_samplingRate; }
-  //QString uidString() const;
   double valueAt(const size_t idx) const;
   const std::vector<TimeValuePair>& values() const { return m_values; }
   std::vector<TimeValuePair>::const_iterator valuesBegin() const { return m_values.begin(); }
index 44e62cb277b962d01d7f0acae72d9942c0de2aee..2714860696a0526e11559f6bbea164d218eec6cd 100644 (file)
@@ -44,6 +44,26 @@ SignalController::SignalController(std::shared_ptr<Signal> signal, QObject* pare
   connect(m_ctxMenu.m_acDeletePeak, SIGNAL(triggered()), this, SLOT(onCtxMenuDeletePeak()));
 }
 
+double SignalController::currentStartX() const
+{
+  return m_signal->pairAt(m_fromIdx).first;
+}
+
+double SignalController::currentStartY() const
+{
+  return m_yMin;
+}
+
+double SignalController::currentStopX() const
+{
+  return m_signal->pairAt(m_toIdx).first;
+}
+
+double SignalController::currentStopY() const
+{
+  return m_yMax;
+}
+
 /* Public methods */
 void SignalController::draw()
 {
@@ -75,26 +95,10 @@ void SignalController::drawFullGraph()
 
 void SignalController::drawGraph()
 {
-  double* arr;
-  size_t len;
-
-  if (m_fromIdx > m_toIdx) {
-    Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "From index lower than to index");
-    return;
-  }
-  if (m_fromIdx == m_toIdx)
-    return; //Nothing to zoom to
-  if (m_toIdx >= m_signal->valuesCount() || m_fromIdx >= m_signal->valuesCount()) {
-    Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "Invalid value index");
-    return;
-  }
-  len = m_toIdx - m_fromIdx;
-
-  arr = new double[len];
-  for (uint idx = 0; idx < len; idx++)
-    arr[idx] = m_signal->valueAt(idx + m_fromIdx);
-
-  emit viewDrawGraph(arr, len, m_yMin, m_yMax);
+  size_t len = m_toIdx - m_fromIdx;
+  double* arr = generateDrawData(m_fromIdx, m_toIdx);
+  if (arr != nullptr)
+    emit viewDrawGraph(arr, len, m_yMin, m_yMax);
 }
 
 void SignalController::drawIntegratedPeak(const std::shared_ptr<IntegratedPeak> peak)
@@ -142,6 +146,30 @@ void SignalController::drawIntegratedPeak(const std::shared_ptr<IntegratedPeak>
   emit viewDrawIntegration(fromX, fromY, toX, toY, peak->peakIdx() - m_fromIdx, m_signal->valueAt(peak->peakIdx()), peakTime, peakArea, valley);
 }
 
+double* SignalController::generateDrawData(size_t from, size_t to)
+{
+  double* arr;
+  size_t len;
+
+  if (from > to) {
+    Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "From index lower than to index");
+    return nullptr;
+  }
+  if (from == to)
+    return nullptr;
+  if (to >= m_signal->valuesCount() || from >= m_signal->valuesCount()) {
+    Logger::log(Logger::Level::CRITICAL, ME_SENDER_STR, "Invalid value index");
+    return nullptr;
+  }
+  len = to - from;
+
+  arr = new double[len];
+  for (uint idx = 0; idx < len; idx++)
+    arr[idx] = m_signal->valueAt(idx + from);
+
+  return arr;
+}
+
 bool SignalController::updateConstraints(const int fromX, const int fromY, const int toX, const int toY)
 {
   size_t xRange = m_toIdx - m_fromIdx;
index b11e7580c9bda4c790c3ae47dcfff23ad6b39370..1fae1a2df9d7c48055f10245343e16901b101bce 100644 (file)
@@ -37,8 +37,15 @@ class SignalController : public QObject
 public:
   explicit SignalController(std::shared_ptr<Signal> signal, QObject* parent = nullptr);
   ~SignalController();
+  double currentYMax() const { return m_yMax; }
+  double currentYMin() const { return m_yMin; }
+  double currentStartX() const;
+  double currentStartY() const;
+  double currentStopX() const;
+  double currentStopY() const;
   void draw();
   SignalDataTableModel* dataTableModel() { return m_dtblModel; }
+  double* generateDrawData(size_t from, size_t to);
   IntegrationTableModel* integrationTableModel() { return m_integTblModel;}
   const std::shared_ptr<Signal> signal() const { return m_signal; }
   const std::shared_ptr<Integrator> cIntegrator() const { return m_integrator; }
index c099fa96a52bb7e333512786a1b66fda64586b85..b58529d82a65ff3c9e0db5ae341728f691d1430e 100644 (file)
@@ -37,7 +37,9 @@ 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 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; }
   std::shared_ptr<SignalController> controllerAt(const std::string& key);
   QDate date() const { return m_date; }
   QString dirName() const { return m_dirName; }
@@ -45,7 +47,6 @@ public:
   QString operatorName() const { return m_operatorName; }
   QString sampleInfo() const { return m_sampleInfo; }
   std::shared_ptr<Signal> signalAt(const std::string& key);
-  const std::unordered_map<std::string, std::shared_ptr<Signal>>& allSignals() const { return m_signals; }
   size_t signalCount() const { return m_signals.size(); }
   QTime time() const { return m_time; }