From 948905a780f642833bb5de408a8776c2380ff3f2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Wed, 27 Nov 2013 19:11:47 +0100 Subject: [PATCH] Generalize data export. --- Anyanka.pro | 12 +-- csvdatawriterbackend.cpp | 57 ++++++++++++++ csvdatawriterbackend.h | 41 ++++++++++ csvrawdatawriter.cpp | 21 ------ csvrawdatawriter.h | 18 ----- datafileexporter.cpp | 146 ++++++++++++++++++++++++++++++++++++ datafileexporter.h | 63 ++++++++++++++++ datamanager.cpp | 52 ++++++++++--- datamanager.h | 1 + datawriterbackend.cpp | 29 +++++++ datawriterbackend.h | 45 +++++++++++ gui/exportrawdatadialog.cpp | 22 ++++++ gui/exportrawdatadialog.h | 22 ++++++ gui/mainwindow.cpp | 1 + gui/mainwindow.h | 2 + main.cpp | 1 + mathhelpers.h | 2 +- rawdataexporter.cpp | 119 ----------------------------- rawdataexporter.h | 39 ---------- rawdatawriter.cpp | 7 -- rawdatawriter.h | 22 ------ signal.h | 1 + 22 files changed, 478 insertions(+), 245 deletions(-) create mode 100644 csvdatawriterbackend.cpp create mode 100644 csvdatawriterbackend.h delete mode 100644 csvrawdatawriter.cpp delete mode 100644 csvrawdatawriter.h create mode 100644 datafileexporter.cpp create mode 100644 datafileexporter.h create mode 100644 datawriterbackend.cpp create mode 100644 datawriterbackend.h delete mode 100644 rawdataexporter.cpp delete mode 100644 rawdataexporter.h delete mode 100644 rawdatawriter.cpp delete mode 100644 rawdatawriter.h diff --git a/Anyanka.pro b/Anyanka.pro index f398720..5d5babe 100644 --- a/Anyanka.pro +++ b/Anyanka.pro @@ -47,9 +47,9 @@ SOURCES += main.cpp\ gui/aboutanyanka.cpp \ globalinfo.cpp \ gui/exportrawdatadialog.cpp \ - rawdataexporter.cpp \ - rawdatawriter.cpp \ - csvrawdatawriter.cpp + datafileexporter.cpp \ + datawriterbackend.cpp \ + csvdatawriterbackend.cpp HEADERS += \ datafilesloader.h \ @@ -77,9 +77,9 @@ HEADERS += \ globalinfo.h \ windows_defines.h \ gui/exportrawdatadialog.h \ - rawdataexporter.h \ - rawdatawriter.h \ - csvrawdatawriter.h + datafileexporter.h \ + datawriterbackend.h \ + csvdatawriterbackend.h FORMS += \ gui/mainwindow.ui \ diff --git a/csvdatawriterbackend.cpp b/csvdatawriterbackend.cpp new file mode 100644 index 0000000..6c8583e --- /dev/null +++ b/csvdatawriterbackend.cpp @@ -0,0 +1,57 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + +#include "csvdatawriterbackend.h" + +CSVDataWriterBackend::CSVDataWriterBackend(QObject* parent) : + DataWriterBackend("csv", parent) +{ + locale = QLocale::system(); +} + +QString CSVDataWriterBackend::header(const QVariantList& data) const +{ + QString line; + + for (const QVariant& v : data) + line += v.toString() + ";"; + + return line + "\n"; +} + +QString CSVDataWriterBackend::filename(const QString& name, const QString& extra) const +{ + QString newname = name; + if (extra.compare("") != 0) + return newname + "_" + extra + "." + FILE_EXTENSION; + else + return newname + "." + FILE_EXTENSION; +} + +QString CSVDataWriterBackend::line(const QVariantList& data) const +{ + QString line; + for (const QVariant& v : data) + line += locale.toString(v.toDouble(), 'g') + ";"; + + return line + "\n"; +} diff --git a/csvdatawriterbackend.h b/csvdatawriterbackend.h new file mode 100644 index 0000000..491dc3b --- /dev/null +++ b/csvdatawriterbackend.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + +#ifndef CSVRAWDATAWRITER_H +#define CSVRAWDATAWRITER_H + +#include "datawriterbackend.h" +#include + +class CSVDataWriterBackend : public DataWriterBackend +{ +public: + CSVDataWriterBackend(QObject* parent = nullptr); + QString header(const QVariantList& data) const; + QString filename(const QString& name, const QString& extra) const; + QString line(const QVariantList& data) const; + +private: + QLocale locale; +}; + +#endif // CSVRAWDATAWRITER_H diff --git a/csvrawdatawriter.cpp b/csvrawdatawriter.cpp deleted file mode 100644 index 8d464c6..0000000 --- a/csvrawdatawriter.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "csvrawdatawriter.h" - -CSVRawDataWriter::CSVRawDataWriter(QObject* parent) : - RawDataWriter("csv", parent) -{ - locale = QLocale::system(); -} - -QString CSVRawDataWriter::filename(const QString& name, const QString& extra) const -{ - QString newname = name; - if (extra.compare("") != 0) - return newname + "_" + extra + "." + FILE_EXTENSION; - else - return newname + "." + FILE_EXTENSION; -} - -QString CSVRawDataWriter::line(const double time, const double value) const -{ - return locale.toString(time) + ";" + locale.toString(value); -} diff --git a/csvrawdatawriter.h b/csvrawdatawriter.h deleted file mode 100644 index 60307b9..0000000 --- a/csvrawdatawriter.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef CSVRAWDATAWRITER_H -#define CSVRAWDATAWRITER_H - -#include "rawdatawriter.h" -#include - -class CSVRawDataWriter : public RawDataWriter -{ -public: - CSVRawDataWriter(QObject* parent = nullptr); - QString filename(const QString& name, const QString& extra) const; - QString line(const double time, const double value) const; - -private: - QLocale locale; -}; - -#endif // CSVRAWDATAWRITER_H diff --git a/datafileexporter.cpp b/datafileexporter.cpp new file mode 100644 index 0000000..ecf507d --- /dev/null +++ b/datafileexporter.cpp @@ -0,0 +1,146 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + +#include "datafileexporter.h" +#include "csvdatawriterbackend.h" +#include +#include +#include + +const QStringList DataFileExporter::SUPPORTED_FORMATS = QStringList() << "Comma separated values (CSV)"; + +DataFileExporter::DataFileExporter(QObject* parent) : + QObject(parent) +{ +} + +/* Public methods */ + +DataFileExporter::ReturnCode DataFileExporter:: +exportData(const WriteList& list, const QString& path, const int formatIdx) +{ + QDir dir(path); + QFile file(path); + QString plainName = file.fileName(); + OutputFormats format; + DataFileExporter::ReturnCode ret; + DataWriterBackend* backend; + + if (formatIdx < 0 || formatIdx >= SUPPORTED_FORMATS.length()) { + QMessageBox::warning(nullptr, "Data export error", "Invalid format selected"); + return ReturnCode::E_TRYAGAIN; + } + + if (path.compare("") == 0) { + QMessageBox::information(nullptr, "Data export error", "No output file specified."); + return ReturnCode::E_TRYAGAIN; + } + if (dir.exists()) { + QMessageBox::information(nullptr, "Data export error", "Selected path points to a directory. Name of output file is required."); + return ReturnCode::E_TRYAGAIN; + } + + if (file.exists()) { + int ret = QMessageBox::question(nullptr, "Data export", "The selected file already exists. Do you wish to overwrite it?"); + if (ret == QMessageBox::No) + return ReturnCode::E_TRYAGAIN; + else + file.remove(); + } + + format = formatIdxToFormat(formatIdx); + switch (format) { + case OutputFormats::CSV: + backend = new CSVDataWriterBackend(this); + break; + } + + if (list.size() > 1) + file.setFileName(backend->filename(plainName, list.cbegin()->first.c_str())); + else + file.setFileName(backend->filename(plainName)); + + /* Export first signal to file */ + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::critical(nullptr, "Data export error", "Cannot open output file for writing."); + delete backend; + return ReturnCode::E_FAILED; + } + + ret = writeToFile(file, backend, list.cbegin()->second); + if (ret != ReturnCode::SUCCESS) { + file.close(); + delete backend; + return ret; + } + + //for (int idx = 1; idx < header.size(); idx++) { + WriteList::const_iterator cit = list.cbegin(); + std::advance(cit, 1); + for (; cit != list.cend(); cit++) { + file.setFileName(backend->filename(plainName, cit->first.c_str())); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::critical(nullptr, "Data export error", "Cannot open output file '" + file.fileName() + "' for writing."); + return ReturnCode::E_FAILED; + } + ret = writeToFile(file, backend, cit->second); + file.close(); + if (ret != ReturnCode::SUCCESS) + break; + } + + delete backend; + return ret; +} + +/* Private methods */ + +DataFileExporter::OutputFormats DataFileExporter::formatIdxToFormat(const int idx) +{ + switch (idx) { + case 0: + return OutputFormats::CSV; + } +} + +DataFileExporter::ReturnCode DataFileExporter::writeToFile(QFile& file, const DataWriterBackend* backend, const std::pair>& data) +{ + QString line; + QByteArray bytes; + qint64 w; + + line = backend->header(data.first); + bytes = line.toUtf8(); + w = file.write(bytes); + if (w < bytes.size()) + return ReturnCode::E_FAILED; + + for (const QVariantList& l : data.second) { + line = backend->line(l); + bytes = line.toUtf8(); + w = file.write(bytes); + if (w < bytes.size()) + return ReturnCode::E_FAILED; + } + + return ReturnCode::SUCCESS; +} diff --git a/datafileexporter.h b/datafileexporter.h new file mode 100644 index 0000000..96b4583 --- /dev/null +++ b/datafileexporter.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + +#ifndef RAWDATAEXPORTER_H +#define RAWDATAEXPORTER_H + +#include "datawriterbackend.h" +#include "signal.h" +#include +#include +#include +#include + +class DataFileExporter : public QObject +{ + Q_OBJECT +public: + enum class ReturnCode { + SUCCESS, + E_TRYAGAIN, + E_FAILED + }; + typedef std::unordered_map>> WriteList; + + explicit DataFileExporter(QObject* parent = nullptr); + ReturnCode exportData(const WriteList& header, const QString& path, const int formatIdx); + + static const QStringList SUPPORTED_FORMATS; +private: + enum class OutputFormats { + CSV + }; + + OutputFormats formatIdxToFormat(const int idx); + QString toCSVLine(double time, double value); + ReturnCode writeToFile(QFile& file, const DataWriterBackend* writer, const std::pair>& data); + +signals: + +public slots: + +}; + +#endif // RAWDATAEXPORTER_H diff --git a/datamanager.cpp b/datamanager.cpp index 240a848..b2440c3 100644 --- a/datamanager.cpp +++ b/datamanager.cpp @@ -22,7 +22,7 @@ #include "datamanager.h" #include "logger.h" -#include "rawdataexporter.h" +#include "datafileexporter.h" #include "gui/exportrawdatadialog.h" #include @@ -284,37 +284,65 @@ void DataManager::showOneSignal(std::shared_ptr ctrl) /* Public slots */ +void DataManager::onExportPeaks() +{ + std::vector> ctrls; + + if (m_activeSequence == nullptr) + return; + if (m_activeSequence->selectedRun() == nullptr) + return; +} + void DataManager::onExportRawData() { - RawDataExporter exporter(this); - ExportRawDataDialog dlg(RawDataExporter::SUPPORTED_FORMATS); - std::vector> sigs; + DataFileExporter exporter(this); + ExportRawDataDialog dlg(DataFileExporter::SUPPORTED_FORMATS); + DataFileExporter::WriteList writeList; + DataFileExporter::ReturnCode ret; if (m_activeSequence == nullptr) return; if (m_activeSequence->selectedRun() == nullptr) return; - for (int idx = 0; idx < m_activeSequence->selectedRun()->signalCount(); idx++) + for (uint idx = 0; idx < m_activeSequence->selectedRun()->signalCount(); idx++) dlg.addAvailableSignal(m_activeSequence->selectedRun()->signalAt(idx)->descriptiveName()); - RawDataExporter::ReturnCode ret; do { int dret = dlg.exec(); if (dret == QDialog::Rejected) return; else if (dret == QDialog::Accepted && dlg.selectedSignalsCount() < 1) { QMessageBox::information(nullptr, "Data export error", "No signals selected"); - ret = RawDataExporter::ReturnCode::E_TRYAGAIN; + ret = DataFileExporter::ReturnCode::E_TRYAGAIN; } else if (dret == QDialog::Accepted && dlg.selectedSignalsCount() >= 1) { - sigs.clear(); + /* Generate data to export */ for (int idx = 0; idx < dlg.signalsCount(); idx++) { - if (dlg.isSignalSelected(idx)) - sigs.push_back(m_activeSequence->selectedRun()->signalAt(idx)); + QVariantList header; + std::vector lines; + std::pair> p; + std::shared_ptr sig; + std::string dname; + if (!dlg.isSignalSelected(idx)) + continue; + + sig = m_activeSequence->selectedRun()->signalAt(idx); + dname = m_activeSequence->selectedRun()->signalAt(idx)->descriptiveName().toStdString(); + + /* Create header */ + header << QString("time [" + sig->xunitToString() + "]") << QString("value [" + sig->yunitToString() + "]"); + for (const Signal::TimeValuePair& tvp : sig->values()) { + QVariantList line; + line << tvp.first << tvp.second; + lines.push_back(line); + } + p = std::pair>(header, lines); + writeList[dname] = p; } - ret = exporter.exportData(sigs, dlg.destination(), dlg.format()); + ret = exporter.exportData(writeList, dlg.destination(), dlg.format()); } - } while (ret == RawDataExporter::ReturnCode::E_TRYAGAIN); + } while (ret == DataFileExporter::ReturnCode::E_TRYAGAIN); } void DataManager::onLoadSequence(const QString& dir) diff --git a/datamanager.h b/datamanager.h index 364621d..def182c 100644 --- a/datamanager.h +++ b/datamanager.h @@ -81,6 +81,7 @@ signals: void setSingleRunInfo(const QString& method, const QString& operatorname, const QString& sample, const QString& datetime); public slots: + void onExportPeaks(); void onExportRawData(); void onLoadSequence(const QString& dir); void onLoadSingleRun(const QString& dir); diff --git a/datawriterbackend.cpp b/datawriterbackend.cpp new file mode 100644 index 0000000..4f5c86e --- /dev/null +++ b/datawriterbackend.cpp @@ -0,0 +1,29 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + +#include "datawriterbackend.h" + +DataWriterBackend::DataWriterBackend(const QString& extension, QObject* parent) : + QObject(parent), + FILE_EXTENSION(extension) +{ +} diff --git a/datawriterbackend.h b/datawriterbackend.h new file mode 100644 index 0000000..9399e2c --- /dev/null +++ b/datawriterbackend.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + +#ifndef DATAFILEWRITER_H +#define DATAFILEWRITER_H + +#include + +class DataWriterBackend : public QObject +{ + Q_OBJECT +public: + explicit DataWriterBackend(const QString& extension, QObject* parent = nullptr); + virtual QString header(const QVariantList& data) const = 0; + virtual QString filename(const QString& name, const QString& extra = QString()) const = 0; + virtual QString line(const QVariantList& data) const = 0; + + const QString FILE_EXTENSION; + +signals: + +public slots: + +}; + +#endif // DATAFILEWRITER_H diff --git a/gui/exportrawdatadialog.cpp b/gui/exportrawdatadialog.cpp index 3a8e1c5..e4817c8 100644 --- a/gui/exportrawdatadialog.cpp +++ b/gui/exportrawdatadialog.cpp @@ -1,3 +1,25 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + #include "exportrawdatadialog.h" #include "ui_exportrawdatadialog.h" #include diff --git a/gui/exportrawdatadialog.h b/gui/exportrawdatadialog.h index ac4b17c..d8c8014 100644 --- a/gui/exportrawdatadialog.h +++ b/gui/exportrawdatadialog.h @@ -1,3 +1,25 @@ +/* + Copyright (c) 2013 Michal Malý + + 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. +*/ + #ifndef EXPORTRAWDATADIALOG_H #define EXPORTRAWDATADIALOG_H diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 7029504..49bf371 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -72,6 +72,7 @@ void MainWindow::connectActions() connect(ui->actionLoad_sequence, SIGNAL(triggered()), this, SLOT(onLoadSequence())); /* EXPORT menu */ connect(ui->actionRaw_values, SIGNAL(triggered()), this, SLOT(onExportRawData())); + connect(ui->actionIntegration_results, SIGNAL(triggered()), this, SLOT(onExportPeaks())); /* HELP menu */ connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(onAboutAnyanka())); /* RUN/SEQ cboxes*/ diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 71d8083..a83bb79 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -69,6 +69,7 @@ public slots: private slots: void onAboutAnyanka(); + void onExportPeaks() { emit exportPeaks(); } void onExportRawData() { emit exportRawData(); } void onIntegrateSelected(); void onLoadSequence(); @@ -80,6 +81,7 @@ private slots: signals: void controlModeChanged(GraphControlModes mode); + void exportPeaks(); void exportRawData(); void loadSequence(const QString& dir); void loadSingleRun(const QString& dir); diff --git a/main.cpp b/main.cpp index b676700..847418d 100644 --- 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(setActiveSingleRunIndex(int)), mWin.get(), SLOT(onSetActiveSingleRunIndex(int))); QObject::connect(dMgr.get(), SIGNAL(setSingleRunInfo(QString,QString,QString,QString)), mWin.get(), SLOT(onSetSingleRunInfo(QString,QString,QString,QString))); + 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))); QObject::connect(mWin.get(), SIGNAL(loadSequence(QString)), dMgr.get(), SLOT(onLoadSequence(QString))); diff --git a/mathhelpers.h b/mathhelpers.h index 9d03215..f2ee3cd 100644 --- a/mathhelpers.h +++ b/mathhelpers.h @@ -25,7 +25,7 @@ template T average(T* vals, size_t len) { T sum = 0; - for (int i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) sum += vals[i]; return sum / len; } diff --git a/rawdataexporter.cpp b/rawdataexporter.cpp deleted file mode 100644 index 08dd391..0000000 --- a/rawdataexporter.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "rawdataexporter.h" -#include "csvrawdatawriter.h" -#include -#include -#include - -const QStringList RawDataExporter::SUPPORTED_FORMATS = QStringList() << "Comma separated values (CSV)"; - -RawDataExporter::RawDataExporter(QObject* parent) : - QObject(parent) -{ -} - -/* Public methods */ - -RawDataExporter::ReturnCode RawDataExporter::exportData(const std::vector> sigs, const QString& path, const int formatIdx) -{ - QDir dir(path); - QFile file(path); - QString plainName = file.fileName(); - OutputFormats format; - RawDataExporter::ReturnCode ret; - RawDataWriter* writer; - - if (formatIdx < 0 || formatIdx >= SUPPORTED_FORMATS.length()) { - QMessageBox::warning(nullptr, "Data export error", "Invalid format selected"); - return ReturnCode::E_TRYAGAIN; - } - - if (path.compare("") == 0) { - QMessageBox::information(nullptr, "Data export error", "No output file specified."); - return ReturnCode::E_TRYAGAIN; - } - if (dir.exists()) { - QMessageBox::information(nullptr, "Data export error", "Selected path points to a directory. Name of output file is required."); - return ReturnCode::E_TRYAGAIN; - } - - if (file.exists()) { - int ret = QMessageBox::question(nullptr, "Data export", "The selected file already exists. Do you wish to overwrite it?"); - if (ret == QMessageBox::No) - return ReturnCode::E_TRYAGAIN; - else - file.remove(); - } - - format = formatIdxToFormat(formatIdx); - switch (format) { - case OutputFormats::CSV: - writer = new CSVRawDataWriter(this); - break; - } - - if (sigs.size() > 1) - file.setFileName(writer->filename(plainName, sigs.at(0)->descriptiveName())); - else - file.setFileName(writer->filename(plainName)); - - /* Export first signal to file */ - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - QMessageBox::critical(nullptr, "Data export error", "Cannot open output file for writing."); - delete writer; - return ReturnCode::E_FAILED; - } - - ret = writeToFile(file, writer, sigs.at(0)); - if (ret != ReturnCode::SUCCESS) { - file.close(); - delete writer; - return ret; - } - - for (int idx = 1; idx < sigs.size(); idx++) { - file.setFileName(writer->filename(plainName, sigs.at(idx)->descriptiveName())); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - QMessageBox::critical(nullptr, "Data export error", "Cannot open output file '" + file.fileName() + "' for writing."); - return ReturnCode::E_FAILED; - } - ret = writeToFile(file, writer, sigs.at(idx)); - file.close(); - if (ret != ReturnCode::SUCCESS) - break; - } - - delete writer; - return ret; -} - -/* Private methods */ - -RawDataExporter::OutputFormats RawDataExporter::formatIdxToFormat(const int idx) -{ - switch (idx) { - case 0: - return OutputFormats::CSV; - } -} - -RawDataExporter::ReturnCode RawDataExporter::writeToFile(QFile& file, const RawDataWriter* writer, const std::shared_ptr signal) -{ - QString line; - QByteArray bytes; - qint64 w; - - bytes = QString("time;value\n").toUtf8(); - w = file.write(bytes); - if (w < bytes.size()) - return ReturnCode::E_FAILED; - - for (int idx = 0; idx < signal->valuesCount(); idx++) { - line = writer->line(signal->timeAt(idx), signal->valueAt(idx)); - bytes = line.toUtf8(); - w = file.write(bytes); - if (w < bytes.size()) - return ReturnCode::E_FAILED; - } - - return ReturnCode::SUCCESS; -} diff --git a/rawdataexporter.h b/rawdataexporter.h deleted file mode 100644 index 00bff2f..0000000 --- a/rawdataexporter.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef RAWDATAEXPORTER_H -#define RAWDATAEXPORTER_H - -#include "rawdatawriter.h" -#include "signal.h" -#include -#include -#include - -class RawDataExporter : public QObject -{ - Q_OBJECT -public: - enum class ReturnCode { - SUCCESS, - E_TRYAGAIN, - E_FAILED - }; - - explicit RawDataExporter(QObject* parent = nullptr); - ReturnCode exportData(std::vector> sigs, const QString& path, const int formatIdx); - - static const QStringList SUPPORTED_FORMATS; -private: - enum class OutputFormats { - CSV - }; - - OutputFormats formatIdxToFormat(const int idx); - QString toCSVLine(double time, double value); - ReturnCode writeToFile(QFile& file, const RawDataWriter* writer, const std::shared_ptr signal); - -signals: - -public slots: - -}; - -#endif // RAWDATAEXPORTER_H diff --git a/rawdatawriter.cpp b/rawdatawriter.cpp deleted file mode 100644 index d3dbd4c..0000000 --- a/rawdatawriter.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "rawdatawriter.h" - -RawDataWriter::RawDataWriter(const QString& extension, QObject* parent) : - QObject(parent), - FILE_EXTENSION(extension) -{ -} diff --git a/rawdatawriter.h b/rawdatawriter.h deleted file mode 100644 index 59daa97..0000000 --- a/rawdatawriter.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef RAWDATAWRITER_H -#define RAWDATAWRITER_H - -#include - -class RawDataWriter : public QObject -{ - Q_OBJECT -public: - explicit RawDataWriter(const QString& extension, QObject* parent = nullptr); - virtual QString filename(const QString& name, const QString& extra = QString()) const = 0; - virtual QString line(const double time, const double value) const = 0; - - const QString FILE_EXTENSION; - -signals: - -public slots: - -}; - -#endif // RAWDATAWRITER_H diff --git a/signal.h b/signal.h index fd30f17..3423094 100644 --- a/signal.h +++ b/signal.h @@ -67,6 +67,7 @@ public: double samplingRate() const { return m_samplingRate; } QString uidString() const; double valueAt(const size_t idx) const; + const std::vector& values() const { return m_values; } std::vector::const_iterator valuesBegin() const { return m_values.begin(); } size_t valuesCount() const { return m_values.size(); } std::vector::const_iterator valuesEnd() const { return m_values.end(); } -- 2.43.5