annotate framework/SVFileReader.cpp @ 122:ab861544f998

* Comment out problematic test -- sincerequest_t always seemed to be zero when this line was reached, so the pointer was often getting stuck if you asked to play a loop that had been drawn to the left of the position the pointer was at when you then tried to play it
author Chris Cannam
date Fri, 06 Jun 2008 10:32:50 +0000
parents 9554c19c42fd
children e2aec1708a2c
rev   line source
Chris@45 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@45 2
Chris@45 3 /*
Chris@45 4 Sonic Visualiser
Chris@45 5 An audio file viewer and annotation editor.
Chris@45 6 Centre for Digital Music, Queen Mary, University of London.
Chris@45 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@45 8
Chris@45 9 This program is free software; you can redistribute it and/or
Chris@45 10 modify it under the terms of the GNU General Public License as
Chris@45 11 published by the Free Software Foundation; either version 2 of the
Chris@45 12 License, or (at your option) any later version. See the file
Chris@45 13 COPYING included with this distribution for more information.
Chris@45 14 */
Chris@45 15
Chris@45 16 #include "SVFileReader.h"
Chris@45 17
Chris@45 18 #include "layer/Layer.h"
Chris@45 19 #include "view/View.h"
Chris@45 20 #include "base/PlayParameters.h"
Chris@45 21 #include "base/PlayParameterRepository.h"
Chris@116 22 #include "base/Preferences.h"
Chris@45 23
Chris@45 24 #include "data/fileio/AudioFileReaderFactory.h"
Chris@45 25 #include "data/fileio/FileSource.h"
Chris@45 26
Chris@109 27 #include "widgets/FileFinder.h"
Chris@109 28
Chris@45 29 #include "data/model/WaveFileModel.h"
Chris@45 30 #include "data/model/EditableDenseThreeDimensionalModel.h"
Chris@45 31 #include "data/model/SparseOneDimensionalModel.h"
Chris@45 32 #include "data/model/SparseTimeValueModel.h"
Chris@45 33 #include "data/model/NoteModel.h"
Chris@45 34 #include "data/model/TextModel.h"
Chris@45 35 #include "data/model/ImageModel.h"
Chris@111 36 #include "data/model/AlignmentModel.h"
Chris@45 37
Chris@106 38 #include "transform/TransformFactory.h"
Chris@72 39
Chris@45 40 #include "view/Pane.h"
Chris@45 41
Chris@109 42 #include "widgets/ProgressDialog.h"
Chris@109 43
Chris@45 44 #include "Document.h"
Chris@45 45
Chris@45 46 #include <QString>
Chris@45 47 #include <QMessageBox>
Chris@45 48 #include <QFileDialog>
Chris@45 49
Chris@45 50 #include <iostream>
Chris@45 51
Chris@45 52 SVFileReader::SVFileReader(Document *document,
Chris@45 53 SVFileReaderPaneCallback &callback,
Chris@45 54 QString location) :
Chris@45 55 m_document(document),
Chris@45 56 m_paneCallback(callback),
Chris@45 57 m_location(location),
Chris@45 58 m_currentPane(0),
Chris@45 59 m_currentDataset(0),
Chris@45 60 m_currentDerivedModel(0),
Chris@45 61 m_currentDerivedModelId(-1),
Chris@45 62 m_currentPlayParameters(0),
Chris@72 63 m_currentTransformSource(0),
Chris@45 64 m_datasetSeparator(" "),
Chris@45 65 m_inRow(false),
Chris@45 66 m_inLayer(false),
Chris@45 67 m_inView(false),
Chris@45 68 m_rowNumber(0),
Chris@45 69 m_ok(false)
Chris@45 70 {
Chris@45 71 }
Chris@45 72
Chris@45 73 void
Chris@45 74 SVFileReader::parse(const QString &xmlData)
Chris@45 75 {
Chris@45 76 QXmlInputSource inputSource;
Chris@45 77 inputSource.setData(xmlData);
Chris@45 78 parse(inputSource);
Chris@45 79 }
Chris@45 80
Chris@45 81 void
Chris@45 82 SVFileReader::parse(QXmlInputSource &inputSource)
Chris@45 83 {
Chris@45 84 QXmlSimpleReader reader;
Chris@45 85 reader.setContentHandler(this);
Chris@45 86 reader.setErrorHandler(this);
Chris@45 87 m_ok = reader.parse(inputSource);
Chris@45 88 }
Chris@45 89
Chris@45 90 bool
Chris@45 91 SVFileReader::isOK()
Chris@45 92 {
Chris@45 93 return m_ok;
Chris@45 94 }
Chris@45 95
Chris@45 96 SVFileReader::~SVFileReader()
Chris@45 97 {
Chris@45 98 if (!m_awaitingDatasets.empty()) {
Chris@45 99 std::cerr << "WARNING: SV-XML: File ended with "
Chris@45 100 << m_awaitingDatasets.size() << " unfilled model dataset(s)"
Chris@45 101 << std::endl;
Chris@45 102 }
Chris@45 103
Chris@45 104 std::set<Model *> unaddedModels;
Chris@45 105
Chris@45 106 for (std::map<int, Model *>::iterator i = m_models.begin();
Chris@45 107 i != m_models.end(); ++i) {
Chris@45 108 if (m_addedModels.find(i->second) == m_addedModels.end()) {
Chris@45 109 unaddedModels.insert(i->second);
Chris@45 110 }
Chris@45 111 }
Chris@45 112
Chris@45 113 if (!unaddedModels.empty()) {
Chris@45 114 std::cerr << "WARNING: SV-XML: File contained "
Chris@45 115 << unaddedModels.size() << " unused models"
Chris@45 116 << std::endl;
Chris@45 117 while (!unaddedModels.empty()) {
Chris@45 118 delete *unaddedModels.begin();
Chris@45 119 unaddedModels.erase(unaddedModels.begin());
Chris@45 120 }
Chris@45 121 }
Chris@45 122 }
Chris@45 123
Chris@45 124 bool
Chris@45 125 SVFileReader::startElement(const QString &, const QString &,
Chris@45 126 const QString &qName,
Chris@45 127 const QXmlAttributes &attributes)
Chris@45 128 {
Chris@45 129 QString name = qName.toLower();
Chris@45 130
Chris@45 131 bool ok = false;
Chris@45 132
Chris@45 133 // Valid element names:
Chris@45 134 //
Chris@45 135 // sv
Chris@45 136 // data
Chris@45 137 // dataset
Chris@45 138 // display
Chris@45 139 // derivation
Chris@45 140 // playparameters
Chris@45 141 // layer
Chris@45 142 // model
Chris@45 143 // point
Chris@45 144 // row
Chris@45 145 // view
Chris@45 146 // window
Chris@72 147 // plugin
Chris@72 148 // transform
Chris@72 149 // selections
Chris@72 150 // selection
Chris@72 151 // measurement
Chris@45 152
Chris@45 153 if (name == "sv") {
Chris@45 154
Chris@45 155 // nothing needed
Chris@45 156 ok = true;
Chris@45 157
Chris@45 158 } else if (name == "data") {
Chris@45 159
Chris@45 160 // nothing needed
Chris@45 161 m_inData = true;
Chris@45 162 ok = true;
Chris@45 163
Chris@45 164 } else if (name == "display") {
Chris@45 165
Chris@45 166 // nothing needed
Chris@45 167 ok = true;
Chris@45 168
Chris@45 169 } else if (name == "window") {
Chris@45 170
Chris@45 171 ok = readWindow(attributes);
Chris@45 172
Chris@45 173 } else if (name == "model") {
Chris@45 174
Chris@45 175 ok = readModel(attributes);
Chris@45 176
Chris@45 177 } else if (name == "dataset") {
Chris@45 178
Chris@45 179 ok = readDatasetStart(attributes);
Chris@45 180
Chris@45 181 } else if (name == "bin") {
Chris@45 182
Chris@45 183 ok = addBinToDataset(attributes);
Chris@45 184
Chris@45 185 } else if (name == "point") {
Chris@45 186
Chris@45 187 ok = addPointToDataset(attributes);
Chris@45 188
Chris@45 189 } else if (name == "row") {
Chris@45 190
Chris@45 191 ok = addRowToDataset(attributes);
Chris@45 192
Chris@45 193 } else if (name == "layer") {
Chris@45 194
Chris@45 195 addUnaddedModels(); // all models must be specified before first layer
Chris@45 196 ok = readLayer(attributes);
Chris@45 197
Chris@45 198 } else if (name == "view") {
Chris@45 199
Chris@45 200 m_inView = true;
Chris@45 201 ok = readView(attributes);
Chris@45 202
Chris@45 203 } else if (name == "derivation") {
Chris@45 204
Chris@45 205 ok = readDerivation(attributes);
Chris@45 206
Chris@45 207 } else if (name == "playparameters") {
Chris@45 208
Chris@45 209 ok = readPlayParameters(attributes);
Chris@45 210
Chris@45 211 } else if (name == "plugin") {
Chris@45 212
Chris@45 213 ok = readPlugin(attributes);
Chris@45 214
Chris@45 215 } else if (name == "selections") {
Chris@45 216
Chris@45 217 m_inSelections = true;
Chris@45 218 ok = true;
Chris@45 219
Chris@45 220 } else if (name == "selection") {
Chris@45 221
Chris@45 222 ok = readSelection(attributes);
Chris@45 223
Chris@45 224 } else if (name == "measurement") {
Chris@45 225
Chris@45 226 ok = readMeasurement(attributes);
Chris@45 227
Chris@72 228 } else if (name == "transform") {
Chris@72 229
Chris@72 230 ok = readTransform(attributes);
Chris@72 231
Chris@72 232 } else if (name == "parameter") {
Chris@72 233
Chris@72 234 ok = readParameter(attributes);
Chris@72 235
Chris@45 236 } else {
Chris@45 237 std::cerr << "WARNING: SV-XML: Unexpected element \""
Chris@45 238 << name.toLocal8Bit().data() << "\"" << std::endl;
Chris@45 239 }
Chris@45 240
Chris@45 241 if (!ok) {
Chris@45 242 std::cerr << "WARNING: SV-XML: Failed to completely process element \""
Chris@45 243 << name.toLocal8Bit().data() << "\"" << std::endl;
Chris@45 244 }
Chris@45 245
Chris@45 246 return true;
Chris@45 247 }
Chris@45 248
Chris@45 249 bool
Chris@45 250 SVFileReader::characters(const QString &text)
Chris@45 251 {
Chris@45 252 bool ok = false;
Chris@45 253
Chris@45 254 if (m_inRow) {
Chris@45 255 ok = readRowData(text);
Chris@45 256 if (!ok) {
Chris@45 257 std::cerr << "WARNING: SV-XML: Failed to read row data content for row " << m_rowNumber << std::endl;
Chris@45 258 }
Chris@45 259 }
Chris@45 260
Chris@45 261 return true;
Chris@45 262 }
Chris@45 263
Chris@45 264 bool
Chris@45 265 SVFileReader::endElement(const QString &, const QString &,
Chris@45 266 const QString &qName)
Chris@45 267 {
Chris@45 268 QString name = qName.toLower();
Chris@45 269
Chris@45 270 if (name == "dataset") {
Chris@45 271
Chris@45 272 if (m_currentDataset) {
Chris@45 273
Chris@45 274 bool foundInAwaiting = false;
Chris@45 275
Chris@45 276 for (std::map<int, int>::iterator i = m_awaitingDatasets.begin();
Chris@45 277 i != m_awaitingDatasets.end(); ++i) {
Chris@45 278 if (haveModel(i->second) &&
Chris@45 279 m_models[i->second] == m_currentDataset) {
Chris@45 280 m_awaitingDatasets.erase(i);
Chris@45 281 foundInAwaiting = true;
Chris@45 282 break;
Chris@45 283 }
Chris@45 284 }
Chris@45 285
Chris@45 286 if (!foundInAwaiting) {
Chris@45 287 std::cerr << "WARNING: SV-XML: Dataset precedes model, or no model uses dataset" << std::endl;
Chris@45 288 }
Chris@45 289 }
Chris@45 290
Chris@45 291 m_currentDataset = 0;
Chris@45 292
Chris@45 293 } else if (name == "data") {
Chris@45 294
Chris@45 295 addUnaddedModels();
Chris@45 296 m_inData = false;
Chris@45 297
Chris@45 298 } else if (name == "derivation") {
Chris@45 299
Chris@45 300 if (!m_currentDerivedModel) {
Chris@45 301 if (m_currentDerivedModel < 0) {
Chris@45 302 std::cerr << "WARNING: SV-XML: Bad derivation output model id "
Chris@45 303 << m_currentDerivedModelId << std::endl;
Chris@45 304 } else if (haveModel(m_currentDerivedModelId)) {
Chris@45 305 std::cerr << "WARNING: SV-XML: Derivation has existing model "
Chris@45 306 << m_currentDerivedModelId
Chris@45 307 << " as target, not regenerating" << std::endl;
Chris@45 308 } else {
Chris@78 309 QString message;
Chris@45 310 m_currentDerivedModel = m_models[m_currentDerivedModelId] =
Chris@72 311 m_document->addDerivedModel
Chris@72 312 (m_currentTransform,
Chris@72 313 ModelTransformer::Input(m_currentTransformSource,
Chris@78 314 m_currentTransformChannel),
Chris@78 315 message);
Chris@79 316 if (!m_currentDerivedModel) {
Chris@79 317 emit modelRegenerationFailed(tr("(derived model in SV-XML)"),
Chris@79 318 m_currentTransform.getIdentifier(),
Chris@79 319 message);
Chris@79 320 } else if (message != "") {
Chris@79 321 emit modelRegenerationWarning(tr("(derived model in SV-XML)"),
Chris@79 322 m_currentTransform.getIdentifier(),
Chris@79 323 message);
Chris@79 324 }
Chris@45 325 }
Chris@45 326 } else {
Chris@72 327 m_document->addDerivedModel
Chris@72 328 (m_currentTransform,
Chris@72 329 ModelTransformer::Input(m_currentTransformSource,
Chris@72 330 m_currentTransformChannel),
Chris@72 331 m_currentDerivedModel);
Chris@45 332 }
Chris@45 333
Chris@45 334 m_addedModels.insert(m_currentDerivedModel);
Chris@45 335 m_currentDerivedModel = 0;
Chris@45 336 m_currentDerivedModelId = -1;
Chris@72 337 m_currentTransformSource = 0;
Chris@72 338 m_currentTransform = Transform();
Chris@72 339 m_currentTransformChannel = -1;
Chris@45 340
Chris@45 341 } else if (name == "row") {
Chris@45 342 m_inRow = false;
Chris@45 343 } else if (name == "layer") {
Chris@45 344 m_inLayer = false;
Chris@45 345 } else if (name == "view") {
Chris@45 346 m_inView = false;
Chris@45 347 } else if (name == "selections") {
Chris@45 348 m_inSelections = false;
Chris@45 349 } else if (name == "playparameters") {
Chris@45 350 m_currentPlayParameters = 0;
Chris@45 351 }
Chris@45 352
Chris@45 353 return true;
Chris@45 354 }
Chris@45 355
Chris@45 356 bool
Chris@45 357 SVFileReader::error(const QXmlParseException &exception)
Chris@45 358 {
Chris@45 359 m_errorString =
Chris@45 360 QString("ERROR: SV-XML: %1 at line %2, column %3")
Chris@45 361 .arg(exception.message())
Chris@45 362 .arg(exception.lineNumber())
Chris@45 363 .arg(exception.columnNumber());
Chris@45 364 std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
Chris@45 365 return QXmlDefaultHandler::error(exception);
Chris@45 366 }
Chris@45 367
Chris@45 368 bool
Chris@45 369 SVFileReader::fatalError(const QXmlParseException &exception)
Chris@45 370 {
Chris@45 371 m_errorString =
Chris@45 372 QString("FATAL ERROR: SV-XML: %1 at line %2, column %3")
Chris@45 373 .arg(exception.message())
Chris@45 374 .arg(exception.lineNumber())
Chris@45 375 .arg(exception.columnNumber());
Chris@45 376 std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
Chris@45 377 return QXmlDefaultHandler::fatalError(exception);
Chris@45 378 }
Chris@45 379
Chris@45 380
Chris@45 381 #define READ_MANDATORY(TYPE, NAME, CONVERSION) \
Chris@45 382 TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \
Chris@45 383 if (!ok) { \
Chris@45 384 std::cerr << "WARNING: SV-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << std::endl; \
Chris@45 385 return false; \
Chris@45 386 }
Chris@45 387
Chris@45 388 bool
Chris@45 389 SVFileReader::readWindow(const QXmlAttributes &attributes)
Chris@45 390 {
Chris@45 391 bool ok = false;
Chris@45 392
Chris@45 393 READ_MANDATORY(int, width, toInt);
Chris@45 394 READ_MANDATORY(int, height, toInt);
Chris@45 395
Chris@45 396 m_paneCallback.setWindowSize(width, height);
Chris@45 397 return true;
Chris@45 398 }
Chris@45 399
Chris@45 400 void
Chris@45 401 SVFileReader::addUnaddedModels()
Chris@45 402 {
Chris@45 403 std::set<Model *> unaddedModels;
Chris@45 404
Chris@45 405 for (std::map<int, Model *>::iterator i = m_models.begin();
Chris@45 406 i != m_models.end(); ++i) {
Chris@45 407 if (m_addedModels.find(i->second) == m_addedModels.end()) {
Chris@45 408 unaddedModels.insert(i->second);
Chris@45 409 }
Chris@45 410 }
Chris@45 411
Chris@45 412 for (std::set<Model *>::iterator i = unaddedModels.begin();
Chris@45 413 i != unaddedModels.end(); ++i) {
Chris@45 414 m_document->addImportedModel(*i);
Chris@45 415 m_addedModels.insert(*i);
Chris@45 416 }
Chris@45 417 }
Chris@45 418
Chris@45 419 bool
Chris@45 420 SVFileReader::readModel(const QXmlAttributes &attributes)
Chris@45 421 {
Chris@45 422 bool ok = false;
Chris@45 423
Chris@45 424 READ_MANDATORY(int, id, toInt);
Chris@45 425
Chris@45 426 if (haveModel(id)) {
Chris@45 427 std::cerr << "WARNING: SV-XML: Ignoring duplicate model id " << id
Chris@45 428 << std::endl;
Chris@45 429 return false;
Chris@45 430 }
Chris@45 431
Chris@45 432 QString name = attributes.value("name");
Chris@45 433
Chris@45 434 std::cerr << "SVFileReader::readModel: model name \"" << name.toStdString() << "\"" << std::endl;
Chris@45 435
Chris@45 436 READ_MANDATORY(int, sampleRate, toInt);
Chris@45 437
Chris@45 438 QString type = attributes.value("type").trimmed();
Chris@45 439 bool mainModel = (attributes.value("mainModel").trimmed() == "true");
Chris@45 440
Chris@45 441 if (type == "wavefile") {
Chris@45 442
Chris@45 443 WaveFileModel *model = 0;
Chris@45 444 FileFinder *ff = FileFinder::getInstance();
Chris@45 445 QString originalPath = attributes.value("file");
Chris@45 446 QString path = ff->find(FileFinder::AudioFile,
Chris@45 447 originalPath, m_location);
Chris@45 448
Chris@109 449 ProgressDialog dialog(tr("Opening file or URL..."), true, 2000);
Chris@109 450 FileSource file(path, &dialog);
Chris@45 451 file.waitForStatus();
Chris@45 452
Chris@45 453 if (!file.isOK()) {
Chris@45 454 std::cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path.toStdString() << "\" for wave file model: " << file.getErrorString().toStdString() << std::endl;
Chris@45 455 } else if (!file.isAvailable()) {
Chris@45 456 std::cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path.toStdString() << "\" for wave file model: Source unavailable" << std::endl;
Chris@45 457 } else {
Chris@45 458
Chris@45 459 file.waitForData();
Chris@116 460
Chris@116 461 size_t rate = 0;
Chris@116 462
Chris@116 463 if (!mainModel &&
Chris@116 464 Preferences::getInstance()->getResampleOnLoad()) {
Chris@116 465 WaveFileModel *mm = m_document->getMainModel();
Chris@116 466 if (mm) rate = mm->getSampleRate();
Chris@116 467 }
Chris@116 468
Chris@116 469 model = new WaveFileModel(file, rate);
Chris@45 470 if (!model->isOK()) {
Chris@45 471 delete model;
Chris@45 472 model = 0;
Chris@45 473 }
Chris@45 474 }
Chris@45 475
Chris@45 476 if (!model) return false;
Chris@45 477
Chris@45 478 model->setObjectName(name);
Chris@45 479 m_models[id] = model;
Chris@45 480 if (mainModel) {
Chris@45 481 m_document->setMainModel(model);
Chris@45 482 m_addedModels.insert(model);
Chris@45 483 }
Chris@45 484 // Derived models will be added when their derivation
Chris@45 485 // is found.
Chris@45 486
Chris@45 487 return true;
Chris@45 488
Chris@45 489 } else if (type == "dense") {
Chris@45 490
Chris@45 491 READ_MANDATORY(int, dimensions, toInt);
Chris@45 492
Chris@45 493 // Currently the only dense model we support here is the dense
Chris@45 494 // 3d model. Dense time-value models are always file-backed
Chris@45 495 // waveform data, at this point, and they come in as wavefile
Chris@45 496 // models.
Chris@45 497
Chris@45 498 if (dimensions == 3) {
Chris@45 499
Chris@45 500 READ_MANDATORY(int, windowSize, toInt);
Chris@45 501 READ_MANDATORY(int, yBinCount, toInt);
Chris@45 502
Chris@45 503 EditableDenseThreeDimensionalModel *model =
Chris@45 504 new EditableDenseThreeDimensionalModel
Chris@45 505 (sampleRate, windowSize, yBinCount);
Chris@45 506
Chris@45 507 float minimum = attributes.value("minimum").trimmed().toFloat(&ok);
Chris@45 508 if (ok) model->setMinimumLevel(minimum);
Chris@45 509
Chris@45 510 float maximum = attributes.value("maximum").trimmed().toFloat(&ok);
Chris@45 511 if (ok) model->setMaximumLevel(maximum);
Chris@45 512
Chris@45 513 int dataset = attributes.value("dataset").trimmed().toInt(&ok);
Chris@45 514 if (ok) m_awaitingDatasets[dataset] = id;
Chris@45 515
Chris@45 516 model->setObjectName(name);
Chris@45 517 m_models[id] = model;
Chris@45 518 return true;
Chris@45 519
Chris@45 520 } else {
Chris@45 521
Chris@45 522 std::cerr << "WARNING: SV-XML: Unexpected dense model dimension ("
Chris@45 523 << dimensions << ")" << std::endl;
Chris@45 524 }
Chris@45 525 } else if (type == "sparse") {
Chris@45 526
Chris@45 527 READ_MANDATORY(int, dimensions, toInt);
Chris@45 528
Chris@45 529 if (dimensions == 1) {
Chris@45 530
Chris@45 531 READ_MANDATORY(int, resolution, toInt);
Chris@45 532
Chris@45 533 if (attributes.value("subtype") == "image") {
Chris@45 534
Chris@45 535 bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true");
Chris@45 536 ImageModel *model = new ImageModel(sampleRate, resolution,
Chris@45 537 notifyOnAdd);
Chris@45 538 model->setObjectName(name);
Chris@45 539 m_models[id] = model;
Chris@45 540
Chris@45 541 } else {
Chris@45 542
Chris@45 543 SparseOneDimensionalModel *model = new SparseOneDimensionalModel
Chris@45 544 (sampleRate, resolution);
Chris@45 545 model->setObjectName(name);
Chris@45 546 m_models[id] = model;
Chris@45 547 }
Chris@45 548
Chris@45 549 int dataset = attributes.value("dataset").trimmed().toInt(&ok);
Chris@45 550 if (ok) m_awaitingDatasets[dataset] = id;
Chris@45 551
Chris@45 552 return true;
Chris@45 553
Chris@45 554 } else if (dimensions == 2 || dimensions == 3) {
Chris@45 555
Chris@45 556 READ_MANDATORY(int, resolution, toInt);
Chris@45 557
Chris@45 558 bool haveMinMax = true;
Chris@45 559 float minimum = attributes.value("minimum").trimmed().toFloat(&ok);
Chris@45 560 if (!ok) haveMinMax = false;
Chris@45 561 float maximum = attributes.value("maximum").trimmed().toFloat(&ok);
Chris@45 562 if (!ok) haveMinMax = false;
Chris@45 563
Chris@45 564 float valueQuantization =
Chris@45 565 attributes.value("valueQuantization").trimmed().toFloat(&ok);
Chris@45 566
Chris@45 567 bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true");
Chris@45 568
Chris@45 569 QString units = attributes.value("units");
Chris@45 570
Chris@45 571 if (dimensions == 2) {
Chris@45 572 if (attributes.value("subtype") == "text") {
Chris@45 573 TextModel *model = new TextModel
Chris@45 574 (sampleRate, resolution, notifyOnAdd);
Chris@45 575 model->setObjectName(name);
Chris@45 576 m_models[id] = model;
Chris@111 577 } else if (attributes.value("subtype") == "path") {
Chris@111 578 PathModel *model = new PathModel
Chris@111 579 (sampleRate, resolution, notifyOnAdd);
Chris@111 580 model->setObjectName(name);
Chris@111 581 m_models[id] = model;
Chris@45 582 } else {
Chris@45 583 SparseTimeValueModel *model;
Chris@45 584 if (haveMinMax) {
Chris@45 585 model = new SparseTimeValueModel
Chris@45 586 (sampleRate, resolution, minimum, maximum, notifyOnAdd);
Chris@45 587 } else {
Chris@45 588 model = new SparseTimeValueModel
Chris@45 589 (sampleRate, resolution, notifyOnAdd);
Chris@45 590 }
Chris@45 591 model->setScaleUnits(units);
Chris@45 592 model->setObjectName(name);
Chris@45 593 m_models[id] = model;
Chris@45 594 }
Chris@45 595 } else {
Chris@45 596 NoteModel *model;
Chris@45 597 if (haveMinMax) {
Chris@45 598 model = new NoteModel
Chris@45 599 (sampleRate, resolution, minimum, maximum, notifyOnAdd);
Chris@45 600 } else {
Chris@45 601 model = new NoteModel
Chris@45 602 (sampleRate, resolution, notifyOnAdd);
Chris@45 603 }
Chris@45 604 model->setValueQuantization(valueQuantization);
Chris@45 605 model->setScaleUnits(units);
Chris@45 606 model->setObjectName(name);
Chris@45 607 m_models[id] = model;
Chris@45 608 }
Chris@45 609
Chris@45 610 int dataset = attributes.value("dataset").trimmed().toInt(&ok);
Chris@45 611 if (ok) m_awaitingDatasets[dataset] = id;
Chris@45 612
Chris@45 613 return true;
Chris@45 614
Chris@45 615 } else {
Chris@45 616
Chris@45 617 std::cerr << "WARNING: SV-XML: Unexpected sparse model dimension ("
Chris@45 618 << dimensions << ")" << std::endl;
Chris@45 619 }
Chris@111 620
Chris@111 621 } else if (type == "alignment") {
Chris@111 622
Chris@111 623 READ_MANDATORY(int, reference, toInt);
Chris@111 624 READ_MANDATORY(int, aligned, toInt);
Chris@111 625 READ_MANDATORY(int, path, toInt);
Chris@111 626
Chris@111 627 Model *refModel = 0, *alignedModel = 0, *pathModel = 0;
Chris@111 628
Chris@111 629 if (m_models.find(reference) != m_models.end()) {
Chris@111 630 refModel = m_models[reference];
Chris@111 631 } else {
Chris@111 632 std::cerr << "WARNING: SV-XML: Unknown reference model id "
Chris@111 633 << reference << " in alignment model id " << id
Chris@111 634 << std::endl;
Chris@111 635 }
Chris@111 636
Chris@111 637 if (m_models.find(aligned) != m_models.end()) {
Chris@111 638 alignedModel = m_models[aligned];
Chris@111 639 } else {
Chris@111 640 std::cerr << "WARNING: SV-XML: Unknown aligned model id "
Chris@111 641 << aligned << " in alignment model id " << id
Chris@111 642 << std::endl;
Chris@111 643 }
Chris@111 644
Chris@111 645 if (m_models.find(path) != m_models.end()) {
Chris@111 646 pathModel = m_models[path];
Chris@111 647 } else {
Chris@111 648 std::cerr << "WARNING: SV-XML: Unknown path model id "
Chris@111 649 << path << " in alignment model id " << id
Chris@111 650 << std::endl;
Chris@111 651 }
Chris@111 652
Chris@111 653 if (refModel && alignedModel && pathModel) {
Chris@111 654 AlignmentModel *model = new AlignmentModel
Chris@111 655 (refModel, alignedModel, 0, 0);
Chris@111 656 PathModel *pm = dynamic_cast<PathModel *>(pathModel);
Chris@111 657 if (!pm) {
Chris@111 658 std::cerr << "WARNING: SV-XML: Model id " << path
Chris@111 659 << " referenced as path for alignment " << id
Chris@111 660 << " is not a path model" << std::endl;
Chris@111 661 } else {
Chris@111 662 model->setPath(pm);
Chris@111 663 pm->setCompletion(100);
Chris@111 664 }
Chris@111 665 model->setObjectName(name);
Chris@111 666 m_models[id] = model;
Chris@111 667 alignedModel->setAlignment(model);
Chris@111 668 return true;
Chris@111 669 }
Chris@111 670
Chris@45 671 } else {
Chris@45 672
Chris@45 673 std::cerr << "WARNING: SV-XML: Unexpected model type \""
Chris@45 674 << type.toLocal8Bit().data() << "\" for model id " << id << std::endl;
Chris@45 675 }
Chris@45 676
Chris@45 677 return false;
Chris@45 678 }
Chris@45 679
Chris@45 680 bool
Chris@45 681 SVFileReader::readView(const QXmlAttributes &attributes)
Chris@45 682 {
Chris@45 683 QString type = attributes.value("type");
Chris@45 684 m_currentPane = 0;
Chris@45 685
Chris@45 686 if (type != "pane") {
Chris@45 687 std::cerr << "WARNING: SV-XML: Unexpected view type \""
Chris@45 688 << type.toLocal8Bit().data() << "\"" << std::endl;
Chris@45 689 return false;
Chris@45 690 }
Chris@45 691
Chris@45 692 m_currentPane = m_paneCallback.addPane();
Chris@45 693
Chris@45 694 if (!m_currentPane) {
Chris@45 695 std::cerr << "WARNING: SV-XML: Internal error: Failed to add pane!"
Chris@45 696 << std::endl;
Chris@45 697 return false;
Chris@45 698 }
Chris@45 699
Chris@45 700 bool ok = false;
Chris@45 701
Chris@45 702 View *view = m_currentPane;
Chris@45 703
Chris@45 704 // The view properties first
Chris@45 705
Chris@45 706 READ_MANDATORY(size_t, centre, toUInt);
Chris@45 707 READ_MANDATORY(size_t, zoom, toUInt);
Chris@45 708 READ_MANDATORY(int, followPan, toInt);
Chris@45 709 READ_MANDATORY(int, followZoom, toInt);
Chris@45 710 QString tracking = attributes.value("tracking");
Chris@45 711
Chris@45 712 // Specify the follow modes before we set the actual values
Chris@45 713 view->setFollowGlobalPan(followPan);
Chris@45 714 view->setFollowGlobalZoom(followZoom);
Chris@45 715 view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous :
Chris@45 716 tracking == "page" ? PlaybackScrollPage
Chris@45 717 : PlaybackIgnore);
Chris@45 718
Chris@45 719 // Then set these values
Chris@45 720 view->setCentreFrame(centre);
Chris@45 721 view->setZoomLevel(zoom);
Chris@45 722
Chris@45 723 // And pane properties
Chris@45 724 READ_MANDATORY(int, centreLineVisible, toInt);
Chris@45 725 m_currentPane->setCentreLineVisible(centreLineVisible);
Chris@45 726
Chris@45 727 int height = attributes.value("height").toInt(&ok);
Chris@45 728 if (ok) {
Chris@45 729 m_currentPane->resize(m_currentPane->width(), height);
Chris@45 730 }
Chris@45 731
Chris@45 732 return true;
Chris@45 733 }
Chris@45 734
Chris@45 735 bool
Chris@45 736 SVFileReader::readLayer(const QXmlAttributes &attributes)
Chris@45 737 {
Chris@45 738 QString type = attributes.value("type");
Chris@45 739
Chris@45 740 int id;
Chris@45 741 bool ok = false;
Chris@45 742 id = attributes.value("id").trimmed().toInt(&ok);
Chris@45 743
Chris@45 744 if (!ok) {
Chris@45 745 std::cerr << "WARNING: SV-XML: No layer id for layer of type \""
Chris@45 746 << type.toLocal8Bit().data()
Chris@45 747 << "\"" << std::endl;
Chris@45 748 return false;
Chris@45 749 }
Chris@45 750
Chris@45 751 Layer *layer = 0;
Chris@45 752 bool isNewLayer = false;
Chris@45 753
Chris@45 754 // Layers are expected to be defined in layer elements in the data
Chris@45 755 // section, and referred to in layer elements in the view
Chris@45 756 // sections. So if we're in the data section, we expect this
Chris@45 757 // layer not to exist already; if we're in the view section, we
Chris@45 758 // expect it to exist.
Chris@45 759
Chris@45 760 if (m_inData) {
Chris@45 761
Chris@45 762 if (m_layers.find(id) != m_layers.end()) {
Chris@45 763 std::cerr << "WARNING: SV-XML: Ignoring duplicate layer id " << id
Chris@45 764 << " in data section" << std::endl;
Chris@45 765 return false;
Chris@45 766 }
Chris@45 767
Chris@45 768 layer = m_layers[id] = m_document->createLayer
Chris@45 769 (LayerFactory::getInstance()->getLayerTypeForName(type));
Chris@45 770
Chris@45 771 if (layer) {
Chris@45 772 m_layers[id] = layer;
Chris@45 773 isNewLayer = true;
Chris@45 774 }
Chris@45 775
Chris@45 776 } else {
Chris@45 777
Chris@45 778 if (!m_currentPane) {
Chris@45 779 std::cerr << "WARNING: SV-XML: No current pane for layer " << id
Chris@45 780 << " in view section" << std::endl;
Chris@45 781 return false;
Chris@45 782 }
Chris@45 783
Chris@45 784 if (m_layers.find(id) != m_layers.end()) {
Chris@45 785
Chris@45 786 layer = m_layers[id];
Chris@45 787
Chris@45 788 } else {
Chris@45 789 std::cerr << "WARNING: SV-XML: Layer id " << id
Chris@45 790 << " in view section has not been defined -- defining it here"
Chris@45 791 << std::endl;
Chris@45 792
Chris@45 793 layer = m_document->createLayer
Chris@45 794 (LayerFactory::getInstance()->getLayerTypeForName(type));
Chris@45 795
Chris@45 796 if (layer) {
Chris@45 797 m_layers[id] = layer;
Chris@45 798 isNewLayer = true;
Chris@45 799 }
Chris@45 800 }
Chris@45 801 }
Chris@45 802
Chris@45 803 if (!layer) {
Chris@45 804 std::cerr << "WARNING: SV-XML: Failed to add layer of type \""
Chris@45 805 << type.toLocal8Bit().data()
Chris@45 806 << "\"" << std::endl;
Chris@45 807 return false;
Chris@45 808 }
Chris@45 809
Chris@45 810 if (isNewLayer) {
Chris@45 811
Chris@45 812 QString name = attributes.value("name");
Chris@45 813 layer->setObjectName(name);
Chris@45 814
Chris@89 815 QString presentationName = attributes.value("presentationName");
Chris@89 816 layer->setPresentationName(presentationName);
Chris@89 817
Chris@45 818 int modelId;
Chris@45 819 bool modelOk = false;
Chris@45 820 modelId = attributes.value("model").trimmed().toInt(&modelOk);
Chris@45 821
Chris@45 822 if (modelOk) {
Chris@45 823 if (haveModel(modelId)) {
Chris@45 824 Model *model = m_models[modelId];
Chris@45 825 m_document->setModel(layer, model);
Chris@45 826 } else {
Chris@45 827 std::cerr << "WARNING: SV-XML: Unknown model id " << modelId
Chris@45 828 << " in layer definition" << std::endl;
Chris@45 829 }
Chris@45 830 }
Chris@45 831
Chris@45 832 layer->setProperties(attributes);
Chris@45 833 }
Chris@45 834
Chris@45 835 if (!m_inData && m_currentPane) {
Chris@45 836
Chris@45 837 QString visible = attributes.value("visible");
Chris@45 838 bool dormant = (visible == "false");
Chris@45 839
Chris@45 840 // We need to do this both before and after adding the layer
Chris@45 841 // to the view -- we need it to be dormant if appropriate
Chris@45 842 // before it's actually added to the view so that any property
Chris@45 843 // box gets the right state when it's added, but the add layer
Chris@45 844 // command sets dormant to false because it assumes it may be
Chris@45 845 // restoring a previously dormant layer, so we need to set it
Chris@45 846 // again afterwards too. Hm
Chris@45 847 layer->setLayerDormant(m_currentPane, dormant);
Chris@45 848
Chris@45 849 m_document->addLayerToView(m_currentPane, layer);
Chris@45 850
Chris@45 851 layer->setLayerDormant(m_currentPane, dormant);
Chris@45 852 }
Chris@45 853
Chris@45 854 m_currentLayer = layer;
Chris@45 855 m_inLayer = true;
Chris@45 856
Chris@45 857 return true;
Chris@45 858 }
Chris@45 859
Chris@45 860 bool
Chris@45 861 SVFileReader::readDatasetStart(const QXmlAttributes &attributes)
Chris@45 862 {
Chris@45 863 bool ok = false;
Chris@45 864
Chris@45 865 READ_MANDATORY(int, id, toInt);
Chris@45 866 READ_MANDATORY(int, dimensions, toInt);
Chris@45 867
Chris@45 868 if (m_awaitingDatasets.find(id) == m_awaitingDatasets.end()) {
Chris@45 869 std::cerr << "WARNING: SV-XML: Unwanted dataset " << id << std::endl;
Chris@45 870 return false;
Chris@45 871 }
Chris@45 872
Chris@45 873 int modelId = m_awaitingDatasets[id];
Chris@45 874
Chris@45 875 Model *model = 0;
Chris@45 876 if (haveModel(modelId)) {
Chris@45 877 model = m_models[modelId];
Chris@45 878 } else {
Chris@45 879 std::cerr << "WARNING: SV-XML: Internal error: Unknown model " << modelId
Chris@45 880 << " expecting dataset " << id << std::endl;
Chris@45 881 return false;
Chris@45 882 }
Chris@45 883
Chris@45 884 bool good = false;
Chris@45 885
Chris@45 886 switch (dimensions) {
Chris@45 887 case 1:
Chris@45 888 if (dynamic_cast<SparseOneDimensionalModel *>(model)) good = true;
Chris@45 889 else if (dynamic_cast<ImageModel *>(model)) good = true;
Chris@45 890 break;
Chris@45 891
Chris@45 892 case 2:
Chris@45 893 if (dynamic_cast<SparseTimeValueModel *>(model)) good = true;
Chris@45 894 else if (dynamic_cast<TextModel *>(model)) good = true;
Chris@111 895 else if (dynamic_cast<PathModel *>(model)) good = true;
Chris@45 896 break;
Chris@45 897
Chris@45 898 case 3:
Chris@45 899 if (dynamic_cast<NoteModel *>(model)) good = true;
Chris@45 900 else if (dynamic_cast<EditableDenseThreeDimensionalModel *>(model)) {
Chris@45 901 m_datasetSeparator = attributes.value("separator");
Chris@45 902 good = true;
Chris@45 903 }
Chris@45 904 break;
Chris@45 905 }
Chris@45 906
Chris@45 907 if (!good) {
Chris@45 908 std::cerr << "WARNING: SV-XML: Model id " << modelId << " has wrong number of dimensions or inappropriate type for " << dimensions << "-D dataset " << id << std::endl;
Chris@45 909 m_currentDataset = 0;
Chris@45 910 return false;
Chris@45 911 }
Chris@45 912
Chris@45 913 m_currentDataset = model;
Chris@45 914 return true;
Chris@45 915 }
Chris@45 916
Chris@45 917 bool
Chris@45 918 SVFileReader::addPointToDataset(const QXmlAttributes &attributes)
Chris@45 919 {
Chris@45 920 bool ok = false;
Chris@45 921
Chris@45 922 READ_MANDATORY(int, frame, toInt);
Chris@45 923
Chris@45 924 // std::cerr << "SVFileReader::addPointToDataset: frame = " << frame << std::endl;
Chris@45 925
Chris@45 926 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *>
Chris@45 927 (m_currentDataset);
Chris@45 928
Chris@45 929 if (sodm) {
Chris@45 930 // std::cerr << "Current dataset is a sparse one dimensional model" << std::endl;
Chris@45 931 QString label = attributes.value("label");
Chris@45 932 sodm->addPoint(SparseOneDimensionalModel::Point(frame, label));
Chris@45 933 return true;
Chris@45 934 }
Chris@45 935
Chris@45 936 SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *>
Chris@45 937 (m_currentDataset);
Chris@45 938
Chris@45 939 if (stvm) {
Chris@45 940 // std::cerr << "Current dataset is a sparse time-value model" << std::endl;
Chris@45 941 float value = 0.0;
Chris@45 942 value = attributes.value("value").trimmed().toFloat(&ok);
Chris@45 943 QString label = attributes.value("label");
Chris@45 944 stvm->addPoint(SparseTimeValueModel::Point(frame, value, label));
Chris@45 945 return ok;
Chris@45 946 }
Chris@45 947
Chris@45 948 NoteModel *nm = dynamic_cast<NoteModel *>(m_currentDataset);
Chris@45 949
Chris@45 950 if (nm) {
Chris@45 951 // std::cerr << "Current dataset is a note model" << std::endl;
Chris@45 952 float value = 0.0;
Chris@45 953 value = attributes.value("value").trimmed().toFloat(&ok);
Chris@45 954 size_t duration = 0;
Chris@45 955 duration = attributes.value("duration").trimmed().toUInt(&ok);
Chris@45 956 QString label = attributes.value("label");
Chris@61 957 float level = attributes.value("level").trimmed().toFloat(&ok);
Chris@61 958 if (!ok) { // level is optional
Chris@61 959 level = 1.f;
Chris@61 960 ok = true;
Chris@61 961 }
Chris@61 962 nm->addPoint(NoteModel::Point(frame, value, duration, level, label));
Chris@45 963 return ok;
Chris@45 964 }
Chris@45 965
Chris@45 966 TextModel *tm = dynamic_cast<TextModel *>(m_currentDataset);
Chris@45 967
Chris@45 968 if (tm) {
Chris@45 969 // std::cerr << "Current dataset is a text model" << std::endl;
Chris@45 970 float height = 0.0;
Chris@45 971 height = attributes.value("height").trimmed().toFloat(&ok);
Chris@45 972 QString label = attributes.value("label");
Chris@45 973 // std::cerr << "SVFileReader::addPointToDataset: TextModel: frame = " << frame << ", height = " << height << ", label = " << label.toStdString() << ", ok = " << ok << std::endl;
Chris@45 974 tm->addPoint(TextModel::Point(frame, height, label));
Chris@45 975 return ok;
Chris@45 976 }
Chris@45 977
Chris@111 978 PathModel *pm = dynamic_cast<PathModel *>(m_currentDataset);
Chris@111 979
Chris@111 980 if (pm) {
Chris@111 981 // std::cerr << "Current dataset is a path model" << std::endl;
Chris@111 982 int mapframe = attributes.value("mapframe").trimmed().toInt(&ok);
Chris@111 983 // std::cerr << "SVFileReader::addPointToDataset: PathModel: frame = " << frame << ", mapframe = " << mapframe << ", ok = " << ok << std::endl;
Chris@111 984 pm->addPoint(PathModel::Point(frame, mapframe));
Chris@111 985 return ok;
Chris@111 986 }
Chris@111 987
Chris@45 988 ImageModel *im = dynamic_cast<ImageModel *>(m_currentDataset);
Chris@45 989
Chris@45 990 if (im) {
Chris@45 991 // std::cerr << "Current dataset is an image model" << std::endl;
Chris@45 992 QString image = attributes.value("image");
Chris@45 993 QString label = attributes.value("label");
Chris@45 994 // std::cerr << "SVFileReader::addPointToDataset: ImageModel: frame = " << frame << ", image = " << image.toStdString() << ", label = " << label.toStdString() << ", ok = " << ok << std::endl;
Chris@45 995 im->addPoint(ImageModel::Point(frame, image, label));
Chris@45 996 return ok;
Chris@45 997 }
Chris@45 998
Chris@45 999 std::cerr << "WARNING: SV-XML: Point element found in non-point dataset" << std::endl;
Chris@45 1000
Chris@45 1001 return false;
Chris@45 1002 }
Chris@45 1003
Chris@45 1004 bool
Chris@45 1005 SVFileReader::addBinToDataset(const QXmlAttributes &attributes)
Chris@45 1006 {
Chris@45 1007 EditableDenseThreeDimensionalModel *dtdm =
Chris@45 1008 dynamic_cast<EditableDenseThreeDimensionalModel *>
Chris@45 1009 (m_currentDataset);
Chris@45 1010
Chris@45 1011 if (dtdm) {
Chris@45 1012
Chris@45 1013 bool ok = false;
Chris@45 1014 int n = attributes.value("number").trimmed().toInt(&ok);
Chris@45 1015 if (!ok) {
Chris@45 1016 std::cerr << "WARNING: SV-XML: Missing or invalid bin number"
Chris@45 1017 << std::endl;
Chris@45 1018 return false;
Chris@45 1019 }
Chris@45 1020
Chris@45 1021 QString name = attributes.value("name");
Chris@45 1022
Chris@45 1023 dtdm->setBinName(n, name);
Chris@45 1024 return true;
Chris@45 1025 }
Chris@45 1026
Chris@45 1027 std::cerr << "WARNING: SV-XML: Bin definition found in incompatible dataset" << std::endl;
Chris@45 1028
Chris@45 1029 return false;
Chris@45 1030 }
Chris@45 1031
Chris@45 1032
Chris@45 1033 bool
Chris@45 1034 SVFileReader::addRowToDataset(const QXmlAttributes &attributes)
Chris@45 1035 {
Chris@45 1036 m_inRow = false;
Chris@45 1037
Chris@45 1038 bool ok = false;
Chris@45 1039 m_rowNumber = attributes.value("n").trimmed().toInt(&ok);
Chris@45 1040 if (!ok) {
Chris@45 1041 std::cerr << "WARNING: SV-XML: Missing or invalid row number"
Chris@45 1042 << std::endl;
Chris@45 1043 return false;
Chris@45 1044 }
Chris@45 1045
Chris@45 1046 m_inRow = true;
Chris@45 1047
Chris@45 1048 // std::cerr << "SV-XML: In row " << m_rowNumber << std::endl;
Chris@45 1049
Chris@45 1050 return true;
Chris@45 1051 }
Chris@45 1052
Chris@45 1053 bool
Chris@45 1054 SVFileReader::readRowData(const QString &text)
Chris@45 1055 {
Chris@45 1056 EditableDenseThreeDimensionalModel *dtdm =
Chris@45 1057 dynamic_cast<EditableDenseThreeDimensionalModel *>
Chris@45 1058 (m_currentDataset);
Chris@45 1059
Chris@45 1060 bool warned = false;
Chris@45 1061
Chris@45 1062 if (dtdm) {
Chris@45 1063 QStringList data = text.split(m_datasetSeparator);
Chris@45 1064
Chris@45 1065 DenseThreeDimensionalModel::Column values;
Chris@45 1066
Chris@45 1067 for (QStringList::iterator i = data.begin(); i != data.end(); ++i) {
Chris@45 1068
Chris@45 1069 if (values.size() == dtdm->getHeight()) {
Chris@45 1070 if (!warned) {
Chris@45 1071 std::cerr << "WARNING: SV-XML: Too many y-bins in 3-D dataset row "
Chris@45 1072 << m_rowNumber << std::endl;
Chris@45 1073 warned = true;
Chris@45 1074 }
Chris@45 1075 }
Chris@45 1076
Chris@45 1077 bool ok;
Chris@45 1078 float value = i->toFloat(&ok);
Chris@45 1079 if (!ok) {
Chris@45 1080 std::cerr << "WARNING: SV-XML: Bad floating-point value "
Chris@45 1081 << i->toLocal8Bit().data()
Chris@45 1082 << " in row data" << std::endl;
Chris@45 1083 } else {
Chris@45 1084 values.push_back(value);
Chris@45 1085 }
Chris@45 1086 }
Chris@45 1087
Chris@45 1088 dtdm->setColumn(m_rowNumber, values);
Chris@45 1089 return true;
Chris@45 1090 }
Chris@45 1091
Chris@45 1092 std::cerr << "WARNING: SV-XML: Row data found in non-row dataset" << std::endl;
Chris@45 1093
Chris@45 1094 return false;
Chris@45 1095 }
Chris@45 1096
Chris@45 1097 bool
Chris@45 1098 SVFileReader::readDerivation(const QXmlAttributes &attributes)
Chris@45 1099 {
Chris@45 1100 int modelId = 0;
Chris@45 1101 bool modelOk = false;
Chris@45 1102 modelId = attributes.value("model").trimmed().toInt(&modelOk);
Chris@45 1103
Chris@45 1104 if (!modelOk) {
Chris@45 1105 std::cerr << "WARNING: SV-XML: No model id specified for derivation" << std::endl;
Chris@45 1106 return false;
Chris@45 1107 }
Chris@45 1108
Chris@45 1109 if (haveModel(modelId)) {
Chris@45 1110 m_currentDerivedModel = m_models[modelId];
Chris@45 1111 } else {
Chris@45 1112 // we'll regenerate the model when the derivation element ends
Chris@45 1113 m_currentDerivedModel = 0;
Chris@45 1114 }
Chris@45 1115
Chris@45 1116 m_currentDerivedModelId = modelId;
Chris@45 1117
Chris@45 1118 int sourceId = 0;
Chris@45 1119 bool sourceOk = false;
Chris@45 1120 sourceId = attributes.value("source").trimmed().toInt(&sourceOk);
Chris@45 1121
Chris@45 1122 if (sourceOk && haveModel(sourceId)) {
Chris@72 1123 m_currentTransformSource = m_models[sourceId];
Chris@45 1124 } else {
Chris@72 1125 m_currentTransformSource = m_document->getMainModel();
Chris@45 1126 }
Chris@45 1127
Chris@72 1128 m_currentTransform = Transform();
Chris@45 1129
Chris@45 1130 bool ok = false;
Chris@45 1131 int channel = attributes.value("channel").trimmed().toInt(&ok);
Chris@72 1132 if (ok) m_currentTransformChannel = channel;
Chris@72 1133 else m_currentTransformChannel = -1;
Chris@45 1134
Chris@72 1135 QString type = attributes.value("type");
Chris@72 1136
Chris@72 1137 if (type == "transform") {
Chris@72 1138 m_currentTransformIsNewStyle = true;
Chris@72 1139 return true;
Chris@72 1140 } else {
Chris@72 1141 m_currentTransformIsNewStyle = false;
Chris@72 1142 std::cerr << "NOTE: SV-XML: Reading old-style derivation element"
Chris@72 1143 << std::endl;
Chris@72 1144 }
Chris@72 1145
Chris@72 1146 QString transformId = attributes.value("transform");
Chris@72 1147
Chris@72 1148 m_currentTransform.setIdentifier(transformId);
Chris@45 1149
Chris@45 1150 int stepSize = attributes.value("stepSize").trimmed().toInt(&ok);
Chris@72 1151 if (ok) m_currentTransform.setStepSize(stepSize);
Chris@45 1152
Chris@45 1153 int blockSize = attributes.value("blockSize").trimmed().toInt(&ok);
Chris@72 1154 if (ok) m_currentTransform.setBlockSize(blockSize);
Chris@45 1155
Chris@45 1156 int windowType = attributes.value("windowType").trimmed().toInt(&ok);
Chris@72 1157 if (ok) m_currentTransform.setWindowType(WindowType(windowType));
Chris@72 1158
Chris@72 1159 if (!m_currentTransformSource) return true;
Chris@45 1160
Chris@45 1161 QString startFrameStr = attributes.value("startFrame");
Chris@45 1162 QString durationStr = attributes.value("duration");
Chris@45 1163
Chris@45 1164 size_t startFrame = 0;
Chris@45 1165 size_t duration = 0;
Chris@45 1166
Chris@45 1167 if (startFrameStr != "") {
Chris@45 1168 startFrame = startFrameStr.trimmed().toInt(&ok);
Chris@45 1169 if (!ok) startFrame = 0;
Chris@45 1170 }
Chris@45 1171 if (durationStr != "") {
Chris@45 1172 duration = durationStr.trimmed().toInt(&ok);
Chris@45 1173 if (!ok) duration = 0;
Chris@45 1174 }
Chris@45 1175
Chris@72 1176 m_currentTransform.setStartTime
Chris@72 1177 (RealTime::frame2RealTime
Chris@72 1178 (startFrame, m_currentTransformSource->getSampleRate()));
Chris@72 1179
Chris@72 1180 m_currentTransform.setDuration
Chris@72 1181 (RealTime::frame2RealTime
Chris@72 1182 (duration, m_currentTransformSource->getSampleRate()));
Chris@45 1183
Chris@45 1184 return true;
Chris@45 1185 }
Chris@45 1186
Chris@45 1187 bool
Chris@45 1188 SVFileReader::readPlayParameters(const QXmlAttributes &attributes)
Chris@45 1189 {
Chris@45 1190 m_currentPlayParameters = 0;
Chris@45 1191
Chris@45 1192 int modelId = 0;
Chris@45 1193 bool modelOk = false;
Chris@45 1194 modelId = attributes.value("model").trimmed().toInt(&modelOk);
Chris@45 1195
Chris@45 1196 if (!modelOk) {
Chris@45 1197 std::cerr << "WARNING: SV-XML: No model id specified for play parameters" << std::endl;
Chris@45 1198 return false;
Chris@45 1199 }
Chris@45 1200
Chris@45 1201 if (haveModel(modelId)) {
Chris@45 1202
Chris@45 1203 bool ok = false;
Chris@45 1204
Chris@45 1205 PlayParameters *parameters = PlayParameterRepository::getInstance()->
Chris@45 1206 getPlayParameters(m_models[modelId]);
Chris@45 1207
Chris@45 1208 if (!parameters) {
Chris@45 1209 std::cerr << "WARNING: SV-XML: Play parameters for model "
Chris@45 1210 << modelId
Chris@45 1211 << " not found - has model been added to document?"
Chris@45 1212 << std::endl;
Chris@45 1213 return false;
Chris@45 1214 }
Chris@45 1215
Chris@45 1216 bool muted = (attributes.value("mute").trimmed() == "true");
Chris@45 1217 parameters->setPlayMuted(muted);
Chris@45 1218
Chris@45 1219 float pan = attributes.value("pan").toFloat(&ok);
Chris@45 1220 if (ok) parameters->setPlayPan(pan);
Chris@45 1221
Chris@45 1222 float gain = attributes.value("gain").toFloat(&ok);
Chris@45 1223 if (ok) parameters->setPlayGain(gain);
Chris@45 1224
Chris@45 1225 QString pluginId = attributes.value("pluginId");
Chris@45 1226 if (pluginId != "") parameters->setPlayPluginId(pluginId);
Chris@45 1227
Chris@45 1228 m_currentPlayParameters = parameters;
Chris@45 1229
Chris@45 1230 // std::cerr << "Current play parameters for model: " << m_models[modelId] << ": " << m_currentPlayParameters << std::endl;
Chris@45 1231
Chris@45 1232 } else {
Chris@45 1233
Chris@45 1234 std::cerr << "WARNING: SV-XML: Unknown model " << modelId
Chris@45 1235 << " for play parameters" << std::endl;
Chris@45 1236 return false;
Chris@45 1237 }
Chris@45 1238
Chris@45 1239 return true;
Chris@45 1240 }
Chris@45 1241
Chris@45 1242 bool
Chris@45 1243 SVFileReader::readPlugin(const QXmlAttributes &attributes)
Chris@45 1244 {
Chris@45 1245 if (m_currentDerivedModelId < 0 && !m_currentPlayParameters) {
Chris@45 1246 std::cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << std::endl;
Chris@45 1247 return false;
Chris@45 1248 }
Chris@45 1249
Chris@72 1250 if (!m_currentPlayParameters && m_currentTransformIsNewStyle) {
Chris@72 1251 return true;
Chris@72 1252 }
Chris@72 1253
Chris@45 1254 QString configurationXml = "<plugin";
Chris@45 1255
Chris@45 1256 for (int i = 0; i < attributes.length(); ++i) {
Chris@45 1257 configurationXml += QString(" %1=\"%2\"")
Chris@45 1258 .arg(attributes.qName(i))
Chris@45 1259 .arg(XmlExportable::encodeEntities(attributes.value(i)));
Chris@45 1260 }
Chris@45 1261
Chris@45 1262 configurationXml += "/>";
Chris@45 1263
Chris@45 1264 if (m_currentPlayParameters) {
Chris@45 1265 m_currentPlayParameters->setPlayPluginConfiguration(configurationXml);
Chris@45 1266 } else {
Chris@72 1267 TransformFactory::getInstance()->
Chris@72 1268 setParametersFromPluginConfigurationXml(m_currentTransform,
Chris@72 1269 configurationXml);
Chris@45 1270 }
Chris@45 1271
Chris@45 1272 return true;
Chris@45 1273 }
Chris@45 1274
Chris@45 1275 bool
Chris@72 1276 SVFileReader::readTransform(const QXmlAttributes &attributes)
Chris@72 1277 {
Chris@72 1278 if (m_currentDerivedModelId < 0) {
Chris@72 1279 std::cerr << "WARNING: SV-XML: Transform found outside derivation" << std::endl;
Chris@72 1280 return false;
Chris@72 1281 }
Chris@72 1282
Chris@82 1283 m_currentTransform = Transform();
Chris@72 1284 m_currentTransform.setFromXmlAttributes(attributes);
Chris@72 1285 return true;
Chris@72 1286 }
Chris@72 1287
Chris@72 1288 bool
Chris@72 1289 SVFileReader::readParameter(const QXmlAttributes &attributes)
Chris@72 1290 {
Chris@72 1291 if (m_currentDerivedModelId < 0) {
Chris@72 1292 std::cerr << "WARNING: SV-XML: Parameter found outside derivation" << std::endl;
Chris@72 1293 return false;
Chris@72 1294 }
Chris@72 1295
Chris@72 1296 QString name = attributes.value("name");
Chris@72 1297 if (name == "") {
Chris@72 1298 std::cerr << "WARNING: SV-XML: Ignoring nameless transform parameter"
Chris@72 1299 << std::endl;
Chris@72 1300 return false;
Chris@72 1301 }
Chris@72 1302
Chris@72 1303 float value = attributes.value("value").trimmed().toFloat();
Chris@72 1304
Chris@72 1305 m_currentTransform.setParameter(name, value);
Chris@72 1306 return true;
Chris@72 1307 }
Chris@72 1308
Chris@72 1309 bool
Chris@45 1310 SVFileReader::readSelection(const QXmlAttributes &attributes)
Chris@45 1311 {
Chris@45 1312 bool ok;
Chris@45 1313
Chris@45 1314 READ_MANDATORY(int, start, toInt);
Chris@45 1315 READ_MANDATORY(int, end, toInt);
Chris@45 1316
Chris@45 1317 m_paneCallback.addSelection(start, end);
Chris@45 1318
Chris@45 1319 return true;
Chris@45 1320 }
Chris@45 1321
Chris@45 1322 bool
Chris@45 1323 SVFileReader::readMeasurement(const QXmlAttributes &attributes)
Chris@45 1324 {
Chris@45 1325 std::cerr << "SVFileReader::readMeasurement: inLayer "
Chris@45 1326 << m_inLayer << ", layer " << m_currentLayer << std::endl;
Chris@45 1327
Chris@45 1328 if (!m_inLayer) {
Chris@45 1329 std::cerr << "WARNING: SV-XML: Measurement found outside layer" << std::endl;
Chris@45 1330 return false;
Chris@45 1331 }
Chris@45 1332
Chris@45 1333 m_currentLayer->addMeasurementRect(attributes);
Chris@45 1334 return true;
Chris@45 1335 }
Chris@45 1336
Chris@45 1337 SVFileReaderPaneCallback::~SVFileReaderPaneCallback()
Chris@45 1338 {
Chris@45 1339 }
Chris@45 1340