annotate widgets/CSVFormatDialog.cpp @ 551:c2ba2796cbee sv-v1.7

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