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@560
|
28 #include <iostream>
|
Chris@378
|
29
|
Chris@560
|
30 CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format) :
|
Chris@378
|
31 QDialog(parent),
|
Chris@560
|
32 m_format(format)
|
Chris@378
|
33 {
|
Chris@378
|
34 setModal(true);
|
Chris@378
|
35 setWindowTitle(tr("Select Data Format"));
|
Chris@378
|
36
|
Chris@378
|
37 QGridLayout *layout = new QGridLayout;
|
Chris@378
|
38
|
Chris@560
|
39 int row = 0;
|
Chris@378
|
40
|
Chris@560
|
41 layout->addWidget(new QLabel(tr("Please select the correct data format for this file.")),
|
Chris@560
|
42 row++, 0, 1, 4);
|
Chris@560
|
43
|
Chris@560
|
44 QFrame *exampleFrame = new QFrame;
|
Chris@560
|
45 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
|
Chris@560
|
46 exampleFrame->setLineWidth(2);
|
Chris@560
|
47 QGridLayout *exampleLayout = new QGridLayout;
|
Chris@560
|
48 exampleFrame->setLayout(exampleLayout);
|
Chris@560
|
49
|
Chris@560
|
50 QPalette palette = exampleFrame->palette();
|
Chris@560
|
51 palette.setColor(QPalette::Window, palette.color(QPalette::Base));
|
Chris@560
|
52 exampleFrame->setPalette(palette);
|
Chris@560
|
53
|
Chris@560
|
54 QFont fp;
|
Chris@560
|
55 fp.setFixedPitch(true);
|
Chris@560
|
56 fp.setStyleHint(QFont::TypeWriter);
|
Chris@560
|
57 fp.setFamily("Monospaced");
|
Chris@560
|
58
|
Chris@560
|
59 int columns = format.getColumnCount();
|
Chris@560
|
60 QList<QStringList> example = m_format.getExample();
|
Chris@560
|
61
|
Chris@560
|
62 for (int i = 0; i < columns; ++i) {
|
Chris@560
|
63
|
Chris@560
|
64 QComboBox *cpc = new QComboBox;
|
Chris@560
|
65 m_columnPurposeCombos.push_back(cpc);
|
Chris@560
|
66 exampleLayout->addWidget(cpc, 0, i);
|
Chris@560
|
67
|
Chris@560
|
68 // NB must be in the same order as the CSVFormat::ColumnPurpose enum
|
Chris@560
|
69 cpc->addItem(tr("<ignore>")); // ColumnUnknown
|
Chris@560
|
70 cpc->addItem(tr("Time")); // ColumnStartTime
|
Chris@560
|
71 cpc->addItem(tr("End time")); // ColumnEndTime
|
Chris@560
|
72 cpc->addItem(tr("Duration")); // ColumnDuration
|
Chris@560
|
73 cpc->addItem(tr("Value")); // ColumnValue
|
Chris@560
|
74 cpc->addItem(tr("Label")); // ColumnLabel
|
Chris@560
|
75 cpc->setCurrentIndex(int(m_format.getColumnPurpose(i)));
|
Chris@560
|
76 connect(cpc, SIGNAL(activated(int)), this, SLOT(columnPurposeChanged(int)));
|
Chris@560
|
77
|
Chris@560
|
78 if (i < m_format.getMaxExampleCols()) {
|
Chris@560
|
79 for (int j = 0; j < example.size() && j < 6; ++j) {
|
Chris@560
|
80 QLabel *label = new QLabel;
|
Chris@560
|
81 label->setTextFormat(Qt::PlainText);
|
Chris@560
|
82 label->setText(example[j][i]);
|
Chris@560
|
83 label->setFont(fp);
|
Chris@560
|
84 label->setPalette(palette);
|
Chris@560
|
85 exampleLayout->addWidget(label, j+1, i);
|
Chris@560
|
86 }
|
Chris@560
|
87 }
|
Chris@560
|
88 }
|
Chris@560
|
89
|
Chris@560
|
90 layout->addWidget(exampleFrame, row, 0, 1, 4);
|
Chris@560
|
91 layout->setColumnStretch(3, 10);
|
Chris@560
|
92 layout->setRowStretch(row++, 10);
|
Chris@560
|
93
|
Chris@560
|
94 layout->addWidget(new QLabel(tr("Each row describes:")), row, 0);
|
Chris@378
|
95
|
Chris@378
|
96 m_modelTypeCombo = new QComboBox;
|
Chris@378
|
97 m_modelTypeCombo->addItem(tr("A point in time"));
|
Chris@378
|
98 m_modelTypeCombo->addItem(tr("A value at a time"));
|
Chris@559
|
99 m_modelTypeCombo->addItem(tr("A value across a time range"));
|
Chris@378
|
100 m_modelTypeCombo->addItem(tr("A set of values"));
|
Chris@560
|
101 layout->addWidget(m_modelTypeCombo, row++, 1, 1, 2);
|
Chris@378
|
102 connect(m_modelTypeCombo, SIGNAL(activated(int)),
|
Chris@378
|
103 this, SLOT(modelTypeChanged(int)));
|
Chris@560
|
104 m_modelTypeCombo->setCurrentIndex(int(m_format.getModelType()));
|
Chris@378
|
105
|
Chris@560
|
106 layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0);
|
Chris@378
|
107
|
Chris@378
|
108 m_timingTypeCombo = new QComboBox;
|
Chris@560
|
109 m_timingTypeCombo->addItem(tr("Explicitly, in seconds"));
|
Chris@560
|
110 m_timingTypeCombo->addItem(tr("Explicitly, in audio sample frames"));
|
Chris@560
|
111 m_timingTypeCombo->addItem(tr("Implicitly: rows are equally spaced in time"));
|
Chris@560
|
112 layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2);
|
Chris@378
|
113 connect(m_timingTypeCombo, SIGNAL(activated(int)),
|
Chris@378
|
114 this, SLOT(timingTypeChanged(int)));
|
Chris@560
|
115 m_timingTypeCombo->setCurrentIndex
|
Chris@560
|
116 (m_format.getTimingType() == CSVFormat::ExplicitTiming ?
|
Chris@560
|
117 m_format.getTimeUnits() == CSVFormat::TimeSeconds ? 0 : 1 : 2);
|
Chris@559
|
118
|
Chris@378
|
119 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):"));
|
Chris@560
|
120 layout->addWidget(m_sampleRateLabel, row, 0);
|
Chris@378
|
121
|
Chris@378
|
122 size_t sampleRates[] = {
|
Chris@378
|
123 8000, 11025, 12000, 22050, 24000, 32000,
|
Chris@378
|
124 44100, 48000, 88200, 96000, 176400, 192000
|
Chris@378
|
125 };
|
Chris@378
|
126
|
Chris@378
|
127 m_sampleRateCombo = new QComboBox;
|
Chris@378
|
128 for (size_t i = 0; i < sizeof(sampleRates) / sizeof(sampleRates[0]); ++i) {
|
Chris@378
|
129 m_sampleRateCombo->addItem(QString("%1").arg(sampleRates[i]));
|
Chris@560
|
130 if (sampleRates[i] == m_format.getSampleRate()) {
|
Chris@560
|
131 m_sampleRateCombo->setCurrentIndex(i);
|
Chris@560
|
132 }
|
Chris@378
|
133 }
|
Chris@378
|
134 m_sampleRateCombo->setEditable(true);
|
Chris@378
|
135
|
Chris@560
|
136 layout->addWidget(m_sampleRateCombo, row++, 1);
|
Chris@378
|
137 connect(m_sampleRateCombo, SIGNAL(activated(QString)),
|
Chris@378
|
138 this, SLOT(sampleRateChanged(QString)));
|
Chris@378
|
139 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)),
|
Chris@378
|
140 this, SLOT(sampleRateChanged(QString)));
|
Chris@378
|
141
|
Chris@378
|
142 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:"));
|
Chris@560
|
143 layout->addWidget(m_windowSizeLabel, row, 0);
|
Chris@378
|
144
|
Chris@378
|
145 m_windowSizeCombo = new QComboBox;
|
Chris@378
|
146 for (int i = 0; i <= 16; ++i) {
|
Chris@378
|
147 int value = 1 << i;
|
Chris@378
|
148 m_windowSizeCombo->addItem(QString("%1").arg(value));
|
Chris@560
|
149 if (value == int(m_format.getWindowSize())) {
|
Chris@560
|
150 m_windowSizeCombo->setCurrentIndex(i);
|
Chris@560
|
151 }
|
Chris@378
|
152 }
|
Chris@378
|
153 m_windowSizeCombo->setEditable(true);
|
Chris@378
|
154
|
Chris@560
|
155 layout->addWidget(m_windowSizeCombo, row++, 1);
|
Chris@378
|
156 connect(m_windowSizeCombo, SIGNAL(activated(QString)),
|
Chris@378
|
157 this, SLOT(windowSizeChanged(QString)));
|
Chris@378
|
158 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)),
|
Chris@378
|
159 this, SLOT(windowSizeChanged(QString)));
|
Chris@378
|
160
|
Chris@512
|
161 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
|
Chris@512
|
162 QDialogButtonBox::Cancel);
|
Chris@560
|
163 layout->addWidget(bb, row++, 0, 1, 4);
|
Chris@512
|
164 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
|
Chris@512
|
165 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
|
Chris@378
|
166
|
Chris@512
|
167 setLayout(layout);
|
Chris@378
|
168
|
Chris@559
|
169 modelTypeChanged(m_modelTypeCombo->currentIndex());
|
Chris@378
|
170 timingTypeChanged(m_timingTypeCombo->currentIndex());
|
Chris@378
|
171 }
|
Chris@378
|
172
|
Chris@378
|
173 CSVFormatDialog::~CSVFormatDialog()
|
Chris@378
|
174 {
|
Chris@378
|
175 }
|
Chris@378
|
176
|
Chris@378
|
177 CSVFormat
|
Chris@378
|
178 CSVFormatDialog::getFormat() const
|
Chris@378
|
179 {
|
Chris@560
|
180 return m_format;
|
Chris@378
|
181 }
|
Chris@378
|
182
|
Chris@378
|
183 void
|
Chris@378
|
184 CSVFormatDialog::modelTypeChanged(int type)
|
Chris@378
|
185 {
|
Chris@560
|
186 m_format.setModelType((CSVFormat::ModelType)type);
|
Chris@378
|
187 }
|
Chris@378
|
188
|
Chris@378
|
189 void
|
Chris@378
|
190 CSVFormatDialog::timingTypeChanged(int type)
|
Chris@378
|
191 {
|
Chris@378
|
192 switch (type) {
|
Chris@378
|
193
|
Chris@378
|
194 case 0:
|
Chris@560
|
195 m_format.setTimingType(CSVFormat::ExplicitTiming);
|
Chris@560
|
196 m_format.setTimeUnits(CSVFormat::TimeSeconds);
|
Chris@378
|
197 m_sampleRateCombo->setEnabled(false);
|
Chris@378
|
198 m_sampleRateLabel->setEnabled(false);
|
Chris@378
|
199 m_windowSizeCombo->setEnabled(false);
|
Chris@378
|
200 m_windowSizeLabel->setEnabled(false);
|
Chris@378
|
201 break;
|
Chris@378
|
202
|
Chris@378
|
203 case 1:
|
Chris@560
|
204 m_format.setTimingType(CSVFormat::ExplicitTiming);
|
Chris@560
|
205 m_format.setTimeUnits(CSVFormat::TimeAudioFrames);
|
Chris@378
|
206 m_sampleRateCombo->setEnabled(true);
|
Chris@378
|
207 m_sampleRateLabel->setEnabled(true);
|
Chris@378
|
208 m_windowSizeCombo->setEnabled(false);
|
Chris@378
|
209 m_windowSizeLabel->setEnabled(false);
|
Chris@378
|
210 break;
|
Chris@378
|
211
|
Chris@378
|
212 case 2:
|
Chris@560
|
213 m_format.setTimingType(CSVFormat::ImplicitTiming);
|
Chris@560
|
214 m_format.setTimeUnits(CSVFormat::TimeWindows);
|
Chris@378
|
215 m_sampleRateCombo->setEnabled(true);
|
Chris@378
|
216 m_sampleRateLabel->setEnabled(true);
|
Chris@378
|
217 m_windowSizeCombo->setEnabled(true);
|
Chris@378
|
218 m_windowSizeLabel->setEnabled(true);
|
Chris@378
|
219 break;
|
Chris@378
|
220 }
|
Chris@559
|
221 }
|
Chris@559
|
222
|
Chris@559
|
223 void
|
Chris@378
|
224 CSVFormatDialog::sampleRateChanged(QString rateString)
|
Chris@378
|
225 {
|
Chris@378
|
226 bool ok = false;
|
Chris@378
|
227 int sampleRate = rateString.toInt(&ok);
|
Chris@560
|
228 if (ok) m_format.setSampleRate(sampleRate);
|
Chris@378
|
229 }
|
Chris@378
|
230
|
Chris@378
|
231 void
|
Chris@378
|
232 CSVFormatDialog::windowSizeChanged(QString sizeString)
|
Chris@378
|
233 {
|
Chris@378
|
234 bool ok = false;
|
Chris@378
|
235 int size = sizeString.toInt(&ok);
|
Chris@560
|
236 if (ok) m_format.setWindowSize(size);
|
Chris@378
|
237 }
|
Chris@560
|
238
|
Chris@560
|
239 void
|
Chris@560
|
240 CSVFormatDialog::columnPurposeChanged(int purpose)
|
Chris@560
|
241 {
|
Chris@560
|
242 QObject *o = sender();
|
Chris@560
|
243 QComboBox *cb = qobject_cast<QComboBox *>(o);
|
Chris@560
|
244 if (!cb) return;
|
Chris@560
|
245 int changedCol = -1;
|
Chris@560
|
246 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
|
Chris@560
|
247 if (cb == m_columnPurposeCombos[i]) {
|
Chris@560
|
248 changedCol = i;
|
Chris@560
|
249 break;
|
Chris@560
|
250 }
|
Chris@560
|
251 }
|
Chris@560
|
252 if (changedCol < 0) {
|
Chris@560
|
253 std::cerr << "Hm, some problem here -- column combo changed, but cannot locate column" << std::endl;
|
Chris@560
|
254 return;
|
Chris@560
|
255 }
|
Chris@560
|
256
|
Chris@560
|
257 }
|
Chris@560
|
258
|
Chris@560
|
259
|