From: Michal Malý Date: Wed, 27 Nov 2013 18:11:47 +0000 (+0100) Subject: Generalize data export. X-Git-Tag: 0.2a~11 X-Git-Url: https://gitweb.devoid-pointer.net/?a=commitdiff_plain;h=948905a780f642833bb5de408a8776c2380ff3f2;p=anyanka.git Generalize data export. --- 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(); }