LayerFactory.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "LayerFactory.h"
00017 
00018 #include "WaveformLayer.h"
00019 #include "SpectrogramLayer.h"
00020 #include "TimeRulerLayer.h"
00021 #include "TimeInstantLayer.h"
00022 #include "TimeValueLayer.h"
00023 #include "NoteLayer.h"
00024 #include "TextLayer.h"
00025 #include "ImageLayer.h"
00026 #include "Colour3DPlotLayer.h"
00027 #include "SpectrumLayer.h"
00028 #include "SliceLayer.h"
00029 #include "SliceableLayer.h"
00030 
00031 #include "base/Clipboard.h"
00032 
00033 #include "data/model/RangeSummarisableTimeValueModel.h"
00034 #include "data/model/DenseTimeValueModel.h"
00035 #include "data/model/SparseOneDimensionalModel.h"
00036 #include "data/model/SparseTimeValueModel.h"
00037 #include "data/model/NoteModel.h"
00038 #include "data/model/TextModel.h"
00039 #include "data/model/ImageModel.h"
00040 #include "data/model/DenseThreeDimensionalModel.h"
00041 #include "data/model/WaveFileModel.h"
00042 #include "data/model/WritableWaveFileModel.h"
00043 
00044 #include <QDomDocument>
00045 #include <QDomElement>
00046 #include <QDomNamedNodeMap>
00047 #include <QDomAttr>
00048 
00049 #include <QSettings>
00050 
00051 LayerFactory *
00052 LayerFactory::m_instance = new LayerFactory;
00053 
00054 LayerFactory *
00055 LayerFactory::getInstance()
00056 {
00057     return m_instance;
00058 }
00059 
00060 LayerFactory::~LayerFactory()
00061 {
00062 }
00063 
00064 QString
00065 LayerFactory::getLayerPresentationName(LayerType type)
00066 {
00067     switch (type) {
00068     case Waveform:     return Layer::tr("Waveform");
00069     case Spectrogram:  return Layer::tr("Spectrogram");
00070     case TimeRuler:    return Layer::tr("Ruler");
00071     case TimeInstants: return Layer::tr("Time Instants");
00072     case TimeValues:   return Layer::tr("Time Values");
00073     case Notes:        return Layer::tr("Notes");
00074     case Text:         return Layer::tr("Text");
00075     case Image:        return Layer::tr("Images");
00076     case Colour3DPlot: return Layer::tr("Colour 3D Plot");
00077     case Spectrum:     return Layer::tr("Spectrum");
00078     case Slice:        return Layer::tr("Time Slice");
00079 
00080     case MelodicRangeSpectrogram:
00081         // The user can change all the parameters of this after the
00082         // fact -- there's nothing permanently melodic-range about it
00083         // that should be encoded in its name
00084         return Layer::tr("Spectrogram");
00085 
00086     case PeakFrequencySpectrogram:
00087         // likewise
00088         return Layer::tr("Spectrogram");
00089 
00090     default: break;
00091     }
00092 
00093     return Layer::tr("Layer");
00094 }
00095 
00096 bool
00097 LayerFactory::isLayerSliceable(const Layer *layer)
00098 {
00099     if (dynamic_cast<const SliceableLayer *>(layer)) {
00100         if (dynamic_cast<const SpectrogramLayer *>(layer)) {
00101 
00103             // problem managing the models.  The source model for the
00104             // slice layer has to be one of the spectrogram's FFT
00105             // models -- that's fine, except that we can't store &
00106             // recall the slice layer with a reference to that model
00107             // because the model is internal to the spectrogram layer
00108             // and the document has no record of it.  We would need
00109             // some other way of managing models that are used in this
00110             // way.  For the moment we just don't allow slices of
00111             // spectrograms -- and provide a spectrum layer for this
00112             // instead.
00113             //
00114             // This business needs a bit more thought -- either come
00115             // up with a sensible way to deal with that stuff, or
00116             // simplify the existing slice layer logic so that it
00117             // doesn't have to deal with models disappearing on it at
00118             // all (and use the normal Document setModel mechanism to
00119             // set its sliceable model instead of the fancy pants
00120             // nonsense it's doing at the moment).
00121 
00122             return false;
00123         }
00124         return true;
00125     }
00126     return false;
00127 }
00128 
00129 LayerFactory::LayerTypeSet
00130 LayerFactory::getValidLayerTypes(Model *model)
00131 {
00132     LayerTypeSet types;
00133 
00134     if (dynamic_cast<DenseThreeDimensionalModel *>(model)) {
00135         types.insert(Colour3DPlot);
00136         types.insert(Slice);
00137     }
00138 
00139     if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) {
00140         types.insert(Waveform);
00141     }
00142 
00143     if (dynamic_cast<DenseTimeValueModel *>(model)) {
00144         types.insert(Spectrogram);
00145         types.insert(MelodicRangeSpectrogram);
00146         types.insert(PeakFrequencySpectrogram);
00147     }
00148 
00149     if (dynamic_cast<SparseOneDimensionalModel *>(model)) {
00150         types.insert(TimeInstants);
00151     }
00152 
00153     if (dynamic_cast<SparseTimeValueModel *>(model)) {
00154         types.insert(TimeValues);
00155     
00156 }
00157     if (dynamic_cast<NoteModel *>(model)) {
00158         types.insert(Notes);
00159     }
00160 
00161     if (dynamic_cast<TextModel *>(model)) {
00162         types.insert(Text);
00163     }
00164 
00165     if (dynamic_cast<ImageModel *>(model)) {
00166         types.insert(Image);
00167     }
00168 
00169     if (dynamic_cast<DenseTimeValueModel *>(model)) {
00170         types.insert(Spectrum);
00171     }
00172 
00173     // We don't count TimeRuler here as it doesn't actually display
00174     // the data, although it can be backed by any model
00175 
00176     return types;
00177 }
00178 
00179 LayerFactory::LayerTypeSet
00180 LayerFactory::getValidEmptyLayerTypes()
00181 {
00182     LayerTypeSet types;
00183     types.insert(TimeInstants);
00184     types.insert(TimeValues);
00185     types.insert(Notes);
00186     types.insert(Text);
00187     types.insert(Image);
00189     return types;
00190 }
00191 
00192 LayerFactory::LayerType
00193 LayerFactory::getLayerType(const Layer *layer)
00194 {
00195     if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform;
00196     if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram;
00197     if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler;
00198     if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants;
00199     if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues;
00200     if (dynamic_cast<const NoteLayer *>(layer)) return Notes;
00201     if (dynamic_cast<const TextLayer *>(layer)) return Text;
00202     if (dynamic_cast<const ImageLayer *>(layer)) return Image;
00203     if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot;
00204     if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum;
00205     if (dynamic_cast<const SliceLayer *>(layer)) return Slice;
00206     return UnknownLayer;
00207 }
00208 
00209 QString
00210 LayerFactory::getLayerIconName(LayerType type)
00211 {
00212     switch (type) {
00213     case Waveform: return "waveform";
00214     case Spectrogram: return "spectrogram";
00215     case TimeRuler: return "timeruler";
00216     case TimeInstants: return "instants";
00217     case TimeValues: return "values";
00218     case Notes: return "notes";
00219     case Text: return "text";
00220     case Image: return "image";
00221     case Colour3DPlot: return "colour3d";
00222     case Spectrum: return "spectrum";
00223     case Slice: return "spectrum";
00224     case MelodicRangeSpectrogram: return "spectrogram";
00225     case PeakFrequencySpectrogram: return "spectrogram";
00226     default: return "unknown";
00227     }
00228 }
00229 
00230 QString
00231 LayerFactory::getLayerTypeName(LayerType type)
00232 {
00233     switch (type) {
00234     case Waveform: return "waveform";
00235     case Spectrogram: return "spectrogram";
00236     case TimeRuler: return "timeruler";
00237     case TimeInstants: return "timeinstants";
00238     case TimeValues: return "timevalues";
00239     case Notes: return "notes";
00240     case Text: return "text";
00241     case Image: return "image";
00242     case Colour3DPlot: return "colour3dplot";
00243     case Spectrum: return "spectrum";
00244     case Slice: return "slice";
00245     case MelodicRangeSpectrogram: return "melodicrange";
00246     case PeakFrequencySpectrogram: return "peakfrequency";
00247     default: return "unknown";
00248     }
00249 }
00250 
00251 LayerFactory::LayerType
00252 LayerFactory::getLayerTypeForName(QString name)
00253 {
00254     if (name == "waveform") return Waveform;
00255     if (name == "spectrogram") return Spectrogram;
00256     if (name == "timeruler") return TimeRuler;
00257     if (name == "timeinstants") return TimeInstants;
00258     if (name == "timevalues") return TimeValues;
00259     if (name == "notes") return Notes;
00260     if (name == "text") return Text;
00261     if (name == "image") return Image;
00262     if (name == "colour3dplot") return Colour3DPlot;
00263     if (name == "spectrum") return Spectrum;
00264     if (name == "slice") return Slice;
00265     return UnknownLayer;
00266 }
00267 
00268 void
00269 LayerFactory::setModel(Layer *layer, Model *model)
00270 {
00271 //    if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model))
00272 //      return;
00273 
00274     if (trySetModel<WaveformLayer, WaveFileModel>(layer, model))
00275         return;
00276 
00277     if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model))
00278         return;
00279 
00280     if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
00281         return;
00282 
00283     if (trySetModel<TimeRulerLayer, Model>(layer, model))
00284         return;
00285 
00286     if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model))
00287         return;
00288 
00289     if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model))
00290         return;
00291 
00292     if (trySetModel<NoteLayer, NoteModel>(layer, model))
00293         return;
00294 
00295     if (trySetModel<TextLayer, TextModel>(layer, model))
00296         return;
00297 
00298     if (trySetModel<ImageLayer, ImageModel>(layer, model))
00299         return;
00300 
00301     if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model))
00302         return;
00303 
00304     if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model))
00305         return;
00306 
00307     if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model)) 
00308         return;
00309 
00310 //    if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model)) 
00311 //        return;
00312 }
00313 
00314 Model *
00315 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel)
00316 {
00317     if (layerType == TimeInstants) {
00318         return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1);
00319     } else if (layerType == TimeValues) {
00320         return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true);
00321     } else if (layerType == Notes) {
00322         return new NoteModel(baseModel->getSampleRate(), 1, true);
00323     } else if (layerType == Text) {
00324         return new TextModel(baseModel->getSampleRate(), 1, true);
00325     } else if (layerType == Image) {
00326         return new ImageModel(baseModel->getSampleRate(), 1, true);
00327     } else {
00328         return 0;
00329     }
00330 }
00331 
00332 int
00333 LayerFactory::getChannel(Layer *layer)
00334 {
00335     if (dynamic_cast<WaveformLayer *>(layer)) {
00336         return dynamic_cast<WaveformLayer *>(layer)->getChannel();
00337     } 
00338     if (dynamic_cast<SpectrogramLayer *>(layer)) {
00339         return dynamic_cast<SpectrogramLayer *>(layer)->getChannel();
00340     }
00341     return -1;
00342 }
00343 
00344 void
00345 LayerFactory::setChannel(Layer *layer, int channel)
00346 {
00347     if (dynamic_cast<WaveformLayer *>(layer)) {
00348         dynamic_cast<WaveformLayer *>(layer)->setChannel(channel);
00349         return;
00350     } 
00351     if (dynamic_cast<SpectrogramLayer *>(layer)) {
00352         dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel);
00353         return;
00354     }
00355     if (dynamic_cast<SpectrumLayer *>(layer)) {
00356         dynamic_cast<SpectrumLayer *>(layer)->setChannel(channel);
00357         return;
00358     }
00359 }
00360 
00361 Layer *
00362 LayerFactory::createLayer(LayerType type)
00363 {
00364     Layer *layer = 0;
00365 
00366     switch (type) {
00367 
00368     case Waveform:
00369         layer = new WaveformLayer;
00370         break;
00371 
00372     case Spectrogram:
00373         layer = new SpectrogramLayer;
00374         break;
00375 
00376     case TimeRuler:
00377         layer = new TimeRulerLayer;
00378         break;
00379 
00380     case TimeInstants:
00381         layer = new TimeInstantLayer;
00382         break;
00383 
00384     case TimeValues:
00385         layer = new TimeValueLayer;
00386         break;
00387 
00388     case Notes:
00389         layer = new NoteLayer;
00390         break;
00391 
00392     case Text:
00393         layer = new TextLayer;
00394         break;
00395 
00396     case Image:
00397         layer = new ImageLayer;
00398         break;
00399 
00400     case Colour3DPlot:
00401         layer = new Colour3DPlotLayer;
00402         break;
00403 
00404     case Spectrum:
00405         layer = new SpectrumLayer;
00406         break;
00407 
00408     case Slice:
00409         layer = new SliceLayer;
00410         break;
00411 
00412     case MelodicRangeSpectrogram: 
00413         layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange);
00414         break;
00415 
00416     case PeakFrequencySpectrogram: 
00417         layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks);
00418         break;
00419 
00420     default: break;
00421     }
00422 
00423     if (!layer) {
00424         std::cerr << "LayerFactory::createLayer: Unknown layer type " 
00425                   << type << std::endl;
00426     } else {
00427 //      std::cerr << "LayerFactory::createLayer: Setting object name "
00428 //                << getLayerPresentationName(type).toStdString() << " on " << layer << std::endl;
00429         layer->setObjectName(getLayerPresentationName(type));
00430         setLayerDefaultProperties(type, layer);
00431     }
00432 
00433     return layer;
00434 }
00435 
00436 void
00437 LayerFactory::setLayerDefaultProperties(LayerType type, Layer *layer)
00438 {
00439 //    std::cerr << "LayerFactory::setLayerDefaultProperties: type " << type << " (name \"" << getLayerTypeName(type).toStdString() << "\")" << std::endl;
00440 
00441     QSettings settings;
00442     settings.beginGroup("LayerDefaults");
00443     QString defaults = settings.value(getLayerTypeName(type), "").toString();
00444     if (defaults == "") return;
00445 
00446 //    std::cerr << "defaults=\"" << defaults.toStdString() << "\"" << std::endl;
00447 
00448     QString xml = layer->toXmlString();
00449     QDomDocument docOld, docNew;
00450     
00451     if (docOld.setContent(xml, false) &&
00452         docNew.setContent(defaults, false)) {
00453         
00454         QXmlAttributes attrs;
00455         
00456         QDomElement layerElt = docNew.firstChildElement("layer");
00457         QDomNamedNodeMap attrNodes = layerElt.attributes();
00458         
00459         for (unsigned int i = 0; i < attrNodes.length(); ++i) {
00460             QDomAttr attr = attrNodes.item(i).toAttr();
00461             if (attr.isNull()) continue;
00462 //            std::cerr << "append \"" << attr.name().toStdString()
00463 //                      << "\" -> \"" << attr.value().toStdString() << "\""
00464 //                      << std::endl;
00465             attrs.append(attr.name(), "", "", attr.value());
00466         }
00467         
00468         layerElt = docOld.firstChildElement("layer");
00469         attrNodes = layerElt.attributes();
00470         for (unsigned int i = 0; i < attrNodes.length(); ++i) {
00471             QDomAttr attr = attrNodes.item(i).toAttr();
00472             if (attr.isNull()) continue;
00473             if (attrs.value(attr.name()) == "") {
00474 //                std::cerr << "append \"" << attr.name().toStdString()
00475 //                          << "\" -> \"" << attr.value().toStdString() << "\""
00476 //                          << std::endl;
00477                 attrs.append(attr.name(), "", "", attr.value());
00478             }
00479         }
00480         
00481         layer->setProperties(attrs);
00482     }
00483 
00484     settings.endGroup();
00485 }
00486 
00487 LayerFactory::LayerType
00488 LayerFactory::getLayerTypeForClipboardContents(const Clipboard &clip)
00489 {
00490     const Clipboard::PointList &contents = clip.getPoints();
00491 
00492     bool haveFrame = false;
00493     bool haveValue = false;
00494     bool haveDuration = false;
00495 
00496     for (Clipboard::PointList::const_iterator i = contents.begin();
00497          i != contents.end(); ++i) {
00498         if (i->haveFrame()) haveFrame = true;
00499         if (i->haveValue()) haveValue = true;
00500         if (i->haveDuration()) haveDuration = true;
00501     }
00502 
00503     if (haveFrame && haveValue && haveDuration) return Notes;
00504     if (haveFrame && haveValue) return TimeValues;
00505     return TimeInstants;
00506 }
00507     

Generated on Wed Feb 20 15:45:26 2008 for SonicVisualiser by  doxygen 1.5.1