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