annotate main/OSCHandler.cpp @ 232:99e0dfd3ea75

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