annotate widgets/CSVExportDialog.cpp @ 1568:3943553b95b0 csv-export-dialog

Add CSV export dialog, + associated supporting changes
author Chris Cannam
date Tue, 14 Jan 2020 15:41:17 +0000
parents
children 9cd77efef37c
rev   line source
Chris@1568 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1568 2
Chris@1568 3 /*
Chris@1568 4 Sonic Visualiser
Chris@1568 5 An audio file viewer and annotation editor.
Chris@1568 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1568 7
Chris@1568 8 This program is free software; you can redistribute it and/or
Chris@1568 9 modify it under the terms of the GNU General Public License as
Chris@1568 10 published by the Free Software Foundation; either version 2 of the
Chris@1568 11 License, or (at your option) any later version. See the file
Chris@1568 12 COPYING included with this distribution for more information.
Chris@1568 13 */
Chris@1568 14
Chris@1568 15 #include "CSVExportDialog.h"
Chris@1568 16
Chris@1568 17 #include "view/ViewManager.h"
Chris@1568 18
Chris@1568 19 #include <QVBoxLayout>
Chris@1568 20 #include <QGridLayout>
Chris@1568 21 #include <QGroupBox>
Chris@1568 22 #include <QLabel>
Chris@1568 23 #include <QDialogButtonBox>
Chris@1568 24 #include <QRadioButton>
Chris@1568 25 #include <QButtonGroup>
Chris@1568 26 #include <QCheckBox>
Chris@1568 27 #include <QComboBox>
Chris@1568 28
Chris@1568 29 #include <vector>
Chris@1568 30
Chris@1568 31 using namespace std;
Chris@1568 32
Chris@1568 33 //!!! todo: remember & re-apply last set of options chosen for this layer type
Chris@1568 34
Chris@1568 35 CSVExportDialog::CSVExportDialog(Configuration config, QWidget *parent) :
Chris@1568 36 QDialog(parent),
Chris@1568 37 m_config(config)
Chris@1568 38 {
Chris@1568 39 setWindowTitle(tr("Export Layer"));
Chris@1568 40
Chris@1568 41 QString intro = tr("Exporting layer \"%1\" to %2 file.")
Chris@1568 42 .arg(config.layerName)
Chris@1568 43 .arg(config.fileExtension.toUpper());
Chris@1568 44
Chris@1568 45 QVBoxLayout *vbox = new QVBoxLayout;
Chris@1568 46
Chris@1568 47 QLabel *label = new QLabel(intro);
Chris@1568 48 vbox->addWidget(label);
Chris@1568 49
Chris@1568 50 int space = ViewManager::scalePixelSize(2);
Chris@1568 51
Chris@1568 52 vbox->addSpacing(space);
Chris@1568 53
Chris@1568 54 QGroupBox *rowColGroup = new QGroupBox(tr("Row and column options:"));
Chris@1568 55 QGridLayout *rowColLayout = new QGridLayout;
Chris@1568 56 rowColGroup->setLayout(rowColLayout);
Chris@1568 57
Chris@1568 58 vector<pair<QString, QChar>> separators {
Chris@1568 59 { tr("Comma"), ',' },
Chris@1568 60 { tr("Tab"), '\t' },
Chris@1568 61 { tr("Space"), ' ' },
Chris@1568 62 { tr("Pipe"), '|' },
Chris@1568 63 { tr("Slash"), '/' },
Chris@1568 64 { tr("Colon"), ':' }
Chris@1568 65 };
Chris@1568 66
Chris@1568 67 QChar defaultSeparator = ',';
Chris@1568 68 if (m_config.fileExtension != "csv") {
Chris@1568 69 defaultSeparator = '\t';
Chris@1568 70 }
Chris@1568 71
Chris@1568 72 rowColLayout->addWidget(new QLabel(tr("Column separator:"), 0, 0));
Chris@1568 73 m_separatorCombo = new QComboBox;
Chris@1568 74 for (auto p: separators) {
Chris@1568 75 if (p.second == '\t' || p.second == ' ') {
Chris@1568 76 m_separatorCombo->addItem(p.first, p.second);
Chris@1568 77 } else {
Chris@1568 78 m_separatorCombo->addItem(tr("%1 '%2'").arg(p.first).arg(p.second),
Chris@1568 79 p.second);
Chris@1568 80 }
Chris@1568 81 if (p.second == defaultSeparator) {
Chris@1568 82 m_separatorCombo->setCurrentIndex(m_separatorCombo->count()-1);
Chris@1568 83 }
Chris@1568 84 }
Chris@1568 85 m_separatorCombo->setEditable(false);
Chris@1568 86 rowColLayout->addWidget(m_separatorCombo, 0, 1);
Chris@1568 87 rowColLayout->setColumnStretch(2, 10);
Chris@1568 88
Chris@1568 89 m_header = new QCheckBox
Chris@1568 90 (tr("Include a header row before the data rows"));
Chris@1568 91 m_timestamps = new QCheckBox
Chris@1568 92 (tr("Include a timestamp column before the data columns"));
Chris@1568 93 rowColLayout->addWidget(m_header, 1, 0, 1, 3);
Chris@1568 94 rowColLayout->addWidget(m_timestamps, 2, 0, 1, 3);
Chris@1568 95
Chris@1568 96 if (!m_config.isDense) {
Chris@1568 97 m_timestamps->setChecked(true);
Chris@1568 98 m_timestamps->setEnabled(false);
Chris@1568 99 }
Chris@1568 100
Chris@1568 101 vbox->addWidget(rowColGroup);
Chris@1568 102
Chris@1568 103 vbox->addSpacing(space);
Chris@1568 104
Chris@1568 105 QGroupBox *framesGroup = new QGroupBox
Chris@1568 106 (tr("Timing format:"));
Chris@1568 107
Chris@1568 108 m_seconds = new QRadioButton
Chris@1568 109 (tr("Write times in seconds"));
Chris@1568 110 m_frames = new QRadioButton
Chris@1568 111 (tr("Write times in audio sample frames"));
Chris@1568 112 m_seconds->setChecked(true);
Chris@1568 113
Chris@1568 114 QVBoxLayout *framesLayout = new QVBoxLayout;
Chris@1568 115 framesLayout->addWidget(m_seconds);
Chris@1568 116 framesLayout->addWidget(m_frames);
Chris@1568 117 framesGroup->setLayout(framesLayout);
Chris@1568 118 vbox->addWidget(framesGroup);
Chris@1568 119
Chris@1568 120 vbox->addSpacing(space);
Chris@1568 121
Chris@1568 122 if (m_config.isDense) {
Chris@1568 123 m_seconds->setEnabled(false);
Chris@1568 124 m_frames->setEnabled(false);
Chris@1568 125 }
Chris@1568 126
Chris@1568 127 QGroupBox *rangeGroup = new QGroupBox
Chris@1568 128 (tr("Range to export:"));
Chris@1568 129
Chris@1568 130 QButtonGroup *selectionGroup = new QButtonGroup(rangeGroup);
Chris@1568 131 QButtonGroup *viewGroup = new QButtonGroup(rangeGroup);
Chris@1568 132
Chris@1568 133 m_selectionOnly = new QRadioButton
Chris@1568 134 (tr("Export only the current selection"));
Chris@1568 135 QRadioButton *fullDuration = new QRadioButton
Chris@1568 136 (tr("Export the full duration of the model"));
Chris@1568 137
Chris@1568 138 selectionGroup->addButton(m_selectionOnly);
Chris@1568 139 selectionGroup->addButton(fullDuration);
Chris@1568 140
Chris@1568 141 if (m_config.haveSelection) {
Chris@1568 142 m_selectionOnly->setChecked(true);
Chris@1568 143 } else {
Chris@1568 144 m_selectionOnly->setEnabled(false);
Chris@1568 145 fullDuration->setEnabled(false);
Chris@1568 146 fullDuration->setChecked(true);
Chris@1568 147 }
Chris@1568 148
Chris@1568 149 QVBoxLayout *rangeLayout = new QVBoxLayout;
Chris@1568 150 rangeLayout->addWidget(m_selectionOnly);
Chris@1568 151 rangeLayout->addWidget(fullDuration);
Chris@1568 152
Chris@1568 153 if (m_config.haveView && m_config.isDense) {
Chris@1568 154
Chris@1568 155 m_viewOnly = new QRadioButton
Chris@1568 156 (tr("Export only the height of the visible view"));
Chris@1568 157 QRadioButton *fullHeight = new QRadioButton
Chris@1568 158 (tr("Export the full height of the model"));
Chris@1568 159
Chris@1568 160 viewGroup->addButton(m_viewOnly);
Chris@1568 161 viewGroup->addButton(fullHeight);
Chris@1568 162
Chris@1568 163 m_viewOnly->setChecked(true);
Chris@1568 164
Chris@1568 165 rangeLayout->addSpacing(space);
Chris@1568 166
Chris@1568 167 rangeLayout->addWidget(m_viewOnly);
Chris@1568 168 rangeLayout->addWidget(fullHeight);
Chris@1568 169
Chris@1568 170 } else {
Chris@1568 171 m_viewOnly = nullptr;
Chris@1568 172 }
Chris@1568 173
Chris@1568 174 rangeGroup->setLayout(rangeLayout);
Chris@1568 175 vbox->addWidget(rangeGroup);
Chris@1568 176
Chris@1568 177 vbox->addSpacing(space);
Chris@1568 178
Chris@1568 179 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
Chris@1568 180 QDialogButtonBox::Cancel);
Chris@1568 181 vbox->addWidget(bb);
Chris@1568 182 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
Chris@1568 183 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
Chris@1568 184
Chris@1568 185 connect(m_timestamps, SIGNAL(toggled(bool)),
Chris@1568 186 this, SLOT(timestampsToggled(bool)));
Chris@1568 187
Chris@1568 188 setLayout(vbox);
Chris@1568 189 }
Chris@1568 190
Chris@1568 191 void
Chris@1568 192 CSVExportDialog::timestampsToggled(bool on)
Chris@1568 193 {
Chris@1568 194 m_seconds->setEnabled(on);
Chris@1568 195 m_frames->setEnabled(on);
Chris@1568 196 }
Chris@1568 197
Chris@1568 198 QString
Chris@1568 199 CSVExportDialog::getDelimiter() const
Chris@1568 200 {
Chris@1568 201 return m_separatorCombo->currentData().toChar();
Chris@1568 202 }
Chris@1568 203
Chris@1568 204 bool
Chris@1568 205 CSVExportDialog::shouldIncludeHeader() const
Chris@1568 206 {
Chris@1568 207 return m_header && m_header->isChecked();
Chris@1568 208 }
Chris@1568 209
Chris@1568 210 bool
Chris@1568 211 CSVExportDialog::shouldIncludeTimestamps() const
Chris@1568 212 {
Chris@1568 213 return m_timestamps && m_timestamps->isChecked();
Chris@1568 214 }
Chris@1568 215
Chris@1568 216 bool
Chris@1568 217 CSVExportDialog::shouldWriteTimeInFrames() const
Chris@1568 218 {
Chris@1568 219 return shouldIncludeTimestamps() && m_frames && m_frames->isChecked();
Chris@1568 220 }
Chris@1568 221
Chris@1568 222 bool
Chris@1568 223 CSVExportDialog::shouldConstrainToViewHeight() const
Chris@1568 224 {
Chris@1568 225 return m_viewOnly && m_viewOnly->isChecked();
Chris@1568 226 }
Chris@1568 227
Chris@1568 228 bool
Chris@1568 229 CSVExportDialog::shouldConstrainToSelection() const
Chris@1568 230 {
Chris@1568 231 return m_selectionOnly && m_selectionOnly->isChecked();
Chris@1568 232 }
Chris@1568 233