changeset 21:ac5491829e61

add - EasaierSessionManager - Easaier menus - Interval model
author lbajardsilogic
date Mon, 14 May 2007 13:15:26 +0000
parents 32d0a863e040
children f4b98622e1dc
files sv/main/EasaierSessionManager.cpp sv/main/EasaierSessionManager.h sv/main/MainWindow.cpp sv/main/MainWindow.h
diffstat 4 files changed, 934 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sv/main/EasaierSessionManager.cpp	Mon May 14 13:15:26 2007 +0000
@@ -0,0 +1,361 @@
+/* -*- 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 "EasaierSessionManager.h"
+
+#include <QUrl>
+#include <QMessageBox>
+#include <QTextStream>
+#include <iostream>
+
+#include "layer/Layer.h"
+#include "base/TempDirectory.h"
+#include "data/fileio/AudioSourceInfoReader.h"
+#include "data/fileio/ModelReader.h"
+#include "data/fileio/QueryConfigReader.h"
+#include "data/fileio/SparqlResultsReader.h"
+#include "data/model/WaveFileModel.h"
+#include "main/MainWindow.h"
+#include "widgets/QueryResultsWidget.h"
+
+EasaierSessionManager::EasaierSessionManager(HttpClient* httpClient) : QObject(),
+	m_fileName(""),
+	m_httpClient(httpClient),
+	m_document(0),
+	m_audioSourceInfoModel(0),
+	m_queryModel(0)
+{}
+
+EasaierSessionManager::~EasaierSessionManager()
+{
+	closeSession();
+	m_httpClient = 0;
+}
+
+bool EasaierSessionManager::newSession()
+{
+	closeSession();
+
+	m_queryModel = new QueryModel();
+	loadFile("http://easaier.silogic.fr/data/query/queryfield.xml", LoadedFile::QUERY_CONFIG);
+
+	return true;
+}
+
+bool EasaierSessionManager::openSession(Document *document)
+{
+	newSession();
+
+	m_fileName = document->getAudioSourceInfoFileName();
+	m_document = document;
+
+	loadFile(m_fileName, LoadedFile::AUDIO_SOURCE_INFO );
+	
+	return true;
+}
+
+bool EasaierSessionManager::openAudioInfoFile(Document *document)
+{
+	closeFile();
+
+	m_fileName = document->getAudioSourceInfoFileName();
+	m_document = document;
+
+	loadFile(m_fileName, LoadedFile::AUDIO_SOURCE_INFO);
+	
+	return true;
+}
+
+void EasaierSessionManager::closeFile()
+{
+	m_audioSourceInfoModel = 0;
+
+	while (!m_loadFile.empty())
+	{
+		delete m_loadFile.begin()->second;
+	    m_loadFile.erase(m_loadFile.begin());
+	}
+
+	m_modelLoaded.clear();
+	
+	disconnect(m_httpClient, SIGNAL(requestFinished(int, bool)), this, SLOT(fileLoaded(int, bool)));
+}
+
+void EasaierSessionManager::closeSession()
+{
+	closeFile();
+
+	m_fileName = "";
+	m_document = 0;
+	
+	if (m_queryModel)
+	{
+		delete m_queryModel;
+		m_queryModel = 0;
+	}
+}
+
+void EasaierSessionManager::loadFile(const QString& uri, LoadedFile::FileType type)
+{
+	if (uri == 0)
+		return;
+
+	if (m_httpClient->getHost() == "")
+	{
+		return;
+	}
+
+	QUrl url(uri);
+	QString path = url.path();
+	QString directory = path.left(path.lastIndexOf("/"));
+	QString filename = path.right(path.length() - path.lastIndexOf("/"));
+
+	if (directory.left(1) == "/")
+	{
+		directory.remove(0, 1);
+	}
+
+	//create the subdirectory in local
+	QString localPath = TempDirectory::getInstance()->getSubDirectoryPath(directory);
+	localPath.append(filename);
+
+	LoadedFile* newFile = new LoadedFile(localPath);
+	newFile->setFileType(type);
+	newFile->setUri(uri);
+
+	std::cerr << "Ask for file : GET " << path.toStdString() << std::endl;
+
+	int index = m_httpClient->get(path, newFile);
+
+	m_loadFile[index] = newFile;
+
+	connect(m_httpClient, SIGNAL(requestFinished(int, bool)), this, SLOT(fileLoaded(int, bool)));
+
+/*	if (type == LoadedFile::QUERY_RESULTS)
+		MainWindow::instance()->statusBar()->showMessage(tr("Querying database..."));
+	else if (type == LoadedFile::QUERY_CONFIG)
+		MainWindow::instance()->statusBar()->showMessage(tr("Asking for query config..."));
+	else
+		MainWindow::instance()->statusBar()->showMessage(tr("Loading File : %1").arg(filename));*/
+}
+
+void EasaierSessionManager::fileLoaded(int index, bool error)
+{
+	QString errorString = m_httpClient->errorString();
+	std::map<int , LoadedFile*>::iterator iter = m_loadFile.find(index);
+	if (iter == m_loadFile.end())
+	{
+		return;
+	}
+	if (error)
+	{
+		QMessageBox::critical(MainWindow::instance(), tr("Download Failed"), m_httpClient->errorString());
+		return; 
+	}
+	bool read = false;
+	
+	//retreive loaded file
+	LoadedFile* loadedFile = iter->second;
+	loadedFile->close();
+	
+	//save type and filename for reading
+	LoadedFile::FileType type = loadedFile->getFileType();
+	QString filename = loadedFile->fileName();
+	QString uri = loadedFile->getUri();
+
+	//delete de file and erase from the loaded file queue
+	delete loadedFile;
+	m_loadFile.erase(iter);
+
+/*	if ((type == LoadedFile::QUERY_RESULTS) || (type == LoadedFile::QUERY_CONFIG))
+	{
+		MainWindow::instance()->statusBar()->clearMessage();
+	}
+	else
+	{
+		QString name = filename.right(filename.length() - filename.lastIndexOf("/"));
+		MainWindow::instance()->statusBar()->showMessage(tr("File Loaded : %1").arg(name), 3000);
+	}*/
+
+	//read and load (in m_document) the file according to its type 
+	switch (type) {
+
+		case LoadedFile::AUDIO_SOURCE_INFO :
+		{
+		    m_audioSourceInfoModel = new AudioSourceInfoModel();
+			AudioSourceInfoReader audioSourceInfoReader(m_audioSourceInfoModel);
+			read = audioSourceInfoReader.parse(filename);
+			if (read)
+			{
+				m_document->setAudioSourceInfoModel(m_audioSourceInfoModel);
+				loadRelatedModel();
+			}
+		    break;
+		}
+		case LoadedFile::MODEL :
+		{
+			QString modelName = m_audioSourceInfoModel->getKey(uri);
+
+			read = addModelToLayers(modelName, filename);
+
+		    break;
+		}
+		case LoadedFile::METADATA :
+		{
+			ModelReader modelReader(m_document,0, m_currentPane);
+			read = modelReader.parse(filename);
+
+		    break;
+		}
+		case LoadedFile::QUERY_CONFIG :
+		{
+			QueryConfigReader reader(m_queryModel);
+			bool ok = reader.parse(filename);
+
+			if (ok)
+				emit queryModelLoaded(m_queryModel);
+
+			read = ok;
+		    break;
+		}
+		case LoadedFile::QUERY_RESULTS :
+		{
+			QueryResultsWidget* resultsWidget = MainWindow::instance()->getQueryResultsWidget();
+			resultsWidget->reset();
+
+			if (resultsWidget)
+			{
+				SparqlResultsReader reader(resultsWidget);
+				read = reader.parse(filename);
+			}
+		    break;
+		}
+		default: break;
+	}
+
+	//if the file could not be read by any reader
+	if (!read)
+	{
+		QFile file(filename);
+		if (file.open(QFile::ReadOnly)) {
+			QMessageBox::critical(MainWindow::instance(), tr("Download Error"), file.readAll());
+		}
+	}
+}
+
+void EasaierSessionManager::loadRelatedModel()
+{
+	std::set<Layer *> layers = m_document->getLayers();
+	std::set<Layer *>::iterator iter;
+
+	std::set<QString> loadedModel;
+
+	for (iter=layers.begin(); iter != layers.end(); iter++)
+	{
+		Layer * layer = *iter;
+
+		QString modelName	= layer->getModelName();
+		if (modelName != "")
+		{
+			QString modelId		= QString::number(layer->getModelId());
+			modelName.append(modelId);
+
+		} else if (layer->getLayerPresentationName() == "Waveform")
+		{
+			modelName = "audiofile";
+			int modelId = 1;
+			layer->setModelName(modelName);
+			layer->setModelId(modelId);
+			modelName.append(QString::number(modelId));
+		} 
+		
+		if (modelName != "")
+		{
+			QString uri = m_audioSourceInfoModel->getInfo(modelName);
+				
+			std::set<QString>::iterator iterModel = m_modelLoaded.find(uri);
+
+			if (iterModel == m_modelLoaded.end())
+			{
+				m_modelLoaded.insert(uri);
+				loadFile(uri, LoadedFile::MODEL);
+			}
+		}
+	}
+}
+
+bool EasaierSessionManager::addModelToLayers(const QString& name, const QString& filename)
+{
+	std::set<Layer *> layers = m_document->getLayers();
+	std::set<Layer *>::iterator iter;
+
+	std::map<QString, Model *> addedModel;
+
+	bool ok = false;
+
+	for (iter=layers.begin(); iter != layers.end(); iter++)
+	{
+		Layer * layer = *iter;
+
+		QString modelName	= layer->getModelName();
+		QString modelId		= QString::number(layer->getModelId());
+
+		modelName.append(modelId);
+		modelName = modelName.toLower();
+
+		if (modelName == name)
+		{
+			std::map<QString, Model *>::iterator iterModel;
+			iterModel = addedModel.find(modelName);
+
+			if (iterModel == addedModel.end())
+			{
+				if (filename.right(4) == ".ogg")
+				{
+					WaveFileModel *model = new WaveFileModel(filename);
+					m_document->setMainModel(model);
+					addedModel[modelName] = (Model* ) model;
+					ok = true;
+				} else
+				{
+					ModelReader modelReader(m_document, layer);
+					ok = modelReader.parse(filename);
+				}
+			}
+			else
+			{
+				Model* model = iterModel->second;
+				m_document->addImportedModel(model);
+				m_document->setModel(layer, model);
+			}
+		}
+	}
+
+	return ok;
+}
+
+void EasaierSessionManager::importMetadata(const QString& filename, Pane* pane)
+{
+	loadFile(filename, LoadedFile::METADATA);
+	m_currentPane = pane;
+}
+
+void EasaierSessionManager::queryDatabase(const QString& themeName)
+{
+	QString text = tr("Sorry query database information on the %1 theme is not yet available. All results are returned").arg(themeName);	
+	QMessageBox::information( MainWindow::instance(), tr("Query database information"), text);
+	
+	QString filename = "http://easaier.silogic.fr/data/query/results.xml";
+
+	loadFile(filename, LoadedFile::QUERY_RESULTS);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sv/main/EasaierSessionManager.h	Mon May 14 13:15:26 2007 +0000
@@ -0,0 +1,124 @@
+/* -*- 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 _EASAIER_SESSION_MANAGER_H_
+#define _EASAIER_SESSION_MANAGER_H_
+
+#include <QObject>
+#include <QFile>
+
+#include <map>
+#include <set>
+
+#include "data/fileio/HttpClient.h"
+#include "document/Document.h"
+#include "view/Pane.h"
+#include "data/model/QueryModel.h"
+
+class EasaierSessionManager : public QObject
+{
+	Q_OBJECT
+public:
+	EasaierSessionManager(HttpClient* httpClient);
+	virtual ~EasaierSessionManager();
+
+	class LoadedFile : public QFile
+	{
+	public:
+		LoadedFile() : QFile(){}
+		LoadedFile(const QString & name ) : QFile(name ){}
+		virtual ~LoadedFile(){}
+
+		enum FileType {
+			UNKNOWN				= 0,
+			AUDIO_SOURCE_INFO	= 1, // information (metadata) about an audio file
+			MODEL				= 2, // load a model in a existing layer
+			METADATA			= 3, // load the model and create an associated layer
+			QUERY_CONFIG		= 4, // config of the queries
+			QUERY_RESULTS		= 5  // query results
+		};
+
+		inline FileType getFileType() const {return m_type;}
+		inline void setFileType(const FileType type) {m_type = type;}
+
+		inline QString getUri() const {return m_uri;}
+		inline void setUri(const QString& uri) {m_uri = uri;}
+
+	protected:
+		FileType m_type;
+
+		QString m_uri;
+
+	};
+
+public:
+
+	inline void setHttpClient(HttpClient* httpClient) {m_httpClient = httpClient;}
+
+	void loadFile(const QString& uri, LoadedFile::FileType type);
+
+	bool newSession();
+	void closeSession();
+	void closeFile();
+
+	/* open a existing session file:
+	- open the audio source info file 
+	- load the appropriate metadata (needed by opened layers)
+	*/
+	bool openSession(Document *document);
+
+	/* open an audio source info file
+	*/
+	bool openAudioInfoFile(Document *document);
+
+	/*import metadata info in a new layer*/
+	void importMetadata(const QString& filename, Pane* pane);
+
+	/* load the appropriate metadata (needed by opened layers)
+	 of an audio file
+	*/
+	void loadRelatedModel();
+
+	/* add the metadata  to the corresponding layers */
+	bool addModelToLayers(const QString& name, const QString& filename);
+
+	/*query the database*/
+	void queryDatabase(const QString& themeName);
+
+public slots:
+	void fileLoaded(int, bool);
+
+signals:
+	void queryModelLoaded(QueryModel* queryModel);
+
+private:
+
+
+	QString							m_fileName;
+
+	HttpClient						*m_httpClient;
+
+	Document						*m_document;
+	
+	std::map<int , LoadedFile*>		m_loadFile;
+
+	AudioSourceInfoModel			*m_audioSourceInfoModel;
+
+	std::set<QString>				m_modelLoaded;
+
+	Pane							*m_currentPane;
+
+	QueryModel						*m_queryModel;
+};
+
+#endif
\ No newline at end of file
--- a/sv/main/MainWindow.cpp	Mon May 14 13:14:43 2007 +0000
+++ b/sv/main/MainWindow.cpp	Mon May 14 13:15:26 2007 +0000
@@ -66,6 +66,7 @@
 #include "base/Clipboard.h"
 #include "base/TempDirectory.h"
 #include "osc/OSCQueue.h"
