annotate framework/SVFileReader.cpp @ 77:0535c49069ba

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