Chris@378: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@378: Chris@378: /* Chris@378: Sonic Visualiser Chris@378: An audio file viewer and annotation editor. Chris@378: Centre for Digital Music, Queen Mary, University of London. Chris@378: This file copyright 2006 Chris Cannam. Chris@378: Chris@378: This program is free software; you can redistribute it and/or Chris@378: modify it under the terms of the GNU General Public License as Chris@378: published by the Free Software Foundation; either version 2 of the Chris@378: License, or (at your option) any later version. See the file Chris@378: COPYING included with this distribution for more information. Chris@378: */ Chris@378: Chris@378: #include "CSVFormatDialog.h" Chris@378: Chris@378: #include Chris@378: #include Chris@378: #include Chris@378: #include Chris@378: #include Chris@378: #include Chris@378: #include Chris@378: #include Chris@378: Chris@378: Chris@378: CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format, Chris@378: size_t defaultSampleRate) : Chris@378: QDialog(parent), Chris@378: m_modelType(CSVFormat::OneDimensionalModel), Chris@378: m_timingType(CSVFormat::ExplicitTiming), Chris@378: m_timeUnits(CSVFormat::TimeAudioFrames), Chris@378: m_separator(""), Chris@378: m_behaviour(QString::KeepEmptyParts) Chris@378: { Chris@378: setModal(true); Chris@378: setWindowTitle(tr("Select Data Format")); Chris@378: Chris@378: m_modelType = format.getModelType(); Chris@378: m_timingType = format.getTimingType(); Chris@378: m_timeUnits = format.getTimeUnits(); Chris@378: m_separator = format.getSeparator(); Chris@378: m_sampleRate = format.getSampleRate(); Chris@378: m_windowSize = format.getWindowSize(); Chris@378: m_behaviour = format.getSplitBehaviour(); Chris@378: m_example = format.getExample(); Chris@378: m_maxExampleCols = format.getMaxExampleCols(); Chris@378: Chris@378: QGridLayout *layout = new QGridLayout; Chris@378: Chris@378: layout->addWidget(new QLabel(tr("Select Data Format

