Mercurial > hg > easaier-soundaccess
diff sv/document/ESFileReader.cpp @ 19:2a6f70f97395
add
- EasaierSessionManager
- Easaier menus
- Interval model
author | lbajardsilogic |
---|---|
date | Mon, 14 May 2007 13:13:59 +0000 |
parents | |
children | 74d1b3bda5a3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sv/document/ESFileReader.cpp Mon May 14 13:13:59 2007 +0000 @@ -0,0 +1,348 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* Sound Access + EASAIER client application. + Silogic 2007. Laure Bajard. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include <QString> +#include <QMessageBox> +#include <QFileDialog> +#include <QUrl> + +#include <iostream> + +#include "ESFileReader.h" + +#include "layer/Layer.h" +#include "view/View.h" +#include "base/PlayParameters.h" +#include "base/PlayParameterRepository.h" +#include "base/TempDirectory.h" +#include "data/fileio/AudioFileReaderFactory.h" +#include "data/model/WaveFileModel.h" +#include "data/model/DenseThreeDimensionalModel.h" +#include "data/model/SparseOneDimensionalModel.h" +#include "data/model/SparseTimeValueModel.h" +#include "data/model/NoteModel.h" +#include "data/model/TextModel.h" +#include "view/Pane.h" +#include "document/Document.h" + + +ESFileReader::ESFileReader(Document *document, + ESFileReaderPaneCallback &callback) : QXmlDefaultHandler(), + m_document(document), + m_paneCallback(callback), + m_currentPane(0), + m_inView(false), + m_inData(false), + m_ok(false) +{} + +void +ESFileReader::parse(const QString &xmlData) +{ + QXmlInputSource inputSource; + inputSource.setData(xmlData); + parse(inputSource); +} + +void +ESFileReader::parse(QXmlInputSource &inputSource) +{ + QXmlSimpleReader reader; + reader.setContentHandler(this); + reader.setErrorHandler(this); + m_ok = reader.parse(inputSource); +} + +bool +ESFileReader::isOK() +{ + return m_ok; +} + +ESFileReader::~ESFileReader() +{} + +bool +ESFileReader::startElement(const QString &, const QString &, + const QString &qName, + const QXmlAttributes &attributes) +{ + QString name = qName.toLower(); + + bool ok = false; + + // Valid element names: + // + // easaiersession + // data + // easaierresources + // audio + // display + // window + // view + // layer + + if (name == "easaiersession") { + // nothing needed + ok = true; + + } else if (name == "data") { + // nothing needed + m_inData = true; + ok = true; + + } else if (name == "easaierresources") { + // nothing needed + ok = true; + + } else if (name == "audio") { + QString filename = attributes.value("value"); + m_document->setAudioSourceInfoFileName(filename); + + } else if (name == "display") { + // nothing needed + ok = true; + + } else if (name == "window") { + ok = readWindow(attributes); + + } else if (name == "view") { + m_inView = true; + ok = readView(attributes); + + } else if (name == "layer") { + ok = readLayer(attributes); + + } + + if (!ok) { + std::cerr << "WARNING: Easaier Session-XML: Failed to completely process element \"" + << name.toLocal8Bit().data() << "\"" << std::endl; + } + + return true; +} + +bool +ESFileReader::characters(const QString &text) +{ + return true; +} + +bool +ESFileReader::endElement(const QString &, const QString &, + const QString &qName) +{ + QString name = qName.toLower(); + + if (name == "data") { + + m_inData = false; + + } else if (name == "view") { + m_inView = false; + } + + return true; +} + +bool +ESFileReader::error(const QXmlParseException &exception) +{ + m_errorString = + QString("ERROR: Easaier Session-XML: %1 at line %2, column %3") + .arg(exception.message()) + .arg(exception.lineNumber()) + .arg(exception.columnNumber()); + std::cerr << m_errorString.toLocal8Bit().data() << std::endl; + return QXmlDefaultHandler::error(exception); +} + +bool +ESFileReader::fatalError(const QXmlParseException &exception) +{ + m_errorString = + QString("FATAL ERROR: Easaier Session-XML: %1 at line %2, column %3") + .arg(exception.message()) + .arg(exception.lineNumber()) + .arg(exception.columnNumber()); + std::cerr << m_errorString.toLocal8Bit().data() << std::endl; + return QXmlDefaultHandler::fatalError(exception); +} + + +#define READ_MANDATORY(TYPE, NAME, CONVERSION) \ + TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \ + if (!ok) { \ + std::cerr << "WARNING: Easaier Session-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << std::endl; \ + return false; \ + } + +bool +ESFileReader::readWindow(const QXmlAttributes &attributes) +{ + bool ok = false; + + READ_MANDATORY(int, width, toInt); + READ_MANDATORY(int, height, toInt); + + m_paneCallback.setWindowSize(width, height); + return true; +} + +bool +ESFileReader::readView(const QXmlAttributes &attributes) +{ + QString type = attributes.value("type"); + m_currentPane = 0; + + if (type != "pane") { + std::cerr << "WARNING: Easaier session-XML: Unexpected view type \"" + << type.toLocal8Bit().data() << "\"" << std::endl; + return false; + } + + m_currentPane = m_paneCallback.addPane(); + + if (!m_currentPane) { + std::cerr << "WARNING: Easaier session-XML: Internal error: Failed to add pane!" + << std::endl; + return false; + } + + bool ok = false; + + View *view = m_currentPane; + + // The view properties first + + READ_MANDATORY(size_t, centre, toUInt); + READ_MANDATORY(size_t, zoom, toUInt); + READ_MANDATORY(int, followPan, toInt); + READ_MANDATORY(int, followZoom, toInt); + QString tracking = attributes.value("tracking"); + + // Specify the follow modes before we set the actual values + view->setFollowGlobalPan(followPan); + view->setFollowGlobalZoom(followZoom); + view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous : + tracking == "page" ? PlaybackScrollPage + : PlaybackIgnore); + + // Then set these values + view->setCentreFrame(centre); + view->setZoomLevel(zoom); + + // And pane properties + READ_MANDATORY(int, centreLineVisible, toInt); + m_currentPane->setCentreLineVisible(centreLineVisible); + + int height = attributes.value("height").toInt(&ok); + if (ok) { + m_currentPane->resize(m_currentPane->width(), height); + } + + return true; +} + +bool +ESFileReader::readLayer(const QXmlAttributes &attributes) +{ + QString type = attributes.value("type"); + + int id; + bool ok = false; + id = attributes.value("id").trimmed().toInt(&ok); + + if (!ok) { + std::cerr << "WARNING: Easaier session-XML: No layer id for layer of type \"" + << type.toLocal8Bit().data() + << "\"" << std::endl; + return false; + } + + Layer *layer = 0; + bool isNewLayer = false; + + // Layers are expected to be defined in layer elements in the data + // section, and referred to in layer elements in the view + // sections. So if we're in the data section, we expect this + // layer not to exist already; if we're in the view section, we + // expect it to exist. + + if (m_inData) { + + if (m_layers.find(id) != m_layers.end()) { + std::cerr << "WARNING: Easaier session-XML: Ignoring duplicate layer id " << id + << " in data section" << std::endl; + return false; + } + + layer = m_layers[id] = m_document->createLayer + (LayerFactory::getInstance()->getLayerTypeForName(type)); + + if (layer) { + m_layers[id] = layer; + isNewLayer = true; + } + + } else { + + if (!m_currentPane) { + std::cerr << "WARNING: Easaier session-XML: No current pane for layer " << id + << " in view section" << std::endl; + return false; + } + + if (m_layers.find(id) != m_layers.end()) { + + layer = m_layers[id]; + + } else { + layer = m_document->createLayer(LayerFactory::getInstance()->getLayerTypeForName(type)); + + if (layer) { + m_layers[id] = layer; + isNewLayer = true; + } + } + } + + if (!layer) { + std::cerr << "WARNING: Easaier session-XML: Failed to add layer of type \"" + << type.toLocal8Bit().data() + << "\"" << std::endl; + return false; + } + + if (isNewLayer) { + + QString name = attributes.value("name"); + layer->setObjectName(name); + + QString modelName = attributes.value("model"); + int modelId = attributes.value("modelId").toInt(); + + layer->setModelName(modelName); + layer->setModelId(modelId); + + layer->setProperties(attributes); + } + + if (!m_inData && m_currentPane) { + m_document->addLayerToView(m_currentPane, layer); + } + + return true; +} +