annotate 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
rev   line source
lbajardsilogic@19 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@19 2
lbajardsilogic@19 3 /* Sound Access
lbajardsilogic@19 4 EASAIER client application.
lbajardsilogic@19 5 Silogic 2007. Laure Bajard.
lbajardsilogic@19 6
lbajardsilogic@19 7 This program is free software; you can redistribute it and/or
lbajardsilogic@19 8 modify it under the terms of the GNU General Public License as
lbajardsilogic@19 9 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@19 10 License, or (at your option) any later version. See the file
lbajardsilogic@19 11 COPYING included with this distribution for more information.
lbajardsilogic@19 12 */
lbajardsilogic@19 13
lbajardsilogic@19 14 #include <QString>
lbajardsilogic@19 15 #include <QMessageBox>
lbajardsilogic@19 16 #include <QFileDialog>
lbajardsilogic@19 17 #include <QUrl>
lbajardsilogic@19 18
lbajardsilogic@19 19 #include <iostream>
lbajardsilogic@19 20
lbajardsilogic@19 21 #include "ESFileReader.h"
lbajardsilogic@19 22
lbajardsilogic@19 23 #include "layer/Layer.h"
lbajardsilogic@19 24 #include "view/View.h"
lbajardsilogic@19 25 #include "base/PlayParameters.h"
lbajardsilogic@19 26 #include "base/PlayParameterRepository.h"
lbajardsilogic@19 27 #include "base/TempDirectory.h"
lbajardsilogic@19 28 #include "data/fileio/AudioFileReaderFactory.h"
lbajardsilogic@19 29 #include "data/model/WaveFileModel.h"
lbajardsilogic@19 30 #include "data/model/DenseThreeDimensionalModel.h"
lbajardsilogic@19 31 #include "data/model/SparseOneDimensionalModel.h"
lbajardsilogic@19 32 #include "data/model/SparseTimeValueModel.h"
lbajardsilogic@19 33 #include "data/model/NoteModel.h"
lbajardsilogic@19 34 #include "data/model/TextModel.h"
lbajardsilogic@19 35 #include "view/Pane.h"
lbajardsilogic@19 36 #include "document/Document.h"
lbajardsilogic@19 37
lbajardsilogic@19 38
lbajardsilogic@19 39 ESFileReader::ESFileReader(Document *document,
lbajardsilogic@19 40 ESFileReaderPaneCallback &callback) : QXmlDefaultHandler(),
lbajardsilogic@19 41 m_document(document),
lbajardsilogic@19 42 m_paneCallback(callback),
lbajardsilogic@19 43 m_currentPane(0),
lbajardsilogic@19 44 m_inView(false),
lbajardsilogic@19 45 m_inData(false),
lbajardsilogic@19 46 m_ok(false)
lbajardsilogic@19 47 {}
lbajardsilogic@19 48
lbajardsilogic@19 49 void
lbajardsilogic@19 50 ESFileReader::parse(const QString &xmlData)
lbajardsilogic@19 51 {
lbajardsilogic@19 52 QXmlInputSource inputSource;
lbajardsilogic@19 53 inputSource.setData(xmlData);
lbajardsilogic@19 54 parse(inputSource);
lbajardsilogic@19 55 }
lbajardsilogic@19 56
lbajardsilogic@19 57 void
lbajardsilogic@19 58 ESFileReader::parse(QXmlInputSource &inputSource)
lbajardsilogic@19 59 {
lbajardsilogic@19 60 QXmlSimpleReader reader;
lbajardsilogic@19 61 reader.setContentHandler(this);
lbajardsilogic@19 62 reader.setErrorHandler(this);
lbajardsilogic@19 63 m_ok = reader.parse(inputSource);
lbajardsilogic@19 64 }
lbajardsilogic@19 65
lbajardsilogic@19 66 bool
lbajardsilogic@19 67 ESFileReader::isOK()
lbajardsilogic@19 68 {
lbajardsilogic@19 69 return m_ok;
lbajardsilogic@19 70 }
lbajardsilogic@19 71
lbajardsilogic@19 72 ESFileReader::~ESFileReader()
lbajardsilogic@19 73 {}
lbajardsilogic@19 74
lbajardsilogic@19 75 bool
lbajardsilogic@19 76 ESFileReader::startElement(const QString &, const QString &,
lbajardsilogic@19 77 const QString &qName,
lbajardsilogic@19 78 const QXmlAttributes &attributes)
lbajardsilogic@19 79 {
lbajardsilogic@19 80 QString name = qName.toLower();
lbajardsilogic@19 81
lbajardsilogic@19 82 bool ok = false;
lbajardsilogic@19 83
lbajardsilogic@19 84 // Valid element names:
lbajardsilogic@19 85 //
lbajardsilogic@19 86 // easaiersession
lbajardsilogic@19 87 // data
lbajardsilogic@19 88 // easaierresources
lbajardsilogic@19 89 // audio
lbajardsilogic@19 90 // display
lbajardsilogic@19 91 // window
lbajardsilogic@19 92 // view
lbajardsilogic@19 93 // layer
lbajardsilogic@19 94
lbajardsilogic@19 95 if (name == "easaiersession") {
lbajardsilogic@19 96 // nothing needed
lbajardsilogic@19 97 ok = true;
lbajardsilogic@19 98
lbajardsilogic@19 99 } else if (name == "data") {
lbajardsilogic@19 100 // nothing needed
lbajardsilogic@19 101 m_inData = true;
lbajardsilogic@19 102 ok = true;
lbajardsilogic@19 103
lbajardsilogic@19 104 } else if (name == "easaierresources") {
lbajardsilogic@19 105 // nothing needed
lbajardsilogic@19 106 ok = true;
lbajardsilogic@19 107
lbajardsilogic@19 108 } else if (name == "audio") {
lbajardsilogic@19 109 QString filename = attributes.value("value");
lbajardsilogic@19 110 m_document->setAudioSourceInfoFileName(filename);
lbajardsilogic@19 111
lbajardsilogic@19 112 } else if (name == "display") {
lbajardsilogic@19 113 // nothing needed
lbajardsilogic@19 114 ok = true;
lbajardsilogic@19 115
lbajardsilogic@19 116 } else if (name == "window") {
lbajardsilogic@19 117 ok = readWindow(attributes);
lbajardsilogic@19 118
lbajardsilogic@19 119 } else if (name == "view") {
lbajardsilogic@19 120 m_inView = true;
lbajardsilogic@19 121 ok = readView(attributes);
lbajardsilogic@19 122
lbajardsilogic@19 123 } else if (name == "layer") {
lbajardsilogic@19 124 ok = readLayer(attributes);
lbajardsilogic@19 125
lbajardsilogic@19 126 }
lbajardsilogic@19 127
lbajardsilogic@19 128 if (!ok) {
lbajardsilogic@19 129 std::cerr << "WARNING: Easaier Session-XML: Failed to completely process element \""
lbajardsilogic@19 130 << name.toLocal8Bit().data() << "\"" << std::endl;
lbajardsilogic@19 131 }
lbajardsilogic@19 132
lbajardsilogic@19 133 return true;
lbajardsilogic@19 134 }
lbajardsilogic@19 135
lbajardsilogic@19 136 bool
lbajardsilogic@19 137 ESFileReader::characters(const QString &text)
lbajardsilogic@19 138 {
lbajardsilogic@19 139 return true;
lbajardsilogic@19 140 }
lbajardsilogic@19 141
lbajardsilogic@19 142 bool
lbajardsilogic@19 143 ESFileReader::endElement(const QString &, const QString &,
lbajardsilogic@19 144 const QString &qName)
lbajardsilogic@19 145 {
lbajardsilogic@19 146 QString name = qName.toLower();
lbajardsilogic@19 147
lbajardsilogic@19 148 if (name == "data") {
lbajardsilogic@19 149
lbajardsilogic@19 150 m_inData = false;
lbajardsilogic@19 151
lbajardsilogic@19 152 } else if (name == "view") {
lbajardsilogic@19 153 m_inView = false;
lbajardsilogic@19 154 }
lbajardsilogic@19 155
lbajardsilogic@19 156 return true;
lbajardsilogic@19 157 }
lbajardsilogic@19 158
lbajardsilogic@19 159 bool
lbajardsilogic@19 160 ESFileReader::error(const QXmlParseException &exception)
lbajardsilogic@19 161 {
lbajardsilogic@19 162 m_errorString =
lbajardsilogic@19 163 QString("ERROR: Easaier Session-XML: %1 at line %2, column %3")
lbajardsilogic@19 164 .arg(exception.message())
lbajardsilogic@19 165 .arg(exception.lineNumber())
lbajardsilogic@19 166 .arg(exception.columnNumber());
lbajardsilogic@19 167 std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
lbajardsilogic@19 168 return QXmlDefaultHandler::error(exception);
lbajardsilogic@19 169 }
lbajardsilogic@19 170
lbajardsilogic@19 171 bool
lbajardsilogic@19 172 ESFileReader::fatalError(const QXmlParseException &exception)
lbajardsilogic@19 173 {
lbajardsilogic@19 174 m_errorString =
lbajardsilogic@19 175 QString("FATAL ERROR: Easaier Session-XML: %1 at line %2, column %3")
lbajardsilogic@19 176 .arg(exception.message())
lbajardsilogic@19 177 .arg(exception.lineNumber())
lbajardsilogic@19 178 .arg(exception.columnNumber());
lbajardsilogic@19 179 std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
lbajardsilogic@19 180 return QXmlDefaultHandler::fatalError(exception);
lbajardsilogic@19 181 }
lbajardsilogic@19 182
lbajardsilogic@19 183
lbajardsilogic@19 184 #define READ_MANDATORY(TYPE, NAME, CONVERSION) \
lbajardsilogic@19 185 TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \
lbajardsilogic@19 186 if (!ok) { \
lbajardsilogic@19 187 std::cerr << "WARNING: Easaier Session-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << std::endl; \
lbajardsilogic@19 188 return false; \
lbajardsilogic@19 189 }
lbajardsilogic@19 190
lbajardsilogic@19 191 bool
lbajardsilogic@19 192 ESFileReader::readWindow(const QXmlAttributes &attributes)
lbajardsilogic@19 193 {
lbajardsilogic@19 194 bool ok = false;
lbajardsilogic@19 195
lbajardsilogic@19 196 READ_MANDATORY(int, width, toInt);
lbajardsilogic@19 197 READ_MANDATORY(int, height, toInt);
lbajardsilogic@19 198
lbajardsilogic@19 199 m_paneCallback.setWindowSize(width, height);
lbajardsilogic@19 200 return true;
lbajardsilogic@19 201 }
lbajardsilogic@19 202
lbajardsilogic@19 203 bool
lbajardsilogic@19 204 ESFileReader::readView(const QXmlAttributes &attributes)
lbajardsilogic@19 205 {
lbajardsilogic@19 206 QString type = attributes.value("type");
lbajardsilogic@19 207 m_currentPane = 0;
lbajardsilogic@19 208
lbajardsilogic@19 209 if (type != "pane") {
lbajardsilogic@19 210 std::cerr << "WARNING: Easaier session-XML: Unexpected view type \""
lbajardsilogic@19 211 << type.toLocal8Bit().data() << "\"" << std::endl;
lbajardsilogic@19 212 return false;
lbajardsilogic@19 213 }
lbajardsilogic@19 214
lbajardsilogic@19 215 m_currentPane = m_paneCallback.addPane();
lbajardsilogic@19 216
lbajardsilogic@19 217 if (!m_currentPane) {
lbajardsilogic@19 218 std::cerr << "WARNING: Easaier session-XML: Internal error: Failed to add pane!"
lbajardsilogic@19 219 << std::endl;
lbajardsilogic@19 220 return false;
lbajardsilogic@19 221 }
lbajardsilogic@19 222
lbajardsilogic@19 223 bool ok = false;
lbajardsilogic@19 224
lbajardsilogic@19 225 View *view = m_currentPane;
lbajardsilogic@19 226
lbajardsilogic@19 227 // The view properties first
lbajardsilogic@19 228
lbajardsilogic@19 229 READ_MANDATORY(size_t, centre, toUInt);
lbajardsilogic@19 230 READ_MANDATORY(size_t, zoom, toUInt);
lbajardsilogic@19 231 READ_MANDATORY(int, followPan, toInt);
lbajardsilogic@19 232 READ_MANDATORY(int, followZoom, toInt);
lbajardsilogic@19 233 QString tracking = attributes.value("tracking");
lbajardsilogic@19 234
lbajardsilogic@19 235 // Specify the follow modes before we set the actual values
lbajardsilogic@19 236 view->setFollowGlobalPan(followPan);
lbajardsilogic@19 237 view->setFollowGlobalZoom(followZoom);
lbajardsilogic@19 238 view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous :
lbajardsilogic@19 239 tracking == "page" ? PlaybackScrollPage
lbajardsilogic@19 240 : PlaybackIgnore);
lbajardsilogic@19 241
lbajardsilogic@19 242 // Then set these values
lbajardsilogic@19 243 view->setCentreFrame(centre);
lbajardsilogic@19 244 view->setZoomLevel(zoom);
lbajardsilogic@19 245
lbajardsilogic@19 246 // And pane properties
lbajardsilogic@19 247 READ_MANDATORY(int, centreLineVisible, toInt);
lbajardsilogic@19 248 m_currentPane->setCentreLineVisible(centreLineVisible);
lbajardsilogic@19 249
lbajardsilogic@19 250 int height = attributes.value("height").toInt(&ok);
lbajardsilogic@19 251 if (ok) {
lbajardsilogic@19 252 m_currentPane->resize(m_currentPane->width(), height);
lbajardsilogic@19 253 }
lbajardsilogic@19 254
lbajardsilogic@19 255 return true;
lbajardsilogic@19 256 }
lbajardsilogic@19 257
lbajardsilogic@19 258 bool
lbajardsilogic@19 259 ESFileReader::readLayer(const QXmlAttributes &attributes)
lbajardsilogic@19 260 {
lbajardsilogic@19 261 QString type = attributes.value("type");
lbajardsilogic@19 262
lbajardsilogic@19 263 int id;
lbajardsilogic@19 264 bool ok = false;
lbajardsilogic@19 265 id = attributes.value("id").trimmed().toInt(&ok);
lbajardsilogic@19 266
lbajardsilogic@19 267 if (!ok) {
lbajardsilogic@19 268 std::cerr << "WARNING: Easaier session-XML: No layer id for layer of type \""
lbajardsilogic@19 269 << type.toLocal8Bit().data()
lbajardsilogic@19 270 << "\"" << std::endl;
lbajardsilogic@19 271 return false;
lbajardsilogic@19 272 }
lbajardsilogic@19 273
lbajardsilogic@19 274 Layer *layer = 0;
lbajardsilogic@19 275 bool isNewLayer = false;
lbajardsilogic@19 276
lbajardsilogic@19 277 // Layers are expected to be defined in layer elements in the data
lbajardsilogic@19 278 // section, and referred to in layer elements in the view
lbajardsilogic@19 279 // sections. So if we're in the data section, we expect this
lbajardsilogic@19 280 // layer not to exist already; if we're in the view section, we
lbajardsilogic@19 281 // expect it to exist.
lbajardsilogic@19 282
lbajardsilogic@19 283 if (m_inData) {
lbajardsilogic@19 284
lbajardsilogic@19 285 if (m_layers.find(id) != m_layers.end()) {
lbajardsilogic@19 286 std::cerr << "WARNING: Easaier session-XML: Ignoring duplicate layer id " << id
lbajardsilogic@19 287 << " in data section" << std::endl;
lbajardsilogic@19 288 return false;
lbajardsilogic@19 289 }
lbajardsilogic@19 290
lbajardsilogic@19 291 layer = m_layers[id] = m_document->createLayer
lbajardsilogic@19 292 (LayerFactory::getInstance()->getLayerTypeForName(type));
lbajardsilogic@19 293
lbajardsilogic@19 294 if (layer) {
lbajardsilogic@19 295 m_layers[id] = layer;
lbajardsilogic@19 296 isNewLayer = true;
lbajardsilogic@19 297 }
lbajardsilogic@19 298
lbajardsilogic@19 299 } else {
lbajardsilogic@19 300
lbajardsilogic@19 301 if (!m_currentPane) {
lbajardsilogic@19 302 std::cerr << "WARNING: Easaier session-XML: No current pane for layer " << id
lbajardsilogic@19 303 << " in view section" << std::endl;
lbajardsilogic@19 304 return false;
lbajardsilogic@19 305 }
lbajardsilogic@19 306
lbajardsilogic@19 307 if (m_layers.find(id) != m_layers.end()) {
lbajardsilogic@19 308
lbajardsilogic@19 309 layer = m_layers[id];
lbajardsilogic@19 310
lbajardsilogic@19 311 } else {
lbajardsilogic@19 312 layer = m_document->createLayer(LayerFactory::getInstance()->getLayerTypeForName(type));
lbajardsilogic@19 313
lbajardsilogic@19 314 if (layer) {
lbajardsilogic@19 315 m_layers[id] = layer;
lbajardsilogic@19 316 isNewLayer = true;
lbajardsilogic@19 317 }
lbajardsilogic@19 318 }
lbajardsilogic@19 319 }
lbajardsilogic@19 320
lbajardsilogic@19 321 if (!layer) {
lbajardsilogic@19 322 std::cerr << "WARNING: Easaier session-XML: Failed to add layer of type \""
lbajardsilogic@19 323 << type.toLocal8Bit().data()
lbajardsilogic@19 324 << "\"" << std::endl;
lbajardsilogic@19 325 return false;
lbajardsilogic@19 326 }
lbajardsilogic@19 327
lbajardsilogic@19 328 if (isNewLayer) {
lbajardsilogic@19 329
lbajardsilogic@19 330 QString name = attributes.value("name");
lbajardsilogic@19 331 layer->setObjectName(name);
lbajardsilogic@19 332
lbajardsilogic@19 333 QString modelName = attributes.value("model");
lbajardsilogic@19 334 int modelId = attributes.value("modelId").toInt();
lbajardsilogic@19 335
lbajardsilogic@19 336 layer->setModelName(modelName);
lbajardsilogic@19 337 layer->setModelId(modelId);
lbajardsilogic@19 338
lbajardsilogic@19 339 layer->setProperties(attributes);
lbajardsilogic@19 340 }
lbajardsilogic@19 341
lbajardsilogic@19 342 if (!m_inData && m_currentPane) {
lbajardsilogic@19 343 m_document->addLayerToView(m_currentPane, layer);
lbajardsilogic@19 344 }
lbajardsilogic@19 345
lbajardsilogic@19 346 return true;
lbajardsilogic@19 347 }
lbajardsilogic@19 348