Mercurial > hg > svapp
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 { |