annotate widgets/CSVFormatDialog.cpp @ 559:5bcfc5606528

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