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