+#include "main/EasaierSessionManager.h"
 
 // For version information
 #include "vamp/vamp.h"
@@ -94,6 +95,7 @@
 #include <QProcess>
 #include <QCheckBox>
 #include <QRegExp>
+#include <QFileDialog>
 
 #include <iostream>
 #include <cstdio>
@@ -141,6 +143,8 @@
     m_abandoning(false),
     m_preferencesDialog(0)
 {
+	m_instance = this;
+
     setWindowTitle(tr("Sonic Visualiser"));
 
     UnitDatabase::getInstance()->registerUnit("Hz");
@@ -321,6 +325,10 @@
     }
 
 	m_httpClient = new HttpClient(TempDirectory::getInstance()->getConfigPath());
+	m_EasaierManager = new EasaierSessionManager(m_httpClient);
+
+	connect(m_EasaierManager, SIGNAL(queryModelLoaded(QueryModel*)),
+	    this, SLOT(queryModelLoaded(QueryModel*)));
 
     setupMenus();
     setupToolbars();
@@ -337,11 +345,15 @@
     if (!m_abandoning) {
         closeSession();
     }
+	delete m_EasaierManager;
+    delete m_httpClient;
     delete m_playTarget;
     delete m_playSource;
     delete m_viewManager;
     delete m_oscQueue;
     Profiles::getInstance()->dump();
