SVFileReader.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "SVFileReader.h"
00017 
00018 #include "layer/Layer.h"
00019 #include "view/View.h"
00020 #include "base/PlayParameters.h"
00021 #include "base/PlayParameterRepository.h"
00022 
00023 #include "data/fileio/AudioFileReaderFactory.h"
00024 #include "data/fileio/FileFinder.h"
00025 #include "data/fileio/FileSource.h"
00026 
00027 #include "data/model/WaveFileModel.h"
00028 #include "data/model/EditableDenseThreeDimensionalModel.h"
00029 #include "data/model/SparseOneDimensionalModel.h"
00030 #include "data/model/SparseTimeValueModel.h"
00031 #include "data/model/NoteModel.h"
00032 #include "data/model/TextModel.h"
00033 #include "data/model/ImageModel.h"
00034 
00035 #include "plugin/transform/TransformFactory.h"
00036 
00037 #include "view/Pane.h"
00038 
00039 #include "Document.h"
00040 
00041 #include <QString>
00042 #include <QMessageBox>
00043 #include <QFileDialog>
00044 
00045 #include <iostream>
00046 
00047 SVFileReader::SVFileReader(Document *document,
00048                            SVFileReaderPaneCallback &callback,
00049                            QString location) :
00050     m_document(document),
00051     m_paneCallback(callback),
00052     m_location(location),
00053     m_currentPane(0),
00054     m_currentDataset(0),
00055     m_currentDerivedModel(0),
00056     m_currentDerivedModelId(-1),
00057     m_currentPlayParameters(0),
00058     m_currentTransformSource(0),
00059     m_datasetSeparator(" "),
00060     m_inRow(false),
00061     m_inLayer(false),
00062     m_inView(false),
00063     m_rowNumber(0),
00064     m_ok(false)
00065 {
00066 }
00067 
00068 void
00069 SVFileReader::parse(const QString &xmlData)
00070 {
00071     QXmlInputSource inputSource;
00072     inputSource.setData(xmlData);
00073     parse(inputSource);
00074 }
00075 
00076 void
00077 SVFileReader::parse(QXmlInputSource &inputSource)
00078 {
00079     QXmlSimpleReader reader;
00080     reader.setContentHandler(this);
00081     reader.setErrorHandler(this);
00082     m_ok = reader.parse(inputSource);
00083 }    
00084 
00085 bool
00086 SVFileReader::isOK()
00087 {
00088     return m_ok;
00089 }
00090         
00091 SVFileReader::~SVFileReader()
00092 {
00093     if (!m_awaitingDatasets.empty()) {
00094         std::cerr << "WARNING: SV-XML: File ended with "
00095                   << m_awaitingDatasets.size() << " unfilled model dataset(s)"
00096                   << std::endl;
00097     }
00098 
00099     std::set<Model *> unaddedModels;
00100 
00101     for (std::map<int, Model *>::iterator i = m_models.begin();
00102          i != m_models.end(); ++i) {
00103         if (m_addedModels.find(i->second) == m_addedModels.end()) {
00104             unaddedModels.insert(i->second);
00105         }
00106     }
00107 
00108     if (!unaddedModels.empty()) {
00109         std::cerr << "WARNING: SV-XML: File contained "
00110                   << unaddedModels.size() << " unused models"
00111                   << std::endl;
00112         while (!unaddedModels.empty()) {
00113             delete *unaddedModels.begin();
00114             unaddedModels.erase(unaddedModels.begin());
00115         }
00116     }   
00117 }
00118 
00119 bool
00120 SVFileReader::startElement(const QString &, const QString &,
00121                            const QString &qName,
00122                            const QXmlAttributes &attributes)
00123 {
00124     QString name = qName.toLower();
00125 
00126     bool ok = false;
00127 
00128     // Valid element names:
00129     //
00130     // sv
00131     // data
00132     // dataset
00133     // display
00134     // derivation
00135     // playparameters
00136     // layer
00137     // model
00138     // point
00139     // row
00140     // view
00141     // window
00142     // plugin
00143     // transform
00144     // selections
00145     // selection
00146     // measurement
00147 
00148     if (name == "sv") {
00149 
00150         // nothing needed
00151         ok = true;
00152 
00153     } else if (name == "data") {
00154 
00155         // nothing needed
00156         m_inData = true;
00157         ok = true;
00158 
00159     } else if (name == "display") {
00160 
00161         // nothing needed
00162         ok = true;
00163 
00164     } else if (name == "window") {
00165 
00166         ok = readWindow(attributes);
00167 
00168     } else if (name == "model") {
00169 
00170         ok = readModel(attributes);
00171     
00172     } else if (name == "dataset") {
00173         
00174         ok = readDatasetStart(attributes);
00175 
00176     } else if (name == "bin") {
00177         
00178         ok = addBinToDataset(attributes);
00179     
00180     } else if (name == "point") {
00181         
00182         ok = addPointToDataset(attributes);
00183 
00184     } else if (name == "row") {
00185 
00186         ok = addRowToDataset(attributes);
00187 
00188     } else if (name == "layer") {
00189 
00190         addUnaddedModels(); // all models must be specified before first layer
00191         ok = readLayer(attributes);
00192 
00193     } else if (name == "view") {
00194 
00195         m_inView = true;
00196         ok = readView(attributes);
00197 
00198     } else if (name == "derivation") {
00199 
00200         ok = readDerivation(attributes);
00201 
00202     } else if (name == "playparameters") {
00203         
00204         ok = readPlayParameters(attributes);
00205 
00206     } else if (name == "plugin") {
00207 
00208         ok = readPlugin(attributes);
00209 
00210     } else if (name == "selections") {
00211 
00212         m_inSelections = true;
00213         ok = true;
00214 
00215     } else if (name == "selection") {
00216 
00217         ok = readSelection(attributes);
00218 
00219     } else if (name == "measurement") {
00220 
00221         ok = readMeasurement(attributes);
00222 
00223     } else if (name == "transform") {
00224         
00225         ok = readTransform(attributes);
00226 
00227     } else if (name == "parameter") {
00228 
00229         ok = readParameter(attributes);
00230 
00231     } else {
00232         std::cerr << "WARNING: SV-XML: Unexpected element \""
00233                   << name.toLocal8Bit().data() << "\"" << std::endl;
00234     }
00235 
00236     if (!ok) {
00237         std::cerr << "WARNING: SV-XML: Failed to completely process element \""
00238                   << name.toLocal8Bit().data() << "\"" << std::endl;
00239     }
00240 
00241     return true;
00242 }
00243 
00244 bool
00245 SVFileReader::characters(const QString &text)
00246 {
00247     bool ok = false;
00248 
00249     if (m_inRow) {
00250         ok = readRowData(text);
00251         if (!ok) {
00252             std::cerr << "WARNING: SV-XML: Failed to read row data content for row " << m_rowNumber << std::endl;
00253         }
00254     }
00255 
00256     return true;
00257 }
00258 
00259 bool
00260 SVFileReader::endElement(const QString &, const QString &,
00261                          const QString &qName)
00262 {
00263     QString name = qName.toLower();
00264 
00265     if (name == "dataset") {
00266 
00267         if (m_currentDataset) {
00268             
00269             bool foundInAwaiting = false;
00270 
00271             for (std::map<int, int>::iterator i = m_awaitingDatasets.begin();
00272                  i != m_awaitingDatasets.end(); ++i) {
00273                 if (haveModel(i->second) &&
00274                     m_models[i->second] == m_currentDataset) {
00275                     m_awaitingDatasets.erase(i);
00276                     foundInAwaiting = true;
00277                     break;
00278                 }
00279             }
00280 
00281             if (!foundInAwaiting) {
00282                 std::cerr << "WARNING: SV-XML: Dataset precedes model, or no model uses dataset" << std::endl;
00283             }
00284         }
00285 
00286         m_currentDataset = 0;
00287 
00288     } else if (name == "data") {
00289 
00290         addUnaddedModels();
00291         m_inData = false;
00292 
00293     } else if (name == "derivation") {
00294 
00295         if (!m_currentDerivedModel) {
00296             if (m_currentDerivedModel < 0) {
00297                 std::cerr << "WARNING: SV-XML: Bad derivation output model id "
00298                           << m_currentDerivedModelId << std::endl;
00299             } else if (haveModel(m_currentDerivedModelId)) {
00300                 std::cerr << "WARNING: SV-XML: Derivation has existing model "
00301                           << m_currentDerivedModelId
00302                           << " as target, not regenerating" << std::endl;
00303             } else {
00304                 QString message;
00305                 m_currentDerivedModel = m_models[m_currentDerivedModelId] =
00306                     m_document->addDerivedModel
00307                     (m_currentTransform,
00308                      ModelTransformer::Input(m_currentTransformSource,
00309                                              m_currentTransformChannel),
00310                      message);
00311                 if (!m_currentDerivedModel) {
00312                     emit modelRegenerationFailed(tr("(derived model in SV-XML)"),
00313                                                  m_currentTransform.getIdentifier(),
00314                                                  message);
00315                 } else if (message != "") {
00316                     emit modelRegenerationWarning(tr("(derived model in SV-XML)"),
00317                                                   m_currentTransform.getIdentifier(),
00318                                                   message);
00319                 }                    
00320             }
00321         } else {
00322             m_document->addDerivedModel
00323                 (m_currentTransform,
00324                  ModelTransformer::Input(m_currentTransformSource,
00325                                          m_currentTransformChannel),
00326                  m_currentDerivedModel);
00327         }
00328 
00329         m_addedModels.insert(m_currentDerivedModel);
00330         m_currentDerivedModel = 0;
00331         m_currentDerivedModelId = -1;
00332         m_currentTransformSource = 0;
00333         m_currentTransform = Transform();
00334         m_currentTransformChannel = -1;
00335 
00336     } else if (name == "row") {
00337         m_inRow = false;
00338     } else if (name == "layer") {
00339         m_inLayer = false;
00340     } else if (name == "view") {
00341         m_inView = false;
00342     } else if (name == "selections") {
00343         m_inSelections = false;
00344     } else if (name == "playparameters") {
00345         m_currentPlayParameters = 0;
00346     }
00347 
00348     return true;
00349 }
00350 
00351 bool
00352 SVFileReader::error(const QXmlParseException &exception)
00353 {
00354     m_errorString =
00355         QString("ERROR: SV-XML: %1 at line %2, column %3")
00356         .arg(exception.message())
00357         .arg(exception.lineNumber())
00358         .arg(exception.columnNumber());
00359     std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
00360     return QXmlDefaultHandler::error(exception);
00361 }
00362 
00363 bool
00364 SVFileReader::fatalError(const QXmlParseException &exception)
00365 {
00366     m_errorString =
00367         QString("FATAL ERROR: SV-XML: %1 at line %2, column %3")
00368         .arg(exception.message())
00369         .arg(exception.lineNumber())
00370         .arg(exception.columnNumber());
00371     std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
00372     return QXmlDefaultHandler::fatalError(exception);
00373 }
00374 
00375 
00376 #define READ_MANDATORY(TYPE, NAME, CONVERSION)                \
00377     TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \
00378     if (!ok) { \
00379         std::cerr << "WARNING: SV-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << std::endl; \
00380         return false; \
00381     }
00382 
00383 bool
00384 SVFileReader::readWindow(const QXmlAttributes &attributes)
00385 {
00386     bool ok = false;
00387 
00388     READ_MANDATORY(int, width, toInt);
00389     READ_MANDATORY(int, height, toInt);
00390 
00391     m_paneCallback.setWindowSize(width, height);
00392     return true;
00393 }
00394 
00395 void
00396 SVFileReader::addUnaddedModels()
00397 {
00398     std::set<Model *> unaddedModels;
00399     
00400     for (std::map<int, Model *>::iterator i = m_models.begin();
00401          i != m_models.end(); ++i) {
00402         if (m_addedModels.find(i->second) == m_addedModels.end()) {
00403             unaddedModels.insert(i->second);
00404         }
00405     }
00406     
00407     for (std::set<Model *>::iterator i = unaddedModels.begin();
00408          i != unaddedModels.end(); ++i) {
00409         m_document->addImportedModel(*i);
00410         m_addedModels.insert(*i);
00411     }
00412 }
00413 
00414 bool
00415 SVFileReader::readModel(const QXmlAttributes &attributes)
00416 {
00417     bool ok = false;
00418 
00419     READ_MANDATORY(int, id, toInt);
00420 
00421     if (haveModel(id)) {
00422         std::cerr << "WARNING: SV-XML: Ignoring duplicate model id " << id
00423                   << std::endl;
00424         return false;
00425     }
00426 
00427     QString name = attributes.value("name");
00428 
00429     std::cerr << "SVFileReader::readModel: model name \"" << name.toStdString() << "\"" << std::endl;
00430 
00431     READ_MANDATORY(int, sampleRate, toInt);
00432 
00433     QString type = attributes.value("type").trimmed();
00434     bool mainModel = (attributes.value("mainModel").trimmed() == "true");
00435 
00436     if (type == "wavefile") {
00437         
00438         WaveFileModel *model = 0;
00439         FileFinder *ff = FileFinder::getInstance();
00440         QString originalPath = attributes.value("file");
00441         QString path = ff->find(FileFinder::AudioFile,
00442                                 originalPath, m_location);
00443 
00444         FileSource file(path, FileSource::ProgressDialog);
00445         file.waitForStatus();
00446 
00447         if (!file.isOK()) {
00448             std::cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path.toStdString() << "\" for wave file model: " << file.getErrorString().toStdString() << std::endl;
00449         } else if (!file.isAvailable()) {
00450             std::cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path.toStdString() << "\" for wave file model: Source unavailable" << std::endl;
00451         } else {
00452 
00453             file.waitForData();
00454             model = new WaveFileModel(file);
00455             if (!model->isOK()) {
00456                 delete model;
00457                 model = 0;
00458             }
00459         }
00460 
00461         if (!model) return false;
00462 
00463         model->setObjectName(name);
00464         m_models[id] = model;
00465         if (mainModel) {
00466             m_document->setMainModel(model);
00467             m_addedModels.insert(model);
00468         }
00469         // Derived models will be added when their derivation
00470         // is found.
00471 
00472         return true;
00473 
00474     } else if (type == "dense") {
00475         
00476         READ_MANDATORY(int, dimensions, toInt);
00477                     
00478         // Currently the only dense model we support here is the dense
00479         // 3d model.  Dense time-value models are always file-backed
00480         // waveform data, at this point, and they come in as wavefile
00481         // models.
00482         
00483         if (dimensions == 3) {
00484             
00485             READ_MANDATORY(int, windowSize, toInt);
00486             READ_MANDATORY(int, yBinCount, toInt);
00487             
00488             EditableDenseThreeDimensionalModel *model =
00489                 new EditableDenseThreeDimensionalModel
00490                 (sampleRate, windowSize, yBinCount);
00491             
00492             float minimum = attributes.value("minimum").trimmed().toFloat(&ok);
00493             if (ok) model->setMinimumLevel(minimum);
00494             
00495             float maximum = attributes.value("maximum").trimmed().toFloat(&ok);
00496             if (ok) model->setMaximumLevel(maximum);
00497 
00498             int dataset = attributes.value("dataset").trimmed().toInt(&ok);
00499             if (ok) m_awaitingDatasets[dataset] = id;
00500 
00501             model->setObjectName(name);
00502             m_models[id] = model;
00503             return true;
00504 
00505         } else {
00506 
00507             std::cerr << "WARNING: SV-XML: Unexpected dense model dimension ("
00508                       << dimensions << ")" << std::endl;
00509         }
00510     } else if (type == "sparse") {
00511 
00512         READ_MANDATORY(int, dimensions, toInt);
00513                   
00514         if (dimensions == 1) {
00515             
00516             READ_MANDATORY(int, resolution, toInt);
00517 
00518             if (attributes.value("subtype") == "image") {
00519 
00520                 bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true");
00521                 ImageModel *model = new ImageModel(sampleRate, resolution,
00522                                                    notifyOnAdd);
00523                 model->setObjectName(name);
00524                 m_models[id] = model;
00525 
00526             } else {
00527 
00528                 SparseOneDimensionalModel *model = new SparseOneDimensionalModel
00529                     (sampleRate, resolution);
00530                 model->setObjectName(name);
00531                 m_models[id] = model;
00532             }
00533 
00534             int dataset = attributes.value("dataset").trimmed().toInt(&ok);
00535             if (ok) m_awaitingDatasets[dataset] = id;
00536 
00537             return true;
00538 
00539         } else if (dimensions == 2 || dimensions == 3) {
00540             
00541             READ_MANDATORY(int, resolution, toInt);
00542 
00543             bool haveMinMax = true;
00544             float minimum = attributes.value("minimum").trimmed().toFloat(&ok);
00545             if (!ok) haveMinMax = false;
00546             float maximum = attributes.value("maximum").trimmed().toFloat(&ok);
00547             if (!ok) haveMinMax = false;
00548 
00549             float valueQuantization =
00550                 attributes.value("valueQuantization").trimmed().toFloat(&ok);
00551 
00552             bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true");
00553 
00554             QString units = attributes.value("units");
00555 
00556             if (dimensions == 2) {
00557                 if (attributes.value("subtype") == "text") {
00558                     TextModel *model = new TextModel
00559                         (sampleRate, resolution, notifyOnAdd);
00560                     model->setObjectName(name);
00561                     m_models[id] = model;
00562                 } else {
00563                     SparseTimeValueModel *model;
00564                     if (haveMinMax) {
00565                         model = new SparseTimeValueModel
00566                             (sampleRate, resolution, minimum, maximum, notifyOnAdd);
00567                     } else {
00568                         model = new SparseTimeValueModel
00569                             (sampleRate, resolution, notifyOnAdd);
00570                     }
00571                     model->setScaleUnits(units);
00572                     model->setObjectName(name);
00573                     m_models[id] = model;
00574                 }
00575             } else {
00576                 NoteModel *model;
00577                 if (haveMinMax) {
00578                     model = new NoteModel
00579                         (sampleRate, resolution, minimum, maximum, notifyOnAdd);
00580                 } else {
00581                     model = new NoteModel
00582                         (sampleRate, resolution, notifyOnAdd);
00583                 }
00584                 model->setValueQuantization(valueQuantization);
00585                 model->setScaleUnits(units);
00586                 model->setObjectName(name);
00587                 m_models[id] = model;
00588             }
00589 
00590             int dataset = attributes.value("dataset").trimmed().toInt(&ok);
00591             if (ok) m_awaitingDatasets[dataset] = id;
00592 
00593             return true;
00594 
00595         } else {
00596 
00597             std::cerr << "WARNING: SV-XML: Unexpected sparse model dimension ("
00598                       << dimensions << ")" << std::endl;
00599         }
00600     } else {
00601 
00602         std::cerr << "WARNING: SV-XML: Unexpected model type \""
00603                   << type.toLocal8Bit().data() << "\" for model id " << id << std::endl;
00604     }
00605 
00606     return false;
00607 }
00608 
00609 bool
00610 SVFileReader::readView(const QXmlAttributes &attributes)
00611 {
00612     QString type = attributes.value("type");
00613     m_currentPane = 0;
00614     
00615     if (type != "pane") {
00616         std::cerr << "WARNING: SV-XML: Unexpected view type \""
00617                   << type.toLocal8Bit().data() << "\"" << std::endl;
00618         return false;
00619     }
00620 
00621     m_currentPane = m_paneCallback.addPane();
00622 
00623     if (!m_currentPane) {
00624         std::cerr << "WARNING: SV-XML: Internal error: Failed to add pane!"
00625                   << std::endl;
00626         return false;
00627     }
00628 
00629     bool ok = false;
00630 
00631     View *view = m_currentPane;
00632 
00633     // The view properties first
00634 
00635     READ_MANDATORY(size_t, centre, toUInt);
00636     READ_MANDATORY(size_t, zoom, toUInt);
00637     READ_MANDATORY(int, followPan, toInt);
00638     READ_MANDATORY(int, followZoom, toInt);
00639     QString tracking = attributes.value("tracking");
00640 
00641     // Specify the follow modes before we set the actual values
00642     view->setFollowGlobalPan(followPan);
00643     view->setFollowGlobalZoom(followZoom);
00644     view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous :
00645                             tracking == "page" ? PlaybackScrollPage
00646                             : PlaybackIgnore);
00647 
00648     // Then set these values
00649     view->setCentreFrame(centre);
00650     view->setZoomLevel(zoom);
00651 
00652     // And pane properties
00653     READ_MANDATORY(int, centreLineVisible, toInt);
00654     m_currentPane->setCentreLineVisible(centreLineVisible);
00655 
00656     int height = attributes.value("height").toInt(&ok);
00657     if (ok) {
00658         m_currentPane->resize(m_currentPane->width(), height);
00659     }
00660 
00661     return true;
00662 }
00663 
00664 bool
00665 SVFileReader::readLayer(const QXmlAttributes &attributes)
00666 {
00667     QString type = attributes.value("type");
00668 
00669     int id;
00670     bool ok = false;
00671     id = attributes.value("id").trimmed().toInt(&ok);
00672 
00673     if (!ok) {
00674         std::cerr << "WARNING: SV-XML: No layer id for layer of type \""
00675                   << type.toLocal8Bit().data()
00676                   << "\"" << std::endl;
00677         return false;
00678     }
00679 
00680     Layer *layer = 0;
00681     bool isNewLayer = false;
00682 
00683     // Layers are expected to be defined in layer elements in the data
00684     // section, and referred to in layer elements in the view
00685     // sections.  So if we're in the data section, we expect this
00686     // layer not to exist already; if we're in the view section, we
00687     // expect it to exist.
00688 
00689     if (m_inData) {
00690 
00691         if (m_layers.find(id) != m_layers.end()) {
00692             std::cerr << "WARNING: SV-XML: Ignoring duplicate layer id " << id
00693                       << " in data section" << std::endl;
00694             return false;
00695         }
00696 
00697         layer = m_layers[id] = m_document->createLayer
00698             (LayerFactory::getInstance()->getLayerTypeForName(type));
00699 
00700         if (layer) {
00701             m_layers[id] = layer;
00702             isNewLayer = true;
00703         }
00704 
00705     } else {
00706 
00707         if (!m_currentPane) {
00708             std::cerr << "WARNING: SV-XML: No current pane for layer " << id
00709                       << " in view section" << std::endl;
00710             return false;
00711         }
00712 
00713         if (m_layers.find(id) != m_layers.end()) {
00714             
00715             layer = m_layers[id];
00716         
00717         } else {
00718             std::cerr << "WARNING: SV-XML: Layer id " << id 
00719                       << " in view section has not been defined -- defining it here"
00720                       << std::endl;
00721 
00722             layer = m_document->createLayer
00723                 (LayerFactory::getInstance()->getLayerTypeForName(type));
00724 
00725             if (layer) {
00726                 m_layers[id] = layer;
00727                 isNewLayer = true;
00728             }
00729         }
00730     }
00731             
00732     if (!layer) {
00733         std::cerr << "WARNING: SV-XML: Failed to add layer of type \""
00734                   << type.toLocal8Bit().data()
00735                   << "\"" << std::endl;
00736         return false;
00737     }
00738 
00739     if (isNewLayer) {
00740 
00741         QString name = attributes.value("name");
00742         layer->setObjectName(name);
00743 
00744         QString presentationName = attributes.value("presentationName");
00745         layer->setPresentationName(presentationName);
00746 
00747         int modelId;
00748         bool modelOk = false;
00749         modelId = attributes.value("model").trimmed().toInt(&modelOk);
00750 
00751         if (modelOk) {
00752             if (haveModel(modelId)) {
00753                 Model *model = m_models[modelId];
00754                 m_document->setModel(layer, model);
00755             } else {
00756                 std::cerr << "WARNING: SV-XML: Unknown model id " << modelId
00757                           << " in layer definition" << std::endl;
00758             }
00759         }
00760 
00761         layer->setProperties(attributes);
00762     }
00763 
00764     if (!m_inData && m_currentPane) {
00765 
00766         QString visible = attributes.value("visible");
00767         bool dormant = (visible == "false");
00768 
00769         // We need to do this both before and after adding the layer
00770         // to the view -- we need it to be dormant if appropriate
00771         // before it's actually added to the view so that any property
00772         // box gets the right state when it's added, but the add layer
00773         // command sets dormant to false because it assumes it may be
00774         // restoring a previously dormant layer, so we need to set it
00775         // again afterwards too.  Hm
00776         layer->setLayerDormant(m_currentPane, dormant);
00777 
00778         m_document->addLayerToView(m_currentPane, layer);
00779 
00780         layer->setLayerDormant(m_currentPane, dormant);
00781     }
00782 
00783     m_currentLayer = layer;
00784     m_inLayer = true;
00785 
00786     return true;
00787 }
00788 
00789 bool
00790 SVFileReader::readDatasetStart(const QXmlAttributes &attributes)
00791 {
00792     bool ok = false;
00793 
00794     READ_MANDATORY(int, id, toInt);
00795     READ_MANDATORY(int, dimensions, toInt);
00796     
00797     if (m_awaitingDatasets.find(id) == m_awaitingDatasets.end()) {
00798         std::cerr << "WARNING: SV-XML: Unwanted dataset " << id << std::endl;
00799         return false;
00800     }
00801     
00802     int modelId = m_awaitingDatasets[id];
00803     
00804     Model *model = 0;
00805     if (haveModel(modelId)) {
00806         model = m_models[modelId];
00807     } else {
00808         std::cerr << "WARNING: SV-XML: Internal error: Unknown model " << modelId
00809                   << " expecting dataset " << id << std::endl;
00810         return false;
00811     }
00812 
00813     bool good = false;
00814 
00815     switch (dimensions) {
00816     case 1:
00817         if (dynamic_cast<SparseOneDimensionalModel *>(model)) good = true;
00818         else if (dynamic_cast<ImageModel *>(model)) good = true;
00819         break;
00820 
00821     case 2:
00822         if (dynamic_cast<SparseTimeValueModel *>(model)) good = true;
00823         else if (dynamic_cast<TextModel *>(model)) good = true;
00824         break;
00825 
00826     case 3:
00827         if (dynamic_cast<NoteModel *>(model)) good = true;
00828         else if (dynamic_cast<EditableDenseThreeDimensionalModel *>(model)) {
00829             m_datasetSeparator = attributes.value("separator");
00830             good = true;
00831         }
00832         break;
00833     }
00834 
00835     if (!good) {
00836         std::cerr << "WARNING: SV-XML: Model id " << modelId << " has wrong number of dimensions or inappropriate type for " << dimensions << "-D dataset " << id << std::endl;
00837         m_currentDataset = 0;
00838         return false;
00839     }
00840 
00841     m_currentDataset = model;
00842     return true;
00843 }
00844 
00845 bool
00846 SVFileReader::addPointToDataset(const QXmlAttributes &attributes)
00847 {
00848     bool ok = false;
00849 
00850     READ_MANDATORY(int, frame, toInt);
00851 
00852 //    std::cerr << "SVFileReader::addPointToDataset: frame = " << frame << std::endl;
00853 
00854     SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *>
00855         (m_currentDataset);
00856 
00857     if (sodm) {
00858 //        std::cerr << "Current dataset is a sparse one dimensional model" << std::endl;
00859         QString label = attributes.value("label");
00860         sodm->addPoint(SparseOneDimensionalModel::Point(frame, label));
00861         return true;
00862     }
00863 
00864     SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *>
00865         (m_currentDataset);
00866 
00867     if (stvm) {
00868 //        std::cerr << "Current dataset is a sparse time-value model" << std::endl;
00869         float value = 0.0;
00870         value = attributes.value("value").trimmed().toFloat(&ok);
00871         QString label = attributes.value("label");
00872         stvm->addPoint(SparseTimeValueModel::Point(frame, value, label));
00873         return ok;
00874     }
00875         
00876     NoteModel *nm = dynamic_cast<NoteModel *>(m_currentDataset);
00877 
00878     if (nm) {
00879 //        std::cerr << "Current dataset is a note model" << std::endl;
00880         float value = 0.0;
00881         value = attributes.value("value").trimmed().toFloat(&ok);
00882         size_t duration = 0;
00883         duration = attributes.value("duration").trimmed().toUInt(&ok);
00884         QString label = attributes.value("label");
00885         float level = attributes.value("level").trimmed().toFloat(&ok);
00886         if (!ok) { // level is optional
00887             level = 1.f;
00888             ok = true;
00889         }
00890         nm->addPoint(NoteModel::Point(frame, value, duration, level, label));
00891         return ok;
00892     }
00893 
00894     TextModel *tm = dynamic_cast<TextModel *>(m_currentDataset);
00895 
00896     if (tm) {
00897 //        std::cerr << "Current dataset is a text model" << std::endl;
00898         float height = 0.0;
00899         height = attributes.value("height").trimmed().toFloat(&ok);
00900         QString label = attributes.value("label");
00901 //        std::cerr << "SVFileReader::addPointToDataset: TextModel: frame = " << frame << ", height = " << height << ", label = " << label.toStdString() << ", ok = " << ok << std::endl;
00902         tm->addPoint(TextModel::Point(frame, height, label));
00903         return ok;
00904     }
00905 
00906     ImageModel *im = dynamic_cast<ImageModel *>(m_currentDataset);
00907 
00908     if (im) {
00909 //        std::cerr << "Current dataset is an image model" << std::endl;
00910         QString image = attributes.value("image");
00911         QString label = attributes.value("label");
00912 //        std::cerr << "SVFileReader::addPointToDataset: ImageModel: frame = " << frame << ", image = " << image.toStdString() << ", label = " << label.toStdString() << ", ok = " << ok << std::endl;
00913         im->addPoint(ImageModel::Point(frame, image, label));
00914         return ok;
00915     }
00916 
00917     std::cerr << "WARNING: SV-XML: Point element found in non-point dataset" << std::endl;
00918 
00919     return false;
00920 }
00921 
00922 bool
00923 SVFileReader::addBinToDataset(const QXmlAttributes &attributes)
00924 {
00925     EditableDenseThreeDimensionalModel *dtdm = 
00926         dynamic_cast<EditableDenseThreeDimensionalModel *>
00927         (m_currentDataset);
00928 
00929     if (dtdm) {
00930 
00931         bool ok = false;
00932         int n = attributes.value("number").trimmed().toInt(&ok);
00933         if (!ok) {
00934             std::cerr << "WARNING: SV-XML: Missing or invalid bin number"
00935                       << std::endl;
00936             return false;
00937         }
00938 
00939         QString name = attributes.value("name");
00940 
00941         dtdm->setBinName(n, name);
00942         return true;
00943     }
00944 
00945     std::cerr << "WARNING: SV-XML: Bin definition found in incompatible dataset" << std::endl;
00946 
00947     return false;
00948 }
00949 
00950 
00951 bool
00952 SVFileReader::addRowToDataset(const QXmlAttributes &attributes)
00953 {
00954     m_inRow = false;
00955 
00956     bool ok = false;
00957     m_rowNumber = attributes.value("n").trimmed().toInt(&ok);
00958     if (!ok) {
00959         std::cerr << "WARNING: SV-XML: Missing or invalid row number"
00960                   << std::endl;
00961         return false;
00962     }
00963     
00964     m_inRow = true;
00965 
00966 //    std::cerr << "SV-XML: In row " << m_rowNumber << std::endl;
00967     
00968     return true;
00969 }
00970 
00971 bool
00972 SVFileReader::readRowData(const QString &text)
00973 {
00974     EditableDenseThreeDimensionalModel *dtdm =
00975         dynamic_cast<EditableDenseThreeDimensionalModel *>
00976         (m_currentDataset);
00977 
00978     bool warned = false;
00979 
00980     if (dtdm) {
00981         QStringList data = text.split(m_datasetSeparator);
00982 
00983         DenseThreeDimensionalModel::Column values;
00984 
00985         for (QStringList::iterator i = data.begin(); i != data.end(); ++i) {
00986 
00987             if (values.size() == dtdm->getHeight()) {
00988                 if (!warned) {
00989                     std::cerr << "WARNING: SV-XML: Too many y-bins in 3-D dataset row "
00990                               << m_rowNumber << std::endl;
00991                     warned = true;
00992                 }
00993             }
00994 
00995             bool ok;
00996             float value = i->toFloat(&ok);
00997             if (!ok) {
00998                 std::cerr << "WARNING: SV-XML: Bad floating-point value "
00999                           << i->toLocal8Bit().data()
01000                           << " in row data" << std::endl;
01001             } else {
01002                 values.push_back(value);
01003             }
01004         }
01005 
01006         dtdm->setColumn(m_rowNumber, values);
01007         return true;
01008     }
01009 
01010     std::cerr << "WARNING: SV-XML: Row data found in non-row dataset" << std::endl;
01011 
01012     return false;
01013 }
01014 
01015 bool
01016 SVFileReader::readDerivation(const QXmlAttributes &attributes)
01017 {
01018     int modelId = 0;
01019     bool modelOk = false;
01020     modelId = attributes.value("model").trimmed().toInt(&modelOk);
01021 
01022     if (!modelOk) {
01023         std::cerr << "WARNING: SV-XML: No model id specified for derivation" << std::endl;
01024         return false;
01025     }
01026 
01027     if (haveModel(modelId)) {
01028         m_currentDerivedModel = m_models[modelId];
01029     } else {
01030         // we'll regenerate the model when the derivation element ends
01031         m_currentDerivedModel = 0;
01032     }
01033     
01034     m_currentDerivedModelId = modelId;
01035     
01036     int sourceId = 0;
01037     bool sourceOk = false;
01038     sourceId = attributes.value("source").trimmed().toInt(&sourceOk);
01039 
01040     if (sourceOk && haveModel(sourceId)) {
01041         m_currentTransformSource = m_models[sourceId];
01042     } else {
01043         m_currentTransformSource = m_document->getMainModel();
01044     }
01045 
01046     m_currentTransform = Transform();
01047 
01048     bool ok = false;
01049     int channel = attributes.value("channel").trimmed().toInt(&ok);
01050     if (ok) m_currentTransformChannel = channel;
01051     else m_currentTransformChannel = -1;
01052 
01053     QString type = attributes.value("type");
01054 
01055     if (type == "transform") {
01056         m_currentTransformIsNewStyle = true;
01057         return true;
01058     } else {
01059         m_currentTransformIsNewStyle = false;
01060         std::cerr << "NOTE: SV-XML: Reading old-style derivation element"
01061                   << std::endl;
01062     }
01063 
01064     QString transformId = attributes.value("transform");
01065 
01066     m_currentTransform.setIdentifier(transformId);
01067 
01068     int stepSize = attributes.value("stepSize").trimmed().toInt(&ok);
01069     if (ok) m_currentTransform.setStepSize(stepSize);
01070 
01071     int blockSize = attributes.value("blockSize").trimmed().toInt(&ok);
01072     if (ok) m_currentTransform.setBlockSize(blockSize);
01073 
01074     int windowType = attributes.value("windowType").trimmed().toInt(&ok);
01075     if (ok) m_currentTransform.setWindowType(WindowType(windowType));
01076 
01077     if (!m_currentTransformSource) return true;
01078 
01079     QString startFrameStr = attributes.value("startFrame");
01080     QString durationStr = attributes.value("duration");
01081 
01082     size_t startFrame = 0;
01083     size_t duration = 0;
01084 
01085     if (startFrameStr != "") {
01086         startFrame = startFrameStr.trimmed().toInt(&ok);
01087         if (!ok) startFrame = 0;
01088     }
01089     if (durationStr != "") {
01090         duration = durationStr.trimmed().toInt(&ok);
01091         if (!ok) duration = 0;
01092     }
01093 
01094     m_currentTransform.setStartTime
01095         (RealTime::frame2RealTime
01096          (startFrame, m_currentTransformSource->getSampleRate()));
01097 
01098     m_currentTransform.setDuration
01099         (RealTime::frame2RealTime
01100          (duration, m_currentTransformSource->getSampleRate()));
01101 
01102     return true;
01103 }
01104 
01105 bool
01106 SVFileReader::readPlayParameters(const QXmlAttributes &attributes)
01107 {
01108     m_currentPlayParameters = 0;
01109 
01110     int modelId = 0;
01111     bool modelOk = false;
01112     modelId = attributes.value("model").trimmed().toInt(&modelOk);
01113 
01114     if (!modelOk) {
01115         std::cerr << "WARNING: SV-XML: No model id specified for play parameters" << std::endl;
01116         return false;
01117     }
01118 
01119     if (haveModel(modelId)) {
01120 
01121         bool ok = false;
01122 
01123         PlayParameters *parameters = PlayParameterRepository::getInstance()->
01124             getPlayParameters(m_models[modelId]);
01125 
01126         if (!parameters) {
01127             std::cerr << "WARNING: SV-XML: Play parameters for model "
01128                       << modelId
01129                       << " not found - has model been added to document?"
01130                       << std::endl;
01131             return false;
01132         }
01133         
01134         bool muted = (attributes.value("mute").trimmed() == "true");
01135         parameters->setPlayMuted(muted);
01136         
01137         float pan = attributes.value("pan").toFloat(&ok);
01138         if (ok) parameters->setPlayPan(pan);
01139         
01140         float gain = attributes.value("gain").toFloat(&ok);
01141         if (ok) parameters->setPlayGain(gain);
01142         
01143         QString pluginId = attributes.value("pluginId");
01144         if (pluginId != "") parameters->setPlayPluginId(pluginId);
01145         
01146         m_currentPlayParameters = parameters;
01147 
01148 //        std::cerr << "Current play parameters for model: " << m_models[modelId] << ": " << m_currentPlayParameters << std::endl;
01149 
01150     } else {
01151 
01152         std::cerr << "WARNING: SV-XML: Unknown model " << modelId
01153                   << " for play parameters" << std::endl;
01154         return false;
01155     }
01156 
01157     return true;
01158 }
01159 
01160 bool
01161 SVFileReader::readPlugin(const QXmlAttributes &attributes)
01162 {
01163     if (m_currentDerivedModelId < 0 && !m_currentPlayParameters) {
01164         std::cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << std::endl;
01165         return false;
01166     }
01167 
01168     if (!m_currentPlayParameters && m_currentTransformIsNewStyle) {
01169         return true;
01170     }
01171 
01172     QString configurationXml = "<plugin";
01173     
01174     for (int i = 0; i < attributes.length(); ++i) {
01175         configurationXml += QString(" %1=\"%2\"")
01176             .arg(attributes.qName(i))
01177             .arg(XmlExportable::encodeEntities(attributes.value(i)));
01178     }
01179 
01180     configurationXml += "/>";
01181 
01182     if (m_currentPlayParameters) {
01183         m_currentPlayParameters->setPlayPluginConfiguration(configurationXml);
01184     } else {
01185         TransformFactory::getInstance()->
01186             setParametersFromPluginConfigurationXml(m_currentTransform,
01187                                                     configurationXml);
01188     }
01189 
01190     return true;
01191 }
01192 
01193 bool
01194 SVFileReader::readTransform(const QXmlAttributes &attributes)
01195 {
01196     if (m_currentDerivedModelId < 0) {
01197         std::cerr << "WARNING: SV-XML: Transform found outside derivation" << std::endl;
01198         return false;
01199     }
01200 
01201     m_currentTransform = Transform();
01202     m_currentTransform.setFromXmlAttributes(attributes);
01203     return true;
01204 }
01205 
01206 bool
01207 SVFileReader::readParameter(const QXmlAttributes &attributes)
01208 {
01209     if (m_currentDerivedModelId < 0) {
01210         std::cerr << "WARNING: SV-XML: Parameter found outside derivation" << std::endl;
01211         return false;
01212     }
01213 
01214     QString name = attributes.value("name");
01215     if (name == "") {
01216         std::cerr << "WARNING: SV-XML: Ignoring nameless transform parameter"
01217                   << std::endl;
01218         return false;
01219     }
01220 
01221     float value = attributes.value("value").trimmed().toFloat();
01222 
01223     m_currentTransform.setParameter(name, value);
01224     return true;
01225 }
01226 
01227 bool
01228 SVFileReader::readSelection(const QXmlAttributes &attributes)
01229 {
01230     bool ok;
01231 
01232     READ_MANDATORY(int, start, toInt);
01233     READ_MANDATORY(int, end, toInt);
01234 
01235     m_paneCallback.addSelection(start, end);
01236 
01237     return true;
01238 }
01239 
01240 bool
01241 SVFileReader::readMeasurement(const QXmlAttributes &attributes)
01242 {
01243     std::cerr << "SVFileReader::readMeasurement: inLayer "
01244               << m_inLayer << ", layer " << m_currentLayer << std::endl;
01245 
01246     if (!m_inLayer) {
01247         std::cerr << "WARNING: SV-XML: Measurement found outside layer" << std::endl;
01248         return false;
01249     }
01250 
01251     m_currentLayer->addMeasurementRect(attributes);
01252     return true;
01253 }
01254 
01255 SVFileReaderPaneCallback::~SVFileReaderPaneCallback()
01256 {
01257 }
01258 

Generated on Wed Feb 20 15:45:28 2008 for SonicVisualiser by  doxygen 1.5.1