00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "MainWindow.h"
00017 #include "data/osc/OSCQueue.h"
00018
00019 #include "layer/WaveformLayer.h"
00020 #include "view/ViewManager.h"
00021 #include "view/Pane.h"
00022 #include "view/PaneStack.h"
00023 #include "data/model/WaveFileModel.h"
00024 #include "base/CommandHistory.h"
00025 #include "audioio/AudioCallbackPlaySource.h"
00026 #include "audioio/AudioCallbackPlayTarget.h"
00027 #include "framework/Document.h"
00028 #include "data/fileio/WavFileWriter.h"
00029 #include "plugin/transform/TransformFactory.h"
00030 #include "widgets/Fader.h"
00031 #include "widgets/AudioDial.h"
00032
00033 #include <QFileInfo>
00034
00035 void
00036 MainWindow::handleOSCMessage(const OSCMessage &message)
00037 {
00038 std::cerr << "MainWindow::handleOSCMessage: thread id = "
00039 << QThread::currentThreadId() << std::endl;
00040
00041
00042
00043 if (message.getMethod() == "open") {
00044
00045 if (message.getArgCount() == 1 &&
00046 message.getArg(0).canConvert(QVariant::String)) {
00047 QString path = message.getArg(0).toString();
00048 if (open(path, ReplaceMainModel) != FileOpenSucceeded) {
00049 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \""
00050 << path.toStdString() << "\"" << std::endl;
00051 }
00053
00054 }
00055
00056 } else if (message.getMethod() == "openadditional") {
00057
00058 if (message.getArgCount() == 1 &&
00059 message.getArg(0).canConvert(QVariant::String)) {
00060 QString path = message.getArg(0).toString();
00061 if (open(path, CreateAdditionalModel) != FileOpenSucceeded) {
00062 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \""
00063 << path.toStdString() << "\"" << std::endl;
00064 }
00065 }
00066
00067 } else if (message.getMethod() == "recent" ||
00068 message.getMethod() == "last") {
00069
00070 int n = 0;
00071 if (message.getMethod() == "recent" &&
00072 message.getArgCount() == 1 &&
00073 message.getArg(0).canConvert(QVariant::Int)) {
00074 n = message.getArg(0).toInt() - 1;
00075 }
00076 std::vector<QString> recent = m_recentFiles.getRecent();
00077 if (n >= 0 && n < int(recent.size())) {
00078 if (open(recent[n], ReplaceMainModel) != FileOpenSucceeded) {
00079 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \""
00080 << recent[n].toStdString() << "\"" << std::endl;
00081 }
00082 }
00083
00084 } else if (message.getMethod() == "save") {
00085
00086 QString path;
00087 if (message.getArgCount() == 1 &&
00088 message.getArg(0).canConvert(QVariant::String)) {
00089 path = message.getArg(0).toString();
00090 if (QFileInfo(path).exists()) {
00091 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in save" << std::endl;
00092 } else {
00093 saveSessionFile(path);
00094 }
00095 }
00096
00097 } else if (message.getMethod() == "export") {
00098
00099 QString path;
00100 if (getMainModel()) {
00101 if (message.getArgCount() == 1 &&
00102 message.getArg(0).canConvert(QVariant::String)) {
00103 path = message.getArg(0).toString();
00104 if (QFileInfo(path).exists()) {
00105 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in export" << std::endl;
00106 } else {
00107 WavFileWriter writer(path,
00108 getMainModel()->getSampleRate(),
00109 getMainModel()->getChannelCount());
00110 MultiSelection ms = m_viewManager->getSelection();
00111 if (!ms.getSelections().empty()) {
00112 writer.writeModel(getMainModel(), &ms);
00113 } else {
00114 writer.writeModel(getMainModel());
00115 }
00116 }
00117 }
00118 }
00119
00120 } else if (message.getMethod() == "jump" ||
00121 message.getMethod() == "play") {
00122
00123 if (getMainModel()) {
00124
00125 unsigned long frame = m_viewManager->getPlaybackFrame();
00126 bool selection = false;
00127 bool play = (message.getMethod() == "play");
00128
00129 if (message.getArgCount() == 1) {
00130
00131 if (message.getArg(0).canConvert(QVariant::String) &&
00132 message.getArg(0).toString() == "selection") {
00133
00134 selection = true;
00135
00136 } else if (message.getArg(0).canConvert(QVariant::String) &&
00137 message.getArg(0).toString() == "end") {
00138
00139 frame = getMainModel()->getEndFrame();
00140
00141 } else if (message.getArg(0).canConvert(QVariant::Double)) {
00142
00143 double time = message.getArg(0).toDouble();
00144 if (time < 0.0) time = 0.0;
00145
00146 frame = lrint(time * getMainModel()->getSampleRate());
00147 }
00148 }
00149
00150 if (frame > getMainModel()->getEndFrame()) {
00151 frame = getMainModel()->getEndFrame();
00152 }
00153
00154 if (play) {
00155 m_viewManager->setPlaySelectionMode(selection);
00156 }
00157
00158 if (selection) {
00159 MultiSelection::SelectionList sl = m_viewManager->getSelections();
00160 if (!sl.empty()) {
00161 frame = sl.begin()->getStartFrame();
00162 }
00163 }
00164
00165 m_viewManager->setPlaybackFrame(frame);
00166
00167 if (play && !m_playSource->isPlaying()) {
00168 m_playSource->play(frame);
00169 }
00170 }
00171
00172 } else if (message.getMethod() == "stop") {
00173
00174 if (m_playSource->isPlaying()) m_playSource->stop();
00175
00176 } else if (message.getMethod() == "loop") {
00177
00178 if (message.getArgCount() == 1 &&
00179 message.getArg(0).canConvert(QVariant::String)) {
00180
00181 QString str = message.getArg(0).toString();
00182 if (str == "on") {
00183 m_viewManager->setPlayLoopMode(true);
00184 } else if (str == "off") {
00185 m_viewManager->setPlayLoopMode(false);
00186 }
00187 }
00188
00189 } else if (message.getMethod() == "solo") {
00190
00191 if (message.getArgCount() == 1 &&
00192 message.getArg(0).canConvert(QVariant::String)) {
00193
00194 QString str = message.getArg(0).toString();
00195 if (str == "on") {
00196 m_viewManager->setPlaySoloMode(true);
00197 } else if (str == "off") {
00198 m_viewManager->setPlaySoloMode(false);
00199 }
00200 }
00201
00202 } else if (message.getMethod() == "select" ||
00203 message.getMethod() == "addselect") {
00204
00205 if (getMainModel()) {
00206
00207 int f0 = getMainModel()->getStartFrame();
00208 int f1 = getMainModel()->getEndFrame();
00209
00210 bool done = false;
00211
00212 if (message.getArgCount() == 2 &&
00213 message.getArg(0).canConvert(QVariant::Double) &&
00214 message.getArg(1).canConvert(QVariant::Double)) {
00215
00216 double t0 = message.getArg(0).toDouble();
00217 double t1 = message.getArg(1).toDouble();
00218 if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; }
00219 if (t0 < 0.0) t0 = 0.0;
00220 if (t1 < 0.0) t1 = 0.0;
00221
00222 f0 = lrint(t0 * getMainModel()->getSampleRate());
00223 f1 = lrint(t1 * getMainModel()->getSampleRate());
00224
00225 Pane *pane = m_paneStack->getCurrentPane();
00226 Layer *layer = 0;
00227 if (pane) layer = pane->getSelectedLayer();
00228 if (layer) {
00229 size_t resolution;
00230 layer->snapToFeatureFrame(pane, f0, resolution,
00231 Layer::SnapLeft);
00232 layer->snapToFeatureFrame(pane, f1, resolution,
00233 Layer::SnapRight);
00234 }
00235
00236 } else if (message.getArgCount() == 1 &&
00237 message.getArg(0).canConvert(QVariant::String)) {
00238
00239 QString str = message.getArg(0).toString();
00240 if (str == "none") {
00241 m_viewManager->clearSelections();
00242 done = true;
00243 }
00244 }
00245
00246 if (!done) {
00247 if (message.getMethod() == "select") {
00248 m_viewManager->setSelection(Selection(f0, f1));
00249 } else {
00250 m_viewManager->addSelection(Selection(f0, f1));
00251 }
00252 }
00253 }
00254
00255 } else if (message.getMethod() == "add") {
00256
00257 if (getMainModel()) {
00258
00259 if (message.getArgCount() >= 1 &&
00260 message.getArg(0).canConvert(QVariant::String)) {
00261
00262 int channel = -1;
00263 if (message.getArgCount() == 2 &&
00264 message.getArg(0).canConvert(QVariant::Int)) {
00265 channel = message.getArg(0).toInt();
00266 if (channel < -1 ||
00267 channel > int(getMainModel()->getChannelCount())) {
00268 std::cerr << "WARNING: MainWindow::handleOSCMessage: channel "
00269 << channel << " out of range" << std::endl;
00270 channel = -1;
00271 }
00272 }
00273
00274 QString str = message.getArg(0).toString();
00275
00276 LayerFactory::LayerType type =
00277 LayerFactory::getInstance()->getLayerTypeForName(str);
00278
00279 if (type == LayerFactory::UnknownLayer) {
00280 std::cerr << "WARNING: MainWindow::handleOSCMessage: unknown layer "
00281 << "type " << str.toStdString() << std::endl;
00282 } else {
00283
00284 LayerConfiguration configuration(type,
00285 getMainModel(),
00286 channel);
00287
00288 addPane(configuration,
00289 tr("Add %1 Pane")
00290 .arg(LayerFactory::getInstance()->
00291 getLayerPresentationName(type)));
00292 }
00293 }
00294 }
00295
00296 } else if (message.getMethod() == "undo") {
00297
00298 CommandHistory::getInstance()->undo();
00299
00300 } else if (message.getMethod() == "redo") {
00301
00302 CommandHistory::getInstance()->redo();
00303
00304 } else if (message.getMethod() == "set") {
00305
00306 if (message.getArgCount() == 2 &&
00307 message.getArg(0).canConvert(QVariant::String) &&
00308 message.getArg(1).canConvert(QVariant::Double)) {
00309
00310 QString property = message.getArg(0).toString();
00311 float value = (float)message.getArg(1).toDouble();
00312
00313 if (property == "gain") {
00314 if (value < 0.0) value = 0.0;
00315 m_fader->setValue(value);
00316 if (m_playTarget) m_playTarget->setOutputGain(value);
00317 } else if (property == "speedup") {
00318 m_playSpeed->setMappedValue(value);
00319 } else if (property == "overlays") {
00320 if (value < 0.5) {
00321 m_viewManager->setOverlayMode(ViewManager::NoOverlays);
00322 } else if (value < 1.5) {
00323 m_viewManager->setOverlayMode(ViewManager::MinimalOverlays);
00324 } else if (value < 2.5) {
00325 m_viewManager->setOverlayMode(ViewManager::StandardOverlays);
00326 } else {
00327 m_viewManager->setOverlayMode(ViewManager::AllOverlays);
00328 }
00329 } else if (property == "zoomwheels") {
00330 m_viewManager->setZoomWheelsEnabled(value > 0.5);
00331 } else if (property == "propertyboxes") {
00332 bool toggle = ((value < 0.5) !=
00333 (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks));
00334 if (toggle) togglePropertyBoxes();
00335 }
00336
00337 } else {
00338 PropertyContainer *container = 0;
00339 Pane *pane = m_paneStack->getCurrentPane();
00340 if (pane &&
00341 message.getArgCount() == 3 &&
00342 message.getArg(0).canConvert(QVariant::String) &&
00343 message.getArg(1).canConvert(QVariant::String) &&
00344 message.getArg(2).canConvert(QVariant::String)) {
00345 if (message.getArg(0).toString() == "pane") {
00346 container = pane->getPropertyContainer(0);
00347 } else if (message.getArg(0).toString() == "layer") {
00348 container = pane->getSelectedLayer();
00349 }
00350 }
00351 if (container) {
00352 QString nameString = message.getArg(1).toString();
00353 QString valueString = message.getArg(2).toString();
00354 container->setPropertyWithCommand(nameString, valueString);
00355 }
00356 }
00357
00358 } else if (message.getMethod() == "setcurrent") {
00359
00360 int paneIndex = -1, layerIndex = -1;
00361 bool wantLayer = false;
00362
00363 if (message.getArgCount() >= 1 &&
00364 message.getArg(0).canConvert(QVariant::Int)) {
00365
00366 paneIndex = message.getArg(0).toInt() - 1;
00367
00368 if (message.getArgCount() >= 2 &&
00369 message.getArg(1).canConvert(QVariant::Int)) {
00370 wantLayer = true;
00371 layerIndex = message.getArg(1).toInt() - 1;
00372 }
00373 }
00374
00375 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) {
00376 Pane *pane = m_paneStack->getPane(paneIndex);
00377 m_paneStack->setCurrentPane(pane);
00378 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) {
00379 Layer *layer = pane->getLayer(layerIndex);
00380 m_paneStack->setCurrentLayer(pane, layer);
00381 } else if (wantLayer && layerIndex == -1) {
00382 m_paneStack->setCurrentLayer(pane, 0);
00383 }
00384 }
00385
00386 } else if (message.getMethod() == "delete") {
00387
00388 if (message.getArgCount() == 1 &&
00389 message.getArg(0).canConvert(QVariant::String)) {
00390
00391 QString target = message.getArg(0).toString();
00392
00393 if (target == "pane") {
00394
00395 deleteCurrentPane();
00396
00397 } else if (target == "layer") {
00398
00399 deleteCurrentLayer();
00400
00401 } else {
00402
00403 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown delete target " << target.toStdString() << std::endl;
00404 }
00405 }
00406
00407 } else if (message.getMethod() == "zoom") {
00408
00409 if (message.getArgCount() == 1) {
00410 if (message.getArg(0).canConvert(QVariant::String) &&
00411 message.getArg(0).toString() == "in") {
00412 zoomIn();
00413 } else if (message.getArg(0).canConvert(QVariant::String) &&
00414 message.getArg(0).toString() == "out") {
00415 zoomOut();
00416 } else if (message.getArg(0).canConvert(QVariant::String) &&
00417 message.getArg(0).toString() == "default") {
00418 zoomDefault();
00419 } else if (message.getArg(0).canConvert(QVariant::Double)) {
00420 double level = message.getArg(0).toDouble();
00421 Pane *currentPane = m_paneStack->getCurrentPane();
00422 if (level < 1.0) level = 1.0;
00423 if (currentPane) currentPane->setZoomLevel(lrint(level));
00424 }
00425 }
00426
00427 } else if (message.getMethod() == "zoomvertical") {
00428
00429 Pane *pane = m_paneStack->getCurrentPane();
00430 Layer *layer = 0;
00431 if (pane && pane->getLayerCount() > 0) {
00432 layer = pane->getLayer(pane->getLayerCount() - 1);
00433 }
00434 int defaultStep = 0;
00435 int steps = 0;
00436 if (layer) {
00437 steps = layer->getVerticalZoomSteps(defaultStep);
00438 if (message.getArgCount() == 1 && steps > 0) {
00439 if (message.getArg(0).canConvert(QVariant::String) &&
00440 message.getArg(0).toString() == "in") {
00441 int step = layer->getCurrentVerticalZoomStep() + 1;
00442 if (step < steps) layer->setVerticalZoomStep(step);
00443 } else if (message.getArg(0).canConvert(QVariant::String) &&
00444 message.getArg(0).toString() == "out") {
00445 int step = layer->getCurrentVerticalZoomStep() - 1;
00446 if (step >= 0) layer->setVerticalZoomStep(step);
00447 } else if (message.getArg(0).canConvert(QVariant::String) &&
00448 message.getArg(0).toString() == "default") {
00449 layer->setVerticalZoomStep(defaultStep);
00450 }
00451 } else if (message.getArgCount() == 2) {
00452 if (message.getArg(0).canConvert(QVariant::Double) &&
00453 message.getArg(1).canConvert(QVariant::Double)) {
00454 double min = message.getArg(0).toDouble();
00455 double max = message.getArg(1).toDouble();
00456 layer->setDisplayExtents(min, max);
00457 }
00458 }
00459 }
00460
00461 } else if (message.getMethod() == "quit") {
00462
00463 m_abandoning = true;
00464 close();
00465
00466 } else if (message.getMethod() == "resize") {
00467
00468 if (message.getArgCount() == 2) {
00469
00470 int width = 0, height = 0;
00471
00472 if (message.getArg(1).canConvert(QVariant::Int)) {
00473
00474 height = message.getArg(1).toInt();
00475
00476 if (message.getArg(0).canConvert(QVariant::String) &&
00477 message.getArg(0).toString() == "pane") {
00478
00479 Pane *pane = m_paneStack->getCurrentPane();
00480 if (pane) pane->resize(pane->width(), height);
00481
00482 } else if (message.getArg(0).canConvert(QVariant::Int)) {
00483
00484 width = message.getArg(0).toInt();
00485 resize(width, height);
00486 }
00487 }
00488 }
00489
00490 } else if (message.getMethod() == "transform") {
00491
00492 Pane *pane = m_paneStack->getCurrentPane();
00493
00494 if (getMainModel() &&
00495 pane &&
00496 message.getArgCount() == 1 &&
00497 message.getArg(0).canConvert(QVariant::String)) {
00498
00499 TransformId transformId = message.getArg(0).toString();
00500
00501 Transform transform = TransformFactory::getInstance()->
00502 getDefaultTransformFor(transformId);
00503
00504 Layer *newLayer = m_document->createDerivedLayer
00505 (transform, getMainModel());
00506
00507 if (newLayer) {
00508 m_document->addLayerToView(pane, newLayer);
00509 m_recentTransforms.add(transformId);
00510 m_paneStack->setCurrentLayer(pane, newLayer);
00511 }
00512 }
00513
00514 } else {
00515 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported "
00516 << "method \"" << message.getMethod().toStdString()
00517 << "\"" << std::endl;
00518 }
00519
00520 }