annotate widgets/CSVFormatDialog.cpp @ 378:22b72f0f6a4e

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