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