+
+	m_instance = 0;
 }
 
 QString
@@ -437,6 +449,7 @@
     }
 
     setupFileMenu();
+	setupEasaierMenu();
     setupEditMenu();
     setupViewMenu();
     setupPaneAndLayerMenus();
@@ -454,7 +467,7 @@
 
     QMenu *menu = menuBar()->addMenu(tr("&File"));
     menu->setTearOffEnabled(true);
-    QToolBar *toolbar = addToolBar(tr("File Toolbar"));
+    //QToolBar *toolbar = addToolBar(tr("File Toolbar"));
 
     QIcon icon(":icons/filenew.png");
     icon.addFile(":icons/filenew-22.png");
@@ -463,7 +476,7 @@
     action->setStatusTip(tr("Abandon the current Sonic Visualiser session and start a new one"));
     connect(action, SIGNAL(triggered()), this, SLOT(newSession()));
     menu->addAction(action);
-    toolbar->addAction(action);
+    //toolbar->addAction(action);
 
     icon = QIcon(":icons/fileopensession.png");
     action = new QAction(icon, tr("&Open Session..."), this);
@@ -478,7 +491,7 @@
     action = new QAction(icon, tr("&Open..."), this);
     action->setStatusTip(tr("Open a session file, audio file, or layer"));
     connect(action, SIGNAL(triggered()), this, SLOT(openSomething()));
