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