# HG changeset patch # User lbajardsilogic # Date 1179148439 0 # Node ID 2a6f70f973956ab22a8a30d956a51c6ac324d030 # Parent d8e6709e90753ea088e954081d0415a11bf5cce9 add - EasaierSessionManager - Easaier menus - Interval model diff -r d8e6709e9075 -r 2a6f70f97395 sv/document/Document.cpp --- a/sv/document/Document.cpp Mon May 14 13:13:14 2007 +0000 +++ b/sv/document/Document.cpp Mon May 14 13:13:59 2007 +0000 @@ -32,7 +32,8 @@ //!!! still need to handle command history, documentRestored/documentModified Document::Document() : - m_mainModel(0) + m_mainModel(0), + m_audioSourceInfoModel(0) { connect(this, SIGNAL(modelAboutToBeDeleted(Model *)), TransformFactory::getInstance(), @@ -71,6 +72,12 @@ } } + if (m_audioSourceInfoModel) + { + delete m_audioSourceInfoModel; + m_audioSourceInfoModel = 0; + } + // std::cerr << "Document::~Document: About to get rid of main model" // << std::endl; emit modelAboutToBeDeleted(m_mainModel); @@ -312,6 +319,12 @@ delete oldMainModel; } +void Document::setAudioSourceInfoModel(AudioSourceInfoModel *infoModel) +{ + m_audioSourceInfoModel = infoModel; + emit audioSourceInfoAdded(m_audioSourceInfoModel); +} + void Document::addDerivedModel(TransformId transform, Model *inputModel, @@ -861,3 +874,24 @@ return s; } +QString +Document::toEasaierXmlString(QString indent, QString extraAttributes) const +{ + QString s; + + s += indent + QString("\n") + .arg(extraAttributes == "" ? "" : " ").arg(extraAttributes); + + s += indent + indent + QString("\n"); + + s += indent + indent + indent + QString("\n"); + + s += indent + indent + QString("\n"); + + s += indent + "\n"; + + return s; +} diff -r d8e6709e9075 -r 2a6f70f97395 sv/document/Document.h --- a/sv/document/Document.h Mon May 14 13:13:14 2007 +0000 +++ b/sv/document/Document.h Mon May 14 13:13:59 2007 +0000 @@ -20,6 +20,7 @@ #include "transform/Transform.h" #include "transform/PluginTransform.h" #include "base/Command.h" +#include "data/model/AudioSourceInfoModel.h" #include #include @@ -137,6 +138,11 @@ std::vector getTransformInputModels(); + inline void setAudioSourceInfoFileName(const QString& name){m_audioSourceInfoFileName = name;} + inline QString getAudioSourceInfoFileName() const { return m_audioSourceInfoFileName;} + + void setAudioSourceInfoModel(AudioSourceInfoModel *infoModel); + /** * Add a derived model associated with the given transform, * running the transform and returning the resulting model. @@ -189,9 +195,13 @@ */ void removeLayerFromView(View *, Layer *); + inline std::set& getLayers(){return m_layers;} + void toXml(QTextStream &, QString indent, QString extraAttributes) const; QString toXmlString(QString indent, QString extraAttributes) const; + QString toEasaierXmlString(QString indent, QString extraAttributes) const; + signals: void layerAdded(Layer *); void layerRemoved(Layer *); @@ -208,6 +218,8 @@ void modelGenerationFailed(QString transformName); void modelRegenerationFailed(QString layerName, QString transformName); + void audioSourceInfoAdded(AudioSourceInfoModel *); + protected: void releaseModel(Model *model); @@ -233,6 +245,16 @@ */ WaveFileModel *m_mainModel; + /** + * The name of the file on the easaier server that provides info on title, author...etc + */ + QString m_audioSourceInfoFileName; + + /** + * The model that provides info on title, author...etc + */ + AudioSourceInfoModel *m_audioSourceInfoModel; + struct ModelRecord { // Information associated with a non-main model. If this diff -r d8e6709e9075 -r 2a6f70f97395 sv/document/ESFileReader.cpp --- /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 +#include +#include +#include + +#include + +#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; +} + diff -r d8e6709e9075 -r 2a6f70f97395 sv/document/ESFileReader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sv/document/ESFileReader.h Mon May 14 13:13:59 2007 +0000 @@ -0,0 +1,90 @@ +/* -*- 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. +*/ + +#ifndef _ES_FILE_READER_H_ +#define _ES_FILE_READER_H_ + +#include "layer/LayerFactory.h" +#include "transform/Transform.h" +#include "data/model/AudioSourceInfoModel.h" +#include "data/fileio/HttpClient.h" + +#include + +#include + +class Pane; +class Model; +class Document; +class PlayParameters; + +class ESFileReaderPaneCallback +{ +public: + virtual ~ESFileReaderPaneCallback(){} + virtual Pane *addPane() = 0; + virtual void setWindowSize(int width, int height) = 0; + virtual void addSelection(int start, int end) = 0; +}; + +class ESFileReader : public QXmlDefaultHandler +{ +public: + ESFileReader(Document *document, + ESFileReaderPaneCallback &callback); + virtual ~ESFileReader(); + + void parse(const QString &xmlData); + void parse(QXmlInputSource &source); + + bool isOK(); + QString getErrorString() const { return m_errorString; } + + // For loading a single layer onto an existing pane + void setCurrentPane(Pane *pane) { m_currentPane = pane; } + + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes& atts); + + virtual bool characters(const QString &); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + + bool error(const QXmlParseException &exception); + bool fatalError(const QXmlParseException &exception); + +protected: + bool readWindow(const QXmlAttributes &); + bool readView(const QXmlAttributes &); + bool readLayer(const QXmlAttributes &); + + Document *m_document; + ESFileReaderPaneCallback &m_paneCallback; + Pane *m_currentPane; + std::map m_layers; + + bool m_inView; + bool m_inData; + + QString m_errorString; + bool m_ok; + +}; + + + +#endif