Mercurial > hg > svgui
comparison widgets/CSVFormatDialog.cpp @ 1323:8068a0bee550
Merge from branch import-audio-data
author | Chris Cannam |
---|---|
date | Wed, 12 Sep 2018 15:58:11 +0100 |
parents | fbda05431ce0 |
children | 0930a27ebea2 |
comparison
equal
deleted
inserted
replaced
1316:c0d8356e274f | 1323:8068a0bee550 |
---|---|
2 | 2 |
3 /* | 3 /* |
4 Sonic Visualiser | 4 Sonic Visualiser |
5 An audio file viewer and annotation editor. | 5 An audio file viewer and annotation editor. |
6 Centre for Digital Music, Queen Mary, University of London. | 6 Centre for Digital Music, Queen Mary, University of London. |
7 This file copyright 2006 Chris Cannam. | 7 This file copyright 2006-2018 Chris Cannam and QMUL. |
8 | 8 |
9 This program is free software; you can redistribute it and/or | 9 This program is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU General Public License as | 10 modify it under the terms of the GNU General Public License as |
11 published by the Free Software Foundation; either version 2 of the | 11 published by the Free Software Foundation; either version 2 of the |
12 License, or (at your option) any later version. See the file | 12 License, or (at your option) any later version. See the file |
46 | 46 |
47 QGridLayout *layout = new QGridLayout; | 47 QGridLayout *layout = new QGridLayout; |
48 | 48 |
49 int row = 0; | 49 int row = 0; |
50 | 50 |
51 layout->addWidget(new QLabel(tr("Please select the correct data format for this file.")), | 51 layout->addWidget |
52 row++, 0, 1, 4); | 52 (new QLabel(tr("Please select the correct data format for this file.")), |
53 row++, 0, 1, 4); | |
53 | 54 |
54 QFrame *exampleFrame = new QFrame; | 55 QFrame *exampleFrame = new QFrame; |
55 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); | 56 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); |
56 exampleFrame->setLineWidth(2); | 57 exampleFrame->setLineWidth(2); |
57 QGridLayout *exampleLayout = new QGridLayout; | 58 QGridLayout *exampleLayout = new QGridLayout; |
62 palette.setColor(QPalette::Window, palette.color(QPalette::Base)); | 63 palette.setColor(QPalette::Window, palette.color(QPalette::Base)); |
63 exampleFrame->setPalette(palette); | 64 exampleFrame->setPalette(palette); |
64 | 65 |
65 QFont fp; | 66 QFont fp; |
66 fp.setPointSize(int(floor(fp.pointSize() * 0.9))); | 67 fp.setPointSize(int(floor(fp.pointSize() * 0.9))); |
67 // fp.setFixedPitch(true); | |
68 // fp.setStyleHint(QFont::TypeWriter); | |
69 // fp.setFamily("Monospaced"); | |
70 | 68 |
71 int columns = format.getColumnCount(); | 69 int columns = format.getColumnCount(); |
72 QList<QStringList> example = m_format.getExample(); | 70 QList<QStringList> example = m_format.getExample(); |
73 | 71 |
74 for (int i = 0; i < columns; ++i) { | 72 for (int i = 0; i < columns; ++i) { |
75 | 73 |
76 QComboBox *cpc = new QComboBox; | 74 QComboBox *cpc = new QComboBox; |
77 m_columnPurposeCombos.push_back(cpc); | 75 m_columnPurposeCombos.push_back(cpc); |
78 exampleLayout->addWidget(cpc, 0, i); | 76 exampleLayout->addWidget(cpc, 0, i); |
79 connect(cpc, SIGNAL(activated(int)), this, SLOT(columnPurposeChanged(int))); | 77 connect(cpc, SIGNAL(activated(int)), this, SLOT(columnPurposeChanged(int))); |
80 | 78 |
81 if (i == m_maxDisplayCols && columns > i + 2) { | 79 if (i == m_maxDisplayCols && columns > i + 2) { |
82 m_fuzzyColumn = i; | 80 m_fuzzyColumn = i; |
81 | |
83 cpc->addItem(tr("<ignore>")); | 82 cpc->addItem(tr("<ignore>")); |
84 cpc->addItem(tr("Values")); | 83 cpc->addItem(tr("Values")); |
85 cpc->setCurrentIndex | 84 cpc->setCurrentIndex |
86 (m_format.getColumnPurpose(i-1) == CSVFormat::ColumnUnknown ? 0 : 1); | 85 (m_format.getColumnPurpose(i-1) == |
87 exampleLayout->addWidget(new QLabel(tr("(%1 more)").arg(columns - i)), | 86 CSVFormat::ColumnUnknown ? 0 : 1); |
88 1, i); | 87 |
88 exampleLayout->addWidget | |
89 (new QLabel(tr("(%1 more)").arg(columns - i)), 1, i); | |
89 break; | 90 break; |
90 } | 91 } |
91 | 92 |
92 // NB must be in the same order as the CSVFormat::ColumnPurpose enum | 93 // NB must be in the same order as the CSVFormat::ColumnPurpose enum |
93 cpc->addItem(tr("<ignore>")); // ColumnUnknown | 94 cpc->addItem(tr("<ignore>")); // ColumnUnknown |
96 cpc->addItem(tr("Duration")); // ColumnDuration | 97 cpc->addItem(tr("Duration")); // ColumnDuration |
97 cpc->addItem(tr("Value")); // ColumnValue | 98 cpc->addItem(tr("Value")); // ColumnValue |
98 cpc->addItem(tr("Pitch")); // ColumnPitch | 99 cpc->addItem(tr("Pitch")); // ColumnPitch |
99 cpc->addItem(tr("Label")); // ColumnLabel | 100 cpc->addItem(tr("Label")); // ColumnLabel |
100 cpc->setCurrentIndex(int(m_format.getColumnPurpose(i))); | 101 cpc->setCurrentIndex(int(m_format.getColumnPurpose(i))); |
101 | 102 |
102 for (int j = 0; j < example.size() && j < 6; ++j) { | 103 for (int j = 0; j < example.size() && j < 6; ++j) { |
103 if (i >= example[j].size()) { | 104 if (i >= example[j].size()) { |
104 continue; | 105 continue; |
105 } | 106 } |
106 QLabel *label = new QLabel; | 107 QLabel *label = new QLabel; |
130 }; | 131 }; |
131 | 132 |
132 for (auto &l: m_timingLabels) { | 133 for (auto &l: m_timingLabels) { |
133 m_timingTypeCombo->addItem(l.second); | 134 m_timingTypeCombo->addItem(l.second); |
134 } | 135 } |
135 | 136 |
136 layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2); | 137 layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2); |
137 | 138 |
138 connect(m_timingTypeCombo, SIGNAL(activated(int)), | 139 connect(m_timingTypeCombo, SIGNAL(activated(int)), |
139 this, SLOT(timingTypeChanged(int))); | 140 this, SLOT(timingTypeChanged(int))); |
140 | 141 |
141 m_initialTimingOption = TimingImplicit; | 142 m_initialTimingOption = TimingImplicit; |
142 if (m_format.getTimingType() == CSVFormat::ExplicitTiming) { | 143 if (m_format.getTimingType() == CSVFormat::ExplicitTiming) { |
143 switch (m_format.getTimeUnits()) { | 144 switch (m_format.getTimeUnits()) { |
144 case CSVFormat::TimeSeconds: | 145 case CSVFormat::TimeSeconds: |
145 m_initialTimingOption = TimingExplicitSeconds; break; | 146 m_initialTimingOption = TimingExplicitSeconds; break; |
150 case CSVFormat::TimeWindows: | 151 case CSVFormat::TimeWindows: |
151 m_initialTimingOption = TimingImplicit; break; | 152 m_initialTimingOption = TimingImplicit; break; |
152 } | 153 } |
153 } | 154 } |
154 m_timingTypeCombo->setCurrentIndex(int(m_initialTimingOption)); | 155 m_timingTypeCombo->setCurrentIndex(int(m_initialTimingOption)); |
155 | 156 |
156 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):")); | 157 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):")); |
157 layout->addWidget(m_sampleRateLabel, row, 0); | 158 layout->addWidget(m_sampleRateLabel, row, 0); |
158 | 159 |
159 int sampleRates[] = { | 160 int sampleRates[] = { |
160 8000, 11025, 12000, 22050, 24000, 32000, | 161 8000, 11025, 12000, 22050, 24000, 32000, |
176 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)), | 177 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)), |
177 this, SLOT(sampleRateChanged(QString))); | 178 this, SLOT(sampleRateChanged(QString))); |
178 | 179 |
179 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); | 180 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); |
180 layout->addWidget(m_windowSizeLabel, row, 0); | 181 layout->addWidget(m_windowSizeLabel, row, 0); |
181 | 182 |
182 m_windowSizeCombo = new QComboBox; | 183 m_windowSizeCombo = new QComboBox; |
183 for (int i = 0; i <= 16; ++i) { | 184 for (int i = 0; i <= 16; ++i) { |
184 int value = 1 << i; | 185 int value = 1 << i; |
185 m_windowSizeCombo->addItem(QString("%1").arg(value)); | 186 m_windowSizeCombo->addItem(QString("%1").arg(value)); |
186 if (value == int(m_format.getWindowSize())) { | 187 if (value == int(m_format.getWindowSize())) { |
187 m_windowSizeCombo->setCurrentIndex(i); | 188 m_windowSizeCombo->setCurrentIndex(i); |
188 } | 189 } |
189 } | 190 } |
190 m_windowSizeCombo->setEditable(true); | 191 m_windowSizeCombo->setEditable(true); |
191 | 192 |
192 layout->addWidget(m_windowSizeCombo, row++, 1); | 193 layout->addWidget(m_windowSizeCombo, row++, 1); |
193 connect(m_windowSizeCombo, SIGNAL(activated(QString)), | 194 connect(m_windowSizeCombo, SIGNAL(activated(QString)), |
194 this, SLOT(windowSizeChanged(QString))); | 195 this, SLOT(windowSizeChanged(QString))); |
195 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), | 196 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), |
196 this, SLOT(windowSizeChanged(QString))); | 197 this, SLOT(windowSizeChanged(QString))); |
223 } | 224 } |
224 | 225 |
225 void | 226 void |
226 CSVFormatDialog::updateModelLabel() | 227 CSVFormatDialog::updateModelLabel() |
227 { | 228 { |
229 if (!m_modelLabel) { | |
230 return; | |
231 } | |
232 | |
228 LayerFactory *f = LayerFactory::getInstance(); | 233 LayerFactory *f = LayerFactory::getInstance(); |
229 | 234 |
230 QString s; | 235 QString s; |
231 switch (m_format.getModelType()) { | 236 switch (m_format.getModelType()) { |
232 case CSVFormat::OneDimensionalModel: | 237 case CSVFormat::OneDimensionalModel: |
242 s = f->getLayerPresentationName(LayerFactory::Notes); | 247 s = f->getLayerPresentationName(LayerFactory::Notes); |
243 break; | 248 break; |
244 case CSVFormat::ThreeDimensionalModel: | 249 case CSVFormat::ThreeDimensionalModel: |
245 s = f->getLayerPresentationName(LayerFactory::Colour3DPlot); | 250 s = f->getLayerPresentationName(LayerFactory::Colour3DPlot); |
246 break; | 251 break; |
252 case CSVFormat::WaveFileModel: | |
253 s = f->getLayerPresentationName(LayerFactory::Waveform); | |
254 break; | |
247 } | 255 } |
248 | 256 |
249 m_modelLabel->setText("\n" + tr("Data will be displayed in a %1 layer.").arg(s)); | 257 m_modelLabel->setText("\n" + tr("Data will be displayed in a %1 layer.") |
258 .arg(s)); | |
250 } | 259 } |
251 | 260 |
252 void | 261 void |
253 CSVFormatDialog::applyStartTimePurpose() | 262 CSVFormatDialog::applyStartTimePurpose() |
254 { | 263 { |
339 { | 348 { |
340 QObject *o = sender(); | 349 QObject *o = sender(); |
341 QComboBox *cb = qobject_cast<QComboBox *>(o); | 350 QComboBox *cb = qobject_cast<QComboBox *>(o); |
342 if (!cb) return; | 351 if (!cb) return; |
343 | 352 |
353 // Ensure a consistent set of column purposes, in case of a | |
354 // situation where some combinations are contradictory. Only | |
355 // updates the UI, does not update the stored format record from | |
356 // the UI - that's the job of updateFormatFromDialog | |
357 | |
344 CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose)p; | 358 CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose)p; |
345 | 359 |
346 bool haveStartTime = false; // so as to update timing type combo appropriately | 360 bool haveStartTime = false; // so as to update timing type combo appropriately |
347 | 361 |
348 // Ensure the column purpose combos are consistent with one | 362 // Ensure the column purpose combos are consistent with one |
410 } | 424 } |
411 | 425 |
412 updateFormatFromDialog(); | 426 updateFormatFromDialog(); |
413 updateComboVisibility(); | 427 updateComboVisibility(); |
414 } | 428 } |
415 | 429 |
416 void | 430 void |
417 CSVFormatDialog::updateFormatFromDialog() | 431 CSVFormatDialog::updateFormatFromDialog() |
418 { | 432 { |
419 switch (TimingOption(m_timingTypeCombo->currentIndex())) { | 433 switch (TimingOption(m_timingTypeCombo->currentIndex())) { |
420 | 434 |
421 case TimingExplicitSeconds: | 435 case TimingExplicitSeconds: |
422 m_format.setTimingType(CSVFormat::ExplicitTiming); | 436 m_format.setTimingType(CSVFormat::ExplicitTiming); |
423 m_format.setTimeUnits(CSVFormat::TimeSeconds); | 437 m_format.setTimeUnits(CSVFormat::TimeSeconds); |
424 break; | 438 break; |
425 | 439 |
426 case TimingExplicitMsec: | 440 case TimingExplicitMsec: |
427 m_format.setTimingType(CSVFormat::ExplicitTiming); | 441 m_format.setTimingType(CSVFormat::ExplicitTiming); |
428 m_format.setTimeUnits(CSVFormat::TimeMilliseconds); | 442 m_format.setTimeUnits(CSVFormat::TimeMilliseconds); |
429 break; | 443 break; |
430 | 444 |
431 case TimingExplicitSamples: | 445 case TimingExplicitSamples: |
432 m_format.setTimingType(CSVFormat::ExplicitTiming); | 446 m_format.setTimingType(CSVFormat::ExplicitTiming); |
433 m_format.setTimeUnits(CSVFormat::TimeAudioFrames); | 447 m_format.setTimeUnits(CSVFormat::TimeAudioFrames); |
434 break; | 448 break; |
435 | 449 |
436 case TimingImplicit: | 450 case TimingImplicit: |
437 m_format.setTimingType(CSVFormat::ImplicitTiming); | 451 m_format.setTimingType(CSVFormat::ImplicitTiming); |
438 m_format.setTimeUnits(CSVFormat::TimeWindows); | 452 m_format.setTimeUnits(CSVFormat::TimeWindows); |
439 break; | 453 break; |
440 } | 454 } |
441 | 455 |
442 bool haveStartTime = false; | 456 bool haveStartTime = false; |
443 bool haveDuration = false; | 457 bool haveDuration = false; |
444 bool havePitch = false; | 458 bool havePitch = false; |
445 int valueCount = 0; | 459 int valueCount = 0; |
446 | 460 |
447 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) { | 461 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) { |
448 | 462 |
449 QComboBox *thisCombo = m_columnPurposeCombos[i]; | 463 QComboBox *thisCombo = m_columnPurposeCombos[i]; |
450 | 464 |
451 CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose) | 465 CSVFormat::ColumnPurpose purpose = |
452 (thisCombo->currentIndex()); | 466 (CSVFormat::ColumnPurpose) (thisCombo->currentIndex()); |
453 | 467 |
454 if (i == m_fuzzyColumn) { | 468 if (i == m_fuzzyColumn) { |
455 for (int j = i; j < m_format.getColumnCount(); ++j) { | 469 for (int j = i; j < m_format.getColumnCount(); ++j) { |
456 if (purpose == CSVFormat::ColumnUnknown) { | 470 if (purpose == CSVFormat::ColumnUnknown) { |
457 m_format.setColumnPurpose(j, CSVFormat::ColumnUnknown); | 471 m_format.setColumnPurpose(j, CSVFormat::ColumnUnknown); |
458 } else { // Value | 472 } else { // Value |