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
|