svgui  1.9
LayerFactory.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "LayerFactory.h"
17 
18 #include "WaveformLayer.h"
19 #include "SpectrogramLayer.h"
20 #include "TimeRulerLayer.h"
21 #include "TimeInstantLayer.h"
22 #include "TimeValueLayer.h"
23 #include "NoteLayer.h"
24 #include "FlexiNoteLayer.h"
25 #include "RegionLayer.h"
26 #include "TextLayer.h"
27 #include "ImageLayer.h"
28 #include "Colour3DPlotLayer.h"
29 #include "SpectrumLayer.h"
30 #include "SliceLayer.h"
31 #include "SliceableLayer.h"
32 
33 #include "base/Clipboard.h"
34 
35 #include "data/model/RangeSummarisableTimeValueModel.h"
36 #include "data/model/DenseTimeValueModel.h"
37 #include "data/model/SparseOneDimensionalModel.h"
38 #include "data/model/SparseTimeValueModel.h"
39 #include "data/model/NoteModel.h"
40 #include "data/model/FlexiNoteModel.h"
41 #include "data/model/RegionModel.h"
42 #include "data/model/TextModel.h"
43 #include "data/model/ImageModel.h"
44 #include "data/model/DenseThreeDimensionalModel.h"
45 #include "data/model/WaveFileModel.h"
46 #include "data/model/WritableWaveFileModel.h"
47 
48 #include <QDomDocument>
49 #include <QDomElement>
50 #include <QDomNamedNodeMap>
51 #include <QDomAttr>
52 
53 #include <QSettings>
54 
57 
60 {
61  return m_instance;
62 }
63 
65 {
66 }
67 
68 QString
70 {
71  switch (type) {
72  case Waveform: return Layer::tr("Waveform");
73  case Spectrogram: return Layer::tr("Spectrogram");
74  case TimeRuler: return Layer::tr("Ruler");
75  case TimeInstants: return Layer::tr("Time Instants");
76  case TimeValues: return Layer::tr("Time Values");
77  case Notes: return Layer::tr("Notes");
78  case FlexiNotes: return Layer::tr("Flexible Notes");
79  case Regions: return Layer::tr("Regions");
80  case Text: return Layer::tr("Text");
81  case Image: return Layer::tr("Images");
82  case Colour3DPlot: return Layer::tr("Colour 3D Plot");
83  case Spectrum: return Layer::tr("Spectrum");
84  case Slice: return Layer::tr("Time Slice");
85 
87  // The user can change all the parameters of this after the
88  // fact -- there's nothing permanently melodic-range about it
89  // that should be encoded in its name
90  return Layer::tr("Spectrogram");
91 
93  // likewise
94  return Layer::tr("Spectrogram");
95 
96  case UnknownLayer:
97  default:
98  cerr << "WARNING: LayerFactory::getLayerPresentationName passed unknown layer" << endl;
99  return Layer::tr("Unknown Layer");
100  }
101 }
102 
103 bool
105 {
106  if (dynamic_cast<const SliceableLayer *>(layer)) {
107  if (dynamic_cast<const SpectrogramLayer *>(layer)) {
108 
110  // problem managing the models. The source model for the
111  // slice layer has to be one of the spectrogram's FFT
112  // models -- that's fine, except that we can't store &
113  // recall the slice layer with a reference to that model
114  // because the model is internal to the spectrogram layer
115  // and the document has no record of it. We would need
116  // some other way of managing models that are used in this
117  // way. For the moment we just don't allow slices of
118  // spectrograms -- and provide a spectrum layer for this
119  // instead.
120  //
121  // This business needs a bit more thought -- either come
122  // up with a sensible way to deal with that stuff, or
123  // simplify the existing slice layer logic so that it
124  // doesn't have to deal with models disappearing on it at
125  // all (and use the normal Document setModel mechanism to
126  // set its sliceable model instead of the fancy pants
127  // nonsense it's doing at the moment).
128 
129  return false;
130  }
131  return true;
132  }
133  return false;
134 }
135 
138 {
139  LayerTypeSet types;
140 
141  if (dynamic_cast<DenseThreeDimensionalModel *>(model)) {
142  types.insert(Colour3DPlot);
143  types.insert(Slice);
144  }
145 
146  if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) {
147  types.insert(Waveform);
148  }
149 
150  if (dynamic_cast<DenseTimeValueModel *>(model)) {
151  types.insert(Spectrogram);
152  types.insert(MelodicRangeSpectrogram);
153  types.insert(PeakFrequencySpectrogram);
154  }
155 
156  if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
157  types.insert(TimeInstants);
158  }
159 
160  if (dynamic_cast<SparseTimeValueModel *>(model)) {
161  types.insert(TimeValues);
162  }
163 
164  if (dynamic_cast<NoteModel *>(model)) {
165  types.insert(Notes);
166  }
167 
168  // NOTE: GF: types is a set, so order of insertion does not matter
169  if (dynamic_cast<FlexiNoteModel *>(model)) {
170  types.insert(FlexiNotes);
171  }
172 
173  if (dynamic_cast<RegionModel *>(model)) {
174  types.insert(Regions);
175  }
176 
177  if (dynamic_cast<TextModel *>(model)) {
178  types.insert(Text);
179  }
180 
181  if (dynamic_cast<ImageModel *>(model)) {
182  types.insert(Image);
183  }
184 
185  if (dynamic_cast<DenseTimeValueModel *>(model)) {
186  types.insert(Spectrum);
187  }
188 
189  // We don't count TimeRuler here as it doesn't actually display
190  // the data, although it can be backed by any model
191 
192  return types;
193 }
194 
197 {
198  LayerTypeSet types;
199  types.insert(TimeInstants);
200  types.insert(TimeValues);
201  types.insert(FlexiNotes);
202  types.insert(Notes);
203  types.insert(Regions);
204  types.insert(Text);
205  types.insert(Image);
207  return types;
208 }
209 
212 {
213  if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
214  if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
215  if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
216  if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
217  if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
218  if (dynamic_cast<const FlexiNoteLayer *>(layer)) return FlexiNotes;
219  if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
220  if (dynamic_cast<const RegionLayer *>(layer)) return Regions;
221  if (dynamic_cast<const TextLayer *>(layer)) return Text;
222  if (dynamic_cast<const ImageLayer *>(layer)) return Image;
223  if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
224  if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
225  if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
226  return UnknownLayer;
227 }
228 
229 QString
231 {
232  switch (type) {
233  case Waveform: return "waveform";
234  case Spectrogram: return "spectrogram";
235  case TimeRuler: return "timeruler";
236  case TimeInstants: return "instants";
237  case TimeValues: return "values";
238  case Notes: return "notes";
239  case FlexiNotes: return "flexinotes";
240  case Regions: return "regions";
241  case Text: return "text";
242  case Image: return "image";
243  case Colour3DPlot: return "colour3d";
244  case Spectrum: return "spectrum";
245  case Slice: return "spectrum";
246  case MelodicRangeSpectrogram: return "spectrogram";
247  case PeakFrequencySpectrogram: return "spectrogram";
248  case UnknownLayer:
249  default:
250  cerr << "WARNING: LayerFactory::getLayerIconName passed unknown layer" << endl;
251  return "unknown";
252  }
253 }
254 
255 QString
257 {
258  switch (type) {
259  case Waveform: return "waveform";
260  case Spectrogram: return "spectrogram";
261  case TimeRuler: return "timeruler";
262  case TimeInstants: return "timeinstants";
263  case TimeValues: return "timevalues";
264  case Notes: return "notes";
265  case FlexiNotes: return "flexinotes";
266  case Regions: return "regions";
267  case Text: return "text";
268  case Image: return "image";
269  case Colour3DPlot: return "colour3dplot";
270  case Spectrum: return "spectrum";
271  case Slice: return "slice";
272  case MelodicRangeSpectrogram: return "melodicrange";
273  case PeakFrequencySpectrogram: return "peakfrequency";
274  case UnknownLayer:
275  default:
276  cerr << "WARNING: LayerFactory::getLayerTypeName passed unknown layer" << endl;
277  return "unknown";
278  }
279 }
280 
283 {
284  if (name == "waveform") return Waveform;
285  if (name == "spectrogram") return Spectrogram;
286  if (name == "timeruler") return TimeRuler;
287  if (name == "timeinstants") return TimeInstants;
288  if (name == "timevalues") return TimeValues;
289  if (name == "flexinotes") return FlexiNotes;
290  if (name == "regions") return Regions;
291  if (name == "text") return Text;
292  if (name == "image") return Image;
293  if (name == "colour3dplot") return Colour3DPlot;
294  if (name == "spectrum") return Spectrum;
295  if (name == "slice") return Slice;
296  return UnknownLayer;
297 }
298 
299 void
300 LayerFactory::setModel(Layer *layer, Model *model)
301 {
302 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
303 // return;
304 
305  if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
306  return;
307 
308  if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
309  return;
310 
311  if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
312  return;
313 
314  if (trySetModel<TimeRulerLayer, Model>(layer, model))
315  return;
316 
317  if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
318  return;
319 
320  if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
321  return;
322 
323  if (trySetModel<NoteLayer, NoteModel>(layer, model))
324  return;
325 
326  // GF: added FlexiNoteLayer
327  if (trySetModel<FlexiNoteLayer, FlexiNoteModel>(layer, model))
328  return;
329 
330  if (trySetModel<RegionLayer, RegionModel>(layer, model))
331  return;
332 
333  if (trySetModel<TextLayer, TextModel>(layer, model))
334  return;
335 
336  if (trySetModel<ImageLayer, ImageModel>(layer, model))
337  return;
338 
339  if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
340  return;
341 
342  if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
343  return;
344 
345  if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model))
346  return;
347 
348 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model))
349 // return;
350 }
351 
352 Model *
353 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
354 {
355  if (layerType == TimeInstants) {
356  return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
357  } else if (layerType == TimeValues) {
358  return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
359  } else if (layerType == FlexiNotes) {
360  return new FlexiNoteModel(baseModel->getSampleRate(), 1, true);
361  } else if (layerType == Notes) {
362  return new NoteModel(baseModel->getSampleRate(), 1, true);
363  } else if (layerType == Regions) {
364  return new RegionModel(baseModel->getSampleRate(), 1, true);
365  } else if (layerType == Text) {
366  return new TextModel(baseModel->getSampleRate(), 1, true);
367  } else if (layerType == Image) {
368  return new ImageModel(baseModel->getSampleRate(), 1, true);
369  } else {
370  return 0;
371  }
372 }
373 
374 int
376 {
377  if (dynamic_cast<WaveformLayer *>(layer)) {
378  return dynamic_cast<WaveformLayer *>(layer)->getChannel();
379  }
380  if (dynamic_cast<SpectrogramLayer *>(layer)) {
381  return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
382  }
383  return -1;
384 }
385 
386 void
387 LayerFactory::setChannel(Layer *layer, int channel)
388 {
389  if (dynamic_cast<WaveformLayer *>(layer)) {
390  dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
391  return;
392  }
393  if (dynamic_cast<SpectrogramLayer *>(layer)) {
394  dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
395  return;
396  }
397  if (dynamic_cast<SpectrumLayer *>(layer)) {
398  dynamic_cast<SpectrumLayer *>(layer)->setChannel(channel);
399  return;
400  }
401 }
402 
403 Layer *
405 {
406  Layer *layer = 0;
407 
408  switch (type) {
409 
410  case Waveform:
411  layer = new WaveformLayer;
412  break;
413 
414  case Spectrogram:
415  layer = new SpectrogramLayer;
416  break;
417 
418  case TimeRuler:
419  layer = new TimeRulerLayer;
420  break;
421 
422  case TimeInstants:
423  layer = new TimeInstantLayer;
424  break;
425 
426  case TimeValues:
427  layer = new TimeValueLayer;
428  break;
429 
430  case FlexiNotes:
431  layer = new FlexiNoteLayer;
432  break;
433 
434  case Notes:
435  layer = new NoteLayer;
436  break;
437 
438  case Regions:
439  layer = new RegionLayer;
440  break;
441 
442  case Text:
443  layer = new TextLayer;
444  break;
445 
446  case Image:
447  layer = new ImageLayer;
448  break;
449 
450  case Colour3DPlot:
451  layer = new Colour3DPlotLayer;
452  break;
453 
454  case Spectrum:
455  layer = new SpectrumLayer;
456  break;
457 
458  case Slice:
459  layer = new SliceLayer;
460  break;
461 
464  break;
465 
468  break;
469 
470  case UnknownLayer:
471  default:
472  cerr << "WARNING: LayerFactory::createLayer passed unknown layer" << endl;
473  break;
474  }
475 
476  if (!layer) {
477  cerr << "LayerFactory::createLayer: Unknown layer type "
478  << type << endl;
479  } else {
480 // SVDEBUG << "LayerFactory::createLayer: Setting object name "
481 // << getLayerPresentationName(type) << " on " << layer << endl;
483  setLayerDefaultProperties(type, layer);
484  }
485 
486  return layer;
487 }
488 
489 void
491 {
492 // SVDEBUG << "LayerFactory::setLayerDefaultProperties: type " << type << " (name \"" << getLayerTypeName(type) << "\")" << endl;
493 
494  QSettings settings;
495  settings.beginGroup("LayerDefaults");
496  QString defaults = settings.value(getLayerTypeName(type), "").toString();
497  if (defaults == "") return;
498 
499 // cerr << "defaults=\"" << defaults << "\"" << endl;
500 
501  QString xml = layer->toXmlString();
502  QDomDocument docOld, docNew;
503 
504  if (docOld.setContent(xml, false) &&
505  docNew.setContent(defaults, false)) {
506 
507  QXmlAttributes attrs;
508 
509  QDomElement layerElt = docNew.firstChildElement("layer");
510  QDomNamedNodeMap attrNodes = layerElt.attributes();
511 
512  for (int i = 0; i < attrNodes.length(); ++i) {
513  QDomAttr attr = attrNodes.item(i).toAttr();
514  if (attr.isNull()) continue;
515 // cerr << "append \"" << attr.name()
516 // << "\" -> \"" << attr.value() << "\""
517 // << endl;
518  attrs.append(attr.name(), "", "", attr.value());
519  }
520 
521  layerElt = docOld.firstChildElement("layer");
522  attrNodes = layerElt.attributes();
523  for (int i = 0; i < attrNodes.length(); ++i) {
524  QDomAttr attr = attrNodes.item(i).toAttr();
525  if (attr.isNull()) continue;
526  if (attrs.value(attr.name()) == "") {
527 // cerr << "append \"" << attr.name()
528 // << "\" -> \"" << attr.value() << "\""
529 // << endl;
530  attrs.append(attr.name(), "", "", attr.value());
531  }
532  }
533 
534  layer->setProperties(attrs);
535  }
536 
537  settings.endGroup();
538 }
539 
542 {
543  const Clipboard::PointList &contents = clip.getPoints();
544 
545  bool haveFrame = false;
546  bool haveValue = false;
547  bool haveDuration = false;
548  bool haveLevel = false;
549 
550  for (Clipboard::PointList::const_iterator i = contents.begin();
551  i != contents.end(); ++i) {
552  if (i->haveFrame()) haveFrame = true;
553  if (i->haveValue()) haveValue = true;
554  if (i->haveDuration()) haveDuration = true;
555  if (i->haveLevel()) haveLevel = true;
556  }
557 
558  if (haveFrame && haveValue && haveDuration && haveLevel) return Notes;
559  if (haveFrame && haveValue && haveDuration) return Regions;
560  if (haveFrame && haveValue) return TimeValues;
561  return TimeInstants;
562 }
563 
static LayerFactory * getInstance()
QString getLayerIconName(LayerType)
The base class for visual representations of the data found in a Model.
Definition: Layer.h:52
virtual void setProperties(const QXmlAttributes &)=0
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
SpectrogramLayer represents waveform data (obtained from a DenseTimeValueModel) in spectrogram form.
bool isLayerSliceable(const Layer *)
LayerType getLayerTypeForName(QString)
LayerTypeSet getValidLayerTypes(Model *model)
This is a view that displays dense 3-D data (time, some sort of binned y-axis range,...
Model * createEmptyModel(LayerType type, Model *baseModel)
LayerTypeSet getValidEmptyLayerTypes()
int getChannel(Layer *layer)
void setModel(Layer *layer, Model *model)
virtual void setObjectName(const QString &name)
Definition: Layer.cpp:100
QString getLayerPresentationName(LayerType type)
static LayerFactory * m_instance
Definition: LayerFactory.h:95
void setChannel(Layer *layer, int channel)
Layer * createLayer(LayerType type)
std::set< LayerType > LayerTypeSet
Definition: LayerFactory.h:58
LayerType getLayerType(const Layer *)
LayerType getLayerTypeForClipboardContents(const Clipboard &)
QString getLayerTypeName(LayerType)
virtual ~LayerFactory()
void setLayerDefaultProperties(LayerType type, Layer *layer)