annotate framework/SVFileReader.cpp @ 109:2dd30a7cd21a

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