Mercurial > hg > sonic-visualiser
comparison document/Document.h @ 0:cd5d7ff8ef38
* Reorganising code base. This revision will not compile.
author | Chris Cannam |
---|---|
date | Mon, 31 Jul 2006 12:03:45 +0000 |
parents | |
children | 61259228d029 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cd5d7ff8ef38 |
---|---|
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 #ifndef _DOCUMENT_H_ | |
17 #define _DOCUMENT_H_ | |
18 | |
19 #include "layer/LayerFactory.h" | |
20 #include "transform/Transform.h" | |
21 #include "base/Command.h" | |
22 | |
23 #include <map> | |
24 #include <set> | |
25 | |
26 class Model; | |
27 class Layer; | |
28 class View; | |
29 class WaveFileModel; | |
30 | |
31 /** | |
32 * A Sonic Visualiser document consists of a set of data models, and | |
33 * also the visualisation layers used to display them. Changes to the | |
34 * layers and their layout need to be stored and managed in much the | |
35 * same way as changes to the underlying data. | |
36 * | |
37 * The document manages: | |
38 * | |
39 * -- A main data model, which provides the underlying sample rate and | |
40 * such like. This must be a wave file model. | |
41 * | |
42 * -- Any number of imported models, which contain data without any | |
43 * requirement to remember where the data came from or how to | |
44 * regenerate it. | |
45 * | |
46 * -- Any number of models generated by transforms such as feature | |
47 * extraction plugins. For these, we also record the source model and | |
48 * the name of the transform used to generate the model so that we can | |
49 * regenerate it (potentially from a different source) on demand. | |
50 * | |
51 * -- A flat list of layers. Elsewhere, the GUI may distribute these | |
52 * across any number of view widgets. A layer may be viewable on more | |
53 * than one view at once, in principle. A layer refers to one model, | |
54 * but the same model can be in use in more than one layer. | |
55 * | |
56 * The document does *not* manage the existence or structure of Pane | |
57 * and other view widgets. However, it does provide convenience | |
58 * methods for reference-counted command-based management of the | |
59 * association between layers and views (addLayerToView, | |
60 * removeLayerFromView). | |
61 */ | |
62 | |
63 class Document : public QObject, | |
64 public XmlExportable | |
65 { | |
66 Q_OBJECT | |
67 | |
68 public: | |
69 Document(); | |
70 virtual ~Document(); | |
71 | |
72 /** | |
73 * Create and return a new layer of the given type, associated | |
74 * with no model. The caller may set any model on this layer, but | |
75 * the model must also be registered with the document via the | |
76 * add-model methods below. | |
77 */ | |
78 Layer *createLayer(LayerFactory::LayerType); | |
79 | |
80 /** | |
81 * Create and return a new layer of the given type, associated | |
82 * with the current main model (if appropriate to the layer type). | |
83 */ | |
84 Layer *createMainModelLayer(LayerFactory::LayerType); | |
85 | |
86 /** | |
87 * Create and return a new layer associated with the given model, | |
88 * and register the model as an imported model. | |
89 */ | |
90 Layer *createImportedLayer(Model *); | |
91 | |
92 /** | |
93 * Create and return a new layer of the given type, with an | |
94 * appropriate empty model. If the given type is not one for | |
95 * which an empty model can meaningfully be created, return 0. | |
96 */ | |
97 Layer *createEmptyLayer(LayerFactory::LayerType); | |
98 | |
99 /** | |
100 * Create and return a new layer of the given type, associated | |
101 * with the given transform name. This method does not run the | |
102 * transform itself, nor create a model. The caller can safely | |
103 * add a model to the layer later, but note that all models used | |
104 * by a transform layer _must_ be registered with the document | |
105 * using addDerivedModel below. | |
106 */ | |
107 Layer *createDerivedLayer(LayerFactory::LayerType, TransformName); | |
108 | |
109 /** | |
110 * Create and return a suitable layer for the given transform, | |
111 * running the transform and associating the resulting model with | |
112 * the new layer. | |
113 */ | |
114 Layer *createDerivedLayer(TransformName, | |
115 Model *inputModel, | |
116 int inputChannel, // -1 -> all | |
117 QString configurationXml); | |
118 | |
119 /** | |
120 * Set the main model (the source for playback sample rate, etc) | |
121 * to the given wave file model. This will regenerate any derived | |
122 * models that were based on the previous main model. | |
123 */ | |
124 void setMainModel(WaveFileModel *); | |
125 | |
126 /** | |
127 * Get the main model (the source for playback sample rate, etc). | |
128 */ | |
129 WaveFileModel *getMainModel() { return m_mainModel; } | |
130 | |
131 /** | |
132 * Add a derived model associated with the given transform name. | |
133 * This is necessary to register any derived model that was not | |
134 * created by the document using | |
135 * e.g. createDerivedLayer(TransformName) above. | |
136 */ | |
137 void addDerivedModel(TransformName, | |
138 Model *inputModel, | |
139 int inputChannel, // -1 -> all | |
140 Model *outputModelToAdd, | |
141 QString configurationXml); | |
142 | |
143 /** | |
144 * Add an imported (non-derived, non-main) model. This is | |
145 * necessary to register any imported model that is associated | |
146 * with a layer. | |
147 */ | |
148 void addImportedModel(Model *); | |
149 | |
150 /** | |
151 * Associate the given model with the given layer. The model must | |
152 * have already been registered using one of the addXXModel | |
153 * methods above. | |
154 */ | |
155 void setModel(Layer *, Model *); | |
156 | |
157 /** | |
158 * Set the given layer to use the given channel of its model (-1 | |
159 * means all available channels). | |
160 */ | |
161 void setChannel(Layer *, int); | |
162 | |
163 /** | |
164 * Add the given layer to the given view. If the layer is | |
165 * intended to show a particular model, the model should normally | |
166 * be set using setModel before this method is called. | |
167 */ | |
168 void addLayerToView(View *, Layer *); | |
169 | |
170 /** | |
171 * Remove the given layer from the given view. | |
172 */ | |
173 void removeLayerFromView(View *, Layer *); | |
174 | |
175 void toXml(QTextStream &, QString indent, QString extraAttributes) const; | |
176 QString toXmlString(QString indent, QString extraAttributes) const; | |
177 | |
178 signals: | |
179 void layerAdded(Layer *); | |
180 void layerRemoved(Layer *); | |
181 void layerAboutToBeDeleted(Layer *); | |
182 | |
183 // Emitted when a layer is first added to a view, or when it is | |
184 // last removed from a view | |
185 void layerInAView(Layer *, bool); | |
186 | |
187 void modelAdded(Model *); | |
188 void mainModelChanged(WaveFileModel *); // emitted after modelAdded | |
189 void modelAboutToBeDeleted(Model *); | |
190 | |
191 void modelGenerationFailed(QString transformName); | |
192 void modelRegenerationFailed(QString layerName, QString transformName); | |
193 | |
194 protected: | |
195 Model *createModelForTransform(TransformName transform, | |
196 Model *inputModel, | |
197 int channel, | |
198 QString configurationXml); | |
199 void releaseModel(Model *model); | |
200 | |
201 /** | |
202 * Delete the given layer, and also its associated model if no | |
203 * longer used by any other layer. In general, this should be the | |
204 * only method used to delete layers -- doing so directly is a bit | |
205 * of a social gaffe. | |
206 */ | |
207 void deleteLayer(Layer *, bool force = false); | |
208 | |
209 /* | |
210 * Every model that is in use by a layer in the document must be | |
211 * found in either m_mainModel, m_derivedModels or | |
212 * m_importedModels. We own and control the lifespan of all of | |
213 * these models. | |
214 */ | |
215 | |
216 /** | |
217 * The model that provides the underlying sample rate, etc. This | |
218 * model is not reference counted for layers, and is not freed | |
219 * unless it is replaced or the document is deleted. | |
220 */ | |
221 WaveFileModel *m_mainModel; | |
222 | |
223 struct ModelRecord | |
224 { | |
225 // Information associated with a non-main model. If this | |
226 // model is derived from another, then source will be non-NULL | |
227 // and the transform name will be set appropriately. If the | |
228 // transform name is set but source is NULL, then there was a | |
229 // transform involved but the (target) model has been modified | |
230 // since being generated from it. | |
231 const Model *source; | |
232 TransformName transform; | |
233 int channel; | |
234 QString configurationXml; | |
235 | |
236 // Count of the number of layers using this model. | |
237 int refcount; | |
238 }; | |
239 | |
240 typedef std::map<Model *, ModelRecord> ModelMap; | |
241 ModelMap m_models; | |
242 | |
243 class AddLayerCommand : public Command | |
244 { | |
245 public: | |
246 AddLayerCommand(Document *d, View *view, Layer *layer); | |
247 virtual ~AddLayerCommand(); | |
248 | |
249 virtual void execute(); | |
250 virtual void unexecute(); | |
251 virtual QString getName() const { return m_name; } | |
252 | |
253 protected: | |
254 Document *m_d; | |
255 View *m_view; // I don't own this | |
256 Layer *m_layer; // Document owns this, but I determine its lifespans | |
257 QString m_name; | |
258 bool m_added; | |
259 }; | |
260 | |
261 class RemoveLayerCommand : public Command | |
262 { | |
263 public: | |
264 RemoveLayerCommand(Document *d, View *view, Layer *layer); | |
265 virtual ~RemoveLayerCommand(); | |
266 | |
267 virtual void execute(); | |
268 virtual void unexecute(); | |
269 virtual QString getName() const { return m_name; } | |
270 | |
271 protected: | |
272 Document *m_d; | |
273 View *m_view; // I don't own this | |
274 Layer *m_layer; // Document owns this, but I determine its lifespan | |
275 QString m_name; | |
276 bool m_added; | |
277 }; | |
278 | |
279 typedef std::map<Layer *, std::set<View *> > LayerViewMap; | |
280 LayerViewMap m_layerViewMap; | |
281 | |
282 void addToLayerViewMap(Layer *, View *); | |
283 void removeFromLayerViewMap(Layer *, View *); | |
284 | |
285 QString getUniqueLayerName(QString candidate); | |
286 | |
287 /** | |
288 * And these are the layers. We also control the lifespans of | |
289 * these (usually through the commands used to add and remove them). | |
290 */ | |
291 typedef std::set<Layer *> LayerSet; | |
292 LayerSet m_layers; | |
293 }; | |
294 | |
295 #endif |