annotate document/Document.cpp @ 25:e74f508db18c

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