annotate layer/LayerFactory.cpp @ 1386:fc3d89f88690 spectrogramparam

Use log-frequency rather than log-bin for calculating x coord in spectrum. This has the advantage that frequency positions don't move when we change the window size or oversampling ratio, but it does give us an unhelpfully large amount of space for very low frequencies - to be considered
author Chris Cannam
date Mon, 12 Nov 2018 11:34:34 +0000
parents a34a2a25907c
children c8a6fd3f9dff
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@1266 87 // The user can change all the parameters of this after the
Chris@1266 88 // fact -- there's nothing permanently melodic-range about it
Chris@1266 89 // that should be encoded in its name
Chris@1266 90 return Layer::tr("Spectrogram");
Chris@11 91
Chris@37 92 case PeakFrequencySpectrogram:
Chris@1266 93 // likewise
Chris@1266 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@1266 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@1266 147 types.insert(Waveform);
Chris@0 148 }
Chris@0 149
Chris@0 150 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@1266 151 types.insert(Spectrogram);
Chris@1266 152 types.insert(MelodicRangeSpectrogram);
Chris@1266 153 types.insert(PeakFrequencySpectrogram);
Chris@0 154 }
Chris@0 155
Chris@0 156 if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
Chris@1266 157 types.insert(TimeInstants);
Chris@0 158 }
Chris@0 159
Chris@0 160 if (dynamic_cast<SparseTimeValueModel *>(model)) {
Chris@1266 161 types.insert(TimeValues);
Chris@411 162 }
Chris@411 163
Chris@35 164 if (dynamic_cast<NoteModel *>(model)) {
Chris@1266 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)) {
Chris@1266 170 types.insert(FlexiNotes);
matthiasm@621 171 }
matthiasm@621 172
Chris@411 173 if (dynamic_cast<RegionModel *>(model)) {
Chris@1266 174 types.insert(Regions);
Chris@411 175 }
Chris@411 176
Chris@35 177 if (dynamic_cast<TextModel *>(model)) {
Chris@1266 178 types.insert(Text);
Chris@30 179 }
Chris@30 180
Chris@303 181 if (dynamic_cast<ImageModel *>(model)) {
Chris@1266 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@962 201 // Because this is strictly a UI function -- list the layer types
Chris@962 202 // to show in a menu -- it should not contain FlexiNotes; the
Chris@962 203 // layer isn't meaningfully editable in SV
Chris@962 204 // types.insert(FlexiNotes);
Chris@30 205 types.insert(Notes);
Chris@411 206 types.insert(Regions);
Chris@35 207 types.insert(Text);
Chris@303 208 types.insert(Image);
Chris@17 209 //!!! and in principle Colour3DPlot -- now that's a challenge
Chris@17 210 return types;
Chris@17 211 }
Chris@17 212
Chris@0 213 LayerFactory::LayerType
Chris@6 214 LayerFactory::getLayerType(const Layer *layer)
Chris@0 215 {
Chris@6 216 if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
Chris@6 217 if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
Chris@6 218 if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
Chris@6 219 if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
Chris@6 220 if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
Chris@782 221 if (dynamic_cast<const FlexiNoteLayer *>(layer)) return FlexiNotes;
Chris@30 222 if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
Chris@411 223 if (dynamic_cast<const RegionLayer *>(layer)) return Regions;
Chris@35 224 if (dynamic_cast<const TextLayer *>(layer)) return Text;
Chris@303 225 if (dynamic_cast<const ImageLayer *>(layer)) return Image;
Chris@6 226 if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
Chris@133 227 if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
Chris@193 228 if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
Chris@6 229 return UnknownLayer;
Chris@6 230 }
Chris@6 231
Chris@6 232 QString
Chris@17 233 LayerFactory::getLayerIconName(LayerType type)
Chris@17 234 {
Chris@17 235 switch (type) {
Chris@17 236 case Waveform: return "waveform";
Chris@17 237 case Spectrogram: return "spectrogram";
Chris@17 238 case TimeRuler: return "timeruler";
Chris@17 239 case TimeInstants: return "instants";
Chris@17 240 case TimeValues: return "values";
Chris@30 241 case Notes: return "notes";
Chris@782 242 case FlexiNotes: return "flexinotes";
Chris@411 243 case Regions: return "regions";
Chris@35 244 case Text: return "text";
Chris@303 245 case Image: return "image";
Chris@17 246 case Colour3DPlot: return "colour3d";
Chris@133 247 case Spectrum: return "spectrum";
Chris@193 248 case Slice: return "spectrum";
Chris@326 249 case MelodicRangeSpectrogram: return "spectrogram";
Chris@326 250 case PeakFrequencySpectrogram: return "spectrogram";
Chris@805 251 case UnknownLayer:
Chris@805 252 default:
Chris@805 253 cerr << "WARNING: LayerFactory::getLayerIconName passed unknown layer" << endl;
Chris@805 254 return "unknown";
Chris@17 255 }
Chris@17 256 }
Chris@17 257
Chris@17 258 QString
Chris@6 259 LayerFactory::getLayerTypeName(LayerType type)
Chris@6 260 {
Chris@6 261 switch (type) {
Chris@6 262 case Waveform: return "waveform";
Chris@6 263 case Spectrogram: return "spectrogram";
Chris@6 264 case TimeRuler: return "timeruler";
Chris@6 265 case TimeInstants: return "timeinstants";
Chris@6 266 case TimeValues: return "timevalues";
Chris@30 267 case Notes: return "notes";
matthiasm@623 268 case FlexiNotes: return "flexinotes";
Chris@411 269 case Regions: return "regions";
Chris@35 270 case Text: return "text";
Chris@303 271 case Image: return "image";
Chris@6 272 case Colour3DPlot: return "colour3dplot";
Chris@133 273 case Spectrum: return "spectrum";
Chris@193 274 case Slice: return "slice";
Chris@326 275 case MelodicRangeSpectrogram: return "melodicrange";
Chris@326 276 case PeakFrequencySpectrogram: return "peakfrequency";
Chris@805 277 case UnknownLayer:
Chris@805 278 default:
Chris@805 279 cerr << "WARNING: LayerFactory::getLayerTypeName passed unknown layer" << endl;
Chris@805 280 return "unknown";
Chris@6 281 }
Chris@6 282 }
Chris@6 283
Chris@6 284 LayerFactory::LayerType
Chris@6 285 LayerFactory::getLayerTypeForName(QString name)
Chris@6 286 {
Chris@6 287 if (name == "waveform") return Waveform;
Chris@6 288 if (name == "spectrogram") return Spectrogram;
Chris@6 289 if (name == "timeruler") return TimeRuler;
Chris@6 290 if (name == "timeinstants") return TimeInstants;
Chris@6 291 if (name == "timevalues") return TimeValues;
Chris@1005 292 if (name == "notes") return Notes;
matthiasm@623 293 if (name == "flexinotes") return FlexiNotes;
Chris@411 294 if (name == "regions") return Regions;
Chris@35 295 if (name == "text") return Text;
Chris@303 296 if (name == "image") return Image;
Chris@6 297 if (name == "colour3dplot") return Colour3DPlot;
Chris@133 298 if (name == "spectrum") return Spectrum;
Chris@193 299 if (name == "slice") return Slice;
Chris@0 300 return UnknownLayer;
Chris@0 301 }
Chris@0 302
Chris@0 303 void
Chris@0 304 LayerFactory::setModel(Layer *layer, Model *model)
Chris@0 305 {
Chris@156 306 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
Chris@1266 307 // return;
Chris@1266 308
Chris@156 309 if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
Chris@1266 310 return;
Chris@156 311
Chris@156 312 if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
Chris@1266 313 return;
Chris@0 314
Chris@0 315 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@1266 316 return;
Chris@0 317
Chris@0 318 if (trySetModel<TimeRulerLayer, Model>(layer, model))
Chris@1266 319 return;
Chris@0 320
Chris@0 321 if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
Chris@1266 322 return;
Chris@0 323
Chris@0 324 if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
Chris@1266 325 return;
Chris@0 326
gyorgyf@626 327 if (trySetModel<NoteLayer, NoteModel>(layer, model))
Chris@1266 328 return;
Chris@30 329
Chris@782 330 // GF: added FlexiNoteLayer
gyorgyf@626 331 if (trySetModel<FlexiNoteLayer, FlexiNoteModel>(layer, model))
Chris@1266 332 return;
Chris@1266 333
Chris@411 334 if (trySetModel<RegionLayer, RegionModel>(layer, model))
Chris@1266 335 return;
Chris@411 336
Chris@35 337 if (trySetModel<TextLayer, TextModel>(layer, model))
Chris@1266 338 return;
Chris@35 339
Chris@303 340 if (trySetModel<ImageLayer, ImageModel>(layer, model))
Chris@1266 341 return;
Chris@303 342
Chris@0 343 if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
Chris@1266 344 return;
Chris@0 345
Chris@0 346 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@1266 347 return;
Chris@133 348
Chris@133 349 if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model))
Chris@133 350 return;
Chris@193 351
Chris@193 352 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model))
Chris@193 353 // return;
Chris@0 354 }
Chris@0 355
Chris@17 356 Model *
Chris@17 357 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
Chris@17 358 {
Chris@17 359 if (layerType == TimeInstants) {
Chris@1266 360 return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
Chris@17 361 } else if (layerType == TimeValues) {
Chris@1266 362 return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
Chris@782 363 } else if (layerType == FlexiNotes) {
Chris@1266 364 return new FlexiNoteModel(baseModel->getSampleRate(), 1, true);
Chris@30 365 } else if (layerType == Notes) {
Chris@1266 366 return new NoteModel(baseModel->getSampleRate(), 1, true);
Chris@411 367 } else if (layerType == Regions) {
Chris@1266 368 return new RegionModel(baseModel->getSampleRate(), 1, true);
Chris@35 369 } else if (layerType == Text) {
Chris@1266 370 return new TextModel(baseModel->getSampleRate(), 1, true);
Chris@303 371 } else if (layerType == Image) {
Chris@1266 372 return new ImageModel(baseModel->getSampleRate(), 1, true);
Chris@17 373 } else {
Chris@1266 374 return 0;
Chris@17 375 }
Chris@17 376 }
Chris@17 377
Chris@53 378 int
Chris@53 379 LayerFactory::getChannel(Layer *layer)
Chris@53 380 {
Chris@53 381 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@1266 382 return dynamic_cast<WaveformLayer *>(layer)->getChannel();
Chris@53 383 }
Chris@53 384 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@1266 385 return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
Chris@53 386 }
Chris@53 387 return -1;
Chris@53 388 }
Chris@53 389
Chris@53 390 void
Chris@53 391 LayerFactory::setChannel(Layer *layer, int channel)
Chris@53 392 {
Chris@53 393 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@1266 394 dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
Chris@1266 395 return;
Chris@53 396 }
Chris@53 397 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@1266 398 dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
Chris@1266 399 return;
Chris@53 400 }
Chris@349 401 if (dynamic_cast<SpectrumLayer *>(layer)) {
Chris@1266 402 dynamic_cast<SpectrumLayer *>(layer)->setChannel(channel);
Chris@1266 403 return;
Chris@349 404 }
Chris@53 405 }
Chris@53 406
Chris@0 407 Layer *
Chris@53 408 LayerFactory::createLayer(LayerType type)
Chris@0 409 {
Chris@0 410 Layer *layer = 0;
Chris@0 411
Chris@0 412 switch (type) {
Chris@0 413
Chris@0 414 case Waveform:
Chris@1266 415 layer = new WaveformLayer;
Chris@1266 416 break;
Chris@0 417
Chris@0 418 case Spectrogram:
Chris@1266 419 layer = new SpectrogramLayer;
Chris@1266 420 break;
Chris@0 421
Chris@0 422 case TimeRuler:
Chris@1266 423 layer = new TimeRulerLayer;
Chris@1266 424 break;
Chris@0 425
Chris@0 426 case TimeInstants:
Chris@1266 427 layer = new TimeInstantLayer;
Chris@1266 428 break;
Chris@0 429
Chris@0 430 case TimeValues:
Chris@1266 431 layer = new TimeValueLayer;
Chris@1266 432 break;
Chris@0 433
matthiasm@623 434 case FlexiNotes:
Chris@1266 435 layer = new FlexiNoteLayer;
Chris@1266 436 break;
matthiasm@623 437
Chris@30 438 case Notes:
Chris@1266 439 layer = new NoteLayer;
Chris@1266 440 break;
Chris@30 441
Chris@411 442 case Regions:
Chris@1266 443 layer = new RegionLayer;
Chris@1266 444 break;
Chris@411 445
Chris@35 446 case Text:
Chris@1266 447 layer = new TextLayer;
Chris@1266 448 break;
Chris@35 449
Chris@303 450 case Image:
Chris@1266 451 layer = new ImageLayer;
Chris@1266 452 break;
Chris@303 453
Chris@0 454 case Colour3DPlot:
Chris@1266 455 layer = new Colour3DPlotLayer;
Chris@1266 456 break;
Chris@0 457
Chris@133 458 case Spectrum:
Chris@133 459 layer = new SpectrumLayer;
Chris@133 460 break;
Chris@133 461
Chris@193 462 case Slice:
Chris@193 463 layer = new SliceLayer;
Chris@193 464 break;
Chris@193 465
Chris@0 466 case MelodicRangeSpectrogram:
Chris@1266 467 layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange);
Chris@1266 468 break;
Chris@11 469
Chris@37 470 case PeakFrequencySpectrogram:
Chris@1266 471 layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks);
Chris@1266 472 break;
Chris@37 473
Chris@805 474 case UnknownLayer:
Chris@805 475 default:
Chris@805 476 cerr << "WARNING: LayerFactory::createLayer passed unknown layer" << endl;
Chris@805 477 break;
Chris@0 478 }
Chris@0 479
Chris@0 480 if (!layer) {
Chris@1266 481 cerr << "LayerFactory::createLayer: Unknown layer type "
Chris@1266 482 << type << endl;
Chris@0 483 } else {
Chris@1266 484 // SVDEBUG << "LayerFactory::createLayer: Setting object name "
Chris@1266 485 // << getLayerPresentationName(type) << " on " << layer << endl;
Chris@1266 486 layer->setObjectName(getLayerPresentationName(type));
Chris@326 487 setLayerDefaultProperties(type, layer);
Chris@0 488 }
Chris@0 489
Chris@0 490 return layer;
Chris@0 491 }
Chris@0 492
Chris@326 493 void
Chris@326 494 LayerFactory::setLayerDefaultProperties(LayerType type, Layer *layer)
Chris@326 495 {
Chris@587 496 // SVDEBUG << "LayerFactory::setLayerDefaultProperties: type " << type << " (name \"" << getLayerTypeName(type) << "\")" << endl;
Chris@327 497
Chris@326 498 QSettings settings;
Chris@326 499 settings.beginGroup("LayerDefaults");
Chris@326 500 QString defaults = settings.value(getLayerTypeName(type), "").toString();
Chris@326 501 if (defaults == "") return;
Chris@326 502
Chris@682 503 // cerr << "defaults=\"" << defaults << "\"" << endl;
Chris@327 504
Chris@326 505 QString xml = layer->toXmlString();
Chris@326 506 QDomDocument docOld, docNew;
Chris@326 507
Chris@326 508 if (docOld.setContent(xml, false) &&
Chris@326 509 docNew.setContent(defaults, false)) {
Chris@326 510
Chris@326 511 QXmlAttributes attrs;
Chris@326 512
Chris@326 513 QDomElement layerElt = docNew.firstChildElement("layer");
Chris@326 514 QDomNamedNodeMap attrNodes = layerElt.attributes();
Chris@326 515
Chris@805 516 for (int i = 0; i < attrNodes.length(); ++i) {
Chris@326 517 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@326 518 if (attr.isNull()) continue;
Chris@683 519 // cerr << "append \"" << attr.name()
Chris@584 520 // << "\" -> \"" << attr.value() << "\""
Chris@682 521 // << endl;
Chris@326 522 attrs.append(attr.name(), "", "", attr.value());
Chris@326 523 }
Chris@326 524
Chris@326 525 layerElt = docOld.firstChildElement("layer");
Chris@326 526 attrNodes = layerElt.attributes();
Chris@805 527 for (int i = 0; i < attrNodes.length(); ++i) {
Chris@326 528 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@326 529 if (attr.isNull()) continue;
Chris@326 530 if (attrs.value(attr.name()) == "") {
Chris@683 531 // cerr << "append \"" << attr.name()
Chris@584 532 // << "\" -> \"" << attr.value() << "\""
Chris@682 533 // << endl;
Chris@326 534 attrs.append(attr.name(), "", "", attr.value());
Chris@326 535 }
Chris@326 536 }
Chris@326 537
Chris@326 538 layer->setProperties(attrs);
Chris@326 539 }
Chris@326 540
Chris@326 541 settings.endGroup();
Chris@326 542 }
Chris@326 543
Chris@360 544 LayerFactory::LayerType
Chris@360 545 LayerFactory::getLayerTypeForClipboardContents(const Clipboard &clip)
Chris@360 546 {
Chris@360 547 const Clipboard::PointList &contents = clip.getPoints();
Chris@360 548
Chris@360 549 bool haveFrame = false;
Chris@360 550 bool haveValue = false;
Chris@360 551 bool haveDuration = false;
Chris@411 552 bool haveLevel = false;
Chris@360 553
Chris@360 554 for (Clipboard::PointList::const_iterator i = contents.begin();
Chris@360 555 i != contents.end(); ++i) {
Chris@360 556 if (i->haveFrame()) haveFrame = true;
Chris@360 557 if (i->haveValue()) haveValue = true;
Chris@360 558 if (i->haveDuration()) haveDuration = true;
Chris@411 559 if (i->haveLevel()) haveLevel = true;
Chris@360 560 }
Chris@360 561
Chris@411 562 if (haveFrame && haveValue && haveDuration && haveLevel) return Notes;
Chris@411 563 if (haveFrame && haveValue && haveDuration) return Regions;
Chris@360 564 if (haveFrame && haveValue) return TimeValues;
Chris@360 565 return TimeInstants;
Chris@360 566 }
Chris@360 567