annotate main/OSCHandler.cpp @ 2265:d33dff02b39b sandbox-notarize

Work on sandboxing (possibly) and using the hardened runtime for notarization. Supply appropriate bundle ID for helpers as well as main application, and request inherited sandbox entitlements. Currently works with sandboxing (apparently) but not yet with the hardened runtime, where we can't load plugins signed by third parties even with the com.apple.security.cs.disable-library-validation entitlement because their team IDs don't match the host. Possibly that exception is supposed to be requested some other way?
author Chris Cannam
date Thu, 25 Apr 2019 16:46:02 +0100
parents e9c77a4c865e
children eb7f4579e5cc
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@248 24 #include "widgets/CommandHistory.h"
Chris@1035 25 #include "audio/AudioCallbackPlaySource.h"
Chris@216 26 #include "framework/Document.h"
Chris@216 27 #include "data/fileio/WavFileWriter.h"
Chris@249 28 #include "transform/TransformFactory.h"
Chris@1386 29 #include "widgets/LevelPanWidget.h"
Chris@1431 30 #include "widgets/LevelPanToolButton.h"
Chris@216 31 #include "widgets/AudioDial.h"
Chris@216 32
Chris@1035 33 #include <bqaudioio/SystemPlaybackTarget.h>
Chris@1035 34
Chris@216 35 #include <QFileInfo>
Chris@216 36
Chris@216 37 void
Chris@216 38 MainWindow::handleOSCMessage(const OSCMessage &message)
Chris@216 39 {
Chris@1617 40 SVDEBUG << "OSCHandler: method = \""
Chris@1617 41 << message.getMethod() << "\"" << endl;
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@1617 49 cerr << "OSCHandler: File open failed for path \""
Chris@665 50 << path << "\"" << 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@1617 62 cerr << "OSCHandler: File open failed for path \""
Chris@665 63 << path << "\"" << 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@1617 79 cerr << "OSCHandler: File open failed for path \""
Chris@665 80 << recent[n] << "\"" << 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@1617 91 SVDEBUG << "OSCHandler: Refusing to overwrite existing file in save" << 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@1617 105 SVDEBUG << "OSCHandler: Refusing to overwrite existing file in export" << endl;
Chris@216 106 } else {
Chris@216 107 WavFileWriter writer(path,
Chris@216 108 getMainModel()->getSampleRate(),
Chris@428 109 getMainModel()->getChannelCount(),
Chris@428 110 WavFileWriter::WriteToTemporary);
Chris@216 111 MultiSelection ms = m_viewManager->getSelection();
Chris@216 112 if (!ms.getSelections().empty()) {
Chris@216 113 writer.writeModel(getMainModel(), &ms);
Chris@216 114 } else {
Chris@216 115 writer.writeModel(getMainModel());
Chris@216 116 }
Chris@216 117 }
Chris@216 118 }
Chris@216 119 }
Chris@216 120
Chris@2242 121 } else if (message.getMethod() == "exportlayer") {
Chris@2242 122
Chris@2242 123 QString path;
Chris@2242 124 if (message.getArgCount() == 1 &&
Chris@2242 125 message.getArg(0).canConvert(QVariant::String)) {
Chris@2242 126 path = message.getArg(0).toString();
Chris@2242 127 if (QFileInfo(path).exists()) {
Chris@2242 128 SVDEBUG << "OSCHandler: Refusing to overwrite existing file in layer export" << endl;
Chris@2242 129 } else {
Chris@2242 130 Pane *currentPane = nullptr;
Chris@2242 131 Layer *currentLayer = nullptr;
Chris@2242 132 if (m_paneStack) currentPane = m_paneStack->getCurrentPane();
Chris@2242 133 if (currentPane) currentLayer = currentPane->getSelectedLayer();
Chris@2242 134 if (currentLayer) {
Chris@2242 135 QString error;
Chris@2242 136 if (!exportLayerTo(currentLayer, path, error)) {
Chris@2242 137 SVCERR << "OSCHandler: Failed to export current layer to " << path << ": " << error << endl;
Chris@2242 138 }
Chris@2242 139 } else {
Chris@2242 140 SVCERR << "OSCHandler: No current layer to export" << endl;
Chris@2242 141 }
Chris@2242 142 }
Chris@2242 143 }
Chris@2242 144
Chris@216 145 } else if (message.getMethod() == "jump" ||
Chris@216 146 message.getMethod() == "play") {
Chris@216 147
Chris@216 148 if (getMainModel()) {
Chris@216 149
Chris@922 150 sv_frame_t frame = m_viewManager->getPlaybackFrame();
Chris@216 151 bool selection = false;
Chris@216 152 bool play = (message.getMethod() == "play");
Chris@216 153
Chris@216 154 if (message.getArgCount() == 1) {
Chris@216 155
Chris@216 156 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 157 message.getArg(0).toString() == "selection") {
Chris@216 158
Chris@216 159 selection = true;
Chris@216 160
Chris@216 161 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 162 message.getArg(0).toString() == "end") {
Chris@216 163
Chris@216 164 frame = getMainModel()->getEndFrame();
Chris@216 165
Chris@216 166 } else if (message.getArg(0).canConvert(QVariant::Double)) {
Chris@216 167
Chris@216 168 double time = message.getArg(0).toDouble();
Chris@216 169 if (time < 0.0) time = 0.0;
Chris@216 170
Chris@216 171 frame = lrint(time * getMainModel()->getSampleRate());
Chris@216 172 }
Chris@216 173 }
Chris@216 174
Chris@216 175 if (frame > getMainModel()->getEndFrame()) {
Chris@216 176 frame = getMainModel()->getEndFrame();
Chris@216 177 }
Chris@216 178
Chris@216 179 if (play) {
Chris@216 180 m_viewManager->setPlaySelectionMode(selection);
Chris@216 181 }
Chris@216 182
Chris@216 183 if (selection) {
Chris@216 184 MultiSelection::SelectionList sl = m_viewManager->getSelections();
Chris@216 185 if (!sl.empty()) {
Chris@216 186 frame = sl.begin()->getStartFrame();
Chris@216 187 }
Chris@216 188 }
Chris@216 189
Chris@1617 190 SVDEBUG << "OSCHandler: Setting playback frame to " << frame << endl;
Chris@1617 191
Chris@216 192 m_viewManager->setPlaybackFrame(frame);
Chris@216 193
Chris@1617 194 if (play) {
Chris@1617 195 if (!m_playSource->isPlaying()) {
Chris@1617 196 SVDEBUG << "OSCHandler: Play source is not yet playing, calling play()" << endl;
Chris@1617 197 // handles audio device suspend/resume etc, as
Chris@1617 198 // well as calling m_playSource->play(frame)
Chris@1617 199 MainWindow::play();
Chris@1617 200 } else {
Chris@1617 201 SVDEBUG << "OSCHandler: Play source is already playing, not starting it" << endl;
Chris@1617 202 }
Chris@1617 203 } else {
Chris@1617 204 SVDEBUG << "OSCHandler: Jump only requested, not starting playback" << endl;
Chris@216 205 }
Chris@216 206 }
Chris@216 207
Chris@313 208 } else if (message.getMethod() == "ffwd") {
Chris@313 209
Chris@313 210 if (message.getArgCount() == 1) {
Chris@313 211
Chris@313 212 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@313 213 message.getArg(0).toString() == "similar") {
Chris@313 214
Chris@313 215 ffwdSimilar();
Chris@313 216 }
Chris@313 217 } else {
Chris@313 218
Chris@313 219 ffwd();
Chris@313 220 }
Chris@313 221
Chris@313 222 } else if (message.getMethod() == "rewind") {
Chris@313 223
Chris@313 224 if (message.getArgCount() == 1) {
Chris@313 225
Chris@313 226 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@313 227 message.getArg(0).toString() == "similar") {
Chris@313 228
Chris@313 229 rewindSimilar();
Chris@313 230 }
Chris@313 231 } else {
Chris@313 232
Chris@313 233 rewind();
Chris@313 234 }
Chris@313 235
Chris@216 236 } else if (message.getMethod() == "stop") {
Chris@216 237
Chris@1617 238 if (m_playSource->isPlaying()) {
Chris@1617 239 // As with play, we want to use the MainWindow
Chris@1617 240 // function rather than call m_playSource directly
Chris@1617 241 // because that way the audio driver suspend/resume
Chris@1617 242 // etc is handled properly
Chris@1617 243 MainWindow::stop();
Chris@1617 244 }
Chris@216 245
Chris@216 246 } else if (message.getMethod() == "loop") {
Chris@216 247
Chris@216 248 if (message.getArgCount() == 1 &&
Chris@216 249 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 250
Chris@216 251 QString str = message.getArg(0).toString();
Chris@216 252 if (str == "on") {
Chris@216 253 m_viewManager->setPlayLoopMode(true);
Chris@216 254 } else if (str == "off") {
Chris@216 255 m_viewManager->setPlayLoopMode(false);
Chris@216 256 }
Chris@216 257 }
Chris@216 258
Chris@216 259 } else if (message.getMethod() == "solo") {
Chris@216 260
Chris@216 261 if (message.getArgCount() == 1 &&
Chris@216 262 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 263
Chris@216 264 QString str = message.getArg(0).toString();
Chris@216 265 if (str == "on") {
Chris@216 266 m_viewManager->setPlaySoloMode(true);
Chris@216 267 } else if (str == "off") {
Chris@216 268 m_viewManager->setPlaySoloMode(false);
Chris@216 269 }
Chris@216 270 }
Chris@216 271
Chris@216 272 } else if (message.getMethod() == "select" ||
Chris@216 273 message.getMethod() == "addselect") {
Chris@216 274
Chris@216 275 if (getMainModel()) {
Chris@216 276
Chris@920 277 sv_frame_t f0 = getMainModel()->getStartFrame();
Chris@920 278 sv_frame_t f1 = getMainModel()->getEndFrame();
Chris@216 279
Chris@216 280 bool done = false;
Chris@216 281
Chris@216 282 if (message.getArgCount() == 2 &&
Chris@216 283 message.getArg(0).canConvert(QVariant::Double) &&
Chris@216 284 message.getArg(1).canConvert(QVariant::Double)) {
Chris@216 285
Chris@216 286 double t0 = message.getArg(0).toDouble();
Chris@216 287 double t1 = message.getArg(1).toDouble();
Chris@216 288 if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; }
Chris@216 289 if (t0 < 0.0) t0 = 0.0;
Chris@216 290 if (t1 < 0.0) t1 = 0.0;
Chris@216 291
Chris@216 292 f0 = lrint(t0 * getMainModel()->getSampleRate());
Chris@216 293 f1 = lrint(t1 * getMainModel()->getSampleRate());
Chris@216 294
Chris@216 295 Pane *pane = m_paneStack->getCurrentPane();
Chris@2126 296 Layer *layer = nullptr;
Chris@216 297 if (pane) layer = pane->getSelectedLayer();
Chris@216 298 if (layer) {
Chris@730 299 int resolution;
Chris@216 300 layer->snapToFeatureFrame(pane, f0, resolution,
Chris@216 301 Layer::SnapLeft);
Chris@216 302 layer->snapToFeatureFrame(pane, f1, resolution,
Chris@216 303 Layer::SnapRight);
Chris@216 304 }
Chris@216 305
Chris@216 306 } else if (message.getArgCount() == 1 &&
Chris@216 307 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 308
Chris@216 309 QString str = message.getArg(0).toString();
Chris@216 310 if (str == "none") {
Chris@216 311 m_viewManager->clearSelections();
Chris@216 312 done = true;
Chris@216 313 }
Chris@216 314 }
Chris@216 315
Chris@216 316 if (!done) {
Chris@216 317 if (message.getMethod() == "select") {
Chris@216 318 m_viewManager->setSelection(Selection(f0, f1));
Chris@216 319 } else {
Chris@216 320 m_viewManager->addSelection(Selection(f0, f1));
Chris@216 321 }
Chris@216 322 }
Chris@216 323 }
Chris@216 324
Chris@216 325 } else if (message.getMethod() == "add") {
Chris@216 326
Chris@216 327 if (getMainModel()) {
Chris@216 328
Chris@216 329 if (message.getArgCount() >= 1 &&
Chris@216 330 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 331
Chris@216 332 int channel = -1;
Chris@216 333 if (message.getArgCount() == 2 &&
Chris@216 334 message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 335 channel = message.getArg(0).toInt();
Chris@216 336 if (channel < -1 ||
Chris@216 337 channel > int(getMainModel()->getChannelCount())) {
Chris@1617 338 cerr << "WARNING: OSCHandler: channel "
Chris@665 339 << channel << " out of range" << endl;
Chris@216 340 channel = -1;
Chris@216 341 }
Chris@216 342 }
Chris@216 343
Chris@216 344 QString str = message.getArg(0).toString();
Chris@216 345
Chris@216 346 LayerFactory::LayerType type =
Chris@216 347 LayerFactory::getInstance()->getLayerTypeForName(str);
Chris@216 348
Chris@216 349 if (type == LayerFactory::UnknownLayer) {
Chris@1617 350 cerr << "WARNING: OSCHandler: unknown layer "
Chris@665 351 << "type " << str << endl;
Chris@216 352 } else {
Chris@216 353
Chris@232 354 LayerConfiguration configuration(type,
Chris@232 355 getMainModel(),
Chris@232 356 channel);
Chris@216 357
Chris@216 358 addPane(configuration,
Chris@216 359 tr("Add %1 Pane")
Chris@216 360 .arg(LayerFactory::getInstance()->
Chris@216 361 getLayerPresentationName(type)));
Chris@216 362 }
Chris@216 363 }
Chris@216 364 }
Chris@216 365
Chris@216 366 } else if (message.getMethod() == "undo") {
Chris@216 367
Chris@216 368 CommandHistory::getInstance()->undo();
Chris@216 369
Chris@216 370 } else if (message.getMethod() == "redo") {
Chris@216 371
Chris@216 372 CommandHistory::getInstance()->redo();
Chris@216 373
Chris@216 374 } else if (message.getMethod() == "set") {
Chris@216 375
Chris@216 376 if (message.getArgCount() == 2 &&
Chris@216 377 message.getArg(0).canConvert(QVariant::String) &&
Chris@216 378 message.getArg(1).canConvert(QVariant::Double)) {
Chris@216 379
Chris@216 380 QString property = message.getArg(0).toString();
Chris@216 381 float value = (float)message.getArg(1).toDouble();
Chris@216 382
Chris@216 383 if (property == "gain") {
Chris@216 384 if (value < 0.0) value = 0.0;
Chris@1386 385 m_mainLevelPan->setLevel(value);
Chris@216 386 if (m_playTarget) m_playTarget->setOutputGain(value);
Chris@1617 387 } else if (property == "speed") {
Chris@1617 388 m_playSpeed->setMappedValue(value);
Chris@216 389 } else if (property == "speedup") {
Chris@1617 390
Chris@1617 391 // The speedup method existed before the speed method
Chris@1617 392 // and is a bit weirder.
Chris@1617 393 //
Chris@1617 394 // For speed(x), x is a percentage of normal speed, so
Chris@1617 395 // x=100 means play at the normal speed, x=50 means
Chris@1617 396 // half speed, x=200 double speed etc.
Chris@1617 397 //
Chris@1617 398 // For speedup(x), x was some sort of modifier of
Chris@1617 399 // percentage thing, so x=0 meant play at the normal
Chris@1617 400 // speed, x=50 meant play at 150% of normal speed,
Chris@1617 401 // x=100 meant play at double speed, and x=-100 rather
Chris@1617 402 // bizarrely meant play at half speed. We handle this
Chris@1617 403 // now by converting to speed percentage as follows:
Chris@1617 404
Chris@1617 405 double percentage = 100.0;
Chris@1617 406 if (value > 0.f) {
Chris@1617 407 percentage = percentage + value;
Chris@1617 408 } else {
Chris@1617 409 percentage = 10000.0 / (percentage - value);
Chris@1617 410 }
Chris@1617 411 SVDEBUG << "OSCHandler: converted speedup(" << value
Chris@1617 412 << ") into speed(" << percentage << ")" << endl;
Chris@1617 413
Chris@1617 414 m_playSpeed->setMappedValue(percentage);
Chris@1617 415
Chris@216 416 } else if (property == "overlays") {
Chris@216 417 if (value < 0.5) {
Chris@216 418 m_viewManager->setOverlayMode(ViewManager::NoOverlays);
Chris@216 419 } else if (value < 1.5) {
Chris@701 420 m_viewManager->setOverlayMode(ViewManager::StandardOverlays);
Chris@216 421 } else {
Chris@216 422 m_viewManager->setOverlayMode(ViewManager::AllOverlays);
Chris@216 423 }
Chris@216 424 } else if (property == "zoomwheels") {
Chris@216 425 m_viewManager->setZoomWheelsEnabled(value > 0.5);
Chris@216 426 } else if (property == "propertyboxes") {
Chris@216 427 bool toggle = ((value < 0.5) !=
Chris@216 428 (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks));
Chris@216 429 if (toggle) togglePropertyBoxes();
Chris@216 430 }
Chris@216 431
Chris@216 432 } else {
Chris@2126 433 PropertyContainer *container = nullptr;
Chris@216 434 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 435 if (pane &&
Chris@216 436 message.getArgCount() == 3 &&
Chris@216 437 message.getArg(0).canConvert(QVariant::String) &&
Chris@216 438 message.getArg(1).canConvert(QVariant::String) &&
Chris@216 439 message.getArg(2).canConvert(QVariant::String)) {
Chris@216 440 if (message.getArg(0).toString() == "pane") {
Chris@216 441 container = pane->getPropertyContainer(0);
Chris@216 442 } else if (message.getArg(0).toString() == "layer") {
Chris@216 443 container = pane->getSelectedLayer();
Chris@216 444 }
Chris@216 445 }
Chris@216 446 if (container) {
Chris@216 447 QString nameString = message.getArg(1).toString();
Chris@216 448 QString valueString = message.getArg(2).toString();
Chris@248 449 Command *c = container->getSetPropertyCommand
Chris@248 450 (nameString, valueString);
Chris@248 451 if (c) CommandHistory::getInstance()->addCommand(c, true, true);
Chris@216 452 }
Chris@216 453 }
Chris@216 454
Chris@216 455 } else if (message.getMethod() == "setcurrent") {
Chris@216 456
Chris@216 457 int paneIndex = -1, layerIndex = -1;
Chris@216 458 bool wantLayer = false;
Chris@216 459
Chris@216 460 if (message.getArgCount() >= 1 &&
Chris@216 461 message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 462
Chris@216 463 paneIndex = message.getArg(0).toInt() - 1;
Chris@216 464
Chris@216 465 if (message.getArgCount() >= 2 &&
Chris@216 466 message.getArg(1).canConvert(QVariant::Int)) {
Chris@216 467 wantLayer = true;
Chris@216 468 layerIndex = message.getArg(1).toInt() - 1;
Chris@216 469 }
Chris@216 470 }
Chris@216 471
Chris@216 472 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) {
Chris@216 473 Pane *pane = m_paneStack->getPane(paneIndex);
Chris@216 474 m_paneStack->setCurrentPane(pane);
Chris@216 475 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) {
Chris@216 476 Layer *layer = pane->getLayer(layerIndex);
Chris@216 477 m_paneStack->setCurrentLayer(pane, layer);
Chris@216 478 } else if (wantLayer && layerIndex == -1) {
Chris@2126 479 m_paneStack->setCurrentLayer(pane, nullptr);
Chris@216 480 }
Chris@216 481 }
Chris@216 482
Chris@216 483 } else if (message.getMethod() == "delete") {
Chris@216 484
Chris@216 485 if (message.getArgCount() == 1 &&
Chris@216 486 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 487
Chris@216 488 QString target = message.getArg(0).toString();
Chris@216 489
Chris@216 490 if (target == "pane") {
Chris@216 491
Chris@216 492 deleteCurrentPane();
Chris@216 493
Chris@216 494 } else if (target == "layer") {
Chris@216 495
Chris@216 496 deleteCurrentLayer();
Chris@216 497
Chris@216 498 } else {
Chris@216 499
Chris@1617 500 cerr << "WARNING: OSCHandler: Unknown delete target " << target << endl;
Chris@216 501 }
Chris@216 502 }
Chris@216 503
Chris@216 504 } else if (message.getMethod() == "zoom") {
Chris@216 505
Chris@216 506 if (message.getArgCount() == 1) {
Chris@216 507 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 508 message.getArg(0).toString() == "in") {
Chris@216 509 zoomIn();
Chris@216 510 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 511 message.getArg(0).toString() == "out") {
Chris@216 512 zoomOut();
Chris@216 513 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 514 message.getArg(0).toString() == "default") {
Chris@216 515 zoomDefault();
Chris@312 516 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@312 517 message.getArg(0).toString() == "fit") {
Chris@312 518 zoomToFit();
Chris@216 519 } else if (message.getArg(0).canConvert(QVariant::Double)) {
Chris@216 520 double level = message.getArg(0).toDouble();
Chris@216 521 Pane *currentPane = m_paneStack->getCurrentPane();
Chris@2011 522 ZoomLevel zoomLevel;
Chris@2011 523 if (level >= 0.66) {
Chris@2011 524 zoomLevel = ZoomLevel(ZoomLevel::FramesPerPixel,
Chris@2011 525 int(round(level)));
Chris@2011 526 } else {
Chris@2011 527 zoomLevel = ZoomLevel(ZoomLevel::PixelsPerFrame,
Chris@2011 528 int(round(1.0 / level)));
Chris@2011 529 }
Chris@2011 530 if (currentPane) {
Chris@2011 531 currentPane->setZoomLevel(zoomLevel);
Chris@2011 532 }
Chris@216 533 }
Chris@216 534 }
Chris@216 535
Chris@216 536 } else if (message.getMethod() == "zoomvertical") {
Chris@216 537
Chris@216 538 Pane *pane = m_paneStack->getCurrentPane();
Chris@2126 539 Layer *layer = nullptr;
Chris@216 540 if (pane && pane->getLayerCount() > 0) {
Chris@216 541 layer = pane->getLayer(pane->getLayerCount() - 1);
Chris@216 542 }
Chris@216 543 int defaultStep = 0;
Chris@216 544 int steps = 0;
Chris@216 545 if (layer) {
Chris@216 546 steps = layer->getVerticalZoomSteps(defaultStep);
Chris@216 547 if (message.getArgCount() == 1 && steps > 0) {
Chris@216 548 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 549 message.getArg(0).toString() == "in") {
Chris@216 550 int step = layer->getCurrentVerticalZoomStep() + 1;
Chris@216 551 if (step < steps) layer->setVerticalZoomStep(step);
Chris@216 552 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 553 message.getArg(0).toString() == "out") {
Chris@216 554 int step = layer->getCurrentVerticalZoomStep() - 1;
Chris@216 555 if (step >= 0) layer->setVerticalZoomStep(step);
Chris@216 556 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 557 message.getArg(0).toString() == "default") {
Chris@216 558 layer->setVerticalZoomStep(defaultStep);
Chris@216 559 }
Chris@216 560 } else if (message.getArgCount() == 2) {
Chris@216 561 if (message.getArg(0).canConvert(QVariant::Double) &&
Chris@216 562 message.getArg(1).canConvert(QVariant::Double)) {
Chris@216 563 double min = message.getArg(0).toDouble();
Chris@216 564 double max = message.getArg(1).toDouble();
Chris@216 565 layer->setDisplayExtents(min, max);
Chris@216 566 }
Chris@216 567 }
Chris@216 568 }
Chris@216 569
Chris@216 570 } else if (message.getMethod() == "quit") {
Chris@216 571
Chris@216 572 m_abandoning = true;
Chris@216 573 close();
Chris@216 574
Chris@216 575 } else if (message.getMethod() == "resize") {
Chris@216 576
Chris@216 577 if (message.getArgCount() == 2) {
Chris@216 578
Chris@216 579 int width = 0, height = 0;
Chris@216 580
Chris@216 581 if (message.getArg(1).canConvert(QVariant::Int)) {
Chris@216 582
Chris@216 583 height = message.getArg(1).toInt();
Chris@216 584
Chris@216 585 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 586 message.getArg(0).toString() == "pane") {
Chris@216 587
Chris@216 588 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 589 if (pane) pane->resize(pane->width(), height);
Chris@216 590
Chris@216 591 } else if (message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 592
Chris@216 593 width = message.getArg(0).toInt();
Chris@216 594 resize(width, height);
Chris@216 595 }
Chris@216 596 }
Chris@216 597 }
Chris@216 598
Chris@216 599 } else if (message.getMethod() == "transform") {
Chris@216 600
Chris@216 601 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 602
Chris@216 603 if (getMainModel() &&
Chris@216 604 pane &&
Chris@216 605 message.getArgCount() == 1 &&
Chris@216 606 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 607
Chris@224 608 TransformId transformId = message.getArg(0).toString();
Chris@216 609
Chris@1770 610 Transform transform = TransformFactory::getInstance()->
Chris@224 611 getDefaultTransformFor(transformId);
Chris@1770 612
Chris@216 613 Layer *newLayer = m_document->createDerivedLayer
Chris@224 614 (transform, getMainModel());
Chris@216 615
Chris@216 616 if (newLayer) {
Chris@216 617 m_document->addLayerToView(pane, newLayer);
Chris@224 618 m_recentTransforms.add(transformId);
Chris@216 619 m_paneStack->setCurrentLayer(pane, newLayer);
Chris@216 620 }
Chris@216 621 }
Chris@216 622
Chris@216 623 } else {
Chris@1617 624 cerr << "WARNING: OSCHandler: Unknown or unsupported "
Chris@665 625 << "method \"" << message.getMethod()
Chris@665 626 << "\"" << endl;
Chris@216 627 }
Chris@216 628 }