annotate document/SVFileReader.cpp @ 78:9918c8a3f904

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