annotate widgets/CSVFormatDialog.cpp @ 1025:c02de0e34233 spectrogram-minor-refactor

Make paint method do its own timing and abandon if it's taking too long (still needs some work on queueing correct repaints of the remainder)
author Chris Cannam
date Mon, 25 Jan 2016 16:16:21 +0000
parents e5d40d89b1ec
children a34a2a25907c
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@561 18 #include "layer/LayerFactory.h"
Chris@561 19
Chris@674 20 #include "TextAbbrev.h"
Chris@674 21
Chris@378 22 #include <QFrame>
Chris@378 23 #include <QGridLayout>
Chris@378 24 #include <QPushButton>
Chris@378 25 #include <QHBoxLayout>
Chris@378 26 #include <QVBoxLayout>
Chris@378 27 #include <QTableWidget>
Chris@378 28 #include <QComboBox>
Chris@378 29 #include <QLabel>
Chris@512 30 #include <QDialogButtonBox>
Chris@378 31
Chris@560 32 #include <iostream>
Chris@913 33 #include <cmath>
Chris@378 34
Chris@682 35 #include "base/Debug.h"
Chris@682 36
Chris@581 37 CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format,
Chris@581 38 int maxDisplayCols) :
Chris@378 39 QDialog(parent),
Chris@581 40 m_format(format),
Chris@581 41 m_maxDisplayCols(maxDisplayCols),
Chris@581 42 m_fuzzyColumn(-1)
Chris@378 43 {
Chris@378 44 setModal(true);
Chris@378 45 setWindowTitle(tr("Select Data Format"));
Chris@378 46
Chris@378 47 QGridLayout *layout = new QGridLayout;
Chris@378 48
Chris@560 49 int row = 0;
Chris@378 50
Chris@560 51 layout->addWidget(new QLabel(tr("Please select the correct data format for this file.")),
Chris@560 52 row++, 0, 1, 4);
Chris@560 53
Chris@560 54 QFrame *exampleFrame = new QFrame;
Chris@560 55 exampleFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
Chris@560 56 exampleFrame->setLineWidth(2);
Chris@560 57 QGridLayout *exampleLayout = new QGridLayout;
Chris@561 58 exampleLayout->setSpacing(4);
Chris@560 59 exampleFrame->setLayout(exampleLayout);
Chris@560 60
Chris@560 61 QPalette palette = exampleFrame->palette();
Chris@560 62 palette.setColor(QPalette::Window, palette.color(QPalette::Base));
Chris@560 63 exampleFrame->setPalette(palette);
Chris@560 64
Chris@560 65 QFont fp;
Chris@908 66 fp.setPointSize(int(floor(fp.pointSize() * 0.9)));
Chris@561 67 // fp.setFixedPitch(true);
Chris@561 68 // fp.setStyleHint(QFont::TypeWriter);
Chris@561 69 // fp.setFamily("Monospaced");
Chris@560 70
Chris@560 71 int columns = format.getColumnCount();
Chris@560 72 QList<QStringList> example = m_format.getExample();
Chris@560 73
Chris@560 74 for (int i = 0; i < columns; ++i) {
Chris@581 75
Chris@560 76 QComboBox *cpc = new QComboBox;
Chris@560 77 m_columnPurposeCombos.push_back(cpc);
Chris@560 78 exampleLayout->addWidget(cpc, 0, i);
Chris@581 79 connect(cpc, SIGNAL(activated(int)), this, SLOT(columnPurposeChanged(int)));
Chris@581 80
Chris@581 81 if (i == m_maxDisplayCols && columns > i + 2) {
Chris@581 82 m_fuzzyColumn = i;
Chris@581 83 cpc->addItem(tr("<ignore>"));
Chris@581 84 cpc->addItem(tr("Values"));
Chris@581 85 cpc->setCurrentIndex
Chris@581 86 (m_format.getColumnPurpose(i-1) == CSVFormat::ColumnUnknown ? 0 : 1);
Chris@581 87 exampleLayout->addWidget(new QLabel(tr("(%1 more)").arg(columns - i)),
Chris@581 88 1, i);
Chris@581 89 break;
Chris@581 90 }
Chris@560 91
Chris@560 92 // NB must be in the same order as the CSVFormat::ColumnPurpose enum
Chris@560 93 cpc->addItem(tr("<ignore>")); // ColumnUnknown
Chris@560 94 cpc->addItem(tr("Time")); // ColumnStartTime
Chris@560 95 cpc->addItem(tr("End time")); // ColumnEndTime
Chris@560 96 cpc->addItem(tr("Duration")); // ColumnDuration
Chris@560 97 cpc->addItem(tr("Value")); // ColumnValue
Chris@763 98 cpc->addItem(tr("Pitch")); // ColumnPitch
Chris@560 99 cpc->addItem(tr("Label")); // ColumnLabel
Chris@560 100 cpc->setCurrentIndex(int(m_format.getColumnPurpose(i)));
Chris@560 101
Chris@581 102 for (int j = 0; j < example.size() && j < 6; ++j) {
Chris@866 103 if (i >= example[j].size()) {
Chris@866 104 continue;
Chris@866 105 }
Chris@581 106 QLabel *label = new QLabel;
Chris@581 107 label->setTextFormat(Qt::PlainText);
Chris@674 108 QString text = TextAbbrev::abbreviate(example[j][i], 35);
Chris@674 109 label->setText(text);
Chris@581 110 label->setFont(fp);
Chris@581 111 label->setPalette(palette);
Chris@581 112 label->setIndent(8);
Chris@581 113 exampleLayout->addWidget(label, j+1, i);
Chris@560 114 }
Chris@560 115 }
Chris@560 116
Chris@560 117 layout->addWidget(exampleFrame, row, 0, 1, 4);
Chris@560 118 layout->setColumnStretch(3, 10);
Chris@560 119 layout->setRowStretch(row++, 10);
Chris@560 120
Chris@560 121 layout->addWidget(new QLabel(tr("Timing is specified:")), row, 0);
Chris@378 122
Chris@378 123 m_timingTypeCombo = new QComboBox;
Chris@959 124
Chris@959 125 m_timingLabels = {
Chris@959 126 { TimingExplicitSeconds, tr("Explicitly, in seconds") },
Chris@959 127 { TimingExplicitMsec, tr("Explicitly, in milliseconds") },
Chris@959 128 { TimingExplicitSamples, tr("Explicitly, in audio sample frames") },
Chris@959 129 { TimingImplicit, tr("Implicitly: rows are equally spaced in time") }
Chris@959 130 };
Chris@959 131
Chris@959 132 for (auto &l: m_timingLabels) {
Chris@959 133 m_timingTypeCombo->addItem(l.second);
Chris@959 134 }
Chris@959 135
Chris@560 136 layout->addWidget(m_timingTypeCombo, row++, 1, 1, 2);
Chris@959 137
Chris@378 138 connect(m_timingTypeCombo, SIGNAL(activated(int)),
Chris@378 139 this, SLOT(timingTypeChanged(int)));
Chris@959 140
Chris@959 141 m_initialTimingOption = TimingImplicit;
Chris@959 142 if (m_format.getTimingType() == CSVFormat::ExplicitTiming) {
Chris@959 143 switch (m_format.getTimeUnits()) {
Chris@959 144 case CSVFormat::TimeSeconds:
Chris@959 145 m_initialTimingOption = TimingExplicitSeconds; break;
Chris@959 146 case CSVFormat::TimeMilliseconds:
Chris@959 147 m_initialTimingOption = TimingExplicitMsec; break;
Chris@959 148 case CSVFormat::TimeAudioFrames:
Chris@959 149 m_initialTimingOption = TimingExplicitSamples; break;
Chris@959 150 case CSVFormat::TimeWindows:
Chris@959 151 m_initialTimingOption = TimingImplicit; break;
Chris@959 152 }
Chris@959 153 }
Chris@959 154 m_timingTypeCombo->setCurrentIndex(int(m_initialTimingOption));
Chris@559 155
Chris@378 156 m_sampleRateLabel = new QLabel(tr("Audio sample rate (Hz):"));
Chris@560 157 layout->addWidget(m_sampleRateLabel, row, 0);
Chris@378 158
Chris@807 159 int sampleRates[] = {
Chris@378 160 8000, 11025, 12000, 22050, 24000, 32000,
Chris@378 161 44100, 48000, 88200, 96000, 176400, 192000
Chris@378 162 };
Chris@378 163
Chris@378 164 m_sampleRateCombo = new QComboBox;
Chris@807 165 for (int i = 0; i < int(sizeof(sampleRates) / sizeof(sampleRates[0])); ++i) {
Chris@378 166 m_sampleRateCombo->addItem(QString("%1").arg(sampleRates[i]));
Chris@560 167 if (sampleRates[i] == m_format.getSampleRate()) {
Chris@560 168 m_sampleRateCombo->setCurrentIndex(i);
Chris@560 169 }
Chris@378 170 }
Chris@378 171 m_sampleRateCombo->setEditable(true);
Chris@378 172
Chris@560 173 layout->addWidget(m_sampleRateCombo, row++, 1);
Chris@378 174 connect(m_sampleRateCombo, SIGNAL(activated(QString)),
Chris@378 175 this, SLOT(sampleRateChanged(QString)));
Chris@378 176 connect(m_sampleRateCombo, SIGNAL(editTextChanged(QString)),
Chris@378 177 this, SLOT(sampleRateChanged(QString)));
Chris@378 178
Chris@378 179 m_windowSizeLabel = new QLabel(tr("Frame increment between rows:"));
Chris@560 180 layout->addWidget(m_windowSizeLabel, row, 0);
Chris@378 181
Chris@378 182 m_windowSizeCombo = new QComboBox;
Chris@378 183 for (int i = 0; i <= 16; ++i) {
Chris@378 184 int value = 1 << i;
Chris@378 185 m_windowSizeCombo->addItem(QString("%1").arg(value));
Chris@560 186 if (value == int(m_format.getWindowSize())) {
Chris@560 187 m_windowSizeCombo->setCurrentIndex(i);
Chris@560 188 }
Chris@378 189 }
Chris@378 190 m_windowSizeCombo->setEditable(true);
Chris@378 191
Chris@560 192 layout->addWidget(m_windowSizeCombo, row++, 1);
Chris@378 193 connect(m_windowSizeCombo, SIGNAL(activated(QString)),
Chris@378 194 this, SLOT(windowSizeChanged(QString)));
Chris@378 195 connect(m_windowSizeCombo, SIGNAL(editTextChanged(QString)),
Chris@378 196 this, SLOT(windowSizeChanged(QString)));
Chris@378 197
Chris@561 198 m_modelLabel = new QLabel;
Chris@561 199 QFont f(m_modelLabel->font());
Chris@561 200 f.setItalic(true);
Chris@561 201 m_modelLabel->setFont(f);
Chris@561 202 layout->addWidget(m_modelLabel, row++, 0, 1, 4);
Chris@561 203
Chris@512 204 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
Chris@512 205 QDialogButtonBox::Cancel);
Chris@560 206 layout->addWidget(bb, row++, 0, 1, 4);
Chris@512 207 connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
Chris@512 208 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
Chris@378 209
Chris@512 210 setLayout(layout);
Chris@378 211
Chris@378 212 timingTypeChanged(m_timingTypeCombo->currentIndex());
Chris@378 213 }
Chris@378 214
Chris@378 215 CSVFormatDialog::~CSVFormatDialog()
Chris@378 216 {
Chris@378 217 }
Chris@378 218
Chris@378 219 CSVFormat
Chris@378 220 CSVFormatDialog::getFormat() const
Chris@378 221 {
Chris@560 222 return m_format;
Chris@378 223 }
Chris@378 224
Chris@378 225 void
Chris@561 226 CSVFormatDialog::updateModelLabel()
Chris@378 227 {
Chris@561 228 LayerFactory *f = LayerFactory::getInstance();
Chris@561 229
Chris@561 230 QString s;
Chris@561 231 switch (m_format.getModelType()) {
Chris@561 232 case CSVFormat::OneDimensionalModel:
Chris@561 233 s = f->getLayerPresentationName(LayerFactory::TimeInstants);
Chris@561 234 break;
Chris@561 235 case CSVFormat::TwoDimensionalModel:
Chris@561 236 s = f->getLayerPresentationName(LayerFactory::TimeValues);
Chris@561 237 break;
Chris@561 238 case CSVFormat::TwoDimensionalModelWithDuration:
Chris@561 239 s = f->getLayerPresentationName(LayerFactory::Regions);
Chris@561 240 break;
Chris@763 241 case CSVFormat::TwoDimensionalModelWithDurationAndPitch:
Chris@763 242 s = f->getLayerPresentationName(LayerFactory::Notes);
Chris@763 243 break;
Chris@561 244 case CSVFormat::ThreeDimensionalModel:
Chris@561 245 s = f->getLayerPresentationName(LayerFactory::Colour3DPlot);
Chris@561 246 break;
Chris@561 247 }
Chris@561 248
Chris@578 249 m_modelLabel->setText("\n" + tr("Data will be displayed in a %1 layer.").arg(s));
Chris@378 250 }
Chris@378 251
Chris@378 252 void
Chris@959 253 CSVFormatDialog::applyStartTimePurpose()
Chris@959 254 {
Chris@971 255 // First check if we already have any. NB there may be fewer than
Chris@971 256 // m_format.getColumnCount() elements in m_columnPurposeCombos
Chris@992 257 // (because of the fuzzy column behaviour). Note also that the
Chris@992 258 // fuzzy column (which is the one just showing how many more
Chris@992 259 // columns there are) has a different combo with only two items
Chris@992 260 // (ignore or Values)
Chris@971 261 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
Chris@992 262 if (i == m_fuzzyColumn) continue;
Chris@959 263 QComboBox *cb = m_columnPurposeCombos[i];
Chris@959 264 if (cb->currentIndex() == int(CSVFormat::ColumnStartTime)) {
Chris@959 265 return;
Chris@959 266 }
Chris@959 267 }
Chris@959 268 // and if not, select one
Chris@971 269 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
Chris@992 270 if (i == m_fuzzyColumn) continue;
Chris@959 271 QComboBox *cb = m_columnPurposeCombos[i];
Chris@959 272 if (cb->currentIndex() == int(CSVFormat::ColumnValue)) {
Chris@959 273 cb->setCurrentIndex(int(CSVFormat::ColumnStartTime));
Chris@959 274 return;
Chris@959 275 }
Chris@959 276 }
Chris@959 277 }
Chris@959 278
Chris@959 279 void
Chris@959 280 CSVFormatDialog::removeStartTimePurpose()
Chris@959 281 {
Chris@971 282 // NB there may be fewer than m_format.getColumnCount() elements
Chris@971 283 // in m_columnPurposeCombos (because of the fuzzy column
Chris@971 284 // behaviour)
Chris@971 285 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
Chris@992 286 if (i == m_fuzzyColumn) continue;
Chris@959 287 QComboBox *cb = m_columnPurposeCombos[i];
Chris@959 288 if (cb->currentIndex() == int(CSVFormat::ColumnStartTime)) {
Chris@959 289 cb->setCurrentIndex(int(CSVFormat::ColumnValue));
Chris@959 290 }
Chris@959 291 }
Chris@959 292 }
Chris@959 293
Chris@959 294 void
Chris@959 295 CSVFormatDialog::updateComboVisibility()
Chris@959 296 {
Chris@959 297 bool wantRate = (m_format.getTimingType() == CSVFormat::ImplicitTiming ||
Chris@959 298 m_format.getTimeUnits() == CSVFormat::TimeAudioFrames);
Chris@959 299 bool wantWindow = (m_format.getTimingType() == CSVFormat::ImplicitTiming);
Chris@959 300
Chris@959 301 m_sampleRateCombo->setEnabled(wantRate);
Chris@959 302 m_sampleRateLabel->setEnabled(wantRate);
Chris@959 303
Chris@959 304 m_windowSizeCombo->setEnabled(wantWindow);
Chris@959 305 m_windowSizeLabel->setEnabled(wantWindow);
Chris@959 306 }
Chris@959 307
Chris@959 308 void
Chris@378 309 CSVFormatDialog::timingTypeChanged(int type)
Chris@378 310 {
Chris@959 311 // Update any column purpose combos
Chris@959 312 if (TimingOption(type) == TimingImplicit) {
Chris@959 313 removeStartTimePurpose();
Chris@959 314 } else {
Chris@959 315 applyStartTimePurpose();
Chris@378 316 }
Chris@959 317 updateFormatFromDialog();
Chris@959 318 updateComboVisibility();
Chris@559 319 }
Chris@559 320
Chris@559 321 void
Chris@378 322 CSVFormatDialog::sampleRateChanged(QString rateString)
Chris@378 323 {
Chris@378 324 bool ok = false;
Chris@378 325 int sampleRate = rateString.toInt(&ok);
Chris@560 326 if (ok) m_format.setSampleRate(sampleRate);
Chris@378 327 }
Chris@378 328
Chris@378 329 void
Chris@378 330 CSVFormatDialog::windowSizeChanged(QString sizeString)
Chris@378 331 {
Chris@378 332 bool ok = false;
Chris@378 333 int size = sizeString.toInt(&ok);
Chris@560 334 if (ok) m_format.setWindowSize(size);
Chris@378 335 }
Chris@560 336
Chris@560 337 void
Chris@561 338 CSVFormatDialog::columnPurposeChanged(int p)
Chris@560 339 {
Chris@560 340 QObject *o = sender();
Chris@560 341 QComboBox *cb = qobject_cast<QComboBox *>(o);
Chris@560 342 if (!cb) return;
Chris@561 343
Chris@561 344 CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose)p;
Chris@561 345
Chris@959 346 bool haveStartTime = false; // so as to update timing type combo appropriately
Chris@959 347
Chris@959 348 // Ensure the column purpose combos are consistent with one
Chris@959 349 // another, without reference to m_format (which we'll update
Chris@959 350 // separately)
Chris@959 351
Chris@560 352 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
Chris@561 353
Chris@992 354 // The fuzzy column combo only has the entries <ignore> or
Chris@992 355 // Values, so it can't affect the timing type and none of this
Chris@992 356 // logic affects it
Chris@992 357 if (i == m_fuzzyColumn) continue;
Chris@992 358
Chris@959 359 QComboBox *thisCombo = m_columnPurposeCombos[i];
Chris@561 360
Chris@959 361 CSVFormat::ColumnPurpose cp = (CSVFormat::ColumnPurpose)
Chris@959 362 (thisCombo->currentIndex());
Chris@959 363 bool thisChanged = (cb == thisCombo);
Chris@959 364
Chris@959 365 if (!thisChanged) {
Chris@561 366
Chris@561 367 // We can only have one ColumnStartTime column, and only
Chris@561 368 // one of either ColumnDuration or ColumnEndTime
Chris@561 369
Chris@561 370 if (purpose == CSVFormat::ColumnStartTime) {
Chris@561 371 if (cp == purpose) {
Chris@561 372 cp = CSVFormat::ColumnValue;
Chris@561 373 }
Chris@561 374 } else if (purpose == CSVFormat::ColumnDuration ||
Chris@561 375 purpose == CSVFormat::ColumnEndTime) {
Chris@561 376 if (cp == CSVFormat::ColumnDuration ||
Chris@561 377 cp == CSVFormat::ColumnEndTime) {
Chris@561 378 cp = CSVFormat::ColumnValue;
Chris@561 379 }
Chris@561 380 }
Chris@561 381
Chris@561 382 // And we can only have one label
Chris@561 383 if (purpose == CSVFormat::ColumnLabel) {
Chris@561 384 if (cp == purpose) {
Chris@561 385 cp = CSVFormat::ColumnUnknown;
Chris@561 386 }
Chris@561 387 }
Chris@959 388
Chris@959 389 if (cp == CSVFormat::ColumnStartTime) {
Chris@959 390 haveStartTime = true;
Chris@959 391 }
Chris@959 392
Chris@959 393 thisCombo->setCurrentIndex(int(cp));
Chris@959 394
Chris@959 395 } else {
Chris@959 396 if (purpose == CSVFormat::ColumnStartTime) {
Chris@959 397 haveStartTime = true;
Chris@959 398 }
Chris@561 399 }
Chris@959 400 }
Chris@561 401
Chris@959 402 if (!haveStartTime) {
Chris@959 403 m_timingTypeCombo->setCurrentIndex(int(TimingImplicit));
Chris@959 404 } else if (m_timingTypeCombo->currentIndex() == int(TimingImplicit)) {
Chris@959 405 if (m_initialTimingOption == TimingImplicit) {
Chris@959 406 m_timingTypeCombo->setCurrentIndex(TimingExplicitSeconds);
Chris@959 407 } else {
Chris@959 408 m_timingTypeCombo->setCurrentIndex(m_initialTimingOption);
Chris@959 409 }
Chris@959 410 }
Chris@959 411
Chris@959 412 updateFormatFromDialog();
Chris@959 413 updateComboVisibility();
Chris@959 414 }
Chris@959 415
Chris@959 416 void
Chris@959 417 CSVFormatDialog::updateFormatFromDialog()
Chris@959 418 {
Chris@959 419 switch (TimingOption(m_timingTypeCombo->currentIndex())) {
Chris@959 420
Chris@959 421 case TimingExplicitSeconds:
Chris@959 422 m_format.setTimingType(CSVFormat::ExplicitTiming);
Chris@959 423 m_format.setTimeUnits(CSVFormat::TimeSeconds);
Chris@959 424 break;
Chris@959 425
Chris@959 426 case TimingExplicitMsec:
Chris@959 427 m_format.setTimingType(CSVFormat::ExplicitTiming);
Chris@959 428 m_format.setTimeUnits(CSVFormat::TimeMilliseconds);
Chris@959 429 break;
Chris@959 430
Chris@959 431 case TimingExplicitSamples:
Chris@959 432 m_format.setTimingType(CSVFormat::ExplicitTiming);
Chris@959 433 m_format.setTimeUnits(CSVFormat::TimeAudioFrames);
Chris@959 434 break;
Chris@959 435
Chris@959 436 case TimingImplicit:
Chris@959 437 m_format.setTimingType(CSVFormat::ImplicitTiming);
Chris@959 438 m_format.setTimeUnits(CSVFormat::TimeWindows);
Chris@959 439 break;
Chris@959 440 }
Chris@959 441
Chris@959 442 bool haveStartTime = false;
Chris@959 443 bool haveDuration = false;
Chris@959 444 bool havePitch = false;
Chris@959 445 int valueCount = 0;
Chris@959 446
Chris@959 447 for (int i = 0; i < m_columnPurposeCombos.size(); ++i) {
Chris@959 448
Chris@959 449 QComboBox *thisCombo = m_columnPurposeCombos[i];
Chris@959 450
Chris@959 451 CSVFormat::ColumnPurpose purpose = (CSVFormat::ColumnPurpose)
Chris@959 452 (thisCombo->currentIndex());
Chris@959 453
Chris@959 454 if (i == m_fuzzyColumn) {
Chris@992 455 for (int j = i; j < m_format.getColumnCount(); ++j) {
Chris@959 456 if (purpose == CSVFormat::ColumnUnknown) {
Chris@959 457 m_format.setColumnPurpose(j, CSVFormat::ColumnUnknown);
Chris@959 458 } else { // Value
Chris@959 459 m_format.setColumnPurpose(j, CSVFormat::ColumnValue);
Chris@959 460 ++valueCount;
Chris@959 461 }
Chris@959 462 }
Chris@992 463 } else {
Chris@992 464
Chris@992 465 if (purpose == CSVFormat::ColumnStartTime) {
Chris@992 466 haveStartTime = true;
Chris@992 467 }
Chris@992 468 if (purpose == CSVFormat::ColumnEndTime ||
Chris@992 469 purpose == CSVFormat::ColumnDuration) {
Chris@992 470 haveDuration = true;
Chris@992 471 }
Chris@992 472 if (purpose == CSVFormat::ColumnPitch) {
Chris@992 473 havePitch = true;
Chris@992 474 }
Chris@992 475 if (purpose == CSVFormat::ColumnValue) {
Chris@992 476 ++valueCount;
Chris@992 477 }
Chris@992 478
Chris@992 479 m_format.setColumnPurpose(i, purpose);
Chris@959 480 }
Chris@561 481 }
Chris@561 482
Chris@561 483 if (haveStartTime && haveDuration) {
Chris@763 484 if (havePitch) {
Chris@763 485 m_format.setModelType(CSVFormat::TwoDimensionalModelWithDurationAndPitch);
Chris@763 486 } else {
Chris@763 487 m_format.setModelType(CSVFormat::TwoDimensionalModelWithDuration);
Chris@763 488 }
Chris@561 489 } else {
Chris@561 490 if (valueCount > 1) {
Chris@561 491 m_format.setModelType(CSVFormat::ThreeDimensionalModel);
Chris@561 492 } else if (valueCount > 0) {
Chris@561 493 m_format.setModelType(CSVFormat::TwoDimensionalModel);
Chris@561 494 } else {
Chris@561 495 m_format.setModelType(CSVFormat::OneDimensionalModel);
Chris@560 496 }
Chris@560 497 }
Chris@561 498
Chris@561 499 updateModelLabel();
Chris@560 500 }
Chris@560 501
Chris@560 502
Chris@959 503