annotate layer/LayerFactory.cpp @ 1457:160e6d010141 single-point

Avoid showing progress bars for dormant layers. They'll typically be duplicates, e.g. in the vect app you can get many dormant layers all reporting the alignment completion at the same time. (Maybe it would be better just to reject progress bars for alignment in dormant layers? Hm)
author Chris Cannam
date Thu, 16 May 2019 15:50:02 +0100
parents 9e846af73f3e
children f2525e6cbdf1
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"
Chris@411 40 #include "data/model/RegionModel.h"
Chris@128 41 #include "data/model/TextModel.h"
Chris@303 42 #include "data/model/ImageModel.h"
Chris@128 43 #include "data/model/DenseThreeDimensionalModel.h"
Chris@156 44 #include "data/model/WaveFileModel.h"
Chris@156 45 #include "data/model/WritableWaveFileModel.h"
Chris@0 46
Chris@326 47 #include <QDomDocument>
Chris@326 48 #include <QDomElement>
Chris@326 49 #include <QDomNamedNodeMap>
Chris@326 50 #include <QDomAttr>
Chris@326 51
Chris@326 52 #include <QSettings>
Chris@326 53
Chris@0 54 LayerFactory *
Chris@0 55 LayerFactory::m_instance = new LayerFactory;
Chris@0 56
Chris@0 57 LayerFactory *
Chris@125 58 LayerFactory::getInstance()
Chris@0 59 {
Chris@0 60 return m_instance;
Chris@0 61 }
Chris@0 62
Chris@0 63 LayerFactory::~LayerFactory()
Chris@0 64 {
Chris@0 65 }
Chris@0 66
Chris@0 67 QString
Chris@0 68 LayerFactory::getLayerPresentationName(LayerType type)
Chris@0 69 {
Chris@0 70 switch (type) {
Chris@0 71 case Waveform: return Layer::tr("Waveform");
Chris@0 72 case Spectrogram: return Layer::tr("Spectrogram");
Chris@0 73 case TimeRuler: return Layer::tr("Ruler");
Chris@0 74 case TimeInstants: return Layer::tr("Time Instants");
Chris@0 75 case TimeValues: return Layer::tr("Time Values");
Chris@30 76 case Notes: return Layer::tr("Notes");
gyorgyf@625 77 case FlexiNotes: return Layer::tr("Flexible Notes");
Chris@411 78 case Regions: return Layer::tr("Regions");
Chris@35 79 case Text: return Layer::tr("Text");
Chris@303 80 case Image: return Layer::tr("Images");
Chris@0 81 case Colour3DPlot: return Layer::tr("Colour 3D Plot");
Chris@133 82 case Spectrum: return Layer::tr("Spectrum");
Chris@193 83 case Slice: return Layer::tr("Time Slice");
Chris@0 84
Chris@0 85 case MelodicRangeSpectrogram:
Chris@1266 86 // The user can change all the parameters of this after the
Chris@1266 87 // fact -- there's nothing permanently melodic-range about it
Chris@1266 88 // that should be encoded in its name
Chris@1266 89 return Layer::tr("Spectrogram");
Chris@11 90
Chris@37 91 case PeakFrequencySpectrogram:
Chris@1266 92 // likewise
Chris@1266 93 return Layer::tr("Spectrogram");
Chris@37 94
Chris@805 95 case UnknownLayer:
Chris@805 96 default:
Chris@805 97 cerr << "WARNING: LayerFactory::getLayerPresentationName passed unknown layer" << endl;
Chris@805 98 return Layer::tr("Unknown Layer");
Chris@0 99 }
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@1266 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@1266 146 types.insert(Waveform);
Chris@0 147 }
Chris@0 148
Chris@0 149 if (dynamic_cast<DenseTimeValueModel *>(model)) {
Chris@1266 150 types.insert(Spectrogram);
Chris@1266 151 types.insert(MelodicRangeSpectrogram);
Chris@1266 152 types.insert(PeakFrequencySpectrogram);
Chris@0 153 }
Chris@0 154
Chris@0 155 if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
Chris@1266 156 types.insert(TimeInstants);
Chris@0 157 }
Chris@0 158
Chris@0 159 if (dynamic_cast<SparseTimeValueModel *>(model)) {
Chris@1266 160 types.insert(TimeValues);
Chris@411 161 }
Chris@411 162
Chris@35 163 if (dynamic_cast<NoteModel *>(model)) {
Chris@1426 164 NoteModel *nm = dynamic_cast<NoteModel *>(model);
Chris@1426 165 if (nm->getSubtype() == NoteModel::FLEXI_NOTE) {
Chris@1426 166 types.insert(FlexiNotes);
Chris@1426 167 } else {
Chris@1426 168 types.insert(Notes);
Chris@1426 169 }
matthiasm@621 170 }
matthiasm@621 171
Chris@411 172 if (dynamic_cast<RegionModel *>(model)) {
Chris@1266 173 types.insert(Regions);
Chris@411 174 }
Chris@411 175
Chris@35 176 if (dynamic_cast<TextModel *>(model)) {
Chris@1266 177 types.insert(Text);
Chris@30 178 }
Chris@30 179
Chris@303 180 if (dynamic_cast<ImageModel *>(model)) {
Chris@1266 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@962 200 // Because this is strictly a UI function -- list the layer types
Chris@962 201 // to show in a menu -- it should not contain FlexiNotes; the
Chris@962 202 // layer isn't meaningfully editable in SV
Chris@962 203 // types.insert(FlexiNotes);
Chris@30 204 types.insert(Notes);
Chris@411 205 types.insert(Regions);
Chris@35 206 types.insert(Text);
Chris@303 207 types.insert(Image);
Chris@17 208 //!!! and in principle Colour3DPlot -- now that's a challenge
Chris@17 209 return types;
Chris@17 210 }
Chris@17 211
Chris@0 212 LayerFactory::LayerType
Chris@6 213 LayerFactory::getLayerType(const Layer *layer)
Chris@0 214 {
Chris@6 215 if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
Chris@6 216 if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
Chris@6 217 if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
Chris@6 218 if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
Chris@6 219 if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
Chris@782 220 if (dynamic_cast<const FlexiNoteLayer *>(layer)) return FlexiNotes;
Chris@30 221 if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
Chris@411 222 if (dynamic_cast<const RegionLayer *>(layer)) return Regions;
Chris@35 223 if (dynamic_cast<const TextLayer *>(layer)) return Text;
Chris@303 224 if (dynamic_cast<const ImageLayer *>(layer)) return Image;
Chris@6 225 if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
Chris@133 226 if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
Chris@193 227 if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
Chris@6 228 return UnknownLayer;
Chris@6 229 }
Chris@6 230
Chris@6 231 QString
Chris@17 232 LayerFactory::getLayerIconName(LayerType type)
Chris@17 233 {
Chris@17 234 switch (type) {
Chris@17 235 case Waveform: return "waveform";
Chris@17 236 case Spectrogram: return "spectrogram";
Chris@17 237 case TimeRuler: return "timeruler";
Chris@17 238 case TimeInstants: return "instants";
Chris@17 239 case TimeValues: return "values";
Chris@30 240 case Notes: return "notes";
Chris@782 241 case FlexiNotes: return "flexinotes";
Chris@411 242 case Regions: return "regions";
Chris@35 243 case Text: return "text";
Chris@303 244 case Image: return "image";
Chris@17 245 case Colour3DPlot: return "colour3d";
Chris@133 246 case Spectrum: return "spectrum";
Chris@193 247 case Slice: return "spectrum";
Chris@326 248 case MelodicRangeSpectrogram: return "spectrogram";
Chris@326 249 case PeakFrequencySpectrogram: return "spectrogram";
Chris@805 250 case UnknownLayer:
Chris@805 251 default:
Chris@805 252 cerr << "WARNING: LayerFactory::getLayerIconName passed unknown layer" << endl;
Chris@805 253 return "unknown";
Chris@17 254 }
Chris@17 255 }
Chris@17 256
Chris@17 257 QString
Chris@6 258 LayerFactory::getLayerTypeName(LayerType type)
Chris@6 259 {
Chris@6 260 switch (type) {
Chris@6 261 case Waveform: return "waveform";
Chris@6 262 case Spectrogram: return "spectrogram";
Chris@6 263 case TimeRuler: return "timeruler";
Chris@6 264 case TimeInstants: return "timeinstants";
Chris@6 265 case TimeValues: return "timevalues";
Chris@30 266 case Notes: return "notes";
matthiasm@623 267 case FlexiNotes: return "flexinotes";
Chris@411 268 case Regions: return "regions";
Chris@35 269 case Text: return "text";
Chris@303 270 case Image: return "image";
Chris@6 271 case Colour3DPlot: return "colour3dplot";
Chris@133 272 case Spectrum: return "spectrum";
Chris@193 273 case Slice: return "slice";
Chris@326 274 case MelodicRangeSpectrogram: return "melodicrange";
Chris@326 275 case PeakFrequencySpectrogram: return "peakfrequency";
Chris@805 276 case UnknownLayer:
Chris@805 277 default:
Chris@805 278 cerr << "WARNING: LayerFactory::getLayerTypeName passed unknown layer" << endl;
Chris@805 279 return "unknown";
Chris@6 280 }
Chris@6 281 }
Chris@6 282
Chris@6 283 LayerFactory::LayerType
Chris@6 284 LayerFactory::getLayerTypeForName(QString name)
Chris@6 285 {
Chris@6 286 if (name == "waveform") return Waveform;
Chris@6 287 if (name == "spectrogram") return Spectrogram;
Chris@6 288 if (name == "timeruler") return TimeRuler;
Chris@6 289 if (name == "timeinstants") return TimeInstants;
Chris@6 290 if (name == "timevalues") return TimeValues;
Chris@1005 291 if (name == "notes") return Notes;
matthiasm@623 292 if (name == "flexinotes") return FlexiNotes;
Chris@411 293 if (name == "regions") return Regions;
Chris@35 294 if (name == "text") return Text;
Chris@303 295 if (name == "image") return Image;
Chris@6 296 if (name == "colour3dplot") return Colour3DPlot;
Chris@133 297 if (name == "spectrum") return Spectrum;
Chris@193 298 if (name == "slice") return Slice;
Chris@0 299 return UnknownLayer;
Chris@0 300 }
Chris@0 301
Chris@0 302 void
Chris@0 303 LayerFactory::setModel(Layer *layer, Model *model)
Chris@0 304 {
Chris@156 305 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
Chris@1266 306 // return;
Chris@1266 307
Chris@156 308 if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
Chris@1266 309 return;
Chris@156 310
Chris@156 311 if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
Chris@1266 312 return;
Chris@0 313
Chris@0 314 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@1266 315 return;
Chris@0 316
Chris@0 317 if (trySetModel<TimeRulerLayer, Model>(layer, model))
Chris@1266 318 return;
Chris@0 319
Chris@0 320 if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
Chris@1266 321 return;
Chris@0 322
Chris@0 323 if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
Chris@1266 324 return;
Chris@0 325
gyorgyf@626 326 if (trySetModel<NoteLayer, NoteModel>(layer, model))
Chris@1266 327 return;
Chris@30 328
Chris@1426 329 if (trySetModel<FlexiNoteLayer, NoteModel>(layer, model))
Chris@1266 330 return;
Chris@1266 331
Chris@411 332 if (trySetModel<RegionLayer, RegionModel>(layer, model))
Chris@1266 333 return;
Chris@411 334
Chris@35 335 if (trySetModel<TextLayer, TextModel>(layer, model))
Chris@1266 336 return;
Chris@35 337
Chris@303 338 if (trySetModel<ImageLayer, ImageModel>(layer, model))
Chris@1266 339 return;
Chris@303 340
Chris@0 341 if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
Chris@1266 342 return;
Chris@0 343
Chris@0 344 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
Chris@1266 345 return;
Chris@133 346
Chris@133 347 if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model))
Chris@133 348 return;
Chris@193 349
Chris@193 350 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model))
Chris@193 351 // return;
Chris@0 352 }
Chris@0 353
Chris@17 354 Model *
Chris@17 355 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
Chris@17 356 {
Chris@17 357 if (layerType == TimeInstants) {
Chris@1266 358 return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
Chris@17 359 } else if (layerType == TimeValues) {
Chris@1266 360 return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
Chris@782 361 } else if (layerType == FlexiNotes) {
Chris@1426 362 return new NoteModel(baseModel->getSampleRate(), 1, true);
Chris@30 363 } else if (layerType == Notes) {
Chris@1266 364 return new NoteModel(baseModel->getSampleRate(), 1, true);
Chris@411 365 } else if (layerType == Regions) {
Chris@1266 366 return new RegionModel(baseModel->getSampleRate(), 1, true);
Chris@35 367 } else if (layerType == Text) {
Chris@1266 368 return new TextModel(baseModel->getSampleRate(), 1, true);
Chris@303 369 } else if (layerType == Image) {
Chris@1266 370 return new ImageModel(baseModel->getSampleRate(), 1, true);
Chris@17 371 } else {
Chris@1408 372 return nullptr;
Chris@17 373 }
Chris@17 374 }
Chris@17 375
Chris@53 376 int
Chris@53 377 LayerFactory::getChannel(Layer *layer)
Chris@53 378 {
Chris@53 379 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@1266 380 return dynamic_cast<WaveformLayer *>(layer)->getChannel();
Chris@53 381 }
Chris@53 382 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@1266 383 return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
Chris@53 384 }
Chris@53 385 return -1;
Chris@53 386 }
Chris@53 387
Chris@53 388 void
Chris@53 389 LayerFactory::setChannel(Layer *layer, int channel)
Chris@53 390 {
Chris@53 391 if (dynamic_cast<WaveformLayer *>(layer)) {
Chris@1266 392 dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
Chris@1266 393 return;
Chris@53 394 }
Chris@53 395 if (dynamic_cast<SpectrogramLayer *>(layer)) {
Chris@1266 396 dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
Chris@1266 397 return;
Chris@53 398 }
Chris@349 399 if (dynamic_cast<SpectrumLayer *>(layer)) {
Chris@1266 400 dynamic_cast<SpectrumLayer *>(layer)->setChannel(channel);
Chris@1266 401 return;
Chris@349 402 }
Chris@53 403 }
Chris@53 404
Chris@0 405 Layer *
Chris@53 406 LayerFactory::createLayer(LayerType type)
Chris@0 407 {
Chris@1408 408 Layer *layer = nullptr;
Chris@0 409
Chris@0 410 switch (type) {
Chris@0 411
Chris@0 412 case Waveform:
Chris@1266 413 layer = new WaveformLayer;
Chris@1266 414 break;
Chris@0 415
Chris@0 416 case Spectrogram:
Chris@1266 417 layer = new SpectrogramLayer;
Chris@1266 418 break;
Chris@0 419
Chris@0 420 case TimeRuler:
Chris@1266 421 layer = new TimeRulerLayer;
Chris@1266 422 break;
Chris@0 423
Chris@0 424 case TimeInstants:
Chris@1266 425 layer = new TimeInstantLayer;
Chris@1266 426 break;
Chris@0 427
Chris@0 428 case TimeValues:
Chris@1266 429 layer = new TimeValueLayer;
Chris@1266 430 break;
Chris@0 431
matthiasm@623 432 case FlexiNotes:
Chris@1266 433 layer = new FlexiNoteLayer;
Chris@1266 434 break;
matthiasm@623 435
Chris@30 436 case Notes:
Chris@1266 437 layer = new NoteLayer;
Chris@1266 438 break;
Chris@30 439
Chris@411 440 case Regions:
Chris@1266 441 layer = new RegionLayer;
Chris@1266 442 break;
Chris@411 443
Chris@35 444 case Text:
Chris@1266 445 layer = new TextLayer;
Chris@1266 446 break;
Chris@35 447
Chris@303 448 case Image:
Chris@1266 449 layer = new ImageLayer;
Chris@1266 450 break;
Chris@303 451
Chris@0 452 case Colour3DPlot:
Chris@1266 453 layer = new Colour3DPlotLayer;
Chris@1266 454 break;
Chris@0 455
Chris@133 456 case Spectrum:
Chris@133 457 layer = new SpectrumLayer;
Chris@133 458 break;
Chris@133 459
Chris@193 460 case Slice:
Chris@193 461 layer = new SliceLayer;
Chris@193 462 break;
Chris@193 463
Chris@0 464 case MelodicRangeSpectrogram:
Chris@1266 465 layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange);
Chris@1266 466 break;
Chris@11 467
Chris@37 468 case PeakFrequencySpectrogram:
Chris@1266 469 layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks);
Chris@1266 470 break;
Chris@37 471
Chris@805 472 case UnknownLayer:
Chris@805 473 default:
Chris@805 474 cerr << "WARNING: LayerFactory::createLayer passed unknown layer" << endl;
Chris@805 475 break;
Chris@0 476 }
Chris@0 477
Chris@0 478 if (!layer) {
Chris@1266 479 cerr << "LayerFactory::createLayer: Unknown layer type "
Chris@1266 480 << type << endl;
Chris@0 481 } else {
Chris@1266 482 // SVDEBUG << "LayerFactory::createLayer: Setting object name "
Chris@1266 483 // << getLayerPresentationName(type) << " on " << layer << endl;
Chris@1266 484 layer->setObjectName(getLayerPresentationName(type));
Chris@326 485 setLayerDefaultProperties(type, layer);
Chris@0 486 }
Chris@0 487
Chris@0 488 return layer;
Chris@0 489 }
Chris@0 490
Chris@326 491 void
Chris@326 492 LayerFactory::setLayerDefaultProperties(LayerType type, Layer *layer)
Chris@326 493 {
Chris@587 494 // SVDEBUG << "LayerFactory::setLayerDefaultProperties: type " << type << " (name \"" << getLayerTypeName(type) << "\")" << endl;
Chris@327 495
Chris@326 496 QSettings settings;
Chris@326 497 settings.beginGroup("LayerDefaults");
Chris@326 498 QString defaults = settings.value(getLayerTypeName(type), "").toString();
Chris@326 499 if (defaults == "") return;
Chris@1455 500 setLayerProperties(layer, defaults);
Chris@1455 501 settings.endGroup();
Chris@1455 502 }
Chris@326 503
Chris@1455 504 void
Chris@1455 505 LayerFactory::setLayerProperties(Layer *layer, QString newXml)
Chris@1455 506 {
Chris@1455 507 QDomDocument docOld, docNew;
Chris@1455 508 QString oldXml = layer->toXmlString();
Chris@327 509
Chris@1455 510 if (!docOld.setContent(oldXml, false)) {
Chris@1455 511 SVCERR << "LayerFactory::setLayerProperties: Failed to parse XML for existing layer properties! XML string is: " << oldXml << endl;
Chris@1455 512 return;
Chris@1455 513 }
Chris@1455 514
Chris@1455 515 if (!docNew.setContent(newXml, false)) {
Chris@1455 516 SVCERR << "LayerFactory::setLayerProperties: Failed to parse XML: " << newXml << endl;
Chris@1455 517 return;
Chris@1455 518 }
Chris@326 519
Chris@1455 520 QXmlAttributes attrs;
Chris@326 521
Chris@1455 522 QDomElement layerElt = docNew.firstChildElement("layer");
Chris@1455 523 QDomNamedNodeMap attrNodes = layerElt.attributes();
Chris@326 524
Chris@1455 525 for (int i = 0; i < attrNodes.length(); ++i) {
Chris@1455 526 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@1455 527 if (attr.isNull()) continue;
Chris@683 528 // cerr << "append \"" << attr.name()
Chris@584 529 // << "\" -> \"" << attr.value() << "\""
Chris@682 530 // << endl;
Chris@1455 531 attrs.append(attr.name(), "", "", attr.value());
Chris@1455 532 }
Chris@1455 533
Chris@1455 534 layerElt = docOld.firstChildElement("layer");
Chris@1455 535 attrNodes = layerElt.attributes();
Chris@1455 536 for (int i = 0; i < attrNodes.length(); ++i) {
Chris@1455 537 QDomAttr attr = attrNodes.item(i).toAttr();
Chris@1455 538 if (attr.isNull()) continue;
Chris@1455 539 if (attrs.value(attr.name()) == "") {
Chris@683 540 // cerr << "append \"" << attr.name()
Chris@584 541 // << "\" -> \"" << attr.value() << "\""
Chris@682 542 // << endl;
Chris@1455 543 attrs.append(attr.name(), "", "", attr.value());
Chris@326 544 }
Chris@326 545 }
Chris@1455 546
Chris@1455 547 layer->setProperties(attrs);
Chris@326 548 }
Chris@326 549
Chris@360 550 LayerFactory::LayerType
Chris@360 551 LayerFactory::getLayerTypeForClipboardContents(const Clipboard &clip)
Chris@360 552 {
Chris@1423 553 const EventVector &contents = clip.getPoints();
Chris@360 554
Chris@360 555 bool haveValue = false;
Chris@360 556 bool haveDuration = false;
Chris@411 557 bool haveLevel = false;
Chris@360 558
Chris@1423 559 for (EventVector::const_iterator i = contents.begin();
Chris@360 560 i != contents.end(); ++i) {
Chris@1423 561 if (i->hasValue()) haveValue = true;
Chris@1423 562 if (i->hasDuration()) haveDuration = true;
Chris@1423 563 if (i->hasLevel()) haveLevel = true;
Chris@360 564 }
Chris@360 565
Chris@1423 566 if (haveValue && haveDuration && haveLevel) return Notes;
Chris@1423 567 if (haveValue && haveDuration) return Regions;
Chris@1423 568 if (haveValue) return TimeValues;
Chris@360 569 return TimeInstants;
Chris@360 570 }
Chris@360 571