view data/fileio/ModelReader.cpp @ 282:d9319859a4cf tip

(none)
author benoitrigolleau
date Fri, 31 Oct 2008 11:00:24 +0000
parents ee047fc1a552
children
line wrap: on
line source
/* -*- 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 "ModelReader.h"

#include "document/Document.h"
#include "layer/Layer.h"

#include "data/model/EditableDenseThreeDimensionalModel.h"
#include "data/model/SparseOneDimensionalModel.h"
#include "data/model/SparseTimeValueModel.h"
#include "data/model/NoteModel.h"
#include "data/model/TextModel.h"
#include "data/model/IntervalModel.h"
#include "view/Pane.h"
#include "main/MainWindow.h"

#include <iostream>

ModelReader::ModelReader(Document *document, Layer * layer, Pane * pane) : 
	m_document(document),
	m_layer(layer),
	m_pane(pane)
{
}

bool ModelReader::parse(const QString & filename)
{
	ModelHandler handler(m_document, m_layer, m_pane);
    QXmlSimpleReader reader;
    reader.setContentHandler(&handler);
    reader.setErrorHandler(&handler);

	QFile file(filename);

    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        return false;
    }

    QXmlInputSource xmlInputSource(&file);
    if (reader.parse(xmlInputSource))
	{
		return true;
	}
	
	return false;
}

ModelHandler::ModelHandler(Document *document, Layer * layer, Pane* pane) : QXmlDefaultHandler(),
	m_document(document),
	m_layer(layer),
	m_pane(pane),
    m_model(0),
	m_inBinding(false),
	m_curBindingName(""),
	m_sampleRate(44100)
{
	m_sampleRate = MainWindow::instance()->getMainModelSampleRate();
}

bool ModelHandler::startElement(const QString &namespaceURI, const QString &localName,
						  const QString &qName, const QXmlAttributes &attributes)
{
	
    QString name = qName.toLower();

    bool ok = false;

	if (name == "sparql") {

		// nothing needed
		ok = true;

    } else if (name == "head") {

		// nothing needed
		ok = true;

    } else if (name == "variable") {

		// nothing needed
		ok = true;
    
    } else if (name == "results") {
	
		// nothing needed
		ok = true;

    } else if (name == "result") {
	
		//m_resultsWidget->newResult();
		ok = true;

    } else if (name == "binding") {
	
		m_curBindingName = attributes.value("name");
		ok = true;

    } else if ( (name == "uri") || (name == "literal") ) {
		m_inBinding = true;	
		ok = true;
	}

    if (!ok) {
		std::cerr << "WARNING: ModelReader-XML: Failed to completely process element \""
		  << name.toLocal8Bit().data() << "\"" << std::endl;
    }

    return true;
}

bool ModelHandler::endElement(const QString &namespaceURI, const QString &localName,
						const QString &qName)
{
	QString name = qName.toLower();

	if ( (name == "uri") || (name == "literal") )
	{
		m_inBinding = false;
		m_curBindingName = "";

	} else if (name == "result")
	{
		addNewData();
	}

    return true;
}

bool ModelHandler::characters(const QString &str)
{
	if (m_inBinding)
	{
		m_info[m_curBindingName] = str;
	}

    return true;
}

bool ModelHandler::error(const QXmlParseException &exception)
{
	QString errorString;
	errorString += QString("ERROR: ModelReader-XML: %1 at line %2, column %3")
	.arg(exception.message())
	.arg(exception.lineNumber())
	.arg(exception.columnNumber());
    std::cerr << errorString.toLocal8Bit().data() << std::endl;
    return QXmlDefaultHandler::error(exception);
}

bool ModelHandler::fatalError(const QXmlParseException &exception)
{
	QString errorString;
	errorString += QString("FATAL ERROR: ModelReader-XML: %1 at line %2, column %3")
	.arg(exception.message())
	.arg(exception.lineNumber())
	.arg(exception.columnNumber());
    std::cerr << errorString.toLocal8Bit().data() << std::endl;
    return QXmlDefaultHandler::fatalError(exception);
}

void ModelHandler::addNewData()
{
	m_layer = 0;
	m_model = 0;

	if (m_info.find("beginsAt") != m_info.end())
	{
		addDataInterval();
	} else if (m_info.find("at") != m_info.end())
	{
		addDataTimeInstants();
	}

	m_info.clear();
}

void ModelHandler::addDataInterval()
{
	std::map<QString, QString>::iterator iter;
	
	std::map<QString, QString>::iterator iterEventLabel = m_info.find("event_label");
	if (iterEventLabel == m_info.end())
		return;

	QString eventLabel = iterEventLabel->second;

	std::set<Layer *> layers = m_document->getLayers();
	std::set<Layer *>::iterator iterLayer;
	bool findLayer = false;
	
	for (iterLayer=layers.begin(); iterLayer != layers.end(); iterLayer++)
	{
		if ((*iterLayer)->objectName() == eventLabel)
		{
			m_layer = (*iterLayer);
			findLayer = true;
			m_model = m_layer->getModel();
		}
	}

	if (!findLayer)
	{
		//create layer
		m_layer = m_document->createLayer(LayerFactory::getInstance()->getLayerTypeForName("interval"));

		if (!m_layer) {
			std::cerr << "WARNING: modelreader-XML: Failed to add layer of type interval" << std::endl;
			return ;
		}
		m_layer->setObjectName(eventLabel);
		
		m_layer->setModelName(eventLabel);
		
		if (m_pane && m_layer)
		{
			m_document->addLayerToViewWithoutCommand(m_pane, m_layer);
		}
	}	

	if (!m_model)
	{
		//create model	
		IntervalModel * model = new IntervalModel(m_sampleRate, 1, true);
		m_model = model;
		m_model->setObjectName(eventLabel);

		//set color and value for interval
		IntervalModel *im = dynamic_cast<IntervalModel*> (m_model);
		if ((m_pane) && (im))
		{
			int modulo = m_pane->getIntervalModulo();
			im->setMeanValue(modulo*0.2+0.2);
			m_layer->setProperty("Colour", modulo + 1);
		}

		//link model, layer document and view
		if (m_model && m_layer)
		{
			m_document->addImportedModel(m_model);
			m_document->setModel(m_layer, m_model);
		}
	}
		
	//add interval
	IntervalModel *im = dynamic_cast<IntervalModel*> (m_model);
	if (im)
	{
		//start
		iter = m_info.find("beginsAt");
		if (iter == m_info.end())
			return;
		QString beginAt = iter->second;
		long start = beginAt.mid(2, beginAt.length()-3).toDouble()*m_sampleRate;
		//end
		iter = m_info.find("duration");
		if (iter == m_info.end())
			return;
		QString duration = iter->second;
		long temp = duration.mid(2, duration.length()-3).toDouble();
		long end = start + duration.mid(2, duration.length()-3).toDouble()*m_sampleRate;
		//label
		QString label = "";
		for (iter = m_info.begin(); iter != m_info.end(); iter++)
		{
			QString propertylabel = iter->first;
			if ((propertylabel != "beginsAt") && (propertylabel != "duration") && 
				(propertylabel != "event_label") && (propertylabel != "signal") )
				label += iter->second + " - ";
		}
		//value
		std::cerr << "modelreader-XML: beginAt = " << beginAt.toStdString() << " duration : " << duration.toStdString() << std::endl;
		std::cerr << "modelreader-XML: temp = " << temp << std::endl;
		std::cerr << "modelreader-XML: start = " << start << " end : " << end << std::endl;
			
		float value = im->getMeanValue();
		im->addInterval(start, end, label, value);
	}
}

void ModelHandler::addDataTimeInstants()
{
	std::map<QString, QString>::iterator iter;

	std::map<QString, QString>::iterator iterEventLabel = m_info.find("event_label");
	if (iterEventLabel == m_info.end())
		return;

	QString eventLabel = iterEventLabel->second;

	std::set<Layer *> layers = m_document->getLayers();
	std::set<Layer *>::iterator iterLayer;
	bool findLayer = false;

	for (iterLayer=layers.begin(); iterLayer != layers.end(); iterLayer++)
	{
		if ((*iterLayer)->objectName() == eventLabel)
		{
			m_layer = (*iterLayer);
			findLayer = true;
			m_model = m_layer->getModel();
		}
	}

	if (!findLayer)
	{
		//create layer
		m_layer = m_document->createLayer(LayerFactory::getInstance()->getLayerTypeForName("timeinstants"));

		if (!m_layer) {
			std::cerr << "WARNING: modelreader-XML: Failed to add layer of type timeinstants" << std::endl;
			return ;
		}
		m_layer->setObjectName(eventLabel);

		m_layer->setModelName(eventLabel);
		
		if (m_pane && m_layer)
		{
			m_document->addLayerToView(m_pane, m_layer);
		}
	}

	if (!m_model)
	{
		//create model
		SparseOneDimensionalModel *model = new SparseOneDimensionalModel(m_sampleRate, 512);
		m_model = model;
		m_model->setObjectName(eventLabel);
		
		//link model, layer document and view
		if (m_model && m_layer)
		{
			m_document->addImportedModel(m_model);
			m_document->setModel(m_layer, m_model);
		}
	}

	//add point
	SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *>	(m_model);
    if (sodm) 
	{
		//frame
		iter = m_info.find("at");
		if (iter == m_info.end())
			return;
		QString at = iter->second;
		long frame = at.toDouble()*m_sampleRate;

		sodm->addPoint(SparseOneDimensionalModel::Point(frame, ""));
    }

}