annotate layer/LayerFactory.cpp @ 1608:6616e1899daa

Make ImageLayer able to report whether an image format can be opened
author Chris Cannam
date Mon, 11 May 2020 17:28:12 +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