annotate data/fileio/CSVFileWriter.cpp @ 1833:21c792334c2e sensible-delimited-data-strings

Rewrite all the DelimitedDataString stuff so as to return vectors of individual cell strings rather than having the classes add the delimiters themselves. Rename accordingly to names based on StringExport. Take advantage of this in the CSV writer code so as to properly quote cells that contain delimiter characters.
author Chris Cannam
date Fri, 03 Apr 2020 17:11:05 +0100
parents fd5a87f3c5b4
children
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@148 7 This file copyright 2006 Chris Cannam.
Chris@148 8
Chris@148 9 This program is free software; you can redistribute it and/or
Chris@148 10 modify it under the terms of the GNU General Public License as
Chris@148 11 published by the Free Software Foundation; either version 2 of the
Chris@148 12 License, or (at your option) any later version. See the file
Chris@148 13 COPYING included with this distribution for more information.
Chris@148 14 */
Chris@148 15
Chris@148 16 #include "CSVFileWriter.h"
dev@1436 17 #include "CSVStreamWriter.h"
Chris@148 18
Chris@150 19 #include "model/Model.h"
Chris@148 20 #include "model/SparseOneDimensionalModel.h"
Chris@148 21 #include "model/SparseTimeValueModel.h"
Chris@148 22 #include "model/NoteModel.h"
Chris@148 23 #include "model/TextModel.h"
Chris@148 24
Chris@675 25 #include "base/TempWriteFile.h"
Chris@675 26 #include "base/Exceptions.h"
Chris@839 27 #include "base/Selection.h"
Chris@675 28
Chris@148 29 #include <QFile>
Chris@148 30 #include <QTextStream>
dev@1436 31 #include <exception>
Chris@148 32
Chris@1063 33 CSVFileWriter::CSVFileWriter(QString path,
Chris@1063 34 Model *model,
Chris@1063 35 QString delimiter,
Chris@1063 36 DataExportOptions options) :
Chris@148 37 m_path(path),
Chris@148 38 m_model(model),
Chris@148 39 m_error(""),
Chris@1063 40 m_delimiter(delimiter),
Chris@1063 41 m_options(options)
Chris@148 42 {
Chris@148 43 }
Chris@148 44
Chris@148 45 CSVFileWriter::~CSVFileWriter()
Chris@148 46 {
Chris@148 47 }
Chris@148 48
Chris@148 49 bool
Chris@148 50 CSVFileWriter::isOK() const
Chris@148 51 {
Chris@148 52 return m_error == "";
Chris@148 53 }
Chris@148 54
Chris@148 55 QString
Chris@148 56 CSVFileWriter::getError() const
Chris@148 57 {
Chris@148 58 return m_error;
Chris@148 59 }
Chris@148 60
Chris@148 61 void
Chris@148 62 CSVFileWriter::write()
Chris@148 63 {
dev@1436 64 Selection all {
dev@1436 65 m_model->getStartFrame(),
dev@1436 66 m_model->getEndFrame()
dev@1436 67 };
dev@1436 68 MultiSelection selections;
dev@1436 69 selections.addSelection(all);
cannam@1452 70 writeSelection(selections);
Chris@148 71 }
Chris@148 72
Chris@839 73 void
cannam@1452 74 CSVFileWriter::writeSelection(MultiSelection selection)
Chris@839 75 {
Chris@839 76 try {
Chris@839 77 TempWriteFile temp(m_path);
Chris@148 78
Chris@839 79 QFile file(temp.getTemporaryFilename());
Chris@839 80 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
Chris@839 81 m_error = tr("Failed to open file %1 for writing")
Chris@839 82 .arg(temp.getTemporaryFilename());
Chris@839 83 return;
Chris@839 84 }
Chris@839 85
Chris@839 86 QTextStream out(&file);
Chris@839 87
Chris@1816 88 if (m_options & DataExportIncludeHeader) {
Chris@1833 89 out << StringBits::joinDelimited
Chris@1833 90 (m_model->getStringExportHeaders(m_options),
Chris@1833 91 m_delimiter)
Chris@1816 92 << endl;
Chris@1816 93 }
Chris@1815 94
cannam@1452 95 sv_frame_t blockSize = 65536;
cannam@1452 96
cannam@1452 97 if (m_model->isSparse()) {
cannam@1452 98 // Write the whole in one go, as re-seeking for each block
cannam@1452 99 // may be very costly otherwise
cannam@1452 100 sv_frame_t startFrame, endFrame;
cannam@1452 101 selection.getExtents(startFrame, endFrame);
cannam@1452 102 blockSize = endFrame - startFrame;
cannam@1452 103 }
cannam@1452 104
dev@1445 105 bool completed = CSVStreamWriter::writeInChunks(
dev@1445 106 out,
dev@1445 107 *m_model,
cannam@1452 108 selection,
dev@1445 109 m_reporter,
dev@1445 110 m_delimiter,
cannam@1452 111 m_options,
cannam@1452 112 blockSize
dev@1442 113 );
Chris@839 114
Chris@839 115 file.close();
dev@1436 116 if (completed) {
dev@1436 117 temp.moveToTarget();
dev@1436 118 }
Chris@839 119
Chris@839 120 } catch (FileOperationFailed &f) {
Chris@839 121 m_error = f.what();
dev@1436 122 } catch (const std::exception &e) { // ProgressReporter could throw
dev@1436 123 m_error = e.what();
Chris@839 124 }
Chris@839 125 }