Chris@378
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@378
|
2
|
Chris@378
|
3 /*
|
Chris@378
|
4 Sonic Visualiser
|
Chris@378
|
5 An audio file viewer and annotation editor.
|
Chris@378
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@378
|
7 This file copyright 2006 Chris Cannam.
|
Chris@378
|
8
|
Chris@378
|
9 This program is free software; you can redistribute it and/or
|
Chris@378
|
10 modify it under the terms of the GNU General Public License as
|
Chris@378
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@378
|
12 License, or (at your option) any later version. See the file
|
Chris@378
|
13 COPYING included with this distribution for more information.
|
Chris@378
|
14 */
|
Chris@378
|
15
|
Chris@378
|
16 #include "CSVFormatDialog.h"
|
Chris@378
|
17
|
Chris@378
|
18 #include <QFrame>
|
Chris@378
|
19 #include <QGridLayout>
|
Chris@378
|
20 #include <QPushButton>
|
Chris@378
|
21 #include <QHBoxLayout>
|
Chris@378
|
22 #include <QVBoxLayout>
|
Chris@378
|
23 #include <QTableWidget>
|
Chris@378
|
24 #include <QComboBox>
|
Chris@378
|
25 #include <QLabel>
|
Chris@512
|
26 #include <QDialogButtonBox>
|
Chris@378
|
27
|
Chris@378
|
28
|
Chris@378
|
29 CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format,
|
Chris@378
|
30 size_t defaultSampleRate) :
|
Chris@378
|
31 QDialog(parent),
|
Chris@378
|
32 m_modelType(CSVFormat::OneDimensionalModel),
|
Chris@378
|
33 m_timingType(CSVFormat::ExplicitTiming),
|
Chris@378
|
34 m_timeUnits(CSVFormat::TimeAudioFrames),
|
Chris@378
|
35 m_separator(""),
|
Chris@378
|
36 m_behaviour(QString::KeepEmptyParts)
|
Chris@378
|
37 {
|
Chris@378
|
38 setModal(true);
|
Chris@378
|
39 setWindowTitle(tr("Select Data Format"));
|
Chris@378
|
40
|
Chris@378
|
41 m_modelType = format.getModelType();
|
Chris@378
|
42 m_timingType = format.getTimingType();
|
Chris@378
|
43 m_timeUnits = format.getTimeUnits();
|
Chris@378
|
44 m_separator = format.getSeparator();
|
Chris@378
|
45 m_sampleRate = format.getSampleRate();
|
Chris@378
|
46 m_windowSize = format.getWindowSize();
|
Chris@378
|
47 m_behaviour = format.getSplitBehaviour();
|
Chris@378
|
48 m_example = format.getExample();
|
Chris@378
|
49 m_maxExampleCols = format.getMaxExampleCols();
|
Chris@378
|
50
|
Chris@378
|
51 QGridLayout *layout = new QGridLayout;
|
Chris@378
|
52
|
Chris@378
|
53 layout->addWidget(new QLabel(tr("<b>Select Data Format</b><p>Please select the correct data format for this file.")),
|
Chris@378
|
54 0, 0, 1, 4);
|
Chris@378
|
55
|
Chris@378
|
56 layout->addWidget(new QLabel(tr("Each row specifies:")), 1, 0);
|
Chris@378
|
57
|
Chris@378
|
58 m_modelTypeCombo = new QComboBox;
|
Chris@378
|
59 m_modelTypeCombo->addItem(tr("A point in time"));
|
Chris@378
|
60 m_modelTypeCombo->addItem(tr("A value at a time"));
|
Chris@378
|
61 m_modelTypeCombo->addItem(tr("A set of values"));
|
Chris@378
|
62 layout->addWidget(m_modelTypeCombo, 1, 1, 1, 2);
|
Chris@378
|
63 connect(m_modelTypeCombo, SIGNAL(activated(int)),
|
Chris@378
|
64 this, SLOT(modelTypeChanged(int)));
|
Chris@378
|
65 m_modelTypeCombo->setCurrentIndex(int(m_modelType));
|
Chris@378
|
66
|
Chris@378
|
67 layout->addWidget(new QLabel(tr("The first column contains:")), 2, 0);
|
Chris@378
|
68
|
Chris@378
|
69 m_timingTypeCombo = new QComboBox;
|
Chris@378
|
70 m_timingTypeCombo->addItem(tr("Time, in seconds"));
|
Chris@378
|
71 m_timingTypeCombo->addItem(tr("Time, in audio sample frames"));
|
Chris@378
|
72 m_timingTypeCombo->addItem(tr("Data (rows are consecutive in time)"));
|
Chris@378
|
73 layout->addWidget(m_timingTypeCombo, 2, 1, 1, 2);
|
Chris@378
|
74 connect(m_timingTypeCombo, SIGNAL(activated(int)),
|
Chris@378
|
75 this, SLOT(timingTypeChanged(int)));
|
Chris@378
|
76 m_timingTypeCombo->setCurrentIndex(m_timingType == CSVFormat::ExplicitTiming ?
|
Chris@378
|
77 m_timeUnits == CSVFormat::TimeSeconds ? 0 : 1 : 2);
|
Chris@378
|
78
|
Chris@378
|
79 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):"));
|
Chris@378
|
80 layout->addWidget(m_sampleRateLabel, 3, 0);
|
Chris@378
|
81
|
Chris@378
|
82 size_t sampleRates[] = {
|
Chris@378
|
83 8000, 11025, 12000, 22050, 24000, 32000,
|
Chris@378
|
84 44100, 48000, 88200, 96000, 176400, 192000
|
Chris@378
|
85 };
|
Chris@378
|
86
|
Chris@378
|
87 m_sampleRateCombo = new QComboBox;
|
Chris@378
|
88 m_sampleRate = defaultSampleRate;
|
Chris@378
|
89 for (size_t i = 0; i < sizeof(sampleRates) / sizeof(sampleRates[0]); ++i) {
|
Chris@378
|
90 m_sampleRateCombo->addItem(QString("%1").arg(sampleRates[i]));
|
Chris@378
|
91 if (sampleRates[i] == m_sampleRate) m_sampleRateCombo->setCurrentIndex(i);
|
Chris@378
|
92 }
|
Chris@378
|
93 m_sampleRateCombo->setEditable(true);
|
Chris@378
|
94
|
Chris@378
|
95 layout->addWidget(m_sampleRateCombo, 3, 1);
|
Chris@378
|
96 connect(m_sampleRateCombo, SIGNAL(activated(QString)),
|
Chris@378
|
97 this, SLOT(sampleRateChanged(QString)));
|
Chris@378
|
98 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)),
|
Chris@378
|
99 this, SLOT(sampleRateChanged(QString)));
|
Chris@378
|
100
|
Chris@378
|
101 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:"));
|
Chris@378
|
102 layout->addWidget(m_windowSizeLabel, 4, 0);
|
Chris@378
|
103
|
Chris@378
|
104 m_windowSizeCombo = new QComboBox;
|
Chris@378
|
105 m_windowSize = 1024;
|
Chris@378
|
106 for (int i = 0; i <= 16; ++i) {
|
Chris@378
|
107 int value = 1 << i;
|
Chris@378
|
108 m_windowSizeCombo->addItem(QString("%1").arg(value));
|
Chris@378
|
109 if (value == int(m_windowSize)) m_windowSizeCombo->setCurrentIndex(i);
|
Chris@378
|
110 }
|
Chris@378
|
111 m_windowSizeCombo->setEditable(true);
|
Chris@378
|
112
|
Chris@378
|
113 layout->addWidget(m_windowSizeCombo, 4, 1);
|
Chris@378
|
114 connect(m_windowSizeCombo, SIGNAL(activated(QString)),
|
Chris@378
|
115 this, SLOT(windowSizeChanged(QString)));
|
Chris@378
|
116 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)),
|
Chris@378
|
117 this, SLOT(windowSizeChanged(QString)));
|
Chris@378
|
118
|
Chris@378
|
119 layout->addWidget(new QLabel(tr("\nExample data from file:")), 5, 0, 1, 4);
|
Chris@378
|
120
|
Chris@378
|
121 m_exampleWidget = new QTableWidget
|
Chris@378
|
122 (std::min(10, m_example.size()), m_maxExampleCols);
|
Chris@378
|
123
|
Chris@378
|
124 layout->addWidget(m_exampleWidget, 6, 0, 1, 4);
|
Chris@378
|
125 layout->setColumnStretch(3, 10);
|
Chris@512
|
126 layout->setRowStretch(6, 10);
|
Chris@378
|
127
|
Chris@512
|
128 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
|
Chris@512
|
129 QDialogButtonBox::Cancel);
|
Chris@512
|
130 layout->addWidget(bb, 7, 0, 1, 4);
|
Chris@512
|
131 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
|
Chris@512
|
132 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
|
Chris@378
|
133
|
Chris@512
|
134 setLayout(layout);
|
Chris@378
|
135
|
Chris@378
|
136 timingTypeChanged(m_timingTypeCombo->currentIndex());
|
Chris@378
|
137 }
|
Chris@378
|
138
|
Chris@378
|
139 CSVFormatDialog::~CSVFormatDialog()
|
Chris@378
|
140 {
|
Chris@378
|
141 }
|
Chris@378
|
142
|
Chris@378
|
143 CSVFormat
|
Chris@378
|
144 CSVFormatDialog::getFormat() const
|
Chris@378
|
145 {
|
Chris@378
|
146 CSVFormat format;
|
Chris@378
|
147 format.setModelType(m_modelType);
|
Chris@378
|
148 format.setTimingType(m_timingType);
|
Chris@378
|
149 format.setTimeUnits(m_timeUnits);
|
Chris@378
|
150 format.setSeparator(m_separator);
|
Chris@378
|
151 format.setSampleRate(m_sampleRate);
|
Chris@378
|
152 format.setWindowSize(m_windowSize);
|
Chris@378
|
153 format.setSplitBehaviour(m_behaviour);
|
Chris@378
|
154 return format;
|
Chris@378
|
155 }
|
Chris@378
|
156
|
Chris@378
|
157 void
|
Chris@378
|
158 CSVFormatDialog::populateExample()
|
Chris@378
|
159 {
|
Chris@378
|
160 m_exampleWidget->setColumnCount
|
Chris@378
|
161 (m_timingType == CSVFormat::ExplicitTiming ?
|
Chris@378
|
162 m_maxExampleCols - 1 : m_maxExampleCols);
|
Chris@378
|
163
|
Chris@378
|
164 m_exampleWidget->setHorizontalHeaderLabels(QStringList());
|
Chris@378
|
165
|
Chris@378
|
166 for (int i = 0; i < m_example.size(); ++i) {
|
Chris@378
|
167 for (int j = 0; j < m_example[i].size(); ++j) {
|
Chris@378
|
168
|
Chris@378
|
169 QTableWidgetItem *item = new QTableWidgetItem(m_example[i][j]);
|
Chris@378
|
170
|
Chris@378
|
171 if (j == 0) {
|
Chris@378
|
172 if (m_timingType == CSVFormat::ExplicitTiming) {
|
Chris@378
|
173 m_exampleWidget->setVerticalHeaderItem(i, item);
|
Chris@378
|
174 continue;
|
Chris@378
|
175 } else {
|
Chris@378
|
176 QTableWidgetItem *header =
|
Chris@378
|
177 new QTableWidgetItem(QString("%1").arg(i));
|
Chris@378
|
178 header->setFlags(Qt::ItemIsEnabled);
|
Chris@378
|
179 m_exampleWidget->setVerticalHeaderItem(i, header);
|
Chris@378
|
180 }
|
Chris@378
|
181 }
|
Chris@378
|
182 int index = j;
|
Chris@378
|
183 if (m_timingType == CSVFormat::ExplicitTiming) --index;
|
Chris@378
|
184 item->setFlags(Qt::ItemIsEnabled);
|
Chris@378
|
185 m_exampleWidget->setItem(i, index, item);
|
Chris@378
|
186 }
|
Chris@378
|
187 }
|
Chris@378
|
188 }
|
Chris@378
|
189
|
Chris@378
|
190 void
|
Chris@378
|
191 CSVFormatDialog::modelTypeChanged(int type)
|
Chris@378
|
192 {
|
Chris@378
|
193 m_modelType = (CSVFormat::ModelType)type;
|
Chris@378
|
194
|
Chris@378
|
195 if (m_modelType == CSVFormat::ThreeDimensionalModel) {
|
Chris@378
|
196 // We can't load 3d models with explicit timing, because the 3d
|
Chris@378
|
197 // model is dense so we need a fixed sample increment
|
Chris@378
|
198 m_timingTypeCombo->setCurrentIndex(2);
|
Chris@378
|
199 timingTypeChanged(2);
|
Chris@378
|
200 }
|
Chris@378
|
201 }
|
Chris@378
|
202
|
Chris@378
|
203 void
|
Chris@378
|
204 CSVFormatDialog::timingTypeChanged(int type)
|
Chris@378
|
205 {
|
Chris@378
|
206 switch (type) {
|
Chris@378
|
207
|
Chris@378
|
208 case 0:
|
Chris@378
|
209 m_timingType = CSVFormat::ExplicitTiming;
|
Chris@378
|
210 m_timeUnits = CSVFormat::TimeSeconds;
|
Chris@378
|
211 m_sampleRateCombo->setEnabled(false);
|
Chris@378
|
212 m_sampleRateLabel->setEnabled(false);
|
Chris@378
|
213 m_windowSizeCombo->setEnabled(false);
|
Chris@378
|
214 m_windowSizeLabel->setEnabled(false);
|
Chris@378
|
215 if (m_modelType == CSVFormat::ThreeDimensionalModel) {
|
Chris@378
|
216 m_modelTypeCombo->setCurrentIndex(1);
|
Chris@378
|
217 modelTypeChanged(1);
|
Chris@378
|
218 }
|
Chris@378
|
219 break;
|
Chris@378
|
220
|
Chris@378
|
221 case 1:
|
Chris@378
|
222 m_timingType = CSVFormat::ExplicitTiming;
|
Chris@378
|
223 m_timeUnits = CSVFormat::TimeAudioFrames;
|
Chris@378
|
224 m_sampleRateCombo->setEnabled(true);
|
Chris@378
|
225 m_sampleRateLabel->setEnabled(true);
|
Chris@378
|
226 m_windowSizeCombo->setEnabled(false);
|
Chris@378
|
227 m_windowSizeLabel->setEnabled(false);
|
Chris@378
|
228 if (m_modelType == CSVFormat::ThreeDimensionalModel) {
|
Chris@378
|
229 m_modelTypeCombo->setCurrentIndex(1);
|
Chris@378
|
230 modelTypeChanged(1);
|
Chris@378
|
231 }
|
Chris@378
|
232 break;
|
Chris@378
|
233
|
Chris@378
|
234 case 2:
|
Chris@378
|
235 m_timingType = CSVFormat::ImplicitTiming;
|
Chris@378
|
236 m_timeUnits = CSVFormat::TimeWindows;
|
Chris@378
|
237 m_sampleRateCombo->setEnabled(true);
|
Chris@378
|
238 m_sampleRateLabel->setEnabled(true);
|
Chris@378
|
239 m_windowSizeCombo->setEnabled(true);
|
Chris@378
|
240 m_windowSizeLabel->setEnabled(true);
|
Chris@378
|
241 break;
|
Chris@378
|
242 }
|
Chris@378
|
243
|
Chris@378
|
244 populateExample();
|
Chris@378
|
245 }
|
Chris@378
|
246
|
Chris@378
|
247 void
|
Chris@378
|
248 CSVFormatDialog::sampleRateChanged(QString rateString)
|
Chris@378
|
249 {
|
Chris@378
|
250 bool ok = false;
|
Chris@378
|
251 int sampleRate = rateString.toInt(&ok);
|
Chris@378
|
252 if (ok) m_sampleRate = sampleRate;
|
Chris@378
|
253 }
|
Chris@378
|
254
|
Chris@378
|
255 void
|
Chris@378
|
256 CSVFormatDialog::windowSizeChanged(QString sizeString)
|
Chris@378
|
257 {
|
Chris@378
|
258 bool ok = false;
|
Chris@378
|
259 int size = sizeString.toInt(&ok);
|
Chris@378
|
260 if (ok) m_windowSize = size;
|
Chris@378
|
261 }
|