annotate layer/LayerFactory.cpp @ 1605:ae2d5f8ff005

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