# HG changeset patch # User Chris Cannam # Date 1536230971 -3600 # Node ID b149b53df3659af0e9ac0384e751a3a77cfd8daa # Parent c2fa7bb1eca9151f66b477c7580c2f25c116c06e Support audio-format CSV format selection in dialog diff -r c2fa7bb1eca9 -r b149b53df365 widgets/CSVFormatDialog.cpp --- a/widgets/CSVFormatDialog.cpp Tue Sep 04 13:19:32 2018 +0100 +++ b/widgets/CSVFormatDialog.cpp Thu Sep 06 11:49:31 2018 +0100 @@ -37,6 +37,9 @@ CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format, int maxDisplayCols) : QDialog(parent), + m_dialogType(format.getModelType() == CSVFormat::WaveFileModel ? + AudioDataDialog : + AnnotationDataDialog), m_format(format), m_maxDisplayCols(maxDisplayCols), m_fuzzyColumn(-1) @@ -48,8 +51,9 @@ int row = 0; - layout->addWidget(new QLabel(tr("Please select the correct data format for this file.")), - row++, 0, 1, 4); + layout->addWidget + (new QLabel(tr("Please select the correct data format for this file.")), + row++, 0, 1, 4); QFrame *exampleFrame = new QFrame; exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); @@ -64,9 +68,6 @@ QFont fp; fp.setPointSize(int(floor(fp.pointSize() * 0.9))); -// fp.setFixedPitch(true); -// fp.setStyleHint(QFont::TypeWriter); -// fp.setFamily("Monospaced"); int columns = format.getColumnCount(); QList example = m_format.getExample(); @@ -77,28 +78,49 @@ m_columnPurposeCombos.push_back(cpc); exampleLayout->addWidget(cpc, 0, i); connect(cpc, SIGNAL(activated(int)), this, SLOT(columnPurposeChanged(int))); - + if (i == m_maxDisplayCols && columns > i + 2) { m_fuzzyColumn = i; - cpc->addItem(tr("")); - cpc->addItem(tr("Values")); - cpc->setCurrentIndex - (m_format.getColumnPurpose(i-1) == CSVFormat::ColumnUnknown ? 0 : 1); - exampleLayout->addWidget(new QLabel(tr("(%1 more)").arg(columns - i)), - 1, i); + + if (m_dialogType == AnnotationDataDialog) { + cpc->addItem(tr("")); + cpc->addItem(tr("Values")); + cpc->setCurrentIndex + (m_format.getColumnPurpose(i-1) == + CSVFormat::ColumnUnknown ? 0 : 1); + } else { + cpc->addItem(tr("")); + cpc->addItem(tr("Audio channels")); + cpc->setCurrentIndex + (m_format.isColumnNumeric(i-1) ? 1 : 0); + } + exampleLayout->addWidget + (new QLabel(tr("(%1 more)").arg(columns - i)), 1, i); break; } - // NB must be in the same order as the CSVFormat::ColumnPurpose enum - cpc->addItem(tr("")); // ColumnUnknown - cpc->addItem(tr("Time")); // ColumnStartTime - cpc->addItem(tr("End time")); // ColumnEndTime - cpc->addItem(tr("Duration")); // ColumnDuration - cpc->addItem(tr("Value")); // ColumnValue - cpc->addItem(tr("Pitch")); // ColumnPitch - cpc->addItem(tr("Label")); // ColumnLabel - cpc->setCurrentIndex(int(m_format.getColumnPurpose(i))); + if (m_dialogType == AnnotationDataDialog) { + // NB must be in the same order as the CSVFormat::ColumnPurpose enum + cpc->addItem(tr("")); // ColumnUnknown + cpc->addItem(tr("Time")); // ColumnStartTime + cpc->addItem(tr("End time")); // ColumnEndTime + cpc->addItem(tr("Duration")); // ColumnDuration + cpc->addItem(tr("Value")); // ColumnValue + cpc->addItem(tr("Pitch")); // ColumnPitch + cpc->addItem(tr("Label")); // ColumnLabel + cpc->setCurrentIndex(int(m_format.getColumnPurpose(i))); + + } else { + cpc->addItem(tr("")); + cpc->addItem(tr("Audio channel")); + if (m_format.isColumnNumeric(i)) { + cpc->setCurrentIndex(1); + } else { + cpc->setCurrentIndex(0); + } + } + for (int j = 0; j < example.size() && j < 6; ++j) { if (i >= example[j].size()) { continue; @@ -118,41 +140,48 @@ layout->setColumnStretch(3, 10); layout->setRowStretch(row++, 10); - layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0); + if (m_dialogType == AnnotationDataDialog) { - m_timingTypeCombo = new QComboBox; + layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0); + + m_timingTypeCombo = new QComboBox; - m_timingLabels = { - { TimingExplicitSeconds, tr("Explicitly, in seconds") }, - { TimingExplicitMsec, tr("Explicitly, in milliseconds") }, - { TimingExplicitSamples, tr("Explicitly, in audio sample frames") }, - { TimingImplicit, tr("Implicitly: rows are equally spaced in time") } - }; + m_timingLabels = { + { TimingExplicitSeconds, tr("Explicitly, in seconds") }, + { TimingExplicitMsec, tr("Explicitly, in milliseconds") }, + { TimingExplicitSamples, tr("Explicitly, in audio sample frames") }, + { TimingImplicit, tr("Implicitly: rows are equally spaced in time") } + }; - for (auto &l: m_timingLabels) { - m_timingTypeCombo->addItem(l.second); + for (auto &l: m_timingLabels) { + m_timingTypeCombo->addItem(l.second); + } + + layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2); + + connect(m_timingTypeCombo, SIGNAL(activated(int)), + this, SLOT(timingTypeChanged(int))); + + m_initialTimingOption = TimingImplicit; + if (m_format.getTimingType() == CSVFormat::ExplicitTiming) { + switch (m_format.getTimeUnits()) { + case CSVFormat::TimeSeconds: + m_initialTimingOption = TimingExplicitSeconds; break; + case CSVFormat::TimeMilliseconds: + m_initialTimingOption = TimingExplicitMsec; break; + case CSVFormat::TimeAudioFrames: + m_initialTimingOption = TimingExplicitSamples; break; + case CSVFormat::TimeWindows: + m_initialTimingOption = TimingImplicit; break; + } + } + m_timingTypeCombo->setCurrentIndex(int(m_initialTimingOption)); + + } else { + + m_timingTypeCombo = 0; } - - layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2); - - connect(m_timingTypeCombo, SIGNAL(activated(int)), - this, SLOT(timingTypeChanged(int))); - - m_initialTimingOption = TimingImplicit; - if (m_format.getTimingType() == CSVFormat::ExplicitTiming) { - switch (m_format.getTimeUnits()) { - case CSVFormat::TimeSeconds: - m_initialTimingOption = TimingExplicitSeconds; break; - case CSVFormat::TimeMilliseconds: - m_initialTimingOption = TimingExplicitMsec; break; - case CSVFormat::TimeAudioFrames: - m_initialTimingOption = TimingExplicitSamples; break; - case CSVFormat::TimeWindows: - m_initialTimingOption = TimingImplicit; break; - } - } - m_timingTypeCombo->setCurrentIndex(int(m_initialTimingOption)); - + m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):")); layout->addWidget(m_sampleRateLabel, row, 0); @@ -176,30 +205,38 @@ connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)), this, SLOT(sampleRateChanged(QString))); - m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); - layout->addWidget(m_windowSizeLabel, row, 0); + if (m_dialogType == AnnotationDataDialog) { + + m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); + layout->addWidget(m_windowSizeLabel, row, 0); - m_windowSizeCombo = new QComboBox; - for (int i = 0; i <= 16; ++i) { - int value = 1 << i; - m_windowSizeCombo->addItem(QString("%1").arg(value)); - if (value == int(m_format.getWindowSize())) { - m_windowSizeCombo->setCurrentIndex(i); + m_windowSizeCombo = new QComboBox; + for (int i = 0; i <= 16; ++i) { + int value = 1 << i; + m_windowSizeCombo->addItem(QString("%1").arg(value)); + if (value == int(m_format.getWindowSize())) { + m_windowSizeCombo->setCurrentIndex(i); + } } + m_windowSizeCombo->setEditable(true); + + layout->addWidget(m_windowSizeCombo, row++, 1); + connect(m_windowSizeCombo, SIGNAL(activated(QString)), + this, SLOT(windowSizeChanged(QString))); + connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), + this, SLOT(windowSizeChanged(QString))); + + m_modelLabel = new QLabel; + QFont f(m_modelLabel->font()); + f.setItalic(true); + m_modelLabel->setFont(f); + layout->addWidget(m_modelLabel, row++, 0, 1, 4); + + } else { + m_windowSizeLabel = 0; + m_windowSizeCombo = 0; + m_modelLabel = 0; } - m_windowSizeCombo->setEditable(true); - - layout->addWidget(m_windowSizeCombo, row++, 1); - connect(m_windowSizeCombo, SIGNAL(activated(QString)), - this, SLOT(windowSizeChanged(QString))); - connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), - this, SLOT(windowSizeChanged(QString))); - - m_modelLabel = new QLabel; - QFont f(m_modelLabel->font()); - f.setItalic(true); - m_modelLabel->setFont(f); - layout->addWidget(m_modelLabel, row++, 0, 1, 4); QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); @@ -209,7 +246,12 @@ setLayout(layout); - timingTypeChanged(m_timingTypeCombo->currentIndex()); + if (m_timingTypeCombo) { + timingTypeChanged(m_timingTypeCombo->currentIndex()); + } else { + updateFormatFromDialog(); + updateComboVisibility(); + } } CSVFormatDialog::~CSVFormatDialog() @@ -225,6 +267,10 @@ void CSVFormatDialog::updateModelLabel() { + if (!m_modelLabel) { + return; + } + LayerFactory *f = LayerFactory::getInstance(); QString s; @@ -249,12 +295,17 @@ break; } - m_modelLabel->setText("\n" + tr("Data will be displayed in a %1 layer.").arg(s)); + m_modelLabel->setText("\n" + tr("Data will be displayed in a %1 layer.") + .arg(s)); } void CSVFormatDialog::applyStartTimePurpose() { + if (m_dialogType == AudioDataDialog) { + return; + } + // First check if we already have any. NB there may be fewer than // m_format.getColumnCount() elements in m_columnPurposeCombos // (because of the fuzzy column behaviour). Note also that the @@ -282,6 +333,10 @@ void CSVFormatDialog::removeStartTimePurpose() { + if (m_dialogType == AudioDataDialog) { + return; + } + // NB there may be fewer than m_format.getColumnCount() elements // in m_columnPurposeCombos (because of the fuzzy column // behaviour) @@ -297,15 +352,18 @@ void CSVFormatDialog::updateComboVisibility() { - bool wantRate = (m_format.getTimingType() == CSVFormat::ImplicitTiming || + bool wantRate = (m_dialogType == AudioDataDialog || + m_format.getTimingType() == CSVFormat::ImplicitTiming || m_format.getTimeUnits() == CSVFormat::TimeAudioFrames); bool wantWindow = (m_format.getTimingType() == CSVFormat::ImplicitTiming); m_sampleRateCombo->setEnabled(wantRate); m_sampleRateLabel->setEnabled(wantRate); - m_windowSizeCombo->setEnabled(wantWindow); - m_windowSizeLabel->setEnabled(wantWindow); + if (m_windowSizeCombo) { + m_windowSizeCombo->setEnabled(wantWindow); + m_windowSizeLabel->setEnabled(wantWindow); + } } void @@ -344,6 +402,23 @@ QComboBox *cb = qobject_cast(o); if (!cb) return; + if (m_dialogType == AnnotationDataDialog) { + columnPurposeChangedForAnnotationType(cb, p); + } + + updateFormatFromDialog(); + updateComboVisibility(); +} + +void +CSVFormatDialog::columnPurposeChangedForAnnotationType(QComboBox *cb, int p) +{ + // Ensure a consistent set of column purposes, in a situation + // where some combinations are contradictory. This is only + // relevant to annotation type formats. Only updates the UI, does + // not update the stored format record from the UI - that's the + // job of updateFormatFromDialog + CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose)p; bool haveStartTime = false; // so as to update timing type combo appropriately @@ -402,46 +477,50 @@ } } - if (!haveStartTime) { - m_timingTypeCombo->setCurrentIndex(int(TimingImplicit)); - } else if (m_timingTypeCombo->currentIndex() == int(TimingImplicit)) { - if (m_initialTimingOption == TimingImplicit) { - m_timingTypeCombo->setCurrentIndex(TimingExplicitSeconds); - } else { - m_timingTypeCombo->setCurrentIndex(m_initialTimingOption); + if (m_timingTypeCombo) { + if (!haveStartTime) { + m_timingTypeCombo->setCurrentIndex(int(TimingImplicit)); + } else if (m_timingTypeCombo->currentIndex() == int(TimingImplicit)) { + if (m_initialTimingOption == TimingImplicit) { + m_timingTypeCombo->setCurrentIndex(TimingExplicitSeconds); + } else { + m_timingTypeCombo->setCurrentIndex(m_initialTimingOption); + } } } - - updateFormatFromDialog(); - updateComboVisibility(); } - + void CSVFormatDialog::updateFormatFromDialog() { - switch (TimingOption(m_timingTypeCombo->currentIndex())) { + if (m_timingTypeCombo) { + switch (TimingOption(m_timingTypeCombo->currentIndex())) { - case TimingExplicitSeconds: - m_format.setTimingType(CSVFormat::ExplicitTiming); - m_format.setTimeUnits(CSVFormat::TimeSeconds); - break; + case TimingExplicitSeconds: + m_format.setTimingType(CSVFormat::ExplicitTiming); + m_format.setTimeUnits(CSVFormat::TimeSeconds); + break; - case TimingExplicitMsec: - m_format.setTimingType(CSVFormat::ExplicitTiming); - m_format.setTimeUnits(CSVFormat::TimeMilliseconds); - break; + case TimingExplicitMsec: + m_format.setTimingType(CSVFormat::ExplicitTiming); + m_format.setTimeUnits(CSVFormat::TimeMilliseconds); + break; - case TimingExplicitSamples: - m_format.setTimingType(CSVFormat::ExplicitTiming); + case TimingExplicitSamples: + m_format.setTimingType(CSVFormat::ExplicitTiming); + m_format.setTimeUnits(CSVFormat::TimeAudioFrames); + break; + + case TimingImplicit: + m_format.setTimingType(CSVFormat::ImplicitTiming); + m_format.setTimeUnits(CSVFormat::TimeWindows); + break; + } + } else if (m_dialogType == AudioDataDialog) { + m_format.setTimingType(CSVFormat::ImplicitTiming); m_format.setTimeUnits(CSVFormat::TimeAudioFrames); - break; - - case TimingImplicit: - m_format.setTimingType(CSVFormat::ImplicitTiming); - m_format.setTimeUnits(CSVFormat::TimeWindows); - break; } - + bool haveStartTime = false; bool haveDuration = false; bool havePitch = false; @@ -451,8 +530,15 @@ QComboBox *thisCombo = m_columnPurposeCombos[i]; - CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose) - (thisCombo->currentIndex()); + CSVFormat::ColumnPurpose purpose; + + if (m_dialogType == AnnotationDataDialog) { + purpose = (CSVFormat::ColumnPurpose) (thisCombo->currentIndex()); + } else { + purpose = (thisCombo->currentIndex() == 1 ? + CSVFormat::ColumnValue : + CSVFormat::ColumnUnknown); + } if (i == m_fuzzyColumn) { for (int j = i; j < m_format.getColumnCount(); ++j) { @@ -483,7 +569,9 @@ } } - if (haveStartTime && haveDuration) { + if (m_dialogType == AudioDataDialog) { + m_format.setModelType(CSVFormat::WaveFileModel); + } else if (haveStartTime && haveDuration) { if (havePitch) { m_format.setModelType(CSVFormat::TwoDimensionalModelWithDurationAndPitch); } else { diff -r c2fa7bb1eca9 -r b149b53df365 widgets/CSVFormatDialog.h --- a/widgets/CSVFormatDialog.h Tue Sep 04 13:19:32 2018 +0100 +++ b/widgets/CSVFormatDialog.h Thu Sep 06 11:49:31 2018 +0100 @@ -29,7 +29,8 @@ Q_OBJECT public: - CSVFormatDialog(QWidget *parent, CSVFormat initialFormat, + CSVFormatDialog(QWidget *parent, + CSVFormat initialFormat, int maxDisplayCols = 5); ~CSVFormatDialog(); @@ -45,9 +46,15 @@ void updateModelLabel(); protected: + enum DialogType { + AnnotationDataDialog, + AudioDataDialog + }; + DialogType m_dialogType; + CSVFormat m_format; int m_maxDisplayCols; - + enum TimingOption { TimingExplicitSeconds = 0, TimingExplicitMsec, @@ -57,6 +64,7 @@ std::map m_timingLabels; TimingOption m_initialTimingOption; + void columnPurposeChangedForAnnotationType(QComboBox *, int purpose); void updateComboVisibility(); void applyStartTimePurpose(); void removeStartTimePurpose();