annotate main/OSCHandler.cpp @ 1617:afe620d017d7

Update OSC handler: fix play (which wasn't working because it didn't resume audio driver) and speedup (wrong mapping for the new speed controls), and add more sensible new speed method
author Chris Cannam
date Mon, 27 Feb 2017 15:07:27 +0000
parents f013210eeceb
children 893f556cd5c9
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 // This large function should really be abstracted out.
Chris@216 44
Chris@216 45 if (message.getMethod() == "open") {
Chris@216 46
Chris@216 47 if (message.getArgCount() == 1 &&
Chris@216 48 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 49 QString path = message.getArg(0).toString();
Chris@216 50 if (open(path, ReplaceMainModel) != FileOpenSucceeded) {
Chris@1617 51 cerr << "OSCHandler: File open failed for path \""
Chris@665 52 << path << "\"" << endl;
Chris@216 53 }
Chris@216 54 //!!! we really need to spin here and not return until the
Chris@216 55 // file has been completely decoded...
Chris@216 56 }
Chris@216 57
Chris@216 58 } else if (message.getMethod() == "openadditional") {
Chris@216 59
Chris@216 60 if (message.getArgCount() == 1 &&
Chris@216 61 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 62 QString path = message.getArg(0).toString();
Chris@216 63 if (open(path, CreateAdditionalModel) != FileOpenSucceeded) {
Chris@1617 64 cerr << "OSCHandler: File open failed for path \""
Chris@665 65 << path << "\"" << endl;
Chris@216 66 }
Chris@216 67 }
Chris@216 68
Chris@216 69 } else if (message.getMethod() == "recent" ||
Chris@216 70 message.getMethod() == "last") {
Chris@216 71
Chris@216 72 int n = 0;
Chris@216 73 if (message.getMethod() == "recent" &&
Chris@216 74 message.getArgCount() == 1 &&
Chris@216 75 message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 76 n = message.getArg(0).toInt() - 1;
Chris@216 77 }
Chris@216 78 std::vector<QString> recent = m_recentFiles.getRecent();
Chris@216 79 if (n >= 0 && n < int(recent.size())) {
Chris@216 80 if (open(recent[n], ReplaceMainModel) != FileOpenSucceeded) {
Chris@1617 81 cerr << "OSCHandler: File open failed for path \""
Chris@665 82 << recent[n] << "\"" << endl;
Chris@216 83 }
Chris@216 84 }
Chris@216 85
Chris@216 86 } else if (message.getMethod() == "save") {
Chris@216 87
Chris@216 88 QString path;
Chris@216 89 if (message.getArgCount() == 1 &&
Chris@216 90 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 91 path = message.getArg(0).toString();
Chris@216 92 if (QFileInfo(path).exists()) {
Chris@1617 93 SVDEBUG << "OSCHandler: Refusing to overwrite existing file in save" << endl;
Chris@216 94 } else {
Chris@216 95 saveSessionFile(path);
Chris@216 96 }
Chris@216 97 }
Chris@216 98
Chris@216 99 } else if (message.getMethod() == "export") {
Chris@216 100
Chris@216 101 QString path;
Chris@216 102 if (getMainModel()) {
Chris@216 103 if (message.getArgCount() == 1 &&
Chris@216 104 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 105 path = message.getArg(0).toString();
Chris@216 106 if (QFileInfo(path).exists()) {
Chris@1617 107 SVDEBUG << "OSCHandler: Refusing to overwrite existing file in export" << endl;
Chris@216 108 } else {
Chris@216 109 WavFileWriter writer(path,
Chris@216 110 getMainModel()->getSampleRate(),
Chris@428 111 getMainModel()->getChannelCount(),
Chris@428 112 WavFileWriter::WriteToTemporary);
Chris@216 113 MultiSelection ms = m_viewManager->getSelection();
Chris@216 114 if (!ms.getSelections().empty()) {
Chris@216 115 writer.writeModel(getMainModel(), &ms);
Chris@216 116 } else {
Chris@216 117 writer.writeModel(getMainModel());
Chris@216 118 }
Chris@216 119 }
Chris@216 120 }
Chris@216 121 }
Chris@216 122
Chris@216 123 } else if (message.getMethod() == "jump" ||
Chris@216 124 message.getMethod() == "play") {
Chris@216 125
Chris@216 126 if (getMainModel()) {
Chris@216 127
Chris@922 128 sv_frame_t frame = m_viewManager->getPlaybackFrame();
Chris@216 129 bool selection = false;
Chris@216 130 bool play = (message.getMethod() == "play");
Chris@216 131
Chris@216 132 if (message.getArgCount() == 1) {
Chris@216 133
Chris@216 134 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 135 message.getArg(0).toString() == "selection") {
Chris@216 136
Chris@216 137 selection = true;
Chris@216 138
Chris@216 139 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 140 message.getArg(0).toString() == "end") {
Chris@216 141
Chris@216 142 frame = getMainModel()->getEndFrame();
Chris@216 143
Chris@216 144 } else if (message.getArg(0).canConvert(QVariant::Double)) {
Chris@216 145
Chris@216 146 double time = message.getArg(0).toDouble();
Chris@216 147 if (time < 0.0) time = 0.0;
Chris@216 148
Chris@216 149 frame = lrint(time * getMainModel()->getSampleRate());
Chris@216 150 }
Chris@216 151 }
Chris@216 152
Chris@216 153 if (frame > getMainModel()->getEndFrame()) {
Chris@216 154 frame = getMainModel()->getEndFrame();
Chris@216 155 }
Chris@216 156
Chris@216 157 if (play) {
Chris@216 158 m_viewManager->setPlaySelectionMode(selection);
Chris@216 159 }
Chris@216 160
Chris@216 161 if (selection) {
Chris@216 162 MultiSelection::SelectionList sl = m_viewManager->getSelections();
Chris@216 163 if (!sl.empty()) {
Chris@216 164 frame = sl.begin()->getStartFrame();
Chris@216 165 }
Chris@216 166 }
Chris@216 167
Chris@1617 168 SVDEBUG << "OSCHandler: Setting playback frame to " << frame << endl;
Chris@1617 169
Chris@216 170 m_viewManager->setPlaybackFrame(frame);
Chris@216 171
Chris@1617 172 if (play) {
Chris@1617 173 if (!m_playSource->isPlaying()) {
Chris@1617 174 SVDEBUG << "OSCHandler: Play source is not yet playing, calling play()" << endl;
Chris@1617 175 // handles audio device suspend/resume etc, as
Chris@1617 176 // well as calling m_playSource->play(frame)
Chris@1617 177 MainWindow::play();
Chris@1617 178 } else {
Chris@1617 179 SVDEBUG << "OSCHandler: Play source is already playing, not starting it" << endl;
Chris@1617 180 }
Chris@1617 181 } else {
Chris@1617 182 SVDEBUG << "OSCHandler: Jump only requested, not starting playback" << endl;
Chris@216 183 }
Chris@216 184 }
Chris@216 185
Chris@313 186 } else if (message.getMethod() == "ffwd") {
Chris@313 187
Chris@313 188 if (message.getArgCount() == 1) {
Chris@313 189
Chris@313 190 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@313 191 message.getArg(0).toString() == "similar") {
Chris@313 192
Chris@313 193 ffwdSimilar();
Chris@313 194 }
Chris@313 195 } else {
Chris@313 196
Chris@313 197 ffwd();
Chris@313 198 }
Chris@313 199
Chris@313 200 } else if (message.getMethod() == "rewind") {
Chris@313 201
Chris@313 202 if (message.getArgCount() == 1) {
Chris@313 203
Chris@313 204 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@313 205 message.getArg(0).toString() == "similar") {
Chris@313 206
Chris@313 207 rewindSimilar();
Chris@313 208 }
Chris@313 209 } else {
Chris@313 210
Chris@313 211 rewind();
Chris@313 212 }
Chris@313 213
Chris@216 214 } else if (message.getMethod() == "stop") {
Chris@216 215
Chris@1617 216 if (m_playSource->isPlaying()) {
Chris@1617 217 // As with play, we want to use the MainWindow
Chris@1617 218 // function rather than call m_playSource directly
Chris@1617 219 // because that way the audio driver suspend/resume
Chris@1617 220 // etc is handled properly
Chris@1617 221 MainWindow::stop();
Chris@1617 222 }
Chris@216 223
Chris@216 224 } else if (message.getMethod() == "loop") {
Chris@216 225
Chris@216 226 if (message.getArgCount() == 1 &&
Chris@216 227 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 228
Chris@216 229 QString str = message.getArg(0).toString();
Chris@216 230 if (str == "on") {
Chris@216 231 m_viewManager->setPlayLoopMode(true);
Chris@216 232 } else if (str == "off") {
Chris@216 233 m_viewManager->setPlayLoopMode(false);
Chris@216 234 }
Chris@216 235 }
Chris@216 236
Chris@216 237 } else if (message.getMethod() == "solo") {
Chris@216 238
Chris@216 239 if (message.getArgCount() == 1 &&
Chris@216 240 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 241
Chris@216 242 QString str = message.getArg(0).toString();
Chris@216 243 if (str == "on") {
Chris@216 244 m_viewManager->setPlaySoloMode(true);
Chris@216 245 } else if (str == "off") {
Chris@216 246 m_viewManager->setPlaySoloMode(false);
Chris@216 247 }
Chris@216 248 }
Chris@216 249
Chris@216 250 } else if (message.getMethod() == "select" ||
Chris@216 251 message.getMethod() == "addselect") {
Chris@216 252
Chris@216 253 if (getMainModel()) {
Chris@216 254
Chris@920 255 sv_frame_t f0 = getMainModel()->getStartFrame();
Chris@920 256 sv_frame_t f1 = getMainModel()->getEndFrame();
Chris@216 257
Chris@216 258 bool done = false;
Chris@216 259
Chris@216 260 if (message.getArgCount() == 2 &&
Chris@216 261 message.getArg(0).canConvert(QVariant::Double) &&
Chris@216 262 message.getArg(1).canConvert(QVariant::Double)) {
Chris@216 263
Chris@216 264 double t0 = message.getArg(0).toDouble();
Chris@216 265 double t1 = message.getArg(1).toDouble();
Chris@216 266 if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; }
Chris@216 267 if (t0 < 0.0) t0 = 0.0;
Chris@216 268 if (t1 < 0.0) t1 = 0.0;
Chris@216 269
Chris@216 270 f0 = lrint(t0 * getMainModel()->getSampleRate());
Chris@216 271 f1 = lrint(t1 * getMainModel()->getSampleRate());
Chris@216 272
Chris@216 273 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 274 Layer *layer = 0;
Chris@216 275 if (pane) layer = pane->getSelectedLayer();
Chris@216 276 if (layer) {
Chris@730 277 int resolution;
Chris@216 278 layer->snapToFeatureFrame(pane, f0, resolution,
Chris@216 279 Layer::SnapLeft);
Chris@216 280 layer->snapToFeatureFrame(pane, f1, resolution,
Chris@216 281 Layer::SnapRight);
Chris@216 282 }
Chris@216 283
Chris@216 284 } else if (message.getArgCount() == 1 &&
Chris@216 285 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 286
Chris@216 287 QString str = message.getArg(0).toString();
Chris@216 288 if (str == "none") {
Chris@216 289 m_viewManager->clearSelections();
Chris@216 290 done = true;
Chris@216 291 }
Chris@216 292 }
Chris@216 293
Chris@216 294 if (!done) {
Chris@216 295 if (message.getMethod() == "select") {
Chris@216 296 m_viewManager->setSelection(Selection(f0, f1));
Chris@216 297 } else {
Chris@216 298 m_viewManager->addSelection(Selection(f0, f1));
Chris@216 299 }
Chris@216 300 }
Chris@216 301 }
Chris@216 302
Chris@216 303 } else if (message.getMethod() == "add") {
Chris@216 304
Chris@216 305 if (getMainModel()) {
Chris@216 306
Chris@216 307 if (message.getArgCount() >= 1 &&
Chris@216 308 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 309
Chris@216 310 int channel = -1;
Chris@216 311 if (message.getArgCount() == 2 &&
Chris@216 312 message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 313 channel = message.getArg(0).toInt();
Chris@216 314 if (channel < -1 ||
Chris@216 315 channel > int(getMainModel()->getChannelCount())) {
Chris@1617 316 cerr << "WARNING: OSCHandler: channel "
Chris@665 317 << channel << " out of range" << endl;
Chris@216 318 channel = -1;
Chris@216 319 }
Chris@216 320 }
Chris@216 321
Chris@216 322 QString str = message.getArg(0).toString();
Chris@216 323
Chris@216 324 LayerFactory::LayerType type =
Chris@216 325 LayerFactory::getInstance()->getLayerTypeForName(str);
Chris@216 326
Chris@216 327 if (type == LayerFactory::UnknownLayer) {
Chris@1617 328 cerr << "WARNING: OSCHandler: unknown layer "
Chris@665 329 << "type " << str << endl;
Chris@216 330 } else {
Chris@216 331
Chris@232 332 LayerConfiguration configuration(type,
Chris@232 333 getMainModel(),
Chris@232 334 channel);
Chris@216 335
Chris@216 336 addPane(configuration,
Chris@216 337 tr("Add %1 Pane")
Chris@216 338 .arg(LayerFactory::getInstance()->
Chris@216 339 getLayerPresentationName(type)));
Chris@216 340 }
Chris@216 341 }
Chris@216 342 }
Chris@216 343
Chris@216 344 } else if (message.getMethod() == "undo") {
Chris@216 345
Chris@216 346 CommandHistory::getInstance()->undo();
Chris@216 347
Chris@216 348 } else if (message.getMethod() == "redo") {
Chris@216 349
Chris@216 350 CommandHistory::getInstance()->redo();
Chris@216 351
Chris@216 352 } else if (message.getMethod() == "set") {
Chris@216 353
Chris@216 354 if (message.getArgCount() == 2 &&
Chris@216 355 message.getArg(0).canConvert(QVariant::String) &&
Chris@216 356 message.getArg(1).canConvert(QVariant::Double)) {
Chris@216 357
Chris@216 358 QString property = message.getArg(0).toString();
Chris@216 359 float value = (float)message.getArg(1).toDouble();
Chris@216 360
Chris@216 361 if (property == "gain") {
Chris@216 362 if (value < 0.0) value = 0.0;
Chris@1386 363 m_mainLevelPan->setLevel(value);
Chris@216 364 if (m_playTarget) m_playTarget->setOutputGain(value);
Chris@1617 365 } else if (property == "speed") {
Chris@1617 366 m_playSpeed->setMappedValue(value);
Chris@216 367 } else if (property == "speedup") {
Chris@1617 368
Chris@1617 369 // The speedup method existed before the speed method
Chris@1617 370 // and is a bit weirder.
Chris@1617 371 //
Chris@1617 372 // For speed(x), x is a percentage of normal speed, so
Chris@1617 373 // x=100 means play at the normal speed, x=50 means
Chris@1617 374 // half speed, x=200 double speed etc.
Chris@1617 375 //
Chris@1617 376 // For speedup(x), x was some sort of modifier of
Chris@1617 377 // percentage thing, so x=0 meant play at the normal
Chris@1617 378 // speed, x=50 meant play at 150% of normal speed,
Chris@1617 379 // x=100 meant play at double speed, and x=-100 rather
Chris@1617 380 // bizarrely meant play at half speed. We handle this
Chris@1617 381 // now by converting to speed percentage as follows:
Chris@1617 382
Chris@1617 383 double percentage = 100.0;
Chris@1617 384 if (value > 0.f) {
Chris@1617 385 percentage = percentage + value;
Chris@1617 386 } else {
Chris@1617 387 percentage = 10000.0 / (percentage - value);
Chris@1617 388 }
Chris@1617 389 SVDEBUG << "OSCHandler: converted speedup(" << value
Chris@1617 390 << ") into speed(" << percentage << ")" << endl;
Chris@1617 391
Chris@1617 392 m_playSpeed->setMappedValue(percentage);
Chris@1617 393
Chris@216 394 } else if (property == "overlays") {
Chris@216 395 if (value < 0.5) {
Chris@216 396 m_viewManager->setOverlayMode(ViewManager::NoOverlays);
Chris@216 397 } else if (value < 1.5) {
Chris@701 398 m_viewManager->setOverlayMode(ViewManager::StandardOverlays);
Chris@216 399 } else {
Chris@216 400 m_viewManager->setOverlayMode(ViewManager::AllOverlays);
Chris@216 401 }
Chris@216 402 } else if (property == "zoomwheels") {
Chris@216 403 m_viewManager->setZoomWheelsEnabled(value > 0.5);
Chris@216 404 } else if (property == "propertyboxes") {
Chris@216 405 bool toggle = ((value < 0.5) !=
Chris@216 406 (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks));
Chris@216 407 if (toggle) togglePropertyBoxes();
Chris@216 408 }
Chris@216 409
Chris@216 410 } else {
Chris@216 411 PropertyContainer *container = 0;
Chris@216 412 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 413 if (pane &&
Chris@216 414 message.getArgCount() == 3 &&
Chris@216 415 message.getArg(0).canConvert(QVariant::String) &&
Chris@216 416 message.getArg(1).canConvert(QVariant::String) &&
Chris@216 417 message.getArg(2).canConvert(QVariant::String)) {
Chris@216 418 if (message.getArg(0).toString() == "pane") {
Chris@216 419 container = pane->getPropertyContainer(0);
Chris@216 420 } else if (message.getArg(0).toString() == "layer") {
Chris@216 421 container = pane->getSelectedLayer();
Chris@216 422 }
Chris@216 423 }
Chris@216 424 if (container) {
Chris@216 425 QString nameString = message.getArg(1).toString();
Chris@216 426 QString valueString = message.getArg(2).toString();
Chris@248 427 Command *c = container->getSetPropertyCommand
Chris@248 428 (nameString, valueString);
Chris@248 429 if (c) CommandHistory::getInstance()->addCommand(c, true, true);
Chris@216 430 }
Chris@216 431 }
Chris@216 432
Chris@216 433 } else if (message.getMethod() == "setcurrent") {
Chris@216 434
Chris@216 435 int paneIndex = -1, layerIndex = -1;
Chris@216 436 bool wantLayer = false;
Chris@216 437
Chris@216 438 if (message.getArgCount() >= 1 &&
Chris@216 439 message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 440
Chris@216 441 paneIndex = message.getArg(0).toInt() - 1;
Chris@216 442
Chris@216 443 if (message.getArgCount() >= 2 &&
Chris@216 444 message.getArg(1).canConvert(QVariant::Int)) {
Chris@216 445 wantLayer = true;
Chris@216 446 layerIndex = message.getArg(1).toInt() - 1;
Chris@216 447 }
Chris@216 448 }
Chris@216 449
Chris@216 450 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) {
Chris@216 451 Pane *pane = m_paneStack->getPane(paneIndex);
Chris@216 452 m_paneStack->setCurrentPane(pane);
Chris@216 453 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) {
Chris@216 454 Layer *layer = pane->getLayer(layerIndex);
Chris@216 455 m_paneStack->setCurrentLayer(pane, layer);
Chris@216 456 } else if (wantLayer && layerIndex == -1) {
Chris@216 457 m_paneStack->setCurrentLayer(pane, 0);
Chris@216 458 }
Chris@216 459 }
Chris@216 460
Chris@216 461 } else if (message.getMethod() == "delete") {
Chris@216 462
Chris@216 463 if (message.getArgCount() == 1 &&
Chris@216 464 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 465
Chris@216 466 QString target = message.getArg(0).toString();
Chris@216 467
Chris@216 468 if (target == "pane") {
Chris@216 469
Chris@216 470 deleteCurrentPane();
Chris@216 471
Chris@216 472 } else if (target == "layer") {
Chris@216 473
Chris@216 474 deleteCurrentLayer();
Chris@216 475
Chris@216 476 } else {
Chris@216 477
Chris@1617 478 cerr << "WARNING: OSCHandler: Unknown delete target " << target << endl;
Chris@216 479 }
Chris@216 480 }
Chris@216 481
Chris@216 482 } else if (message.getMethod() == "zoom") {
Chris@216 483
Chris@216 484 if (message.getArgCount() == 1) {
Chris@216 485 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 486 message.getArg(0).toString() == "in") {
Chris@216 487 zoomIn();
Chris@216 488 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 489 message.getArg(0).toString() == "out") {
Chris@216 490 zoomOut();
Chris@216 491 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 492 message.getArg(0).toString() == "default") {
Chris@216 493 zoomDefault();
Chris@312 494 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@312 495 message.getArg(0).toString() == "fit") {
Chris@312 496 zoomToFit();
Chris@216 497 } else if (message.getArg(0).canConvert(QVariant::Double)) {
Chris@216 498 double level = message.getArg(0).toDouble();
Chris@216 499 Pane *currentPane = m_paneStack->getCurrentPane();
Chris@216 500 if (level < 1.0) level = 1.0;
Chris@922 501 if (currentPane) currentPane->setZoomLevel(int(lrint(level)));
Chris@216 502 }
Chris@216 503 }
Chris@216 504
Chris@216 505 } else if (message.getMethod() == "zoomvertical") {
Chris@216 506
Chris@216 507 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 508 Layer *layer = 0;
Chris@216 509 if (pane && pane->getLayerCount() > 0) {
Chris@216 510 layer = pane->getLayer(pane->getLayerCount() - 1);
Chris@216 511 }
Chris@216 512 int defaultStep = 0;
Chris@216 513 int steps = 0;
Chris@216 514 if (layer) {
Chris@216 515 steps = layer->getVerticalZoomSteps(defaultStep);
Chris@216 516 if (message.getArgCount() == 1 && steps > 0) {
Chris@216 517 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 518 message.getArg(0).toString() == "in") {
Chris@216 519 int step = layer->getCurrentVerticalZoomStep() + 1;
Chris@216 520 if (step < steps) layer->setVerticalZoomStep(step);
Chris@216 521 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 522 message.getArg(0).toString() == "out") {
Chris@216 523 int step = layer->getCurrentVerticalZoomStep() - 1;
Chris@216 524 if (step >= 0) layer->setVerticalZoomStep(step);
Chris@216 525 } else if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 526 message.getArg(0).toString() == "default") {
Chris@216 527 layer->setVerticalZoomStep(defaultStep);
Chris@216 528 }
Chris@216 529 } else if (message.getArgCount() == 2) {
Chris@216 530 if (message.getArg(0).canConvert(QVariant::Double) &&
Chris@216 531 message.getArg(1).canConvert(QVariant::Double)) {
Chris@216 532 double min = message.getArg(0).toDouble();
Chris@216 533 double max = message.getArg(1).toDouble();
Chris@216 534 layer->setDisplayExtents(min, max);
Chris@216 535 }
Chris@216 536 }
Chris@216 537 }
Chris@216 538
Chris@216 539 } else if (message.getMethod() == "quit") {
Chris@216 540
Chris@216 541 m_abandoning = true;
Chris@216 542 close();
Chris@216 543
Chris@216 544 } else if (message.getMethod() == "resize") {
Chris@216 545
Chris@216 546 if (message.getArgCount() == 2) {
Chris@216 547
Chris@216 548 int width = 0, height = 0;
Chris@216 549
Chris@216 550 if (message.getArg(1).canConvert(QVariant::Int)) {
Chris@216 551
Chris@216 552 height = message.getArg(1).toInt();
Chris@216 553
Chris@216 554 if (message.getArg(0).canConvert(QVariant::String) &&
Chris@216 555 message.getArg(0).toString() == "pane") {
Chris@216 556
Chris@216 557 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 558 if (pane) pane->resize(pane->width(), height);
Chris@216 559
Chris@216 560 } else if (message.getArg(0).canConvert(QVariant::Int)) {
Chris@216 561
Chris@216 562 width = message.getArg(0).toInt();
Chris@216 563 resize(width, height);
Chris@216 564 }
Chris@216 565 }
Chris@216 566 }
Chris@216 567
Chris@216 568 } else if (message.getMethod() == "transform") {
Chris@216 569
Chris@216 570 Pane *pane = m_paneStack->getCurrentPane();
Chris@216 571
Chris@216 572 if (getMainModel() &&
Chris@216 573 pane &&
Chris@216 574 message.getArgCount() == 1 &&
Chris@216 575 message.getArg(0).canConvert(QVariant::String)) {
Chris@216 576
Chris@224 577 TransformId transformId = message.getArg(0).toString();
Chris@216 578
Chris@224 579 Transform transform = TransformFactory::getInstance()->
Chris@224 580 getDefaultTransformFor(transformId);
Chris@224 581
Chris@216 582 Layer *newLayer = m_document->createDerivedLayer
Chris@224 583 (transform, getMainModel());
Chris@216 584
Chris@216 585 if (newLayer) {
Chris@216 586 m_document->addLayerToView(pane, newLayer);
Chris@224 587 m_recentTransforms.add(transformId);
Chris@216 588 m_paneStack->setCurrentLayer(pane, newLayer);
Chris@216 589 }
Chris@216 590 }
Chris@216 591
Chris@216 592 } else {
Chris@1617 593 cerr << "WARNING: OSCHandler: Unknown or unsupported "
Chris@665 594 << "method \"" << message.getMethod()
Chris@665 595 << "\"" << endl;
Chris@216 596 }
Chris@216 597 }