-    toolbar->addAction(action);
+    //toolbar->addAction(action);
 
     icon = QIcon(":icons/filesave.png");
     icon.addFile(":icons/filesave-22.png");
@@ -488,7 +501,7 @@
     connect(action, SIGNAL(triggered()), this, SLOT(saveSession()));
     connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool)));
     menu->addAction(action);
-    toolbar->addAction(action);
+    //toolbar->addAction(action);
 	
     icon = QIcon(":icons/filesaveas.png");
     icon.addFile(":icons/filesaveas-22.png");
@@ -496,7 +509,7 @@
     action->setStatusTip(tr("Save the current session into a new Sonic Visualiser session file"));
     connect(action, SIGNAL(triggered()), this, SLOT(saveSessionAs()));
     menu->addAction(action);
-    toolbar->addAction(action);
+    //toolbar->addAction(action);
 
     menu->addSeparator();
 
@@ -585,6 +598,56 @@
 }
 
 void
+MainWindow::setupEasaierMenu()
+{
+	if (m_mainMenusCreated) return;
+
+	QMenu* menu = menuBar()->addMenu(tr("&Easaier"));
+	QToolBar *toolbar = addToolBar(tr("Easaier session Toolbar"));
+	
+	QIcon icon(":icons/filenew.png");
+    QAction *action = new QAction(icon, tr("&New Session"), this);
+	action->setShortcut(tr("Ctrl+N"));
+	action->setStatusTip(tr("Clear the current Easaier session and start a new one"));
+	connect(action, SIGNAL(triggered()), this, SLOT(newEasaierSession()));
+	menu->addAction(action);
+	toolbar->addAction(action);
+
+	icon = QIcon(":icons/fileopen.png");
+    action = new QAction(icon, tr("&Open Session..."), this);
+	action->setShortcut(tr("Ctrl+O"));
+	action->setStatusTip(tr("Open a previously saved Easaier session file"));
+	connect(action, SIGNAL(triggered()), this, SLOT(openEasaierSession()));
+	menu->addAction(action);
+	toolbar->addAction(action);
+
+    icon = QIcon(":icons/filesave.png");
+    action = new QAction(icon, tr("&Save Session"), this);
+	action->setShortcut(tr("Ctrl+S"));
+	action->setStatusTip(tr("Save the current session into a Easaier session file"));
+	connect(action, SIGNAL(triggered()), this, SLOT(saveEasaierSession()));
+	//connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool)));
+	menu->addAction(action);
+	toolbar->addAction(action);
+
+	icon = QIcon(":icons/filesaveas.png");
+    action = new QAction(icon, tr("Save Session &As..."), this);
+	action->setStatusTip(tr("Save the current session into a new Easaier session file"));
+	connect(action, SIGNAL(triggered()), this, SLOT(saveEasaierSessionAs()));
+	menu->addAction(action);
+	toolbar->addAction(action);
+
+	menu->addSeparator();
+
+	action = new QAction(QIcon(":/icons/exit.png"),
+				 tr("&Quit"), this);
+	action->setShortcut(tr("Ctrl+Q"));
+	connect(action, SIGNAL(triggered()), this, SLOT(exit()));
+	menu->addAction(action);
+
+}
+
+void
 MainWindow::setupEditMenu()
 {
     if (m_mainMenusCreated) return;
@@ -2631,6 +2694,8 @@
 
     m_overview->registerView(pane);
 
+	m_EasaierManager->newSession();
+
     CommandHistory::getInstance()->clear();
     CommandHistory::getInstance()->documentSaved();
     documentRestored();
@@ -2670,6 +2735,9 @@
     connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)),
 	    this, SLOT(modelAboutToBeDeleted(Model *)));
 
