Chris@127
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@127
|
2
|
Chris@127
|
3 /*
|
Chris@127
|
4 Sonic Visualiser
|
Chris@127
|
5 An audio file viewer and annotation editor.
|
Chris@127
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@182
|
7 This file copyright 2006 Chris Cannam and QMUL.
|
Chris@127
|
8
|
Chris@127
|
9 This program is free software; you can redistribute it and/or
|
Chris@127
|
10 modify it under the terms of the GNU General Public License as
|
Chris@127
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@127
|
12 License, or (at your option) any later version. See the file
|
Chris@127
|
13 COPYING included with this distribution for more information.
|
Chris@127
|
14 */
|
Chris@127
|
15
|
Chris@127
|
16 #include "Layer.h"
|
Chris@128
|
17 #include "view/View.h"
|
Chris@128
|
18 #include "data/model/Model.h"
|
Chris@268
|
19 #include "base/CommandHistory.h"
|
Chris@127
|
20
|
Chris@127
|
21 #include <iostream>
|
Chris@127
|
22
|
Chris@131
|
23 #include <QMutexLocker>
|
Chris@267
|
24 #include <QMouseEvent>
|
Chris@131
|
25
|
Chris@131
|
26 #include "LayerFactory.h"
|
Chris@128
|
27 #include "base/PlayParameterRepository.h"
|
Chris@127
|
28
|
Chris@267
|
29 Layer::Layer() :
|
Chris@267
|
30 m_haveDraggingRect(false)
|
Chris@127
|
31 {
|
Chris@127
|
32 }
|
Chris@127
|
33
|
Chris@127
|
34 Layer::~Layer()
|
Chris@127
|
35 {
|
Chris@127
|
36 // std::cerr << "Layer::~Layer(" << this << ")" << std::endl;
|
Chris@127
|
37 }
|
Chris@127
|
38
|
Chris@127
|
39 QString
|
Chris@127
|
40 Layer::getPropertyContainerIconName() const
|
Chris@127
|
41 {
|
Chris@127
|
42 return LayerFactory::getInstance()->getLayerIconName
|
Chris@127
|
43 (LayerFactory::getInstance()->getLayerType(this));
|
Chris@127
|
44 }
|
Chris@127
|
45
|
Chris@127
|
46 QString
|
Chris@127
|
47 Layer::getLayerPresentationName() const
|
Chris@127
|
48 {
|
Chris@203
|
49 // QString layerName = objectName();
|
Chris@203
|
50
|
Chris@203
|
51 LayerFactory *factory = LayerFactory::getInstance();
|
Chris@203
|
52 QString layerName = factory->getLayerPresentationName
|
Chris@203
|
53 (factory->getLayerType(this));
|
Chris@203
|
54
|
Chris@127
|
55 QString modelName;
|
Chris@127
|
56 if (getModel()) modelName = getModel()->objectName();
|
Chris@127
|
57
|
Chris@127
|
58 QString text;
|
Chris@127
|
59 if (modelName != "") {
|
Chris@127
|
60 text = QString("%1: %2").arg(modelName).arg(layerName);
|
Chris@127
|
61 } else {
|
Chris@127
|
62 text = layerName;
|
Chris@127
|
63 }
|
Chris@127
|
64
|
Chris@127
|
65 return text;
|
Chris@127
|
66 }
|
Chris@127
|
67
|
Chris@127
|
68 void
|
Chris@127
|
69 Layer::setObjectName(const QString &name)
|
Chris@127
|
70 {
|
Chris@127
|
71 QObject::setObjectName(name);
|
Chris@127
|
72 emit layerNameChanged();
|
Chris@127
|
73 }
|
Chris@127
|
74
|
Chris@127
|
75 PlayParameters *
|
Chris@127
|
76 Layer::getPlayParameters()
|
Chris@127
|
77 {
|
Chris@127
|
78 // std::cerr << "Layer (" << this << ", " << objectName().toStdString() << ")::getPlayParameters: model is "<< getModel() << std::endl;
|
Chris@127
|
79 const Model *model = getModel();
|
Chris@127
|
80 if (model) {
|
Chris@127
|
81 return PlayParameterRepository::getInstance()->getPlayParameters(model);
|
Chris@127
|
82 }
|
Chris@127
|
83 return 0;
|
Chris@127
|
84 }
|
Chris@127
|
85
|
Chris@127
|
86 void
|
Chris@131
|
87 Layer::setLayerDormant(const View *v, bool dormant)
|
Chris@131
|
88 {
|
Chris@131
|
89 const void *vv = (const void *)v;
|
Chris@131
|
90 QMutexLocker locker(&m_dormancyMutex);
|
Chris@131
|
91 m_dormancy[vv] = dormant;
|
Chris@131
|
92 }
|
Chris@131
|
93
|
Chris@131
|
94 bool
|
Chris@131
|
95 Layer::isLayerDormant(const View *v) const
|
Chris@131
|
96 {
|
Chris@131
|
97 const void *vv = (const void *)v;
|
Chris@131
|
98 QMutexLocker locker(&m_dormancyMutex);
|
Chris@131
|
99 if (m_dormancy.find(vv) == m_dormancy.end()) return false;
|
Chris@131
|
100 return m_dormancy.find(vv)->second;
|
Chris@131
|
101 }
|
Chris@131
|
102
|
Chris@131
|
103 void
|
Chris@127
|
104 Layer::showLayer(View *view, bool show)
|
Chris@127
|
105 {
|
Chris@127
|
106 setLayerDormant(view, !show);
|
Chris@127
|
107 emit layerParametersChanged();
|
Chris@127
|
108 }
|
Chris@127
|
109
|
Chris@260
|
110 bool
|
Chris@267
|
111 Layer::getXScaleValue(const View *v, int x, float &value, QString &unit) const
|
Chris@260
|
112 {
|
Chris@260
|
113 if (!hasTimeXAxis()) return false;
|
Chris@260
|
114
|
Chris@260
|
115 const Model *m = getModel();
|
Chris@260
|
116 if (!m) return false;
|
Chris@260
|
117
|
Chris@260
|
118 value = float(v->getFrameForX(x)) / m->getSampleRate();
|
Chris@260
|
119 unit = "s";
|
Chris@260
|
120 return true;
|
Chris@260
|
121 }
|
Chris@260
|
122
|
Chris@268
|
123 bool
|
Chris@268
|
124 Layer::MeasureRect::operator<(const MeasureRect &mr) const
|
Chris@268
|
125 {
|
Chris@268
|
126 if (haveFrames) {
|
Chris@268
|
127 if (startFrame == mr.startFrame) {
|
Chris@268
|
128 if (endFrame != mr.endFrame) {
|
Chris@268
|
129 return endFrame < mr.endFrame;
|
Chris@268
|
130 }
|
Chris@268
|
131 } else {
|
Chris@268
|
132 return startFrame < mr.startFrame;
|
Chris@268
|
133 }
|
Chris@268
|
134 } else {
|
Chris@268
|
135 if (pixrect.x() == mr.pixrect.x()) {
|
Chris@268
|
136 if (pixrect.width() != mr.pixrect.width()) {
|
Chris@268
|
137 return pixrect.width() < mr.pixrect.width();
|
Chris@268
|
138 }
|
Chris@268
|
139 } else {
|
Chris@268
|
140 return pixrect.x() < mr.pixrect.x();
|
Chris@268
|
141 }
|
Chris@268
|
142 }
|
Chris@268
|
143
|
Chris@268
|
144 // the two rects are equal in x and width
|
Chris@268
|
145
|
Chris@268
|
146 if (pixrect.y() == mr.pixrect.y()) {
|
Chris@268
|
147 return pixrect.height() < mr.pixrect.height();
|
Chris@268
|
148 } else {
|
Chris@268
|
149 return pixrect.y() < mr.pixrect.y();
|
Chris@268
|
150 }
|
Chris@268
|
151 }
|
Chris@268
|
152
|
Chris@268
|
153 QString
|
Chris@268
|
154 Layer::AddMeasurementRectCommand::getName() const
|
Chris@268
|
155 {
|
Chris@268
|
156 return tr("Make Measurement");
|
Chris@268
|
157 }
|
Chris@268
|
158
|
Chris@268
|
159 void
|
Chris@268
|
160 Layer::AddMeasurementRectCommand::execute()
|
Chris@268
|
161 {
|
Chris@268
|
162 m_layer->addMeasureRect(m_rect);
|
Chris@268
|
163 }
|
Chris@268
|
164
|
Chris@268
|
165 void
|
Chris@268
|
166 Layer::AddMeasurementRectCommand::unexecute()
|
Chris@268
|
167 {
|
Chris@268
|
168 m_layer->deleteMeasureRect(m_rect);
|
Chris@268
|
169 }
|
Chris@268
|
170
|
Chris@267
|
171 void
|
Chris@267
|
172 Layer::measureStart(View *v, QMouseEvent *e)
|
Chris@267
|
173 {
|
Chris@267
|
174 m_draggingRect.pixrect = QRect(e->x(), e->y(), 0, 0);
|
Chris@267
|
175 if (hasTimeXAxis()) {
|
Chris@268
|
176 m_draggingRect.haveFrames = true;
|
Chris@267
|
177 m_draggingRect.startFrame = v->getFrameForX(e->x());
|
Chris@267
|
178 m_draggingRect.endFrame = m_draggingRect.startFrame;
|
Chris@268
|
179 } else {
|
Chris@268
|
180 m_draggingRect.haveFrames = false;
|
Chris@267
|
181 }
|
Chris@267
|
182 m_haveDraggingRect = true;
|
Chris@267
|
183 }
|
Chris@267
|
184
|
Chris@267
|
185 void
|
Chris@267
|
186 Layer::measureDrag(View *v, QMouseEvent *e)
|
Chris@267
|
187 {
|
Chris@267
|
188 if (!m_haveDraggingRect) return;
|
Chris@268
|
189
|
Chris@267
|
190 m_draggingRect.pixrect = QRect(m_draggingRect.pixrect.x(),
|
Chris@267
|
191 m_draggingRect.pixrect.y(),
|
Chris@267
|
192 e->x() - m_draggingRect.pixrect.x(),
|
Chris@268
|
193 e->y() - m_draggingRect.pixrect.y())
|
Chris@268
|
194 .normalized();
|
Chris@268
|
195
|
Chris@267
|
196 if (hasTimeXAxis()) {
|
Chris@267
|
197 m_draggingRect.endFrame = v->getFrameForX(e->x());
|
Chris@267
|
198 }
|
Chris@267
|
199 }
|
Chris@267
|
200
|
Chris@267
|
201 void
|
Chris@267
|
202 Layer::measureEnd(View *v, QMouseEvent *e)
|
Chris@267
|
203 {
|
Chris@267
|
204 if (!m_haveDraggingRect) return;
|
Chris@267
|
205 measureDrag(v, e);
|
Chris@268
|
206
|
Chris@268
|
207 CommandHistory::getInstance()->addCommand
|
Chris@268
|
208 (new AddMeasurementRectCommand(this, m_draggingRect));
|
Chris@268
|
209
|
Chris@267
|
210 m_haveDraggingRect = false;
|
Chris@267
|
211 }
|
Chris@267
|
212
|
Chris@267
|
213 void
|
Chris@267
|
214 Layer::paintMeasurementRects(View *v, QPainter &paint) const
|
Chris@267
|
215 {
|
Chris@267
|
216 if (m_haveDraggingRect) {
|
Chris@268
|
217 paintMeasurementRect(v, paint, m_draggingRect);
|
Chris@267
|
218 }
|
Chris@267
|
219
|
Chris@268
|
220 for (MeasureRectSet::const_iterator i = m_measureRects.begin();
|
Chris@268
|
221 i != m_measureRects.end(); ++i) {
|
Chris@268
|
222 paintMeasurementRect(v, paint, *i);
|
Chris@267
|
223 }
|
Chris@267
|
224 }
|
Chris@267
|
225
|
Chris@268
|
226 void
|
Chris@268
|
227 Layer::paintMeasurementRect(View *v, QPainter &paint, MeasureRect &r)
|
Chris@268
|
228 {
|
Chris@268
|
229 if (r.haveFrames) {
|
Chris@268
|
230
|
Chris@268
|
231 int x0 = -1;
|
Chris@268
|
232 int x1 = v->width() + 1;
|
Chris@268
|
233
|
Chris@268
|
234 if (r.startFrame >= v->getStartFrame()) {
|
Chris@268
|
235 x0 = v->getXForFrame(r.startFrame);
|
Chris@268
|
236 }
|
Chris@268
|
237 if (r.endFrame <= v->getEndFrame()) {
|
Chris@268
|
238 x1 = v->getXForFrame(r.endFrame);
|
Chris@268
|
239 }
|
Chris@268
|
240
|
Chris@268
|
241 QRect pr = QRect(x0, r.pixrect.y(),
|
Chris@268
|
242 x1 - x0, r.pixrect.height());
|
Chris@268
|
243
|
Chris@268
|
244 r.pixrect = pr;
|
Chris@268
|
245 }
|
Chris@268
|
246
|
Chris@268
|
247 v->drawMeasurementRect(paint, this, r.pixrect);
|
Chris@268
|
248 }
|
Chris@268
|
249
|
Chris@268
|
250 QString
|
Chris@268
|
251 Layer::toXmlString(QString indent, QString extraAttributes) const
|
Chris@268
|
252 {
|
Chris@268
|
253 QString s;
|
Chris@268
|
254
|
Chris@268
|
255 s += indent;
|
Chris@268
|
256
|
Chris@268
|
257 s += QString("<layer id=\"%2\" type=\"%1\" name=\"%3\" model=\"%4\" %5/>\n")
|
Chris@268
|
258 .arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName
|
Chris@268
|
259 (LayerFactory::getInstance()->getLayerType(this))))
|
Chris@268
|
260 .arg(getObjectExportId(this))
|
Chris@268
|
261 .arg(encodeEntities(objectName()))
|
Chris@268
|
262 .arg(getObjectExportId(getModel()))
|
Chris@268
|
263 .arg(extraAttributes);
|
Chris@268
|
264
|
Chris@268
|
265 return s;
|
Chris@268
|
266 }
|