svapp
1.9
|
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 #include "base/Preferences.h" 00023 00024 #include "data/fileio/AudioFileReaderFactory.h" 00025 #include "data/fileio/FileSource.h" 00026 00027 #include "data/fileio/FileFinder.h" 00028 00029 #include "data/model/WaveFileModel.h" 00030 #include "data/model/EditableDenseThreeDimensionalModel.h" 00031 #include "data/model/SparseOneDimensionalModel.h" 00032 #include "data/model/SparseTimeValueModel.h" 00033 #include "data/model/NoteModel.h" 00034 #include "data/model/FlexiNoteModel.h" 00035 #include "data/model/RegionModel.h" 00036 #include "data/model/TextModel.h" 00037 #include "data/model/ImageModel.h" 00038 #include "data/model/AlignmentModel.h" 00039 00040 #include "transform/TransformFactory.h" 00041 00042 #include "view/Pane.h" 00043 00044 #include "widgets/ProgressDialog.h" 00045 00046 #include "Document.h" 00047 00048 #include <QString> 00049 #include <QMessageBox> 00050 #include <QFileDialog> 00051 00052 #include <iostream> 00053 00054 SVFileReader::SVFileReader(Document *document, 00055 SVFileReaderPaneCallback &callback, 00056 QString location) : 00057 m_document(document), 00058 m_paneCallback(callback), 00059 m_location(location), 00060 m_currentPane(0), 00061 m_currentLayer(0), 00062 m_currentDataset(0), 00063 m_currentDerivedModel(0), 00064 m_currentDerivedModelId(-1), 00065 m_currentPlayParameters(0), 00066 m_currentTransformSource(0), 00067 m_currentTransformChannel(0), 00068 m_currentTransformIsNewStyle(true), 00069 m_datasetSeparator(" "), 00070 m_inRow(false), 00071 m_inLayer(false), 00072 m_inView(false), 00073 m_inData(false), 00074 m_inSelections(false), 00075 m_rowNumber(0), 00076 m_ok(false) 00077 { 00078 } 00079 00080 void 00081 SVFileReader::parse(const QString &xmlData) 00082 { 00083 QXmlInputSource inputSource; 00084 inputSource.setData(xmlData); 00085 parse(inputSource); 00086 } 00087 00088 void 00089 SVFileReader::parse(QXmlInputSource &inputSource) 00090 { 00091 QXmlSimpleReader reader; 00092 reader.setContentHandler(this); 00093 reader.setErrorHandler(this); 00094 m_ok = reader.parse(inputSource); 00095 } 00096 00097 bool 00098 SVFileReader::isOK() 00099 { 00100 return m_ok; 00101 } 00102 00103 SVFileReader::~SVFileReader() 00104 { 00105 if (!m_awaitingDatasets.empty()) { 00106 cerr << "WARNING: SV-XML: File ended with " 00107 << m_awaitingDatasets.size() << " unfilled model dataset(s)" 00108 << endl; 00109 } 00110 00111 std::set<Model *> unaddedModels; 00112 00113 for (std::map<int, Model *>::iterator i = m_models.begin(); 00114 i != m_models.end(); ++i) { 00115 if (m_addedModels.find(i->second) == m_addedModels.end()) { 00116 unaddedModels.insert(i->second); 00117 } 00118 } 00119 00120 if (!unaddedModels.empty()) { 00121 cerr << "WARNING: SV-XML: File contained " 00122 << unaddedModels.size() << " unused models" 00123 << endl; 00124 while (!unaddedModels.empty()) { 00125 delete *unaddedModels.begin(); 00126 unaddedModels.erase(unaddedModels.begin()); 00127 } 00128 } 00129 } 00130 00131 bool 00132 SVFileReader::startElement(const QString &, const QString &, 00133 const QString &qName, 00134 const QXmlAttributes &attributes) 00135 { 00136 QString name = qName.toLower(); 00137 00138 bool ok = false; 00139 00140 // Valid element names: 00141 // 00142 // sv 00143 // data 00144 // dataset 00145 // display 00146 // derivation 00147 // playparameters 00148 // layer 00149 // model 00150 // point 00151 // row 00152 // view 00153 // window 00154 // plugin 00155 // transform 00156 // selections 00157 // selection 00158 // measurement 00159 00160 if (name == "sv") { 00161 00162 // nothing needed 00163 ok = true; 00164 00165 } else if (name == "data") { 00166 00167 // nothing needed 00168 m_inData = true; 00169 ok = true; 00170 00171 } else if (name == "display") { 00172 00173 // nothing needed 00174 ok = true; 00175 00176 } else if (name == "window") { 00177 00178 ok = readWindow(attributes); 00179 00180 } else if (name == "model") { 00181 00182 ok = readModel(attributes); 00183 00184 } else if (name == "dataset") { 00185 00186 ok = readDatasetStart(attributes); 00187 00188 } else if (name == "bin") { 00189 00190 ok = addBinToDataset(attributes); 00191 00192 } else if (name == "point") { 00193 00194 ok = addPointToDataset(attributes); 00195 00196 } else if (name == "row") { 00197 00198 ok = addRowToDataset(attributes); 00199 00200 } else if (name == "layer") { 00201 00202 addUnaddedModels(); // all models must be specified before first layer 00203 ok = readLayer(attributes); 00204 00205 } else if (name == "view") { 00206 00207 m_inView = true; 00208 ok = readView(attributes); 00209 00210 } else if (name == "derivation") { 00211 00212 ok = readDerivation(attributes); 00213 00214 } else if (name == "playparameters") { 00215 00216 ok = readPlayParameters(attributes); 00217 00218 } else if (name == "plugin") { 00219 00220 ok = readPlugin(attributes); 00221 00222 } else if (name == "selections") { 00223 00224 m_inSelections = true; 00225 ok = true; 00226 00227 } else if (name == "selection") { 00228 00229 ok = readSelection(attributes); 00230 00231 } else if (name == "measurement") { 00232 00233 ok = readMeasurement(attributes); 00234 00235 } else if (name == "transform") { 00236 00237 ok = readTransform(attributes); 00238 00239 } else if (name == "parameter") { 00240 00241 ok = readParameter(attributes); 00242 00243 } else { 00244 cerr << "WARNING: SV-XML: Unexpected element \"" 00245 << name << "\"" << endl; 00246 } 00247 00248 if (!ok) { 00249 cerr << "WARNING: SV-XML: Failed to completely process element \"" 00250 << name << "\"" << endl; 00251 } 00252 00253 return true; 00254 } 00255 00256 bool 00257 SVFileReader::characters(const QString &text) 00258 { 00259 bool ok = false; 00260 00261 if (m_inRow) { 00262 ok = readRowData(text); 00263 if (!ok) { 00264 cerr << "WARNING: SV-XML: Failed to read row data content for row " << m_rowNumber << endl; 00265 } 00266 } 00267 00268 return true; 00269 } 00270 00271 bool 00272 SVFileReader::endElement(const QString &, const QString &, 00273 const QString &qName) 00274 { 00275 QString name = qName.toLower(); 00276 00277 if (name == "dataset") { 00278 00279 if (m_currentDataset) { 00280 00281 bool foundInAwaiting = false; 00282 00283 for (std::map<int, int>::iterator i = m_awaitingDatasets.begin(); 00284 i != m_awaitingDatasets.end(); ++i) { 00285 if (haveModel(i->second) && 00286 m_models[i->second] == m_currentDataset) { 00287 m_awaitingDatasets.erase(i); 00288 foundInAwaiting = true; 00289 break; 00290 } 00291 } 00292 00293 if (!foundInAwaiting) { 00294 cerr << "WARNING: SV-XML: Dataset precedes model, or no model uses dataset" << endl; 00295 } 00296 } 00297 00298 m_currentDataset = 0; 00299 00300 } else if (name == "data") { 00301 00302 addUnaddedModels(); 00303 m_inData = false; 00304 00305 } else if (name == "derivation") { 00306 00307 if (!m_currentDerivedModel) { 00308 if (m_currentDerivedModelId < 0) { 00309 cerr << "WARNING: SV-XML: Bad derivation output model id " 00310 << m_currentDerivedModelId << endl; 00311 } else if (haveModel(m_currentDerivedModelId)) { 00312 cerr << "WARNING: SV-XML: Derivation has existing model " 00313 << m_currentDerivedModelId 00314 << " as target, not regenerating" << endl; 00315 } else { 00316 QString message; 00317 m_currentDerivedModel = m_models[m_currentDerivedModelId] = 00318 m_document->addDerivedModel 00319 (m_currentTransform, 00320 ModelTransformer::Input(m_currentTransformSource, 00321 m_currentTransformChannel), 00322 message); 00323 if (!m_currentDerivedModel) { 00324 emit modelRegenerationFailed(tr("(derived model in SV-XML)"), 00325 m_currentTransform.getIdentifier(), 00326 message); 00327 } else if (message != "") { 00328 emit modelRegenerationWarning(tr("(derived model in SV-XML)"), 00329 m_currentTransform.getIdentifier(), 00330 message); 00331 } 00332 } 00333 } else { 00334 m_document->addAlreadyDerivedModel 00335 (m_currentTransform, 00336 ModelTransformer::Input(m_currentTransformSource, 00337 m_currentTransformChannel), 00338 m_currentDerivedModel); 00339 } 00340 00341 m_addedModels.insert(m_currentDerivedModel); 00342 m_currentDerivedModel = 0; 00343 m_currentDerivedModelId = -1; 00344 m_currentTransformSource = 0; 00345 m_currentTransform = Transform(); 00346 m_currentTransformChannel = -1; 00347 00348 } else if (name == "row") { 00349 m_inRow = false; 00350 } else if (name == "layer") { 00351 m_inLayer = false; 00352 } else if (name == "view") { 00353 m_inView = false; 00354 } else if (name == "selections") { 00355 m_inSelections = false; 00356 } else if (name == "playparameters") { 00357 m_currentPlayParameters = 0; 00358 } 00359 00360 return true; 00361 } 00362 00363 bool 00364 SVFileReader::error(const QXmlParseException &exception) 00365 { 00366 m_errorString = 00367 QString("ERROR: SV-XML: %1 at line %2, column %3") 00368 .arg(exception.message()) 00369 .arg(exception.lineNumber()) 00370 .arg(exception.columnNumber()); 00371 cerr << m_errorString << endl; 00372 return QXmlDefaultHandler::error(exception); 00373 } 00374 00375 bool 00376 SVFileReader::fatalError(const QXmlParseException &exception) 00377 { 00378 m_errorString = 00379 QString("FATAL ERROR: SV-XML: %1 at line %2, column %3") 00380 .arg(exception.message()) 00381 .arg(exception.lineNumber()) 00382 .arg(exception.columnNumber()); 00383 cerr << m_errorString << endl; 00384 return QXmlDefaultHandler::fatalError(exception); 00385 } 00386 00387 00388 #define READ_MANDATORY(TYPE, NAME, CONVERSION) \ 00389 TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \ 00390 if (!ok) { \ 00391 cerr << "WARNING: SV-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << endl; \ 00392 return false; \ 00393 } 00394 00395 bool 00396 SVFileReader::readWindow(const QXmlAttributes &attributes) 00397 { 00398 bool ok = false; 00399 00400 READ_MANDATORY(int, width, toInt); 00401 READ_MANDATORY(int, height, toInt); 00402 00403 m_paneCallback.setWindowSize(width, height); 00404 return true; 00405 } 00406 00407 void 00408 SVFileReader::addUnaddedModels() 00409 { 00410 std::set<Model *> unaddedModels; 00411 00412 for (std::map<int, Model *>::iterator i = m_models.begin(); 00413 i != m_models.end(); ++i) { 00414 if (m_addedModels.find(i->second) == m_addedModels.end()) { 00415 unaddedModels.insert(i->second); 00416 } 00417 } 00418 00419 for (std::set<Model *>::iterator i = unaddedModels.begin(); 00420 i != unaddedModels.end(); ++i) { 00421 Model *model = *i; 00422 // don't want to add these models, because their lifespans 00423 // are entirely dictated by the models that "own" them even 00424 // though they were read independently from the .sv file. 00425 // (pity we don't have a nicer way) 00426 if (!dynamic_cast<PathModel *>(model) && 00427 !dynamic_cast<AlignmentModel *>(model)) { 00428 m_document->addImportedModel(model); 00429 } 00430 // but we add all models here, so they don't get deleted 00431 // when the file loader is destroyed 00432 m_addedModels.insert(model); 00433 } 00434 } 00435 00436 bool 00437 SVFileReader::readModel(const QXmlAttributes &attributes) 00438 { 00439 bool ok = false; 00440 00441 READ_MANDATORY(int, id, toInt); 00442 00443 if (haveModel(id)) { 00444 cerr << "WARNING: SV-XML: Ignoring duplicate model id " << id 00445 << endl; 00446 return false; 00447 } 00448 00449 QString name = attributes.value("name"); 00450 00451 SVDEBUG << "SVFileReader::readModel: model name \"" << name << "\"" << endl; 00452 00453 READ_MANDATORY(int, sampleRate, toInt); 00454 00455 QString type = attributes.value("type").trimmed(); 00456 bool isMainModel = (attributes.value("mainModel").trimmed() == "true"); 00457 00458 if (type == "wavefile") { 00459 00460 WaveFileModel *model = 0; 00461 FileFinder *ff = FileFinder::getInstance(); 00462 QString originalPath = attributes.value("file"); 00463 QString path = ff->find(FileFinder::AudioFile, 00464 originalPath, m_location); 00465 00466 SVDEBUG << "Wave file originalPath = " << originalPath << ", path = " 00467 << path << endl; 00468 00469 ProgressDialog dialog(tr("Opening file or URL..."), true, 2000); 00470 FileSource file(path, &dialog); 00471 file.waitForStatus(); 00472 00473 if (!file.isOK()) { 00474 cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path << "\" for wave file model: " << file.getErrorString() << endl; 00475 } else if (!file.isAvailable()) { 00476 cerr << "SVFileReader::readModel: Failed to retrieve file \"" << path << "\" for wave file model: Source unavailable" << endl; 00477 } else { 00478 00479 file.waitForData(); 00480 00481 int rate = sampleRate; 00482 00483 if (Preferences::getInstance()->getFixedSampleRate() != 0) { 00484 rate = Preferences::getInstance()->getFixedSampleRate(); 00485 } else if (rate == 0 && 00486 !isMainModel && 00487 Preferences::getInstance()->getResampleOnLoad()) { 00488 WaveFileModel *mm = m_document->getMainModel(); 00489 if (mm) rate = mm->getSampleRate(); 00490 } 00491 00492 model = new WaveFileModel(file, rate); 00493 if (!model->isOK()) { 00494 delete model; 00495 model = 0; 00496 } 00497 } 00498 00499 if (!model) return false; 00500 00501 model->setObjectName(name); 00502 m_models[id] = model; 00503 if (isMainModel) { 00504 m_document->setMainModel(model); 00505 m_addedModels.insert(model); 00506 } 00507 // Derived models will be added when their derivation 00508 // is found. 00509 00510 return true; 00511 00512 } else if (type == "dense") { 00513 00514 READ_MANDATORY(int, dimensions, toInt); 00515 00516 // Currently the only dense model we support here is the dense 00517 // 3d model. Dense time-value models are always file-backed 00518 // waveform data, at this point, and they come in as wavefile 00519 // models. 00520 00521 if (dimensions == 3) { 00522 00523 READ_MANDATORY(int, windowSize, toInt); 00524 READ_MANDATORY(int, yBinCount, toInt); 00525 00526 EditableDenseThreeDimensionalModel *model = 00527 new EditableDenseThreeDimensionalModel 00528 (sampleRate, windowSize, yBinCount, 00529 EditableDenseThreeDimensionalModel::NoCompression); 00530 00531 float minimum = attributes.value("minimum").trimmed().toFloat(&ok); 00532 if (ok) model->setMinimumLevel(minimum); 00533 00534 float maximum = attributes.value("maximum").trimmed().toFloat(&ok); 00535 if (ok) model->setMaximumLevel(maximum); 00536 00537 int dataset = attributes.value("dataset").trimmed().toInt(&ok); 00538 if (ok) m_awaitingDatasets[dataset] = id; 00539 00540 int startFrame = attributes.value("startFrame").trimmed().toInt(&ok); 00541 if (ok) model->setStartFrame(startFrame); 00542 00543 model->setObjectName(name); 00544 m_models[id] = model; 00545 return true; 00546 00547 } else { 00548 00549 cerr << "WARNING: SV-XML: Unexpected dense model dimension (" 00550 << dimensions << ")" << endl; 00551 } 00552 } else if (type == "sparse") { 00553 00554 READ_MANDATORY(int, dimensions, toInt); 00555 00556 if (dimensions == 1) { 00557 00558 READ_MANDATORY(int, resolution, toInt); 00559 00560 if (attributes.value("subtype") == "image") { 00561 00562 bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true"); 00563 ImageModel *model = new ImageModel(sampleRate, resolution, 00564 notifyOnAdd); 00565 model->setObjectName(name); 00566 m_models[id] = model; 00567 00568 } else { 00569 00570 SparseOneDimensionalModel *model = new SparseOneDimensionalModel 00571 (sampleRate, resolution); 00572 model->setObjectName(name); 00573 m_models[id] = model; 00574 } 00575 00576 int dataset = attributes.value("dataset").trimmed().toInt(&ok); 00577 if (ok) m_awaitingDatasets[dataset] = id; 00578 00579 return true; 00580 00581 } else if (dimensions == 2 || dimensions == 3) { 00582 00583 READ_MANDATORY(int, resolution, toInt); 00584 00585 bool haveMinMax = true; 00586 float minimum = attributes.value("minimum").trimmed().toFloat(&ok); 00587 if (!ok) haveMinMax = false; 00588 float maximum = attributes.value("maximum").trimmed().toFloat(&ok); 00589 if (!ok) haveMinMax = false; 00590 00591 float valueQuantization = 00592 attributes.value("valueQuantization").trimmed().toFloat(&ok); 00593 00594 bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true"); 00595 00596 QString units = attributes.value("units"); 00597 00598 if (dimensions == 2) { 00599 if (attributes.value("subtype") == "text") { 00600 TextModel *model = new TextModel 00601 (sampleRate, resolution, notifyOnAdd); 00602 model->setObjectName(name); 00603 m_models[id] = model; 00604 } else if (attributes.value("subtype") == "path") { 00605 PathModel *model = new PathModel 00606 (sampleRate, resolution, notifyOnAdd); 00607 model->setObjectName(name); 00608 m_models[id] = model; 00609 } else { 00610 SparseTimeValueModel *model; 00611 if (haveMinMax) { 00612 model = new SparseTimeValueModel 00613 (sampleRate, resolution, minimum, maximum, notifyOnAdd); 00614 } else { 00615 model = new SparseTimeValueModel 00616 (sampleRate, resolution, notifyOnAdd); 00617 } 00618 model->setScaleUnits(units); 00619 model->setObjectName(name); 00620 m_models[id] = model; 00621 } 00622 } else { 00623 if (attributes.value("subtype") == "region") { 00624 RegionModel *model; 00625 if (haveMinMax) { 00626 model = new RegionModel 00627 (sampleRate, resolution, minimum, maximum, notifyOnAdd); 00628 } else { 00629 model = new RegionModel 00630 (sampleRate, resolution, notifyOnAdd); 00631 } 00632 model->setValueQuantization(valueQuantization); 00633 model->setScaleUnits(units); 00634 model->setObjectName(name); 00635 m_models[id] = model; 00636 } else if (attributes.value("subtype") == "flexinote") { 00637 FlexiNoteModel *model; 00638 if (haveMinMax) { 00639 model = new FlexiNoteModel 00640 (sampleRate, resolution, minimum, maximum, notifyOnAdd); 00641 } else { 00642 model = new FlexiNoteModel 00643 (sampleRate, resolution, notifyOnAdd); 00644 } 00645 model->setValueQuantization(valueQuantization); 00646 model->setScaleUnits(units); 00647 model->setObjectName(name); 00648 m_models[id] = model; 00649 } else { 00650 // note models written out by SV 1.3 and earlier 00651 // have no subtype, so we can't test that 00652 NoteModel *model; 00653 if (haveMinMax) { 00654 model = new NoteModel 00655 (sampleRate, resolution, minimum, maximum, notifyOnAdd); 00656 } else { 00657 model = new NoteModel 00658 (sampleRate, resolution, notifyOnAdd); 00659 } 00660 model->setValueQuantization(valueQuantization); 00661 model->setScaleUnits(units); 00662 model->setObjectName(name); 00663 m_models[id] = model; 00664 } 00665 } 00666 00667 int dataset = attributes.value("dataset").trimmed().toInt(&ok); 00668 if (ok) m_awaitingDatasets[dataset] = id; 00669 00670 return true; 00671 00672 } else { 00673 00674 cerr << "WARNING: SV-XML: Unexpected sparse model dimension (" 00675 << dimensions << ")" << endl; 00676 } 00677 00678 } else if (type == "alignment") { 00679 00680 READ_MANDATORY(int, reference, toInt); 00681 READ_MANDATORY(int, aligned, toInt); 00682 READ_MANDATORY(int, path, toInt); 00683 00684 Model *refModel = 0, *alignedModel = 0, *pathModel = 0; 00685 00686 if (m_models.find(reference) != m_models.end()) { 00687 refModel = m_models[reference]; 00688 } else { 00689 cerr << "WARNING: SV-XML: Unknown reference model id " 00690 << reference << " in alignment model id " << id 00691 << endl; 00692 } 00693 00694 if (m_models.find(aligned) != m_models.end()) { 00695 alignedModel = m_models[aligned]; 00696 } else { 00697 cerr << "WARNING: SV-XML: Unknown aligned model id " 00698 << aligned << " in alignment model id " << id 00699 << endl; 00700 } 00701 00702 if (m_models.find(path) != m_models.end()) { 00703 pathModel = m_models[path]; 00704 } else { 00705 cerr << "WARNING: SV-XML: Unknown path model id " 00706 << path << " in alignment model id " << id 00707 << endl; 00708 } 00709 00710 if (refModel && alignedModel && pathModel) { 00711 AlignmentModel *model = new AlignmentModel 00712 (refModel, alignedModel, 0, 0); 00713 PathModel *pm = dynamic_cast<PathModel *>(pathModel); 00714 if (!pm) { 00715 cerr << "WARNING: SV-XML: Model id " << path 00716 << " referenced as path for alignment " << id 00717 << " is not a path model" << endl; 00718 } else { 00719 model->setPath(pm); 00720 pm->setCompletion(100); 00721 } 00722 model->setObjectName(name); 00723 m_models[id] = model; 00724 alignedModel->setAlignment(model); 00725 return true; 00726 } 00727 00728 } else { 00729 00730 cerr << "WARNING: SV-XML: Unexpected model type \"" 00731 << type << "\" for model id " << id << endl; 00732 } 00733 00734 return false; 00735 } 00736 00737 bool 00738 SVFileReader::readView(const QXmlAttributes &attributes) 00739 { 00740 QString type = attributes.value("type"); 00741 m_currentPane = 0; 00742 00743 if (type != "pane") { 00744 cerr << "WARNING: SV-XML: Unexpected view type \"" 00745 << type << "\"" << endl; 00746 return false; 00747 } 00748 00749 m_currentPane = m_paneCallback.addPane(); 00750 00751 cerr << "SVFileReader::addPane: pane is " << m_currentPane << endl; 00752 00753 if (!m_currentPane) { 00754 cerr << "WARNING: SV-XML: Internal error: Failed to add pane!" 00755 << endl; 00756 return false; 00757 } 00758 00759 bool ok = false; 00760 00761 View *view = m_currentPane; 00762 00763 // The view properties first 00764 00765 READ_MANDATORY(int, centre, toInt); 00766 READ_MANDATORY(int, zoom, toInt); 00767 READ_MANDATORY(int, followPan, toInt); 00768 READ_MANDATORY(int, followZoom, toInt); 00769 QString tracking = attributes.value("tracking"); 00770 00771 // Specify the follow modes before we set the actual values 00772 view->setFollowGlobalPan(followPan); 00773 view->setFollowGlobalZoom(followZoom); 00774 view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous : 00775 tracking == "page" ? PlaybackScrollPageWithCentre : 00776 tracking == "daw" ? PlaybackScrollPage 00777 : PlaybackIgnore); 00778 00779 // Then set these values 00780 view->setCentreFrame(centre); 00781 view->setZoomLevel(zoom); 00782 00783 // And pane properties 00784 READ_MANDATORY(int, centreLineVisible, toInt); 00785 m_currentPane->setCentreLineVisible(centreLineVisible); 00786 00787 int height = attributes.value("height").toInt(&ok); 00788 if (ok) { 00789 m_currentPane->resize(m_currentPane->width(), height); 00790 } 00791 00792 return true; 00793 } 00794 00795 bool 00796 SVFileReader::readLayer(const QXmlAttributes &attributes) 00797 { 00798 QString type = attributes.value("type"); 00799 00800 int id; 00801 bool ok = false; 00802 id = attributes.value("id").trimmed().toInt(&ok); 00803 00804 if (!ok) { 00805 cerr << "WARNING: SV-XML: No layer id for layer of type \"" 00806 << type 00807 << "\"" << endl; 00808 return false; 00809 } 00810 00811 Layer *layer = 0; 00812 bool isNewLayer = false; 00813 00814 // Layers are expected to be defined in layer elements in the data 00815 // section, and referred to in layer elements in the view 00816 // sections. So if we're in the data section, we expect this 00817 // layer not to exist already; if we're in the view section, we 00818 // expect it to exist. 00819 00820 if (m_inData) { 00821 00822 if (m_layers.find(id) != m_layers.end()) { 00823 cerr << "WARNING: SV-XML: Ignoring duplicate layer id " << id 00824 << " in data section" << endl; 00825 return false; 00826 } 00827 00828 layer = m_layers[id] = m_document->createLayer 00829 (LayerFactory::getInstance()->getLayerTypeForName(type)); 00830 00831 if (layer) { 00832 m_layers[id] = layer; 00833 isNewLayer = true; 00834 } 00835 00836 } else { 00837 00838 if (!m_currentPane) { 00839 cerr << "WARNING: SV-XML: No current pane for layer " << id 00840 << " in view section" << endl; 00841 return false; 00842 } 00843 00844 if (m_layers.find(id) != m_layers.end()) { 00845 00846 layer = m_layers[id]; 00847 00848 } else { 00849 cerr << "WARNING: SV-XML: Layer id " << id 00850 << " in view section has not been defined -- defining it here" 00851 << endl; 00852 00853 layer = m_document->createLayer 00854 (LayerFactory::getInstance()->getLayerTypeForName(type)); 00855 00856 if (layer) { 00857 m_layers[id] = layer; 00858 isNewLayer = true; 00859 } 00860 } 00861 } 00862 00863 if (!layer) { 00864 cerr << "WARNING: SV-XML: Failed to add layer of type \"" 00865 << type 00866 << "\"" << endl; 00867 return false; 00868 } 00869 00870 if (isNewLayer) { 00871 00872 QString name = attributes.value("name"); 00873 layer->setObjectName(name); 00874 00875 QString presentationName = attributes.value("presentationName"); 00876 layer->setPresentationName(presentationName); 00877 00878 int modelId; 00879 bool modelOk = false; 00880 modelId = attributes.value("model").trimmed().toInt(&modelOk); 00881 00882 if (modelOk) { 00883 if (haveModel(modelId)) { 00884 Model *model = m_models[modelId]; 00885 m_document->setModel(layer, model); 00886 } else { 00887 cerr << "WARNING: SV-XML: Unknown model id " << modelId 00888 << " in layer definition" << endl; 00889 } 00890 } 00891 00892 layer->setProperties(attributes); 00893 } 00894 00895 if (!m_inData && m_currentPane) { 00896 00897 QString visible = attributes.value("visible"); 00898 bool dormant = (visible == "false"); 00899 00900 // We need to do this both before and after adding the layer 00901 // to the view -- we need it to be dormant if appropriate 00902 // before it's actually added to the view so that any property 00903 // box gets the right state when it's added, but the add layer 00904 // command sets dormant to false because it assumes it may be 00905 // restoring a previously dormant layer, so we need to set it 00906 // again afterwards too. Hm 00907 layer->setLayerDormant(m_currentPane, dormant); 00908 00909 m_document->addLayerToView(m_currentPane, layer); 00910 00911 layer->setLayerDormant(m_currentPane, dormant); 00912 } 00913 00914 m_currentLayer = layer; 00915 m_inLayer = true; 00916 00917 return true; 00918 } 00919 00920 bool 00921 SVFileReader::readDatasetStart(const QXmlAttributes &attributes) 00922 { 00923 bool ok = false; 00924 00925 READ_MANDATORY(int, id, toInt); 00926 READ_MANDATORY(int, dimensions, toInt); 00927 00928 if (m_awaitingDatasets.find(id) == m_awaitingDatasets.end()) { 00929 cerr << "WARNING: SV-XML: Unwanted dataset " << id << endl; 00930 return false; 00931 } 00932 00933 int modelId = m_awaitingDatasets[id]; 00934 00935 Model *model = 0; 00936 if (haveModel(modelId)) { 00937 model = m_models[modelId]; 00938 } else { 00939 cerr << "WARNING: SV-XML: Internal error: Unknown model " << modelId 00940 << " expecting dataset " << id << endl; 00941 return false; 00942 } 00943 00944 bool good = false; 00945 00946 switch (dimensions) { 00947 case 1: 00948 if (dynamic_cast<SparseOneDimensionalModel *>(model)) good = true; 00949 else if (dynamic_cast<ImageModel *>(model)) good = true; 00950 break; 00951 00952 case 2: 00953 if (dynamic_cast<SparseTimeValueModel *>(model)) good = true; 00954 else if (dynamic_cast<TextModel *>(model)) good = true; 00955 else if (dynamic_cast<PathModel *>(model)) good = true; 00956 break; 00957 00958 case 3: 00959 if (dynamic_cast<NoteModel *>(model)) good = true; 00960 else if (dynamic_cast<FlexiNoteModel *>(model)) good = true; 00961 else if (dynamic_cast<RegionModel *>(model)) good = true; 00962 else if (dynamic_cast<EditableDenseThreeDimensionalModel *>(model)) { 00963 m_datasetSeparator = attributes.value("separator"); 00964 good = true; 00965 } 00966 break; 00967 } 00968 00969 if (!good) { 00970 cerr << "WARNING: SV-XML: Model id " << modelId << " has wrong number of dimensions or inappropriate type for " << dimensions << "-D dataset " << id << endl; 00971 m_currentDataset = 0; 00972 return false; 00973 } 00974 00975 m_currentDataset = model; 00976 return true; 00977 } 00978 00979 bool 00980 SVFileReader::addPointToDataset(const QXmlAttributes &attributes) 00981 { 00982 bool ok = false; 00983 00984 READ_MANDATORY(int, frame, toInt); 00985 00986 // SVDEBUG << "SVFileReader::addPointToDataset: frame = " << frame << endl; 00987 00988 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *> 00989 (m_currentDataset); 00990 00991 if (sodm) { 00992 // cerr << "Current dataset is a sparse one dimensional model" << endl; 00993 QString label = attributes.value("label"); 00994 sodm->addPoint(SparseOneDimensionalModel::Point(frame, label)); 00995 return true; 00996 } 00997 00998 SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *> 00999 (m_currentDataset); 01000 01001 if (stvm) { 01002 cerr << "Current dataset is a sparse time-value model" << endl; 01003 float value = 0.0; 01004 value = attributes.value("value").trimmed().toFloat(&ok); 01005 QString label = attributes.value("label"); 01006 stvm->addPoint(SparseTimeValueModel::Point(frame, value, label)); 01007 return ok; 01008 } 01009 01010 NoteModel *nm = dynamic_cast<NoteModel *>(m_currentDataset); 01011 01012 if (nm) { 01013 cerr << "Current dataset is a note model" << endl; 01014 float value = 0.0; 01015 value = attributes.value("value").trimmed().toFloat(&ok); 01016 int duration = 0; 01017 duration = attributes.value("duration").trimmed().toInt(&ok); 01018 QString label = attributes.value("label"); 01019 float level = attributes.value("level").trimmed().toFloat(&ok); 01020 if (!ok) { // level is optional 01021 level = 1.f; 01022 ok = true; 01023 } 01024 nm->addPoint(NoteModel::Point(frame, value, duration, level, label)); 01025 return ok; 01026 } 01027 01028 FlexiNoteModel *fnm = dynamic_cast<FlexiNoteModel *>(m_currentDataset); 01029 01030 if (fnm) { 01031 cerr << "Current dataset is a flexinote model" << endl; 01032 float value = 0.0; 01033 value = attributes.value("value").trimmed().toFloat(&ok); 01034 int duration = 0; 01035 duration = attributes.value("duration").trimmed().toInt(&ok); 01036 QString label = attributes.value("label"); 01037 float level = attributes.value("level").trimmed().toFloat(&ok); 01038 if (!ok) { // level is optional 01039 level = 1.f; 01040 ok = true; 01041 } 01042 fnm->addPoint(FlexiNoteModel::Point(frame, value, duration, level, label)); 01043 return ok; 01044 } 01045 01046 RegionModel *rm = dynamic_cast<RegionModel *>(m_currentDataset); 01047 01048 if (rm) { 01049 cerr << "Current dataset is a region model" << endl; 01050 float value = 0.0; 01051 value = attributes.value("value").trimmed().toFloat(&ok); 01052 int duration = 0; 01053 duration = attributes.value("duration").trimmed().toInt(&ok); 01054 QString label = attributes.value("label"); 01055 rm->addPoint(RegionModel::Point(frame, value, duration, label)); 01056 return ok; 01057 } 01058 01059 TextModel *tm = dynamic_cast<TextModel *>(m_currentDataset); 01060 01061 if (tm) { 01062 // cerr << "Current dataset is a text model" << endl; 01063 float height = 0.0; 01064 height = attributes.value("height").trimmed().toFloat(&ok); 01065 QString label = attributes.value("label"); 01066 // SVDEBUG << "SVFileReader::addPointToDataset: TextModel: frame = " << frame << ", height = " << height << ", label = " << label << ", ok = " << ok << endl; 01067 tm->addPoint(TextModel::Point(frame, height, label)); 01068 return ok; 01069 } 01070 01071 PathModel *pm = dynamic_cast<PathModel *>(m_currentDataset); 01072 01073 if (pm) { 01074 // cerr << "Current dataset is a path model" << endl; 01075 int mapframe = attributes.value("mapframe").trimmed().toInt(&ok); 01076 // SVDEBUG << "SVFileReader::addPointToDataset: PathModel: frame = " << frame << ", mapframe = " << mapframe << ", ok = " << ok << endl; 01077 pm->addPoint(PathModel::Point(frame, mapframe)); 01078 return ok; 01079 } 01080 01081 ImageModel *im = dynamic_cast<ImageModel *>(m_currentDataset); 01082 01083 if (im) { 01084 // cerr << "Current dataset is an image model" << endl; 01085 QString image = attributes.value("image"); 01086 QString label = attributes.value("label"); 01087 // SVDEBUG << "SVFileReader::addPointToDataset: ImageModel: frame = " << frame << ", image = " << image << ", label = " << label << ", ok = " << ok << endl; 01088 im->addPoint(ImageModel::Point(frame, image, label)); 01089 return ok; 01090 } 01091 01092 cerr << "WARNING: SV-XML: Point element found in non-point dataset" << endl; 01093 01094 return false; 01095 } 01096 01097 bool 01098 SVFileReader::addBinToDataset(const QXmlAttributes &attributes) 01099 { 01100 EditableDenseThreeDimensionalModel *dtdm = 01101 dynamic_cast<EditableDenseThreeDimensionalModel *> 01102 (m_currentDataset); 01103 01104 if (dtdm) { 01105 01106 bool ok = false; 01107 int n = attributes.value("number").trimmed().toInt(&ok); 01108 if (!ok) { 01109 cerr << "WARNING: SV-XML: Missing or invalid bin number" 01110 << endl; 01111 return false; 01112 } 01113 01114 QString name = attributes.value("name"); 01115 01116 dtdm->setBinName(n, name); 01117 return true; 01118 } 01119 01120 cerr << "WARNING: SV-XML: Bin definition found in incompatible dataset" << endl; 01121 01122 return false; 01123 } 01124 01125 01126 bool 01127 SVFileReader::addRowToDataset(const QXmlAttributes &attributes) 01128 { 01129 m_inRow = false; 01130 01131 bool ok = false; 01132 m_rowNumber = attributes.value("n").trimmed().toInt(&ok); 01133 if (!ok) { 01134 cerr << "WARNING: SV-XML: Missing or invalid row number" 01135 << endl; 01136 return false; 01137 } 01138 01139 m_inRow = true; 01140 01141 // cerr << "SV-XML: In row " << m_rowNumber << endl; 01142 01143 return true; 01144 } 01145 01146 bool 01147 SVFileReader::readRowData(const QString &text) 01148 { 01149 EditableDenseThreeDimensionalModel *dtdm = 01150 dynamic_cast<EditableDenseThreeDimensionalModel *> 01151 (m_currentDataset); 01152 01153 bool warned = false; 01154 01155 if (dtdm) { 01156 QStringList data = text.split(m_datasetSeparator); 01157 01158 DenseThreeDimensionalModel::Column values; 01159 01160 for (QStringList::iterator i = data.begin(); i != data.end(); ++i) { 01161 01162 if (values.size() == (int)dtdm->getHeight()) { 01163 if (!warned) { 01164 cerr << "WARNING: SV-XML: Too many y-bins in 3-D dataset row " 01165 << m_rowNumber << endl; 01166 warned = true; 01167 } 01168 } 01169 01170 bool ok; 01171 float value = i->toFloat(&ok); 01172 if (!ok) { 01173 cerr << "WARNING: SV-XML: Bad floating-point value " 01174 << i->toLocal8Bit().data() 01175 << " in row data" << endl; 01176 } else { 01177 values.push_back(value); 01178 } 01179 } 01180 01181 dtdm->setColumn(m_rowNumber, values); 01182 return true; 01183 } 01184 01185 cerr << "WARNING: SV-XML: Row data found in non-row dataset" << endl; 01186 01187 return false; 01188 } 01189 01190 bool 01191 SVFileReader::readDerivation(const QXmlAttributes &attributes) 01192 { 01193 int modelId = 0; 01194 bool modelOk = false; 01195 modelId = attributes.value("model").trimmed().toInt(&modelOk); 01196 01197 if (!modelOk) { 01198 cerr << "WARNING: SV-XML: No model id specified for derivation" << endl; 01199 return false; 01200 } 01201 01202 if (haveModel(modelId)) { 01203 m_currentDerivedModel = m_models[modelId]; 01204 } else { 01205 // we'll regenerate the model when the derivation element ends 01206 m_currentDerivedModel = 0; 01207 } 01208 01209 m_currentDerivedModelId = modelId; 01210 01211 int sourceId = 0; 01212 bool sourceOk = false; 01213 sourceId = attributes.value("source").trimmed().toInt(&sourceOk); 01214 01215 if (sourceOk && haveModel(sourceId)) { 01216 m_currentTransformSource = m_models[sourceId]; 01217 } else { 01218 m_currentTransformSource = m_document->getMainModel(); 01219 } 01220 01221 m_currentTransform = Transform(); 01222 01223 bool ok = false; 01224 int channel = attributes.value("channel").trimmed().toInt(&ok); 01225 if (ok) m_currentTransformChannel = channel; 01226 else m_currentTransformChannel = -1; 01227 01228 QString type = attributes.value("type"); 01229 01230 if (type == "transform") { 01231 m_currentTransformIsNewStyle = true; 01232 return true; 01233 } else { 01234 m_currentTransformIsNewStyle = false; 01235 SVDEBUG << "NOTE: SV-XML: Reading old-style derivation element" 01236 << endl; 01237 } 01238 01239 QString transformId = attributes.value("transform"); 01240 01241 m_currentTransform.setIdentifier(transformId); 01242 01243 int stepSize = attributes.value("stepSize").trimmed().toInt(&ok); 01244 if (ok) m_currentTransform.setStepSize(stepSize); 01245 01246 int blockSize = attributes.value("blockSize").trimmed().toInt(&ok); 01247 if (ok) m_currentTransform.setBlockSize(blockSize); 01248 01249 int windowType = attributes.value("windowType").trimmed().toInt(&ok); 01250 if (ok) m_currentTransform.setWindowType(WindowType(windowType)); 01251 01252 if (!m_currentTransformSource) return true; 01253 01254 QString startFrameStr = attributes.value("startFrame"); 01255 QString durationStr = attributes.value("duration"); 01256 01257 int startFrame = 0; 01258 int duration = 0; 01259 01260 if (startFrameStr != "") { 01261 startFrame = startFrameStr.trimmed().toInt(&ok); 01262 if (!ok) startFrame = 0; 01263 } 01264 if (durationStr != "") { 01265 duration = durationStr.trimmed().toInt(&ok); 01266 if (!ok) duration = 0; 01267 } 01268 01269 m_currentTransform.setStartTime 01270 (RealTime::frame2RealTime 01271 (startFrame, m_currentTransformSource->getSampleRate())); 01272 01273 m_currentTransform.setDuration 01274 (RealTime::frame2RealTime 01275 (duration, m_currentTransformSource->getSampleRate())); 01276 01277 return true; 01278 } 01279 01280 bool 01281 SVFileReader::readPlayParameters(const QXmlAttributes &attributes) 01282 { 01283 m_currentPlayParameters = 0; 01284 01285 int modelId = 0; 01286 bool modelOk = false; 01287 modelId = attributes.value("model").trimmed().toInt(&modelOk); 01288 01289 if (!modelOk) { 01290 cerr << "WARNING: SV-XML: No model id specified for play parameters" << endl; 01291 return false; 01292 } 01293 01294 if (haveModel(modelId)) { 01295 01296 bool ok = false; 01297 01298 PlayParameters *parameters = PlayParameterRepository::getInstance()-> 01299 getPlayParameters(m_models[modelId]); 01300 01301 if (!parameters) { 01302 cerr << "WARNING: SV-XML: Play parameters for model " 01303 << modelId 01304 << " not found - has model been added to document?" 01305 << endl; 01306 return false; 01307 } 01308 01309 bool muted = (attributes.value("mute").trimmed() == "true"); 01310 parameters->setPlayMuted(muted); 01311 01312 float pan = attributes.value("pan").toFloat(&ok); 01313 if (ok) parameters->setPlayPan(pan); 01314 01315 float gain = attributes.value("gain").toFloat(&ok); 01316 if (ok) parameters->setPlayGain(gain); 01317 01318 QString clipId = attributes.value("clipId"); 01319 if (clipId != "") parameters->setPlayClipId(clipId); 01320 01321 m_currentPlayParameters = parameters; 01322 01323 // cerr << "Current play parameters for model: " << m_models[modelId] << ": " << m_currentPlayParameters << endl; 01324 01325 } else { 01326 01327 cerr << "WARNING: SV-XML: Unknown model " << modelId 01328 << " for play parameters" << endl; 01329 return false; 01330 } 01331 01332 return true; 01333 } 01334 01335 bool 01336 SVFileReader::readPlugin(const QXmlAttributes &attributes) 01337 { 01338 if (m_currentDerivedModelId >= 0) { 01339 return readPluginForTransform(attributes); 01340 } else if (m_currentPlayParameters) { 01341 return readPluginForPlayback(attributes); 01342 } else { 01343 cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << endl; 01344 return false; 01345 } 01346 } 01347 01348 bool 01349 SVFileReader::readPluginForTransform(const QXmlAttributes &attributes) 01350 { 01351 if (m_currentTransformIsNewStyle) { 01352 // Not needed, we have the transform element instead 01353 return true; 01354 } 01355 01356 QString configurationXml = "<plugin"; 01357 01358 for (int i = 0; i < attributes.length(); ++i) { 01359 configurationXml += QString(" %1=\"%2\"") 01360 .arg(attributes.qName(i)) 01361 .arg(XmlExportable::encodeEntities(attributes.value(i))); 01362 } 01363 01364 configurationXml += "/>"; 01365 01366 TransformFactory::getInstance()-> 01367 setParametersFromPluginConfigurationXml(m_currentTransform, 01368 configurationXml); 01369 return true; 01370 } 01371 01372 bool 01373 SVFileReader::readPluginForPlayback(const QXmlAttributes &attributes) 01374 { 01375 // Obsolete but supported for compatibility 01376 01377 QString ident = attributes.value("identifier"); 01378 if (ident == "sample_player") { 01379 QString clipId = attributes.value("program"); 01380 if (clipId != "") m_currentPlayParameters->setPlayClipId(clipId); 01381 } 01382 01383 return true; 01384 } 01385 01386 bool 01387 SVFileReader::readTransform(const QXmlAttributes &attributes) 01388 { 01389 if (m_currentDerivedModelId < 0) { 01390 cerr << "WARNING: SV-XML: Transform found outside derivation" << endl; 01391 return false; 01392 } 01393 01394 m_currentTransform = Transform(); 01395 m_currentTransform.setFromXmlAttributes(attributes); 01396 return true; 01397 } 01398 01399 bool 01400 SVFileReader::readParameter(const QXmlAttributes &attributes) 01401 { 01402 if (m_currentDerivedModelId < 0) { 01403 cerr << "WARNING: SV-XML: Parameter found outside derivation" << endl; 01404 return false; 01405 } 01406 01407 QString name = attributes.value("name"); 01408 if (name == "") { 01409 cerr << "WARNING: SV-XML: Ignoring nameless transform parameter" 01410 << endl; 01411 return false; 01412 } 01413 01414 float value = attributes.value("value").trimmed().toFloat(); 01415 01416 m_currentTransform.setParameter(name, value); 01417 return true; 01418 } 01419 01420 bool 01421 SVFileReader::readSelection(const QXmlAttributes &attributes) 01422 { 01423 bool ok; 01424 01425 READ_MANDATORY(int, start, toInt); 01426 READ_MANDATORY(int, end, toInt); 01427 01428 m_paneCallback.addSelection(start, end); 01429 01430 return true; 01431 } 01432 01433 bool 01434 SVFileReader::readMeasurement(const QXmlAttributes &attributes) 01435 { 01436 SVDEBUG << "SVFileReader::readMeasurement: inLayer " 01437 << m_inLayer << ", layer " << m_currentLayer << endl; 01438 01439 if (!m_inLayer) { 01440 cerr << "WARNING: SV-XML: Measurement found outside layer" << endl; 01441 return false; 01442 } 01443 01444 m_currentLayer->addMeasurementRect(attributes); 01445 return true; 01446 } 01447 01448 SVFileReaderPaneCallback::~SVFileReaderPaneCallback() 01449 { 01450 } 01451 01452 01453 class SVFileIdentifier : public QXmlDefaultHandler 01454 { 01455 public: 01456 SVFileIdentifier() : 01457 m_inSv(false), 01458 m_inData(false), 01459 m_type(SVFileReader::UnknownFileType) 01460 { } 01461 virtual ~SVFileIdentifier() { } 01462 01463 void parse(QXmlInputSource &source) { 01464 QXmlSimpleReader reader; 01465 reader.setContentHandler(this); 01466 reader.setErrorHandler(this); 01467 reader.parse(source); 01468 } 01469 01470 SVFileReader::FileType getType() const { return m_type; } 01471 01472 virtual bool startElement(const QString &, 01473 const QString &, 01474 const QString &qName, 01475 const QXmlAttributes& atts) 01476 { 01477 QString name = qName.toLower(); 01478 01479 // SV session files have an sv element containing a data 01480 // element containing a model element with mainModel="true". 01481 01482 // If the sv element is present but the rest does not satisfy, 01483 // then it's (probably) an SV layer file. 01484 01485 // Otherwise, it's of unknown type. 01486 01487 if (name == "sv") { 01488 m_inSv = true; 01489 if (m_type == SVFileReader::UnknownFileType) { 01490 m_type = SVFileReader::SVLayerFile; 01491 } 01492 return true; 01493 } else if (name == "data") { 01494 if (!m_inSv) return true; 01495 m_inData = true; 01496 } else if (name == "model") { 01497 if (!m_inData) return true; 01498 if (atts.value("mainModel").trimmed() == "true") { 01499 if (m_type == SVFileReader::SVLayerFile) { 01500 m_type = SVFileReader::SVSessionFile; 01501 return false; // done 01502 } 01503 } 01504 } 01505 return true; 01506 } 01507 01508 virtual bool endElement(const QString &, 01509 const QString &, 01510 const QString &qName) 01511 { 01512 QString name = qName.toLower(); 01513 01514 if (name == "sv") { 01515 if (m_inSv) { 01516 m_inSv = false; 01517 return false; // done 01518 } 01519 } else if (name == "data") { 01520 if (m_inData) { 01521 m_inData = false; 01522 return false; // also done, nothing after the first 01523 // data element is of use here 01524 } 01525 } 01526 return true; 01527 } 01528 01529 private: 01530 bool m_inSv; 01531 bool m_inData; 01532 SVFileReader::FileType m_type; 01533 }; 01534 01535 01536 SVFileReader::FileType 01537 SVFileReader::identifyXmlFile(QString path) 01538 { 01539 QFile file(path); 01540 SVFileIdentifier identifier; 01541 QXmlInputSource source(&file); 01542 identifier.parse(source); 01543 return identifier.getType(); 01544 } 01545 01546 01547