comparison framework/MainWindowBase.cpp @ 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 e2ad6fe768b0
children 16932dfaf64e
comparison
equal deleted inserted replaced
728:2dce002539a0 729:15da3ab3d416
2801 .arg(path).arg(f.what())); 2801 .arg(path).arg(f.what()));
2802 return false; 2802 return false;
2803 } 2803 }
2804 } 2804 }
2805 2805
2806 //!!! should we pull out the whole export logic into another
2807 // class? then we can more reasonably query it for things like
2808 // "can we export this layer type to this file format? can we
2809 // export selections, or only the whole layer?"
2810
2806 bool 2811 bool
2807 MainWindowBase::exportLayerTo(Layer *layer, View *fromView, 2812 MainWindowBase::exportLayerToSVL(Layer *layer,
2808 MultiSelection *selectionsToWrite, 2813 QString path, QString &error)
2809 QString path, QString &error) 2814 {
2810 {
2811 //!!! should we pull out the whole export logic into another
2812 // class? then we can more reasonably query it for things like
2813 // "can we export this layer type to this file format? can we
2814 // export selections, or only the whole layer?"
2815
2816 if (QFileInfo(path).suffix() == "") path += ".svl"; 2815 if (QFileInfo(path).suffix() == "") path += ".svl";
2817 2816
2818 QString suffix = QFileInfo(path).suffix().toLower(); 2817 QString suffix = QFileInfo(path).suffix().toLower();
2819 2818
2820 auto model = ModelById::get(layer->getExportModel(fromView)); 2819 auto model = ModelById::get(layer->getExportModel(nullptr));
2821 if (!model) { 2820 if (!model) {
2822 error = tr("Internal error: unknown model"); 2821 error = tr("Internal error: unknown model");
2823 return false; 2822 return false;
2824 } 2823 }
2825 2824
2826 if (suffix == "xml" || suffix == "svl") { 2825 QFile file(path);
2827 2826 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
2828 QFile file(path); 2827 error = tr("Failed to open file %1 for writing").arg(path);
2829 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
2830 error = tr("Failed to open file %1 for writing").arg(path);
2831 } else {
2832 QTextStream out(&file);
2833 out.setCodec(QTextCodec::codecForName("UTF-8"));
2834 out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
2835 << "<!DOCTYPE sonic-visualiser>\n"
2836 << "<sv>\n"
2837 << " <data>\n";
2838
2839 model->toXml(out, " ");
2840
2841 out << " </data>\n"
2842 << " <display>\n";
2843
2844 layer->toXml(out, " ");
2845
2846 out << " </display>\n"
2847 << "</sv>\n";
2848 }
2849
2850 } else if (suffix == "mid" || suffix == "midi") {
2851
2852 auto nm = ModelById::getAs<NoteModel>(layer->getModel());
2853
2854 if (!nm) {
2855 error = tr("Can't export non-note layers to MIDI");
2856 } else if (!selectionsToWrite) {
2857 MIDIFileWriter writer(path, nm.get(), nm->getSampleRate());
2858 writer.write();
2859 if (!writer.isOK()) {
2860 error = writer.getError();
2861 }
2862 } else {
2863 NoteModel temporary(nm->getSampleRate(),
2864 nm->getResolution(),
2865 nm->getValueMinimum(),
2866 nm->getValueMaximum(),
2867 false);
2868 temporary.setScaleUnits(nm->getScaleUnits());
2869 for (const auto &s: selectionsToWrite->getSelections()) {
2870 EventVector ev(nm->getEventsStartingWithin
2871 (s.getStartFrame(), s.getDuration()));
2872 for (const auto &e: ev) {
2873 temporary.add(e);
2874 }
2875 }
2876 MIDIFileWriter writer(path, &temporary, temporary.getSampleRate());
2877 writer.write();
2878 if (!writer.isOK()) {
2879 error = writer.getError();
2880 }
2881 }
2882
2883 } else if (suffix == "ttl" || suffix == "n3") {
2884
2885 if (!RDFExporter::canExportModel(model.get())) {
2886 error = tr("Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values)");
2887 } else {
2888 RDFExporter exporter(path, model.get());
2889 exporter.write();
2890 if (!exporter.isOK()) {
2891 error = exporter.getError();
2892 }
2893 }
2894
2895 } else { 2828 } else {
2896 2829 QTextStream out(&file);
2897 ProgressDialog dialog { 2830 out.setCodec(QTextCodec::codecForName("UTF-8"));
2898 QObject::tr("Exporting layer..."), true, 500, this, 2831 out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
2899 Qt::ApplicationModal 2832 << "<!DOCTYPE sonic-visualiser>\n"
2900 }; 2833 << "<sv>\n"
2901 2834 << " <data>\n";
2902 CSVFileWriter writer(path, model.get(), &dialog, 2835
2903 ((suffix == "csv") ? "," : "\t")); 2836 model->toXml(out, " ");
2904 2837
2905 if (selectionsToWrite) { 2838 out << " </data>\n"
2906 writer.writeSelection(*selectionsToWrite); 2839 << " <display>\n";
2907 } else { 2840
2908 writer.write(); 2841 layer->toXml(out, " ");
2909 } 2842
2910 2843 out << " </display>\n"
2844 << "</sv>\n";
2845 }
2846
2847 return (error == "");
2848 }
2849
2850 bool
2851 MainWindowBase::exportLayerToMIDI(Layer *layer,
2852 MultiSelection *selectionsToWrite,
2853 QString path, QString &error)
2854 {
2855 if (QFileInfo(path).suffix() == "") path += ".mid";
2856
2857 QString suffix = QFileInfo(path).suffix().toLower();
2858
2859 auto model = ModelById::get(layer->getExportModel(nullptr));
2860 if (!model) {
2861 error = tr("Internal error: unknown model");
2862 return false;
2863 }
2864
2865 auto nm = ModelById::getAs<NoteModel>(layer->getModel());
2866
2867 if (!nm) {
2868 error = tr("Can't export non-note layers to MIDI");
2869 } else if (!selectionsToWrite) {
2870 MIDIFileWriter writer(path, nm.get(), nm->getSampleRate());
2871 writer.write();
2911 if (!writer.isOK()) { 2872 if (!writer.isOK()) {
2912 error = writer.getError(); 2873 error = writer.getError();
2913 if (error == "") { 2874 }
2914 error = tr("Failed to export layer for an unknown reason"); 2875 } else {
2876 NoteModel temporary(nm->getSampleRate(),
2877 nm->getResolution(),
2878 nm->getValueMinimum(),
2879 nm->getValueMaximum(),
2880 false);
2881 temporary.setScaleUnits(nm->getScaleUnits());
2882 for (const auto &s: selectionsToWrite->getSelections()) {
2883 EventVector ev(nm->getEventsStartingWithin
2884 (s.getStartFrame(), s.getDuration()));
2885 for (const auto &e: ev) {
2886 temporary.add(e);
2915 } 2887 }
2916 } 2888 }
2917 } 2889 MIDIFileWriter writer(path, &temporary, temporary.getSampleRate());
2918 2890 writer.write();
2891 if (!writer.isOK()) {
2892 error = writer.getError();
2893 }
2894 }
2895
2919 return (error == ""); 2896 return (error == "");
2897 }
2898
2899 bool
2900 MainWindowBase::exportLayerToRDF(Layer *layer,
2901 QString path, QString &error)
2902 {
2903 if (QFileInfo(path).suffix() == "") path += ".ttl";
2904
2905 QString suffix = QFileInfo(path).suffix().toLower();
2906
2907 auto model = ModelById::get(layer->getExportModel(nullptr));
2908 if (!model) {
2909 error = tr("Internal error: unknown model");
2910 return false;
2911 }
2912
2913 if (!RDFExporter::canExportModel(model.get())) {
2914 error = tr("Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values)");
2915 } else {
2916 RDFExporter exporter(path, model.get());
2917 exporter.write();
2918 if (!exporter.isOK()) {
2919 error = exporter.getError();
2920 }
2921 }
2922
2923 return (error == "");
2924 }
2925
2926 bool
2927 MainWindowBase::exportLayerToCSV(Layer *layer, LayerGeometryProvider *provider,
2928 MultiSelection *selectionsToWrite,
2929 QString delimiter,
2930 DataExportOptions options,
2931 QString path, QString &error)
2932 {
2933 if (QFileInfo(path).suffix() == "") path += ".csv";
2934
2935 QString suffix = QFileInfo(path).suffix().toLower();
2936
2937 auto model = ModelById::get(layer->getExportModel(provider));
2938 if (!model) {
2939 error = tr("Internal error: unknown model");
2940 return false;
2941 }
2942
2943 ProgressDialog dialog {
2944 QObject::tr("Exporting layer..."), true, 500, this,
2945 Qt::ApplicationModal
2946 };
2947
2948 CSVFileWriter writer(path, model.get(), &dialog, delimiter, options);
2949
2950 if (selectionsToWrite) {
2951 writer.writeSelection(*selectionsToWrite);
2952 } else {
2953 writer.write();
2954 }
2955
2956 if (!writer.isOK()) {
2957 error = writer.getError();
2958 if (error == "") {
2959 error = tr("Failed to export layer for an unknown reason");
2960 }
2961 }
2962
2963 return (error == "");
2964 }
2965
2966 bool
2967 MainWindowBase::exportLayerTo(Layer *layer, LayerGeometryProvider *provider,
2968 MultiSelection *selectionsToWrite,
2969 QString path, QString &error)
2970 {
2971 if (QFileInfo(path).suffix() == "") path += ".svl";
2972 QString suffix = QFileInfo(path).suffix().toLower();
2973
2974 if (suffix == "xml" || suffix == "svl") {
2975 return exportLayerToSVL(layer, path, error);
2976 } else if (suffix == "mid" || suffix == "midi") {
2977 return exportLayerToMIDI(layer, selectionsToWrite, path, error);
2978 } else if (suffix == "ttl" || suffix == "n3") {
2979 return exportLayerToRDF(layer, path, error);
2980 } else {
2981 return exportLayerToCSV(layer, provider, selectionsToWrite,
2982 (suffix == "csv" ? "," : "\t"),
2983 DataExportDefaults, path, error);
2984 }
2920 } 2985 }
2921 2986
2922 void 2987 void
2923 MainWindowBase::toXml(QTextStream &out, bool asTemplate) 2988 MainWindowBase::toXml(QTextStream &out, bool asTemplate)
2924 { 2989 {