Please select the correct data format for this file.")), Chris@378: 0, 0, 1, 4); Chris@378: Chris@378: layout->addWidget(new QLabel(tr("Each row specifies:")), 1, 0); Chris@378: Chris@378: m_modelTypeCombo = new QComboBox; Chris@378: m_modelTypeCombo->addItem(tr("A point in time")); Chris@378: m_modelTypeCombo->addItem(tr("A value at a time")); Chris@378: m_modelTypeCombo->addItem(tr("A set of values")); Chris@378: layout->addWidget(m_modelTypeCombo, 1, 1, 1, 2); Chris@378: connect(m_modelTypeCombo, SIGNAL(activated(int)), Chris@378: this, SLOT(modelTypeChanged(int))); Chris@378: m_modelTypeCombo->setCurrentIndex(int(m_modelType)); Chris@378: Chris@378: layout->addWidget(new QLabel(tr("The first column contains:")), 2, 0); Chris@378: Chris@378: m_timingTypeCombo = new QComboBox; Chris@378: m_timingTypeCombo->addItem(tr("Time, in seconds")); Chris@378: m_timingTypeCombo->addItem(tr("Time, in audio sample frames")); Chris@378: m_timingTypeCombo->addItem(tr("Data (rows are consecutive in time)")); Chris@378: layout->addWidget(m_timingTypeCombo, 2, 1, 1, 2); Chris@378: connect(m_timingTypeCombo, SIGNAL(activated(int)), Chris@378: this, SLOT(timingTypeChanged(int))); Chris@378: m_timingTypeCombo->setCurrentIndex(m_timingType == CSVFormat::ExplicitTiming ? Chris@378: m_timeUnits == CSVFormat::TimeSeconds ? 0 : 1 : 2); Chris@378: Chris@378: m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):")); Chris@378: layout->addWidget(m_sampleRateLabel, 3, 0); Chris@378: Chris@378: size_t sampleRates[] = { Chris@378: 8000, 11025, 12000, 22050, 24000, 32000, Chris@378: 44100, 48000, 88200, 96000, 176400, 192000 Chris@378: }; Chris@378: Chris@378: m_sampleRateCombo = new QComboBox; Chris@378: m_sampleRate = defaultSampleRate; Chris@378: for (size_t i = 0; i < sizeof(sampleRates) / sizeof(sampleRates[0]); ++i) { Chris@378: m_sampleRateCombo->addItem(QString("%1").arg(sampleRates[i])); Chris@378: if (sampleRates[i] == m_sampleRate) m_sampleRateCombo->setCurrentIndex(i); Chris@378: } Chris@378: m_sampleRateCombo->setEditable(true); Chris@378: Chris@378: layout->addWidget(m_sampleRateCombo, 3, 1); Chris@378: connect(m_sampleRateCombo, SIGNAL(activated(QString)), Chris@378: this, SLOT(sampleRateChanged(QString))); Chris@378: connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)), Chris@378: this, SLOT(sampleRateChanged(QString))); Chris@378: Chris@378: m_windowSizeLabel = new QLabel(tr("Frame increment between rows:")); Chris@378: layout->addWidget(m_windowSizeLabel, 4, 0); Chris@378: Chris@378: m_windowSizeCombo = new QComboBox; Chris@378: m_windowSize = 1024; Chris@378: for (int i = 0; i <= 16; ++i) { Chris@378: int value = 1 << i; Chris@378: m_windowSizeCombo->addItem(QString("%1").arg(value)); Chris@378: if (value == int(m_windowSize)) m_windowSizeCombo->setCurrentIndex(i); Chris@378: } Chris@378: m_windowSizeCombo->setEditable(true); Chris@378: Chris@378: layout->addWidget(m_windowSizeCombo, 4, 1); Chris@378: connect(m_windowSizeCombo, SIGNAL(activated(QString)), Chris@378: this, SLOT(windowSizeChanged(QString))); Chris@378: connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)), Chris@378: this, SLOT(windowSizeChanged(QString))); Chris@378: Chris@378: layout->addWidget(new QLabel(tr("\nExample data from file:")), 5, 0, 1, 4); Chris@378: Chris@378: m_exampleWidget = new QTableWidget Chris@378: (std::min(10, m_example.size()), m_maxExampleCols); Chris@378: Chris@378: layout->addWidget(m_exampleWidget, 6, 0, 1, 4); Chris@378: layout->setColumnStretch(3, 10); Chris@378: layout->setRowStretch(4, 10); Chris@378: Chris@378: QPushButton *ok = new QPushButton(tr("OK")); Chris@378: connect(ok, SIGNAL(clicked()), this, SLOT(accept())); Chris@378: ok->setDefault(true); Chris@378: Chris@378: QPushButton *cancel = new QPushButton(tr("Cancel")); Chris@378: connect(cancel, SIGNAL(clicked()), this, SLOT(reject())); Chris@378: Chris@378: QHBoxLayout *buttonLayout = new QHBoxLayout; Chris@378: buttonLayout->addStretch(1); Chris@378: buttonLayout->addWidget(ok); Chris@378: buttonLayout->addWidget(cancel); Chris@378: Chris@378: QVBoxLayout *mainLayout = new QVBoxLayout; Chris@378: mainLayout->addLayout(layout); Chris@378: mainLayout->addLayout(buttonLayout); Chris@378: Chris@378: setLayout(mainLayout); Chris@378: Chris@378: timingTypeChanged(m_timingTypeCombo->currentIndex()); Chris@378: } Chris@378: Chris@378: CSVFormatDialog::~CSVFormatDialog() Chris@378: { Chris@378: } Chris@378: Chris@378: CSVFormat Chris@378: CSVFormatDialog::getFormat() const Chris@378: { Chris@378: CSVFormat format; Chris@378: format.setModelType(m_modelType); Chris@378: format.setTimingType(m_timingType); Chris@378: format.setTimeUnits(m_timeUnits); Chris@378: format.setSeparator(m_separator); Chris@378: format.setSampleRate(m_sampleRate); Chris@378: format.setWindowSize(m_windowSize); Chris@378: format.setSplitBehaviour(m_behaviour); Chris@378: return format; Chris@378: } Chris@378: Chris@378: void Chris@378: CSVFormatDialog::populateExample() Chris@378: { Chris@378: m_exampleWidget->setColumnCount Chris@378: (m_timingType == CSVFormat::ExplicitTiming ? Chris@378: m_maxExampleCols - 1 : m_maxExampleCols); Chris@378: Chris@378: m_exampleWidget->setHorizontalHeaderLabels(QStringList()); Chris@378: Chris@378: for (int i = 0; i < m_example.size(); ++i) { Chris@378: for (int j = 0; j < m_example[i].size(); ++j) { Chris@378: Chris@378: QTableWidgetItem *item = new QTableWidgetItem(m_example[i][j]); Chris@378: Chris@378: if (j == 0) { Chris@378: if (m_timingType == CSVFormat::ExplicitTiming) { Chris@378: m_exampleWidget->setVerticalHeaderItem(i, item); Chris@378: continue; Chris@378: } else { Chris@378: QTableWidgetItem *header = Chris@378: new QTableWidgetItem(QString("%1").arg(i)); Chris@378: header->setFlags(Qt::ItemIsEnabled); Chris@378: m_exampleWidget->setVerticalHeaderItem(i, header); Chris@378: } Chris@378: } Chris@378: int index = j; Chris@378: if (m_timingType == CSVFormat::ExplicitTiming) --index; Chris@378: item->setFlags(Qt::ItemIsEnabled); Chris@378: m_exampleWidget->setItem(i, index, item); Chris@378: } Chris@378: } Chris@378: } Chris@378: Chris@378: void Chris@378: CSVFormatDialog::modelTypeChanged(int type) Chris@378: { Chris@378: m_modelType = (CSVFormat::ModelType)type; Chris@378: Chris@378: if (m_modelType == CSVFormat::ThreeDimensionalModel) { Chris@378: // We can't load 3d models with explicit timing, because the 3d Chris@378: // model is dense so we need a fixed sample increment Chris@378: m_timingTypeCombo->setCurrentIndex(2); Chris@378: timingTypeChanged(2); Chris@378: } Chris@378: } Chris@378: Chris@378: void Chris@378: CSVFormatDialog::timingTypeChanged(int type) Chris@378: { Chris@378: switch (type) { Chris@378: Chris@378: case 0: Chris@378: m_timingType = CSVFormat::ExplicitTiming; Chris@378: m_timeUnits = CSVFormat::TimeSeconds; Chris@378: m_sampleRateCombo->setEnabled(false); Chris@378: m_sampleRateLabel->setEnabled(false); Chris@378: m_windowSizeCombo->setEnabled(false); Chris@378: m_windowSizeLabel->setEnabled(false); Chris@378: if (m_modelType == CSVFormat::ThreeDimensionalModel) { Chris@378: m_modelTypeCombo->setCurrentIndex(1); Chris@378: modelTypeChanged(1); Chris@378: } Chris@378: break; Chris@378: Chris@378: case 1: Chris@378: m_timingType = CSVFormat::ExplicitTiming; Chris@378: m_timeUnits = CSVFormat::TimeAudioFrames; Chris@378: m_sampleRateCombo->setEnabled(true); Chris@378: m_sampleRateLabel->setEnabled(true); Chris@378: m_windowSizeCombo->setEnabled(false); Chris@378: m_windowSizeLabel->setEnabled(false); Chris@378: if (m_modelType == CSVFormat::ThreeDimensionalModel) { Chris@378: m_modelTypeCombo->setCurrentIndex(1); Chris@378: modelTypeChanged(1); Chris@378: } Chris@378: break; Chris@378: Chris@378: case 2: Chris@378: m_timingType = CSVFormat::ImplicitTiming; Chris@378: m_timeUnits = CSVFormat::TimeWindows; Chris@378: m_sampleRateCombo->setEnabled(true); Chris@378: m_sampleRateLabel->setEnabled(true); Chris@378: m_windowSizeCombo->setEnabled(true); Chris@378: m_windowSizeLabel->setEnabled(true); Chris@378: break; Chris@378: } Chris@378: Chris@378: populateExample(); Chris@378: } Chris@378: Chris@378: void Chris@378: CSVFormatDialog::sampleRateChanged(QString rateString) Chris@378: { Chris@378: bool ok = false; Chris@378: int sampleRate = rateString.toInt(&ok); Chris@378: if (ok) m_sampleRate = sampleRate; Chris@378: } Chris@378: Chris@378: void Chris@378: CSVFormatDialog::windowSizeChanged(QString sizeString) Chris@378: { Chris@378: bool ok = false; Chris@378: int size = sizeString.toInt(&ok); Chris@378: if (ok) m_windowSize = size; Chris@378: }