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
|