--- qsampler/trunk/src/qsamplerMainForm.cpp 2008/02/15 17:08:33 1693 +++ qsampler/trunk/src/qsamplerMainForm.cpp 2008/02/19 09:18:45 1704 @@ -2,7 +2,7 @@ // /**************************************************************************** Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved. - Copyright (C) 2007, Christian Schoenebeck + Copyright (C) 2007, 2008 Christian Schoenebeck This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -33,6 +33,7 @@ #include "qsamplerInstrumentListForm.h" #include "qsamplerDeviceForm.h" #include "qsamplerOptionsForm.h" +#include "qsamplerDeviceStatusForm.h" #include #include @@ -481,9 +482,10 @@ void MainForm::closeEvent ( QCloseEvent *pCloseEvent ) { - if (queryClose()) + if (queryClose()) { + DeviceStatusForm::deleteAllInstances(); pCloseEvent->accept(); - else + } else pCloseEvent->ignore(); } @@ -552,6 +554,9 @@ if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) { CustomEvent *pEvent = static_cast (pCustomEvent); switch (pEvent->event()) { + case LSCP_EVENT_CHANNEL_COUNT: + updateAllChannelStrips(true); + break; case LSCP_EVENT_CHANNEL_INFO: { int iChannelID = pEvent->data().toInt(); ChannelStrip *pChannelStrip = channelStrip(iChannelID); @@ -559,15 +564,43 @@ channelStripChanged(pChannelStrip); break; } -#if CONFIG_LSCP_CHANNEL_MIDI + case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT: + if (m_pDeviceForm) m_pDeviceForm->refreshDevices(); + DeviceStatusForm::onDevicesChanged(); + updateViewMidiDeviceStatusMenu(); + break; + case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: { + if (m_pDeviceForm) m_pDeviceForm->refreshDevices(); + const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt(); + DeviceStatusForm::onDeviceChanged(iDeviceID); + break; + } + case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT: + if (m_pDeviceForm) m_pDeviceForm->refreshDevices(); + break; + case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO: + if (m_pDeviceForm) m_pDeviceForm->refreshDevices(); + break; +#if CONFIG_EVENT_CHANNEL_MIDI case LSCP_EVENT_CHANNEL_MIDI: { - int iChannelID = pEvent->data().section(' ', 0, 0).toInt(); + const int iChannelID = pEvent->data().section(' ', 0, 0).toInt(); ChannelStrip *pChannelStrip = channelStrip(iChannelID); if (pChannelStrip) pChannelStrip->midiArrived(); break; } #endif +#if CONFIG_EVENT_DEVICE_MIDI + case LSCP_EVENT_DEVICE_MIDI: { + const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt(); + const int iPortID = pEvent->data().section(' ', 1, 1).toInt(); + DeviceStatusForm* pDeviceStatusForm = + DeviceStatusForm::getInstance(iDeviceID); + if (pDeviceStatusForm) + pDeviceStatusForm->midiArrived(iPortID); + break; + } +#endif default: appendMessagesColor(tr("Notify event: %1 data: %2") .arg(::lscp_event_to_text(pEvent->event())) @@ -576,6 +609,21 @@ } } +void MainForm::updateViewMidiDeviceStatusMenu() { + m_ui.viewMidiDeviceStatusMenu->clear(); + const std::map statusForms = + DeviceStatusForm::getInstances(); + for ( + std::map::const_iterator iter = statusForms.begin(); + iter != statusForms.end(); ++iter + ) { + DeviceStatusForm* pForm = iter->second; + m_ui.viewMidiDeviceStatusMenu->addAction( + pForm->visibleAction() + ); + } +} + // Context menu event handler. void MainForm::contextMenuEvent( QContextMenuEvent *pEvent ) { @@ -1923,6 +1971,20 @@ } #endif + updateAllChannelStrips(false); + + // Do we auto-arrange? + if (m_pOptions && m_pOptions->bAutoArrange) + channelsArrange(); + + // Remember to refresh devices and instruments... + if (m_pInstrumentListForm) + m_pInstrumentListForm->refreshInstruments(); + if (m_pDeviceForm) + m_pDeviceForm->refreshDevices(); +} + +void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) { // Retrieve the current channel list. int *piChannelIDs = ::lscp_list_channels(m_pClient); if (piChannelIDs == NULL) { @@ -1939,20 +2001,32 @@ if (!channelStrip(piChannelIDs[iChannel])) createChannelStrip(new Channel(piChannelIDs[iChannel])); } - m_pWorkspace->setUpdatesEnabled(true); - } - // Do we auto-arrange? - if (m_pOptions && m_pOptions->bAutoArrange) - channelsArrange(); + // Do we auto-arrange? + if (m_pOptions && m_pOptions->bAutoArrange) + channelsArrange(); - // Remember to refresh devices and instruments... - if (m_pInstrumentListForm) - m_pInstrumentListForm->refreshInstruments(); - if (m_pDeviceForm) - m_pDeviceForm->refreshDevices(); -} + stabilizeForm(); + // remove dead channel strips + if (bRemoveDeadStrips) { + for (int i = 0; channelStripAt(i); ++i) { + ChannelStrip* pChannelStrip = channelStripAt(i); + bool bExists = false; + for (int j = 0; piChannelIDs[j] >= 0; ++j) { + if (!pChannelStrip->channel()) break; + if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) { + // strip exists, don't touch it + bExists = true; + break; + } + } + if (!bExists) destroyChannelStrip(pChannelStrip); + } + } + m_pWorkspace->setUpdatesEnabled(true); + } +} // Update the recent files list and menu. void MainForm::updateRecentFiles ( const QString& sFilename ) @@ -2231,6 +2305,16 @@ return pChannelStrip; } +void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) { + // Just delete the channel strip. + delete pChannelStrip; + + // Do we auto-arrange? + if (m_pOptions && m_pOptions->bAutoArrange) + channelsArrange(); + + stabilizeForm(); +} // Retrieve the active channel strip. ChannelStrip* MainForm::activeChannelStrip (void) @@ -2242,11 +2326,16 @@ // Retrieve a channel strip by index. ChannelStrip* MainForm::channelStripAt ( int iChannel ) { + if (!m_pWorkspace) return NULL; + QWidgetList wlist = m_pWorkspace->windowList(); if (wlist.isEmpty()) return NULL; - return static_cast (wlist.at(iChannel)); + if (iChannel < 0 || iChannel >= wlist.size()) + return NULL; + + return dynamic_cast (wlist.at(iChannel)); } @@ -2616,15 +2705,34 @@ .arg(::lscp_client_get_timeout(m_pClient))); // Subscribe to channel info change notifications... + if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK) + appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)"); if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK) appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)"); -#if CONFIG_LSCP_CHANNEL_MIDI + DeviceStatusForm::onDevicesChanged(); // initialize + updateViewMidiDeviceStatusMenu(); + if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK) + appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)"); + if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK) + appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)"); + if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK) + appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)"); + if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK) + appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)"); + +#if CONFIG_EVENT_CHANNEL_MIDI // Subscribe to channel MIDI data notifications... if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK) appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)"); #endif +#if CONFIG_EVENT_DEVICE_MIDI + // Subscribe to channel MIDI data notifications... + if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK) + appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)"); +#endif + // We may stop scheduling around. stopSchedule(); @@ -2677,10 +2785,18 @@ closeSession(false); // Close us as a client... -#if CONFIG_LSCP_CHANNEL_MIDI +#if CONFIG_EVENT_DEVICE_MIDI + ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI); +#endif +#if CONFIG_EVENT_CHANNEL_MIDI ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI); #endif + ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO); + ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT); + ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO); + ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT); ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO); + ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT); ::lscp_client_destroy(m_pClient); m_pClient = NULL;