annotate layer/LayerFactory.cpp @ 789:9fd1bdf214dd tonioni

Play pointer: when user drags pane during playback such that the pointer is no longer visible, accept that and stop trying to track it until pointer naturally comes back within visible area
author Chris Cannam
date Thu, 12 Jun 2014 12:48:11 +0100
parents ddae586bc47b
children 1d526ba11a24
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@11 96 default: break;
Chris@0 97 }
Chris@0 98
Chris@0 99 return Layer::tr("Layer");
Chris@0 100 }
Chris@0 101
Chris@193 102 bool
Chris@193 103 LayerFactory::isLayerSliceable(const Layer *layer)
Chris@193 104 {
Chris@193 105 if (dynamic_cast<const SliceableLayer *>(layer)) {
Chris@193 106 if (dynamic_cast<const SpectrogramLayer *>(layer)) {
Chris@193 107
Chris@193 108 //!!! We can create slices of spectrograms, but there's a
Chris@193 109 // problem managing the models. The source model for the
Chris@193 110 // slice layer has to be one of the spectrogram's FFT
Chris@193 111 // models -- that's fine, except that we can't store &
Chris@193 112 // recall the slice layer with a reference to that model
Chris@193 113 // because the model is internal to the spectrogram layer
Chris@193 114 // and the document has no record of it. We would need
Chris@193 115 // some other way of managing models that are used in this
Chris@193 116 // way. For the moment we just don't allow slices of
Chris@193 117 // spectrograms -- and provide a spectrum layer for this
Chris@193 118 // instead.
Chris@193 119 //
Chris@193 120 // This business needs a bit more thought -- either come
Chris@193 121 // up with a sensible way to deal with that stuff, or
Chris@193 122 // simplify the existing slice layer logic so that it
Chris@193 123 // doesn't have to deal with models disappearing on it at
Chris@193 124 // all (and use the normal Document setModel mechanism to
Chris@193 125 // set its sliceable model instead of the fancy pants
Chris@193 126 // nonsense it's doing at the moment).
Chris@193 127
Chris@193 128 return false;
Chris@193 129 }
Chris@193 130 return true;
Chris@193 131 }
Chris@193 132 return false;
Chris@193 133 }
Chris@193 134
Chris@0 135 LayerFactory::LayerTypeSet
Chris@0 136 LayerFactory::getValidLayerTypes(Model *model)
Chris@0 137 {
Chris@0 138 LayerTypeSet types;
Chris@0 139
Chris@0 140 if (dynamic_cast<DenseThreeDimensionalModel *>(model)) {
Chris@0 141 types.insert(Colour3DPlot);
Chris@193 142 types.insert(Slice);
Chris@193 143 }
Chris@193 144
Chris@193 145 if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) {
Chris@193 146 types.insert(Waveform);
Chris@0 147 }
Chris@0 148
Chris@0 149 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@0 150 types.insert(Spectrogram);
Chris@0 151 types.insert(MelodicRangeSpectrogram);
Chris@37 152 types.insert(PeakFrequencySpectrogram);
Chris@0 153 }
Chris@0 154
Chris@0 155 if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
Chris@0 156 types.insert(TimeInstants);
Chris@0 157 }
Chris@0 158
Chris@0 159 if (dynamic_cast<SparseTimeValueModel *>(model)) {
Chris@0 160 types.insert(TimeValues);
Chris@411 161 }
Chris@411 162
Chris@35 163 if (dynamic_cast<NoteModel *>(model)) {
Chris@35 164 types.insert(Notes);
Chris@0 165 }
Chris@0 166
Chris@782 167 // NOTE: GF: types is a set, so order of insertion does not matter
matthiasm@621 168 if (dynamic_cast<FlexiNoteModel *>(model)) {
matthiasm@621 169 types.insert(FlexiNotes);
matthiasm@621 170 }
matthiasm@621 171
Chris@411 172 if (dynamic_cast<RegionModel *>(model)) {
Chris@411 173 types.insert(Regions);
Chris@411 174 }
Chris@411 175
Chris@35 176 if (dynamic_cast<TextModel *>(model)) {
Chris@35 177 types.insert(Text);
Chris@30 178 }
Chris@30 179
Chris@303 180 if (dynamic_cast<ImageModel *>(model)) {
Chris@303 181 types.insert(Image);
Chris@303 182 }
Chris@303 183
Chris@133 184 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@133 185 types.insert(Spectrum);
Chris@133 186 }
Chris@133 187
Chris@0 188 // We don't count TimeRuler here as it doesn't actually display
Chris@0 189 // the data, although it can be backed by any model
Chris@0 190
Chris@0 191 return types;
Chris@0 192 }
Chris@0 193
Chris@17 194 LayerFactory::LayerTypeSet
Chris@17 195 LayerFactory::getValidEmptyLayerTypes()
Chris@17 196 {
Chris@17 197 LayerTypeSet types;
Chris@17 198 types.insert(TimeInstants);
Chris@17 199 types.insert(TimeValues);
Chris@782 200 types.insert(FlexiNotes);
Chris@30 201 types.insert(Notes);
Chris@411 202 types.insert(Regions);
Chris@35 203 types.insert(Text);
Chris@303 204 types.insert(Image);
Chris@17 205 //!!! and in principle Colour3DPlot -- now that's a challenge
Chris@17 206 return types;
Chris@17 207 }
Chris@17 208
Chris@0 209 LayerFactory::LayerType
Chris@6 210 LayerFactory::getLayerType(const Layer *layer)
Chris@0 211 {
Chris@6 212 if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
Chris@6 213 if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
Chris@6 214 if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
Chris@6 215 if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
Chris@6 216 if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
Chris@782 217 if (dynamic_cast<const FlexiNoteLayer *>(layer)) return FlexiNotes;
Chris@30 218 if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
Chris@411 219 if (dynamic_cast<const RegionLayer *>(layer)) return Regions;
Chris@35 220 if (dynamic_cast<const TextLayer *>(layer)) return Text;
Chris@303 221 if (dynamic_cast<const ImageLayer *>(layer)) return Image;
Chris@6 222 if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
Chris@133 223 if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
Chris@193 224 if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
Chris@6 225 return UnknownLayer;
Chris@6 226 }
Chris@6 227
Chris@6 228 QString
Chris@17 229 LayerFactory::getLayerIconName(LayerType type)
Chris@17 230 {
Chris@17 231 switch (type) {
Chris@17 232 case Waveform: return "waveform";
Chris@17 233 case Spectrogram: return "spectrogram";
Chris@17 234 case TimeRuler: return "timeruler";
Chris@17 235 case TimeInstants: return "instants";
Chris@17 236 case TimeValues: return "values";
Chris@30 237 case Notes: return "notes";
Chris@782 238 case FlexiNotes: return "flexinotes";
Chris@411 239 case Regions: return "regions";
Chris@35 240 case Text: return "text";
Chris@303 241 case Image: return "image";
Chris@17 242 case Colour3DPlot: return "colour3d";
Chris@133 243 case Spectrum: return "spectrum";
Chris@193 244 case Slice: return "spectrum";
Chris@326 245 case MelodicRangeSpectrogram: return "spectrogram";
Chris@326 246 case PeakFrequencySpectrogram: return "spectrogram";
Chris@17 247 default: return "unknown";
Chris@17 248 }
Chris@17 249 }
Chris@17 250
Chris@17 251 QString
Chris@6 252 LayerFactory::getLayerTypeName(LayerType type)
Chris@6 253 {
Chris@6 254 switch (type) {
Chris@6 255 case Waveform: return "waveform";
Chris@6 256 case Spectrogram: return "spectrogram";
Chris@6 257 case TimeRuler: return "timeruler";
Chris@6 258 case TimeInstants: return "timeinstants";
Chris@6 259 case TimeValues: return "timevalues";
Chris@30 260 case Notes: return "notes";
matthiasm@623 261 case FlexiNotes: return "flexinotes";
Chris@411 262 case Regions: return "regions";
Chris@35 263 case Text: return "text";
Chris@303 264 case Image: return "image";
Chris@6 265 case Colour3DPlot: return "colour3dplot";
Chris@133 266 case Spectrum: return "spectrum";
Chris@193 267 case Slice: return "slice";
Chris@326 268 case MelodicRangeSpectrogram: return "melodicrange";
Chris@326 269 case PeakFrequencySpectrogram: return "peakfrequency";
Chris@6 270 default: return "unknown";
Chris@6 271 }
Chris@6 272 }
Chris@6 273
Chris@6 274 LayerFactory::LayerType
Chris@6 275 LayerFactory::getLayerTypeForName(QString name)
Chris@6 276 {
Chris@6 277 if (name == "waveform") return Waveform;
Chris@6 278 if (name == "spectrogram") return Spectrogram;
Chris@6 279 if (name == "timeruler") return TimeRuler;
Chris@6 280 if (name == "timeinstants") return TimeInstants;
Chris@6 281 if (name == "timevalues") return TimeValues;
matthiasm@623 282 if (name == "flexinotes") return FlexiNotes;
Chris@411 283 if (name == "regions") return Regions;
Chris@35 284 if (name == "text") return Text;
Chris@303 285 if (name == "image") return Image;
Chris@6 286 if (name == "colour3dplot") return Colour3DPlot;
Chris@133 287 if (name == "spectrum") return Spectrum;
Chris@193 288 if (name == "slice") return Slice;
Chris@0 289 return UnknownLayer;
Chris@0 290 }
Chris@0 291
Chris@0 292 void
Chris@0 293 LayerFactory::setModel(Layer *layer, Model *model)
Chris@0 294 {
Chris@156 295 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
Chris@156 296 // return;
gyorgyf@625 297
Chris@156 298 if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
Chris@156 299 return;
Chris@156 300
Chris@156 301 if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
Chris@0 302 return;
Chris@0 303
Chris@0 304 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@0 305 return;
Chris@0 306
Chris@0 307 if (trySetModel<TimeRulerLayer, Model>(layer, model))
Chris@0 308 return;
Chris@0 309
Chris@0 310 if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
Chris@0 311 return;
Chris@0 312
Chris@0 313 if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
Chris@0 314 return;
Chris@0 315
gyorgyf@626 316 if (trySetModel<NoteLayer, NoteModel>(layer, model))
gyorgyf@626 317 return;
Chris@30 318
Chris@782 319 // GF: added FlexiNoteLayer
gyorgyf@626 320 if (trySetModel<FlexiNoteLayer, FlexiNoteModel>(layer, model))
gyorgyf@626 321 return;
gyorgyf@625 322
Chris@411 323 if (trySetModel<RegionLayer, RegionModel>(layer, model))
Chris@411 324 return;
Chris@411 325
Chris@35 326 if (trySetModel<TextLayer, TextModel>(layer, model))
Chris@35 327 return;
Chris@35 328
Chris@303 329 if (trySetModel<ImageLayer, ImageModel>(layer, model))
Chris@303 330 return;
Chris@303 331
Chris@0 332 if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
Chris@0 333 return;
Chris@0 334
Chris@0 335 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@0 336 return;
Chris@133 337
Chris@133 338 if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model))
Chris@133 339 return;
Chris@193 340
Chris@193 341 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model))
Chris@193 342 // return;
Chris@0 343 }
Chris@0 344
Chris@17 345 Model *
Chris@17 346 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
Chris@17 347 {
Chris@17 348 if (layerType == TimeInstants) {
Chris@17 349 return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
Chris@17 350 } else if (layerType == TimeValues) {
Chris@245 351 return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
Chris@782 352 } else if (layerType == FlexiNotes) {
matthiasm@623 353 return new FlexiNoteModel(baseModel->getSampleRate(), 1, true);
Chris@30 354 } else if (layerType == Notes) {
Chris@245 355 return new NoteModel(baseModel->getSampleRate(), 1, true);
Chris@411 356 } else if (layerType == Regions) {
Chris@411 357 return new RegionModel(baseModel->getSampleRate(), 1, true);
Chris@35 358 } else if (layerType == Text) {
Chris@35 359 return new TextModel(baseModel->getSampleRate(), 1, true);
Chris@303 360 } else if (layerType == Image) {
Chris@303 361 return new ImageModel(baseModel->getSampleRate(), 1, true);
Chris@17 362 } else {
Chris@17 363 return 0;
Chris@17 364 }
Chris@17 365 }
Chris@17 366
Chris@53 367 int
Chris@53 368 LayerFactory::getChannel(Layer *layer)
Chris@53 369 {
Chris@53 370 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@53 371 return dynamic_cast<WaveformLayer *>(layer)->getChannel();
Chris@53 372 }
Chris@53 373 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@53 374 return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
Chris@53 375 }
Chris@53 376 return -1;
Chris@53 377 }
Chris@53 378
Chris@53 379 void
Chris@53 380 LayerFactory::setChannel(Layer *layer, int channel)
Chris@53 381 {
Chris@53 382 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@53 383 dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
Chris@53 384 return;
Chris@53 385 }
Chris@53 386 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@53 387 dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
Chris@53 388 return;
Chris@53 389 }
Chris@349 390 if (dynamic_cast<SpectrumLayer *>(layer)) {
Chris@349 391 dynamic_cast<SpectrumLayer *>(layer)->setChannel(channel);
Chris@349 392 return;
Chris@349 393 }
Chris@53 394 }
Chris@53 395
Chris@0 396 Layer *
Chris@53 397 LayerFactory::createLayer(LayerType type)
Chris@0 398 {
Chris@0 399 Layer *layer = 0;
Chris@0 400
Chris@0 401 switch (type) {
Chris@0 402
Chris@0 403 case Waveform:
Chris@44 404 layer = new WaveformLayer;
Chris@0 405 break;
Chris@0 406
Chris@0 407 case Spectrogram:
Chris@44 408 layer = new SpectrogramLayer;
Chris@0 409 break;
Chris@0 410
Chris@0 411 case TimeRuler:
Chris@44 412 layer = new TimeRulerLayer;
Chris@0 413 break;
Chris@0 414
Chris@0 415 case TimeInstants:
Chris@44 416 layer = new TimeInstantLayer;
Chris@0 417 break;
Chris@0 418
Chris@0 419 case TimeValues:
Chris@44 420 layer = new TimeValueLayer;
Chris@0 421 break;
Chris@0 422
matthiasm@623 423 case FlexiNotes:
matthiasm@623 424 layer = new FlexiNoteLayer;
matthiasm@623 425 break;
matthiasm@623 426
Chris@30 427 case Notes:
Chris@44 428 layer = new NoteLayer;
Chris@30 429 break;
Chris@30 430
Chris@411 431 case Regions:
Chris@411 432 layer = new RegionLayer;
Chris@411 433 break;
Chris@411 434
Chris@35 435 case Text:
Chris@44 436 layer = new TextLayer;
Chris@35 437 break;
Chris@35 438
Chris@303 439 case Image:
Chris@303 440 layer = new ImageLayer;
Chris@303 441 break;
Chris@303 442
Chris@0 443 case Colour3DPlot:
Chris@44 444 layer = new Colour3DPlotLayer;
Chris@0 445 break;
Chris@0 446
Chris@133 447 case Spectrum:
Chris@133 448 layer = new SpectrumLayer;
Chris@133 449 break;
Chris@133 450
Chris@193 451 case Slice:
Chris@193 452 layer = new SliceLayer;
Chris@193 453 break;
Chris@193 454
Chris@0 455 case MelodicRangeSpectrogram:
Chris@44 456 layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange);
Chris@0 457 break;
Chris@11 458
Chris@37 459 case PeakFrequencySpectrogram:
Chris@44 460 layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks);
Chris@37 461 break;
Chris@37 462
Chris@11 463 default: break;
Chris@0 464 }
Chris@0 465
Chris@0 466 if (!layer) {
Chris@587 467 SVDEBUG << "LayerFactory::createLayer: Unknown layer type "
Chris@585 468 << type << endl;
Chris@0 469 } else {
Chris@587 470 // SVDEBUG << "LayerFactory::createLayer: Setting object name "
Chris@585 471 // << getLayerPresentationName(type) << " on " << layer << endl;
Chris@0 472 layer->setObjectName(getLayerPresentationName(type));
Chris@326 473 setLayerDefaultProperties(type, layer);
Chris@0 474 }
Chris@0 475
Chris@0 476 return layer;
Chris@0 477 }
Chris@0 478
Chris@326 479 void
Chris@326 480 LayerFactory::setLayerDefaultProperties(LayerType type, Layer *layer)
Chris@326 481 {
Chris@587 482 // SVDEBUG << "LayerFactory::setLayerDefaultProperties: type " << type << " (name \"" << getLayerTypeName(type) << "\")" << endl;
Chris@327 483
Chris@326 484 QSettings settings;
Chris@326 485 settings.beginGroup("LayerDefaults");
Chris@326 486 QString defaults = settings.value(getLayerTypeName(type), "").toString();
Chris@326 487 if (defaults == "") return;
Chris@326 488
Chris@682 489 // cerr << "defaults=\"" << defaults << "\"" << endl;
Chris@327 490
Chris@326 491 QString xml = layer->toXmlString();
Chris@326 492 QDomDocument docOld, docNew;
Chris@326 493
Chris@326 494 if (docOld.setContent(xml, false) &&
Chris@326 495 docNew.setContent(defaults, false)) {
Chris@326 496
Chris@326 497 QXmlAttributes attrs;
Chris@326 498
Chris@326 499 QDomElement layerElt = docNew.firstChildElement("layer");
Chris@326 500 QDomNamedNodeMap attrNodes = layerElt.attributes();
Chris@326 501
Chris@326 502 for (unsigned int i = 0; i < attrNodes.length(); ++i) {
Chris@326 503 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@326 504 if (attr.isNull()) continue;
Chris@683 505 // cerr << "append \"" << attr.name()
Chris@584 506 // << "\" -> \"" << attr.value() << "\""
Chris@682 507 // << endl;
Chris@326 508 attrs.append(attr.name(), "", "", attr.value());
Chris@326 509 }
Chris@326 510
Chris@326 511 layerElt = docOld.firstChildElement("layer");
Chris@326 512 attrNodes = layerElt.attributes();
Chris@326 513 for (unsigned int i = 0; i < attrNodes.length(); ++i) {
Chris@326 514 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@326 515 if (attr.isNull()) continue;
Chris@326 516 if (attrs.value(attr.name()) == "") {
Chris@683 517 // cerr << "append \"" << attr.name()
Chris@584 518 // << "\" -> \"" << attr.value() << "\""
Chris@682 519 // << endl;
Chris@326 520 attrs.append(attr.name(), "", "", attr.value());
Chris@326 521 }
Chris@326 522 }
Chris@326 523
Chris@326 524 layer->setProperties(attrs);
Chris@326 525 }
Chris@326 526
Chris@326 527 settings.endGroup();
Chris@326 528 }
Chris@326 529
Chris@360 530 LayerFactory::LayerType
Chris@360 531 LayerFactory::getLayerTypeForClipboardContents(const Clipboard &clip)
Chris@360 532 {
Chris@360 533 const Clipboard::PointList &contents = clip.getPoints();
Chris@360 534
Chris@360 535 bool haveFrame = false;
Chris@360 536 bool haveValue = false;
Chris@360 537 bool haveDuration = false;
Chris@411 538 bool haveLevel = false;
Chris@360 539
Chris@360 540 for (Clipboard::PointList::const_iterator i = contents.begin();
Chris@360 541 i != contents.end(); ++i) {
Chris@360 542 if (i->haveFrame()) haveFrame = true;
Chris@360 543 if (i->haveValue()) haveValue = true;
Chris@360 544 if (i->haveDuration()) haveDuration = true;
Chris@411 545 if (i->haveLevel()) haveLevel = true;
Chris@360 546 }
Chris@360 547
Chris@411 548 if (haveFrame && haveValue && haveDuration && haveLevel) return Notes;
Chris@411 549 if (haveFrame && haveValue && haveDuration) return Regions;
Chris@360 550 if (haveFrame && haveValue) return TimeValues;
Chris@360 551 return TimeInstants;
Chris@360 552 }
Chris@360 553