comparison document/SVFileReader.cpp @ 0:cd5d7ff8ef38

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