changeset 729:15da3ab3d416 csv-export-dialog

Split export functions into file-type-specific ones; accept various CSV-specific arguments
author Chris Cannam
date Tue, 14 Jan 2020 15:42:46 +0000
parents 2dce002539a0
children 8cf265f9b1b3
files framework/MainWindowBase.cpp framework/MainWindowBase.h
diffstat 2 files changed, 181 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/framework/MainWindowBase.cpp	Fri Jan 10 14:54:43 2020 +0000
+++ b/framework/MainWindowBase.cpp	Tue Jan 14 15:42:46 2020 +0000
@@ -2803,122 +2803,187 @@
     }
 }
 
+//!!! should we pull out the whole export logic into another
+// class?  then we can more reasonably query it for things like
+// "can we export this layer type to this file format? can we
+// export selections, or only the whole layer?"
+
 bool
-MainWindowBase::exportLayerTo(Layer *layer, View *fromView,
-                              MultiSelection *selectionsToWrite,
-                              QString path, QString &error)
+MainWindowBase::exportLayerToSVL(Layer *layer,
+                                 QString path, QString &error)
 {
-    //!!! should we pull out the whole export logic into another
-    // class?  then we can more reasonably query it for things like
-    // "can we export this layer type to this file format? can we
-    // export selections, or only the whole layer?"
-    
     if (QFileInfo(path).suffix() == "") path += ".svl";
 
     QString suffix = QFileInfo(path).suffix().toLower();
 
-    auto model = ModelById::get(layer->getExportModel(fromView));
+    auto model = ModelById::get(layer->getExportModel(nullptr));
     if (!model) {
         error = tr("Internal error: unknown model");
         return false;
     }
 
-    if (suffix == "xml" || suffix == "svl") {
-
-        QFile file(path);
-        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
-            error = tr("Failed to open file %1 for writing").arg(path);
-        } else {
-            QTextStream out(&file);
-            out.setCodec(QTextCodec::codecForName("UTF-8"));
-            out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-                << "<!DOCTYPE sonic-visualiser>\n"
-                << "<sv>\n"
-                << "  <data>\n";
-
-            model->toXml(out, "    ");
-
-            out << "  </data>\n"
-                << "  <display>\n";
-
-            layer->toXml(out, "    ");
-
-            out << "  </display>\n"
-                << "</sv>\n";
+    QFile file(path);
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+        error = tr("Failed to open file %1 for writing").arg(path);
+    } else {
+        QTextStream out(&file);
+        out.setCodec(QTextCodec::codecForName("UTF-8"));
+        out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+            << "<!DOCTYPE sonic-visualiser>\n"
+            << "<sv>\n"
+            << "  <data>\n";
+        
+        model->toXml(out, "    ");
+        
+        out << "  </data>\n"
+            << "  <display>\n";
+        
+        layer->toXml(out, "    ");
+        
+        out << "  </display>\n"
+            << "</sv>\n";
+    }
+
+    return (error == "");
+}
+
+bool
+MainWindowBase::exportLayerToMIDI(Layer *layer,
+                                  MultiSelection *selectionsToWrite,
+                                  QString path, QString &error)
+{
+    if (QFileInfo(path).suffix() == "") path += ".mid";
+
+    QString suffix = QFileInfo(path).suffix().toLower();
+
+    auto model = ModelById::get(layer->getExportModel(nullptr));
+    if (!model) {
+        error = tr("Internal error: unknown model");
+        return false;
+    }
+
+    auto nm = ModelById::getAs<NoteModel>(layer->getModel());
+        
+    if (!nm) {
+        error = tr("Can't export non-note layers to MIDI");
+    } else if (!selectionsToWrite) {
+        MIDIFileWriter writer(path, nm.get(), nm->getSampleRate());
+        writer.write();
+        if (!writer.isOK()) {
+            error = writer.getError();
         }
-
-    } else if (suffix == "mid" || suffix == "midi") {
-
-        auto nm = ModelById::getAs<NoteModel>(layer->getModel());
-
-        if (!nm) {
-            error = tr("Can't export non-note layers to MIDI");
-        } else if (!selectionsToWrite) {
-            MIDIFileWriter writer(path, nm.get(), nm->getSampleRate());
-            writer.write();
-            if (!writer.isOK()) {
-                error = writer.getError();
-            }
-        } else {
-            NoteModel temporary(nm->getSampleRate(),
-                                nm->getResolution(),
-                                nm->getValueMinimum(),
-                                nm->getValueMaximum(),
-                                false);
-            temporary.setScaleUnits(nm->getScaleUnits());
-            for (const auto &s: selectionsToWrite->getSelections()) {
-                EventVector ev(nm->getEventsStartingWithin
-                               (s.getStartFrame(), s.getDuration()));
-                for (const auto &e: ev) {
-                    temporary.add(e);
-                }
-            }
-            MIDIFileWriter writer(path, &temporary, temporary.getSampleRate());
-            writer.write();
-            if (!writer.isOK()) {
-                error = writer.getError();
+    } else {
+        NoteModel temporary(nm->getSampleRate(),
+                            nm->getResolution(),
+                            nm->getValueMinimum(),
+                            nm->getValueMaximum(),
+                            false);
+        temporary.setScaleUnits(nm->getScaleUnits());
+        for (const auto &s: selectionsToWrite->getSelections()) {
+            EventVector ev(nm->getEventsStartingWithin
+                           (s.getStartFrame(), s.getDuration()));
+            for (const auto &e: ev) {
+                temporary.add(e);
             }
         }
-
-    } else if (suffix == "ttl" || suffix == "n3") {
-
-        if (!RDFExporter::canExportModel(model.get())) {
-            error = tr("Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values)");
-        } else {
-            RDFExporter exporter(path, model.get());
-            exporter.write();
-            if (!exporter.isOK()) {
-                error = exporter.getError();
-            }
-        }
-
-    } else {
-
-        ProgressDialog dialog {
-            QObject::tr("Exporting layer..."), true, 500, this,
-            Qt::ApplicationModal
-        };
-            
-        CSVFileWriter writer(path, model.get(), &dialog,
-                             ((suffix == "csv") ? "," : "\t"));
-
-        if (selectionsToWrite) {
-            writer.writeSelection(*selectionsToWrite);
-        } else {
-            writer.write();
-        }
-
+        MIDIFileWriter writer(path, &temporary, temporary.getSampleRate());
+        writer.write();
         if (!writer.isOK()) {
             error = writer.getError();
-            if (error == "") {
-                error = tr("Failed to export layer for an unknown reason");
-            }
         }
     }
-
+    
     return (error == "");
 }
 
+bool
+MainWindowBase::exportLayerToRDF(Layer *layer, 
+                                 QString path, QString &error)
+{
+    if (QFileInfo(path).suffix() == "") path += ".ttl";
+
+    QString suffix = QFileInfo(path).suffix().toLower();
+
+    auto model = ModelById::get(layer->getExportModel(nullptr));
+    if (!model) {
+        error = tr("Internal error: unknown model");
+        return false;
+    }
+    
+    if (!RDFExporter::canExportModel(model.get())) {
+        error = tr("Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values)");
+    } else {
+        RDFExporter exporter(path, model.get());
+        exporter.write();
+        if (!exporter.isOK()) {
+            error = exporter.getError();
+        }
+    }
+
+    return (error == "");
+}
+
+bool
+MainWindowBase::exportLayerToCSV(Layer *layer, LayerGeometryProvider *provider,
+                                 MultiSelection *selectionsToWrite,
+                                 QString delimiter,
+                                 DataExportOptions options,
+                                 QString path, QString &error)
+{
+    if (QFileInfo(path).suffix() == "") path += ".csv";
+
+    QString suffix = QFileInfo(path).suffix().toLower();
+
+    auto model = ModelById::get(layer->getExportModel(provider));
+    if (!model) {
+        error = tr("Internal error: unknown model");
+        return false;
+    }
+
+    ProgressDialog dialog {
+        QObject::tr("Exporting layer..."), true, 500, this,
+        Qt::ApplicationModal
+    };
+            
+    CSVFileWriter writer(path, model.get(), &dialog, delimiter, options);
+
+    if (selectionsToWrite) {
+        writer.writeSelection(*selectionsToWrite);
+    } else {
+        writer.write();
+    }
+
+    if (!writer.isOK()) {
+        error = writer.getError();
+        if (error == "") {
+            error = tr("Failed to export layer for an unknown reason");
+        }
+    }
+
+    return (error == "");
+}
+
+bool
+MainWindowBase::exportLayerTo(Layer *layer, LayerGeometryProvider *provider,
+                              MultiSelection *selectionsToWrite,
+                              QString path, QString &error)
+{
+    if (QFileInfo(path).suffix() == "") path += ".svl";
+    QString suffix = QFileInfo(path).suffix().toLower();
+
+    if (suffix == "xml" || suffix == "svl") {
+        return exportLayerToSVL(layer, path, error);
+    } else if (suffix == "mid" || suffix == "midi") {
+        return exportLayerToMIDI(layer, selectionsToWrite, path, error);
+    } else if (suffix == "ttl" || suffix == "n3") {
+        return exportLayerToRDF(layer, path, error);
+    } else {
+        return exportLayerToCSV(layer, provider, selectionsToWrite,
+                                (suffix == "csv" ? "," : "\t"),
+                                DataExportDefaults, path, error);
+    }
+}
+
 void
 MainWindowBase::toXml(QTextStream &out, bool asTemplate)
 {
--- a/framework/MainWindowBase.h	Fri Jan 10 14:54:43 2020 +0000
+++ b/framework/MainWindowBase.h	Tue Jan 14 15:42:46 2020 +0000
@@ -70,6 +70,7 @@
 class QSignalMapper;
 class QShortcut;
 class AlignmentModel;
+class LayerGeometryProvider;
 
 namespace breakfastquay {
     class SystemPlaybackTarget;
@@ -165,10 +166,28 @@
     virtual bool saveSessionFile(QString path);
     virtual bool saveSessionTemplate(QString path);
 
-    virtual bool exportLayerTo(Layer *layer, View *fromView,
+    virtual bool exportLayerToSVL(Layer *layer,
+                                  QString toPath, QString &error);
+
+    virtual bool exportLayerToMIDI(Layer *layer,
+                                   MultiSelection *selectionsToWrite, // or null
+                                   QString toPath, QString &error);
+
+    virtual bool exportLayerToRDF(Layer *layer,
+                                  QString toPath, QString &error);
+
+    virtual bool exportLayerToCSV(Layer *layer, LayerGeometryProvider *provider,
+                                  MultiSelection *selectionsToWrite, // or null
+                                  QString delimiter,
+                                  DataExportOptions options,
+                                  QString toPath, QString &error);
+
+    // Delegate to one of the above depending on extension of path,
+    // using the default export options
+    virtual bool exportLayerTo(Layer *layer, LayerGeometryProvider *provider,
                                MultiSelection *selectionsToWrite, // or null
                                QString toPath, QString &error);
-
+    
     void cueOSCScript(QString filename);
     
     /// Implementation of FrameTimer interface method