+	connect(m_document, SIGNAL(audioSourceInfoAdded(AudioSourceInfoModel *)),
+	    this, SLOT(audioSourceInfoAdded(AudioSourceInfoModel *)));
+
     connect(m_document, SIGNAL(modelGenerationFailed(QString)),
             this, SLOT(modelGenerationFailed(QString)));
     connect(m_document, SIGNAL(modelRegenerationFailed(QString, QString)),
@@ -2708,6 +2776,10 @@
 	m_paneStack->deletePane(pane);
     }
 
+	m_infoWidget->reset();
+	m_searchWidget->reset();
+	m_resultsWidget->reset();
+
     delete m_document;
     m_document = 0;
     m_viewManager->clearSelections();
@@ -2719,6 +2791,8 @@
     CommandHistory::getInstance()->clear();
     CommandHistory::getInstance()->documentSaved();
     documentRestored();
+
+	m_EasaierManager->closeSession();
 }
 
 void
@@ -3174,6 +3248,40 @@
     out << "</sv>\n";
 }
 
+void MainWindow::toEasaierXml(QTextStream &out)
+{
+    QString s;
+    QString indent("  ");
+
+    s += "<?xml version=\"1.0\"?>\n";
+//    s += "<!DOCTYPE sonic-visualiser>\n";
+    s += "<easaierSession>\n";
+
+    s += "<display>\n";
+
+    s += QString("  <window width=\"%1\" height=\"%2\"/>\n")
+	.arg(width()).arg(height());
+
+    for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
+
+		Pane *pane = m_paneStack->getPane(i);
+
+		if (pane) {
+			s += pane->toEasaierXmlString(indent);
+		}
+    }
+
+    s += "</display>\n";
+
+//    s += m_viewManager->getSelection().toXmlString();
+
+    s += m_document->toEasaierXmlString(indent, "");
+
+    s += "</easaierSession>\n";
+
+    out << s;
+}
+
 Pane *
 MainWindow::addPaneToStack()
 {
@@ -4886,4 +4994,306 @@
 	closeSession();
 	saveConfigFile();
 	close();
+}
+
+QueryResultsWidget * MainWindow::getQueryResultsWidget()
+{
+	return m_resultsWidget;
+}
+
+void MainWindow::newEasaierSession()
+{
+    if (!checkSaveModified()) return;
+
+    closeSession();
+    createDocument();
+
+    Pane *pane = m_paneStack->addPane();
+
+    if (!m_timeRulerLayer) {
+	m_timeRulerLayer = m_document->createMainModelLayer
+	    (LayerFactory::TimeRuler);
+    }
+
+    m_document->addLayerToView(pane, m_timeRulerLayer);
+
+    Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform);
+    m_document->addLayerToView(pane, waveform);
+
+    m_overview->registerView(pane);
+
+	m_EasaierManager->newSession();
+
+    CommandHistory::getInstance()->clear();
+    CommandHistory::getInstance()->documentSaved();
+    documentRestored();
+    updateMenuStates();
+
+		/**************************************************/
+	QWidget *properties = 0;
+
+	properties = new PropertyStack(0, m_paneStack->getCurrentPane() );
+	//properties->show();
+	m_toolBox->removeItem(0);
+	m_toolBox->insertItem(0,"Layers", properties);
+
+	/*connect(properties, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
+		this, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
+	properties->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
+	*/
+
+	/*************************************************/
+}
+
+void MainWindow::openEasaierSession()
+{
+	if (!checkSaveModified()) return;
+
+    QString orig = m_audioFile;
+    if (orig == "") orig = ".";
+    else orig = QFileInfo(orig).absoluteDir().canonicalPath();
+
+    QString path = QFileDialog::getOpenFileName
+	(this, tr("Select a session file"), orig,
+	 tr("Sound Access session files (*.xml)\nAll files (*.*)"));
+
+    if (path.isEmpty()) return;
+
+    if (!(QFileInfo(path).exists() &&
+	  QFileInfo(path).isFile() &&
+	  QFileInfo(path).isReadable())) {
+	QMessageBox::critical(this, tr("Failed to open file"),
+			      tr("File \"%1\" does not exist or is not a readable file").arg(path));
+	return;
+    }
+
+    if (!openEasaierSessionFile(path)) {
+	QMessageBox::critical(this, tr("Failed to open file"),
+			      tr("Session file \"%1\" could not be opened").arg(path));
+    }
+}
+
+bool MainWindow::openEasaierSessionFile(QString path)
+{
+	QFile file(path);
+    if (!file.open(QIODevice::ReadOnly)) {
+        std::cerr << "Failed to open session file \"" << path.toStdString()
+                  << "\": " << file.errorString().toStdString() << std::endl;
+        return false;
+    }
+
+    QString error;
+    closeSession();
+    createDocument();
+
+    PaneCallback callback(this);
+    m_viewManager->clearSelections();
+
+	ESFileReader reader(m_document, callback);
+    QXmlInputSource inputSource(&file);
+    reader.parse(inputSource);
+    
+    if (!reader.isOK()) {
+        error = tr("Easaier XML file read error:\n%1").arg(reader.getErrorString());
+    }
+    
+    file.close();
+
+    bool ok = (error == "");
+    
+    if (ok) {
+		setWindowTitle(tr("Sound Access: %1")
+				   .arg(QFileInfo(path).fileName()));
+		m_sessionFile = path;
+		setupMenus();
+		CommandHistory::getInstance()->clear();
+		CommandHistory::getInstance()->documentSaved();
+		m_documentModified = false;
+		updateMenuStates();
+    } else {
+		setWindowTitle(tr("Sound Access"));
+    }
+
+	m_EasaierManager->openSession(m_document);
+
+		/**************************************************/
+	QWidget *properties = 0;
+
+	properties = new PropertyStack(0, m_paneStack->getCurrentPane() );
+	//properties->show();
+	m_toolBox->removeItem(0);
+	m_toolBox->insertItem(0,"Layers", properties);
+
+	/*connect(properties, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
+		this, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
+	properties->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
+	*/
+
+	/*************************************************/
+
+
+    return ok;
+}
+
+void MainWindow::saveEasaierSession()
+{
+    if (m_sessionFile != "") {
+		if (!saveEasaierSessionFile(m_sessionFile)) {
+			QMessageBox::critical(this, tr("Failed to save file"),
+					  tr("Session file \"%1\" could not be saved.").arg(m_sessionFile));
+		} else {
+			CommandHistory::getInstance()->documentSaved();
+			documentRestored();
+		}
+    } else {
+		saveEasaierSessionAs();
+    }
+}
+
+void
+MainWindow::saveEasaierSessionAs()
+{
+    QString orig = m_audioFile;
+    if (orig == "") orig = ".";
+    else orig = QFileInfo(orig).absoluteDir().canonicalPath();
+
+    QString path;
+    bool good = false;
+
+    while (!good) {
+
+		path = QFileDialog::getSaveFileName
+			(this, tr("Select a file to save to"), orig,
+			 tr("Sound Access session files (*.xml)\nAll files (*.*)"), 0,
+			 QFileDialog::DontConfirmOverwrite); // we'll do that
+
+		if (path.isEmpty()) return;
+
+		if (!path.endsWith(".xml")) path = path + ".xml";
+
+		QFileInfo fi(path);
+
+		if (fi.isDir()) {
+			QMessageBox::critical(this, tr("Directory selected"),
+					  tr("File \"%1\" is a directory").arg(path));
+			continue;
+		}
+
+		if (fi.exists()) {
+			if (QMessageBox::question(this, tr("File exists"),
+						  tr("The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
+						  QMessageBox::Ok,
+						  QMessageBox::Cancel) == QMessageBox::Ok) {
+				good = true;
+			} else {
+				continue;
+			}
+		}
+
+		good = true;
+    }
+
+    if (!saveEasaierSessionFile(path)) {
+		QMessageBox::critical(this, tr("Failed to save file"),
+			      tr("Session file \"%1\" could not be saved.").arg(m_sessionFile));
+    } else {
+		setWindowTitle(tr("Sound Access: %1")
+				   .arg(QFileInfo(path).fileName()));
+		m_sessionFile = path;
+		CommandHistory::getInstance()->documentSaved();
+		documentRestored();
+    }
+}
+
+bool MainWindow::saveEasaierSessionFile(QString path)
+{
+	QFile file(path);
+
+	if (!file.open(QIODevice::WriteOnly)) {
+        std::cerr << "Failed to open session file \"" << path.toStdString()
+                  << "\" for writing: "
+                  << file.errorString().toStdString() << std::endl;
+        return false;
+    }
+
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+
+    QTextStream out(&file);
+    toEasaierXml(out);
+    out.flush();
+
+    QApplication::restoreOverrideCursor();
+
+	if (file.error()) {
+		QMessageBox::critical(this, tr("Failed to write file"),
+					  tr("Failed to write to file \"%1\": %2")
+					  .arg(path).arg(file.errorString()));
+			file.close();
+		return false;
+    }
+
+    file.close();
+    return true;
+}
+
+void MainWindow::importEasaierLayer(const QString& filename)
+{
+	Pane *pane = m_paneStack->getCurrentPane();
+	m_EasaierManager->importMetadata(filename, pane);
+}
+
+void MainWindow::importEasaierFile(const QString& filename)
+{
+	int i = m_paneStack->getPaneCount();
+	while (i > 0) {
+
+		Pane *pane = m_paneStack->getPane(i - 1);
+
+		int j= pane->getLayerCount();
+		while (j > 0) {
+			m_document->removeLayerFromView(pane, pane->getLayer(j - 1));
+			j--;
+		}
+		i--;
+    }
+
+	delete m_document;
+    
+	createDocument();
+	Pane *pane = m_paneStack->getCurrentPane();
+
+    if (!m_timeRulerLayer) {
+		m_timeRulerLayer = m_document->createMainModelLayer(LayerFactory::TimeRuler);
+    }
+
+    m_document->addLayerToView(pane, m_timeRulerLayer);
+
+    Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform);
+    m_document->addLayerToView(pane, waveform);
+	
+	m_document->setAudioSourceInfoFileName(filename);
+	m_EasaierManager->openAudioInfoFile(m_document);
+}
+
+void MainWindow::queryModelLoaded(QueryModel* queryModel)
+{
+	if (m_searchWidget)
+		m_searchWidget->displayQuerymodel(queryModel);
+}
+
+void MainWindow::audioSourceInfoAdded(AudioSourceInfoModel * info)
+{
+	if (m_infoWidget)
+		m_infoWidget->displayAudioSourceInfo(info);
+
+	m_qtabwidget->setCurrentIndex(Info);
+}
+
+void MainWindow::queryDatabase()
+{
+	QString themeName = sender()->objectName();
+
+	m_EasaierManager->queryDatabase(themeName);
+
+	m_qtabwidget->setCurrentIndex(Result);
 }
