annotate data/fileio/CSVStreamWriter.h @ 1552:05c3fbaec8ea

Introduce RelativelyFineZoomConstraint, which encodes more-or-less the scheme that was already used for the horizontal thumbwheel in the pane (which overrode the layers' own zoom constraints unless they said they couldn't support any other)
author Chris Cannam
date Wed, 10 Oct 2018 14:32:34 +0100
parents 743c38b209d0
children 560453546749
rev   line source
dev@1430 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
dev@1430 2
dev@1430 3 /*
dev@1430 4 Sonic Visualiser
dev@1430 5 An audio file viewer and annotation editor.
dev@1430 6 Centre for Digital Music, Queen Mary, University of London.
dev@1438 7 This file copyright 2017 Queen Mary, University of London.
dev@1430 8
dev@1430 9 This program is free software; you can redistribute it and/or
dev@1430 10 modify it under the terms of the GNU General Public License as
dev@1430 11 published by the Free Software Foundation; either version 2 of the
dev@1430 12 License, or (at your option) any later version. See the file
dev@1430 13 COPYING included with this distribution for more information.
dev@1430 14 */
dev@1430 15
cannam@1452 16 #ifndef SV_CSV_STREAM_WRITER_H
cannam@1452 17 #define SV_CSV_STREAM_WRITER_H
dev@1430 18
dev@1434 19 #include "base/BaseTypes.h"
dev@1434 20 #include "base/Selection.h"
dev@1434 21 #include "base/ProgressReporter.h"
dev@1434 22 #include "base/DataExportOptions.h"
dev@1434 23 #include "data/model/Model.h"
dev@1434 24 #include <QString>
dev@1434 25 #include <algorithm>
dev@1445 26 #include <numeric>
dev@1441 27
dev@1438 28 namespace CSVStreamWriter
dev@1430 29 {
dev@1430 30
dev@1445 31 template <class OutStream>
dev@1445 32 bool
dev@1445 33 writeInChunks(OutStream& oss,
dev@1445 34 const Model& model,
dev@1445 35 const MultiSelection& regions,
dev@1445 36 ProgressReporter* reporter = nullptr,
dev@1445 37 QString delimiter = ",",
dev@1445 38 DataExportOptions options = DataExportDefaults,
dev@1445 39 const sv_frame_t blockSize = 16384)
dev@1445 40 {
dev@1447 41 const auto selections = regions.getSelections();
dev@1447 42 if (blockSize <= 0 || selections.empty()) return false;
dev@1445 43
dev@1445 44 // TODO, some form of checking validity of selections?
dev@1445 45 const auto nFramesToWrite = std::accumulate(
dev@1447 46 selections.begin(),
dev@1447 47 selections.end(),
dev@1445 48 0,
dev@1445 49 [](sv_frame_t acc, const Selection& current) -> sv_frame_t {
dev@1445 50 return acc + (current.getEndFrame() - current.getStartFrame());
dev@1445 51 }
dev@1445 52 );
dev@1447 53 const auto finalFrameOfLastRegion = (*selections.crbegin()).getEndFrame();
dev@1445 54
dev@1445 55 const auto wasCancelled = [&reporter]() {
dev@1445 56 return reporter && reporter->wasCancelled();
dev@1445 57 };
dev@1445 58
dev@1445 59 sv_frame_t nFramesWritten = 0;
dev@1445 60 int previousProgress = 0;
dev@1445 61
dev@1447 62 for (const auto& extents : selections) {
dev@1445 63 const auto startFrame = extents.getStartFrame();
dev@1445 64 const auto endFrame = extents.getEndFrame();
dev@1445 65 auto readPtr = startFrame;
dev@1445 66 while (readPtr < endFrame) {
dev@1445 67 if (wasCancelled()) return false;
dev@1445 68
dev@1445 69 const auto start = readPtr;
dev@1445 70 const auto end = std::min(start + blockSize, endFrame);
dev@1449 71 const auto data = model.toDelimitedDataStringSubsetWithOptions(
dev@1445 72 delimiter,
dev@1445 73 options,
dev@1445 74 start,
dev@1445 75 end
dev@1449 76 ).trimmed();
dev@1449 77
dev@1449 78 if ( data != "" ) {
dev@1449 79 oss << data << (end < finalFrameOfLastRegion ? "\n" : "");
dev@1449 80 }
dev@1449 81
dev@1445 82 nFramesWritten += end - start;
Chris@1454 83 const int currentProgress =
Chris@1454 84 int(100 * nFramesWritten / nFramesToWrite);
dev@1445 85 const bool hasIncreased = currentProgress > previousProgress;
dev@1445 86 if (hasIncreased) {
dev@1445 87 if (reporter) reporter->setProgress(currentProgress);
dev@1445 88 previousProgress = currentProgress;
dev@1445 89 }
dev@1445 90 readPtr = end;
dev@1445 91 }
dev@1445 92 }
dev@1445 93 return !wasCancelled(); // setProgress could process event loop
dev@1445 94 }
dev@1445 95
dev@1445 96 template <class OutStream>
dev@1441 97 bool
dev@1441 98 writeInChunks(OutStream& oss,
dev@1441 99 const Model& model,
dev@1441 100 const Selection& extents,
dev@1441 101 ProgressReporter* reporter = nullptr,
dev@1441 102 QString delimiter = ",",
dev@1441 103 DataExportOptions options = DataExportDefaults,
dev@1445 104 const sv_frame_t blockSize = 16384)
dev@1434 105 {
dev@1441 106 const auto startFrame = extents.isEmpty() ?
dev@1434 107 model.getStartFrame() : extents.getStartFrame();
dev@1441 108 const auto endFrame = extents.isEmpty() ?
dev@1434 109 model.getEndFrame() : extents.getEndFrame();
dev@1441 110 const auto hasValidExtents = startFrame >= 0 && endFrame > startFrame;
dev@1441 111 if (!hasValidExtents) return false;
dev@1445 112 Selection all {
dev@1445 113 startFrame,
dev@1445 114 endFrame
dev@1434 115 };
dev@1445 116 MultiSelection regions;
dev@1445 117 regions.addSelection(all);
dev@1445 118 return CSVStreamWriter::writeInChunks(
dev@1445 119 oss,
dev@1445 120 model,
dev@1445 121 regions,
dev@1445 122 reporter,
dev@1445 123 delimiter,
dev@1445 124 options,
dev@1445 125 blockSize
dev@1445 126 );
dev@1434 127 }
dev@1434 128
dev@1434 129 template <class OutStream>
dev@1441 130 bool
dev@1441 131 writeInChunks(OutStream& oss,
dev@1441 132 const Model& model,
dev@1441 133 ProgressReporter* reporter = nullptr,
dev@1441 134 QString delimiter = ",",
dev@1441 135 DataExportOptions options = DataExportDefaults,
dev@1441 136 const sv_frame_t blockSize = 16384)
dev@1434 137 {
dev@1434 138 const Selection empty;
dev@1444 139 return CSVStreamWriter::writeInChunks(
dev@1434 140 oss,
dev@1434 141 model,
dev@1434 142 empty,
dev@1434 143 reporter,
dev@1434 144 delimiter,
dev@1434 145 options,
dev@1434 146 blockSize
dev@1434 147 );
dev@1434 148 }
dev@1438 149 } // namespace CSVStreamWriter
cannam@1452 150 #endif