Mercurial > hg > sonic-visualiser
comparison main/OSCHandler.cpp @ 216:1fa0d271fd2c
* Pull out MainWindow::handleOSCMessage() into a separate file
author | Chris Cannam |
---|---|
date | Thu, 22 Nov 2007 14:13:20 +0000 |
parents | |
children | b5a2428f647b fc542303eda2 |
comparison
equal
deleted
inserted
replaced
215:79ea249689d9 | 216:1fa0d271fd2c |
---|---|
1 | |
2 #include "MainWindow.h" | |
3 #include "data/osc/OSCQueue.h" | |
4 | |
5 #include "layer/WaveformLayer.h" | |
6 #include "view/ViewManager.h" | |
7 #include "view/Pane.h" | |
8 #include "view/PaneStack.h" | |
9 #include "data/model/WaveFileModel.h" | |
10 #include "base/CommandHistory.h" | |
11 #include "audioio/AudioCallbackPlaySource.h" | |
12 #include "audioio/AudioCallbackPlayTarget.h" | |
13 #include "framework/Document.h" | |
14 #include "data/fileio/WavFileWriter.h" | |
15 #include "plugin/transform/ModelTransformerFactory.h" | |
16 #include "widgets/Fader.h" | |
17 #include "widgets/AudioDial.h" | |
18 | |
19 #include <QFileInfo> | |
20 | |
21 void | |
22 MainWindow::handleOSCMessage(const OSCMessage &message) | |
23 { | |
24 std::cerr << "MainWindow::handleOSCMessage: thread id = " | |
25 << QThread::currentThreadId() << std::endl; | |
26 | |
27 // This large function should really be abstracted out. | |
28 | |
29 if (message.getMethod() == "open") { | |
30 | |
31 if (message.getArgCount() == 1 && | |
32 message.getArg(0).canConvert(QVariant::String)) { | |
33 QString path = message.getArg(0).toString(); | |
34 if (open(path, ReplaceMainModel) != FileOpenSucceeded) { | |
35 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \"" | |
36 << path.toStdString() << "\"" << std::endl; | |
37 } | |
38 //!!! we really need to spin here and not return until the | |
39 // file has been completely decoded... | |
40 } | |
41 | |
42 } else if (message.getMethod() == "openadditional") { | |
43 | |
44 if (message.getArgCount() == 1 && | |
45 message.getArg(0).canConvert(QVariant::String)) { | |
46 QString path = message.getArg(0).toString(); | |
47 if (open(path, CreateAdditionalModel) != FileOpenSucceeded) { | |
48 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \"" | |
49 << path.toStdString() << "\"" << std::endl; | |
50 } | |
51 } | |
52 | |
53 } else if (message.getMethod() == "recent" || | |
54 message.getMethod() == "last") { | |
55 | |
56 int n = 0; | |
57 if (message.getMethod() == "recent" && | |
58 message.getArgCount() == 1 && | |
59 message.getArg(0).canConvert(QVariant::Int)) { | |
60 n = message.getArg(0).toInt() - 1; | |
61 } | |
62 std::vector<QString> recent = m_recentFiles.getRecent(); | |
63 if (n >= 0 && n < int(recent.size())) { | |
64 if (open(recent[n], ReplaceMainModel) != FileOpenSucceeded) { | |
65 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \"" | |
66 << recent[n].toStdString() << "\"" << std::endl; | |
67 } | |
68 } | |
69 | |
70 } else if (message.getMethod() == "save") { | |
71 | |
72 QString path; | |
73 if (message.getArgCount() == 1 && | |
74 message.getArg(0).canConvert(QVariant::String)) { | |
75 path = message.getArg(0).toString(); | |
76 if (QFileInfo(path).exists()) { | |
77 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in save" << std::endl; | |
78 } else { | |
79 saveSessionFile(path); | |
80 } | |
81 } | |
82 | |
83 } else if (message.getMethod() == "export") { | |
84 | |
85 QString path; | |
86 if (getMainModel()) { | |
87 if (message.getArgCount() == 1 && | |
88 message.getArg(0).canConvert(QVariant::String)) { | |
89 path = message.getArg(0).toString(); | |
90 if (QFileInfo(path).exists()) { | |
91 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in export" << std::endl; | |
92 } else { | |
93 WavFileWriter writer(path, | |
94 getMainModel()->getSampleRate(), | |
95 getMainModel()->getChannelCount()); | |
96 MultiSelection ms = m_viewManager->getSelection(); | |
97 if (!ms.getSelections().empty()) { | |
98 writer.writeModel(getMainModel(), &ms); | |
99 } else { | |
100 writer.writeModel(getMainModel()); | |
101 } | |
102 } | |
103 } | |
104 } | |
105 | |
106 } else if (message.getMethod() == "jump" || | |
107 message.getMethod() == "play") { | |
108 | |
109 if (getMainModel()) { | |
110 | |
111 unsigned long frame = m_viewManager->getPlaybackFrame(); | |
112 bool selection = false; | |
113 bool play = (message.getMethod() == "play"); | |
114 | |
115 if (message.getArgCount() == 1) { | |
116 | |
117 if (message.getArg(0).canConvert(QVariant::String) && | |
118 message.getArg(0).toString() == "selection") { | |
119 | |
120 selection = true; | |
121 | |
122 } else if (message.getArg(0).canConvert(QVariant::String) && | |
123 message.getArg(0).toString() == "end") { | |
124 | |
125 frame = getMainModel()->getEndFrame(); | |
126 | |
127 } else if (message.getArg(0).canConvert(QVariant::Double)) { | |
128 | |
129 double time = message.getArg(0).toDouble(); | |
130 if (time < 0.0) time = 0.0; | |
131 | |
132 frame = lrint(time * getMainModel()->getSampleRate()); | |
133 } | |
134 } | |
135 | |
136 if (frame > getMainModel()->getEndFrame()) { | |
137 frame = getMainModel()->getEndFrame(); | |
138 } | |
139 | |
140 if (play) { | |
141 m_viewManager->setPlaySelectionMode(selection); | |
142 } | |
143 | |
144 if (selection) { | |
145 MultiSelection::SelectionList sl = m_viewManager->getSelections(); | |
146 if (!sl.empty()) { | |
147 frame = sl.begin()->getStartFrame(); | |
148 } | |
149 } | |
150 | |
151 m_viewManager->setPlaybackFrame(frame); | |
152 | |
153 if (play && !m_playSource->isPlaying()) { | |
154 m_playSource->play(frame); | |
155 } | |
156 } | |
157 | |
158 } else if (message.getMethod() == "stop") { | |
159 | |
160 if (m_playSource->isPlaying()) m_playSource->stop(); | |
161 | |
162 } else if (message.getMethod() == "loop") { | |
163 | |
164 if (message.getArgCount() == 1 && | |
165 message.getArg(0).canConvert(QVariant::String)) { | |
166 | |
167 QString str = message.getArg(0).toString(); | |
168 if (str == "on") { | |
169 m_viewManager->setPlayLoopMode(true); | |
170 } else if (str == "off") { | |
171 m_viewManager->setPlayLoopMode(false); | |
172 } | |
173 } | |
174 | |
175 } else if (message.getMethod() == "solo") { | |
176 | |
177 if (message.getArgCount() == 1 && | |
178 message.getArg(0).canConvert(QVariant::String)) { | |
179 | |
180 QString str = message.getArg(0).toString(); | |
181 if (str == "on") { | |
182 m_viewManager->setPlaySoloMode(true); | |
183 } else if (str == "off") { | |
184 m_viewManager->setPlaySoloMode(false); | |
185 } | |
186 } | |
187 | |
188 } else if (message.getMethod() == "select" || | |
189 message.getMethod() == "addselect") { | |
190 | |
191 if (getMainModel()) { | |
192 | |
193 int f0 = getMainModel()->getStartFrame(); | |
194 int f1 = getMainModel()->getEndFrame(); | |
195 | |
196 bool done = false; | |
197 | |
198 if (message.getArgCount() == 2 && | |
199 message.getArg(0).canConvert(QVariant::Double) && | |
200 message.getArg(1).canConvert(QVariant::Double)) { | |
201 | |
202 double t0 = message.getArg(0).toDouble(); | |
203 double t1 = message.getArg(1).toDouble(); | |
204 if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; } | |
205 if (t0 < 0.0) t0 = 0.0; | |
206 if (t1 < 0.0) t1 = 0.0; | |
207 | |
208 f0 = lrint(t0 * getMainModel()->getSampleRate()); | |
209 f1 = lrint(t1 * getMainModel()->getSampleRate()); | |
210 | |
211 Pane *pane = m_paneStack->getCurrentPane(); | |
212 Layer *layer = 0; | |
213 if (pane) layer = pane->getSelectedLayer(); | |
214 if (layer) { | |
215 size_t resolution; | |
216 layer->snapToFeatureFrame(pane, f0, resolution, | |
217 Layer::SnapLeft); | |
218 layer->snapToFeatureFrame(pane, f1, resolution, | |
219 Layer::SnapRight); | |
220 } | |
221 | |
222 } else if (message.getArgCount() == 1 && | |
223 message.getArg(0).canConvert(QVariant::String)) { | |
224 | |
225 QString str = message.getArg(0).toString(); | |
226 if (str == "none") { | |
227 m_viewManager->clearSelections(); | |
228 done = true; | |
229 } | |
230 } | |
231 | |
232 if (!done) { | |
233 if (message.getMethod() == "select") { | |
234 m_viewManager->setSelection(Selection(f0, f1)); | |
235 } else { | |
236 m_viewManager->addSelection(Selection(f0, f1)); | |
237 } | |
238 } | |
239 } | |
240 | |
241 } else if (message.getMethod() == "add") { | |
242 | |
243 if (getMainModel()) { | |
244 | |
245 if (message.getArgCount() >= 1 && | |
246 message.getArg(0).canConvert(QVariant::String)) { | |
247 | |
248 int channel = -1; | |
249 if (message.getArgCount() == 2 && | |
250 message.getArg(0).canConvert(QVariant::Int)) { | |
251 channel = message.getArg(0).toInt(); | |
252 if (channel < -1 || | |
253 channel > int(getMainModel()->getChannelCount())) { | |
254 std::cerr << "WARNING: MainWindow::handleOSCMessage: channel " | |
255 << channel << " out of range" << std::endl; | |
256 channel = -1; | |
257 } | |
258 } | |
259 | |
260 QString str = message.getArg(0).toString(); | |
261 | |
262 LayerFactory::LayerType type = | |
263 LayerFactory::getInstance()->getLayerTypeForName(str); | |
264 | |
265 if (type == LayerFactory::UnknownLayer) { | |
266 std::cerr << "WARNING: MainWindow::handleOSCMessage: unknown layer " | |
267 << "type " << str.toStdString() << std::endl; | |
268 } else { | |
269 | |
270 PaneConfiguration configuration(type, | |
271 getMainModel(), | |
272 channel); | |
273 | |
274 addPane(configuration, | |
275 tr("Add %1 Pane") | |
276 .arg(LayerFactory::getInstance()-> | |
277 getLayerPresentationName(type))); | |
278 } | |
279 } | |
280 } | |
281 | |
282 } else if (message.getMethod() == "undo") { | |
283 | |
284 CommandHistory::getInstance()->undo(); | |
285 | |
286 } else if (message.getMethod() == "redo") { | |
287 | |
288 CommandHistory::getInstance()->redo(); | |
289 | |
290 } else if (message.getMethod() == "set") { | |
291 | |
292 if (message.getArgCount() == 2 && | |
293 message.getArg(0).canConvert(QVariant::String) && | |
294 message.getArg(1).canConvert(QVariant::Double)) { | |
295 | |
296 QString property = message.getArg(0).toString(); | |
297 float value = (float)message.getArg(1).toDouble(); | |
298 | |
299 if (property == "gain") { | |
300 if (value < 0.0) value = 0.0; | |
301 m_fader->setValue(value); | |
302 if (m_playTarget) m_playTarget->setOutputGain(value); | |
303 } else if (property == "speedup") { | |
304 m_playSpeed->setMappedValue(value); | |
305 } else if (property == "overlays") { | |
306 if (value < 0.5) { | |
307 m_viewManager->setOverlayMode(ViewManager::NoOverlays); | |
308 } else if (value < 1.5) { | |
309 m_viewManager->setOverlayMode(ViewManager::MinimalOverlays); | |
310 } else if (value < 2.5) { | |
311 m_viewManager->setOverlayMode(ViewManager::StandardOverlays); | |
312 } else { | |
313 m_viewManager->setOverlayMode(ViewManager::AllOverlays); | |
314 } | |
315 } else if (property == "zoomwheels") { | |
316 m_viewManager->setZoomWheelsEnabled(value > 0.5); | |
317 } else if (property == "propertyboxes") { | |
318 bool toggle = ((value < 0.5) != | |
319 (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks)); | |
320 if (toggle) togglePropertyBoxes(); | |
321 } | |
322 | |
323 } else { | |
324 PropertyContainer *container = 0; | |
325 Pane *pane = m_paneStack->getCurrentPane(); | |
326 if (pane && | |
327 message.getArgCount() == 3 && | |
328 message.getArg(0).canConvert(QVariant::String) && | |
329 message.getArg(1).canConvert(QVariant::String) && | |
330 message.getArg(2).canConvert(QVariant::String)) { | |
331 if (message.getArg(0).toString() == "pane") { | |
332 container = pane->getPropertyContainer(0); | |
333 } else if (message.getArg(0).toString() == "layer") { | |
334 container = pane->getSelectedLayer(); | |
335 } | |
336 } | |
337 if (container) { | |
338 QString nameString = message.getArg(1).toString(); | |
339 QString valueString = message.getArg(2).toString(); | |
340 container->setPropertyWithCommand(nameString, valueString); | |
341 } | |
342 } | |
343 | |
344 } else if (message.getMethod() == "setcurrent") { | |
345 | |
346 int paneIndex = -1, layerIndex = -1; | |
347 bool wantLayer = false; | |
348 | |
349 if (message.getArgCount() >= 1 && | |
350 message.getArg(0).canConvert(QVariant::Int)) { | |
351 | |
352 paneIndex = message.getArg(0).toInt() - 1; | |
353 | |
354 if (message.getArgCount() >= 2 && | |
355 message.getArg(1).canConvert(QVariant::Int)) { | |
356 wantLayer = true; | |
357 layerIndex = message.getArg(1).toInt() - 1; | |
358 } | |
359 } | |
360 | |
361 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) { | |
362 Pane *pane = m_paneStack->getPane(paneIndex); | |
363 m_paneStack->setCurrentPane(pane); | |
364 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) { | |
365 Layer *layer = pane->getLayer(layerIndex); | |
366 m_paneStack->setCurrentLayer(pane, layer); | |
367 } else if (wantLayer && layerIndex == -1) { | |
368 m_paneStack->setCurrentLayer(pane, 0); | |
369 } | |
370 } | |
371 | |
372 } else if (message.getMethod() == "delete") { | |
373 | |
374 if (message.getArgCount() == 1 && | |
375 message.getArg(0).canConvert(QVariant::String)) { | |
376 | |
377 QString target = message.getArg(0).toString(); | |
378 | |
379 if (target == "pane") { | |
380 | |
381 deleteCurrentPane(); | |
382 | |
383 } else if (target == "layer") { | |
384 | |
385 deleteCurrentLayer(); | |
386 | |
387 } else { | |
388 | |
389 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown delete target " << target.toStdString() << std::endl; | |
390 } | |
391 } | |
392 | |
393 } else if (message.getMethod() == "zoom") { | |
394 | |
395 if (message.getArgCount() == 1) { | |
396 if (message.getArg(0).canConvert(QVariant::String) && | |
397 message.getArg(0).toString() == "in") { | |
398 zoomIn(); | |
399 } else if (message.getArg(0).canConvert(QVariant::String) && | |
400 message.getArg(0).toString() == "out") { | |
401 zoomOut(); | |
402 } else if (message.getArg(0).canConvert(QVariant::String) && | |
403 message.getArg(0).toString() == "default") { | |
404 zoomDefault(); | |
405 } else if (message.getArg(0).canConvert(QVariant::Double)) { | |
406 double level = message.getArg(0).toDouble(); | |
407 Pane *currentPane = m_paneStack->getCurrentPane(); | |
408 if (level < 1.0) level = 1.0; | |
409 if (currentPane) currentPane->setZoomLevel(lrint(level)); | |
410 } | |
411 } | |
412 | |
413 } else if (message.getMethod() == "zoomvertical") { | |
414 | |
415 Pane *pane = m_paneStack->getCurrentPane(); | |
416 Layer *layer = 0; | |
417 if (pane && pane->getLayerCount() > 0) { | |
418 layer = pane->getLayer(pane->getLayerCount() - 1); | |
419 } | |
420 int defaultStep = 0; | |
421 int steps = 0; | |
422 if (layer) { | |
423 steps = layer->getVerticalZoomSteps(defaultStep); | |
424 if (message.getArgCount() == 1 && steps > 0) { | |
425 if (message.getArg(0).canConvert(QVariant::String) && | |
426 message.getArg(0).toString() == "in") { | |
427 int step = layer->getCurrentVerticalZoomStep() + 1; | |
428 if (step < steps) layer->setVerticalZoomStep(step); | |
429 } else if (message.getArg(0).canConvert(QVariant::String) && | |
430 message.getArg(0).toString() == "out") { | |
431 int step = layer->getCurrentVerticalZoomStep() - 1; | |
432 if (step >= 0) layer->setVerticalZoomStep(step); | |
433 } else if (message.getArg(0).canConvert(QVariant::String) && | |
434 message.getArg(0).toString() == "default") { | |
435 layer->setVerticalZoomStep(defaultStep); | |
436 } | |
437 } else if (message.getArgCount() == 2) { | |
438 if (message.getArg(0).canConvert(QVariant::Double) && | |
439 message.getArg(1).canConvert(QVariant::Double)) { | |
440 double min = message.getArg(0).toDouble(); | |
441 double max = message.getArg(1).toDouble(); | |
442 layer->setDisplayExtents(min, max); | |
443 } | |
444 } | |
445 } | |
446 | |
447 } else if (message.getMethod() == "quit") { | |
448 | |
449 m_abandoning = true; | |
450 close(); | |
451 | |
452 } else if (message.getMethod() == "resize") { | |
453 | |
454 if (message.getArgCount() == 2) { | |
455 | |
456 int width = 0, height = 0; | |
457 | |
458 if (message.getArg(1).canConvert(QVariant::Int)) { | |
459 | |
460 height = message.getArg(1).toInt(); | |
461 | |
462 if (message.getArg(0).canConvert(QVariant::String) && | |
463 message.getArg(0).toString() == "pane") { | |
464 | |
465 Pane *pane = m_paneStack->getCurrentPane(); | |
466 if (pane) pane->resize(pane->width(), height); | |
467 | |
468 } else if (message.getArg(0).canConvert(QVariant::Int)) { | |
469 | |
470 width = message.getArg(0).toInt(); | |
471 resize(width, height); | |
472 } | |
473 } | |
474 } | |
475 | |
476 } else if (message.getMethod() == "transform") { | |
477 | |
478 Pane *pane = m_paneStack->getCurrentPane(); | |
479 | |
480 if (getMainModel() && | |
481 pane && | |
482 message.getArgCount() == 1 && | |
483 message.getArg(0).canConvert(QVariant::String)) { | |
484 | |
485 TransformId transform = message.getArg(0).toString(); | |
486 | |
487 Layer *newLayer = m_document->createDerivedLayer | |
488 (transform, | |
489 getMainModel(), | |
490 ModelTransformerFactory::getInstance()->getDefaultContextForTransformer | |
491 (transform, getMainModel()), | |
492 ""); | |
493 | |
494 if (newLayer) { | |
495 m_document->addLayerToView(pane, newLayer); | |
496 m_recentTransforms.add(transform); | |
497 m_paneStack->setCurrentLayer(pane, newLayer); | |
498 } | |
499 } | |
500 | |
501 } else { | |
502 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported " | |
503 << "method \"" << message.getMethod().toStdString() | |
504 << "\"" << std::endl; | |
505 } | |
506 | |
507 } |