\ No newline at end of file
--- a/sv/main/MainWindow.h	Mon May 14 13:14:43 2007 +0000
+++ b/sv/main/MainWindow.h	Mon May 14 13:15:26 2007 +0000
@@ -33,6 +33,7 @@
 #include "data/fileio/FileFinder.h"
 #include "data/fileio/HttpClient.h"
 #include "widgets/WidgetGallery.h"
+#include "document/ESFileReader.h"
 
 #include <map>
 
@@ -60,6 +61,8 @@
 class SearchWidget;
 class QueryResultsWidget;
 class AdvancedToolBox;
+class EasaierSessionManager;
+class QueryModel;
 
 class MainWindow : public QMainWindow
 {
@@ -82,6 +85,13 @@
         FileOpenCancelled
     };
 
+	enum TabName {
+		Search, 
+		Result, 
+		Info, 
+		RelatedMedia, 
+    };
+
     FileOpenStatus openSomeFile(QString path, AudioFileOpenMode = AskUser);
     FileOpenStatus openAudioFile(QString path, AudioFileOpenMode = AskUser);
     FileOpenStatus openLayerFile(QString path);
@@ -93,6 +103,11 @@
 
 	static MainWindow *instance();
 
+	QueryResultsWidget *getQueryResultsWidget();
+
+	bool openEasaierSessionFile(QString path);
+	bool saveEasaierSessionFile(QString path);
+
 signals:
     // Used to toggle the availability of menu actions
     void canAddPane(bool);
