annotate widgets/CSVFormatDialog.cpp @ 1363:bbeffb29bf09

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