annotate layer/LayerFactory.cpp @ 855:57efeb75880d

Simplify some logic where loop was used with an unconditional "break" that meant it could only happen once (from coverity scan)
author Chris Cannam
date Wed, 03 Sep 2014 12:05:45 +0100
parents 1d526ba11a24
children b12cd1c2dad5
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@59 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "LayerFactory.h"
Chris@0 17
Chris@0 18 #include "WaveformLayer.h"
Chris@0 19 #include "SpectrogramLayer.h"
Chris@0 20 #include "TimeRulerLayer.h"
Chris@0 21 #include "TimeInstantLayer.h"
Chris@0 22 #include "TimeValueLayer.h"
Chris@30 23 #include "NoteLayer.h"
matthiasm@621 24 #include "FlexiNoteLayer.h"
Chris@411 25 #include "RegionLayer.h"
Chris@35 26 #include "TextLayer.h"
Chris@303 27 #include "ImageLayer.h"
Chris@0 28 #include "Colour3DPlotLayer.h"
Chris@133 29 #include "SpectrumLayer.h"
Chris@193 30 #include "SliceLayer.h"
Chris@193 31 #include "SliceableLayer.h"
Chris@0 32
Chris@360 33 #include "base/Clipboard.h"
Chris@360 34
Chris@128 35 #include "data/model/RangeSummarisableTimeValueModel.h"
Chris@128 36 #include "data/model/DenseTimeValueModel.h"
Chris@128 37 #include "data/model/SparseOneDimensionalModel.h"
Chris@128 38 #include "data/model/SparseTimeValueModel.h"
Chris@128 39 #include "data/model/NoteModel.h"
matthiasm@621 40 #include "data/model/FlexiNoteModel.h"
Chris@411 41 #include "data/model/RegionModel.h"
Chris@128 42 #include "data/model/TextModel.h"
Chris@303 43 #include "data/model/ImageModel.h"
Chris@128 44 #include "data/model/DenseThreeDimensionalModel.h"
Chris@156 45 #include "data/model/WaveFileModel.h"
Chris@156 46 #include "data/model/WritableWaveFileModel.h"
Chris@0 47
Chris@326 48 #include <QDomDocument>
Chris@326 49 #include <QDomElement>
Chris@326 50 #include <QDomNamedNodeMap>
Chris@326 51 #include <QDomAttr>
Chris@326 52
Chris@326 53 #include <QSettings>
Chris@326 54
Chris@0 55 LayerFactory *
Chris@0 56 LayerFactory::m_instance = new LayerFactory;
Chris@0 57
Chris@0 58 LayerFactory *
Chris@125 59 LayerFactory::getInstance()
Chris@0 60 {
Chris@0 61 return m_instance;
Chris@0 62 }
Chris@0 63
Chris@0 64 LayerFactory::~LayerFactory()
Chris@0 65 {
Chris@0 66 }
Chris@0 67
Chris@0 68 QString
Chris@0 69 LayerFactory::getLayerPresentationName(LayerType type)
Chris@0 70 {
Chris@0 71 switch (type) {
Chris@0 72 case Waveform: return Layer::tr("Waveform");
Chris@0 73 case Spectrogram: return Layer::tr("Spectrogram");
Chris@0 74 case TimeRuler: return Layer::tr("Ruler");
Chris@0 75 case TimeInstants: return Layer::tr("Time Instants");
Chris@0 76 case TimeValues: return Layer::tr("Time Values");
Chris@30 77 case Notes: return Layer::tr("Notes");
gyorgyf@625 78 case FlexiNotes: return Layer::tr("Flexible Notes");
Chris@411 79 case Regions: return Layer::tr("Regions");
Chris@35 80 case Text: return Layer::tr("Text");
Chris@303 81 case Image: return Layer::tr("Images");
Chris@0 82 case Colour3DPlot: return Layer::tr("Colour 3D Plot");
Chris@133 83 case Spectrum: return Layer::tr("Spectrum");
Chris@193 84 case Slice: return Layer::tr("Time Slice");
Chris@0 85
Chris@0 86 case MelodicRangeSpectrogram:
Chris@0 87 // The user can change all the parameters of this after the
Chris@0 88 // fact -- there's nothing permanently melodic-range about it
Chris@0 89 // that should be encoded in its name
Chris@0 90 return Layer::tr("Spectrogram");
Chris@11 91
Chris@37 92 case PeakFrequencySpectrogram:
Chris@37 93 // likewise
Chris@37 94 return Layer::tr("Spectrogram");
Chris@37 95
Chris@805 96 case UnknownLayer:
Chris@805 97 default:
Chris@805 98 cerr << "WARNING: LayerFactory::getLayerPresentationName passed unknown layer" << endl;
Chris@805 99 return Layer::tr("Unknown Layer");
Chris@0 100 }
Chris@0 101 }
Chris@0 102
Chris@193 103 bool
Chris@193 104 LayerFactory::isLayerSliceable(const Layer *layer)
Chris@193 105 {
Chris@193 106 if (dynamic_cast<const SliceableLayer *>(layer)) {
Chris@193 107 if (dynamic_cast<const SpectrogramLayer *>(layer)) {
Chris@193 108
Chris@193 109 //!!! We can create slices of spectrograms, but there's a
Chris@193 110 // problem managing the models. The source model for the
Chris@193 111 // slice layer has to be one of the spectrogram's FFT
Chris@193 112 // models -- that's fine, except that we can't store &
Chris@193 113 // recall the slice layer with a reference to that model
Chris@193 114 // because the model is internal to the spectrogram layer
Chris@193 115 // and the document has no record of it. We would need
Chris@193 116 // some other way of managing models that are used in this
Chris@193 117 // way. For the moment we just don't allow slices of
Chris@193 118 // spectrograms -- and provide a spectrum layer for this
Chris@193 119 // instead.
Chris@193 120 //
Chris@193 121 // This business needs a bit more thought -- either come
Chris@193 122 // up with a sensible way to deal with that stuff, or
Chris@193 123 // simplify the existing slice layer logic so that it
Chris@193 124 // doesn't have to deal with models disappearing on it at
Chris@193 125 // all (and use the normal Document setModel mechanism to
Chris@193 126 // set its sliceable model instead of the fancy pants
Chris@193 127 // nonsense it's doing at the moment).
Chris@193 128
Chris@193 129 return false;
Chris@193 130 }
Chris@193 131 return true;
Chris@193 132 }
Chris@193 133 return false;
Chris@193 134 }
Chris@193 135
Chris@0 136 LayerFactory::LayerTypeSet
Chris@0 137 LayerFactory::getValidLayerTypes(Model *model)
Chris@0 138 {
Chris@0 139 LayerTypeSet types;
Chris@0 140
Chris@0 141 if (dynamic_cast<DenseThreeDimensionalModel *>(model)) {
Chris@0 142 types.insert(Colour3DPlot);
Chris@193 143 types.insert(Slice);
Chris@193 144 }
Chris@193 145
Chris@193 146 if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) {
Chris@193 147 types.insert(Waveform);
Chris@0 148 }
Chris@0 149
Chris@0 150 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@0 151 types.insert(Spectrogram);
Chris@0 152 types.insert(MelodicRangeSpectrogram);
Chris@37 153 types.insert(PeakFrequencySpectrogram);
Chris@0 154 }
Chris@0 155
Chris@0 156 if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
Chris@0 157 types.insert(TimeInstants);
Chris@0 158 }
Chris@0 159
Chris@0 160 if (dynamic_cast<SparseTimeValueModel *>(model)) {
Chris@0 161 types.insert(TimeValues);
Chris@411 162 }
Chris@411 163
Chris@35 164 if (dynamic_cast<NoteModel *>(model)) {
Chris@35 165 types.insert(Notes);
Chris@0 166 }
Chris@0 167
Chris@782 168 // NOTE: GF: types is a set, so order of insertion does not matter
matthiasm@621 169 if (dynamic_cast<FlexiNoteModel *>(model)) {
matthiasm@621 170 types.insert(FlexiNotes);
matthiasm@621 171 }
matthiasm@621 172
Chris@411 173 if (dynamic_cast<RegionModel *>(model)) {
Chris@411 174 types.insert(Regions);
Chris@411 175 }
Chris@411 176
Chris@35 177 if (dynamic_cast<TextModel *>(model)) {
Chris@35 178 types.insert(Text);
Chris@30 179 }
Chris@30 180
Chris@303 181 if (dynamic_cast<ImageModel *>(model)) {
Chris@303 182 types.insert(Image);
Chris@303 183 }
Chris@303 184
Chris@133 185 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@133 186 types.insert(Spectrum);
Chris@133 187 }
Chris@133 188
Chris@0 189 // We don't count TimeRuler here as it doesn't actually display
Chris@0 190 // the data, although it can be backed by any model
Chris@0 191
Chris@0 192 return types;
Chris@0 193 }
Chris@0 194
Chris@17 195 LayerFactory::LayerTypeSet
Chris@17 196 LayerFactory::getValidEmptyLayerTypes()
Chris@17 197 {
Chris@17 198 LayerTypeSet types;
Chris@17 199 types.insert(TimeInstants);
Chris@17 200 types.insert(TimeValues);
Chris@782 201 types.insert(FlexiNotes);
Chris@30 202 types.insert(Notes);
Chris@411 203 types.insert(Regions);
Chris@35 204 types.insert(Text);
Chris@303 205 types.insert(Image);
Chris@17 206 //!!! and in principle Colour3DPlot -- now that's a challenge
Chris@17 207 return types;
Chris@17 208 }
Chris@17 209
Chris@0 210 LayerFactory::LayerType
Chris@6 211 LayerFactory::getLayerType(const Layer *layer)
Chris@0 212 {
Chris@6 213 if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
Chris@6 214 if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
Chris@6 215 if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
Chris@6 216 if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
Chris@6 217 if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
Chris@782 218 if (dynamic_cast<const FlexiNoteLayer *>(layer)) return FlexiNotes;
Chris@30 219 if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
Chris@411 220 if (dynamic_cast<const RegionLayer *>(layer)) return Regions;
Chris@35 221 if (dynamic_cast<const TextLayer *>(layer)) return Text;
Chris@303 222 if (dynamic_cast<const ImageLayer *>(layer)) return Image;
Chris@6 223 if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
Chris@133 224 if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
Chris@193 225 if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
Chris@6 226 return UnknownLayer;
Chris@6 227 }
Chris@6 228
Chris@6 229 QString
Chris@17 230 LayerFactory::getLayerIconName(LayerType type)
Chris@17 231 {
Chris@17 232 switch (type) {
Chris@17 233 case Waveform: return "waveform";
Chris@17 234 case Spectrogram: return "spectrogram";
Chris@17 235 case TimeRuler: return "timeruler";
Chris@17 236 case TimeInstants: return "instants";
Chris@17 237 case TimeValues: return "values";
Chris@30 238 case Notes: return "notes";
Chris@782 239 case FlexiNotes: return "flexinotes";
Chris@411 240 case Regions: return "regions";
Chris@35 241 case Text: return "text";
Chris@303 242 case Image: return "image";
Chris@17 243 case Colour3DPlot: return "colour3d";
Chris@133 244 case Spectrum: return "spectrum";
Chris@193 245 case Slice: return "spectrum";
Chris@326 246 case MelodicRangeSpectrogram: return "spectrogram";
Chris@326 247 case PeakFrequencySpectrogram: return "spectrogram";
Chris@805 248 case UnknownLayer:
Chris@805 249 default:
Chris@805 250 cerr << "WARNING: LayerFactory::getLayerIconName passed unknown layer" << endl;
Chris@805 251 return "unknown";
Chris@17 252 }
Chris@17 253 }
Chris@17 254
Chris@17 255 QString
Chris@6 256 LayerFactory::getLayerTypeName(LayerType type)
Chris@6 257 {
Chris@6 258 switch (type) {
Chris@6 259 case Waveform: return "waveform";
Chris@6 260 case Spectrogram: return "spectrogram";
Chris@6 261 case TimeRuler: return "timeruler";
Chris@6 262 case TimeInstants: return "timeinstants";
Chris@6 263 case TimeValues: return "timevalues";
Chris@30 264 case Notes: return "notes";
matthiasm@623 265 case FlexiNotes: return "flexinotes";
Chris@411 266 case Regions: return "regions";
Chris@35 267 case Text: return "text";
Chris@303 268 case Image: return "image";
Chris@6 269 case Colour3DPlot: return "colour3dplot";
Chris@133 270 case Spectrum: return "spectrum";
Chris@193 271 case Slice: return "slice";
Chris@326 272 case MelodicRangeSpectrogram: return "melodicrange";
Chris@326 273 case PeakFrequencySpectrogram: return "peakfrequency";
Chris@805 274 case UnknownLayer:
Chris@805 275 default:
Chris@805 276 cerr << "WARNING: LayerFactory::getLayerTypeName passed unknown layer" << endl;
Chris@805 277 return "unknown";
Chris@6 278 }
Chris@6 279 }
Chris@6 280
Chris@6 281 LayerFactory::LayerType
Chris@6 282 LayerFactory::getLayerTypeForName(QString name)
Chris@6 283 {
Chris@6 284 if (name == "waveform") return Waveform;
Chris@6 285 if (name == "spectrogram") return Spectrogram;
Chris@6 286 if (name == "timeruler") return TimeRuler;
Chris@6 287 if (name == "timeinstants") return TimeInstants;
Chris@6 288 if (name == "timevalues") return TimeValues;
matthiasm@623 289 if (name == "flexinotes") return FlexiNotes;
Chris@411 290 if (name == "regions") return Regions;
Chris@35 291 if (name == "text") return Text;
Chris@303 292 if (name == "image") return Image;
Chris@6 293 if (name == "colour3dplot") return Colour3DPlot;
Chris@133 294 if (name == "spectrum") return Spectrum;
Chris@193 295 if (name == "slice") return Slice;
Chris@0 296 return UnknownLayer;
Chris@0 297 }
Chris@0 298
Chris@0 299 void
Chris@0 300 LayerFactory::setModel(Layer *layer, Model *model)
Chris@0 301 {
Chris@156 302 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
Chris@156 303 // return;
gyorgyf@625 304
Chris@156 305 if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
Chris@156 306 return;
Chris@156 307
Chris@156 308 if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
Chris@0 309 return;
Chris@0 310
Chris@0 311 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@0 312 return;
Chris@0 313
Chris@0 314 if (trySetModel<TimeRulerLayer, Model>(layer, model))
Chris@0 315 return;
Chris@0 316
Chris@0 317 if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
Chris@0 318 return;
Chris@0 319
Chris@0 320 if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
Chris@0 321 return;
Chris@0 322
gyorgyf@626 323 if (trySetModel<NoteLayer, NoteModel>(layer, model))
gyorgyf@626 324 return;
Chris@30 325
Chris@782 326 // GF: added FlexiNoteLayer
gyorgyf@626 327 if (trySetModel<FlexiNoteLayer, FlexiNoteModel>(layer, model))
gyorgyf@626 328 return;
gyorgyf@625 329
Chris@411 330 if (trySetModel<RegionLayer, RegionModel>(layer, model))
Chris@411 331 return;
Chris@411 332
Chris@35 333 if (trySetModel<TextLayer, TextModel>(layer, model))
Chris@35 334 return;
Chris@35 335
Chris@303 336 if (trySetModel<ImageLayer, ImageModel>(layer, model))
Chris@303 337 return;
Chris@303 338
Chris@0 339 if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
Chris@0 340 return;
Chris@0 341
Chris@0 342 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@0 343 return;
Chris@133 344
Chris@133 345 if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model))
Chris@133 346 return;
Chris@193 347
Chris@193 348 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model))
Chris@193 349 // return;
Chris@0 350 }
Chris@0 351
Chris@17 352 Model *
Chris@17 353 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
Chris@17 354 {
Chris@17 355 if (layerType == TimeInstants) {
Chris@17 356 return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
Chris@17 357 } else if (layerType == TimeValues) {
Chris@245 358 return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
Chris@782 359 } else if (layerType == FlexiNotes) {
matthiasm@623 360 return new FlexiNoteModel(baseModel->getSampleRate(), 1, true);
Chris@30 361 } else if (layerType == Notes) {
Chris@245 362 return new NoteModel(baseModel->getSampleRate(), 1, true);
Chris@411 363 } else if (layerType == Regions) {
Chris@411 364 return new RegionModel(baseModel->getSampleRate(), 1, true);
Chris@35 365 } else if (layerType == Text) {
Chris@35 366 return new TextModel(baseModel->getSampleRate(), 1, true);
Chris@303 367 } else if (layerType == Image) {
Chris@303 368 return new ImageModel(baseModel->getSampleRate(), 1, true);
Chris@17 369 } else {
Chris@17 370 return 0;
Chris@17 371 }
Chris@17 372 }
Chris@17 373
Chris@53 374 int
Chris@53 375 LayerFactory::getChannel(Layer *layer)
Chris@53 376 {
Chris@53 377 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@53 378 return dynamic_cast<WaveformLayer *>(layer)->getChannel();
Chris@53 379 }
Chris@53 380 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@53 381 return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
Chris@53 382 }
Chris@53 383 return -1;
Chris@53 384 }
Chris@53 385
Chris@53 386 void
Chris@53 387 LayerFactory::setChannel(Layer *layer, int channel)
Chris@53 388 {
Chris@53 389 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@53 390 dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
Chris@53 391 return;
Chris@53 392 }
Chris@53 393 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@53 394 dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
Chris@53 395 return;
Chris@53 396 }
Chris@349 397 if (dynamic_cast<SpectrumLayer *>(layer)) {
Chris@349 398 dynamic_cast<SpectrumLayer *>(layer)->setChannel(channel);
Chris@349 399 return;
Chris@349 400 }
Chris@53 401 }
Chris@53 402
Chris@0 403 Layer *
Chris@53 404 LayerFactory::createLayer(LayerType type)
Chris@0 405 {
Chris@0 406 Layer *layer = 0;
Chris@0 407
Chris@0 408 switch (type) {
Chris@0 409
Chris@0 410 case Waveform:
Chris@44 411 layer = new WaveformLayer;
Chris@0 412 break;
Chris@0 413
Chris@0 414 case Spectrogram:
Chris@44 415 layer = new SpectrogramLayer;
Chris@0 416 break;
Chris@0 417
Chris@0 418 case TimeRuler:
Chris@44 419 layer = new TimeRulerLayer;
Chris@0 420 break;
Chris@0 421
Chris@0 422 case TimeInstants:
Chris@44 423 layer = new TimeInstantLayer;
Chris@0 424 break;
Chris@0 425
Chris@0 426 case TimeValues:
Chris@44 427 layer = new TimeValueLayer;
Chris@0 428 break;
Chris@0 429
matthiasm@623 430 case FlexiNotes:
matthiasm@623 431 layer = new FlexiNoteLayer;
matthiasm@623 432 break;
matthiasm@623 433
Chris@30 434 case Notes:
Chris@44 435 layer = new NoteLayer;
Chris@30 436 break;
Chris@30 437
Chris@411 438 case Regions:
Chris@411 439 layer = new RegionLayer;
Chris@411 440 break;
Chris@411 441
Chris@35 442 case Text:
Chris@44 443 layer = new TextLayer;
Chris@35 444 break;
Chris@35 445
Chris@303 446 case Image:
Chris@303 447 layer = new ImageLayer;
Chris@303 448 break;
Chris@303 449
Chris@0 450 case Colour3DPlot:
Chris@44 451 layer = new Colour3DPlotLayer;
Chris@0 452 break;
Chris@0 453
Chris@133 454 case Spectrum:
Chris@133 455 layer = new SpectrumLayer;
Chris@133 456 break;
Chris@133 457
Chris@193 458 case Slice:
Chris@193 459 layer = new SliceLayer;
Chris@193 460 break;
Chris@193 461
Chris@0 462 case MelodicRangeSpectrogram:
Chris@44 463 layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange);
Chris@0 464 break;
Chris@11 465
Chris@37 466 case PeakFrequencySpectrogram:
Chris@44 467 layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks);
Chris@37 468 break;
Chris@37 469
Chris@805 470 case UnknownLayer:
Chris@805 471 default:
Chris@805 472 cerr << "WARNING: LayerFactory::createLayer passed unknown layer" << endl;
Chris@805 473 break;
Chris@0 474 }
Chris@0 475
Chris@0 476 if (!layer) {
Chris@805 477 cerr << "LayerFactory::createLayer: Unknown layer type "
Chris@585 478 << type << endl;
Chris@0 479 } else {
Chris@587 480 // SVDEBUG << "LayerFactory::createLayer: Setting object name "
Chris@585 481 // << getLayerPresentationName(type) << " on " << layer << endl;
Chris@0 482 layer->setObjectName(getLayerPresentationName(type));
Chris@326 483 setLayerDefaultProperties(type, layer);
Chris@0 484 }
Chris@0 485
Chris@0 486 return layer;
Chris@0 487 }
Chris@0 488
Chris@326 489 void
Chris@326 490 LayerFactory::setLayerDefaultProperties(LayerType type, Layer *layer)
Chris@326 491 {
Chris@587 492 // SVDEBUG << "LayerFactory::setLayerDefaultProperties: type " << type << " (name \"" << getLayerTypeName(type) << "\")" << endl;
Chris@327 493
Chris@326 494 QSettings settings;
Chris@326 495 settings.beginGroup("LayerDefaults");
Chris@326 496 QString defaults = settings.value(getLayerTypeName(type), "").toString();
Chris@326 497 if (defaults == "") return;
Chris@326 498
Chris@682 499 // cerr << "defaults=\"" << defaults << "\"" << endl;
Chris@327 500
Chris@326 501 QString xml = layer->toXmlString();
Chris@326 502 QDomDocument docOld, docNew;
Chris@326 503
Chris@326 504 if (docOld.setContent(xml, false) &&
Chris@326 505 docNew.setContent(defaults, false)) {
Chris@326 506
Chris@326 507 QXmlAttributes attrs;
Chris@326 508
Chris@326 509 QDomElement layerElt = docNew.firstChildElement("layer");
Chris@326 510 QDomNamedNodeMap attrNodes = layerElt.attributes();
Chris@326 511
Chris@805 512 for (int i = 0; i < attrNodes.length(); ++i) {
Chris@326 513 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@326 514 if (attr.isNull()) continue;
Chris@683 515 // cerr << "append \"" << attr.name()
Chris@584 516 // << "\" -> \"" << attr.value() << "\""
Chris@682 517 // << endl;
Chris@326 518 attrs.append(attr.name(), "", "", attr.value());
Chris@326 519 }
Chris@326 520
Chris@326 521 layerElt = docOld.firstChildElement("layer");
Chris@326 522 attrNodes = layerElt.attributes();
Chris@805 523 for (int i = 0; i < attrNodes.length(); ++i) {
Chris@326 524 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@326 525 if (attr.isNull()) continue;
Chris@326 526 if (attrs.value(attr.name()) == "") {
Chris@683 527 // cerr << "append \"" << attr.name()
Chris@584 528 // << "\" -> \"" << attr.value() << "\""
Chris@682 529 // << endl;
Chris@326 530 attrs.append(attr.name(), "", "", attr.value());
Chris@326 531 }
Chris@326 532 }
Chris@326 533
Chris@326 534 layer->setProperties(attrs);
Chris@326 535 }
Chris@326 536
Chris@326 537 settings.endGroup();
Chris@326 538 }
Chris@326 539
Chris@360 540 LayerFactory::LayerType
Chris@360 541 LayerFactory::getLayerTypeForClipboardContents(const Clipboard &clip)
Chris@360 542 {
Chris@360 543 const Clipboard::PointList &contents = clip.getPoints();
Chris@360 544
Chris@360 545 bool haveFrame = false;
Chris@360 546 bool haveValue = false;
Chris@360 547 bool haveDuration = false;
Chris@411 548 bool haveLevel = false;
Chris@360 549
Chris@360 550 for (Clipboard::PointList::const_iterator i = contents.begin();
Chris@360 551 i != contents.end(); ++i) {
Chris@360 552 if (i->haveFrame()) haveFrame = true;
Chris@360 553 if (i->haveValue()) haveValue = true;
Chris@360 554 if (i->haveDuration()) haveDuration = true;
Chris@411 555 if (i->haveLevel()) haveLevel = true;
Chris@360 556 }
Chris@360 557
Chris@411 558 if (haveFrame && haveValue && haveDuration && haveLevel) return Notes;
Chris@411 559 if (haveFrame && haveValue && haveDuration) return Regions;
Chris@360 560 if (haveFrame && haveValue) return TimeValues;
Chris@360 561 return TimeInstants;
Chris@360 562 }
Chris@360 563