annotate widgets/CSVExportDialog.cpp @ 1605:ae2d5f8ff005

When asked to render the whole view width, we need to wait for the layers to be ready before we can determine what the width is
author Chris Cannam
date Thu, 30 Apr 2020 14:47:13 +0100
parents 9cd77efef37c
children a6e37c28d762
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@1571 48 label->setWordWrap(true);
Chris@1568 49 vbox->addWidget(label);
Chris@1568 50
Chris@1568 51 int space = ViewManager::scalePixelSize(2);
Chris@1568 52
Chris@1568 53 vbox->addSpacing(space);
Chris@1568 54
Chris@1568 55 QGroupBox *rowColGroup = new QGroupBox(tr("Row and column options:"));
Chris@1568 56 QGridLayout *rowColLayout = new QGridLayout;
Chris@1568 57 rowColGroup->setLayout(rowColLayout);
Chris@1568 58
Chris@1568 59 vector<pair<QString, QChar>> separators {
Chris@1568 60 { tr("Comma"), ',' },
Chris@1568 61 { tr("Tab"), '\t' },
Chris@1568 62 { tr("Space"), ' ' },
Chris@1568 63 { tr("Pipe"), '|' },
Chris@1568 64 { tr("Slash"), '/' },
Chris@1568 65 { tr("Colon"), ':' }
Chris@1568 66 };
Chris@1568 67
Chris@1568 68 QChar defaultSeparator = ',';
Chris@1568 69 if (m_config.fileExtension != "csv") {
Chris@1568 70 defaultSeparator = '\t';
Chris@1568 71 }
Chris@1568 72
Chris@1568 73 rowColLayout->addWidget(new QLabel(tr("Column separator:"), 0, 0));
Chris@1568 74 m_separatorCombo = new QComboBox;
Chris@1568 75 for (auto p: separators) {
Chris@1568 76 if (p.second == '\t' || p.second == ' ') {
Chris@1568 77 m_separatorCombo->addItem(p.first, p.second);
Chris@1568 78 } else {
Chris@1568 79 m_separatorCombo->addItem(tr("%1 '%2'").arg(p.first).arg(p.second),
Chris@1568 80 p.second);
Chris@1568 81 }
Chris@1568 82 if (p.second == defaultSeparator) {
Chris@1568 83 m_separatorCombo->setCurrentIndex(m_separatorCombo->count()-1);
Chris@1568 84 }
Chris@1568 85 }
Chris@1568 86 m_separatorCombo->setEditable(false);
Chris@1568 87 rowColLayout->addWidget(m_separatorCombo, 0, 1);
Chris@1568 88 rowColLayout->setColumnStretch(2, 10);
Chris@1568 89
Chris@1568 90 m_header = new QCheckBox
Chris@1568 91 (tr("Include a header row before the data rows"));
Chris@1568 92 m_timestamps = new QCheckBox
Chris@1568 93 (tr("Include a timestamp column before the data columns"));
Chris@1568 94 rowColLayout->addWidget(m_header, 1, 0, 1, 3);
Chris@1568 95 rowColLayout->addWidget(m_timestamps, 2, 0, 1, 3);
Chris@1568 96
Chris@1568 97 if (!m_config.isDense) {
Chris@1568 98 m_timestamps->setChecked(true);
Chris@1568 99 m_timestamps->setEnabled(false);
Chris@1568 100 }
Chris@1568 101
Chris@1568 102 vbox->addWidget(rowColGroup);
Chris@1568 103
Chris@1568 104 vbox->addSpacing(space);
Chris@1568 105
Chris@1568 106 QGroupBox *framesGroup = new QGroupBox
Chris@1568 107 (tr("Timing format:"));
Chris@1568 108
Chris@1568 109 m_seconds = new QRadioButton
Chris@1568 110 (tr("Write times in seconds"));
Chris@1568 111 m_frames = new QRadioButton
Chris@1568 112 (tr("Write times in audio sample frames"));
Chris@1568 113 m_seconds->setChecked(true);
Chris@1568 114
Chris@1568 115 QVBoxLayout *framesLayout = new QVBoxLayout;
Chris@1568 116 framesLayout->addWidget(m_seconds);
Chris@1568 117 framesLayout->addWidget(m_frames);
Chris@1568 118 framesGroup->setLayout(framesLayout);
Chris@1568 119 vbox->addWidget(framesGroup);
Chris@1568 120
Chris@1568 121 vbox->addSpacing(space);
Chris@1568 122
Chris@1568 123 if (m_config.isDense) {
Chris@1568 124 m_seconds->setEnabled(false);
Chris@1568 125 m_frames->setEnabled(false);
Chris@1568 126 }
Chris@1568 127
Chris@1568 128 QGroupBox *rangeGroup = new QGroupBox
Chris@1568 129 (tr("Range to export:"));
Chris@1568 130
Chris@1568 131 QButtonGroup *selectionGroup = new QButtonGroup(rangeGroup);
Chris@1568 132 QButtonGroup *viewGroup = new QButtonGroup(rangeGroup);
Chris@1568 133
Chris@1568 134 m_selectionOnly = new QRadioButton
Chris@1568 135 (tr("Export only the current selection"));
Chris@1568 136 QRadioButton *fullDuration = new QRadioButton
Chris@1571 137 (tr("Export the full duration of the layer"));
Chris@1568 138
Chris@1568 139 selectionGroup->addButton(m_selectionOnly);
Chris@1568 140 selectionGroup->addButton(fullDuration);
Chris@1568 141
Chris@1568 142 if (m_config.haveSelection) {
Chris@1568 143 m_selectionOnly->setChecked(true);
Chris@1568 144 } else {
Chris@1568 145 m_selectionOnly->setEnabled(false);
Chris@1568 146 fullDuration->setEnabled(false);
Chris@1568 147 fullDuration->setChecked(true);
Chris@1568 148 }
Chris@1568 149
Chris@1568 150 QVBoxLayout *rangeLayout = new QVBoxLayout;
Chris@1568 151 rangeLayout->addWidget(m_selectionOnly);
Chris@1568 152 rangeLayout->addWidget(fullDuration);
Chris@1568 153
Chris@1568 154 if (m_config.haveView && m_config.isDense) {
Chris@1568 155
Chris@1568 156 m_viewOnly = new QRadioButton
Chris@1568 157 (tr("Export only the height of the visible view"));
Chris@1568 158 QRadioButton *fullHeight = new QRadioButton
Chris@1571 159 (tr("Export the full height of the layer"));
Chris@1568 160
Chris@1568 161 viewGroup->addButton(m_viewOnly);
Chris@1568 162 viewGroup->addButton(fullHeight);
Chris@1568 163
Chris@1568 164 m_viewOnly->setChecked(true);
Chris@1568 165
Chris@1568 166 rangeLayout->addSpacing(space);
Chris@1568 167
Chris@1568 168 rangeLayout->addWidget(m_viewOnly);
Chris@1568 169 rangeLayout->addWidget(fullHeight);
Chris@1568 170
Chris@1568 171 } else {
Chris@1568 172 m_viewOnly = nullptr;
Chris@1568 173 }
Chris@1568 174
Chris@1568 175 rangeGroup->setLayout(rangeLayout);
Chris@1568 176 vbox->addWidget(rangeGroup);
Chris@1568 177
Chris@1568 178 vbox->addSpacing(space);
Chris@1568 179
Chris@1568 180 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
Chris@1568 181 QDialogButtonBox::Cancel);
Chris@1568 182 vbox->addWidget(bb);
Chris@1568 183 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
Chris@1568 184 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
Chris@1568 185
Chris@1568 186 connect(m_timestamps, SIGNAL(toggled(bool)),
Chris@1568 187 this, SLOT(timestampsToggled(bool)));
Chris@1568 188
Chris@1568 189 setLayout(vbox);
Chris@1568 190 }
Chris@1568 191
Chris@1568 192 void
Chris@1568 193 CSVExportDialog::timestampsToggled(bool on)
Chris@1568 194 {
Chris@1568 195 m_seconds->setEnabled(on);
Chris@1568 196 m_frames->setEnabled(on);
Chris@1568 197 }
Chris@1568 198
Chris@1568 199 QString
Chris@1568 200 CSVExportDialog::getDelimiter() const
Chris@1568 201 {
Chris@1568 202 return m_separatorCombo->currentData().toChar();
Chris@1568 203 }
Chris@1568 204
Chris@1568 205 bool
Chris@1568 206 CSVExportDialog::shouldIncludeHeader() const
Chris@1568 207 {
Chris@1568 208 return m_header && m_header->isChecked();
Chris@1568 209 }
Chris@1568 210
Chris@1568 211 bool
Chris@1568 212 CSVExportDialog::shouldIncludeTimestamps() const
Chris@1568 213 {
Chris@1568 214 return m_timestamps && m_timestamps->isChecked();
Chris@1568 215 }
Chris@1568 216
Chris@1568 217 bool
Chris@1568 218 CSVExportDialog::shouldWriteTimeInFrames() const
Chris@1568 219 {
Chris@1568 220 return shouldIncludeTimestamps() && m_frames && m_frames->isChecked();
Chris@1568 221 }
Chris@1568 222
Chris@1568 223 bool
Chris@1568 224 CSVExportDialog::shouldConstrainToViewHeight() const
Chris@1568 225 {
Chris@1568 226 return m_viewOnly && m_viewOnly->isChecked();
Chris@1568 227 }
Chris@1568 228
Chris@1568 229 bool
Chris@1568 230 CSVExportDialog::shouldConstrainToSelection() const
Chris@1568 231 {
Chris@1568 232 return m_selectionOnly && m_selectionOnly->isChecked();
Chris@1568 233 }
Chris@1568 234