annotate framework/Document.cpp @ 626:51ecc3e2d71c

Don't resample an incoming audio file to match the main model's rate, if the aim of importing is to replace the main model anyway
author Chris Cannam
date Tue, 09 Oct 2018 15:55:16 +0100
parents 021d42e6c8cb
children 10046d544e76
rev   line source
Chris@45 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@45 2
Chris@45 3 /*
Chris@45 4 Sonic Visualiser
Chris@45 5 An audio file viewer and annotation editor.
Chris@45 6 Centre for Digital Music, Queen Mary, University of London.
Chris@45 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@45 8
Chris@45 9 This program is free software; you can redistribute it and/or
Chris@45 10 modify it under the terms of the GNU General Public License as
Chris@45 11 published by the Free Software Foundation; either version 2 of the
Chris@45 12 License, or (at your option) any later version. See the file
Chris@45 13 COPYING included with this distribution for more information.
Chris@45 14 */
Chris@45 15
Chris@45 16 #include "Document.h"
Chris@45 17
Chris@420 18 #include "Align.h"
Chris@420 19
Chris@45 20 #include "data/model/WaveFileModel.h"
Chris@45 21 #include "data/model/WritableWaveFileModel.h"
Chris@45 22 #include "data/model/DenseThreeDimensionalModel.h"
Chris@45 23 #include "data/model/DenseTimeValueModel.h"
gyorgyf@270 24 #include "data/model/FlexiNoteModel.h"
Chris@588 25 #include "data/model/AggregateWaveModel.h"
gyorgyf@270 26
Chris@45 27 #include "layer/Layer.h"
Chris@105 28 #include "widgets/CommandHistory.h"
Chris@45 29 #include "base/Command.h"
Chris@45 30 #include "view/View.h"
Chris@45 31 #include "base/PlayParameterRepository.h"
Chris@45 32 #include "base/PlayParameters.h"
Chris@106 33 #include "transform/TransformFactory.h"
Chris@106 34 #include "transform/ModelTransformerFactory.h"
gyorgyf@270 35 #include "transform/FeatureExtractionModelTransformer.h"
Chris@45 36 #include <QApplication>
Chris@45 37 #include <QTextStream>
Chris@90 38 #include <QSettings>
Chris@45 39 #include <iostream>
Chris@212 40 #include <typeinfo>
Chris@45 41
Chris@45 42 #include "data/model/AlignmentModel.h"
Chris@423 43 #include "Align.h"
Chris@45 44
Chris@297 45 using std::vector;
Chris@297 46
Chris@138 47 //#define DEBUG_DOCUMENT 1
Chris@77 48
Chris@45 49 //!!! still need to handle command history, documentRestored/documentModified
Chris@45 50
Chris@45 51 Document::Document() :
Chris@47 52 m_mainModel(0),
Chris@423 53 m_autoAlignment(false),
Chris@601 54 m_align(new Align()),
Chris@601 55 m_isIncomplete(false)
Chris@45 56 {
Chris@456 57 connect(this,
Chris@456 58 SIGNAL(modelAboutToBeDeleted(Model *)),
Chris@54 59 ModelTransformerFactory::getInstance(),
Chris@45 60 SLOT(modelAboutToBeDeleted(Model *)));
Chris@456 61
Chris@456 62 connect(ModelTransformerFactory::getInstance(),
Chris@456 63 SIGNAL(transformFailed(QString, QString)),
Chris@456 64 this,
Chris@456 65 SIGNAL(modelGenerationFailed(QString, QString)));
Chris@459 66
Chris@428 67 connect(m_align, SIGNAL(alignmentComplete(AlignmentModel *)),
Chris@428 68 this, SIGNAL(alignmentComplete(AlignmentModel *)));
Chris@45 69 }
Chris@45 70
Chris@45 71 Document::~Document()
Chris@45 72 {
Chris@45 73 //!!! Document should really own the command history. atm we
Chris@45 74 //still refer to it in various places that don't have access to
Chris@45 75 //the document, be nice to fix that
Chris@45 76
Chris@77 77 #ifdef DEBUG_DOCUMENT
Chris@293 78 cerr << "\n\nDocument::~Document: about to clear command history" << endl;
Chris@77 79 #endif
Chris@45 80 CommandHistory::getInstance()->clear();
Chris@45 81
Chris@77 82 #ifdef DEBUG_DOCUMENT
Chris@233 83 SVDEBUG << "Document::~Document: about to delete layers" << endl;
Chris@77 84 #endif
Chris@45 85 while (!m_layers.empty()) {
Chris@595 86 deleteLayer(*m_layers.begin(), true);
Chris@45 87 }
Chris@45 88
Chris@45 89 if (!m_models.empty()) {
Chris@595 90 SVDEBUG << "Document::~Document: WARNING: "
Chris@595 91 << m_models.size() << " model(s) still remain -- "
Chris@595 92 << "should have been garbage collected when deleting layers"
Chris@595 93 << endl;
Chris@595 94 while (!m_models.empty()) {
Chris@45 95 Model *model = m_models.begin()->first;
Chris@595 96 if (model == m_mainModel) {
Chris@595 97 // just in case!
Chris@595 98 SVDEBUG << "Document::~Document: WARNING: Main model is also"
Chris@595 99 << " in models list!" << endl;
Chris@595 100 } else if (model) {
Chris@79 101 model->aboutToDelete();
Chris@595 102 emit modelAboutToBeDeleted(model);
Chris@595 103 delete model;
Chris@595 104 }
Chris@595 105 m_models.erase(m_models.begin());
Chris@595 106 }
Chris@45 107 }
Chris@45 108
Chris@77 109 #ifdef DEBUG_DOCUMENT
Chris@233 110 SVDEBUG << "Document::~Document: About to get rid of main model"
Chris@595 111 << endl;
Chris@77 112 #endif
Chris@45 113 if (m_mainModel) {
Chris@79 114 m_mainModel->aboutToDelete();
Chris@45 115 emit modelAboutToBeDeleted(m_mainModel);
Chris@45 116 }
Chris@45 117
Chris@45 118 emit mainModelChanged(0);
Chris@45 119 delete m_mainModel;
Chris@45 120 }
Chris@45 121
Chris@45 122 Layer *
Chris@45 123 Document::createLayer(LayerFactory::LayerType type)
Chris@45 124 {
Chris@45 125 Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
Chris@45 126 if (!newLayer) return 0;
Chris@45 127
Chris@45 128 newLayer->setObjectName(getUniqueLayerName(newLayer->objectName()));
Chris@45 129
Chris@45 130 m_layers.insert(newLayer);
Chris@52 131
Chris@77 132 #ifdef DEBUG_DOCUMENT
Chris@233 133 SVDEBUG << "Document::createLayer: Added layer of type " << type
Chris@229 134 << ", now have " << m_layers.size() << " layers" << endl;
Chris@77 135 #endif
Chris@52 136
Chris@45 137 emit layerAdded(newLayer);
Chris@45 138
Chris@45 139 return newLayer;
Chris@45 140 }
Chris@45 141
Chris@45 142 Layer *
Chris@45 143 Document::createMainModelLayer(LayerFactory::LayerType type)
Chris@45 144 {
Chris@45 145 Layer *newLayer = createLayer(type);
Chris@45 146 if (!newLayer) return 0;
Chris@45 147 setModel(newLayer, m_mainModel);
Chris@45 148 return newLayer;
Chris@45 149 }
Chris@45 150
Chris@45 151 Layer *
Chris@45 152 Document::createImportedLayer(Model *model)
Chris@45 153 {
Chris@45 154 LayerFactory::LayerTypeSet types =
Chris@595 155 LayerFactory::getInstance()->getValidLayerTypes(model);
Chris@45 156
Chris@45 157 if (types.empty()) {
Chris@595 158 cerr << "WARNING: Document::importLayer: no valid display layer for model" << endl;
Chris@595 159 return 0;
Chris@45 160 }
Chris@45 161
Chris@45 162 //!!! for now, just use the first suitable layer type
Chris@45 163 LayerFactory::LayerType type = *types.begin();
Chris@45 164
Chris@45 165 Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
Chris@45 166 if (!newLayer) return 0;
Chris@45 167
Chris@45 168 newLayer->setObjectName(getUniqueLayerName(newLayer->objectName()));
Chris@45 169
Chris@45 170 addImportedModel(model);
Chris@45 171 setModel(newLayer, model);
Chris@45 172
Chris@45 173 //!!! and all channels
Chris@45 174 setChannel(newLayer, -1);
Chris@45 175
Chris@45 176 m_layers.insert(newLayer);
Chris@52 177
Chris@77 178 #ifdef DEBUG_DOCUMENT
Chris@233 179 SVDEBUG << "Document::createImportedLayer: Added layer of type " << type
Chris@229 180 << ", now have " << m_layers.size() << " layers" << endl;
Chris@77 181 #endif
Chris@52 182
Chris@45 183 emit layerAdded(newLayer);
Chris@45 184 return newLayer;
Chris@45 185 }
Chris@45 186
Chris@45 187 Layer *
Chris@45 188 Document::createEmptyLayer(LayerFactory::LayerType type)
Chris@45 189 {
Chris@61 190 if (!m_mainModel) return 0;
Chris@61 191
Chris@45 192 Model *newModel =
Chris@595 193 LayerFactory::getInstance()->createEmptyModel(type, m_mainModel);
Chris@45 194 if (!newModel) return 0;
Chris@45 195
Chris@45 196 Layer *newLayer = createLayer(type);
Chris@45 197 if (!newLayer) {
Chris@595 198 delete newModel;
Chris@595 199 return 0;
Chris@45 200 }
Chris@45 201
Chris@45 202 addImportedModel(newModel);
Chris@45 203 setModel(newLayer, newModel);
Chris@45 204
Chris@45 205 return newLayer;
Chris@45 206 }
Chris@45 207
Chris@45 208 Layer *
Chris@45 209 Document::createDerivedLayer(LayerFactory::LayerType type,
Chris@595 210 TransformId transform)
Chris@45 211 {
Chris@45 212 Layer *newLayer = createLayer(type);
Chris@45 213 if (!newLayer) return 0;
Chris@45 214
Chris@45 215 newLayer->setObjectName(getUniqueLayerName
Chris@54 216 (TransformFactory::getInstance()->
Chris@54 217 getTransformFriendlyName(transform)));
Chris@45 218
Chris@45 219 return newLayer;
Chris@45 220 }
Chris@297 221
Chris@45 222 Layer *
Chris@72 223 Document::createDerivedLayer(const Transform &transform,
Chris@72 224 const ModelTransformer::Input &input)
Chris@45 225 {
Chris@297 226 Transforms transforms;
Chris@297 227 transforms.push_back(transform);
Chris@297 228 vector<Layer *> layers = createDerivedLayers(transforms, input);
Chris@297 229 if (layers.empty()) return 0;
Chris@297 230 else return layers[0];
Chris@297 231 }
Chris@297 232
Chris@297 233 vector<Layer *>
Chris@297 234 Document::createDerivedLayers(const Transforms &transforms,
Chris@297 235 const ModelTransformer::Input &input)
Chris@297 236 {
Chris@78 237 QString message;
Chris@329 238 vector<Model *> newModels = addDerivedModels(transforms, input, message, 0);
Chris@297 239
Chris@297 240 if (newModels.empty()) {
Chris@297 241 //!!! This identifier may be wrong!
Chris@297 242 emit modelGenerationFailed(transforms[0].getIdentifier(), message);
Chris@297 243 return vector<Layer *>();
Chris@78 244 } else if (message != "") {
Chris@297 245 //!!! This identifier may be wrong!
Chris@297 246 emit modelGenerationWarning(transforms[0].getIdentifier(), message);
Chris@45 247 }
Chris@45 248
Chris@329 249 QStringList names;
Chris@366 250 for (int i = 0; i < (int)newModels.size(); ++i) {
Chris@329 251 names.push_back(getUniqueLayerName
Chris@329 252 (TransformFactory::getInstance()->
Chris@329 253 getTransformFriendlyName
Chris@329 254 (transforms[i].getIdentifier())));
Chris@329 255 }
Chris@329 256
Chris@329 257 vector<Layer *> layers = createLayersForDerivedModels(newModels, names);
Chris@329 258 return layers;
Chris@329 259 }
Chris@329 260
Chris@329 261 class AdditionalModelConverter :
Chris@329 262 public ModelTransformerFactory::AdditionalModelHandler
Chris@329 263 {
Chris@329 264 public:
Chris@329 265 AdditionalModelConverter(Document *doc,
Chris@329 266 Document::LayerCreationHandler *handler) :
Chris@329 267 m_doc(doc),
Chris@329 268 m_handler(handler) {
Chris@329 269 }
Chris@329 270
Chris@329 271 virtual ~AdditionalModelConverter() { }
Chris@329 272
Chris@329 273 void
Chris@329 274 setPrimaryLayers(vector<Layer *> layers) {
Chris@329 275 m_primary = layers;
Chris@329 276 }
Chris@329 277
Chris@329 278 void
Chris@329 279 moreModelsAvailable(vector<Model *> models) {
Chris@329 280 std::cerr << "AdditionalModelConverter::moreModelsAvailable: " << models.size() << " model(s)" << std::endl;
Chris@329 281 // We can't automatically regenerate the additional models on
Chris@329 282 // reload -- we should delete them instead
Chris@329 283 QStringList names;
Chris@329 284 foreach (Model *model, models) {
Chris@329 285 m_doc->addAdditionalModel(model);
Chris@329 286 names.push_back(QString());
Chris@329 287 }
Chris@329 288 vector<Layer *> layers = m_doc->createLayersForDerivedModels
Chris@329 289 (models, names);
Chris@363 290 m_handler->layersCreated(this, m_primary, layers);
Chris@329 291 delete this;
Chris@329 292 }
Chris@329 293
Chris@329 294 void
Chris@329 295 noMoreModelsAvailable() {
Chris@329 296 std::cerr << "AdditionalModelConverter::noMoreModelsAvailable" << std::endl;
Chris@363 297 m_handler->layersCreated(this, m_primary, vector<Layer *>());
Chris@329 298 delete this;
Chris@329 299 }
Chris@329 300
Chris@363 301 void cancel() {
Chris@363 302 foreach (Layer *layer, m_primary) {
Chris@363 303 Model *model = layer->getModel();
Chris@363 304 if (model) {
Chris@363 305 model->abandon();
Chris@363 306 }
Chris@363 307 }
Chris@363 308 }
Chris@363 309
Chris@329 310 private:
Chris@329 311 Document *m_doc;
Chris@329 312 vector<Layer *> m_primary;
Chris@329 313 Document::LayerCreationHandler *m_handler; //!!! how to handle destruction of this?
Chris@329 314 };
Chris@329 315
Chris@363 316 Document::LayerCreationAsyncHandle
Chris@329 317 Document::createDerivedLayersAsync(const Transforms &transforms,
Chris@329 318 const ModelTransformer::Input &input,
Chris@329 319 LayerCreationHandler *handler)
Chris@329 320 {
Chris@329 321 QString message;
Chris@329 322
Chris@329 323 AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler);
Chris@329 324
Chris@329 325 vector<Model *> newModels = addDerivedModels
Chris@329 326 (transforms, input, message, amc);
Chris@329 327
Chris@329 328 QStringList names;
Chris@366 329 for (int i = 0; i < (int)newModels.size(); ++i) {
Chris@329 330 names.push_back(getUniqueLayerName
Chris@329 331 (TransformFactory::getInstance()->
Chris@329 332 getTransformFriendlyName
Chris@329 333 (transforms[i].getIdentifier())));
Chris@329 334 }
Chris@329 335
Chris@329 336 vector<Layer *> layers = createLayersForDerivedModels(newModels, names);
Chris@329 337 amc->setPrimaryLayers(layers);
Chris@329 338
Chris@329 339 if (newModels.empty()) {
Chris@329 340 //!!! This identifier may be wrong!
Chris@329 341 emit modelGenerationFailed(transforms[0].getIdentifier(), message);
Chris@363 342 //!!! what to do with amc?
Chris@329 343 } else if (message != "") {
Chris@329 344 //!!! This identifier may be wrong!
Chris@329 345 emit modelGenerationWarning(transforms[0].getIdentifier(), message);
Chris@363 346 //!!! what to do with amc?
Chris@329 347 }
Chris@363 348
Chris@363 349 return amc;
Chris@363 350 }
Chris@363 351
Chris@363 352 void
Chris@363 353 Document::cancelAsyncLayerCreation(Document::LayerCreationAsyncHandle h)
Chris@363 354 {
Chris@363 355 AdditionalModelConverter *conv = static_cast<AdditionalModelConverter *>(h);
Chris@363 356 conv->cancel();
Chris@329 357 }
Chris@329 358
Chris@329 359 vector<Layer *>
Chris@329 360 Document::createLayersForDerivedModels(vector<Model *> newModels,
Chris@329 361 QStringList names)
Chris@329 362 {
Chris@297 363 vector<Layer *> layers;
Chris@329 364
Chris@297 365 for (int i = 0; i < (int)newModels.size(); ++i) {
Chris@297 366
Chris@297 367 Model *newModel = newModels[i];
Chris@297 368
Chris@297 369 LayerFactory::LayerTypeSet types =
Chris@297 370 LayerFactory::getInstance()->getValidLayerTypes(newModel);
Chris@297 371
Chris@297 372 if (types.empty()) {
Chris@329 373 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl;
Chris@297 374 //!!! inadequate cleanup:
Chris@297 375 newModel->aboutToDelete();
Chris@297 376 emit modelAboutToBeDeleted(newModel);
Chris@297 377 m_models.erase(newModel);
Chris@297 378 delete newModel;
Chris@297 379 return vector<Layer *>();
Chris@297 380 }
Chris@297 381
Chris@297 382 //!!! for now, just use the first suitable layer type
Chris@297 383
Chris@297 384 Layer *newLayer = createLayer(*types.begin());
Chris@297 385 setModel(newLayer, newModel);
Chris@297 386
Chris@297 387 //!!! We need to clone the model when adding the layer, so that it
Chris@297 388 //can be edited without affecting other layers that are based on
Chris@297 389 //the same model. Unfortunately we can't just clone it now,
Chris@297 390 //because it probably hasn't been completed yet -- the transform
Chris@297 391 //runs in the background. Maybe the transform has to handle
Chris@297 392 //cloning and cacheing models itself.
Chris@297 393 //
Chris@297 394 // Once we do clone models here, of course, we'll have to avoid
Chris@297 395 // leaking them too.
Chris@297 396 //
Chris@297 397 // We want the user to be able to add a model to a second layer
Chris@297 398 // _while it's still being calculated in the first_ and have it
Chris@297 399 // work quickly. That means we need to put the same physical
Chris@297 400 // model pointer in both layers, so they can't actually be cloned.
Chris@297 401
Chris@297 402 if (newLayer) {
Chris@329 403 newLayer->setObjectName(names[i]);
Chris@297 404 }
Chris@297 405
Chris@297 406 emit layerAdded(newLayer);
Chris@297 407 layers.push_back(newLayer);
Chris@45 408 }
Chris@45 409
Chris@297 410 return layers;
Chris@45 411 }
Chris@45 412
Chris@45 413 void
Chris@45 414 Document::setMainModel(WaveFileModel *model)
Chris@45 415 {
Chris@45 416 Model *oldMainModel = m_mainModel;
Chris@45 417 m_mainModel = model;
Chris@160 418
Chris@45 419 emit modelAdded(m_mainModel);
Chris@160 420 if (model) {
Chris@160 421 emit activity(tr("Set main model to %1").arg(model->objectName()));
Chris@160 422 } else {
Chris@160 423 emit activity(tr("Clear main model"));
Chris@160 424 }
Chris@45 425
Chris@45 426 std::vector<Layer *> obsoleteLayers;
Chris@53 427 std::set<QString> failedTransformers;
Chris@45 428
Chris@45 429 // We need to ensure that no layer is left using oldMainModel or
Chris@45 430 // any of the old derived models as its model. Either replace the
Chris@45 431 // model, or delete the layer for each layer that is currently
Chris@45 432 // using one of these. Carry out this replacement before we
Chris@45 433 // delete any of the models.
Chris@45 434
Chris@77 435 #ifdef DEBUG_DOCUMENT
Chris@293 436 cerr << "Document::setMainModel: Have "
Chris@293 437 << m_layers.size() << " layers" << endl;
Chris@293 438 cerr << "Models now: ";
Chris@137 439 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@293 440 cerr << i->first << " ";
Chris@137 441 }
Chris@293 442 cerr << endl;
Chris@293 443 cerr << "Old main model: " << oldMainModel << endl;
Chris@77 444 #endif
Chris@52 445
Chris@45 446 for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
Chris@45 447
Chris@595 448 Layer *layer = *i;
Chris@595 449 Model *model = layer->getModel();
Chris@45 450
Chris@77 451 #ifdef DEBUG_DOCUMENT
Chris@293 452 cerr << "Document::setMainModel: inspecting model "
Chris@229 453 << (model ? model->objectName(): "(null)") << " in layer "
Chris@293 454 << layer->objectName() << endl;
Chris@77 455 #endif
Chris@45 456
Chris@595 457 if (model == oldMainModel) {
Chris@77 458 #ifdef DEBUG_DOCUMENT
Chris@293 459 cerr << "... it uses the old main model, replacing" << endl;
Chris@77 460 #endif
Chris@595 461 LayerFactory::getInstance()->setModel(layer, m_mainModel);
Chris@595 462 continue;
Chris@595 463 }
Chris@45 464
Chris@137 465 if (!model) {
Chris@293 466 cerr << "WARNING: Document::setMainModel: Null model in layer "
Chris@293 467 << layer << endl;
Chris@595 468 // get rid of this hideous degenerate
Chris@595 469 obsoleteLayers.push_back(layer);
Chris@595 470 continue;
Chris@595 471 }
Chris@137 472
Chris@595 473 if (m_models.find(model) == m_models.end()) {
Chris@595 474 cerr << "WARNING: Document::setMainModel: Unknown model "
Chris@595 475 << model << " in layer " << layer << endl;
Chris@595 476 // and this one
Chris@595 477 obsoleteLayers.push_back(layer);
Chris@595 478 continue;
Chris@595 479 }
Chris@595 480
Chris@595 481 if (m_models[model].source &&
Chris@70 482 (m_models[model].source == oldMainModel)) {
Chris@45 483
Chris@77 484 #ifdef DEBUG_DOCUMENT
Chris@293 485 cerr << "... it uses a model derived from the old main model, regenerating" << endl;
Chris@77 486 #endif
Chris@45 487
Chris@595 488 // This model was derived from the previous main
Chris@595 489 // model: regenerate it.
Chris@595 490
Chris@595 491 const Transform &transform = m_models[model].transform;
Chris@72 492 QString transformId = transform.getIdentifier();
Chris@595 493
Chris@72 494 //!!! We have a problem here if the number of channels in
Chris@72 495 //the main model has changed.
Chris@72 496
Chris@78 497 QString message;
Chris@595 498 Model *replacementModel =
Chris@45 499 addDerivedModel(transform,
Chris@72 500 ModelTransformer::Input
Chris@78 501 (m_mainModel, m_models[model].channel),
Chris@78 502 message);
Chris@595 503
Chris@595 504 if (!replacementModel) {
Chris@595 505 cerr << "WARNING: Document::setMainModel: Failed to regenerate model for transform \""
Chris@595 506 << transformId << "\"" << " in layer " << layer << endl;
Chris@72 507 if (failedTransformers.find(transformId)
Chris@72 508 == failedTransformers.end()) {
Chris@45 509 emit modelRegenerationFailed(layer->objectName(),
Chris@78 510 transformId,
Chris@78 511 message);
Chris@72 512 failedTransformers.insert(transformId);
Chris@45 513 }
Chris@595 514 obsoleteLayers.push_back(layer);
Chris@595 515 } else {
Chris@78 516 if (message != "") {
Chris@78 517 emit modelRegenerationWarning(layer->objectName(),
Chris@78 518 transformId,
Chris@78 519 message);
Chris@78 520 }
Chris@77 521 #ifdef DEBUG_DOCUMENT
Chris@293 522 cerr << "Replacing model " << model << " (type "
Chris@77 523 << typeid(*model).name() << ") with model "
Chris@77 524 << replacementModel << " (type "
Chris@77 525 << typeid(*replacementModel).name() << ") in layer "
Chris@228 526 << layer << " (name " << layer->objectName() << ")"
Chris@293 527 << endl;
Chris@366 528
Chris@45 529 RangeSummarisableTimeValueModel *rm =
Chris@45 530 dynamic_cast<RangeSummarisableTimeValueModel *>(replacementModel);
Chris@45 531 if (rm) {
Chris@293 532 cerr << "new model has " << rm->getChannelCount() << " channels " << endl;
Chris@45 533 } else {
Chris@293 534 cerr << "new model " << replacementModel << " is not a RangeSummarisableTimeValueModel!" << endl;
Chris@45 535 }
Chris@77 536 #endif
Chris@595 537 setModel(layer, replacementModel);
Chris@595 538 }
Chris@595 539 }
Chris@45 540 }
Chris@45 541
Chris@45 542 for (size_t k = 0; k < obsoleteLayers.size(); ++k) {
Chris@595 543 deleteLayer(obsoleteLayers[k], true);
Chris@45 544 }
Chris@45 545
Chris@48 546 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@329 547 if (i->second.additional) {
Chris@329 548 Model *m = i->first;
Chris@588 549 m->aboutToDelete();
Chris@329 550 emit modelAboutToBeDeleted(m);
Chris@329 551 delete m;
Chris@329 552 }
Chris@329 553 }
Chris@329 554
Chris@329 555 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@86 556
Chris@137 557 Model *m = i->first;
Chris@137 558
Chris@137 559 #ifdef DEBUG_DOCUMENT
Chris@233 560 SVDEBUG << "considering alignment for model " << m << " (name \""
Chris@229 561 << m->objectName() << "\")" << endl;
Chris@137 562 #endif
Chris@137 563
Chris@86 564 if (m_autoAlignment) {
Chris@86 565
Chris@137 566 alignModel(m);
Chris@86 567
Chris@86 568 } else if (oldMainModel &&
Chris@137 569 (m->getAlignmentReference() == oldMainModel)) {
Chris@86 570
Chris@137 571 alignModel(m);
Chris@48 572 }
Chris@48 573 }
Chris@48 574
Chris@77 575 if (oldMainModel) {
Chris@79 576 oldMainModel->aboutToDelete();
Chris@77 577 emit modelAboutToBeDeleted(oldMainModel);
Chris@77 578 }
Chris@77 579
Chris@86 580 if (m_autoAlignment) {
Chris@387 581 SVDEBUG << "Document::setMainModel: auto-alignment is on, aligning model if possible" << endl;
Chris@86 582 alignModel(m_mainModel);
Chris@86 583 }
Chris@86 584
Chris@45 585 emit mainModelChanged(m_mainModel);
Chris@45 586
Chris@45 587 delete oldMainModel;
Chris@45 588 }
Chris@45 589
Chris@45 590 void
Chris@329 591 Document::addAlreadyDerivedModel(const Transform &transform,
Chris@329 592 const ModelTransformer::Input &input,
Chris@329 593 Model *outputModelToAdd)
Chris@45 594 {
Chris@45 595 if (m_models.find(outputModelToAdd) != m_models.end()) {
Chris@595 596 cerr << "WARNING: Document::addAlreadyDerivedModel: Model already added"
Chris@595 597 << endl;
Chris@595 598 return;
Chris@45 599 }
Chris@45 600
Chris@77 601 #ifdef DEBUG_DOCUMENT
Chris@248 602 if (input.getModel()) {
Chris@329 603 cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl;
Chris@248 604 } else {
Chris@329 605 cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl;
Chris@248 606 }
Chris@77 607 #endif
Chris@45 608
Chris@45 609 ModelRecord rec;
Chris@72 610 rec.source = input.getModel();
Chris@72 611 rec.channel = input.getChannel();
Chris@45 612 rec.transform = transform;
Chris@329 613 rec.additional = false;
Chris@45 614 rec.refcount = 0;
Chris@45 615
Chris@72 616 outputModelToAdd->setSourceModel(input.getModel());
Chris@45 617
Chris@45 618 m_models[outputModelToAdd] = rec;
Chris@45 619
Chris@137 620 #ifdef DEBUG_DOCUMENT
Chris@329 621 cerr << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl;
Chris@293 622 cerr << "Models now: ";
Chris@137 623 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@293 624 cerr << i->first << " ";
Chris@137 625 }
Chris@293 626 cerr << endl;
Chris@137 627 #endif
Chris@137 628
Chris@45 629 emit modelAdded(outputModelToAdd);
Chris@45 630 }
Chris@45 631
Chris@45 632
Chris@45 633 void
Chris@45 634 Document::addImportedModel(Model *model)
Chris@45 635 {
Chris@45 636 if (m_models.find(model) != m_models.end()) {
Chris@595 637 cerr << "WARNING: Document::addImportedModel: Model already added"
Chris@595 638 << endl;
Chris@595 639 return;
Chris@45 640 }
Chris@45 641
Chris@45 642 ModelRecord rec;
Chris@45 643 rec.source = 0;
Chris@408 644 rec.channel = 0;
Chris@45 645 rec.refcount = 0;
Chris@329 646 rec.additional = false;
Chris@45 647
Chris@45 648 m_models[model] = rec;
Chris@45 649
Chris@137 650 #ifdef DEBUG_DOCUMENT
Chris@233 651 SVDEBUG << "Document::addImportedModel: Added model " << model << endl;
Chris@293 652 cerr << "Models now: ";
Chris@137 653 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@293 654 cerr << i->first << " ";
Chris@137 655 }
Chris@293 656 cerr << endl;
Chris@137 657 #endif
Chris@137 658
Chris@387 659 if (m_autoAlignment) {
Chris@387 660 SVDEBUG << "Document::addImportedModel: auto-alignment is on, aligning model if possible" << endl;
Chris@387 661 alignModel(model);
Chris@387 662 } else {
Chris@387 663 SVDEBUG << "Document(" << this << "): addImportedModel: auto-alignment is off" << endl;
Chris@387 664 }
Chris@47 665
Chris@45 666 emit modelAdded(model);
Chris@45 667 }
Chris@45 668
Chris@329 669 void
Chris@329 670 Document::addAdditionalModel(Model *model)
Chris@329 671 {
Chris@329 672 if (m_models.find(model) != m_models.end()) {
Chris@595 673 cerr << "WARNING: Document::addAdditionalModel: Model already added"
Chris@595 674 << endl;
Chris@595 675 return;
Chris@329 676 }
Chris@329 677
Chris@329 678 ModelRecord rec;
Chris@329 679 rec.source = 0;
Chris@408 680 rec.channel = 0;
Chris@329 681 rec.refcount = 0;
Chris@329 682 rec.additional = true;
Chris@329 683
Chris@329 684 m_models[model] = rec;
Chris@329 685
Chris@329 686 #ifdef DEBUG_DOCUMENT
Chris@329 687 SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl;
Chris@329 688 cerr << "Models now: ";
Chris@329 689 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@329 690 cerr << i->first << " ";
Chris@329 691 }
Chris@329 692 cerr << endl;
Chris@329 693 #endif
Chris@329 694
Chris@387 695 if (m_autoAlignment) {
Chris@387 696 SVDEBUG << "Document::addAdditionalModel: auto-alignment is on, aligning model if possible" << endl;
Chris@387 697 alignModel(model);
Chris@387 698 }
Chris@329 699
Chris@329 700 emit modelAdded(model);
Chris@329 701 }
Chris@329 702
Chris@588 703 void
Chris@588 704 Document::addAggregateModel(AggregateWaveModel *model)
Chris@588 705 {
Chris@588 706 connect(model, SIGNAL(modelInvalidated()),
Chris@588 707 this, SLOT(aggregateModelInvalidated()));
Chris@588 708 m_aggregateModels.insert(model);
Chris@588 709 }
Chris@588 710
Chris@588 711 void
Chris@588 712 Document::aggregateModelInvalidated()
Chris@588 713 {
Chris@588 714 QObject *s = sender();
Chris@588 715 AggregateWaveModel *aggregate = qobject_cast<AggregateWaveModel *>(s);
Chris@588 716 if (aggregate) releaseModel(aggregate);
Chris@588 717 }
Chris@588 718
Chris@45 719 Model *
Chris@72 720 Document::addDerivedModel(const Transform &transform,
Chris@78 721 const ModelTransformer::Input &input,
Chris@296 722 QString &message)
Chris@45 723 {
Chris@45 724 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@297 725 if (i->second.transform == transform &&
Chris@297 726 i->second.source == input.getModel() &&
Chris@72 727 i->second.channel == input.getChannel()) {
Chris@297 728 std::cerr << "derived model taken from map " << std::endl;
Chris@297 729 return i->first;
Chris@297 730 }
Chris@45 731 }
Chris@45 732
Chris@297 733 Transforms tt;
Chris@297 734 tt.push_back(transform);
Chris@329 735 vector<Model *> mm = addDerivedModels(tt, input, message, 0);
Chris@297 736 if (mm.empty()) return 0;
Chris@297 737 else return mm[0];
Chris@297 738 }
Chris@45 739
Chris@297 740 vector<Model *>
Chris@297 741 Document::addDerivedModels(const Transforms &transforms,
Chris@297 742 const ModelTransformer::Input &input,
Chris@329 743 QString &message,
Chris@329 744 AdditionalModelConverter *amc)
Chris@297 745 {
Chris@297 746 vector<Model *> mm =
Chris@297 747 ModelTransformerFactory::getInstance()->transformMultiple
Chris@329 748 (transforms, input, message, amc);
Chris@83 749
Chris@297 750 for (int j = 0; j < (int)mm.size(); ++j) {
Chris@83 751
Chris@297 752 Model *model = mm[j];
Chris@297 753
Chris@297 754 // The transform we actually used was presumably identical to
Chris@297 755 // the one asked for, except that the version of the plugin
Chris@297 756 // may differ. It's possible that the returned message
Chris@297 757 // contains a warning about this; that doesn't concern us
Chris@297 758 // here, but we do need to ensure that the transform we
Chris@297 759 // remember is correct for what was actually applied, with the
Chris@297 760 // current plugin version.
Chris@297 761
Chris@536 762 //!!! would be nice to short-circuit this -- the version is
Chris@536 763 //!!! static data, shouldn't have to construct a plugin for it
Chris@536 764 //!!! (which may be expensive in Piper-world)
Chris@536 765
Chris@297 766 Transform applied = transforms[j];
Chris@297 767 applied.setPluginVersion
Chris@297 768 (TransformFactory::getInstance()->
Chris@297 769 getDefaultTransformFor(applied.getIdentifier(),
Chris@436 770 applied.getSampleRate())
Chris@297 771 .getPluginVersion());
Chris@297 772
Chris@297 773 if (!model) {
Chris@297 774 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl;
Chris@297 775 } else {
Chris@329 776 addAlreadyDerivedModel(applied, input, model);
Chris@297 777 }
Chris@45 778 }
Chris@595 779
Chris@297 780 return mm;
Chris@45 781 }
Chris@45 782
Chris@45 783 void
Chris@45 784 Document::releaseModel(Model *model) // Will _not_ release main model!
Chris@45 785 {
Chris@45 786 if (model == 0) {
Chris@595 787 return;
Chris@45 788 }
Chris@45 789
Chris@45 790 if (model == m_mainModel) {
Chris@595 791 return;
Chris@45 792 }
Chris@45 793
Chris@45 794 bool toDelete = false;
Chris@45 795
Chris@45 796 if (m_models.find(model) != m_models.end()) {
Chris@595 797 if (m_models[model].refcount == 0) {
Chris@595 798 SVCERR << "WARNING: Document::releaseModel: model " << model
Chris@588 799 << " reference count is zero already!" << endl;
Chris@595 800 } else {
Chris@595 801 if (--m_models[model].refcount == 0) {
Chris@595 802 toDelete = true;
Chris@595 803 }
Chris@595 804 }
Chris@588 805 } else if (m_aggregateModels.find(model) != m_aggregateModels.end()) {
Chris@588 806 SVDEBUG << "Document::releaseModel: is an aggregate model" << endl;
Chris@588 807 toDelete = true;
Chris@45 808 } else {
Chris@595 809 SVCERR << "WARNING: Document::releaseModel: Unfound model "
Chris@588 810 << model << endl;
Chris@595 811 toDelete = true;
Chris@45 812 }
Chris@45 813
Chris@45 814 if (toDelete) {
Chris@45 815
Chris@595 816 int sourceCount = 0;
Chris@45 817
Chris@595 818 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@595 819 if (i->second.source == model) {
Chris@595 820 ++sourceCount;
Chris@595 821 i->second.source = 0;
Chris@595 822 }
Chris@595 823 }
Chris@45 824
Chris@595 825 if (sourceCount > 0) {
Chris@595 826 SVDEBUG << "Document::releaseModel: Deleting model "
Chris@588 827 << model << " even though it is source for "
Chris@588 828 << sourceCount << " other derived model(s) -- resetting "
Chris@588 829 << "their source fields appropriately" << endl;
Chris@595 830 }
Chris@45 831
Chris@79 832 model->aboutToDelete();
Chris@595 833 emit modelAboutToBeDeleted(model);
Chris@595 834 m_models.erase(model);
Chris@137 835
Chris@137 836 #ifdef DEBUG_DOCUMENT
Chris@233 837 SVDEBUG << "Document::releaseModel: Deleted model " << model << endl;
Chris@293 838 cerr << "Models now: ";
Chris@137 839 for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@293 840 cerr << i->first << " ";
Chris@137 841 }
Chris@293 842 cerr << endl;
Chris@137 843 #endif
Chris@137 844
Chris@595 845 delete model;
Chris@45 846 }
Chris@45 847 }
Chris@45 848
Chris@45 849 void
Chris@45 850 Document::deleteLayer(Layer *layer, bool force)
Chris@45 851 {
Chris@45 852 if (m_layerViewMap.find(layer) != m_layerViewMap.end() &&
Chris@595 853 m_layerViewMap[layer].size() > 0) {
Chris@45 854
Chris@595 855 cerr << "WARNING: Document::deleteLayer: Layer "
Chris@595 856 << layer << " [" << layer->objectName() << "]"
Chris@595 857 << " is still used in " << m_layerViewMap[layer].size()
Chris@595 858 << " views!" << endl;
Chris@45 859
Chris@595 860 if (force) {
Chris@45 861
Chris@77 862 #ifdef DEBUG_DOCUMENT
Chris@595 863 cerr << "(force flag set -- deleting from all views)" << endl;
Chris@77 864 #endif
Chris@45 865
Chris@595 866 for (std::set<View *>::iterator j = m_layerViewMap[layer].begin();
Chris@595 867 j != m_layerViewMap[layer].end(); ++j) {
Chris@595 868 // don't use removeLayerFromView, as it issues a command
Chris@595 869 layer->setLayerDormant(*j, true);
Chris@595 870 (*j)->removeLayer(layer);
Chris@595 871 }
Chris@595 872
Chris@595 873 m_layerViewMap.erase(layer);
Chris@45 874
Chris@595 875 } else {
Chris@595 876 return;
Chris@595 877 }
Chris@45 878 }
Chris@45 879
Chris@45 880 if (m_layers.find(layer) == m_layers.end()) {
Chris@595 881 SVDEBUG << "Document::deleteLayer: Layer "
Chris@212 882 << layer << " (" << typeid(layer).name() <<
Chris@212 883 ") does not exist, or has already been deleted "
Chris@595 884 << "(this may not be as serious as it sounds)" << endl;
Chris@595 885 return;
Chris@45 886 }
Chris@45 887
Chris@45 888 m_layers.erase(layer);
Chris@45 889
Chris@132 890 #ifdef DEBUG_DOCUMENT
Chris@233 891 SVDEBUG << "Document::deleteLayer: Removing, now have "
Chris@229 892 << m_layers.size() << " layers" << endl;
Chris@132 893 #endif
Chris@52 894
Chris@45 895 releaseModel(layer->getModel());
Chris@45 896 emit layerRemoved(layer);
Chris@45 897 emit layerAboutToBeDeleted(layer);
Chris@45 898 delete layer;
Chris@45 899 }
Chris@45 900
Chris@45 901 void
Chris@45 902 Document::setModel(Layer *layer, Model *model)
Chris@45 903 {
Chris@45 904 if (model &&
Chris@595 905 model != m_mainModel &&
Chris@595 906 m_models.find(model) == m_models.end()) {
Chris@595 907 cerr << "ERROR: Document::setModel: Layer " << layer
Chris@595 908 << " (\"" << layer->objectName()
Chris@45 909 << "\") wants to use unregistered model " << model
Chris@595 910 << ": register the layer's model before setting it!"
Chris@595 911 << endl;
Chris@595 912 return;
Chris@45 913 }
Chris@45 914
Chris@45 915 Model *previousModel = layer->getModel();
Chris@45 916
Chris@45 917 if (previousModel == model) {
Chris@233 918 SVDEBUG << "NOTE: Document::setModel: Layer " << layer << " (\""
Chris@229 919 << layer->objectName() << "\") is already set to model "
Chris@45 920 << model << " (\""
Chris@229 921 << (model ? model->objectName(): "(null)")
Chris@229 922 << "\")" << endl;
Chris@45 923 return;
Chris@45 924 }
Chris@45 925
Chris@45 926 if (model && model != m_mainModel) {
Chris@595 927 m_models[model].refcount ++;
Chris@45 928 }
Chris@45 929
Chris@45 930 if (model && previousModel) {
Chris@45 931 PlayParameterRepository::getInstance()->copyParameters
Chris@45 932 (previousModel, model);
Chris@45 933 }
Chris@45 934
Chris@45 935 LayerFactory::getInstance()->setModel(layer, model);
Chris@595 936 // std::cerr << "layer type: " << LayerFactory::getInstance()->getLayerTypeName(LayerFactory::getInstance()->getLayerType(layer)) << std::endl;
Chris@45 937
Chris@45 938 if (previousModel) {
Chris@45 939 releaseModel(previousModel);
Chris@45 940 }
Chris@45 941 }
Chris@45 942
Chris@45 943 void
Chris@45 944 Document::setChannel(Layer *layer, int channel)
Chris@45 945 {
Chris@45 946 LayerFactory::getInstance()->setChannel(layer, channel);
Chris@45 947 }
Chris@45 948
Chris@45 949 void
Chris@45 950 Document::addLayerToView(View *view, Layer *layer)
Chris@45 951 {
Chris@45 952 Model *model = layer->getModel();
Chris@45 953 if (!model) {
Chris@77 954 #ifdef DEBUG_DOCUMENT
Chris@595 955 SVDEBUG << "Document::addLayerToView: Layer (\""
Chris@229 956 << layer->objectName() << "\") with no model being added to view: "
Chris@229 957 << "normally you want to set the model first" << endl;
Chris@77 958 #endif
Chris@45 959 } else {
Chris@595 960 if (model != m_mainModel &&
Chris@595 961 m_models.find(model) == m_models.end()) {
Chris@595 962 cerr << "ERROR: Document::addLayerToView: Layer " << layer
Chris@595 963 << " has unregistered model " << model
Chris@595 964 << " -- register the layer's model before adding the layer!" << endl;
Chris@595 965 return;
Chris@595 966 }
Chris@45 967 }
Chris@45 968
Chris@45 969 CommandHistory::getInstance()->addCommand
Chris@595 970 (new Document::AddLayerCommand(this, view, layer));
Chris@45 971 }
Chris@45 972
Chris@45 973 void
Chris@45 974 Document::removeLayerFromView(View *view, Layer *layer)
Chris@45 975 {
Chris@45 976 CommandHistory::getInstance()->addCommand
Chris@595 977 (new Document::RemoveLayerCommand(this, view, layer));
Chris@45 978 }
Chris@45 979
Chris@45 980 void
Chris@45 981 Document::addToLayerViewMap(Layer *layer, View *view)
Chris@45 982 {
Chris@45 983 bool firstView = (m_layerViewMap.find(layer) == m_layerViewMap.end() ||
Chris@45 984 m_layerViewMap[layer].empty());
Chris@45 985
Chris@45 986 if (m_layerViewMap[layer].find(view) !=
Chris@595 987 m_layerViewMap[layer].end()) {
Chris@595 988 cerr << "WARNING: Document::addToLayerViewMap:"
Chris@595 989 << " Layer " << layer << " -> view " << view << " already in"
Chris@595 990 << " layer view map -- internal inconsistency" << endl;
Chris@45 991 }
Chris@45 992
Chris@45 993 m_layerViewMap[layer].insert(view);
Chris@45 994
Chris@45 995 if (firstView) emit layerInAView(layer, true);
Chris@45 996 }
Chris@45 997
Chris@45 998 void
Chris@45 999 Document::removeFromLayerViewMap(Layer *layer, View *view)
Chris@45 1000 {
Chris@45 1001 if (m_layerViewMap[layer].find(view) ==
Chris@595 1002 m_layerViewMap[layer].end()) {
Chris@595 1003 cerr << "WARNING: Document::removeFromLayerViewMap:"
Chris@595 1004 << " Layer " << layer << " -> view " << view << " not in"
Chris@595 1005 << " layer view map -- internal inconsistency" << endl;
Chris@45 1006 }
Chris@45 1007
Chris@45 1008 m_layerViewMap[layer].erase(view);
Chris@45 1009
Chris@45 1010 if (m_layerViewMap[layer].empty()) {
Chris@45 1011 m_layerViewMap.erase(layer);
Chris@45 1012 emit layerInAView(layer, false);
Chris@45 1013 }
Chris@45 1014 }
Chris@45 1015
Chris@45 1016 QString
Chris@45 1017 Document::getUniqueLayerName(QString candidate)
Chris@45 1018 {
Chris@45 1019 for (int count = 1; ; ++count) {
Chris@45 1020
Chris@45 1021 QString adjusted =
Chris@45 1022 (count > 1 ? QString("%1 <%2>").arg(candidate).arg(count) :
Chris@45 1023 candidate);
Chris@45 1024
Chris@45 1025 bool duplicate = false;
Chris@45 1026
Chris@45 1027 for (LayerSet::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
Chris@45 1028 if ((*i)->objectName() == adjusted) {
Chris@45 1029 duplicate = true;
Chris@45 1030 break;
Chris@45 1031 }
Chris@45 1032 }
Chris@45 1033
Chris@45 1034 if (!duplicate) return adjusted;
Chris@45 1035 }
Chris@45 1036 }
Chris@45 1037
Chris@45 1038 std::vector<Model *>
Chris@72 1039 Document::getTransformInputModels()
Chris@45 1040 {
Chris@45 1041 std::vector<Model *> models;
Chris@45 1042
Chris@45 1043 if (!m_mainModel) return models;
Chris@45 1044
Chris@45 1045 models.push_back(m_mainModel);
Chris@45 1046
Chris@45 1047 //!!! This will pick up all models, including those that aren't visible...
Chris@45 1048
Chris@45 1049 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@45 1050
Chris@45 1051 Model *model = i->first;
Chris@45 1052 if (!model || model == m_mainModel) continue;
Chris@45 1053 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model);
Chris@45 1054
Chris@45 1055 if (dtvm) {
Chris@45 1056 models.push_back(dtvm);
Chris@45 1057 }
Chris@45 1058 }
Chris@45 1059
Chris@45 1060 return models;
Chris@45 1061 }
Chris@45 1062
Chris@50 1063 bool
Chris@77 1064 Document::isKnownModel(const Model *model) const
Chris@77 1065 {
Chris@77 1066 if (model == m_mainModel) return true;
Chris@77 1067 return (m_models.find(const_cast<Model *>(model)) != m_models.end());
Chris@77 1068 }
Chris@77 1069
Chris@428 1070 bool
Chris@428 1071 Document::canAlign()
Chris@90 1072 {
Chris@428 1073 return Align::canAlign();
Chris@50 1074 }
Chris@50 1075
Chris@45 1076 void
Chris@45 1077 Document::alignModel(Model *model)
Chris@45 1078 {
Chris@387 1079 SVDEBUG << "Document::alignModel(" << model << ")" << endl;
Chris@387 1080
Chris@387 1081 if (!m_mainModel) {
Chris@387 1082 SVDEBUG << "(no main model to align to)" << endl;
Chris@387 1083 return;
Chris@387 1084 }
Chris@45 1085
Chris@45 1086 RangeSummarisableTimeValueModel *rm =
Chris@45 1087 dynamic_cast<RangeSummarisableTimeValueModel *>(model);
Chris@387 1088 if (!rm) {
Chris@387 1089 SVDEBUG << "(main model is not alignable-to)" << endl;
Chris@387 1090 return;
Chris@387 1091 }
Chris@48 1092
Chris@86 1093 if (rm->getAlignmentReference() == m_mainModel) {
Chris@387 1094 SVDEBUG << "(model " << rm << " is already aligned to main model " << m_mainModel << ")" << endl;
Chris@86 1095 return;
Chris@86 1096 }
Chris@45 1097
Chris@86 1098 if (model == m_mainModel) {
Chris@86 1099 // The reference has an empty alignment to itself. This makes
Chris@86 1100 // it possible to distinguish between the reference and any
Chris@86 1101 // unaligned model just by looking at the model itself,
Chris@86 1102 // without also knowing what the main model is
Chris@233 1103 SVDEBUG << "Document::alignModel(" << model << "): is main model, setting appropriately" << endl;
Chris@86 1104 rm->setAlignment(new AlignmentModel(model, model, 0, 0));
Chris@86 1105 return;
Chris@86 1106 }
Chris@86 1107
Chris@423 1108 if (!m_align->alignModel(m_mainModel, rm)) {
Chris@423 1109 cerr << "Alignment failed: " << m_align->getError() << endl;
Chris@423 1110 emit alignmentFailed(m_align->getError());
Chris@64 1111 }
Chris@45 1112 }
Chris@45 1113
Chris@45 1114 void
Chris@45 1115 Document::alignModels()
Chris@45 1116 {
Chris@45 1117 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
Chris@45 1118 alignModel(i->first);
Chris@45 1119 }
Chris@86 1120 alignModel(m_mainModel);
Chris@45 1121 }
Chris@45 1122
Chris@45 1123 Document::AddLayerCommand::AddLayerCommand(Document *d,
Chris@595 1124 View *view,
Chris@595 1125 Layer *layer) :
Chris@45 1126 m_d(d),
Chris@45 1127 m_view(view),
Chris@45 1128 m_layer(layer),
Chris@45 1129 m_name(qApp->translate("AddLayerCommand", "Add %1 Layer").arg(layer->objectName())),
Chris@45 1130 m_added(false)
Chris@45 1131 {
Chris@45 1132 }
Chris@45 1133
Chris@45 1134 Document::AddLayerCommand::~AddLayerCommand()
Chris@45 1135 {
Chris@77 1136 #ifdef DEBUG_DOCUMENT
Chris@233 1137 SVDEBUG << "Document::AddLayerCommand::~AddLayerCommand" << endl;
Chris@77 1138 #endif
Chris@45 1139 if (!m_added) {
Chris@595 1140 m_d->deleteLayer(m_layer);
Chris@45 1141 }
Chris@45 1142 }
Chris@45 1143
Chris@159 1144 QString
Chris@159 1145 Document::AddLayerCommand::getName() const
Chris@159 1146 {
Chris@165 1147 #ifdef DEBUG_DOCUMENT
Chris@233 1148 SVDEBUG << "Document::AddLayerCommand::getName(): Name is "
Chris@229 1149 << m_name << endl;
Chris@165 1150 #endif
Chris@159 1151 return m_name;
Chris@159 1152 }
Chris@159 1153
Chris@45 1154 void
Chris@45 1155 Document::AddLayerCommand::execute()
Chris@45 1156 {
Chris@45 1157 for (int i = 0; i < m_view->getLayerCount(); ++i) {
Chris@595 1158 if (m_view->getLayer(i) == m_layer) {
Chris@595 1159 // already there
Chris@595 1160 m_layer->setLayerDormant(m_view, false);
Chris@595 1161 m_added = true;
Chris@595 1162 return;
Chris@595 1163 }
Chris@45 1164 }
Chris@45 1165
Chris@45 1166 m_view->addLayer(m_layer);
Chris@45 1167 m_layer->setLayerDormant(m_view, false);
Chris@45 1168
Chris@45 1169 m_d->addToLayerViewMap(m_layer, m_view);
Chris@45 1170 m_added = true;
Chris@45 1171 }
Chris@45 1172
Chris@45 1173 void
Chris@45 1174 Document::AddLayerCommand::unexecute()
Chris@45 1175 {
Chris@45 1176 m_view->removeLayer(m_layer);
Chris@45 1177 m_layer->setLayerDormant(m_view, true);
Chris@45 1178
Chris@45 1179 m_d->removeFromLayerViewMap(m_layer, m_view);
Chris@45 1180 m_added = false;
Chris@45 1181 }
Chris@45 1182
Chris@45 1183 Document::RemoveLayerCommand::RemoveLayerCommand(Document *d,
Chris@595 1184 View *view,
Chris@595 1185 Layer *layer) :
Chris@45 1186 m_d(d),
Chris@45 1187 m_view(view),
Chris@45 1188 m_layer(layer),
Chris@339 1189 m_wasDormant(layer->isLayerDormant(view)),
Chris@45 1190 m_name(qApp->translate("RemoveLayerCommand", "Delete %1 Layer").arg(layer->objectName())),
Chris@45 1191 m_added(true)
Chris@45 1192 {
Chris@45 1193 }
Chris@45 1194
Chris@45 1195 Document::RemoveLayerCommand::~RemoveLayerCommand()
Chris@45 1196 {
Chris@77 1197 #ifdef DEBUG_DOCUMENT
Chris@233 1198 SVDEBUG << "Document::RemoveLayerCommand::~RemoveLayerCommand" << endl;
Chris@77 1199 #endif
Chris@45 1200 if (!m_added) {
Chris@595 1201 m_d->deleteLayer(m_layer);
Chris@45 1202 }
Chris@45 1203 }
Chris@45 1204
Chris@159 1205 QString
Chris@159 1206 Document::RemoveLayerCommand::getName() const
Chris@159 1207 {
Chris@171 1208 #ifdef DEBUG_DOCUMENT
Chris@233 1209 SVDEBUG << "Document::RemoveLayerCommand::getName(): Name is "
Chris@229 1210 << m_name << endl;
Chris@171 1211 #endif
Chris@159 1212 return m_name;
Chris@159 1213 }
Chris@159 1214
Chris@45 1215 void
Chris@45 1216 Document::RemoveLayerCommand::execute()
Chris@45 1217 {
Chris@45 1218 bool have = false;
Chris@45 1219 for (int i = 0; i < m_view->getLayerCount(); ++i) {
Chris@595 1220 if (m_view->getLayer(i) == m_layer) {
Chris@595 1221 have = true;
Chris@595 1222 break;
Chris@595 1223 }
Chris@45 1224 }
Chris@45 1225
Chris@45 1226 if (!have) { // not there!
Chris@595 1227 m_layer->setLayerDormant(m_view, true);
Chris@595 1228 m_added = false;
Chris@595 1229 return;
Chris@45 1230 }
Chris@45 1231
Chris@45 1232 m_view->removeLayer(m_layer);
Chris@45 1233 m_layer->setLayerDormant(m_view, true);
Chris@45 1234
Chris@45 1235 m_d->removeFromLayerViewMap(m_layer, m_view);
Chris@45 1236 m_added = false;
Chris@45 1237 }
Chris@45 1238
Chris@45 1239 void
Chris@45 1240 Document::RemoveLayerCommand::unexecute()
Chris@45 1241 {
Chris@45 1242 m_view->addLayer(m_layer);
Chris@339 1243 m_layer->setLayerDormant(m_view, m_wasDormant);
Chris@45 1244
Chris@45 1245 m_d->addToLayerViewMap(m_layer, m_view);
Chris@45 1246 m_added = true;
Chris@45 1247 }
Chris@45 1248
Chris@45 1249 void
Chris@45 1250 Document::toXml(QTextStream &out, QString indent, QString extraAttributes) const
Chris@45 1251 {
Chris@226 1252 toXml(out, indent, extraAttributes, false);
Chris@226 1253 }
Chris@226 1254
Chris@226 1255 void
Chris@226 1256 Document::toXmlAsTemplate(QTextStream &out, QString indent, QString extraAttributes) const
Chris@226 1257 {
Chris@226 1258 toXml(out, indent, extraAttributes, true);
Chris@226 1259 }
Chris@226 1260
Chris@226 1261 void
Chris@226 1262 Document::toXml(QTextStream &out, QString indent, QString extraAttributes,
Chris@226 1263 bool asTemplate) const
Chris@226 1264 {
Chris@45 1265 out << indent + QString("<data%1%2>\n")
Chris@45 1266 .arg(extraAttributes == "" ? "" : " ").arg(extraAttributes);
Chris@45 1267
Chris@45 1268 if (m_mainModel) {
Chris@108 1269
Chris@226 1270 if (asTemplate) {
Chris@226 1271 writePlaceholderMainModel(out, indent + " ");
Chris@226 1272 } else {
Chris@226 1273 m_mainModel->toXml(out, indent + " ", "mainModel=\"true\"");
Chris@226 1274 }
Chris@108 1275
Chris@108 1276 PlayParameters *playParameters =
Chris@108 1277 PlayParameterRepository::getInstance()->getPlayParameters(m_mainModel);
Chris@108 1278 if (playParameters) {
Chris@108 1279 playParameters->toXml
Chris@108 1280 (out, indent + " ",
Chris@108 1281 QString("model=\"%1\"")
Chris@108 1282 .arg(XmlExportable::getObjectExportId(m_mainModel)));
Chris@108 1283 }
Chris@45 1284 }
Chris@45 1285
Chris@45 1286 // Models that are not used in a layer that is in a view should
Chris@45 1287 // not be written. Get our list of required models first.
Chris@45 1288
Chris@45 1289 std::set<const Model *> used;
Chris@45 1290
Chris@45 1291 for (LayerViewMap::const_iterator i = m_layerViewMap.begin();
Chris@45 1292 i != m_layerViewMap.end(); ++i) {
Chris@45 1293
Chris@589 1294 if (i->first && !i->second.empty()) { // Layer exists, is in views
Chris@589 1295 Model *m = i->first->getModel();
Chris@589 1296 if (m) {
Chris@589 1297 used.insert(m);
Chris@589 1298 if (m->getSourceModel()) {
Chris@589 1299 used.insert(m->getSourceModel());
Chris@589 1300 }
Chris@589 1301 }
Chris@45 1302 }
Chris@45 1303 }
Chris@45 1304
Chris@589 1305 // Write aggregate models first, so that when re-reading
Chris@589 1306 // derivations we already know about their existence. But only
Chris@589 1307 // those that are actually used
Chris@589 1308
Chris@589 1309 for (std::set<Model *>::iterator i = m_aggregateModels.begin();
Chris@589 1310 i != m_aggregateModels.end(); ++i) {
Chris@589 1311
Chris@589 1312 SVDEBUG << "checking aggregate model " << *i << endl;
Chris@589 1313
Chris@589 1314 AggregateWaveModel *aggregate = qobject_cast<AggregateWaveModel *>(*i);
Chris@589 1315 if (!aggregate) continue;
Chris@589 1316 if (used.find(aggregate) == used.end()) {
Chris@589 1317 SVDEBUG << "(unused, skipping)" << endl;
Chris@589 1318 continue;
Chris@589 1319 }
Chris@589 1320
Chris@589 1321 SVDEBUG << "(used, writing)" << endl;
Chris@589 1322
Chris@589 1323 aggregate->toXml(out, indent + " ");
Chris@589 1324 }
Chris@589 1325
Chris@111 1326 std::set<Model *> written;
Chris@111 1327
Chris@45 1328 for (ModelMap::const_iterator i = m_models.begin();
Chris@595 1329 i != m_models.end(); ++i) {
Chris@45 1330
Chris@111 1331 Model *model = i->first;
Chris@595 1332 const ModelRecord &rec = i->second;
Chris@45 1333
Chris@45 1334 if (used.find(model) == used.end()) continue;
Chris@45 1335
Chris@45 1336 // We need an intelligent way to determine which models need
Chris@45 1337 // to be streamed (i.e. have been edited, or are small) and
Chris@45 1338 // which should not be (i.e. remain as generated by a
Chris@45 1339 // transform, and are large).
Chris@45 1340 //
Chris@45 1341 // At the moment we can get away with deciding not to stream
Chris@45 1342 // dense 3d models or writable wave file models, provided they
Chris@45 1343 // were generated from a transform, because at the moment there
Chris@45 1344 // is no way to edit those model types so it should be safe to
Chris@45 1345 // regenerate them. That won't always work in future though.
Chris@45 1346 // It would be particularly nice to be able to ask the user,
Chris@45 1347 // as well as making an intelligent guess.
Chris@45 1348
Chris@45 1349 bool writeModel = true;
Chris@45 1350 bool haveDerivation = false;
Chris@45 1351
Chris@72 1352 if (rec.source && rec.transform.getIdentifier() != "") {
Chris@45 1353 haveDerivation = true;
Chris@45 1354 }
Chris@45 1355
Chris@45 1356 if (haveDerivation) {
Chris@45 1357 if (dynamic_cast<const WritableWaveFileModel *>(model)) {
Chris@45 1358 writeModel = false;
Chris@45 1359 } else if (dynamic_cast<const DenseThreeDimensionalModel *>(model)) {
Chris@45 1360 writeModel = false;
Chris@45 1361 }
Chris@45 1362 }
Chris@45 1363
Chris@45 1364 if (writeModel) {
Chris@111 1365 model->toXml(out, indent + " ");
Chris@111 1366 written.insert(model);
Chris@45 1367 }
Chris@45 1368
Chris@595 1369 if (haveDerivation) {
Chris@72 1370 writeBackwardCompatibleDerivation(out, indent + " ",
Chris@111 1371 model, rec);
Chris@595 1372 }
Chris@45 1373
Chris@45 1374 //!!! We should probably own the PlayParameterRepository
Chris@45 1375 PlayParameters *playParameters =
Chris@111 1376 PlayParameterRepository::getInstance()->getPlayParameters(model);
Chris@45 1377 if (playParameters) {
Chris@45 1378 playParameters->toXml
Chris@45 1379 (out, indent + " ",
Chris@45 1380 QString("model=\"%1\"")
Chris@111 1381 .arg(XmlExportable::getObjectExportId(model)));
Chris@45 1382 }
Chris@45 1383 }
Chris@589 1384
Chris@111 1385 //!!!
Chris@111 1386
Chris@111 1387 // We should write out the alignment models here. AlignmentModel
Chris@111 1388 // needs a toXml that writes out the export IDs of its reference
Chris@111 1389 // and aligned models, and then streams its path model. Note that
Chris@111 1390 // this will only work when the alignment is complete, so we
Chris@111 1391 // should probably wait for it if it isn't already by this point.
Chris@111 1392
Chris@111 1393 for (std::set<Model *>::const_iterator i = written.begin();
Chris@595 1394 i != written.end(); ++i) {
Chris@111 1395
Chris@111 1396 const Model *model = *i;
Chris@111 1397 const AlignmentModel *alignment = model->getAlignment();
Chris@111 1398 if (!alignment) continue;
Chris@111 1399
Chris@111 1400 alignment->toXml(out, indent + " ");
Chris@111 1401 }
Chris@111 1402
Chris@45 1403 for (LayerSet::const_iterator i = m_layers.begin();
Chris@595 1404 i != m_layers.end(); ++i) {
Chris@45 1405
Chris@595 1406 (*i)->toXml(out, indent + " ");
Chris@45 1407 }
Chris@45 1408
Chris@45 1409 out << indent + "</data>\n";
Chris@45 1410 }
Chris@45 1411
Chris@72 1412 void
Chris@226 1413 Document::writePlaceholderMainModel(QTextStream &out, QString indent) const
Chris@226 1414 {
Chris@226 1415 out << indent;
Chris@226 1416 out << QString("<model id=\"%1\" name=\"placeholder\" sampleRate=\"%2\" type=\"wavefile\" file=\":samples/silent.wav\" mainModel=\"true\"/>\n")
Chris@226 1417 .arg(getObjectExportId(m_mainModel))
Chris@226 1418 .arg(m_mainModel->getSampleRate());
Chris@226 1419 }
Chris@226 1420
Chris@226 1421 void
Chris@72 1422 Document::writeBackwardCompatibleDerivation(QTextStream &out, QString indent,
Chris@72 1423 Model *targetModel,
Chris@72 1424 const ModelRecord &rec) const
Chris@72 1425 {
Chris@72 1426 // There is a lot of redundancy in the XML we output here, because
Chris@72 1427 // we want it to work with older SV session file reading code as
Chris@72 1428 // well.
Chris@72 1429 //
Chris@72 1430 // Formerly, a transform was described using a derivation element
Chris@72 1431 // which set out the source and target models, execution context
Chris@72 1432 // (step size, input channel etc) and transform id, containing a
Chris@72 1433 // plugin element which set out the transform parameters and so
Chris@72 1434 // on. (The plugin element came from a "configurationXml" string
Chris@72 1435 // obtained from PluginXml.)
Chris@72 1436 //
Chris@72 1437 // This has been replaced by a derivation element setting out the
Chris@72 1438 // source and target models and input channel, containing a
Chris@72 1439 // transform element which sets out everything in the Transform.
Chris@72 1440 //
Chris@72 1441 // In order to retain compatibility with older SV code, however,
Chris@72 1442 // we have to write out the same stuff into the derivation as
Chris@72 1443 // before, and manufacture an appropriate plugin element as well
Chris@72 1444 // as the transform element. In order that newer code knows it's
Chris@72 1445 // dealing with a newer format, we will also write an attribute
Chris@72 1446 // 'type="transform"' in the derivation element.
Chris@45 1447
Chris@72 1448 const Transform &transform = rec.transform;
Chris@72 1449
Chris@72 1450 // Just for reference, this is what we would write if we didn't
Chris@72 1451 // have to be backward compatible:
Chris@72 1452 //
Chris@72 1453 // out << indent
Chris@72 1454 // << QString("<derivation type=\"transform\" source=\"%1\" "
Chris@72 1455 // "model=\"%2\" channel=\"%3\">\n")
Chris@72 1456 // .arg(XmlExportable::getObjectExportId(rec.source))
Chris@72 1457 // .arg(XmlExportable::getObjectExportId(targetModel))
Chris@72 1458 // .arg(rec.channel);
Chris@72 1459 //
Chris@72 1460 // transform.toXml(out, indent + " ");
Chris@72 1461 //
Chris@72 1462 // out << indent << "</derivation>\n";
Chris@72 1463 //
Chris@72 1464 // Unfortunately, we can't just do that. So we do this...
Chris@72 1465
Chris@72 1466 QString extentsAttributes;
Chris@72 1467 if (transform.getStartTime() != RealTime::zeroTime ||
Chris@72 1468 transform.getDuration() != RealTime::zeroTime) {
Chris@72 1469 extentsAttributes = QString("startFrame=\"%1\" duration=\"%2\" ")
Chris@72 1470 .arg(RealTime::realTime2Frame(transform.getStartTime(),
Chris@72 1471 targetModel->getSampleRate()))
Chris@72 1472 .arg(RealTime::realTime2Frame(transform.getDuration(),
Chris@72 1473 targetModel->getSampleRate()));
Chris@72 1474 }
Chris@595 1475
Chris@72 1476 out << indent;
Chris@72 1477 out << QString("<derivation type=\"transform\" source=\"%1\" "
Chris@72 1478 "model=\"%2\" channel=\"%3\" domain=\"%4\" "
Chris@72 1479 "stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" "
Chris@72 1480 "transform=\"%9\">\n")
Chris@72 1481 .arg(XmlExportable::getObjectExportId(rec.source))
Chris@72 1482 .arg(XmlExportable::getObjectExportId(targetModel))
Chris@72 1483 .arg(rec.channel)
Chris@72 1484 .arg(TransformFactory::getInstance()->getTransformInputDomain
Chris@72 1485 (transform.getIdentifier()))
Chris@72 1486 .arg(transform.getStepSize())
Chris@72 1487 .arg(transform.getBlockSize())
Chris@72 1488 .arg(extentsAttributes)
Chris@72 1489 .arg(int(transform.getWindowType()))
Chris@72 1490 .arg(XmlExportable::encodeEntities(transform.getIdentifier()));
Chris@72 1491
Chris@72 1492 transform.toXml(out, indent + " ");
Chris@72 1493
Chris@72 1494 out << indent << " "
Chris@72 1495 << TransformFactory::getInstance()->getPluginConfigurationXml(transform);
Chris@72 1496
Chris@72 1497 out << indent << "</derivation>\n";
Chris@72 1498 }
Chris@72 1499