@@ -245,9 +260,22 @@
     void help();
     void about();
 
+	void newEasaierSession();
+	void openEasaierSession();
+	void saveEasaierSession();
+    void saveEasaierSessionAs();
+	void importEasaierLayer(const QString& filename);
+	void importEasaierFile(const QString& filename);
+
 	void connectionSettings();
 	void styleSetting();
 
+	void queryModelLoaded(QueryModel* queryModel);
+
+	void audioSourceInfoAdded(AudioSourceInfoModel *);
+
+	void queryDatabase();
+
 	void exit();
 
 protected:
@@ -332,6 +360,7 @@
 
     void setupMenus();
     void setupFileMenu();
+	void setupEasaierMenu();
     void setupEditMenu();
 	void setupSettingMenu();
     void setupViewMenu();
@@ -345,7 +374,7 @@
 
     void addPane(const PaneConfiguration &configuration, QString text);
 
-    class PaneCallback : public SVFileReaderPaneCallback
+    class PaneCallback : public SVFileReaderPaneCallback , public ESFileReaderPaneCallback
     {
     public:
 	PaneCallback(MainWindow *mw) : m_mw(mw) { }
@@ -417,6 +446,7 @@
     void updateVisibleRangeDisplay(Pane *p) const;
 
     void toXml(QTextStream &stream);
+	void toEasaierXml(QTextStream &stream);
 
 	bool saveConfigFile();
 
@@ -433,6 +463,9 @@
 	WidgetGallery			m_gallery;
 
 	HttpClient				*m_httpClient;
+
+	EasaierSessionManager	*m_EasaierManager;
+
 };