From 7efc19692fbfb2b4b97cc602346b9096e93528ae Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Sat, 15 Mar 2014 18:28:35 +0100 Subject: [PATCH] Guess output type by file extension --- Anyanka.pro | 4 +-- csvdatawriterbackend.cpp | 15 +++++++++++- datafileexporter.cpp | 42 ++++++++++++++++++++++++++++++-- datafileexporter.h | 8 +++++- datamanager.cpp | 10 +++++++- gui/exportgraphtoimagedialog.cpp | 14 ++++++++++- gui/exportgraphtoimagedialog.h | 7 ++++++ gui/exportrawdatadialog.cpp | 12 +++++++++ gui/exportrawdatadialog.h | 6 +++++ gui/graphview.h | 2 +- gui/signalview.cpp | 2 +- mathhelpers.h => helpers.h | 21 +++++++++++++--- imagedrawer.cpp | 28 ++++++++++++++++++++- imagedrawer.h | 14 ++++++++--- 14 files changed, 167 insertions(+), 18 deletions(-) rename mathhelpers.h => helpers.h (78%) diff --git a/Anyanka.pro b/Anyanka.pro index 23bccc1..768d7f2 100644 --- a/Anyanka.pro +++ b/Anyanka.pro @@ -68,7 +68,6 @@ HEADERS += \ gui/graphview.h \ signalcontroller.h \ metatypes.h \ - mathhelpers.h \ integratedpeak.h \ sequence.h \ sequenceselectormodel.h \ @@ -88,7 +87,8 @@ HEADERS += \ imagedrawer.h \ signaldrawer.h \ enumflags.h \ - jsonserializable.h + jsonserializable.h \ + helpers.h FORMS += \ gui/mainwindow.ui \ diff --git a/csvdatawriterbackend.cpp b/csvdatawriterbackend.cpp index 5b4e89f..1372426 100644 --- a/csvdatawriterbackend.cpp +++ b/csvdatawriterbackend.cpp @@ -41,7 +41,20 @@ QString CSVDataWriterBackend::header(const QVariantList& data) const QString CSVDataWriterBackend::filename(const QString& name, const QString& extra) const { - QString newname = name; + + QString newname; + int dotIdx; + + dotIdx = name.lastIndexOf('.'); + if (dotIdx > 0) { + QString suffix = name.mid(dotIdx+1).toLower(); + if (suffix.compare(FILE_EXTENSION) == 0) + newname = name.mid(0, dotIdx-1); /* Cut the suffix */ + else + newname = name; + } else + newname = name; + if (extra.compare("") != 0) return newname + "_" + extra + "." + FILE_EXTENSION; else diff --git a/datafileexporter.cpp b/datafileexporter.cpp index 72d8f87..536152f 100644 --- a/datafileexporter.cpp +++ b/datafileexporter.cpp @@ -23,11 +23,26 @@ #include "datafileexporter.h" #include "csvdatawriterbackend.h" +#include "helpers.h" #include #include #include -const QStringList DataFileExporter::SUPPORTED_FORMATS = QStringList() << "Comma separated values (CSV)"; +#include + +const std::vector DataFileExporter::SUPPORTED_FORMATS = { OutputFormat("Comma separated values", "csv") }; + +/* Static methods */ +QStringList DataFileExporter::supportedFormats() +{ + QStringList list; + + for (const OutputFormat& of : SUPPORTED_FORMATS) { + list << of.first; + } + + return list; +} DataFileExporter::DataFileExporter(QObject* parent) : QObject(parent) @@ -46,7 +61,7 @@ exportData(const WriteList& list, const QString& path, const int formatIdx) DataFileExporter::ReturnCode ret; DataWriterBackend* backend; - if (formatIdx < 0 || formatIdx >= SUPPORTED_FORMATS.length()) { + if (formatIdx < 0 || formatIdx >= SUPPORTED_FORMATS.size()) { return ReturnCode::E_INVAL_FORMAT; } @@ -70,6 +85,8 @@ exportData(const WriteList& list, const QString& path, const int formatIdx) case OutputFormats::CSV: backend = new CSVDataWriterBackend(this); break; + default: + return ReturnCode::E_INVAL_FORMAT; } if (list.size() > 1) @@ -141,3 +158,24 @@ DataFileExporter::ReturnCode DataFileExporter::writeToFile(QFile& file, const Da return ReturnCode::SUCCESS; } + +/** Public slots **/ + +void DataFileExporter::guessFormatFromSuffix(const QString& name) +{ + QString suffix = getFileNameSuffix(name); + + if (suffix.length() == 0) + return; + + for (size_t i = 0; i < SUPPORTED_FORMATS.size(); i++) { + const OutputFormat& of = SUPPORTED_FORMATS.at(i); + if (suffix.compare(of.second) == 0) { + qDebug() << "Changing format to idx" << i; + emit formatChanged(i); + return; + } + } + + qDebug() << "Cannot guess type from suffix"; +} diff --git a/datafileexporter.h b/datafileexporter.h index ab99c18..c766577 100644 --- a/datafileexporter.h +++ b/datafileexporter.h @@ -31,6 +31,8 @@ #include #include +typedef std::pair OutputFormat; + class DataFileExporter : public QObject { Q_OBJECT @@ -48,7 +50,7 @@ public: explicit DataFileExporter(QObject* parent = nullptr); ReturnCode exportData(const WriteList& header, const QString& path, const int formatIdx); - static const QStringList SUPPORTED_FORMATS; + static QStringList supportedFormats(); private: enum class OutputFormats { CSV @@ -58,9 +60,13 @@ private: QString toCSVLine(double time, double value); ReturnCode writeToFile(QFile& file, const DataWriterBackend* writer, const std::pair>& data); + static const std::vector SUPPORTED_FORMATS; + signals: + void formatChanged(const int idx); public slots: + void guessFormatFromSuffix(const QString& name); }; diff --git a/datamanager.cpp b/datamanager.cpp index 3d624ef..e3fd161 100644 --- a/datamanager.cpp +++ b/datamanager.cpp @@ -186,11 +186,13 @@ Signal::Equipment DataManager::equipmentFromFiletype(AGRE_Filetype filetype) void DataManager::processDataExport(GeneratorFunc genfunc) { DataFileExporter exporter(this); - ExportRawDataDialog dlg(DataFileExporter::SUPPORTED_FORMATS); + ExportRawDataDialog dlg(DataFileExporter::supportedFormats()); DataFileExporter::WriteList writeList; std::shared_ptr sr = m_activeSequence->selectedRun(); int ret = 1; + connect(&dlg, SIGNAL(fileNameChanged(QString)), &exporter, SLOT(guessFormatFromSuffix(QString))); + connect(&exporter, SIGNAL(formatChanged(int)), &dlg, SLOT(onFormatChanged(int))); for (const std::string& s : sr->allKeys()) dlg.addAvailableSignal(QString::fromStdString(s)); @@ -449,6 +451,12 @@ void DataManager::onExportGraphToImage() if (sr == nullptr) return; + connect(&dlg, &ExportGraphToImageDialog::fileNameChanged, [&dlg, this](const QString& name) { + int idx = ImageDrawer::guessFormatFromSuffix(name); + if (idx > 0) + dlg.onFormatChanged(idx); + }); + for (const std::pair>& p : sr->allControllers()) { GUIViewport vp = p.second->guiViewport(); dlg.addSignal(vp.absFromTime, vp.absFromValue, vp.absToTime, vp.absToValue, p.first); diff --git a/gui/exportgraphtoimagedialog.cpp b/gui/exportgraphtoimagedialog.cpp index 633c4ff..c16bb3f 100644 --- a/gui/exportgraphtoimagedialog.cpp +++ b/gui/exportgraphtoimagedialog.cpp @@ -42,6 +42,7 @@ ExportGraphToImageDialog::ExportGraphToImageDialog(QList formats, QW 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))); + connect(ui->qle_destPath, SIGNAL(textChanged(QString)), this, SLOT(onFileNameChanged(QString))); } void ExportGraphToImageDialog::addSignal(const double fromX, const double fromY, const double toX, const double toY, const std::string& key) @@ -125,7 +126,13 @@ int ExportGraphToImageDialog::imageWidth() const return w; } -/* Private slots */ +/** Public slots **/ +void ExportGraphToImageDialog::onFormatChanged(const int idx) +{ + ui->qcbox_outputFormat->setCurrentIndex(idx); +} + +/** Private slots **/ void ExportGraphToImageDialog::changeBounds(const QString& key) { @@ -194,6 +201,11 @@ void ExportGraphToImageDialog::onBrowseClicked() ui->qle_destPath->setText(fdlg.selectedFiles()[0]); } +void ExportGraphToImageDialog::onFileNameChanged(const QString& name) +{ + emit fileNameChanged(name); +} + ExportGraphToImageDialog::~ExportGraphToImageDialog() { delete ui; diff --git a/gui/exportgraphtoimagedialog.h b/gui/exportgraphtoimagedialog.h index cc1224f..64b2212 100644 --- a/gui/exportgraphtoimagedialog.h +++ b/gui/exportgraphtoimagedialog.h @@ -59,10 +59,17 @@ private: Ui::ExportGraphToImageDialog *ui; +public slots: + void onFormatChanged(const int idx); + private slots: void checkAndAccept(); void changeBounds(const QString& key); void onBrowseClicked(); + void onFileNameChanged(const QString& name); + +signals: + void fileNameChanged(const QString& name); }; diff --git a/gui/exportrawdatadialog.cpp b/gui/exportrawdatadialog.cpp index f5441a7..bb7230a 100644 --- a/gui/exportrawdatadialog.cpp +++ b/gui/exportrawdatadialog.cpp @@ -37,6 +37,7 @@ ExportRawDataDialog::ExportRawDataDialog(const QStringList& supportedFormats, QW connect(ui->qpb_browse, SIGNAL(clicked()), this, SLOT(onBrowseClicked())); connect(ui->qpb_ok, SIGNAL(clicked()), this, SLOT(accept())); connect(ui->qpb_cancel, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->qle_destPath, SIGNAL(textChanged(QString)), this, SLOT(onFileNameChanged(QString))); } /* Public functions */ @@ -79,6 +80,12 @@ std::vector ExportRawDataDialog::selectedSignalKeys() const return kl; } +/* Public slots */ +void ExportRawDataDialog::onFormatChanged(const int idx) +{ + ui->qcbox_formats->setCurrentIndex(idx); +} + /* Private slots */ void ExportRawDataDialog::onBrowseClicked() @@ -88,6 +95,11 @@ void ExportRawDataDialog::onBrowseClicked() ui->qle_destPath->setText(fdlg.selectedFiles()[0]); } +void ExportRawDataDialog::onFileNameChanged(const QString& name) +{ + emit fileNameChanged(name); +} + ExportRawDataDialog::~ExportRawDataDialog() { delete ui; diff --git a/gui/exportrawdatadialog.h b/gui/exportrawdatadialog.h index 2b5581e..b232c41 100644 --- a/gui/exportrawdatadialog.h +++ b/gui/exportrawdatadialog.h @@ -51,9 +51,15 @@ private: QStringList m_supportedFormats; Ui::ExportRawDataDialog* ui; +public slots: + void onFormatChanged(const int idx); + private slots: void onBrowseClicked(); + void onFileNameChanged(const QString& name); +signals: + void fileNameChanged(const QString& name); }; #endif // EXPORTRAWDATADIALOG_H diff --git a/gui/graphview.h b/gui/graphview.h index 2d0bd75..9e44c0e 100644 --- a/gui/graphview.h +++ b/gui/graphview.h @@ -26,7 +26,7 @@ #include "gui/graphviewcontextmenu.h" #include "signaldrawer.h" -#include "mathhelpers.h" +#include "helpers.h" #include "metatypes.h" #include #include diff --git a/gui/signalview.cpp b/gui/signalview.cpp index c1da218..2b8d620 100644 --- a/gui/signalview.cpp +++ b/gui/signalview.cpp @@ -23,7 +23,7 @@ #include "gui/signalview.h" #include "ui_signalview.h" -#include "mathhelpers.h" +#include "helpers.h" #include #include #include diff --git a/mathhelpers.h b/helpers.h similarity index 78% rename from mathhelpers.h rename to helpers.h index 5c2ca7a..c3b889a 100644 --- a/mathhelpers.h +++ b/helpers.h @@ -21,21 +21,34 @@ */ -#ifndef MATHHELPERS_H -#define MATHHELPERS_H +#ifndef HELPERS_H +#define HELPERS_H -template T average(T* vals, size_t len) { +#include + +template static T average(T* vals, size_t len) { T sum = 0; for (size_t i = 0; i < len; i++) sum += vals[i]; return sum / len; } -template T clamp(T in, T min, T max) { +template static T clamp(T in, T min, T max) { if (in < min) return min; if (in > max) return max; } +static QString getFileNameSuffix(const QString& name) +{ + int dotIdx = name.lastIndexOf('.'); + + if (dotIdx < 0) + return ""; + + return name.mid(dotIdx+1).toLower(); +} + + #endif // MATHHELPERS_H diff --git a/imagedrawer.cpp b/imagedrawer.cpp index a8806be..8f2a676 100644 --- a/imagedrawer.cpp +++ b/imagedrawer.cpp @@ -21,13 +21,16 @@ */ +#include "helpers.h" #include "imagedrawer.h" #include #include + #include -ImageDrawer::ImageDrawer(std::shared_ptr controller) : +ImageDrawer::ImageDrawer(std::shared_ptr controller, QObject* parent) : + QObject(parent), SignalDrawer(controller), m_controller(controller) { @@ -40,6 +43,9 @@ ImageDrawer::ReturnCode ImageDrawer::render(const QString& filename, const QByte QImage image; QFile file(filename); + if (m_controller == nullptr) + return ReturnCode::E_NO_CONTROLLER; + if (!setDimensions(width, height)) return ReturnCode::E_INVAL_DIMENSIONS; if (!draw(fromX, fromY, toX, toY, layers)) @@ -69,3 +75,23 @@ QList ImageDrawer::supportedImageFormats() { return QImageWriter::supportedImageFormats(); } + +int ImageDrawer::guessFormatFromSuffix(const QString& name) +{ + QList formats = ImageDrawer::supportedImageFormats(); + QString suffix = getFileNameSuffix(name); + + if (suffix.length() == 0) + return -1; + + for (int i = 0; i < formats.size(); i++) { + const QString f = QString(formats.at(i)); + if (suffix.compare(f) == 0) { + qDebug() << "Changing format to idx" << i << ", type" << f; + return i; + } + } + + qDebug() << "Cannot guess type from suffix"; + return -1; +} diff --git a/imagedrawer.h b/imagedrawer.h index 2b1b237..f3f91ed 100644 --- a/imagedrawer.h +++ b/imagedrawer.h @@ -24,31 +24,39 @@ #ifndef IMAGEDRAWER_H #define IMAGEDRAWER_H +#include "gui/exportgraphtoimagedialog.h" #include "signaldrawer.h" #include -class ImageDrawer : protected SignalDrawer +class ImageDrawer : public QObject, protected SignalDrawer { + Q_OBJECT public: enum class ReturnCode { SUCCESS, - E_INVAL_DIMENSIONS, E_CANNOT_DRAW, E_CANNOT_CREATE_IMAGE, E_CANNOT_WRITE_IMAGE, + E_INVAL_DIMENSIONS, + E_NO_CONTROLLER, E_WOULD_OVERWRITE }; - explicit ImageDrawer(std::shared_ptr controller); + explicit ImageDrawer(std::shared_ptr controller, QObject* parent = nullptr); ReturnCode render(const QString& filename, const QByteArray format, const int width, const int height, const double fromX, const double fromY, const double toX, const double toY, const GraphLayers layers); + static int guessFormatFromSuffix(const QString& name); static QList supportedImageFormats(); private: std::shared_ptr m_controller; QImageWriter m_imageWriter; +public slots: + +signals: + void formatChanged(const int idx); }; -- 2.43.5