annotate sv/document/ESFileReader.cpp @ 203:74d1b3bda5a3

allow to save and restore the filter settings from an easaier session
author lbajardsilogic
date Tue, 29 Jan 2008 17:21:42 +0000
parents 2a6f70f97395
children 3200ed3fc957
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@203 112 } else if (name == "filters") {
lbajardsilogic@203 113 // nothing needed
lbajardsilogic@203 114 ok = true;
lbajardsilogic@203 115
lbajardsilogic@203 116 } else if (name == "filter") {
lbajardsilogic@203 117 // nothing needed
lbajardsilogic@203 118 ok = readFilter(attributes);;
lbajardsilogic@203 119
lbajardsilogic@19 120 } else if (name == "display") {
lbajardsilogic@19 121 // nothing needed
lbajardsilogic@19 122 ok = true;
lbajardsilogic@19 123
lbajardsilogic@19 124 } else if (name == "window") {
lbajardsilogic@19 125 ok = readWindow(attributes);
lbajardsilogic@19 126
lbajardsilogic@19 127 } else if (name == "view") {
lbajardsilogic@19 128 m_inView = true;
lbajardsilogic@19 129 ok = readView(attributes);
lbajardsilogic@19 130
lbajardsilogic@19 131 } else if (name == "layer") {
lbajardsilogic@19 132 ok = readLayer(attributes);
lbajardsilogic@19 133
lbajardsilogic@19 134 }
lbajardsilogic@19 135
lbajardsilogic@19 136 if (!ok) {
lbajardsilogic@19 137 std::cerr << "WARNING: Easaier Session-XML: Failed to completely process element \""
lbajardsilogic@19 138 << name.toLocal8Bit().data() << "\"" << std::endl;
lbajardsilogic@19 139 }
lbajardsilogic@19 140
lbajardsilogic@19 141 return true;
lbajardsilogic@19 142 }
lbajardsilogic@19 143
lbajardsilogic@19 144 bool
lbajardsilogic@19 145 ESFileReader::characters(const QString &text)
lbajardsilogic@19 146 {
lbajardsilogic@19 147 return true;
lbajardsilogic@19 148 }
lbajardsilogic@19 149
lbajardsilogic@19 150 bool
lbajardsilogic@19 151 ESFileReader::endElement(const QString &, const QString &,
lbajardsilogic@19 152 const QString &qName)
lbajardsilogic@19 153 {
lbajardsilogic@19 154 QString name = qName.toLower();
lbajardsilogic@19 155
lbajardsilogic@19 156 if (name == "data") {
lbajardsilogic@19 157
lbajardsilogic@19 158 m_inData = false;
lbajardsilogic@19 159
lbajardsilogic@19 160 } else if (name == "view") {
lbajardsilogic@19 161 m_inView = false;
lbajardsilogic@19 162 }
lbajardsilogic@19 163
lbajardsilogic@19 164 return true;
lbajardsilogic@19 165 }
lbajardsilogic@19 166
lbajardsilogic@19 167 bool
lbajardsilogic@19 168 ESFileReader::error(const QXmlParseException &exception)
lbajardsilogic@19 169 {
lbajardsilogic@19 170 m_errorString =
lbajardsilogic@19 171 QString("ERROR: Easaier Session-XML: %1 at line %2, column %3")
lbajardsilogic@19 172 .arg(exception.message())
lbajardsilogic@19 173 .arg(exception.lineNumber())
lbajardsilogic@19 174 .arg(exception.columnNumber());
lbajardsilogic@19 175 std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
lbajardsilogic@19 176 return QXmlDefaultHandler::error(exception);
lbajardsilogic@19 177 }
lbajardsilogic@19 178
lbajardsilogic@19 179 bool
lbajardsilogic@19 180 ESFileReader::fatalError(const QXmlParseException &exception)
lbajardsilogic@19 181 {
lbajardsilogic@19 182 m_errorString =
lbajardsilogic@19 183 QString("FATAL ERROR: Easaier Session-XML: %1 at line %2, column %3")
lbajardsilogic@19 184 .arg(exception.message())
lbajardsilogic@19 185 .arg(exception.lineNumber())
lbajardsilogic@19 186 .arg(exception.columnNumber());
lbajardsilogic@19 187 std::cerr << m_errorString.toLocal8Bit().data() << std::endl;
lbajardsilogic@19 188 return QXmlDefaultHandler::fatalError(exception);
lbajardsilogic@19 189 }
lbajardsilogic@19 190
lbajardsilogic@19 191
lbajardsilogic@19 192 #define READ_MANDATORY(TYPE, NAME, CONVERSION) \
lbajardsilogic@19 193 TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \
lbajardsilogic@19 194 if (!ok) { \
lbajardsilogic@19 195 std::cerr << "WARNING: Easaier Session-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << std::endl; \
lbajardsilogic@19 196 return false; \
lbajardsilogic@19 197 }
lbajardsilogic@19 198
lbajardsilogic@19 199 bool
lbajardsilogic@19 200 ESFileReader::readWindow(const QXmlAttributes &attributes)
lbajardsilogic@19 201 {
lbajardsilogic@19 202 bool ok = false;
lbajardsilogic@19 203
lbajardsilogic@19 204 READ_MANDATORY(int, width, toInt);
lbajardsilogic@19 205 READ_MANDATORY(int, height, toInt);
lbajardsilogic@19 206
lbajardsilogic@19 207 m_paneCallback.setWindowSize(width, height);
lbajardsilogic@19 208 return true;
lbajardsilogic@19 209 }
lbajardsilogic@19 210
lbajardsilogic@19 211 bool
lbajardsilogic@19 212 ESFileReader::readView(const QXmlAttributes &attributes)
lbajardsilogic@19 213 {
lbajardsilogic@19 214 QString type = attributes.value("type");
lbajardsilogic@19 215 m_currentPane = 0;
lbajardsilogic@19 216
lbajardsilogic@19 217 if (type != "pane") {
lbajardsilogic@19 218 std::cerr << "WARNING: Easaier session-XML: Unexpected view type \""
lbajardsilogic@19 219 << type.toLocal8Bit().data() << "\"" << std::endl;
lbajardsilogic@19 220 return false;
lbajardsilogic@19 221 }
lbajardsilogic@19 222
lbajardsilogic@19 223 m_currentPane = m_paneCallback.addPane();
lbajardsilogic@19 224
lbajardsilogic@19 225 if (!m_currentPane) {
lbajardsilogic@19 226 std::cerr << "WARNING: Easaier session-XML: Internal error: Failed to add pane!"
lbajardsilogic@19 227 << std::endl;
lbajardsilogic@19 228 return false;
lbajardsilogic@19 229 }
lbajardsilogic@19 230
lbajardsilogic@19 231 bool ok = false;
lbajardsilogic@19 232
lbajardsilogic@19 233 View *view = m_currentPane;
lbajardsilogic@19 234
lbajardsilogic@19 235 // The view properties first
lbajardsilogic@19 236
lbajardsilogic@19 237 READ_MANDATORY(size_t, centre, toUInt);
lbajardsilogic@19 238 READ_MANDATORY(size_t, zoom, toUInt);
lbajardsilogic@19 239 READ_MANDATORY(int, followPan, toInt);
lbajardsilogic@19 240 READ_MANDATORY(int, followZoom, toInt);
lbajardsilogic@19 241 QString tracking = attributes.value("tracking");
lbajardsilogic@19 242
lbajardsilogic@19 243 // Specify the follow modes before we set the actual values
lbajardsilogic@19 244 view->setFollowGlobalPan(followPan);
lbajardsilogic@19 245 view->setFollowGlobalZoom(followZoom);
lbajardsilogic@19 246 view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous :
lbajardsilogic@19 247 tracking == "page" ? PlaybackScrollPage
lbajardsilogic@19 248 : PlaybackIgnore);
lbajardsilogic@19 249
lbajardsilogic@19 250 // Then set these values
lbajardsilogic@19 251 view->setCentreFrame(centre);
lbajardsilogic@19 252 view->setZoomLevel(zoom);
lbajardsilogic@19 253
lbajardsilogic@19 254 // And pane properties
lbajardsilogic@19 255 READ_MANDATORY(int, centreLineVisible, toInt);
lbajardsilogic@19 256 m_currentPane->setCentreLineVisible(centreLineVisible);
lbajardsilogic@19 257
lbajardsilogic@19 258 int height = attributes.value("height").toInt(&ok);
lbajardsilogic@19 259 if (ok) {
lbajardsilogic@19 260 m_currentPane->resize(m_currentPane->width(), height);
lbajardsilogic@19 261 }
lbajardsilogic@19 262
lbajardsilogic@19 263 return true;
lbajardsilogic@19 264 }
lbajardsilogic@19 265
lbajardsilogic@19 266 bool
lbajardsilogic@19 267 ESFileReader::readLayer(const QXmlAttributes &attributes)
lbajardsilogic@19 268 {
lbajardsilogic@19 269 QString type = attributes.value("type");
lbajardsilogic@19 270
lbajardsilogic@19 271 int id;
lbajardsilogic@19 272 bool ok = false;
lbajardsilogic@19 273 id = attributes.value("id").trimmed().toInt(&ok);
lbajardsilogic@19 274
lbajardsilogic@19 275 if (!ok) {
lbajardsilogic@19 276 std::cerr << "WARNING: Easaier session-XML: No layer id for layer of type \""
lbajardsilogic@19 277 << type.toLocal8Bit().data()
lbajardsilogic@19 278 << "\"" << std::endl;
lbajardsilogic@19 279 return false;
lbajardsilogic@19 280 }
lbajardsilogic@19 281
lbajardsilogic@19 282 Layer *layer = 0;
lbajardsilogic@19 283 bool isNewLayer = false;
lbajardsilogic@19 284
lbajardsilogic@19 285 // Layers are expected to be defined in layer elements in the data
lbajardsilogic@19 286 // section, and referred to in layer elements in the view
lbajardsilogic@19 287 // sections. So if we're in the data section, we expect this
lbajardsilogic@19 288 // layer not to exist already; if we're in the view section, we
lbajardsilogic@19 289 // expect it to exist.
lbajardsilogic@19 290
lbajardsilogic@19 291 if (m_inData) {
lbajardsilogic@19 292
lbajardsilogic@19 293 if (m_layers.find(id) != m_layers.end()) {
lbajardsilogic@19 294 std::cerr << "WARNING: Easaier session-XML: Ignoring duplicate layer id " << id
lbajardsilogic@19 295 << " in data section" << std::endl;
lbajardsilogic@19 296 return false;
lbajardsilogic@19 297 }
lbajardsilogic@19 298
lbajardsilogic@19 299 layer = m_layers[id] = m_document->createLayer
lbajardsilogic@19 300 (LayerFactory::getInstance()->getLayerTypeForName(type));
lbajardsilogic@19 301
lbajardsilogic@19 302 if (layer) {
lbajardsilogic@19 303 m_layers[id] = layer;
lbajardsilogic@19 304 isNewLayer = true;
lbajardsilogic@19 305 }
lbajardsilogic@19 306
lbajardsilogic@19 307 } else {
lbajardsilogic@19 308
lbajardsilogic@19 309 if (!m_currentPane) {
lbajardsilogic@19 310 std::cerr << "WARNING: Easaier session-XML: No current pane for layer " << id
lbajardsilogic@19 311 << " in view section" << std::endl;
lbajardsilogic@19 312 return false;
lbajardsilogic@19 313 }
lbajardsilogic@19 314
lbajardsilogic@19 315 if (m_layers.find(id) != m_layers.end()) {
lbajardsilogic@19 316
lbajardsilogic@19 317 layer = m_layers[id];
lbajardsilogic@19 318
lbajardsilogic@19 319 } else {
lbajardsilogic@19 320 layer = m_document->createLayer(LayerFactory::getInstance()->getLayerTypeForName(type));
lbajardsilogic@19 321
lbajardsilogic@19 322 if (layer) {
lbajardsilogic@19 323 m_layers[id] = layer;
lbajardsilogic@19 324 isNewLayer = true;
lbajardsilogic@19 325 }
lbajardsilogic@19 326 }
lbajardsilogic@19 327 }
lbajardsilogic@19 328
lbajardsilogic@19 329 if (!layer) {
lbajardsilogic@19 330 std::cerr << "WARNING: Easaier session-XML: Failed to add layer of type \""
lbajardsilogic@19 331 << type.toLocal8Bit().data()
lbajardsilogic@19 332 << "\"" << std::endl;
lbajardsilogic@19 333 return false;
lbajardsilogic@19 334 }
lbajardsilogic@19 335
lbajardsilogic@19 336 if (isNewLayer) {
lbajardsilogic@19 337
lbajardsilogic@19 338 QString name = attributes.value("name");
lbajardsilogic@19 339 layer->setObjectName(name);
lbajardsilogic@19 340
lbajardsilogic@19 341 QString modelName = attributes.value("model");
lbajardsilogic@19 342 int modelId = attributes.value("modelId").toInt();
lbajardsilogic@19 343
lbajardsilogic@19 344 layer->setModelName(modelName);
lbajardsilogic@19 345 layer->setModelId(modelId);
lbajardsilogic@19 346
lbajardsilogic@19 347 layer->setProperties(attributes);
lbajardsilogic@19 348 }
lbajardsilogic@19 349
lbajardsilogic@19 350 if (!m_inData && m_currentPane) {
lbajardsilogic@19 351 m_document->addLayerToView(m_currentPane, layer);
lbajardsilogic@19 352 }
lbajardsilogic@19 353
lbajardsilogic@19 354 return true;
lbajardsilogic@19 355 }
lbajardsilogic@19 356
lbajardsilogic@203 357 bool
lbajardsilogic@203 358 ESFileReader::readFilter(const QXmlAttributes &attributes)
lbajardsilogic@203 359 {
lbajardsilogic@203 360 QString name = attributes.value("name");
lbajardsilogic@203 361
lbajardsilogic@203 362 FilterStack *filterStack = m_document->getRealTimeFilterStack();
lbajardsilogic@203 363
lbajardsilogic@203 364 if (!filterStack)
lbajardsilogic@203 365 {
lbajardsilogic@203 366 std::cerr << "WARNING: Easaier session-XML: Failed to get filterStack \""
lbajardsilogic@203 367 << name.toLocal8Bit().data()
lbajardsilogic@203 368 << "\"" << std::endl;
lbajardsilogic@203 369 return false;
lbajardsilogic@203 370 }
lbajardsilogic@203 371
lbajardsilogic@203 372 Filter *curFilter = filterStack->findFilter(name);
lbajardsilogic@203 373
lbajardsilogic@203 374 if (!curFilter)
lbajardsilogic@203 375 {
lbajardsilogic@203 376 std::cerr << "WARNING: Easaier session-XML: Failed to get filter \""
lbajardsilogic@203 377 << name.toLocal8Bit().data()
lbajardsilogic@203 378 << "\"" << std::endl;
lbajardsilogic@203 379 return false;
lbajardsilogic@203 380 }
lbajardsilogic@203 381
lbajardsilogic@203 382 curFilter->setProperties(attributes);
lbajardsilogic@203 383
lbajardsilogic@203 384 return true;
lbajardsilogic@203 385 }