annotate document/SVFileReader.cpp @ 197:c08c312b2399

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