Mercurial > hg > easaier-soundaccess
comparison sv/document/Document.cpp @ 0:fc9323a41f5a
start base : Sonic Visualiser sv1-1.0rc1
author | lbajardsilogic |
---|---|
date | Fri, 11 May 2007 09:08:14 +0000 |
parents | |
children | 2a6f70f97395 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fc9323a41f5a |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2006 Chris Cannam and QMUL. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #include "Document.h" | |
17 | |
18 #include "data/model/WaveFileModel.h" | |
19 #include "data/model/WritableWaveFileModel.h" | |
20 #include "data/model/DenseThreeDimensionalModel.h" | |
21 #include "data/model/DenseTimeValueModel.h" | |
22 #include "layer/Layer.h" | |
23 #include "base/CommandHistory.h" | |
24 #include "base/Command.h" | |
25 #include "view/View.h" | |
26 #include "base/PlayParameterRepository.h" | |
27 #include "base/PlayParameters.h" | |
28 #include "transform/TransformFactory.h" | |
29 #include <QApplication> | |
30 #include <iostream> | |
31 | |
32 //!!! still need to handle command history, documentRestored/documentModified | |
33 | |
34 Document::Document() : | |
35 m_mainModel(0) | |
36 { | |
37 connect(this, SIGNAL(modelAboutToBeDeleted(Model *)), | |
38 TransformFactory::getInstance(), | |
39 SLOT(modelAboutToBeDeleted(Model *))); | |
40 } | |
41 | |
42 Document::~Document() | |
43 { | |
44 //!!! Document should really own the command history. atm we | |
45 //still refer to it in various places that don't have access to | |
46 //the document, be nice to fix that | |
47 | |
48 // std::cerr << "\n\nDocument::~Document: about to clear command history" << std::endl; | |
49 CommandHistory::getInstance()->clear(); | |
50 | |
51 // std::cerr << "Document::~Document: about to delete layers" << std::endl; | |
52 while (!m_layers.empty()) { | |
53 deleteLayer(*m_layers.begin(), true); | |
54 } | |
55 | |
56 if (!m_models.empty()) { | |
57 std::cerr << "Document::~Document: WARNING: " | |
58 << m_models.size() << " model(s) still remain -- " | |
59 << "should have been garbage collected when deleting layers" | |
60 << std::endl; | |
61 while (!m_models.empty()) { | |
62 if (m_models.begin()->first == m_mainModel) { | |
63 // just in case! | |
64 std::cerr << "Document::~Document: WARNING: Main model is also" | |
65 << " in models list!" << std::endl; | |
66 } else { | |
67 emit modelAboutToBeDeleted(m_models.begin()->first); | |
68 delete m_models.begin()->first; | |
69 } | |
70 m_models.erase(m_models.begin()); | |
71 } | |
72 } | |
73 | |
74 // std::cerr << "Document::~Document: About to get rid of main model" | |
75 // << std::endl; | |
76 emit modelAboutToBeDeleted(m_mainModel); | |
77 emit mainModelChanged(0); | |
78 delete m_mainModel; | |
79 | |
80 } | |
81 | |
82 Layer * | |
83 Document::createLayer(LayerFactory::LayerType type) | |
84 { | |
85 Layer *newLayer = LayerFactory::getInstance()->createLayer(type); | |
86 if (!newLayer) return 0; | |
87 | |
88 newLayer->setObjectName(getUniqueLayerName(newLayer->objectName())); | |
89 | |
90 m_layers.insert(newLayer); | |
91 emit layerAdded(newLayer); | |
92 | |
93 return newLayer; | |
94 } | |
95 | |
96 Layer * | |
97 Document::createMainModelLayer(LayerFactory::LayerType type) | |
98 { | |
99 Layer *newLayer = createLayer(type); | |
100 if (!newLayer) return 0; | |
101 setModel(newLayer, m_mainModel); | |
102 return newLayer; | |
103 } | |
104 | |
105 Layer * | |
106 Document::createImportedLayer(Model *model) | |
107 { | |
108 LayerFactory::LayerTypeSet types = | |
109 LayerFactory::getInstance()->getValidLayerTypes(model); | |
110 | |
111 if (types.empty()) { | |
112 std::cerr << "WARNING: Document::importLayer: no valid display layer for model" << std::endl; | |
113 return 0; | |
114 } | |
115 | |
116 //!!! for now, just use the first suitable layer type | |
117 LayerFactory::LayerType type = *types.begin(); | |
118 | |
119 Layer *newLayer = LayerFactory::getInstance()->createLayer(type); | |
120 if (!newLayer) return 0; | |
121 | |
122 newLayer->setObjectName(getUniqueLayerName(newLayer->objectName())); | |
123 | |
124 addImportedModel(model); | |
125 setModel(newLayer, model); | |
126 | |
127 //!!! and all channels | |
128 setChannel(newLayer, -1); | |
129 | |
130 m_layers.insert(newLayer); | |
131 emit layerAdded(newLayer); | |
132 return newLayer; | |
133 } | |
134 | |
135 Layer * | |
136 Document::createEmptyLayer(LayerFactory::LayerType type) | |
137 { | |
138 Model *newModel = | |
139 LayerFactory::getInstance()->createEmptyModel(type, m_mainModel); | |
140 if (!newModel) return 0; | |
141 | |
142 Layer *newLayer = createLayer(type); | |
143 if (!newLayer) { | |
144 delete newModel; | |
145 return 0; | |
146 } | |
147 | |
148 addImportedModel(newModel); | |
149 setModel(newLayer, newModel); | |
150 | |
151 return newLayer; | |
152 } | |
153 | |
154 Layer * | |
155 Document::createDerivedLayer(LayerFactory::LayerType type, | |
156 TransformId transform) | |
157 { | |
158 Layer *newLayer = createLayer(type); | |
159 if (!newLayer) return 0; | |
160 | |
161 newLayer->setObjectName(getUniqueLayerName | |
162 (TransformFactory::getInstance()-> | |
163 getTransformFriendlyName(transform))); | |
164 | |
165 return newLayer; | |
166 } | |
167 | |
168 Layer * | |
169 Document::createDerivedLayer(TransformId transform, | |
170 Model *inputModel, | |
171 const PluginTransform::ExecutionContext &context, | |
172 QString configurationXml) | |
173 { | |
174 Model *newModel = addDerivedModel(transform, inputModel, | |
175 context, configurationXml); | |
176 if (!newModel) { | |
177 // error already printed to stderr by addDerivedModel | |
178 emit modelGenerationFailed(transform); | |
179 return 0; | |
180 } | |
181 | |
182 LayerFactory::LayerTypeSet types = | |
183 LayerFactory::getInstance()->getValidLayerTypes(newModel); | |
184 | |
185 if (types.empty()) { | |
186 std::cerr << "WARNING: Document::createLayerForTransform: no valid display layer for output of transform " << transform.toStdString() << std::endl; | |
187 delete newModel; | |
188 return 0; | |
189 } | |
190 | |
191 //!!! for now, just use the first suitable layer type | |
192 | |
193 Layer *newLayer = createLayer(*types.begin()); | |
194 setModel(newLayer, newModel); | |
195 | |
196 //!!! We need to clone the model when adding the layer, so that it | |
197 //can be edited without affecting other layers that are based on | |
198 //the same model. Unfortunately we can't just clone it now, | |
199 //because it probably hasn't been completed yet -- the transform | |
200 //runs in the background. Maybe the transform has to handle | |
201 //cloning and cacheing models itself. | |
202 // | |
203 // Once we do clone models here, of course, we'll have to avoid | |
204 // leaking them too. | |
205 // | |
206 // We want the user to be able to add a model to a second layer | |
207 // _while it's still being calculated in the first_ and have it | |
208 // work quickly. That means we need to put the same physical | |
209 // model pointer in both layers, so they can't actually be cloned. | |
210 | |
211 if (newLayer) { | |
212 newLayer->setObjectName(getUniqueLayerName | |
213 (TransformFactory::getInstance()-> | |
214 getTransformFriendlyName(transform))); | |
215 } | |
216 | |
217 emit layerAdded(newLayer); | |
218 return newLayer; | |
219 } | |
220 | |
221 void | |
222 Document::setMainModel(WaveFileModel *model) | |
223 { | |
224 Model *oldMainModel = m_mainModel; | |
225 m_mainModel = model; | |
226 | |
227 emit modelAdded(m_mainModel); | |
228 | |
229 std::vector<Layer *> obsoleteLayers; | |
230 std::set<QString> failedTransforms; | |
231 | |
232 // We need to ensure that no layer is left using oldMainModel or | |
233 // any of the old derived models as its model. Either replace the | |
234 // model, or delete the layer for each layer that is currently | |
235 // using one of these. Carry out this replacement before we | |
236 // delete any of the models. | |
237 | |
238 for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { | |
239 | |
240 Layer *layer = *i; | |
241 Model *model = layer->getModel(); | |
242 | |
243 // std::cerr << "Document::setMainModel: inspecting model " | |
244 // << (model ? model->objectName().toStdString() : "(null)") << " in layer " | |
245 // << layer->objectName().toStdString() << std::endl; | |
246 | |
247 if (model == oldMainModel) { | |
248 // std::cerr << "... it uses the old main model, replacing" << std::endl; | |
249 LayerFactory::getInstance()->setModel(layer, m_mainModel); | |
250 continue; | |
251 } | |
252 | |
253 if (m_models.find(model) == m_models.end()) { | |
254 std::cerr << "WARNING: Document::setMainModel: Unknown model " | |
255 << model << " in layer " << layer << std::endl; | |
256 // get rid of this hideous degenerate | |
257 obsoleteLayers.push_back(layer); | |
258 continue; | |
259 } | |
260 | |
261 if (m_models[model].source == oldMainModel) { | |
262 | |
263 // std::cerr << "... it uses a model derived from the old main model, regenerating" << std::endl; | |
264 | |
265 // This model was derived from the previous main | |
266 // model: regenerate it. | |
267 | |
268 TransformId transform = m_models[model].transform; | |
269 PluginTransform::ExecutionContext context = m_models[model].context; | |
270 | |
271 Model *replacementModel = | |
272 addDerivedModel(transform, | |
273 m_mainModel, | |
274 context, | |
275 m_models[model].configurationXml); | |
276 | |
277 if (!replacementModel) { | |
278 std::cerr << "WARNING: Document::setMainModel: Failed to regenerate model for transform \"" | |
279 << transform.toStdString() << "\"" << " in layer " << layer << std::endl; | |
280 if (failedTransforms.find(transform) == failedTransforms.end()) { | |
281 emit modelRegenerationFailed(layer->objectName(), | |
282 transform); | |
283 failedTransforms.insert(transform); | |
284 } | |
285 obsoleteLayers.push_back(layer); | |
286 } else { | |
287 std::cerr << "Replacing model " << model << " (type " | |
288 << typeid(*model).name() << ") with model " | |
289 << replacementModel << " (type " | |
290 << typeid(*replacementModel).name() << ") in layer " | |
291 << layer << " (name " << layer->objectName().toStdString() << ")" | |
292 << std::endl; | |
293 RangeSummarisableTimeValueModel *rm = | |
294 dynamic_cast<RangeSummarisableTimeValueModel *>(replacementModel); | |
295 if (rm) { | |
296 std::cerr << "new model has " << rm->getChannelCount() << " channels " << std::endl; | |
297 } else { | |
298 std::cerr << "new model is not a RangeSummarisableTimeValueModel!" << std::endl; | |
299 } | |
300 setModel(layer, replacementModel); | |
301 } | |
302 } | |
303 } | |
304 | |
305 for (size_t k = 0; k < obsoleteLayers.size(); ++k) { | |
306 deleteLayer(obsoleteLayers[k], true); | |
307 } | |
308 | |
309 emit mainModelChanged(m_mainModel); | |
310 | |
311 // we already emitted modelAboutToBeDeleted for this | |
312 delete oldMainModel; | |
313 } | |
314 | |
315 void | |
316 Document::addDerivedModel(TransformId transform, | |
317 Model *inputModel, | |
318 const PluginTransform::ExecutionContext &context, | |
319 Model *outputModelToAdd, | |
320 QString configurationXml) | |
321 { | |
322 if (m_models.find(outputModelToAdd) != m_models.end()) { | |
323 std::cerr << "WARNING: Document::addDerivedModel: Model already added" | |
324 << std::endl; | |
325 return; | |
326 } | |
327 | |
328 // std::cerr << "Document::addDerivedModel: source is " << inputModel << " \"" << inputModel->objectName().toStdString() << "\"" << std::endl; | |
329 | |
330 ModelRecord rec; | |
331 rec.source = inputModel; | |
332 rec.transform = transform; | |
333 rec.context = context; | |
334 rec.configurationXml = configurationXml; | |
335 rec.refcount = 0; | |
336 | |
337 m_models[outputModelToAdd] = rec; | |
338 | |
339 emit modelAdded(outputModelToAdd); | |
340 } | |
341 | |
342 | |
343 void | |
344 Document::addImportedModel(Model *model) | |
345 { | |
346 if (m_models.find(model) != m_models.end()) { | |
347 std::cerr << "WARNING: Document::addImportedModel: Model already added" | |
348 << std::endl; | |
349 return; | |
350 } | |
351 | |
352 ModelRecord rec; | |
353 rec.source = 0; | |
354 rec.transform = ""; | |
355 rec.refcount = 0; | |
356 | |
357 m_models[model] = rec; | |
358 | |
359 emit modelAdded(model); | |
360 } | |
361 | |
362 Model * | |
363 Document::addDerivedModel(TransformId transform, | |
364 Model *inputModel, | |
365 const PluginTransform::ExecutionContext &context, | |
366 QString configurationXml) | |
367 { | |
368 Model *model = 0; | |
369 | |
370 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | |
371 if (i->second.transform == transform && | |
372 i->second.source == inputModel && | |
373 i->second.context == context && | |
374 i->second.configurationXml == configurationXml) { | |
375 return i->first; | |
376 } | |
377 } | |
378 | |
379 model = TransformFactory::getInstance()->transform | |
380 (transform, inputModel, context, configurationXml); | |
381 | |
382 if (!model) { | |
383 std::cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.toStdString() << std::endl; | |
384 } else { | |
385 addDerivedModel(transform, inputModel, context, model, configurationXml); | |
386 } | |
387 | |
388 return model; | |
389 } | |
390 | |
391 void | |
392 Document::releaseModel(Model *model) // Will _not_ release main model! | |
393 { | |
394 if (model == 0) { | |
395 return; | |
396 } | |
397 | |
398 if (model == m_mainModel) { | |
399 return; | |
400 } | |
401 | |
402 bool toDelete = false; | |
403 | |
404 if (m_models.find(model) != m_models.end()) { | |
405 | |
406 if (m_models[model].refcount == 0) { | |
407 std::cerr << "WARNING: Document::releaseModel: model " << model | |
408 << " reference count is zero already!" << std::endl; | |
409 } else { | |
410 if (--m_models[model].refcount == 0) { | |
411 toDelete = true; | |
412 } | |
413 } | |
414 } else { | |
415 std::cerr << "WARNING: Document::releaseModel: Unfound model " | |
416 << model << std::endl; | |
417 toDelete = true; | |
418 } | |
419 | |
420 if (toDelete) { | |
421 | |
422 int sourceCount = 0; | |
423 | |
424 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | |
425 if (i->second.source == model) { | |
426 ++sourceCount; | |
427 i->second.source = 0; | |
428 } | |
429 } | |
430 | |
431 if (sourceCount > 0) { | |
432 std::cerr << "Document::releaseModel: Deleting model " | |
433 << model << " even though it is source for " | |
434 << sourceCount << " other derived model(s) -- resetting " | |
435 << "their source fields appropriately" << std::endl; | |
436 } | |
437 | |
438 emit modelAboutToBeDeleted(model); | |
439 m_models.erase(model); | |
440 delete model; | |
441 } | |
442 } | |
443 | |
444 void | |
445 Document::deleteLayer(Layer *layer, bool force) | |
446 { | |
447 if (m_layerViewMap.find(layer) != m_layerViewMap.end() && | |
448 m_layerViewMap[layer].size() > 0) { | |
449 | |
450 std::cerr << "WARNING: Document::deleteLayer: Layer " | |
451 << layer << " [" << layer->objectName().toStdString() << "]" | |
452 << " is still used in " << m_layerViewMap[layer].size() | |
453 << " views!" << std::endl; | |
454 | |
455 if (force) { | |
456 | |
457 std::cerr << "(force flag set -- deleting from all views)" << std::endl; | |
458 | |
459 for (std::set<View *>::iterator j = m_layerViewMap[layer].begin(); | |
460 j != m_layerViewMap[layer].end(); ++j) { | |
461 // don't use removeLayerFromView, as it issues a command | |
462 layer->setLayerDormant(*j, true); | |
463 (*j)->removeLayer(layer); | |
464 } | |
465 | |
466 m_layerViewMap.erase(layer); | |
467 | |
468 } else { | |
469 return; | |
470 } | |
471 } | |
472 | |
473 if (m_layers.find(layer) == m_layers.end()) { | |
474 std::cerr << "Document::deleteLayer: Layer " | |
475 << layer << " does not exist, or has already been deleted " | |
476 << "(this may not be as serious as it sounds)" << std::endl; | |
477 return; | |
478 } | |
479 | |
480 m_layers.erase(layer); | |
481 | |
482 releaseModel(layer->getModel()); | |
483 emit layerRemoved(layer); | |
484 emit layerAboutToBeDeleted(layer); | |
485 delete layer; | |
486 } | |
487 | |
488 void | |
489 Document::setModel(Layer *layer, Model *model) | |
490 { | |
491 if (model && | |
492 model != m_mainModel && | |
493 m_models.find(model) == m_models.end()) { | |
494 std::cerr << "ERROR: Document::setModel: Layer " << layer | |
495 << " (\"" << layer->objectName().toStdString() | |
496 << "\") wants to use unregistered model " << model | |
497 << ": register the layer's model before setting it!" | |
498 << std::endl; | |
499 return; | |
500 } | |
501 | |
502 Model *previousModel = layer->getModel(); | |
503 | |
504 if (previousModel == model) { | |
505 std::cerr << "WARNING: Document::setModel: Layer " << layer << " (\"" | |
506 << layer->objectName().toStdString() | |
507 << "\") is already set to model " | |
508 << model << " (\"" | |
509 << (model ? model->objectName().toStdString() : "(null)") | |
510 << "\")" << std::endl; | |
511 return; | |
512 } | |
513 | |
514 if (model && model != m_mainModel) { | |
515 m_models[model].refcount ++; | |
516 } | |
517 | |
518 LayerFactory::getInstance()->setModel(layer, model); | |
519 | |
520 if (previousModel) { | |
521 releaseModel(previousModel); | |
522 } | |
523 } | |
524 | |
525 void | |
526 Document::setChannel(Layer *layer, int channel) | |
527 { | |
528 LayerFactory::getInstance()->setChannel(layer, channel); | |
529 } | |
530 | |
531 void | |
532 Document::addLayerToView(View *view, Layer *layer) | |
533 { | |
534 Model *model = layer->getModel(); | |
535 if (!model) { | |
536 // std::cerr << "Document::addLayerToView: Layer (\"" | |
537 // << layer->objectName().toStdString() | |
538 // << "\") with no model being added to view: " | |
539 // << "normally you want to set the model first" << std::endl; | |
540 } else { | |
541 if (model != m_mainModel && | |
542 m_models.find(model) == m_models.end()) { | |
543 std::cerr << "ERROR: Document::addLayerToView: Layer " << layer | |
544 << " has unregistered model " << model | |
545 << " -- register the layer's model before adding the layer!" << std::endl; | |
546 return; | |
547 } | |
548 } | |
549 | |
550 CommandHistory::getInstance()->addCommand | |
551 (new Document::AddLayerCommand(this, view, layer)); | |
552 } | |
553 | |
554 void | |
555 Document::removeLayerFromView(View *view, Layer *layer) | |
556 { | |
557 CommandHistory::getInstance()->addCommand | |
558 (new Document::RemoveLayerCommand(this, view, layer)); | |
559 } | |
560 | |
561 void | |
562 Document::addToLayerViewMap(Layer *layer, View *view) | |
563 { | |
564 bool firstView = (m_layerViewMap.find(layer) == m_layerViewMap.end() || | |
565 m_layerViewMap[layer].empty()); | |
566 | |
567 if (m_layerViewMap[layer].find(view) != | |
568 m_layerViewMap[layer].end()) { | |
569 std::cerr << "WARNING: Document::addToLayerViewMap:" | |
570 << " Layer " << layer << " -> view " << view << " already in" | |
571 << " layer view map -- internal inconsistency" << std::endl; | |
572 } | |
573 | |
574 m_layerViewMap[layer].insert(view); | |
575 | |
576 if (firstView) emit layerInAView(layer, true); | |
577 } | |
578 | |
579 void | |
580 Document::removeFromLayerViewMap(Layer *layer, View *view) | |
581 { | |
582 if (m_layerViewMap[layer].find(view) == | |
583 m_layerViewMap[layer].end()) { | |
584 std::cerr << "WARNING: Document::removeFromLayerViewMap:" | |
585 << " Layer " << layer << " -> view " << view << " not in" | |
586 << " layer view map -- internal inconsistency" << std::endl; | |
587 } | |
588 | |
589 m_layerViewMap[layer].erase(view); | |
590 | |
591 if (m_layerViewMap[layer].empty()) { | |
592 m_layerViewMap.erase(layer); | |
593 emit layerInAView(layer, false); | |
594 } | |
595 } | |
596 | |
597 QString | |
598 Document::getUniqueLayerName(QString candidate) | |
599 { | |
600 for (int count = 1; ; ++count) { | |
601 | |
602 QString adjusted = | |
603 (count > 1 ? QString("%1 <%2>").arg(candidate).arg(count) : | |
604 candidate); | |
605 | |
606 bool duplicate = false; | |
607 | |
608 for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { | |
609 if ((*i)->objectName() == adjusted) { | |
610 duplicate = true; | |
611 break; | |
612 } | |
613 } | |
614 | |
615 if (!duplicate) return adjusted; | |
616 } | |
617 } | |
618 | |
619 std::vector<Model *> | |
620 Document::getTransformInputModels() | |
621 { | |
622 std::vector<Model *> models; | |
623 | |
624 if (!m_mainModel) return models; | |
625 | |
626 models.push_back(m_mainModel); | |
627 | |
628 //!!! This will pick up all models, including those that aren't visible... | |
629 | |
630 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | |
631 | |
632 Model *model = i->first; | |
633 if (!model || model == m_mainModel) continue; | |
634 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); | |
635 | |
636 if (dtvm) { | |
637 models.push_back(dtvm); | |
638 } | |
639 } | |
640 | |
641 return models; | |
642 } | |
643 | |
644 Document::AddLayerCommand::AddLayerCommand(Document *d, | |
645 View *view, | |
646 Layer *layer) : | |
647 m_d(d), | |
648 m_view(view), | |
649 m_layer(layer), | |
650 m_name(qApp->translate("AddLayerCommand", "Add %1 Layer").arg(layer->objectName())), | |
651 m_added(false) | |
652 { | |
653 } | |
654 | |
655 Document::AddLayerCommand::~AddLayerCommand() | |
656 { | |
657 // std::cerr << "Document::AddLayerCommand::~AddLayerCommand" << std::endl; | |
658 if (!m_added) { | |
659 m_d->deleteLayer(m_layer); | |
660 } | |
661 } | |
662 | |
663 void | |
664 Document::AddLayerCommand::execute() | |
665 { | |
666 for (int i = 0; i < m_view->getLayerCount(); ++i) { | |
667 if (m_view->getLayer(i) == m_layer) { | |
668 // already there | |
669 m_layer->setLayerDormant(m_view, false); | |
670 m_added = true; | |
671 return; | |
672 } | |
673 } | |
674 | |
675 m_view->addLayer(m_layer); | |
676 m_layer->setLayerDormant(m_view, false); | |
677 | |
678 m_d->addToLayerViewMap(m_layer, m_view); | |
679 m_added = true; | |
680 } | |
681 | |
682 void | |
683 Document::AddLayerCommand::unexecute() | |
684 { | |
685 m_view->removeLayer(m_layer); | |
686 m_layer->setLayerDormant(m_view, true); | |
687 | |
688 m_d->removeFromLayerViewMap(m_layer, m_view); | |
689 m_added = false; | |
690 } | |
691 | |
692 Document::RemoveLayerCommand::RemoveLayerCommand(Document *d, | |
693 View *view, | |
694 Layer *layer) : | |
695 m_d(d), | |
696 m_view(view), | |
697 m_layer(layer), | |
698 m_name(qApp->translate("RemoveLayerCommand", "Delete %1 Layer").arg(layer->objectName())), | |
699 m_added(true) | |
700 { | |
701 } | |
702 | |
703 Document::RemoveLayerCommand::~RemoveLayerCommand() | |
704 { | |
705 // std::cerr << "Document::RemoveLayerCommand::~RemoveLayerCommand" << std::endl; | |
706 if (!m_added) { | |
707 m_d->deleteLayer(m_layer); | |
708 } | |
709 } | |
710 | |
711 void | |
712 Document::RemoveLayerCommand::execute() | |
713 { | |
714 bool have = false; | |
715 for (int i = 0; i < m_view->getLayerCount(); ++i) { | |
716 if (m_view->getLayer(i) == m_layer) { | |
717 have = true; | |
718 break; | |
719 } | |
720 } | |
721 | |
722 if (!have) { // not there! | |
723 m_layer->setLayerDormant(m_view, true); | |
724 m_added = false; | |
725 return; | |
726 } | |
727 | |
728 m_view->removeLayer(m_layer); | |
729 m_layer->setLayerDormant(m_view, true); | |
730 | |
731 m_d->removeFromLayerViewMap(m_layer, m_view); | |
732 m_added = false; | |
733 } | |
734 | |
735 void | |
736 Document::RemoveLayerCommand::unexecute() | |
737 { | |
738 m_view->addLayer(m_layer); | |
739 m_layer->setLayerDormant(m_view, false); | |
740 | |
741 m_d->addToLayerViewMap(m_layer, m_view); | |
742 m_added = true; | |
743 } | |
744 | |
745 void | |
746 Document::toXml(QTextStream &out, QString indent, QString extraAttributes) const | |
747 { | |
748 out << indent + QString("<data%1%2>\n") | |
749 .arg(extraAttributes == "" ? "" : " ").arg(extraAttributes); | |
750 | |
751 if (m_mainModel) { | |
752 m_mainModel->toXml(out, indent + " ", "mainModel=\"true\""); | |
753 } | |
754 | |
755 // Models that are not used in a layer that is in a view should | |
756 // not be written. Get our list of required models first. | |
757 | |
758 std::set<const Model *> used; | |
759 | |
760 for (LayerViewMap::const_iterator i = m_layerViewMap.begin(); | |
761 i != m_layerViewMap.end(); ++i) { | |
762 | |
763 if (i->first && !i->second.empty() && i->first->getModel()) { | |
764 used.insert(i->first->getModel()); | |
765 } | |
766 } | |
767 | |
768 for (ModelMap::const_iterator i = m_models.begin(); | |
769 i != m_models.end(); ++i) { | |
770 | |
771 const Model *model = i->first; | |
772 const ModelRecord &rec = i->second; | |
773 | |
774 if (used.find(model) == used.end()) continue; | |
775 | |
776 // We need an intelligent way to determine which models need | |
777 // to be streamed (i.e. have been edited, or are small) and | |
778 // which should not be (i.e. remain as generated by a | |
779 // transform, and are large). | |
780 // | |
781 // At the moment we can get away with deciding not to stream | |
782 // dense 3d models or writable wave file models, provided they | |
783 // were generated from a transform, because at the moment there | |
784 // is no way to edit those model types so it should be safe to | |
785 // regenerate them. That won't always work in future though. | |
786 // It would be particularly nice to be able to ask the user, | |
787 // as well as making an intelligent guess. | |
788 | |
789 bool writeModel = true; | |
790 bool haveDerivation = false; | |
791 | |
792 if (rec.source && rec.transform != "") { | |
793 haveDerivation = true; | |
794 } | |
795 | |
796 if (haveDerivation) { | |
797 if (dynamic_cast<const WritableWaveFileModel *>(model)) { | |
798 writeModel = false; | |
799 } else if (dynamic_cast<const DenseThreeDimensionalModel *>(model)) { | |
800 writeModel = false; | |
801 } | |
802 } | |
803 | |
804 if (writeModel) { | |
805 i->first->toXml(out, indent + " "); | |
806 } | |
807 | |
808 if (haveDerivation) { | |
809 | |
810 //!!! stream the rest of the execution context in both directions (i.e. not just channel) | |
811 | |
812 out << indent; | |
813 out << QString(" <derivation source=\"%1\" model=\"%2\" channel=\"%3\" domain=\"%4\" stepSize=\"%5\" blockSize=\"%6\" windowType=\"%7\" transform=\"%8\"") | |
814 .arg(XmlExportable::getObjectExportId(rec.source)) | |
815 .arg(XmlExportable::getObjectExportId(i->first)) | |
816 .arg(rec.context.channel) | |
817 .arg(rec.context.domain) | |
818 .arg(rec.context.stepSize) | |
819 .arg(rec.context.blockSize) | |
820 .arg(int(rec.context.windowType)) | |
821 .arg(XmlExportable::encodeEntities(rec.transform)); | |
822 | |
823 if (rec.configurationXml != "") { | |
824 out << ">\n " + indent + rec.configurationXml | |
825 + "\n" + indent + " </derivation>\n"; | |
826 } else { | |
827 out << "/>\n"; | |
828 } | |
829 } | |
830 | |
831 //!!! We should probably own the PlayParameterRepository | |
832 PlayParameters *playParameters = | |
833 PlayParameterRepository::getInstance()->getPlayParameters(i->first); | |
834 if (playParameters) { | |
835 playParameters->toXml | |
836 (out, indent + " ", | |
837 QString("model=\"%1\"") | |
838 .arg(XmlExportable::getObjectExportId(i->first))); | |
839 } | |
840 } | |
841 | |
842 for (LayerSet::const_iterator i = m_layers.begin(); | |
843 i != m_layers.end(); ++i) { | |
844 | |
845 (*i)->toXml(out, indent + " "); | |
846 } | |
847 | |
848 out << indent + "</data>\n"; | |
849 } | |
850 | |
851 QString | |
852 Document::toXmlString(QString indent, QString extraAttributes) const | |
853 { | |
854 QString s; | |
855 | |
856 { | |
857 QTextStream out(&s); | |
858 toXml(out, indent, extraAttributes); | |
859 } | |
860 | |
861 return s; | |
862 } | |
863 |