comparison main/MainWindow.cpp @ 70:e269ae6ed008

* When adding a layer, make it the selected layer on that pane * More OSC support, including transforms
author Chris Cannam
date Fri, 10 Nov 2006 17:45:26 +0000
parents 76cc2c424268
children 34dc23246f46
comparison
equal deleted inserted replaced
69:76cc2c424268 70:e269ae6ed008
94 using std::vector; 94 using std::vector;
95 using std::map; 95 using std::map;
96 using std::set; 96 using std::set;
97 97
98 98
99 MainWindow::MainWindow(bool withAudioOutput) : 99 MainWindow::MainWindow(bool withAudioOutput, bool withOSCSupport) :
100 m_document(0), 100 m_document(0),
101 m_paneStack(0), 101 m_paneStack(0),
102 m_viewManager(0), 102 m_viewManager(0),
103 m_overview(0), 103 m_overview(0),
104 m_timeRulerLayer(0), 104 m_timeRulerLayer(0),
105 m_audioOutput(withAudioOutput), 105 m_audioOutput(withAudioOutput),
106 m_playSource(0), 106 m_playSource(0),
107 m_playTarget(0), 107 m_playTarget(0),
108 m_oscQueue(new OSCQueue()), 108 m_oscQueue(withOSCSupport ? new OSCQueue() : 0),
109 m_recentFiles("RecentFiles"), 109 m_recentFiles("RecentFiles"),
110 m_recentTransforms("RecentTransforms", 20), 110 m_recentTransforms("RecentTransforms", 20),
111 m_mainMenusCreated(false), 111 m_mainMenusCreated(false),
112 m_paneMenu(0), 112 m_paneMenu(0),
113 m_layerMenu(0), 113 m_layerMenu(0),
117 m_recentTransformsMenu(0), 117 m_recentTransformsMenu(0),
118 m_rightButtonMenu(0), 118 m_rightButtonMenu(0),
119 m_rightButtonLayerMenu(0), 119 m_rightButtonLayerMenu(0),
120 m_rightButtonTransformsMenu(0), 120 m_rightButtonTransformsMenu(0),
121 m_documentModified(false), 121 m_documentModified(false),
122 m_openingAudioFile(false),
123 m_abandoning(false),
122 m_preferencesDialog(0) 124 m_preferencesDialog(0)
123 { 125 {
124 setWindowTitle(tr("Sonic Visualiser")); 126 setWindowTitle(tr("Sonic Visualiser"));
125 127
126 UnitDatabase::getInstance()->registerUnit("Hz"); 128 UnitDatabase::getInstance()->registerUnit("Hz");
229 connect(Preferences::getInstance(), 231 connect(Preferences::getInstance(),
230 SIGNAL(propertyChanged(PropertyContainer::PropertyName)), 232 SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
231 this, 233 this,
232 SLOT(preferenceChanged(PropertyContainer::PropertyName))); 234 SLOT(preferenceChanged(PropertyContainer::PropertyName)));
233 235
234 if (m_oscQueue->isOK()) { 236 if (m_oscQueue && m_oscQueue->isOK()) {
235 connect(m_oscQueue, SIGNAL(messagesAvailable()), this, SLOT(pollOSC())); 237 connect(m_oscQueue, SIGNAL(messagesAvailable()), this, SLOT(pollOSC()));
236 QTimer *oscTimer = new QTimer(this); 238 QTimer *oscTimer = new QTimer(this);
237 connect(oscTimer, SIGNAL(timeout()), this, SLOT(pollOSC())); 239 connect(oscTimer, SIGNAL(timeout()), this, SLOT(pollOSC()));
238 oscTimer->start(1000); 240 oscTimer->start(1000);
239 } 241 }
246 newSession(); 248 newSession();
247 } 249 }
248 250
249 MainWindow::~MainWindow() 251 MainWindow::~MainWindow()
250 { 252 {
251 closeSession(); 253 if (!m_abandoning) {
254 closeSession();
255 }
252 delete m_playTarget; 256 delete m_playTarget;
253 delete m_playSource; 257 delete m_playSource;
254 delete m_viewManager; 258 delete m_viewManager;
255 delete m_oscQueue; 259 delete m_oscQueue;
256 Profiles::getInstance()->dump(); 260 Profiles::getInstance()->dump();
2040 QFileInfo(path).isFile() && 2044 QFileInfo(path).isFile() &&
2041 QFileInfo(path).isReadable())) { 2045 QFileInfo(path).isReadable())) {
2042 return false; 2046 return false;
2043 } 2047 }
2044 2048
2049 m_openingAudioFile = true;
2050
2045 WaveFileModel *newModel = new WaveFileModel(path); 2051 WaveFileModel *newModel = new WaveFileModel(path);
2046 2052
2047 if (!newModel->isOK()) { 2053 if (!newModel->isOK()) {
2048 delete newModel; 2054 delete newModel;
2055 m_openingAudioFile = false;
2049 return false; 2056 return false;
2050 } 2057 }
2051 2058
2052 bool setAsMain = true; 2059 bool setAsMain = true;
2053 static bool prevSetAsMain = true; 2060 static bool prevSetAsMain = true;
2066 tr("You already have an audio waveform loaded.\nWhat would you like to do with the new audio file?"), 2073 tr("You already have an audio waveform loaded.\nWhat would you like to do with the new audio file?"),
2067 items, prevSetAsMain ? 0 : 1, &ok); 2074 items, prevSetAsMain ? 0 : 1, &ok);
2068 2075
2069 if (!ok || item.isEmpty()) { 2076 if (!ok || item.isEmpty()) {
2070 delete newModel; 2077 delete newModel;
2078 m_openingAudioFile = false;
2071 return false; 2079 return false;
2072 } 2080 }
2073 2081
2074 setAsMain = (item == items[0]); 2082 setAsMain = (item == items[0]);
2075 prevSetAsMain = setAsMain; 2083 prevSetAsMain = setAsMain;
2136 CommandHistory::getInstance()->endCompoundOperation(); 2144 CommandHistory::getInstance()->endCompoundOperation();
2137 } 2145 }
2138 2146
2139 updateMenuStates(); 2147 updateMenuStates();
2140 m_recentFiles.addFile(path); 2148 m_recentFiles.addFile(path);
2149 m_openingAudioFile = false;
2141 2150
2142 return true; 2151 return true;
2143 } 2152 }
2144 2153
2145 void 2154 void
2451 } 2460 }
2452 2461
2453 void 2462 void
2454 MainWindow::closeEvent(QCloseEvent *e) 2463 MainWindow::closeEvent(QCloseEvent *e)
2455 { 2464 {
2456 if (!checkSaveModified()) { 2465 if (!m_abandoning && !checkSaveModified()) {
2457 e->ignore(); 2466 e->ignore();
2458 return; 2467 return;
2459 } 2468 }
2460 2469
2461 QSettings settings; 2470 QSettings settings;
2933 2942
2934 m_document->setChannel(newLayer, configuration.channel); 2943 m_document->setChannel(newLayer, configuration.channel);
2935 m_document->addLayerToView(pane, newLayer); 2944 m_document->addLayerToView(pane, newLayer);
2936 2945
2937 m_paneStack->setCurrentPane(pane); 2946 m_paneStack->setCurrentPane(pane);
2947 m_paneStack->setCurrentLayer(pane, newLayer);
2938 2948
2939 CommandHistory::getInstance()->endCompoundOperation(); 2949 CommandHistory::getInstance()->endCompoundOperation();
2940 2950
2941 updateMenuStates(); 2951 updateMenuStates();
2942 } 2952 }
3127 3137
3128 if (newLayer) { 3138 if (newLayer) {
3129 m_document->addLayerToView(pane, newLayer); 3139 m_document->addLayerToView(pane, newLayer);
3130 m_document->setChannel(newLayer, context.channel); 3140 m_document->setChannel(newLayer, context.channel);
3131 m_recentTransforms.add(transform); 3141 m_recentTransforms.add(transform);
3142 m_paneStack->setCurrentLayer(pane, newLayer);
3132 } 3143 }
3133 3144
3134 updateMenuStates(); 3145 updateMenuStates();
3135 } 3146 }
3136 3147
3410 } 3421 }
3411 3422
3412 void 3423 void
3413 MainWindow::pollOSC() 3424 MainWindow::pollOSC()
3414 { 3425 {
3415 if (m_oscQueue->isEmpty()) return; 3426 if (!m_oscQueue || m_oscQueue->isEmpty()) return;
3416 std::cerr << "MainWindow::pollOSC: have " << m_oscQueue->getMessagesAvailable() << " messages" << std::endl; 3427 std::cerr << "MainWindow::pollOSC: have " << m_oscQueue->getMessagesAvailable() << " messages" << std::endl;
3428
3429 if (m_openingAudioFile) return;
3417 3430
3418 OSCMessage message = m_oscQueue->readMessage(); 3431 OSCMessage message = m_oscQueue->readMessage();
3419 3432
3420 if (message.getTarget() != 0) { 3433 if (message.getTarget() != 0) {
3421 return; //!!! for now -- this class is target 0, others not handled yet 3434 return; //!!! for now -- this class is target 0, others not handled yet
3425 } 3438 }
3426 3439
3427 void 3440 void
3428 MainWindow::handleOSCMessage(const OSCMessage &message) 3441 MainWindow::handleOSCMessage(const OSCMessage &message)
3429 { 3442 {
3443 std::cerr << "MainWindow::handleOSCMessage: thread id = "
3444 << QThread::currentThreadId() << std::endl;
3445
3430 // This large function should really be abstracted out. 3446 // This large function should really be abstracted out.
3431 3447
3432 if (message.getMethod() == "open") { 3448 if (message.getMethod() == "open") {
3433 3449
3434 if (message.getArgCount() == 1 && 3450 if (message.getArgCount() == 1 &&
3666 3682
3667 CommandHistory::getInstance()->redo(); 3683 CommandHistory::getInstance()->redo();
3668 3684
3669 } else if (message.getMethod() == "set") { 3685 } else if (message.getMethod() == "set") {
3670 3686
3671 if (message.getArgCount() >= 2 && 3687 if (message.getArgCount() == 2 &&
3672 message.getArg(0).canConvert(QVariant::String) && 3688 message.getArg(0).canConvert(QVariant::String) &&
3673 message.getArg(1).canConvert(QVariant::Double)) { 3689 message.getArg(1).canConvert(QVariant::Double)) {
3674 3690
3675 QString property = message.getArg(0).toString(); 3691 QString property = message.getArg(0).toString();
3676 float value = (float)message.getArg(1).toDouble(); 3692 float value = (float)message.getArg(1).toDouble();
3687 } else if (value < 1.5) { 3703 } else if (value < 1.5) {
3688 m_viewManager->setOverlayMode(ViewManager::BasicOverlays); 3704 m_viewManager->setOverlayMode(ViewManager::BasicOverlays);
3689 } else { 3705 } else {
3690 m_viewManager->setOverlayMode(ViewManager::AllOverlays); 3706 m_viewManager->setOverlayMode(ViewManager::AllOverlays);
3691 } 3707 }
3708 } else if (property == "zoomwheels") {
3709 m_viewManager->setZoomWheelsEnabled(value > 0.5);
3710 }
3711
3712 } else {
3713 PropertyContainer *container = 0;
3714 Pane *pane = m_paneStack->getCurrentPane();
3715 if (pane &&
3716 message.getArgCount() == 3 &&
3717 message.getArg(0).canConvert(QVariant::String) &&
3718 message.getArg(1).canConvert(QVariant::String) &&
3719 message.getArg(2).canConvert(QVariant::String)) {
3720 if (message.getArg(0).toString() == "pane") {
3721 container = pane->getPropertyContainer(0);
3722 } else if (message.getArg(0).toString() == "layer") {
3723 container = pane->getSelectedLayer();
3724 }
3725 }
3726 if (container) {
3727 QString nameString = message.getArg(1).toString();
3728 QString valueString = message.getArg(2).toString();
3729 container->setPropertyWithCommand(nameString, valueString);
3692 } 3730 }
3693 } 3731 }
3694 3732
3695 } else if (message.getMethod() == "setcurrent") { 3733 } else if (message.getMethod() == "setcurrent") {
3696 3734
3709 } 3747 }
3710 } 3748 }
3711 3749
3712 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) { 3750 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) {
3713 Pane *pane = m_paneStack->getPane(paneIndex); 3751 Pane *pane = m_paneStack->getPane(paneIndex);
3752 m_paneStack->setCurrentPane(pane);
3714 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) { 3753 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) {
3715 Layer *layer = pane->getLayer(layerIndex); 3754 Layer *layer = pane->getLayer(layerIndex);
3716 m_paneStack->setCurrentLayer(pane, layer); 3755 m_paneStack->setCurrentLayer(pane, layer);
3717 } else if (wantLayer && layerIndex == -1) { 3756 } else if (wantLayer && layerIndex == -1) {
3718 m_paneStack->setCurrentLayer(pane, 0); 3757 m_paneStack->setCurrentLayer(pane, 0);
3719 } else {
3720 m_paneStack->setCurrentPane(pane);
3721 } 3758 }
3722 } 3759 }
3723 3760
3724 } else if (message.getMethod() == "delete") { 3761 } else if (message.getMethod() == "delete") {
3725 3762
3757 } else if (message.getArg(0).canConvert(QVariant::Double)) { 3794 } else if (message.getArg(0).canConvert(QVariant::Double)) {
3758 double level = message.getArg(0).toDouble(); 3795 double level = message.getArg(0).toDouble();
3759 Pane *currentPane = m_paneStack->getCurrentPane(); 3796 Pane *currentPane = m_paneStack->getCurrentPane();
3760 if (level < 1.0) level = 1.0; 3797 if (level < 1.0) level = 1.0;
3761 if (currentPane) currentPane->setZoomLevel(lrint(level)); 3798 if (currentPane) currentPane->setZoomLevel(lrint(level));
3799 }
3800 }
3801
3802 } else if (message.getMethod() == "quit") {
3803
3804 m_abandoning = true;
3805 close();
3806
3807 } else if (message.getMethod() == "resize") {
3808
3809 if (message.getArgCount() == 2) {
3810
3811 int width = 0, height = 0;
3812
3813 if (message.getArg(1).canConvert(QVariant::Int)) {
3814
3815 height = message.getArg(1).toInt();
3816
3817 if (message.getArg(0).canConvert(QVariant::String) &&
3818 message.getArg(0).toString() == "pane") {
3819
3820 Pane *pane = m_paneStack->getCurrentPane();
3821 if (pane) pane->resize(pane->width(), height);
3822
3823 } else if (message.getArg(0).canConvert(QVariant::Int)) {
3824
3825 width = message.getArg(0).toInt();
3826 resize(width, height);
3827 }
3828 }
3829 }
3830
3831 } else if (message.getMethod() == "transform") {
3832
3833 Pane *pane = m_paneStack->getCurrentPane();
3834
3835 if (getMainModel() &&
3836 pane &&
3837 message.getArgCount() == 1 &&
3838 message.getArg(0).canConvert(QVariant::String)) {
3839
3840 TransformName transform = message.getArg(0).toString();
3841
3842 Layer *newLayer = m_document->createDerivedLayer
3843 (transform,
3844 getMainModel(),
3845 PluginTransform::ExecutionContext(),
3846 "");
3847
3848 if (newLayer) {
3849 m_document->addLayerToView(pane, newLayer);
3850 m_recentTransforms.add(transform);
3851 m_paneStack->setCurrentLayer(pane, newLayer);
3762 } 3852 }
3763 } 3853 }
3764 3854
3765 } else { 3855 } else {
3766 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported " 3856 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported "
3917 #endif 4007 #endif
3918 aboutText += tr("<br>With LADSPA plugin support (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld").arg(LADSPA_VERSION); 4008 aboutText += tr("<br>With LADSPA plugin support (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld").arg(LADSPA_VERSION);
3919 aboutText += tr("<br>With DSSI plugin support (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton").arg(DSSI_VERSION); 4009 aboutText += tr("<br>With DSSI plugin support (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton").arg(DSSI_VERSION);
3920 #ifdef HAVE_LIBLO 4010 #ifdef HAVE_LIBLO
3921 aboutText += tr("<br>With liblo Lite OSC library (v%1) &copy; Steve Harris").arg(LIBLO_VERSION); 4011 aboutText += tr("<br>With liblo Lite OSC library (v%1) &copy; Steve Harris").arg(LIBLO_VERSION);
3922 if (m_oscQueue->isOK()) { 4012 if (m_oscQueue && m_oscQueue->isOK()) {
3923 aboutText += tr("<p>The OSC URL for this instance is: \"%1\"").arg(m_oscQueue->getOSCURL()); 4013 aboutText += tr("<p>The OSC URL for this instance is: \"%1\"").arg(m_oscQueue->getOSCURL());
3924 } 4014 }
3925 #endif 4015 #endif
3926 aboutText += "</p>"; 4016 aboutText += "</p>";
3927 #endif 4017 #endif