summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog7
-rw-r--r--muse2/muse/app.cpp796
-rw-r--r--muse2/muse/app.h27
-rw-r--r--muse2/muse/audiotrack.cpp1
-rw-r--r--muse2/muse/conf.cpp40
-rw-r--r--muse2/muse/confmport.cpp6
-rw-r--r--muse2/muse/driver/jack.cpp24
-rw-r--r--muse2/muse/gconfig.cpp3
-rw-r--r--muse2/muse/gconfig.h1
-rw-r--r--muse2/muse/globals.cpp4
-rw-r--r--muse2/muse/globals.h10
-rw-r--r--muse2/muse/mixer/astrip.cpp1058
-rw-r--r--muse2/muse/mixer/astrip.h6
-rw-r--r--muse2/muse/mixer/mstrip.cpp52
-rw-r--r--muse2/muse/mixer/mstrip.h5
-rw-r--r--muse2/muse/node.cpp2
-rw-r--r--muse2/muse/route.cpp22
-rw-r--r--muse2/muse/route.h15
-rw-r--r--muse2/muse/seqmsg.cpp4
-rw-r--r--muse2/muse/song.cpp4
-rw-r--r--muse2/muse/wavetrack.cpp2
-rw-r--r--muse2/muse/widgets/CMakeLists.txt4
-rw-r--r--muse2/muse/widgets/genset.cpp3
-rw-r--r--muse2/muse/widgets/gensetbase.ui23
-rw-r--r--muse2/muse/widgets/menutitleitem.cpp48
-rw-r--r--muse2/muse/widgets/mtrackinfo.cpp98
-rw-r--r--muse2/muse/widgets/mtrackinfo.h2
-rw-r--r--muse2/muse/widgets/musewidgetsplug.cpp5
-rw-r--r--muse2/muse/widgets/popupmenu.cpp91
-rw-r--r--muse2/muse/widgets/popupmenu.h3
-rw-r--r--muse2/muse/widgets/routepopup.cpp1416
-rw-r--r--muse2/muse/widgets/routepopup.h73
-rw-r--r--muse2/synti/deicsonze/deicsonzeplugin.cpp8
33 files changed, 1720 insertions, 2143 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index 24545b76..613cecc1 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -3,6 +3,13 @@
- Added step-rec-support for drum edit and score edit (flo93)
- put step-rec-stuff into its own class (flo93)
- moved clefTypes out of scoreedit.h to prevent compile-horror (flo93)
+ - Declared struct Route as QMetaType to make it a QVariant type. (Tim)
+ - Moved: All routing popup menu stuff from app, astrip, mstrip, mtrackinfo into
+ new class RoutePopupMenu, *massively* cleaning up those 4 files.
+ Used the new Route QVariant type as action data instead of integers.
+ - Moved MenuTitleItem definitions from astrip.cpp into it's own menutitleitem.cpp (Tim)
+ - Added to settings: "Make popup menus stay open. Otherwise hold Ctrl." (Tim)
+ To avoid showing new users non-standard behaviour, the default is off!
24.05.2011:
- Awl::PitchEdit now can be set with the musical keyboard (flo93)
- fixed y-stretch (flo93)
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 62871b18..72cdad6a 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -43,7 +43,7 @@
#include "mixdowndialog.h"
#include "pianoroll.h"
#include "scoreedit.h"
-#include "popupmenu.h"
+#include "routepopup.h"
#include "shortcutconfig.h"
#include "songinfo.h"
#include "ticksynth.h"
@@ -93,7 +93,6 @@ static QString* projectList[PROJECT_LIST_LEN];
extern void initMidiSynth();
extern void exitJackAudio();
extern void exitDummyAudio();
-// p3.3.39
extern void exitOSC();
#ifdef HAVE_LASH
@@ -809,7 +808,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
editInstrument = 0;
routingPopupMenu = 0;
progress = 0;
- //routingPopupView = 0;
appName = QString("MusE");
setWindowTitle(appName);
@@ -1658,7 +1656,6 @@ void MusE::initMidiDevices()
audio->msgInitMidiDevices();
- // Added by T356
//audio->msgIdle(false);
}
@@ -2080,7 +2077,7 @@ bool MusE::save(const QString& name, bool overwriteWarn)
if (ferror(f)) {
QString s = "Write File\n" + name + "\nfailed: "
//+ strerror(errno);
- + QString(strerror(errno)); // p4.0.0
+ + QString(strerror(errno));
QMessageBox::critical(this,
tr("MusE: Write File failed"), s);
popenFlag? pclose(f) : fclose(f);
@@ -2172,10 +2169,10 @@ void MusE::closeEvent(QCloseEvent* event)
printf("MusE: Exiting Metronome\n");
exitMetronome();
- // p3.3.47
- // Make sure to clear the menu, which deletes any sub menus.
+ // Make sure to delete the menu. ~routingPopupMenu() will NOT be called automatically.
+ // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus. p4.0.26
if(routingPopupMenu)
- routingPopupMenu->clear();
+ delete routingPopupMenu;
#if 0
if(routingPopupView)
{
@@ -2201,10 +2198,8 @@ void MusE::closeEvent(QCloseEvent* event)
d.remove(f.completeBaseName() + ".wca");
}
- // Added by Tim. p3.3.14
-
#ifdef HAVE_LASH
- // Disconnect gracefully from LASH.
+ // Disconnect gracefully from LASH. Tim. p3.3.14
if(lash_client)
{
if(debugMsg)
@@ -2292,789 +2287,18 @@ void MusE::showTransport(bool flag)
//---------------------------------------------------------
// getRoutingPopupMenu
+// Get the special common routing popup menu. Used (so far)
+// by audio strip, midi strip, and midi trackinfo.
//---------------------------------------------------------
-PopupMenu* MusE::getRoutingPopupMenu()
+RoutePopupMenu* MusE::getRoutingPopupMenu()
{
if(!routingPopupMenu)
- routingPopupMenu = new PopupMenu(this, true);
+ routingPopupMenu = new RoutePopupMenu(this);
return routingPopupMenu;
}
//---------------------------------------------------------
-// updateRouteMenus
-//---------------------------------------------------------
-
-void MusE::updateRouteMenus(Track* track, QObject* master)
-{
- // NOTE: The purpose of this routine is to make sure the items actually reflect
- // the routing status.
- // In case for some reason a route could not be added (or removed).
- // Then the item will be properly un-checked (or checked) here.
-
- //if(!track || track != gRoutingPopupMenuMaster || track->type() == Track::AUDIO_AUX)
- //if(!track || track->type() == Track::AUDIO_AUX)
- if(!track || gRoutingPopupMenuMaster != master) // p3.3.50
- return;
-
- PopupMenu* pup = getRoutingPopupMenu();
-
- if(pup->actions().isEmpty())
- return;
-
- if(!pup->isVisible())
- return;
-
- //AudioTrack* t = (AudioTrack*)track;
- RouteList* rl = gIsOutRoutingPopupMenu ? track->outRoutes() : track->inRoutes();
-
- iRouteMenuMap imm = gRoutingMenuMap.begin();
- for(; imm != gRoutingMenuMap.end(); ++imm)
- {
- // p3.3.50 Ignore the 'toggle' items.
- if(imm->second.type == Route::MIDI_PORT_ROUTE &&
- //imm->first >= (MIDI_PORTS * MIDI_CHANNELS) && imm->first < (MIDI_PORTS * MIDI_CHANNELS + MIDI_PORTS))
- imm->second.channel == (1 << MIDI_CHANNELS) - 1) // p4.0.14 See if all channels are set, rather than using ID.
- continue;
-
-
- // p4.0.14 TODO FIXME Couldn't quite figure out the logic yet. It should be possible (I hope).
- // But not really required for now, as per above note.
- if(gIsOutRoutingPopupMenu && track->isMidiTrack() &&
- imm->second.type == Route::TRACK_ROUTE && imm->second.track->type() == Track::AUDIO_INPUT)
- return;
- #if 0
- printf("imm route:\n");
- imm->second.dump();
- if(track->isMidiTrack())
- {
- if(imm->second.type == Route::TRACK_ROUTE && imm->second.track->type() == Track::AUDIO_INPUT)
- {
- Route &aRoute = imm->second;
- int chbit = aRoute.channel;
- ///Route bRoute(track, chbit);
- ///int mdidx = bRoute.midiPort;
- int port = ((MidiTrack*)track)->outPort();
- if(port < 0 || port >= MIDI_PORTS)
- continue;
- int tchbit = 1 << ((MidiTrack*)track)->outChannel();
-
- MidiPort* mp = &midiPorts[port];
-
- ///Route bRoute(port, chbit);
-
- //int chmask = 0;
- bool found = false;
- RouteList* mprl = gIsOutRoutingPopupMenu ? mp->outRoutes() : mp->inRoutes();
- iRoute ir = mprl->begin();
- for(; ir != mprl->end(); ++ir)
- {
- printf("mp route:\n");
- ir->dump();
- ///if(aRoute.type == Route::TRACK_ROUTE) // Is the map route a track route?
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == aRoute.track) // Is the track route a midi port route?
- //&& (ir->channel & chbit) == chbit)
- //&& (ir->channel & tchbit)) // Is the exact channel mask bit(s) set?
- {
- printf("track matches\n");
- if(ir->channel & tchbit)
- {
- found = true;
- printf("found: bit matches\n");
- }
- break;
- }
- }
- ///else
- ///if(*ir == aRoute)
- ///{
- //found = true;
- /// break;
- ///}
- }
- //pup->setItemChecked(imm->first, found);
- //printf("MusE::updateRouteMenus setItemChecked\n");
- // TODO: MusE-2: Convert this, fastest way is to change the routing map, otherwise this requires a lookup.
- //if(pup->isItemChecked(imm->first) != (irl != rl->end()))
- // pup->setItemChecked(imm->first, irl != rl->end());
- QAction* act = pup->findActionFromData(imm->first);
- //printf("set act checked to:%d\n", ir != mprl->end());
- //if(act && act->isChecked() != (ir != mprl->end()))
- // act->setChecked(ir != mprl->end());
- printf("set act checked to:%d\n", found);
- if(act && act->isChecked() != found)
- act->setChecked(found);
-
- //return;
- }
- }
- #endif
-
- //bool found = false;
- iRoute irl = rl->begin();
- for(; irl != rl->end(); ++irl)
- {
- if(imm->second.type == Route::MIDI_PORT_ROUTE) // p3.3.50 Is the map route a midi port route?
- {
- if(irl->type == Route::MIDI_PORT_ROUTE && irl->midiPort == imm->second.midiPort // Is the track route a midi port route?
- && (irl->channel & imm->second.channel) == imm->second.channel) // Is the exact channel mask bit(s) set?
- {
- //found = true;
- break;
- }
- }
- else
- if(*irl == imm->second)
- {
- //found = true;
- break;
- }
- }
- //pup->setItemChecked(imm->first, found);
- //printf("MusE::updateRouteMenus setItemChecked\n");
- // TODO: MusE-2: Convert this, fastest way is to change the routing map, otherwise this requires a lookup.
- //if(pup->isItemChecked(imm->first) != (irl != rl->end()))
- // pup->setItemChecked(imm->first, irl != rl->end());
- QAction* act = pup->findActionFromData(imm->first);
- if(act && act->isChecked() != (irl != rl->end()))
- act->setChecked(irl != rl->end());
- }
-}
-
-//---------------------------------------------------------
-// routingPopupMenuActivated
-//---------------------------------------------------------
-
-void MusE::routingPopupMenuActivated(Track* track, int n)
-{
- //if(!track || (track != gRoutingPopupMenuMaster))
- if(!track)
- return;
-
- if(track->isMidiTrack())
- {
- PopupMenu* pup = getRoutingPopupMenu();
-
- if(pup->actions().isEmpty())
- return;
-
- //MidiTrack* t = (MidiTrack*)track;
- RouteList* rl = gIsOutRoutingPopupMenu ? track->outRoutes() : track->inRoutes();
-
- if(n == -1)
- return;
-
- if(!gIsOutRoutingPopupMenu && n == 0) // p4.0.17
- {
- muse->configMidiPorts();
- return;
- }
-
- iRouteMenuMap imm = gRoutingMenuMap.find(n);
- if(imm == gRoutingMenuMap.end())
- return;
-
- // Support Midi Port to Audio Input track routes. p4.0.14 Tim.
- if(imm->second.type == Route::TRACK_ROUTE)
- {
- //if(gIsOutRoutingPopupMenu) // Try to avoid splitting like this.
- {
- Route &aRoute = imm->second;
- int chbit = aRoute.channel;
- int port = ((MidiTrack*)track)->outPort();
- if(port < 0 || port >= MIDI_PORTS)
- return;
-
- MidiPort* mp = &midiPorts[port];
- ///MidiDevice* md = mp->device();
-
- // This is desirable, but could lead to 'hidden' routes unless we add more support
- // such as removing the existing routes when user changes flags.
- // So for now, just list all valid ports whether read or write.
- ///if(!md)
- /// return;
- ///if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2)))
- /// return;
-
- //int channel = ((MidiTrack*)track->outChannel();
- Route bRoute(port, chbit);
-
- int chmask = 0;
- RouteList* mprl = gIsOutRoutingPopupMenu ? mp->outRoutes() : mp->inRoutes();
- iRoute ir = mprl->begin();
- for (; ir != mprl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == aRoute.track) // Is there already a route to this port?
- {
- chmask = ir->channel; // Grab the channel mask.
- break;
- }
- }
- //if (iir != rl->end())
- if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
- {
- // disconnect
- if(gIsOutRoutingPopupMenu)
- audio->msgRemoveRoute(bRoute, aRoute);
- else
- audio->msgRemoveRoute(aRoute, bRoute);
- }
- else
- {
- // connect
- if(gIsOutRoutingPopupMenu)
- audio->msgAddRoute(bRoute, aRoute);
- else
- audio->msgAddRoute(aRoute, bRoute);
- }
-
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
-
- }
- return;
- }
-
-
- if(imm->second.type != Route::MIDI_PORT_ROUTE)
- return;
- Route &aRoute = imm->second;
- int chbit = aRoute.channel;
- Route bRoute(track, chbit);
- int mdidx = aRoute.midiPort;
-
- MidiPort* mp = &midiPorts[mdidx];
- MidiDevice* md = mp->device();
- //if(!md) // Removed p4.0.17 Allow connections to ports with no device.
- // return;
-
- //if(!(md->rwFlags() & 2))
- //if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2)))
- if(md && !(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2))) // p4.0.17
- return;
-
- int chmask = 0;
- iRoute iir = rl->begin();
- for (; iir != rl->end(); ++iir)
- {
- //if(*iir == (dst ? bRoute : aRoute))
- //if(*iir == aRoute)
- if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx) // p3.3.50 Is there already a route to this port?
- {
- chmask = iir->channel; // p3.3.50 Grab the channel mask.
- break;
- }
- }
- //if (iir != rl->end())
- if ((chmask & chbit) == chbit) // p3.3.50 Is the channel's bit(s) set?
- {
- // disconnect
- if(gIsOutRoutingPopupMenu)
- audio->msgRemoveRoute(bRoute, aRoute);
- else
- audio->msgRemoveRoute(aRoute, bRoute);
- }
- else
- {
- // connect
- if(gIsOutRoutingPopupMenu)
- audio->msgAddRoute(bRoute, aRoute);
- else
- audio->msgAddRoute(aRoute, bRoute);
- }
-
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- }
- else
- {
- // TODO: Try to move code from AudioStrip::routingPopupMenuActivated into here.
-
- /*
- PopupMenu* pup = getRoutingPopupMenu();
-
- printf("MusE::routingPopupMenuActivated audio n:%d count:%d\n", n, pup->count());
-
- if(pup->count() == 0)
- return;
-
- AudioTrack* t = (AudioTrack*)track;
- RouteList* rl = gIsOutRoutingPopupMenu ? t->outRoutes() : t->inRoutes();
-
- //QPoint ppt = QCursor::pos();
-
- if(n == -1)
- {
- //printf("MusE::routingPopupMenuActivated audio n = -1 deleting popup...\n");
- printf("MusE::routingPopupMenuActivated audio n = -1\n");
- ///delete pup;
- ///pup = 0;
- return;
- }
- else
- //if(n == 0)
- //{
- //printf("MusE::routingPopupMenuActivated audio n = 0 = tearOffHandle\n");
- //oR->setDown(false);
- // return;
- //}
- //else
- {
- if(gIsOutRoutingPopupMenu)
- {
- QString s(pup->text(n));
-
- //printf("AudioStrip::routingPopupMenuActivated audio text:%s\n", s.toLatin1().constData());
-
- if(track->type() == Track::AUDIO_OUTPUT)
- {
- ///delete orpup;
-
- int chan = n & 0xf;
-
- //Route srcRoute(t, -1);
- //Route srcRoute(t, chan, chans);
- //Route srcRoute(t, chan, 1);
- Route srcRoute(t, chan);
-
- //Route dstRoute(s, true, -1);
- Route dstRoute(s, true, -1, Route::JACK_ROUTE);
- //Route dstRoute(s, true, 0, Route::JACK_ROUTE);
-
- //srcRoute.channel = dstRoute.channel = chan;
- dstRoute.channel = chan;
- //dstRoute.channels = 1;
-
- // check if route src->dst exists:
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == dstRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect if route exists
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect if route does not exist
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
-
- // p3.3.47
- //pup->popup(ppt, 0);
-
- //oR->setDown(false);
- return;
-
- // p3.3.46
- ///goto _redisplay;
- }
-
- iRouteMenuMap imm = gRoutingMenuMap.find(n);
- if(imm == gRoutingMenuMap.end())
- {
- ///delete orpup;
- //oR->setDown(false); // orpup->exec() catches mouse release event
- return;
- }
-
- //int chan = n >> 16;
- //int chans = (chan >> 15) + 1; // Bit 31 MSB: Mono or stereo.
- //chan &= 0xffff;
- //int chan = imm->second.channel;
- //int chans = imm->second.channels;
-
- //Route srcRoute(t, -1);
- //srcRoute.remoteChannel = chan;
- //Route srcRoute(t, chan, chans);
- Route srcRoute(t, imm->second.channel, imm->second.channels);
- //Route srcRoute(t, imm->second.channel);
- srcRoute.remoteChannel = imm->second.remoteChannel;
-
- //Route dstRoute(s, true, -1);
- //Route dstRoute(s, true, -1, Route::TRACK_ROUTE);
- Route &dstRoute = imm->second;
-
- // check if route src->dst exists:
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == dstRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect if route exists
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect if route does not exist
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
-
- // p3.3.46
- //oR->setDown(false);
- ///goto _redisplay;
-
- // p3.3.47
- //pup->popup(ppt, 0);
- }
- else
- {
- QString s(pup->text(n));
-
- if(track->type() == Track::AUDIO_INPUT)
- {
- ///delete pup;
- int chan = n & 0xf;
-
- Route srcRoute(s, false, -1, Route::JACK_ROUTE);
- Route dstRoute(t, chan);
-
- srcRoute.channel = chan;
-
- iRoute irl = rl->begin();
- for(; irl != rl->end(); ++irl)
- {
- if(*irl == srcRoute)
- break;
- }
- if(irl != rl->end())
- // disconnect
- audio->msgRemoveRoute(srcRoute, dstRoute);
- else
- // connect
- audio->msgAddRoute(srcRoute, dstRoute);
-
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- //iR->setDown(false); // pup->exec() catches mouse release event
- return;
-
- // p3.3.46
- ///goto _redisplay;
- }
-
- iRouteMenuMap imm = gRoutingMenuMap.find(n);
- if(imm == gRoutingMenuMap.end())
- {
- //delete pup;
- //iR->setDown(false); // pup->exec() catches mouse release event
- return;
- }
-
- //int chan = n >> 16;
- //int chans = (chan >> 15) + 1; // Bit 31 MSB: Mono or stereo.
- //chan &= 0xffff;
- //int chan = imm->second.channel;
- //int chans = imm->second.channels;
-
- //Route srcRoute(s, false, -1);
- //Route srcRoute(s, false, -1, Route::TRACK_ROUTE);
- Route &srcRoute = imm->second;
-
- //Route dstRoute(t, -1);
- //Route dstRoute(t, chan, chans);
- Route dstRoute(t, imm->second.channel, imm->second.channels);
- //Route dstRoute(t, imm->second.channel);
- dstRoute.remoteChannel = imm->second.remoteChannel;
-
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == srcRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
-
- // p3.3.46
- //iR->setDown(false);
- ///goto _redisplay;
-
-
-
-
- }
-
- }
- */
-
- }
- //else
- //{
- //}
-}
-
-//---------------------------------------------------------
-// routingPopupMenuAboutToHide
-//---------------------------------------------------------
-
-void MusE::routingPopupMenuAboutToHide()
-{
- // Hmm, can't do this? Sub-menus stay open with this. Re-arranged, testing... Nope.
- //PopupMenu* pup = muse->getRoutingPopupMenu();
- //pup->disconnect();
- //pup->clear();
-
- gRoutingMenuMap.clear();
- gRoutingPopupMenuMaster = 0;
-}
-
-//---------------------------------------------------------
-// prepareRoutingPopupMenu
-//---------------------------------------------------------
-
-PopupMenu* MusE::prepareRoutingPopupMenu(Track* track, bool dst)
-{
- if(!track)
- return 0;
-
- if(track->isMidiTrack())
- {
- RouteList* rl = dst ? track->outRoutes() : track->inRoutes();
- //Route dst(track, -1);
-
- PopupMenu* pup = getRoutingPopupMenu();
- pup->disconnect();
- //connect(pup, SIGNAL(activated(int)), SLOT(routingPopupMenuActivated(int)));
- //connect(pup, SIGNAL(aboutToHide()), SLOT(routingPopupMenuAboutToHide()));
-
- pup->clear();
- gRoutingMenuMap.clear();
-
- int gid = 0;
- QAction* act = 0;
-
- if(dst)
- {
- // Support Midi Port to Audio Input track routes. p4.0.14 Tim.
- int port = ((MidiTrack*)track)->outPort();
- if(port >= 0 && port < MIDI_PORTS)
- {
- MidiPort* mp = &midiPorts[port];
-
- // p4.0.17 Do not list synth devices! Requiring valid device is desirable,
- // but could lead to 'hidden' routes unless we add more support
- // such as removing the existing routes when user changes flags.
- // So for now, just list all valid ports whether read or write.
- if(mp->device() && !mp->device()->isSynti())
- {
- RouteList* mprl = mp->outRoutes();
- int chbits = 1 << ((MidiTrack*)track)->outChannel();
- //MidiDevice* md = mp->device();
- //if(!md)
- // continue;
-
- pup->addSeparator();
- pup->addAction(new MenuTitleItem(tr("Soloing chain"), pup));
- PopupMenu* subp = new PopupMenu(pup, true);
- subp->setTitle(tr("Audio returns"));
- pup->addMenu(subp);
-
- InputList* al = song->inputs();
- for (iAudioInput i = al->begin(); i != al->end(); ++i)
- {
- Track* t = *i;
- QString s(t->name());
-
- act = subp->addAction(s);
- act->setData(gid);
- act->setCheckable(true);
-
- Route r(t, chbits);
-
- gRoutingMenuMap.insert( pRouteMenuMap(gid, r) );
-
- for(iRoute ir = mprl->begin(); ir != mprl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == t && (ir->channel & chbits))
- {
- act->setChecked(true);
- break;
- }
- }
- ++gid;
- }
- }
- }
- }
- else
- {
- // Warn if no devices available. Add an item to open midi config. p4.0.17
- int pi = 0;
- for( ; pi < MIDI_PORTS; ++pi)
- {
- MidiDevice* md = midiPorts[pi].device();
- if(md && !md->isSynti() && (md->rwFlags() & 2))
- break;
- }
- if(pi == MIDI_PORTS)
- {
- act = pup->addAction(tr("Warning: No midi input devices!"));
- act->setCheckable(false);
- act->setData(-1);
- pup->addSeparator();
- }
- act = pup->addAction(QIcon(*settings_midiport_softsynthsIcon), tr("Open midi config..."));
- act->setCheckable(false);
- act->setData(gid);
- pup->addSeparator();
- ++gid;
-
- pup->addAction(new MenuTitleItem("Midi input ports", pup));
-
- for(int i = 0; i < MIDI_PORTS; ++i)
- {
- // NOTE: Could possibly list all devices, bypassing ports, but no, let's stick with ports.
- MidiPort* mp = &midiPorts[i];
- MidiDevice* md = mp->device();
- //if(!md)
- // continue;
-
- // p4.0.17 Do not list synth devices!
- if(md && md->isSynti())
- continue;
-
- if(md && !(md->rwFlags() & 2))
- continue;
-
- //printf("MusE::prepareRoutingPopupMenu adding submenu portnum:%d\n", i);
-
- // MusE-2: Check this - needed with QMenu? Help says no. No - verified, it actually causes double triggers!
- //connect(subp, SIGNAL(triggered(QAction*)), pup, SIGNAL(triggered(QAction*)));
- //connect(subp, SIGNAL(aboutToHide()), pup, SIGNAL(aboutToHide()));
-
- int chanmask = 0;
- // p3.3.50 To reduce number of routes required, from one per channel to just one containing a channel mask.
- // Look for the first route to this midi port. There should always be only a single route for each midi port, now.
- iRoute ir = rl->begin();
- for( ; ir != rl->end(); ++ir)
- {
- if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
- {
- // We have a route to the midi port. Grab the channel mask.
- chanmask = ir->channel;
- break;
- }
- }
- // p4.0.17 List ports with no device, but with routes to this track, in the main popup.
- if(!md && ir == rl->end())
- continue;
-
- PopupMenu* subp = new PopupMenu(pup, true);
- subp->setTitle(QString("%1:").arg(i+1) + (md ? md->name() : tr("<none>")));
-
- for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
- {
- act = subp->addAction(QString("Channel %1").arg(ch+1));
- act->setCheckable(true);
- act->setData(gid);
-
- int chbit = 1 << ch;
- Route srcRoute(i, chbit); // p3.3.50 In accordance with new channel mask, use the bit position.
-
- gRoutingMenuMap.insert( pRouteMenuMap(gid, srcRoute) );
-
- if(chanmask & chbit) // p3.3.50 Is the channel already set? Show item check mark.
- act->setChecked(true);
-
- ++gid;
- }
- //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
- act = subp->addAction(tr("Toggle all"));
- //act->setCheckable(true);
- act->setData(gid);
- Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
- gRoutingMenuMap.insert( pRouteMenuMap(gid, togRoute) );
- ++gid;
- pup->addMenu(subp);
- }
-
- #if 0
- // p4.0.17 List ports with no device and no in routes, in a separate popup.
- PopupMenu* morep = new PopupMenu(pup, true);
- morep->setTitle(tr("More..."));
- for(int i = 0; i < MIDI_PORTS; ++i)
- {
- MidiPort* mp = &midiPorts[i];
- if(mp->device())
- continue;
-
- PopupMenu* subp = new PopupMenu(morep, true);
- subp->setTitle(QString("%1:").arg(i) + tr("<none>"));
-
- // MusE-2: Check this - needed with QMenu? Help says no. No - verified, it actually causes double triggers!
- //connect(subp, SIGNAL(triggered(QAction*)), pup, SIGNAL(triggered(QAction*)));
- //connect(subp, SIGNAL(aboutToHide()), pup, SIGNAL(aboutToHide()));
-
- iRoute ir = rl->begin();
- for( ; ir != rl->end(); ++ir)
- {
- if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
- break;
- }
- if(ir != rl->end())
- continue;
-
- for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
- {
- act = subp->addAction(QString("Channel %1").arg(ch+1));
- act->setCheckable(true);
- act->setData(gid);
-
- int chbit = 1 << ch;
- Route srcRoute(i, chbit); // In accordance with new channel mask, use the bit position.
-
- gRoutingMenuMap.insert( pRouteMenuMap(gid, srcRoute) );
-
- //if(chanmask & chbit) // Is the channel already set? Show item check mark.
- // act->setChecked(true);
-
- ++gid;
- }
- //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
- act = subp->addAction(QString("Toggle all"));
- //act->setCheckable(true);
- act->setData(gid);
- Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
- gRoutingMenuMap.insert( pRouteMenuMap(gid, togRoute) );
- ++gid;
- morep->addMenu(subp);
- }
- pup->addMenu(morep);
- #endif
-
- }
-
- if(pup->actions().isEmpty())
- {
- gRoutingPopupMenuMaster = 0;
- //pup->clear();
- //pup->disconnect();
- gRoutingMenuMap.clear();
- //oR->setDown(false);
- return 0;
- }
-
- gIsOutRoutingPopupMenu = dst;
- return pup;
- }
-
- return 0;
-}
-
-//---------------------------------------------------------
// saveAs
//---------------------------------------------------------
diff --git a/muse2/muse/app.h b/muse2/muse/app.h
index c194b603..256154e2 100644
--- a/muse2/muse/app.h
+++ b/muse2/muse/app.h
@@ -36,8 +36,7 @@ class Transport;
class BigTime;
class Arranger;
class Instrument;
-class PopupMenu;
-class PopupView;
+class RoutePopupMenu;
class Track;
class PrinterConfig;
class MidiSyncConfig;
@@ -69,8 +68,6 @@ class ScoreEdit;
#define MENU_ADD_SYNTH_ID_BASE 0x1000
-
-
//---------------------------------------------------------
// MusE
//---------------------------------------------------------
@@ -164,10 +161,8 @@ class MusE : public QMainWindow
QMenu* menu_functions, *menuScriptPlugins;
QMenu* select, *master, *midiEdit, *addTrack;
- // Special 'stay-open' menu for routes.
- PopupMenu* routingPopupMenu;
- //PopupView* routingPopupView;
-
+ // Special common menu for routes. Used (so far) by audio and midi strip, and midi trackinfo.
+ RoutePopupMenu* routingPopupMenu;
QMenu* follow;
QMenu* midiInputPlugins;
@@ -337,7 +332,6 @@ class MusE : public QMainWindow
private:
void adjustGlobalLists(int startPos, int diff);
-
public slots:
bool saveAs();
void bounceToFile(AudioOutput* ao = 0);
@@ -358,8 +352,6 @@ class MusE : public QMainWindow
void setUsedTool(int);
void showDidYouKnowDialog();
void startEditInstrument();
-
- void routingPopupMenuAboutToHide();
void configMidiPorts();
public:
@@ -371,7 +363,6 @@ class MusE : public QMainWindow
bool importMidi(const QString name, bool merge);
void kbAccel(int);
void changeConfig(bool writeFlag);
-
void seqStop();
bool seqStart();
void setHeartBeat();
@@ -384,18 +375,8 @@ class MusE : public QMainWindow
QWidget* bigtimeWindow();
bool importWaveToTrack(QString& name, unsigned tick=0, Track* track=NULL);
void importPartToTrack(QString& filename, unsigned tick, Track* track);
-
void showTransport(bool flag);
-
- // Special 'stay-open' menu for routes.
- PopupMenu* getRoutingPopupMenu();
- PopupMenu* prepareRoutingPopupMenu(Track* /*track*/, bool /*dst*/);
- void routingPopupMenuActivated(Track* /*track*/, int /*id*/);
- void updateRouteMenus(Track* /*track*/, QObject* /*master*/);
- // Testing...
- //PopupView* getRoutingPopupView();
- //PopupView* prepareRoutingPopupView(Track* /*track*/, bool /*dst*/);
- //void routingPopupViewActivated(Track* /*track*/, int /*id*/);
+ RoutePopupMenu* getRoutingPopupMenu();
#ifdef HAVE_LASH
void lash_idle_cb ();
diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp
index c427a55c..b004638f 100644
--- a/muse2/muse/audiotrack.cpp
+++ b/muse2/muse/audiotrack.cpp
@@ -34,6 +34,7 @@ bool WaveTrack::_isVisible=true;
// Jack often shuts down during file save, causing the routes to be lost in the file.
// cacheJackRouteNames() is ONLY called from MusE::save() in app.cpp
// Update: Not required any more because the real problem was Jack RT priority, which has been fixed.
+// Keep this around for now. It may come in handy if we want to preserve route names with dummy audio driver!
/*
typedef std::multimap <const int, QString> jackRouteNameMap;
std::map <const AudioTrack*, jackRouteNameMap > jackRouteNameCache;
diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp
index 56cbc321..89cdd04d 100644
--- a/muse2/muse/conf.cpp
+++ b/muse2/muse/conf.cpp
@@ -948,6 +948,9 @@ void readConfiguration(Xml& xml, bool readOnlySequencer)
config.projectStoreInFolder = xml.parseInt();
else if (tag == "useProjectSaveDialog")
config.useProjectSaveDialog = xml.parseInt();
+ else if (tag == "popupsDefaultStayOpen")
+ config.popupsDefaultStayOpen = xml.parseInt();
+
else
xml.unknown("configuration");
break;
@@ -1217,7 +1220,6 @@ void MusE::writeGlobalConfiguration(int level, Xml& xml) const
xml.intTag(level, "midiFilterCtrl2", midiFilterCtrl2);
xml.intTag(level, "midiFilterCtrl3", midiFilterCtrl3);
xml.intTag(level, "midiFilterCtrl4", midiFilterCtrl4);
- // Removed by Tim. p3.3.6
//xml.intTag(level, "txDeviceId", txDeviceId);
//xml.intTag(level, "rxDeviceId", rxDeviceId);
@@ -1226,7 +1228,8 @@ void MusE::writeGlobalConfiguration(int level, Xml& xml) const
xml.strTag(level, "externalWavEditor", config.externalWavEditor);
xml.intTag(level, "useOldStyleStopShortCut", config.useOldStyleStopShortCut);
xml.intTag(level, "moveArmedCheckBox", config.moveArmedCheckBox);
-
+ xml.intTag(level, "popupsDefaultStayOpen", config.popupsDefaultStayOpen);
+
//for (int i = 0; i < 6; ++i) {
for (int i = 0; i < NUM_FONTS; ++i) {
char buffer[32];
@@ -1279,39 +1282,8 @@ void MusE::writeGlobalConfiguration(int level, Xml& xml) const
xml.colorTag(level, "auxTrackBg", config.auxTrackBg);
xml.colorTag(level, "synthTrackBg", config.synthTrackBg);
- // Changed by Tim. p3.3.6
-
+ // Removed by Tim. p3.3.6
//xml.intTag(level, "txSyncPort", txSyncPort);
- /*
- // To keep old muse versions happy...
- bool mcsync = mmc = mtc = false;
- for(int sp = 0; sp < MIDI_PORTS; ++sp)
- {
- MidiSyncTxPort* txPort = &midiSyncTxPorts[sp];
- if(txPort->doMCSync() || txPort->doMMC() || txPort->doMTC())
- {
- if(txPort->doMCSync())
- mcsync = true;
- if(txPort->doMMC())
- mmc = true;
- if(txPort->doMTC())
- mtc = true;
- xml.intTag(level, "txSyncPort", sp);
- break;
- }
- }
- */
-
- // Added by Tim. p3.3.6
-
- //xml.tag(level++, "midiSyncInfo");
- //for(iMidiDevice id = midiDevices.begin(); id != midiDevices.end(); ++id)
- //{
- // MidiDevice* md = *id;
- // (*id)->syncInfo().write(level, xml, md);
- //}
- //xml.etag(level, "midiSyncInfo");
-
//xml.intTag(level, "rxSyncPort", rxSyncPort);
xml.intTag(level, "mtctype", mtcType);
xml.nput(level, "<mtcoffset>%02d:%02d:%02d:%02d:%02d</mtcoffset>\n",
diff --git a/muse2/muse/confmport.cpp b/muse2/muse/confmport.cpp
index fc005923..8b323fc1 100644
--- a/muse2/muse/confmport.cpp
+++ b/muse2/muse/confmport.cpp
@@ -507,7 +507,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
//Route dst(*ip, true, i);
//Route rt(*ip, (dev->rwFlags() & 1), -1, Route::JACK_ROUTE);
Route rt(*ip, (col == DEVCOL_OUTROUTES), -1, Route::JACK_ROUTE);
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
{
if (*ir == rt)
{
@@ -553,7 +553,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
Route srcRoute(dev, -1);
Route dstRoute(s, true, -1, Route::JACK_ROUTE);
- iRoute iir = rl->begin();
+ ciRoute iir = rl->begin();
for(; iir != rl->end(); ++iir)
{
if(*iir == dstRoute)
@@ -573,7 +573,7 @@ void MPConfig::rbClicked(QTableWidgetItem* item)
Route srcRoute(s, false, -1, Route::JACK_ROUTE);
Route dstRoute(dev, -1);
- iRoute iir = rl->begin();
+ ciRoute iir = rl->begin();
for(; iir != rl->end(); ++iir)
{
if(*iir == srcRoute)
diff --git a/muse2/muse/driver/jack.cpp b/muse2/muse/driver/jack.cpp
index f70cf3d3..c4d7a8ca 100644
--- a/muse2/muse/driver/jack.cpp
+++ b/muse2/muse/driver/jack.cpp
@@ -711,7 +711,7 @@ void JackAudioDevice::connectJackMidiPorts()
if(port) //
{
RouteList* rl = md->outRoutes();
- for (iRoute r = rl->begin(); r != rl->end(); ++r)
+ for (ciRoute r = rl->begin(); r != rl->end(); ++r)
connect(port, r->jackPort);
}
}
@@ -724,7 +724,7 @@ void JackAudioDevice::connectJackMidiPorts()
if(port) //
{
RouteList* rl = md->inRoutes();
- for (iRoute r = rl->begin(); r != rl->end(); ++r)
+ for (ciRoute r = rl->begin(); r != rl->end(); ++r)
connect(r->jackPort, port);
}
}
@@ -915,7 +915,7 @@ void JackAudioDevice::graphChanged()
// the "right" amount
for (int i = 0;i < 20;i++) {
erased = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -953,7 +953,7 @@ void JackAudioDevice::graphChanged()
const char** pn = ports;
while (*pn) {
bool found = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -1002,7 +1002,7 @@ void JackAudioDevice::graphChanged()
// the "right" amount
for (int i = 0; i < 20 ; i++) {
erased = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -1039,7 +1039,7 @@ void JackAudioDevice::graphChanged()
const char** pn = ports;
while (*pn) {
bool found = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
if (irl->channel != channel)
continue;
QString name = irl->name();
@@ -1113,7 +1113,7 @@ void JackAudioDevice::graphChanged()
for (int i = 0; i < 20 ; i++)
{
erased = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1155,7 +1155,7 @@ void JackAudioDevice::graphChanged()
const char** pn = ports;
while (*pn) {
bool found = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1212,7 +1212,7 @@ void JackAudioDevice::graphChanged()
for (int i = 0; i < 20 ; i++)
{
erased = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1253,7 +1253,7 @@ void JackAudioDevice::graphChanged()
const char** pn = ports;
while (*pn) {
bool found = false;
- for (iRoute irl = rl->begin(); irl != rl->end(); ++irl) {
+ for (ciRoute irl = rl->begin(); irl != rl->end(); ++irl) {
//if (irl->channel != channel)
// continue;
QString name = irl->name();
@@ -1473,7 +1473,7 @@ void JackAudioDevice::start(int /*priority*/)
for (int ch = 0; ch < channel; ++ch) {
RouteList* rl = ai->inRoutes();
void* port = ai->jackPort(ch);
- for (iRoute ir = rl->begin(); ir != rl->end(); ++ir) {
+ for (ciRoute ir = rl->begin(); ir != rl->end(); ++ir) {
if (ir->channel == ch)
connect(ir->jackPort, port);
}
@@ -1486,7 +1486,7 @@ void JackAudioDevice::start(int /*priority*/)
for (int ch = 0; ch < channel; ++ch) {
RouteList* rl = ai->outRoutes();
void* port = ai->jackPort(ch);
- for (iRoute r = rl->begin(); r != rl->end(); ++r) {
+ for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
if (r->channel == ch) {
connect(port, r->jackPort);
}
diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp
index 4d22ad4c..49a6d572 100644
--- a/muse2/muse/gconfig.cpp
+++ b/muse2/muse/gconfig.cpp
@@ -168,6 +168,7 @@ GlobalConfigValues config = {
QString("./"), // projectBaseFolder
true, // projectStoreInFolder
true, // useProjectSaveDialog
- 64 // minControlProcessPeriod
+ 64, // minControlProcessPeriod
+ false // popupsDefaultStayOpen
};
diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h
index cd236b36..acf39782 100644
--- a/muse2/muse/gconfig.h
+++ b/muse2/muse/gconfig.h
@@ -143,6 +143,7 @@ struct GlobalConfigValues {
bool projectStoreInFolder;
bool useProjectSaveDialog;
unsigned long minControlProcessPeriod;
+ bool popupsDefaultStayOpen;
};
extern GlobalConfigValues config;
diff --git a/muse2/muse/globals.cpp b/muse2/muse/globals.cpp
index 00c0f0a9..7f346f87 100644
--- a/muse2/muse/globals.cpp
+++ b/muse2/muse/globals.cpp
@@ -350,10 +350,6 @@ unsigned char rcPlayNote = 29;
unsigned char rcSteprecNote = 36;
bool automation = true;
-QObject* gRoutingPopupMenuMaster = 0;
-RouteMenuMap gRoutingMenuMap;
-bool gIsOutRoutingPopupMenu = false;
-
uid_t euid, ruid; // effective user id, real user id
bool midiSeqRunning = false;
diff --git a/muse2/muse/globals.h b/muse2/muse/globals.h
index 984571e2..cee5e815 100644
--- a/muse2/muse/globals.h
+++ b/muse2/muse/globals.h
@@ -13,7 +13,6 @@
#include "value.h"
#include "mtc.h"
-#include "route.h"
#include <unistd.h>
@@ -172,15 +171,6 @@ extern unsigned char rcSteprecNote;
extern bool midiSeqRunning;
extern bool automation;
-class QObject;
-// Which audio strip, midi strip, or midi track info strip
-// was responsible for popping up the routing menu.
-extern QObject* gRoutingPopupMenuMaster;
-// Map of routing popup menu item IDs to Routes.
-extern RouteMenuMap gRoutingMenuMap;
-// Whether the routes popup was shown by clicking the output routes button, or input routes button.
-extern bool gIsOutRoutingPopupMenu;
-
// p3.3.55
#define JACK_MIDI_OUT_PORT_SUFFIX "_out"
#define JACK_MIDI_IN_PORT_SUFFIX "_in"
diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp
index c1e92e59..5644e6eb 100644
--- a/muse2/muse/mixer/astrip.cpp
+++ b/muse2/muse/mixer/astrip.cpp
@@ -48,33 +48,8 @@
#include "gconfig.h"
#include "ttoolbutton.h"
#include "menutitleitem.h"
-#include "popupmenu.h"
-
-//---------------------------------------------------------
-// MenuTitleItem
-//---------------------------------------------------------
-
-MenuTitleItem::MenuTitleItem(const QString& ss, QWidget* parent)
- : QWidgetAction(parent)
- {
- s = ss;
- // Don't allow to click on it.
- setEnabled(false);
- // Just to be safe, set to -1 instead of default 0.
- setData(-1);
- }
-
-QWidget* MenuTitleItem::createWidget(QWidget *parent)
-{
- QLabel* l = new QLabel(s, parent);
- l->setAlignment(Qt::AlignCenter);
- l->setAutoFillBackground(true);
- //QPalette palette;
- //palette.setColor(label->backgroundRole(), c);
- //l->setPalette(palette);
- l->setBackgroundRole(QPalette::Dark);
- return l;
-}
+//#include "popupmenu.h"
+#include "routepopup.h"
/*
//---------------------------------------------------------
@@ -145,14 +120,6 @@ void AudioStrip::songChanged(int val)
if (val & SC_CHANNELS)
updateChannels();
- // p3.3.47
- // Update the routing popup menu if anything relevant changed.
- if (val & (SC_ROUTE | SC_CHANNELS | SC_CONFIG))
- {
- //updateRouteMenus();
- muse->updateRouteMenus(track, this); // p3.3.50 Use this handy shared routine.
- }
-
// Catch when label font, or configuration min slider and meter values change.
if (val & SC_CONFIG)
{
@@ -215,7 +182,6 @@ void AudioStrip::songChanged(int val)
if (val & SC_TRACK_MODIFIED)
{
setLabelText();
- // Added by Tim. p3.3.9
setLabelFont();
}
@@ -1007,898 +973,14 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at)
}
//---------------------------------------------------------
-// addMenuItem
-//---------------------------------------------------------
-
-static int addMenuItem(AudioTrack* track, Track* route_track, PopupMenu* lb, int id, RouteMenuMap& mm, int channel, int channels, bool isOutput)
-{
- // totalInChannels is only used by syntis.
- int toch = ((AudioTrack*)track)->totalOutChannels();
- // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
- if(track->channels() == 1)
- toch = 1;
-
- // Don't add the last stray mono route if the track is stereo.
- //if(route_track->channels() > 1 && (channel+1 == chans))
- // return id;
-
- RouteList* rl = isOutput ? track->outRoutes() : track->inRoutes();
-
- QAction* act;
-
- QString s(route_track->name());
-
- act = lb->addAction(s);
- act->setData(id);
- act->setCheckable(true);
-
- int ach = channel;
- int bch = -1;
-
- Route r(route_track, isOutput ? ach : bch, channels);
-
- r.remoteChannel = isOutput ? bch : ach;
-
- mm.insert( pRouteMenuMap(id, r) );
-
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == route_track && ir->remoteChannel == r.remoteChannel)
- {
- int tcompch = r.channel;
- if(tcompch == -1)
- tcompch = 0;
- int tcompchs = r.channels;
- if(tcompchs == -1)
- tcompchs = isOutput ? track->channels() : route_track->channels();
-
- int compch = ir->channel;
- if(compch == -1)
- compch = 0;
- int compchs = ir->channels;
- if(compchs == -1)
- compchs = isOutput ? track->channels() : ir->track->channels();
-
- if(compch == tcompch && compchs == tcompchs)
- {
- act->setChecked(true);
- break;
- }
- }
- }
- return ++id;
-}
-
-//---------------------------------------------------------
-// addAuxPorts
-//---------------------------------------------------------
-
-static int addAuxPorts(AudioTrack* t, PopupMenu* lb, int id, RouteMenuMap& mm, int channel, int channels, bool isOutput)
- {
- AuxList* al = song->auxs();
- for (iAudioAux i = al->begin(); i != al->end(); ++i) {
- Track* track = *i;
- if (t == track)
- continue;
- id = addMenuItem(t, track, lb, id, mm, channel, channels, isOutput);
- }
- return id;
- }
-
-//---------------------------------------------------------
-// addInPorts
-//---------------------------------------------------------
-
-static int addInPorts(AudioTrack* t, PopupMenu* lb, int id, RouteMenuMap& mm, int channel, int channels, bool isOutput)
- {
- InputList* al = song->inputs();
- for (iAudioInput i = al->begin(); i != al->end(); ++i) {
- Track* track = *i;
- if (t == track)
- continue;
- id = addMenuItem(t, track, lb, id, mm, channel, channels, isOutput);
- }
- return id;
- }
-
-//---------------------------------------------------------
-// addOutPorts
-//---------------------------------------------------------
-
-static int addOutPorts(AudioTrack* t, PopupMenu* lb, int id, RouteMenuMap& mm, int channel, int channels, bool isOutput)
- {
- OutputList* al = song->outputs();
- for (iAudioOutput i = al->begin(); i != al->end(); ++i) {
- Track* track = *i;
- if (t == track)
- continue;
- id = addMenuItem(t, track, lb, id, mm, channel, channels, isOutput);
- }
- return id;
- }
-
-//---------------------------------------------------------
-// addGroupPorts
-//---------------------------------------------------------
-
-static int addGroupPorts(AudioTrack* t, PopupMenu* lb, int id, RouteMenuMap& mm, int channel, int channels, bool isOutput)
- {
- GroupList* al = song->groups();
- for (iAudioGroup i = al->begin(); i != al->end(); ++i) {
- Track* track = *i;
- if (t == track)
- continue;
- id = addMenuItem(t, track, lb, id, mm, channel, channels, isOutput);
- }
- return id;
- }
-
-//---------------------------------------------------------
-// addWavePorts
-//---------------------------------------------------------
-
-static int addWavePorts(AudioTrack* t, PopupMenu* lb, int id, RouteMenuMap& mm, int channel, int channels, bool isOutput)
- {
- WaveTrackList* al = song->waves();
- for (iWaveTrack i = al->begin(); i != al->end(); ++i) {
- Track* track = *i;
- if (t == track)
- continue;
- id = addMenuItem(t, track, lb, id, mm, channel, channels, isOutput);
- }
- return id;
- }
-
-//---------------------------------------------------------
-// addSyntiPorts
-//---------------------------------------------------------
-
-static int addSyntiPorts(AudioTrack* t, PopupMenu* lb, int id,
- RouteMenuMap& mm, int channel, int channels, bool isOutput)
-{
- RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
-
- QAction* act;
-
- SynthIList* al = song->syntis();
- for (iSynthI i = al->begin(); i != al->end(); ++i)
- {
- Track* track = *i;
- if (t == track)
- continue;
- int toch = ((AudioTrack*)track)->totalOutChannels();
- // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
- if(track->channels() == 1)
- toch = 1;
-
- // totalInChannels is only used by syntis.
- int chans = (!isOutput || track->type() != Track::AUDIO_SOFTSYNTH) ? toch : ((AudioTrack*)track)->totalInChannels();
-
- int tchans = (channels != -1) ? channels: t->channels();
- if(tchans == 2)
- {
- // Ignore odd numbered left-over mono channel.
- //chans = chans & ~1;
- //if(chans != 0)
- chans -= 1;
- }
-
- if(chans > 0)
- {
- PopupMenu* chpup = new PopupMenu(lb, true);
- chpup->setTitle(track->name());
- for(int ch = 0; ch < chans; ++ch)
- {
- char buffer[128];
- if(tchans == 2)
- snprintf(buffer, 128, "%s %d,%d", chpup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
- else
- snprintf(buffer, 128, "%s %d", chpup->tr("Channel").toLatin1().constData(), ch+1);
- act = chpup->addAction(QString(buffer));
- act->setData(id);
- act->setCheckable(true);
-
- int ach = (channel == -1) ? ch : channel;
- int bch = (channel == -1) ? -1 : ch;
-
- Route rt(track, (t->type() != Track::AUDIO_SOFTSYNTH || isOutput) ? ach : bch, tchans);
- //Route rt(track, ch);
- //rt.remoteChannel = -1;
- rt.remoteChannel = (t->type() != Track::AUDIO_SOFTSYNTH || isOutput) ? bch : ach;
-
- mm.insert( pRouteMenuMap(id, rt) );
-
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == track && ir->remoteChannel == rt.remoteChannel)
- {
- int tcompch = rt.channel;
- if(tcompch == -1)
- tcompch = 0;
- int tcompchs = rt.channels;
- if(tcompchs == -1)
- tcompchs = isOutput ? t->channels() : track->channels();
-
- int compch = ir->channel;
- if(compch == -1)
- compch = 0;
- int compchs = ir->channels;
- if(compchs == -1)
- compchs = isOutput ? t->channels() : ir->track->channels();
-
- if(compch == tcompch && compchs == tcompchs)
- {
- act->setChecked(true);
- break;
- }
- }
- }
- ++id;
- }
-
- lb->addMenu(chpup);
- }
- }
- return id;
-}
-
-//---------------------------------------------------------
-// addMultiChannelOutPorts
-//---------------------------------------------------------
-
-static int addMultiChannelPorts(AudioTrack* t, PopupMenu* pup, int id, RouteMenuMap& mm, bool isOutput)
-{
- int toch = t->totalOutChannels();
- // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
- if(t->channels() == 1)
- toch = 1;
-
- // Number of allocated buffers is always MAX_CHANNELS or more, even if _totalOutChannels is less.
- // totalInChannels is only used by syntis.
- int chans = (isOutput || t->type() != Track::AUDIO_SOFTSYNTH) ? toch : t->totalInChannels();
-
- if(chans > 1)
- pup->addAction(new MenuTitleItem("<Mono>", pup));
-
- //
- // If it's more than one channel, create a sub-menu. If it's just one channel, don't bother with a sub-menu...
- //
-
- PopupMenu* chpup = pup;
-
- for(int ch = 0; ch < chans; ++ch)
- {
- // If more than one channel, create the sub-menu.
- if(chans > 1)
- chpup = new PopupMenu(pup, true);
-
- if(isOutput)
- {
- switch(t->type())
- {
-
- case Track::AUDIO_INPUT:
- //id = addWavePorts(t, chpup, id, mm, ch, 1, isOutput); // Rem p4.0.20
- case Track::WAVE:
- case Track::AUDIO_GROUP:
- case Track::AUDIO_SOFTSYNTH:
- case Track::AUDIO_AUX: // p4.0.20
- id = addWavePorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addOutPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addGroupPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addSyntiPorts(t, chpup, id, mm, ch, 1, isOutput);
- //break; // Rem p4.0.20
- //case Track::AUDIO_AUX: //
- //id = addOutPorts(t, chpup, id, mm, ch, 1, isOutput); //
- break;
- default:
- break;
- }
- }
- else
- {
- switch(t->type())
- {
-
- case Track::AUDIO_OUTPUT:
- id = addWavePorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addInPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addGroupPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addAuxPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addSyntiPorts(t, chpup, id, mm, ch, 1, isOutput);
- break;
- case Track::WAVE:
- //id = addInPorts(t, chpup, id, mm, ch, 1, isOutput); // Rem p4.0.20
- //break;
- case Track::AUDIO_SOFTSYNTH:
- case Track::AUDIO_GROUP:
- id = addWavePorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addInPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addGroupPorts(t, chpup, id, mm, ch, 1, isOutput);
- id = addAuxPorts(t, chpup, id, mm, ch, 1, isOutput); // p4.0.20
- id = addSyntiPorts(t, chpup, id, mm, ch, 1, isOutput);
- break;
- default:
- break;
- }
- }
-
- // If more than one channel, add the created sub-menu.
- if(chans > 1)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d", pup->tr("Channel").toLatin1().constData(), ch+1);
- chpup->setTitle(QString(buffer));
- pup->addMenu(chpup);
- }
- }
-
- // For stereo listing, ignore odd numbered left-over channels.
- chans -= 1;
- if(chans > 0)
- {
- // Ignore odd numbered left-over channels.
- //int schans = (chans & ~1) - 1;
-
- pup->addSeparator();
- pup->addAction(new MenuTitleItem("<Stereo>", pup));
-
- //
- // If it's more than two channels, create a sub-menu. If it's just two channels, don't bother with a sub-menu...
- //
-
- chpup = pup;
- if(chans <= 2)
- // Just do one iteration.
- chans = 1;
-
- for(int ch = 0; ch < chans; ++ch)
- {
- // If more than two channels, create the sub-menu.
- if(chans > 2)
- chpup = new PopupMenu(pup, true);
-
- if(isOutput)
- {
- switch(t->type())
- {
- case Track::AUDIO_INPUT:
- //id = addWavePorts(t, chpup, id, mm, ch, 2, isOutput); // Rem p4.0.20
- case Track::WAVE:
- case Track::AUDIO_GROUP:
- case Track::AUDIO_SOFTSYNTH:
- case Track::AUDIO_AUX: // p4.0.20
- id = addWavePorts(t, chpup, id, mm, ch, 2, isOutput); // p4.0.20
- id = addOutPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addGroupPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addSyntiPorts(t, chpup, id, mm, ch, 2, isOutput);
- break;
- //case Track::AUDIO_AUX: // Rem p4.0.20
- // id = addOutPorts(t, chpup, id, mm, ch, 2, isOutput);
- // break;
- default:
- break;
- }
- }
- else
- {
- switch(t->type())
- {
- case Track::AUDIO_OUTPUT:
- id = addWavePorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addInPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addGroupPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addAuxPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addSyntiPorts(t, chpup, id, mm, ch, 2, isOutput);
- break;
- case Track::WAVE:
- //id = addInPorts(t, chpup, id, mm, ch, 2, isOutput); // Rem p4.0.20
- //break;
- case Track::AUDIO_SOFTSYNTH:
- case Track::AUDIO_GROUP:
- id = addWavePorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addInPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addGroupPorts(t, chpup, id, mm, ch, 2, isOutput);
- id = addAuxPorts(t, chpup, id, mm, ch, 2, isOutput); // p4.0.20
- id = addSyntiPorts(t, chpup, id, mm, ch, 2, isOutput);
- break;
- default:
- break;
- }
- }
-
- // If more than two channels, add the created sub-menu.
- if(chans > 2)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d,%d", pup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
- chpup->setTitle(QString(buffer));
- pup->addMenu(chpup);
- }
- }
- }
-
- return id;
-}
-
-//---------------------------------------------------------
-// nonSyntiTrackAddSyntis
-//---------------------------------------------------------
-
-static int nonSyntiTrackAddSyntis(AudioTrack* t, PopupMenu* lb, int id, RouteMenuMap& mm, bool isOutput)
-{
- RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
-
- QAction* act;
- SynthIList* al = song->syntis();
- for (iSynthI i = al->begin(); i != al->end(); ++i)
- {
- Track* track = *i;
- if (t == track)
- continue;
-
- int toch = ((AudioTrack*)track)->totalOutChannels();
- // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
- if(track->channels() == 1)
- toch = 1;
-
- // totalInChannels is only used by syntis.
- int chans = (!isOutput || track->type() != Track::AUDIO_SOFTSYNTH) ? toch : ((AudioTrack*)track)->totalInChannels();
-
- //int schans = synti->channels();
- //if(schans < chans)
- // chans = schans;
-// int tchans = (channels != -1) ? channels: t->channels();
-// if(tchans == 2)
-// {
- // Ignore odd numbered left-over mono channel.
- //chans = chans & ~1;
- //if(chans != 0)
-// chans -= 1;
-// }
- //int tchans = (channels != -1) ? channels: t->channels();
-
- if(chans > 0)
- {
- PopupMenu* chpup = new PopupMenu(lb, true);
- chpup->setTitle(track->name());
- if(chans > 1)
- chpup->addAction(new MenuTitleItem("<Mono>", chpup));
-
- for(int ch = 0; ch < chans; ++ch)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d", chpup->tr("Channel").toLatin1().constData(), ch+1);
- act = chpup->addAction(QString(buffer));
- act->setData(id);
- act->setCheckable(true);
-
- int ach = ch;
- int bch = -1;
-
- Route rt(track, isOutput ? bch : ach, 1);
-
- rt.remoteChannel = isOutput ? ach : bch;
-
- mm.insert( pRouteMenuMap(id, rt) );
-
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == track && ir->remoteChannel == rt.remoteChannel)
- {
- int tcompch = rt.channel;
- if(tcompch == -1)
- tcompch = 0;
- int tcompchs = rt.channels;
- if(tcompchs == -1)
- tcompchs = isOutput ? t->channels() : track->channels();
-
- int compch = ir->channel;
- if(compch == -1)
- compch = 0;
- int compchs = ir->channels;
- if(compchs == -1)
- compchs = isOutput ? t->channels() : ir->track->channels();
-
- if(compch == tcompch && compchs == tcompchs)
- {
- act->setChecked(true);
- break;
- }
- }
- }
- ++id;
- }
-
- chans -= 1;
- if(chans > 0)
- {
- // Ignore odd numbered left-over channels.
- //int schans = (chans & ~1) - 1;
-
- chpup->addSeparator();
- chpup->addAction(new MenuTitleItem("<Stereo>", chpup));
-
- for(int ch = 0; ch < chans; ++ch)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d,%d", chpup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
- act = chpup->addAction(QString(buffer));
- act->setData(id);
- act->setCheckable(true);
-
- int ach = ch;
- int bch = -1;
-
- Route rt(track, isOutput ? bch : ach, 2);
-
- rt.remoteChannel = isOutput ? ach : bch;
-
- mm.insert( pRouteMenuMap(id, rt) );
-
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- if(ir->type == Route::TRACK_ROUTE && ir->track == track && ir->remoteChannel == rt.remoteChannel)
- {
- int tcompch = rt.channel;
- if(tcompch == -1)
- tcompch = 0;
- int tcompchs = rt.channels;
- if(tcompchs == -1)
- tcompchs = isOutput ? t->channels() : track->channels();
-
- int compch = ir->channel;
- if(compch == -1)
- compch = 0;
- int compchs = ir->channels;
- if(compchs == -1)
- compchs = isOutput ? t->channels() : ir->track->channels();
-
- if(compch == tcompch && compchs == tcompchs)
- {
- act->setChecked(true);
- break;
- }
- }
- }
- ++id;
- }
- }
-
- lb->addMenu(chpup);
- }
- }
- return id;
-}
-
-//---------------------------------------------------------
-// addMidiPorts
-//---------------------------------------------------------
-
-static int addMidiPorts(AudioTrack* t, PopupMenu* pup, int id, RouteMenuMap& mm, bool isOutput)
-{
- QAction* act;
- for(int i = 0; i < MIDI_PORTS; ++i)
- {
- MidiPort* mp = &midiPorts[i];
- MidiDevice* md = mp->device();
-
- // This is desirable, but could lead to 'hidden' routes unless we add more support
- // such as removing the existing routes when user changes flags.
- // So for now, just list all valid ports whether read or write.
- if(!md)
- continue;
- //if(!(md->rwFlags() & (isOutput ? 1 : 2)))
- // continue;
-
- // p4.0.17 Do not list synth devices!
- if(md->isSynti())
- continue;
-
- RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
-
- PopupMenu* subp = new PopupMenu(pup, true);
- subp->setTitle(md->name());
-
- int chanmask = 0;
- // To reduce number of routes required, from one per channel to just one containing a channel mask.
- // Look for the first route to this midi port. There should always be only a single route for each midi port, now.
- for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
- {
- if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
- {
- // We have a route to the midi port. Grab the channel mask.
- chanmask = ir->channel;
- break;
- }
- }
-
- for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
- {
- act = subp->addAction(QString("Channel %1").arg(ch+1));
- act->setCheckable(true);
- act->setData(id);
-
- int chbit = 1 << ch;
- Route srcRoute(i, chbit); // In accordance with new channel mask, use the bit position.
-
- mm.insert( pRouteMenuMap(id, srcRoute) );
-
- if(chanmask & chbit) // Is the channel already set? Show item check mark.
- act->setChecked(true);
-
- ++id;
- }
-
- //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
- act = subp->addAction(QString("Toggle all"));
- //act->setCheckable(true);
- act->setData(id);
- Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
- mm.insert( pRouteMenuMap(id, togRoute) );
- ++id;
-
- pup->addMenu(subp);
- }
- return id;
-}
-
-//---------------------------------------------------------
-// routingPopupMenuActivated
-//---------------------------------------------------------
-
-void AudioStrip::routingPopupMenuActivated(QAction* act)
-{
- if(!track || gRoutingPopupMenuMaster != this || track->isMidiTrack())
- return;
-
- PopupMenu* pup = muse->getRoutingPopupMenu();
-
- if(pup->actions().isEmpty())
- return;
-
- AudioTrack* t = (AudioTrack*)track;
- RouteList* rl = gIsOutRoutingPopupMenu ? t->outRoutes() : t->inRoutes();
-
- int n = act->data().toInt();
- if (n == -1)
- return;
-
- iRouteMenuMap imm = gRoutingMenuMap.find(n);
- if(imm == gRoutingMenuMap.end())
- return;
-
- if(gIsOutRoutingPopupMenu)
- {
- Route srcRoute(t, imm->second.channel, imm->second.channels);
- srcRoute.remoteChannel = imm->second.remoteChannel;
-
- Route &dstRoute = imm->second;
-
- // check if route src->dst exists:
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == dstRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect if route exists
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect if route does not exist
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- }
- else
- {
- Route &srcRoute = imm->second;
-
- // Support Midi Port to Audio Input routes. p4.0.14 Tim.
- if(track->type() == Track::AUDIO_INPUT && srcRoute.type == Route::MIDI_PORT_ROUTE)
- {
- int chbit = srcRoute.channel;
- Route dstRoute(t, chbit);
- int mdidx = srcRoute.midiPort;
- int chmask = 0;
- iRoute iir = rl->begin();
- for (; iir != rl->end(); ++iir)
- {
- if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx) // Is there already a route to this port?
- {
- chmask = iir->channel; // Grab the channel mask.
- break;
- }
- }
-
- if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
- {
- //printf("astrip: removing src route ch:%d dst route ch:%d\n", srcRoute.channel, dstRoute.channel);
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else
- {
- //printf("astrip: adding src route ch:%d dst route ch:%d\n", srcRoute.channel, dstRoute.channel);
- audio->msgAddRoute(srcRoute, dstRoute);
- }
-
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- return;
- }
-
- Route dstRoute(t, imm->second.channel, imm->second.channels);
- dstRoute.remoteChannel = imm->second.remoteChannel;
-
- iRoute irl = rl->begin();
- for (; irl != rl->end(); ++irl) {
- if (*irl == srcRoute)
- break;
- }
- if (irl != rl->end()) {
- // disconnect
- audio->msgRemoveRoute(srcRoute, dstRoute);
- }
- else {
- // connect
- audio->msgAddRoute(srcRoute, dstRoute);
- }
- audio->msgUpdateSoloStates();
- song->update(SC_ROUTE);
- }
-}
-
-//---------------------------------------------------------
// iRoutePressed
//---------------------------------------------------------
void AudioStrip::iRoutePressed()
{
- //if(track->isMidiTrack() || (track->type() == Track::AUDIO_AUX) || (track->type() == Track::AUDIO_SOFTSYNTH))
- if(!track || track->isMidiTrack() || track->type() == Track::AUDIO_AUX)
- {
- gRoutingPopupMenuMaster = 0;
- return;
- }
-
- QPoint ppt = QCursor::pos();
-
- PopupMenu* pup = muse->getRoutingPopupMenu();
- pup->disconnect();
-
- AudioTrack* t = (AudioTrack*)track;
- RouteList* irl = t->inRoutes();
-
- QAction* act = 0;
- int gid = 0;
- //int id = 0;
-
- pup->clear();
- gRoutingMenuMap.clear();
- gid = 0;
-
- switch(track->type())
- {
- case Track::AUDIO_INPUT:
- {
- for(int i = 0; i < channel; ++i)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), i+1);
- MenuTitleItem* titel = new MenuTitleItem(QString(buffer), pup);
- pup->addAction(titel);
-
- if(!checkAudioDevice())
- {
- gRoutingPopupMenuMaster = 0;
- pup->clear();
- gRoutingMenuMap.clear();
- iR->setDown(false);
- return;
- }
- std::list<QString> ol = audioDevice->outputPorts();
- for(std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip)
- {
- //id = gid * 16 + i; // IDs removed p4.0.14 Tim.
- act = pup->addAction(*ip);
- //act->setData(id);
- act->setData(gid);
- act->setCheckable(true);
-
- Route dst(*ip, true, i, Route::JACK_ROUTE);
- //gRoutingMenuMap.insert( pRouteMenuMap(id, dst) );
- gRoutingMenuMap.insert( pRouteMenuMap(gid, dst) );
- ++gid;
- for(iRoute ir = irl->begin(); ir != irl->end(); ++ir)
- {
- if(*ir == dst)
- {
- act->setChecked(true);
- break;
- }
- }
- }
- if(i+1 != channel)
- pup->addSeparator();
- }
-
- // p4.0.14
- //
- // Display using separate menus for midi ports and audio outputs:
- //
- pup->addSeparator();
- pup->addAction(new MenuTitleItem(tr("Soloing chain"), pup));
- PopupMenu* subp = new PopupMenu(pup, true);
- subp->setTitle(tr("Audio sends"));
- pup->addMenu(subp);
- gid = addOutPorts(t, subp, gid, gRoutingMenuMap, -1, -1, false);
- subp = new PopupMenu(pup, true);
- subp->setTitle(tr("Midi port sends"));
- pup->addMenu(subp);
- addMidiPorts(t, subp, gid, gRoutingMenuMap, false);
- //
- // Display all in the same menu:
- //
- //pup->addAction(new MenuTitleItem(tr("Audio sends"), pup));
- //gid = addOutPorts(t, pup, gid, gRoutingMenuMap, -1, -1, false);
- //pup->addSeparator();
- //pup->addAction(new MenuTitleItem(tr("Midi sends"), pup));
- //addMidiPorts(t, pup, gid, gRoutingMenuMap, false);
- }
- break;
- //case Track::AUDIO_OUTPUT:
- //case Track::WAVE:
- //case Track::AUDIO_GROUP:
-
- case Track::AUDIO_OUTPUT:
- gid = addWavePorts( t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addInPorts( t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addGroupPorts(t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addAuxPorts( t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = nonSyntiTrackAddSyntis(t, pup, gid, gRoutingMenuMap, false);
- break;
- case Track::WAVE:
- gid = addWavePorts( t, pup, gid, gRoutingMenuMap, -1, -1, false); // p4.0.20
- gid = addInPorts( t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addGroupPorts(t, pup, gid, gRoutingMenuMap, -1, -1, false); //
- gid = addAuxPorts( t, pup, gid, gRoutingMenuMap, -1, -1, false); //
- gid = nonSyntiTrackAddSyntis(t, pup, gid, gRoutingMenuMap, false); //
- break;
- case Track::AUDIO_GROUP:
- gid = addWavePorts( t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addInPorts( t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addGroupPorts(t, pup, gid, gRoutingMenuMap, -1, -1, false);
- gid = addAuxPorts( t, pup, gid, gRoutingMenuMap, -1, -1, false); // p4.0.20
- gid = nonSyntiTrackAddSyntis(t, pup, gid, gRoutingMenuMap, false);
- break;
-
- case Track::AUDIO_SOFTSYNTH:
- gid = addMultiChannelPorts(t, pup, gid, gRoutingMenuMap, false);
- break;
- default:
- gRoutingPopupMenuMaster = 0;
- pup->clear();
- gRoutingMenuMap.clear();
- iR->setDown(false);
- return;
- }
-
- if(pup->actions().isEmpty())
- {
- gRoutingPopupMenuMaster = 0;
- gRoutingMenuMap.clear();
- iR->setDown(false);
- return;
- }
-
- gIsOutRoutingPopupMenu = false;
- gRoutingPopupMenuMaster = this;
- connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
- connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
- pup->popup(ppt);
+ RoutePopupMenu* pup = muse->getRoutingPopupMenu();
iR->setDown(false);
+ pup->exec(QCursor::pos(), track, false);
}
//---------------------------------------------------------
@@ -1907,136 +989,8 @@ void AudioStrip::iRoutePressed()
void AudioStrip::oRoutePressed()
{
- if(!track || track->isMidiTrack())
- {
- gRoutingPopupMenuMaster = 0;
- return;
- }
-
- QPoint ppt = QCursor::pos();
-
- PopupMenu* pup = muse->getRoutingPopupMenu();
- pup->disconnect();
-
- AudioTrack* t = (AudioTrack*)track;
- RouteList* orl = t->outRoutes();
-
- QAction* act = 0;
- int gid = 0;
- //int id = 0;
-
- pup->clear();
- gRoutingMenuMap.clear();
- gid = 0;
-
- switch(track->type())
- {
- case Track::AUDIO_OUTPUT:
- {
- for(int i = 0; i < channel; ++i)
- {
- char buffer[128];
- snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), i+1);
- MenuTitleItem* titel = new MenuTitleItem(QString(buffer), pup);
- pup->addAction(titel);
-
- if(!checkAudioDevice())
- {
- gRoutingPopupMenuMaster = 0;
- pup->clear();
- gRoutingMenuMap.clear();
- oR->setDown(false);
- return;
- }
- std::list<QString> ol = audioDevice->inputPorts();
- for(std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip)
- {
- //id = gid * 16 + i; // IDs removed p4.0.14 Tim.
- act = pup->addAction(*ip);
- //act->setData(id);
- act->setData(gid);
- act->setCheckable(true);
-
- Route dst(*ip, true, i, Route::JACK_ROUTE);
- //gRoutingMenuMap.insert( pRouteMenuMap(id, dst) );
- gRoutingMenuMap.insert( pRouteMenuMap(gid, dst) );
- ++gid;
- for(iRoute ir = orl->begin(); ir != orl->end(); ++ir)
- {
- if(*ir == dst)
- {
- act->setChecked(true);
- break;
- }
- }
- }
- if(i+1 != channel)
- pup->addSeparator();
- }
-
- // p4.0.14
- //
- // Display using separate menu for audio inputs:
- //
- pup->addSeparator();
- pup->addAction(new MenuTitleItem(tr("Soloing chain"), pup));
- PopupMenu* subp = new PopupMenu(pup, true);
- subp->setTitle(tr("Audio returns"));
- pup->addMenu(subp);
- gid = addInPorts(t, subp, gid, gRoutingMenuMap, -1, -1, true);
- //
- // Display all in the same menu:
- //
- //pup->addSeparator();
- //MenuTitleItem* title = new MenuTitleItem(tr("Audio returns"), pup);
- //pup->addAction(title);
- //gid = addInPorts(t, pup, gid, gRoutingMenuMap, -1, -1, true);
- }
- break;
- //case Track::AUDIO_INPUT:
- //case Track::WAVE:
- //case Track::AUDIO_GROUP:
-
- case Track::AUDIO_SOFTSYNTH:
- gid = addMultiChannelPorts(t, pup, gid, gRoutingMenuMap, true);
- break;
-
- case Track::AUDIO_INPUT:
- //gid = addWavePorts( t, pup, gid, gRoutingMenuMap, -1, -1, true); // Rem p4.0.20
- case Track::WAVE:
- case Track::AUDIO_GROUP:
- case Track::AUDIO_AUX:
- //case Track::AUDIO_SOFTSYNTH:
- gid = addWavePorts( t, pup, gid, gRoutingMenuMap, -1, -1, true); // p4.0.20
- gid = addOutPorts( t, pup, gid, gRoutingMenuMap, -1, -1, true);
- gid = addGroupPorts( t, pup, gid, gRoutingMenuMap, -1, -1, true);
- gid = nonSyntiTrackAddSyntis(t, pup, gid, gRoutingMenuMap, true);
- break;
- //case Track::AUDIO_AUX:
- // gid = addOutPorts( t, pup, gid, gRoutingMenuMap, -1, -1, true);
- //break;
-
- default:
- gRoutingPopupMenuMaster = 0;
- pup->clear();
- gRoutingMenuMap.clear();
- oR->setDown(false);
- return;
- }
-
- if(pup->actions().isEmpty())
- {
- gRoutingPopupMenuMaster = 0;
- gRoutingMenuMap.clear();
- oR->setDown(false);
- return;
- }
-
- gIsOutRoutingPopupMenu = true;
- gRoutingPopupMenuMaster = this;
- connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
- connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
- pup->popup(ppt);
+ RoutePopupMenu* pup = muse->getRoutingPopupMenu();
oR->setDown(false);
+ pup->exec(QCursor::pos(), track, true);
}
diff --git a/muse2/muse/mixer/astrip.h b/muse2/muse/mixer/astrip.h
index 10d75305..92867033 100644
--- a/muse2/muse/mixer/astrip.h
+++ b/muse2/muse/mixer/astrip.h
@@ -12,7 +12,7 @@
#include <vector>
#include "strip.h"
-#include "route.h"
+//#include "route.h"
class Slider;
class Knob;
@@ -20,7 +20,7 @@ class Knob;
class QToolButton;
//class QAction;
//class QPopupMenu;
-class PopupMenu;
+//class PopupMenu;
class QButton;
class TransparentToolButton;
class AudioTrack;
@@ -61,7 +61,6 @@ class AudioStrip : public Strip {
void updateVolume();
void updatePan();
void updateChannels();
- //void updateRouteMenus();
private slots:
void stereoToggled(bool);
@@ -69,7 +68,6 @@ class AudioStrip : public Strip {
void offToggled(bool);
void iRoutePressed();
void oRoutePressed();
- void routingPopupMenuActivated(QAction*);
void auxChanged(double, int);
void volumeChanged(double);
void volumePressed();
diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp
index 427f9ed6..d773708a 100644
--- a/muse2/muse/mixer/mstrip.cpp
+++ b/muse2/muse/mixer/mstrip.cpp
@@ -43,7 +43,8 @@
#include "gconfig.h"
#include "ttoolbutton.h"
//#include "utils.h"
-#include "popupmenu.h"
+//#include "popupmenu.h"
+#include "routepopup.h"
enum { KNOB_PAN, KNOB_VAR_SEND, KNOB_REV_SEND, KNOB_CHO_SEND };
@@ -503,26 +504,17 @@ void MidiStrip::songChanged(int val)
if (val & SC_TRACK_MODIFIED)
{
setLabelText();
- // Added by Tim. p3.3.9
setLabelFont();
}
- // Added by Tim. p3.3.9
- // Catch when label font changes.
+ // Catch when label font changes. Tim. p3.3.9
if (val & SC_CONFIG)
{
// Set the strip label's font.
//label->setFont(config.fonts[1]);
setLabelFont();
}
-
- // p3.3.47 Update the routing popup menu if anything relevant changes.
- //if(gRoutingPopupMenuMaster == this && track && (val & (SC_ROUTE | SC_CHANNELS | SC_CONFIG)))
- if(val & (SC_ROUTE | SC_CHANNELS | SC_CONFIG)) // p3.3.50
- // Use this handy shared routine.
- //muse->updateRouteMenus(track);
- muse->updateRouteMenus(track, this); // p3.3.50
}
//---------------------------------------------------------
@@ -1007,35 +999,14 @@ void MidiStrip::setReverbSend(double val)
}
//---------------------------------------------------------
-// routingPopupMenuActivated
-//---------------------------------------------------------
-
-void MidiStrip::routingPopupMenuActivated(QAction* act)
-{
- if(gRoutingPopupMenuMaster != this || !track || !track->isMidiTrack())
- return;
-
- muse->routingPopupMenuActivated(track, act->data().toInt());
-}
-
-//---------------------------------------------------------
// iRoutePressed
//---------------------------------------------------------
void MidiStrip::iRoutePressed()
{
- if(!track || !track->isMidiTrack())
- return;
-
- PopupMenu* pup = muse->prepareRoutingPopupMenu(track, false);
- if(!pup)
- return;
-
- gRoutingPopupMenuMaster = this;
- connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
- connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
- pup->popup(QCursor::pos());
+ RoutePopupMenu* pup = muse->getRoutingPopupMenu();
iR->setDown(false);
+ pup->exec(QCursor::pos(), track, false);
}
//---------------------------------------------------------
@@ -1044,18 +1015,9 @@ void MidiStrip::iRoutePressed()
void MidiStrip::oRoutePressed()
{
- if(!track || !track->isMidiTrack())
- return;
-
- PopupMenu* pup = muse->prepareRoutingPopupMenu(track, true);
- if(!pup)
- return;
-
- gRoutingPopupMenuMaster = this;
- connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
- connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
- pup->popup(QCursor::pos());
+ RoutePopupMenu* pup = muse->getRoutingPopupMenu();
oR->setDown(false);
+ pup->exec(QCursor::pos(), track, true);
}
diff --git a/muse2/muse/mixer/mstrip.h b/muse2/muse/mixer/mstrip.h
index 920cca99..39b55d21 100644
--- a/muse2/muse/mixer/mstrip.h
+++ b/muse2/muse/mixer/mstrip.h
@@ -32,9 +32,6 @@ class MidiStrip : public Strip {
Slider* slider;
DoubleLabel* sl;
TransparentToolButton* off;
- //QToolButton* route;
- //QToolButton* iR;
- //QToolButton* oR;
struct KNOB {
Knob* knob;
@@ -55,11 +52,9 @@ class MidiStrip : public Strip {
void updateOffState();
private slots:
- //void routeClicked();
void offToggled(bool);
void iRoutePressed();
void oRoutePressed();
- void routingPopupMenuActivated(QAction*);
void setVolume(double);
void setPan(double);
void setChorusSend(double);
diff --git a/muse2/muse/node.cpp b/muse2/muse/node.cpp
index 114b03d3..06dbbc8d 100644
--- a/muse2/muse/node.cpp
+++ b/muse2/muse/node.cpp
@@ -1264,7 +1264,7 @@ bool AudioTrack::getData(unsigned pos, int channels, unsigned nframes, float** b
printf("AudioTrack::getData name:%s inRoutes:%d\n", name().toLatin1().constData(), rl->size());
#endif
- iRoute ir = rl->begin();
+ ciRoute ir = rl->begin();
if (ir == rl->end())
return false;
diff --git a/muse2/muse/route.cpp b/muse2/muse/route.cpp
index 6f42c1f2..9425f056 100644
--- a/muse2/muse/route.cpp
+++ b/muse2/muse/route.cpp
@@ -187,7 +187,7 @@ void addRoute(Route src, Route dst)
src.channel = dst.channel;
//src.channels = dst.channels = 1;
RouteList* inRoutes = dst.track->inRoutes();
- for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
+ for (ciRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
{
if (*i == src) // route already there
{
@@ -226,7 +226,7 @@ void addRoute(Route src, Route dst)
//dst.channel = -1;
RouteList* routes = dst.device->inRoutes();
- for (iRoute i = routes->begin(); i != routes->end(); ++i)
+ for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
if (*i == src) // route already there
{
@@ -284,7 +284,7 @@ void addRoute(Route src, Route dst)
dst.channel = src.channel;
//dst.channels = src.channels = 1;
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
+ for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
if (*i == dst) // route already there
{
@@ -312,7 +312,7 @@ void addRoute(Route src, Route dst)
//dst.channels = src.channels = 1;
RouteList* routes = src.device->outRoutes();
- for (iRoute i = routes->begin(); i != routes->end(); ++i)
+ for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
if (*i == dst) // route already there
{
@@ -616,7 +616,7 @@ void addRoute(Route src, Route dst)
// dst.channels = src.track->channels();
//}
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
+ for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
if (*i == dst) // route already there
// TODO:
@@ -1248,7 +1248,7 @@ bool checkRoute(const QString& s, const QString& d)
}
src.channel = dst.channel;
RouteList* inRoutes = dst.track->inRoutes();
- for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
+ for (ciRoute i = inRoutes->begin(); i != inRoutes->end(); ++i)
{
if (*i == src) { // route already there
return false;
@@ -1263,7 +1263,7 @@ bool checkRoute(const QString& s, const QString& d)
src.channel = -1;
//dst.channel = -1;
RouteList* routes = dst.device->inRoutes();
- for (iRoute i = routes->begin(); i != routes->end(); ++i)
+ for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
if (*i == src) { // route already there
return false;
@@ -1286,7 +1286,7 @@ bool checkRoute(const QString& s, const QString& d)
}
RouteList* outRoutes = src.track->outRoutes();
dst.channel = src.channel;
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
+ for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
if (*i == dst) { // route already there
return false;
@@ -1301,7 +1301,7 @@ bool checkRoute(const QString& s, const QString& d)
//dst.channel = src.channel;
dst.channel = -1;
//src.channel = -1;
- for (iRoute i = routes->begin(); i != routes->end(); ++i)
+ for (ciRoute i = routes->begin(); i != routes->end(); ++i)
{
if (*i == dst) { // route already there
return false;
@@ -1314,7 +1314,7 @@ bool checkRoute(const QString& s, const QString& d)
else if (src.type == Route::MIDI_PORT_ROUTE) // p3.3.49
{
RouteList* outRoutes = midiPorts[src.midiPort].outRoutes();
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
+ for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
if (*i == dst) { // route already there
return false;
@@ -1330,7 +1330,7 @@ bool checkRoute(const QString& s, const QString& d)
// src.device->outRoutes() : src.track->outRoutes();
RouteList* outRoutes = (src.type == Route::MIDI_DEVICE_ROUTE) ? src.device->outRoutes() : src.track->outRoutes();
- for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
+ for (ciRoute i = outRoutes->begin(); i != outRoutes->end(); ++i)
{
if (*i == dst) { // route already there
return false;
diff --git a/muse2/muse/route.h b/muse2/muse/route.h
index 2f29bcf8..9809352c 100644
--- a/muse2/muse/route.h
+++ b/muse2/muse/route.h
@@ -9,9 +9,10 @@
#ifndef __ROUTE_H__
#define __ROUTE_H__
+#include <QMetaType>
+
#include <vector>
#include <map>
-
#include "globaldefs.h"
class QString;
@@ -71,6 +72,8 @@ struct Route {
void dump() const;
};
+// Allow Routes to be a QVariant
+Q_DECLARE_METATYPE(Route) ;
//---------------------------------------------------------
// RouteList
@@ -93,11 +96,11 @@ extern bool checkRoute(const QString&, const QString&);
// RouteMenuMap
//---------------------------------------------------------
-typedef std::map<int, Route, std::less<int> >::iterator iRouteMenuMap;
-typedef std::map<int, Route, std::less<int> >::const_iterator ciRouteMenuMap;
-typedef std::map<int, Route, std::less<int> > RouteMenuMap;
-typedef std::pair<int, Route> pRouteMenuMap;
-typedef std::pair<iRouteMenuMap, bool > rpRouteMenuMap;
+//typedef std::map<int, Route, std::less<int> >::iterator iRouteMenuMap;
+//typedef std::map<int, Route, std::less<int> >::const_iterator ciRouteMenuMap;
+//typedef std::map<int, Route, std::less<int> > RouteMenuMap;
+//typedef std::pair<int, Route> pRouteMenuMap;
+//typedef std::pair<iRouteMenuMap, bool > rpRouteMenuMap;
#endif
diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp
index 950015b2..b4d65148 100644
--- a/muse2/muse/seqmsg.cpp
+++ b/muse2/muse/seqmsg.cpp
@@ -396,7 +396,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n)
else if ((i >= n) && ai->jackPort(i))
{
RouteList* ir = node->inRoutes();
- for (iRoute ii = ir->begin(); ii != ir->end(); ++ii)
+ for (ciRoute ii = ir->begin(); ii != ir->end(); ++ii)
{
Route r = *ii;
if ((r.type == Route::JACK_ROUTE) && (r.channel == i))
@@ -427,7 +427,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n)
else if (i >= n && jp)
{
RouteList* ir = node->outRoutes();
- for (iRoute ii = ir->begin(); ii != ir->end(); ++ii)
+ for (ciRoute ii = ir->begin(); ii != ir->end(); ++ii)
{
Route r = *ii;
if ((r.type == Route::JACK_ROUTE) && (r.channel == i))
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index 28ea1210..6750203a 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -2926,7 +2926,7 @@ void Song::connectJackRoutes(AudioTrack* track, bool disconnect)
for(int ch = 0; ch < ao->channels(); ++ch)
{
RouteList* ir = ao->outRoutes();
- for (iRoute ii = ir->begin(); ii != ir->end(); ++ii)
+ for (ciRoute ii = ir->begin(); ii != ir->end(); ++ii)
{
Route r = *ii;
if ((r.type == Route::JACK_ROUTE) && (r.channel == ch))
@@ -2959,7 +2959,7 @@ void Song::connectJackRoutes(AudioTrack* track, bool disconnect)
for(int ch = 0; ch < ai->channels(); ++ch)
{
RouteList* ir = ai->inRoutes();
- for (iRoute ii = ir->begin(); ii != ir->end(); ++ii)
+ for (ciRoute ii = ir->begin(); ii != ir->end(); ++ii)
{
Route r = *ii;
if ((r.type == Route::JACK_ROUTE) && (r.channel == ch))
diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp
index fdebc8b8..ad02084c 100644
--- a/muse2/muse/wavetrack.cpp
+++ b/muse2/muse/wavetrack.cpp
@@ -209,7 +209,7 @@ bool WaveTrack::getData(unsigned framePos, int channels, unsigned nframe, float*
if ((song->bounceTrack != this) && !noInRoute()) {
RouteList* irl = inRoutes();
- iRoute i = irl->begin();
+ ciRoute i = irl->begin();
if(i->track->isMidiTrack())
{
if(debugMsg)
diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt
index 7589ddf0..a4da398f 100644
--- a/muse2/muse/widgets/CMakeLists.txt
+++ b/muse2/muse/widgets/CMakeLists.txt
@@ -47,6 +47,7 @@ QT4_WRAP_CPP (widget_mocs
intlabel.h
knob.h
lcombo.h
+ menutitleitem.h
meter.h
metronome.h
midisyncimpl.h
@@ -63,6 +64,7 @@ QT4_WRAP_CPP (widget_mocs
# posedit.h
poslabel.h
projectcreateimpl.h
+ routepopup.h
scrollscale.h
shortcutcapturedialog.h
shortcutconfig.h
@@ -142,6 +144,7 @@ file (GLOB widgets_source_files
intlabel.cpp
knob.cpp
lcombo.cpp
+ menutitleitem.cpp
meter.cpp
metronome.cpp
midisyncimpl.cpp
@@ -159,6 +162,7 @@ file (GLOB widgets_source_files
# posedit.cpp
poslabel.cpp
projectcreateimpl.cpp
+ routepopup.cpp
scldiv.cpp
scldraw.cpp
sclif.cpp
diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp
index edf3cfda..d8c76874 100644
--- a/muse2/muse/widgets/genset.cpp
+++ b/muse2/muse/widgets/genset.cpp
@@ -151,6 +151,7 @@ Shorter periods are desirable.</string>
oldStyleStopCheckBox->setChecked(config.useOldStyleStopShortCut);
moveArmedCheckBox->setChecked(config.moveArmedCheckBox);
projectSaveCheckBox->setChecked(config.useProjectSaveDialog);
+ popsDefStayOpenCheckBox->setChecked(config.popupsDefaultStayOpen);
//updateSettings(); // TESTING
@@ -263,6 +264,7 @@ void GlobalSettingsConfig::updateSettings()
oldStyleStopCheckBox->setChecked(config.useOldStyleStopShortCut);
moveArmedCheckBox->setChecked(config.moveArmedCheckBox);
projectSaveCheckBox->setChecked(config.useProjectSaveDialog);
+ popsDefStayOpenCheckBox->setChecked(config.popupsDefaultStayOpen);
}
//---------------------------------------------------------
@@ -344,6 +346,7 @@ void GlobalSettingsConfig::apply()
config.useOldStyleStopShortCut = oldStyleStopCheckBox->isChecked();
config.moveArmedCheckBox = moveArmedCheckBox->isChecked();
config.useProjectSaveDialog = projectSaveCheckBox->isChecked();
+ config.popupsDefaultStayOpen = popsDefStayOpenCheckBox->isChecked();
//muse->showMixer(config.mixerVisible);
muse->showMixer1(config.mixer1Visible);
diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui
index ca4b97f8..68f3ebb5 100644
--- a/muse2/muse/widgets/gensetbase.ui
+++ b/muse2/muse/widgets/gensetbase.ui
@@ -1333,7 +1333,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="5" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1346,6 +1346,27 @@ Adjusts responsiveness of audio controls and
</property>
</spacer>
</item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="text">
+ <string>Some popup menus stay open (else hold Ctrl)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QCheckBox" name="popsDefStayOpenCheckBox">
+ <property name="toolTip">
+ <string>Allows some popup menus to stay open.
+Otherwise, hold Ctrl to keep them open.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/muse2/muse/widgets/menutitleitem.cpp b/muse2/muse/widgets/menutitleitem.cpp
new file mode 100644
index 00000000..8769eb02
--- /dev/null
+++ b/muse2/muse/widgets/menutitleitem.cpp
@@ -0,0 +1,48 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// (C) Copyright 1999-2001 Werner Schweer (ws@seh.de)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <QLabel>
+
+#include "menutitleitem.h"
+
+//---------------------------------------------------------
+// MenuTitleItem
+//---------------------------------------------------------
+
+MenuTitleItem::MenuTitleItem(const QString& ss, QWidget* parent)
+ : QWidgetAction(parent)
+ {
+ s = ss;
+ // Don't allow to click on it.
+ setEnabled(false);
+ // Just to be safe, set to -1 instead of default 0.
+ setData(-1);
+ }
+
+QWidget* MenuTitleItem::createWidget(QWidget *parent)
+{
+ QLabel* l = new QLabel(s, parent);
+ l->setAlignment(Qt::AlignCenter);
+ l->setAutoFillBackground(true);
+ //QPalette palette;
+ //palette.setColor(label->backgroundRole(), c);
+ //l->setPalette(palette);
+ l->setBackgroundRole(QPalette::Dark);
+ return l;
+}
+
diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp
index 465b7130..6dd02931 100644
--- a/muse2/muse/widgets/mtrackinfo.cpp
+++ b/muse2/muse/widgets/mtrackinfo.cpp
@@ -26,6 +26,7 @@
#include "app.h"
#include "route.h"
#include "popupmenu.h"
+#include "routepopup.h"
//---------------------------------------------------------
// setTrack
@@ -577,33 +578,6 @@ void MidiTrackInfo::iOutputPortChanged(int index)
}
//---------------------------------------------------------
-// routingPopupMenuActivated
-//---------------------------------------------------------
-
-//void MidiTrackInfo::routingPopupMenuActivated(int n)
-void MidiTrackInfo::routingPopupMenuActivated(QAction* act)
-{
- ///if(!midiTrackInfo || gRoutingPopupMenuMaster != midiTrackInfo || !selected || !selected->isMidiTrack())
- if((gRoutingPopupMenuMaster != this) || !selected || !selected->isMidiTrack())
- return;
- muse->routingPopupMenuActivated(selected, act->data().toInt());
-}
-
-#if 0
-//---------------------------------------------------------
-// routingPopupViewActivated
-//---------------------------------------------------------
-
-void MidiTrackInfo::routingPopupViewActivated(const QModelIndex& mdi)
-{
- ///if(!midiTrackInfo || gRoutingPopupMenuMaster != midiTrackInfo || !selected || !selected->isMidiTrack())
- if(gRoutingPopupMenuMaster != this || !selected || !selected->isMidiTrack())
- return;
- muse->routingPopupMenuActivated(selected, mdi.data().toInt());
-}
-#endif
-
-//---------------------------------------------------------
// inRoutesPressed
//---------------------------------------------------------
@@ -614,44 +588,9 @@ void MidiTrackInfo::inRoutesPressed()
if(!selected->isMidiTrack())
return;
- PopupMenu* pup = muse->prepareRoutingPopupMenu(selected, false);
- //PopupView* pup = muse->prepareRoutingPopupView(selected, false);
-
- /*
- QPoint ppt = QCursor::pos();
-
- int i = 0;
- for( ; i < MIDI_PORTS; ++i)
- {
- if(midiPorts[i].device() && !midiPorts[pi].device()->isSynti())
- break;
- }
- if(!pup || i == MIDI_PORTS)
- {
- int ret = QMessageBox::warning(this, tr("No devices"),
- tr("There are no midi port devices defined.\n"
- "Do you want to open the midi configuration dialog?"),
- QMessageBox::Ok | QMessageBox::Cancel,
- QMessageBox::Ok);
- if (ret == QMessageBox::Ok) {
- //printf("open config midi ports\n");
- muse->configMidiPorts();
- }
- if(!pup)
- return;
- }
- */
-
- ///gRoutingPopupMenuMaster = midiTrackInfo;
- gRoutingPopupMenuMaster = this;
- connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
- //connect(pup, SIGNAL(activated(const QModelIndex&)), SLOT(routingPopupViewActivated(const QModelIndex&)));
- connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
- //connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupViewAboutToHide()));
- pup->popup(QCursor::pos());
- //pup->setVisible(true);
+ RoutePopupMenu* pup = muse->getRoutingPopupMenu();
iRButton->setDown(false);
- return;
+ pup->exec(QCursor::pos(), selected, false);
}
//---------------------------------------------------------
@@ -665,17 +604,9 @@ void MidiTrackInfo::outRoutesPressed()
if(!selected->isMidiTrack())
return;
- PopupMenu* pup = muse->prepareRoutingPopupMenu(selected, true);
- if(!pup)
- return;
-
- ///gRoutingPopupMenuMaster = midiTrackInfo;
- gRoutingPopupMenuMaster = this;
- connect(pup, SIGNAL(triggered(QAction*)), SLOT(routingPopupMenuActivated(QAction*)));
- connect(pup, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide()));
- pup->popup(QCursor::pos());
+ RoutePopupMenu* pup = muse->getRoutingPopupMenu();
oRButton->setDown(false);
- return;
+ pup->exec(QCursor::pos(), selected, true);
}
//---------------------------------------------------------
@@ -1044,7 +975,7 @@ void MidiTrackInfo::iPanChanged(int val)
void MidiTrackInfo::instrPopupActivated(QAction* act)
{
- //printf("MidiTrackInfo::instrPopupActivated\n"); // REMOVE Tim
+ //printf("MidiTrackInfo::instrPopupActivated\n");
if(act && selected)
{
@@ -1076,11 +1007,11 @@ void MidiTrackInfo::instrPopup()
//QMenu* pup = new QMenu;
PopupMenu* pup = new PopupMenu(true);
- ///instr->populatePatchPopup(pop, channel, song->mtype(), track->type() == Track::DRUM);
+ //instr->populatePatchPopup(pop, channel, song->mtype(), track->type() == Track::DRUM);
instr->populatePatchPopup(pup, channel, song->mtype(), track->type() == Track::DRUM);
- ///if(pop->actions().count() == 0)
- /// return;
+ //if(pop->actions().count() == 0)
+ // return;
if(pup->actions().count() == 0)
{
delete pup;
@@ -1090,7 +1021,7 @@ void MidiTrackInfo::instrPopup()
connect(pup, SIGNAL(triggered(QAction*)), SLOT(instrPopupActivated(QAction*)));
//connect(pup, SIGNAL(hovered(QAction*)), SLOT(instrPopupActivated(QAction*)));
- ///QAction *act = pop->exec(iPatch->mapToGlobal(QPoint(10,5)));
+ //QAction *act = pop->exec(iPatch->mapToGlobal(QPoint(10,5)));
QAction *act = pup->exec(iPatch->mapToGlobal(QPoint(10,5)));
if(act)
{
@@ -1310,15 +1241,6 @@ void MidiTrackInfo::updateTrackInfo(int flags)
return;
MidiTrack* track = (MidiTrack*)selected;
- // p3.3.47 Update the routing popup menu if anything relevant changes.
- //if(gRoutingPopupMenuMaster == midiTrackInfo && selected && (flags & (SC_ROUTE | SC_CHANNELS | SC_CONFIG)))
- if(flags & (SC_ROUTE | SC_CHANNELS | SC_CONFIG)) // p3.3.50
- // Use this handy shared routine.
- //muse->updateRouteMenus(selected);
- ///muse->updateRouteMenus(selected, midiTrackInfo); // p3.3.50
- muse->updateRouteMenus(selected, this);
-
- // Added by Tim. p3.3.9
setLabelText();
setLabelFont();
diff --git a/muse2/muse/widgets/mtrackinfo.h b/muse2/muse/widgets/mtrackinfo.h
index 0e559f33..ed229ad6 100644
--- a/muse2/muse/widgets/mtrackinfo.h
+++ b/muse2/muse/widgets/mtrackinfo.h
@@ -46,8 +46,6 @@ class MidiTrackInfo : public QWidget, public Ui::MidiTrackInfoBase
void recEchoToggled(bool);
void inRoutesPressed();
void outRoutesPressed();
- void routingPopupMenuActivated(QAction*);
- //void routingPopupViewActivated(const QModelIndex&);
void instrPopupActivated(QAction*);
protected slots:
diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp
index 8cb0b57e..993b0fb8 100644
--- a/muse2/muse/widgets/musewidgetsplug.cpp
+++ b/muse2/muse/widgets/musewidgetsplug.cpp
@@ -190,13 +190,14 @@ GlobalConfigValues config = {
true, // useDenormalBias
false, // useOutputLimiter
true, // showDidYouKnow
- false, // vstInPlace Enable VST in-place processing
+ false, // vstInPlace Enable VST in-place processing
44100, // Dummy audio preferred sample rate
512 // Dummy audio buffer size
QString("./"), // projectBaseFolder
true, // projectStoreInFolder
true, // useProjectSaveDialog
- 64 // minControlProcessPeriod
+ 64, // minControlProcessPeriod
+ false // popupsDefaultStayOpen
};
//---------------------------------------------------------
diff --git a/muse2/muse/widgets/popupmenu.cpp b/muse2/muse/widgets/popupmenu.cpp
index 263c8475..adbe7dd6 100644
--- a/muse2/muse/widgets/popupmenu.cpp
+++ b/muse2/muse/widgets/popupmenu.cpp
@@ -22,6 +22,8 @@
//#include <QStandardItemModel>
#include "popupmenu.h"
+#include "gconfig.h"
+#include "route.h"
//======================
@@ -82,7 +84,7 @@ void PopupMenu::clear()
QMenu* menu = act->menu();
if(menu)
{
- menu->clear();
+ menu->clear(); // Recursive.
act->setMenu(0); // CHECK: Is this OK?
delete menu;
}
@@ -97,7 +99,25 @@ void PopupMenu::clear()
#endif // POPUP_MENU_DISABLE_AUTO_SCROLL
}
-QAction* PopupMenu::findActionFromData(QVariant v) const
+void PopupMenu::clearAllChecks() const
+{
+ QList<QAction*> list = actions();
+ for(int i = 0; i < list.size(); ++i)
+ {
+ QAction* act = list[i];
+ PopupMenu* menu = static_cast <PopupMenu*>(act->menu());
+ if(menu)
+ menu->clearAllChecks(); // Recursive.
+ if(act->isCheckable())
+ {
+ act->blockSignals(true);
+ act->setChecked(false);
+ act->blockSignals(false);
+ }
+ }
+}
+
+QAction* PopupMenu::findActionFromData(const QVariant& v) const
{
QList<QAction*> list = actions();
for(int i = 0; i < list.size(); ++i)
@@ -106,9 +126,21 @@ QAction* PopupMenu::findActionFromData(QVariant v) const
PopupMenu* menu = (PopupMenu*)act->menu();
if(menu)
{
- if(QAction* actm = menu->findActionFromData(v))
+ if(QAction* actm = menu->findActionFromData(v)) // Recursive.
return actm;
}
+
+ // "Operator == Compares this QVariant with v and returns true if they are equal,
+ // otherwise returns false. In the case of custom types, their equalness operators
+ // are not called. Instead the values' addresses are compared."
+ //
+ // Take care of struct Route first. Insert other future custom structures here too !
+ if(act->data().canConvert<Route>() && v.canConvert<Route>())
+ {
+ if(act->data().value<Route>() == v.value<Route>())
+ return act;
+ }
+ else
if(act->data() == v)
return act;
}
@@ -117,7 +149,7 @@ QAction* PopupMenu::findActionFromData(QVariant v) const
bool PopupMenu::event(QEvent* event)
{
- //printf("PopupMenu::event type:%d\n", event->type()); // REMOVE Tim.
+ //printf("PopupMenu::event type:%d\n", event->type());
switch(event->type())
{
@@ -125,6 +157,7 @@ bool PopupMenu::event(QEvent* event)
case QEvent::MouseButtonDblClick:
{
if(_stayOpen)
+ //if(_stayOpen && config.popupsDefaultStayOpen)
{
QMouseEvent* e = static_cast<QMouseEvent*>(event);
if(e->modifiers() == Qt::NoModifier)
@@ -143,6 +176,7 @@ bool PopupMenu::event(QEvent* event)
case QEvent::KeyPress:
{
if(_stayOpen)
+ //if(_stayOpen && config.popupsDefaultStayOpen)
{
QKeyEvent* e = static_cast<QKeyEvent*>(event);
if(e->modifiers() == Qt::NoModifier && e->key() == Qt::Key_Space)
@@ -169,7 +203,7 @@ bool PopupMenu::event(QEvent* event)
int dw = QApplication::desktop()->width(); // We want the whole thing if multiple monitors.
//printf("PopupMenu::event MouseMove: pos x:%d y:%d globPos x:%d y:%d\n",
- // pos.x(), pos.y(), globPos.x(), globPos.y()); // REMOVE Tim.
+ // pos.x(), pos.y(), globPos.x(), globPos.y());
/*
//QAction* action = actionAt(globPos);
@@ -178,7 +212,7 @@ bool PopupMenu::event(QEvent* event)
{
QRect r = actionGeometry(action);
//printf(" act x:%d y:%d w:%d h:%d popup px:%d py:%d pw:%d ph:%d\n",
- // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height()); // REMOVE Tim.
+ // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height());
//action->hover();
}
@@ -224,7 +258,7 @@ bool PopupMenu::event(QEvent* event)
#ifndef POPUP_MENU_DISABLE_AUTO_SCROLL
void PopupMenu::timerHandler()
{
- // printf("PopupMenu::timerHandler\n"); // REMOVE Tim.
+ // printf("PopupMenu::timerHandler\n");
//if(!isVisible() || !hasFocus())
if(!isVisible())
@@ -261,9 +295,9 @@ void PopupMenu::popHovered(QAction* action)
QRect r = actionGeometry(action);
//printf("PopupMenu::popHovered x:%d y:%d w:%d h:%d px:%d py:%d pw:%d ph:%d\n",
- // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height()); // REMOVE Tim.
+ // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height());
//printf("PopupMenu::popHovered x:%d y:%d w:%d h:%d px:%d py:%d pw:%d ph:%d dtw:%d\n",
- // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height(), dw); // REMOVE Tim.
+ // r.x(), r.y(), r.width(), r.height(), x(), y(), width(), height(), dw);
//int x = r.x() + ctrlSubPop->x();
if(x() + r.x() < 0)
//setGeometry(0, y(), width(), height());
@@ -295,49 +329,20 @@ void PopupMenu::mouseReleaseEvent(QMouseEvent *e)
return;
#else
- if(!_stayOpen)
+ // Check for Ctrl to stay open.
+ if(!_stayOpen || (!config.popupsDefaultStayOpen && (e->modifiers() & Qt::ControlModifier) == 0))
{
QMenu::mouseReleaseEvent(e);
return;
}
- //printf("PopupMenu::mouseReleaseEvent\n"); // REMOVE Tim.
-
- //Q_D(QMenu);
- //if (d->mouseEventTaken(e))
- // return;
-
- //d->mouseDown = false;
- //QAction *action = d->actionAt(e->pos());
+ //printf("PopupMenu::mouseReleaseEvent\n");
QAction *action = actionAt(e->pos());
-
- //for(QWidget *caused = this; caused;) {
- // if (QMenu *m = qobject_cast<QMenu*>(caused)) {
- // QAction *currentAction = d->currentAction;
- // if(currentAction && (!currentAction->isEnabled() || currentAction->menu() || currentAction->isSeparator()))
- // currentAction = 0;
- // caused = m->d_func()->causedPopup.widget;
- // if (m->d_func()->eventLoop)
- // m->d_func()->syncAction = currentAction; // synchronous operation
- // } else {
- // break;
- // }
- //}
-
- //if (action && action == d->currentAction) {
if (action && action == activeAction() && !action->isSeparator() && action->isEnabled())
- {
- //if (action->menu())
- // action->menu()->d_func()->setFirstActionActive();
- //else
- //d->activateAction(action, QAction::Trigger);
- action->activate(QAction::Trigger);
- }
+ action->activate(QAction::Trigger);
else
- //if (d->motions > 6) {
- // d->hideUpToMenuBar();
- // }
QMenu::mouseReleaseEvent(e);
+
#endif // POPUP_MENU_DISABLE_STAY_OPEN
}
diff --git a/muse2/muse/widgets/popupmenu.h b/muse2/muse/widgets/popupmenu.h
index 47be57ae..e0e7d26f 100644
--- a/muse2/muse/widgets/popupmenu.h
+++ b/muse2/muse/widgets/popupmenu.h
@@ -60,8 +60,9 @@ class PopupMenu : public QMenu
PopupMenu(const QString& title, QWidget* parent = 0, bool stayOpen = false);
~PopupMenu();
void clear();
- QAction* findActionFromData(QVariant) const;
+ QAction* findActionFromData(const QVariant&) const;
bool stayOpen() const { return _stayOpen; }
+ void clearAllChecks() const;
};
diff --git a/muse2/muse/widgets/routepopup.cpp b/muse2/muse/widgets/routepopup.cpp
new file mode 100644
index 00000000..910d693d
--- /dev/null
+++ b/muse2/muse/widgets/routepopup.cpp
@@ -0,0 +1,1416 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+//
+// RoutePopupMenu.cpp
+// (C) Copyright 2011 Tim E. Real (terminator356 A T sourceforge D O T net)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "app.h"
+#include "routepopup.h"
+#include "midiport.h"
+#include "mididev.h"
+#include "audio.h"
+#include "driver/audiodev.h"
+#include "song.h"
+#include "track.h"
+#include "synth.h"
+#include "route.h"
+#include "icons.h"
+#include "menutitleitem.h"
+#include "popupmenu.h"
+
+//---------------------------------------------------------
+// addMenuItem
+//---------------------------------------------------------
+
+int RoutePopupMenu::addMenuItem(AudioTrack* track, Track* route_track, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
+{
+ // totalInChannels is only used by syntis.
+ int toch = ((AudioTrack*)track)->totalOutChannels();
+ // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
+ if(track->channels() == 1)
+ toch = 1;
+
+ // Don't add the last stray mono route if the track is stereo.
+ //if(route_track->channels() > 1 && (channel+1 == chans))
+ // return id;
+
+ RouteList* rl = isOutput ? track->outRoutes() : track->inRoutes();
+
+ QAction* act;
+
+ QString s(route_track->name());
+
+ act = lb->addAction(s);
+ act->setCheckable(true);
+
+ int ach = channel;
+ int bch = -1;
+
+ Route r(route_track, isOutput ? ach : bch, channels);
+
+ r.remoteChannel = isOutput ? bch : ach;
+
+ act->setData(qVariantFromValue(r));
+
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == route_track && ir->remoteChannel == r.remoteChannel)
+ {
+ int tcompch = r.channel;
+ if(tcompch == -1)
+ tcompch = 0;
+ int tcompchs = r.channels;
+ if(tcompchs == -1)
+ tcompchs = isOutput ? track->channels() : route_track->channels();
+
+ int compch = ir->channel;
+ if(compch == -1)
+ compch = 0;
+ int compchs = ir->channels;
+ if(compchs == -1)
+ compchs = isOutput ? track->channels() : ir->track->channels();
+
+ if(compch == tcompch && compchs == tcompchs)
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ }
+ return ++id;
+}
+
+//---------------------------------------------------------
+// addAuxPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addAuxPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
+ {
+ AuxList* al = song->auxs();
+ for (iAudioAux i = al->begin(); i != al->end(); ++i) {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ id = addMenuItem(t, track, lb, id, channel, channels, isOutput);
+ }
+ return id;
+ }
+
+//---------------------------------------------------------
+// addInPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addInPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
+ {
+ InputList* al = song->inputs();
+ for (iAudioInput i = al->begin(); i != al->end(); ++i) {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ id = addMenuItem(t, track, lb, id, channel, channels, isOutput);
+ }
+ return id;
+ }
+
+//---------------------------------------------------------
+// addOutPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addOutPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
+ {
+ OutputList* al = song->outputs();
+ for (iAudioOutput i = al->begin(); i != al->end(); ++i) {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ id = addMenuItem(t, track, lb, id, channel, channels, isOutput);
+ }
+ return id;
+ }
+
+//---------------------------------------------------------
+// addGroupPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addGroupPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
+ {
+ GroupList* al = song->groups();
+ for (iAudioGroup i = al->begin(); i != al->end(); ++i) {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ id = addMenuItem(t, track, lb, id, channel, channels, isOutput);
+ }
+ return id;
+ }
+
+//---------------------------------------------------------
+// addWavePorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addWavePorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput)
+ {
+ WaveTrackList* al = song->waves();
+ for (iWaveTrack i = al->begin(); i != al->end(); ++i) {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ id = addMenuItem(t, track, lb, id, channel, channels, isOutput);
+ }
+ return id;
+ }
+
+//---------------------------------------------------------
+// addSyntiPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addSyntiPorts(AudioTrack* t, PopupMenu* lb, int id,
+ int channel, int channels, bool isOutput)
+{
+ RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
+
+ QAction* act;
+
+ SynthIList* al = song->syntis();
+ for (iSynthI i = al->begin(); i != al->end(); ++i)
+ {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ int toch = ((AudioTrack*)track)->totalOutChannels();
+ // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
+ if(track->channels() == 1)
+ toch = 1;
+
+ // totalInChannels is only used by syntis.
+ int chans = (!isOutput || track->type() != Track::AUDIO_SOFTSYNTH) ? toch : ((AudioTrack*)track)->totalInChannels();
+
+ int tchans = (channels != -1) ? channels: t->channels();
+ if(tchans == 2)
+ {
+ // Ignore odd numbered left-over mono channel.
+ //chans = chans & ~1;
+ //if(chans != 0)
+ chans -= 1;
+ }
+
+ if(chans > 0)
+ {
+ PopupMenu* chpup = new PopupMenu(lb, true);
+ chpup->setTitle(track->name());
+ for(int ch = 0; ch < chans; ++ch)
+ {
+ char buffer[128];
+ if(tchans == 2)
+ snprintf(buffer, 128, "%s %d,%d", chpup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
+ else
+ snprintf(buffer, 128, "%s %d", chpup->tr("Channel").toLatin1().constData(), ch+1);
+ act = chpup->addAction(QString(buffer));
+ act->setCheckable(true);
+
+ int ach = (channel == -1) ? ch : channel;
+ int bch = (channel == -1) ? -1 : ch;
+
+ Route rt(track, (t->type() != Track::AUDIO_SOFTSYNTH || isOutput) ? ach : bch, tchans);
+ rt.remoteChannel = (t->type() != Track::AUDIO_SOFTSYNTH || isOutput) ? bch : ach;
+
+ act->setData(qVariantFromValue(rt));
+
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == track && ir->remoteChannel == rt.remoteChannel)
+ {
+ int tcompch = rt.channel;
+ if(tcompch == -1)
+ tcompch = 0;
+ int tcompchs = rt.channels;
+ if(tcompchs == -1)
+ tcompchs = isOutput ? t->channels() : track->channels();
+
+ int compch = ir->channel;
+ if(compch == -1)
+ compch = 0;
+ int compchs = ir->channels;
+ if(compchs == -1)
+ compchs = isOutput ? t->channels() : ir->track->channels();
+
+ if(compch == tcompch && compchs == tcompchs)
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ }
+ ++id;
+ }
+
+ lb->addMenu(chpup);
+ }
+ }
+ return id;
+}
+
+//---------------------------------------------------------
+// addMultiChannelOutPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addMultiChannelPorts(AudioTrack* t, PopupMenu* pup, int id, bool isOutput)
+{
+ int toch = t->totalOutChannels();
+ // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
+ if(t->channels() == 1)
+ toch = 1;
+
+ // Number of allocated buffers is always MAX_CHANNELS or more, even if _totalOutChannels is less.
+ // totalInChannels is only used by syntis.
+ int chans = (isOutput || t->type() != Track::AUDIO_SOFTSYNTH) ? toch : t->totalInChannels();
+
+ if(chans > 1)
+ pup->addAction(new MenuTitleItem("<Mono>", pup));
+
+ //
+ // If it's more than one channel, create a sub-menu. If it's just one channel, don't bother with a sub-menu...
+ //
+
+ PopupMenu* chpup = pup;
+
+ for(int ch = 0; ch < chans; ++ch)
+ {
+ // If more than one channel, create the sub-menu.
+ if(chans > 1)
+ chpup = new PopupMenu(pup, true);
+
+ if(isOutput)
+ {
+ switch(t->type())
+ {
+
+ case Track::AUDIO_INPUT:
+ case Track::WAVE:
+ case Track::AUDIO_GROUP:
+ case Track::AUDIO_SOFTSYNTH:
+ case Track::AUDIO_AUX:
+ id = addWavePorts(t, chpup, id, ch, 1, isOutput);
+ id = addOutPorts(t, chpup, id, ch, 1, isOutput);
+ id = addGroupPorts(t, chpup, id, ch, 1, isOutput);
+ id = addSyntiPorts(t, chpup, id, ch, 1, isOutput);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch(t->type())
+ {
+
+ case Track::AUDIO_OUTPUT:
+ id = addWavePorts(t, chpup, id, ch, 1, isOutput);
+ id = addInPorts(t, chpup, id, ch, 1, isOutput);
+ id = addGroupPorts(t, chpup, id, ch, 1, isOutput);
+ id = addAuxPorts(t, chpup, id, ch, 1, isOutput);
+ id = addSyntiPorts(t, chpup, id, ch, 1, isOutput);
+ break;
+ case Track::WAVE:
+ case Track::AUDIO_SOFTSYNTH:
+ case Track::AUDIO_GROUP:
+ id = addWavePorts(t, chpup, id, ch, 1, isOutput);
+ id = addInPorts(t, chpup, id, ch, 1, isOutput);
+ id = addGroupPorts(t, chpup, id, ch, 1, isOutput);
+ id = addAuxPorts(t, chpup, id, ch, 1, isOutput);
+ id = addSyntiPorts(t, chpup, id, ch, 1, isOutput);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // If more than one channel, add the created sub-menu.
+ if(chans > 1)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d", pup->tr("Channel").toLatin1().constData(), ch+1);
+ chpup->setTitle(QString(buffer));
+ pup->addMenu(chpup);
+ }
+ }
+
+ // For stereo listing, ignore odd numbered left-over channels.
+ chans -= 1;
+ if(chans > 0)
+ {
+ // Ignore odd numbered left-over channels.
+ //int schans = (chans & ~1) - 1;
+
+ pup->addSeparator();
+ pup->addAction(new MenuTitleItem("<Stereo>", pup));
+
+ //
+ // If it's more than two channels, create a sub-menu. If it's just two channels, don't bother with a sub-menu...
+ //
+
+ chpup = pup;
+ if(chans <= 2)
+ // Just do one iteration.
+ chans = 1;
+
+ for(int ch = 0; ch < chans; ++ch)
+ {
+ // If more than two channels, create the sub-menu.
+ if(chans > 2)
+ chpup = new PopupMenu(pup, true);
+
+ if(isOutput)
+ {
+ switch(t->type())
+ {
+ case Track::AUDIO_INPUT:
+ case Track::WAVE:
+ case Track::AUDIO_GROUP:
+ case Track::AUDIO_SOFTSYNTH:
+ case Track::AUDIO_AUX:
+ id = addWavePorts(t, chpup, id, ch, 2, isOutput);
+ id = addOutPorts(t, chpup, id, ch, 2, isOutput);
+ id = addGroupPorts(t, chpup, id, ch, 2, isOutput);
+ id = addSyntiPorts(t, chpup, id, ch, 2, isOutput);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch(t->type())
+ {
+ case Track::AUDIO_OUTPUT:
+ id = addWavePorts(t, chpup, id, ch, 2, isOutput);
+ id = addInPorts(t, chpup, id, ch, 2, isOutput);
+ id = addGroupPorts(t, chpup, id, ch, 2, isOutput);
+ id = addAuxPorts(t, chpup, id, ch, 2, isOutput);
+ id = addSyntiPorts(t, chpup, id, ch, 2, isOutput);
+ break;
+ case Track::WAVE:
+ case Track::AUDIO_SOFTSYNTH:
+ case Track::AUDIO_GROUP:
+ id = addWavePorts(t, chpup, id, ch, 2, isOutput);
+ id = addInPorts(t, chpup, id, ch, 2, isOutput);
+ id = addGroupPorts(t, chpup, id, ch, 2, isOutput);
+ id = addAuxPorts(t, chpup, id, ch, 2, isOutput);
+ id = addSyntiPorts(t, chpup, id, ch, 2, isOutput);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // If more than two channels, add the created sub-menu.
+ if(chans > 2)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d,%d", pup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
+ chpup->setTitle(QString(buffer));
+ pup->addMenu(chpup);
+ }
+ }
+ }
+
+ return id;
+}
+
+//---------------------------------------------------------
+// nonSyntiTrackAddSyntis
+//---------------------------------------------------------
+
+int RoutePopupMenu::nonSyntiTrackAddSyntis(AudioTrack* t, PopupMenu* lb, int id, bool isOutput)
+{
+ RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
+
+ QAction* act;
+ SynthIList* al = song->syntis();
+ for (iSynthI i = al->begin(); i != al->end(); ++i)
+ {
+ Track* track = *i;
+ if (t == track)
+ continue;
+
+ int toch = ((AudioTrack*)track)->totalOutChannels();
+ // If track channels = 1, it must be a mono synth. And synti channels cannot be changed by user.
+ if(track->channels() == 1)
+ toch = 1;
+
+ // totalInChannels is only used by syntis.
+ int chans = (!isOutput || track->type() != Track::AUDIO_SOFTSYNTH) ? toch : ((AudioTrack*)track)->totalInChannels();
+
+ //int schans = synti->channels();
+ //if(schans < chans)
+ // chans = schans;
+// int tchans = (channels != -1) ? channels: t->channels();
+// if(tchans == 2)
+// {
+ // Ignore odd numbered left-over mono channel.
+ //chans = chans & ~1;
+ //if(chans != 0)
+// chans -= 1;
+// }
+ //int tchans = (channels != -1) ? channels: t->channels();
+
+ if(chans > 0)
+ {
+ PopupMenu* chpup = new PopupMenu(lb, true);
+ chpup->setTitle(track->name());
+ if(chans > 1)
+ chpup->addAction(new MenuTitleItem("<Mono>", chpup));
+
+ for(int ch = 0; ch < chans; ++ch)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d", chpup->tr("Channel").toLatin1().constData(), ch+1);
+ act = chpup->addAction(QString(buffer));
+ act->setCheckable(true);
+
+ int ach = ch;
+ int bch = -1;
+
+ Route rt(track, isOutput ? bch : ach, 1);
+
+ rt.remoteChannel = isOutput ? ach : bch;
+
+ act->setData(qVariantFromValue(rt));
+
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == track && ir->remoteChannel == rt.remoteChannel)
+ {
+ int tcompch = rt.channel;
+ if(tcompch == -1)
+ tcompch = 0;
+ int tcompchs = rt.channels;
+ if(tcompchs == -1)
+ tcompchs = isOutput ? t->channels() : track->channels();
+
+ int compch = ir->channel;
+ if(compch == -1)
+ compch = 0;
+ int compchs = ir->channels;
+ if(compchs == -1)
+ compchs = isOutput ? t->channels() : ir->track->channels();
+
+ if(compch == tcompch && compchs == tcompchs)
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ }
+ ++id;
+ }
+
+ chans -= 1;
+ if(chans > 0)
+ {
+ // Ignore odd numbered left-over channels.
+ //int schans = (chans & ~1) - 1;
+
+ chpup->addSeparator();
+ chpup->addAction(new MenuTitleItem("<Stereo>", chpup));
+
+ for(int ch = 0; ch < chans; ++ch)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d,%d", chpup->tr("Channel").toLatin1().constData(), ch+1, ch+2);
+ act = chpup->addAction(QString(buffer));
+ act->setCheckable(true);
+
+ int ach = ch;
+ int bch = -1;
+
+ Route rt(track, isOutput ? bch : ach, 2);
+
+ rt.remoteChannel = isOutput ? ach : bch;
+
+ act->setData(qVariantFromValue(rt));
+
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == track && ir->remoteChannel == rt.remoteChannel)
+ {
+ int tcompch = rt.channel;
+ if(tcompch == -1)
+ tcompch = 0;
+ int tcompchs = rt.channels;
+ if(tcompchs == -1)
+ tcompchs = isOutput ? t->channels() : track->channels();
+
+ int compch = ir->channel;
+ if(compch == -1)
+ compch = 0;
+ int compchs = ir->channels;
+ if(compchs == -1)
+ compchs = isOutput ? t->channels() : ir->track->channels();
+
+ if(compch == tcompch && compchs == tcompchs)
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ }
+ ++id;
+ }
+ }
+
+ lb->addMenu(chpup);
+ }
+ }
+ return id;
+}
+
+//---------------------------------------------------------
+// addMidiPorts
+//---------------------------------------------------------
+
+int RoutePopupMenu::addMidiPorts(AudioTrack* t, PopupMenu* pup, int id, bool isOutput)
+{
+ QAction* act;
+ for(int i = 0; i < MIDI_PORTS; ++i)
+ {
+ MidiPort* mp = &midiPorts[i];
+ MidiDevice* md = mp->device();
+
+ // This is desirable, but could lead to 'hidden' routes unless we add more support
+ // such as removing the existing routes when user changes flags.
+ // So for now, just list all valid ports whether read or write.
+ if(!md)
+ continue;
+ //if(!(md->rwFlags() & (isOutput ? 1 : 2)))
+ // continue;
+
+ // Do not list synth devices!
+ if(md->isSynti())
+ continue;
+
+ RouteList* rl = isOutput ? t->outRoutes() : t->inRoutes();
+
+ PopupMenu* subp = new PopupMenu(pup, true);
+ subp->setTitle(md->name());
+
+ int chanmask = 0;
+ // To reduce number of routes required, from one per channel to just one containing a channel mask.
+ // Look for the first route to this midi port. There should always be only a single route for each midi port, now.
+ for(ciRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
+ {
+ // We have a route to the midi port. Grab the channel mask.
+ chanmask = ir->channel;
+ break;
+ }
+ }
+
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ act = subp->addAction(QString("Channel %1").arg(ch+1));
+ act->setCheckable(true);
+
+ int chbit = 1 << ch;
+ Route srcRoute(i, chbit); // In accordance with channel mask, use the bit position.
+
+ act->setData(qVariantFromValue(srcRoute));
+
+ if(chanmask & chbit) // Is the channel already set? Show item check mark.
+ act->setChecked(true);
+
+ ++id;
+ }
+
+ //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
+ act = subp->addAction(QString("Toggle all"));
+ //act->setCheckable(true);
+ Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
+ act->setData(qVariantFromValue(togRoute));
+ ++id;
+
+ pup->addMenu(subp);
+ }
+ return id;
+}
+
+
+//======================
+// RoutePopupMenu
+//======================
+
+RoutePopupMenu::RoutePopupMenu(QWidget* parent, Track* track, bool isOutput)
+ : _track(track), _isOutMenu(isOutput)
+{
+ _pup = new PopupMenu(parent, true);
+ init();
+}
+
+RoutePopupMenu::RoutePopupMenu(const QString& title, QWidget* parent, Track* track, bool isOutput)
+ : _track(track), _isOutMenu(isOutput)
+{
+ _pup = new PopupMenu(title, parent, true);
+ init();
+}
+
+RoutePopupMenu::~RoutePopupMenu()
+{
+ //printf("RoutePopupMenu::~RoutePopupMenu\n");
+ // Make sure to clear which clears and deletes any sub popups.
+ _pup->clear();
+ delete _pup;
+}
+
+void RoutePopupMenu::init()
+{
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+}
+
+void RoutePopupMenu::songChanged(int val)
+{
+ if(val & (SC_ROUTE | SC_CHANNELS | SC_CONFIG))
+ updateRouteMenus();
+}
+
+void RoutePopupMenu::updateRouteMenus()
+{
+ // NOTE: The purpose of this routine is to make sure the items actually reflect
+ // the routing status.
+ // In case for some reason a route could not be added (or removed).
+ // Then the item will be properly un-checked (or checked) here.
+
+ //printf("RoutePopupMenu::updateRouteMenus\n");
+
+ if(!_track || !_pup || _pup->actions().isEmpty() || !_pup->isVisible())
+ return;
+
+ RouteList* rl = _isOutMenu ? _track->outRoutes() : _track->inRoutes();
+
+ // Clear all the action check marks.
+ _pup->clearAllChecks();
+
+ // Take care of Midi Port to Audio Input routes first...
+ if(_isOutMenu && _track->isMidiTrack())
+ {
+ int port = ((MidiTrack*)_track)->outPort();
+ if(port >= 0 && port < MIDI_PORTS)
+ {
+ MidiPort* mp = &midiPorts[port];
+ RouteList* mprl = mp->outRoutes();
+ for (ciRoute ir = mprl->begin(); ir != mprl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track && ir->track->type() == Track::AUDIO_INPUT)
+ {
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ int chbits = 1 << ch;
+ if(ir->channel & chbits)
+ {
+ Route r(ir->track, chbits);
+ //printf("RoutePopupMenu::updateRouteMenus MidiPort to AudioInput chbits:%d\n", chbits);
+ QAction* act = _pup->findActionFromData(qVariantFromValue(r));
+ if(act)
+ act->setChecked(true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Now check the ones that are found in the route list.
+ for(ciRoute irl = rl->begin(); irl != rl->end(); ++irl)
+ {
+ // Do MidiTrack to MidiPort routes...
+ if(irl->type == Route::MIDI_PORT_ROUTE)
+ {
+ //printf("RoutePopupMenu::updateRouteMenus MIDI_PORT_ROUTE\n");
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ int chbits = 1 << ch;
+ if(irl->channel & chbits)
+ {
+ Route r(irl->midiPort, chbits);
+ QAction* act = _pup->findActionFromData(qVariantFromValue(r));
+ if(act)
+ act->setChecked(true);
+ }
+ }
+ }
+ else
+ // Do all other routes...
+ {
+ //printf("RoutePopupMenu::updateRouteMenus other irl type:%d\n", irl->type);
+ QAction* act = _pup->findActionFromData(qVariantFromValue(*irl));
+ if(act)
+ act->setChecked(true);
+ }
+ }
+}
+
+void RoutePopupMenu::popupActivated(QAction* action)
+{
+ if(!action || !_track || !_pup || _pup->actions().isEmpty())
+ return;
+
+ if(_track->isMidiTrack())
+ {
+ RouteList* rl = _isOutMenu ? _track->outRoutes() : _track->inRoutes();
+
+ // Take care of Route data items first...
+ if(qVariantCanConvert<Route>(action->data()))
+ {
+ Route aRoute = action->data().value<Route>();
+
+ // Support Midi Port to Audio Input track routes.
+ if(aRoute.type == Route::TRACK_ROUTE && aRoute.track && aRoute.track->type() == Track::AUDIO_INPUT)
+ {
+ //if(gIsOutRoutingPopupMenu) // Try to avoid splitting like this.
+ {
+ int chbit = aRoute.channel;
+ int port = ((MidiTrack*)_track)->outPort();
+ if(port < 0 || port >= MIDI_PORTS)
+ return;
+
+ MidiPort* mp = &midiPorts[port];
+ //MidiDevice* md = mp->device();
+
+ // This is desirable, but could lead to 'hidden' routes unless we add more support
+ // such as removing the existing routes when user changes flags.
+ // So for now, just list all valid ports whether read or write.
+ //if(!md)
+ // return;
+ //if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2)))
+ // return;
+
+ Route bRoute(port, chbit);
+
+ int chmask = 0;
+ RouteList* mprl = _isOutMenu ? mp->outRoutes() : mp->inRoutes();
+ ciRoute ir = mprl->begin();
+ for (; ir != mprl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == aRoute.track) // Is there already a route to this port?
+ {
+ chmask = ir->channel; // Grab the channel mask.
+ break;
+ }
+ }
+ if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
+ {
+ // disconnect
+ if(_isOutMenu)
+ audio->msgRemoveRoute(bRoute, aRoute);
+ else
+ audio->msgRemoveRoute(aRoute, bRoute);
+ }
+ else
+ {
+ // connect
+ if(_isOutMenu)
+ audio->msgAddRoute(bRoute, aRoute);
+ else
+ audio->msgAddRoute(aRoute, bRoute);
+ }
+
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+
+ }
+ return;
+ }
+ else if(aRoute.type == Route::MIDI_PORT_ROUTE)
+ {
+ int chbit = aRoute.channel;
+ Route bRoute(_track, chbit);
+ int mdidx = aRoute.midiPort;
+
+ MidiPort* mp = &midiPorts[mdidx];
+ MidiDevice* md = mp->device();
+ //if(!md) // Rem. Allow connections to ports with no device.
+ // return;
+
+ //if(!(md->rwFlags() & 2))
+ //if(!(md->rwFlags() & (gIsOutRoutingPopupMenu ? 1 : 2)))
+ if(md && !(md->rwFlags() & (_isOutMenu ? 1 : 2)))
+ return;
+
+ int chmask = 0;
+ ciRoute iir = rl->begin();
+ for (; iir != rl->end(); ++iir)
+ {
+ if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx) // Is there already a route to this port?
+ {
+ chmask = iir->channel; // Grab the channel mask.
+ break;
+ }
+ }
+ if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
+ {
+ // disconnect
+ if(_isOutMenu)
+ audio->msgRemoveRoute(bRoute, aRoute);
+ else
+ audio->msgRemoveRoute(aRoute, bRoute);
+ }
+ else
+ {
+ // connect
+ if(_isOutMenu)
+ audio->msgAddRoute(bRoute, aRoute);
+ else
+ audio->msgAddRoute(aRoute, bRoute);
+ }
+
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ }
+ }
+ else
+ // ... now take care of integer data items.
+ if(qVariantCanConvert<int>(action->data()))
+ {
+ int n = action->data().value<int>();
+ if(!_isOutMenu && n == 0)
+ muse->configMidiPorts();
+ return;
+ }
+ }
+ else
+ {
+ AudioTrack* t = (AudioTrack*)_track;
+ RouteList* rl = _isOutMenu ? t->outRoutes() : t->inRoutes();
+
+ if(!qVariantCanConvert<Route>(action->data()))
+ return;
+
+ if(_isOutMenu)
+ {
+ Route dstRoute = action->data().value<Route>();
+ Route srcRoute(t, dstRoute.channel, dstRoute.channels);
+ srcRoute.remoteChannel = dstRoute.remoteChannel;
+
+ // check if route src->dst exists:
+ ciRoute irl = rl->begin();
+ for (; irl != rl->end(); ++irl) {
+ if (*irl == dstRoute)
+ break;
+ }
+ if (irl != rl->end()) {
+ // disconnect if route exists
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ }
+ else {
+ // connect if route does not exist
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ }
+ else
+ {
+ Route srcRoute = action->data().value<Route>();
+
+ // Support Midi Port to Audio Input routes.
+ if(_track->type() == Track::AUDIO_INPUT && srcRoute.type == Route::MIDI_PORT_ROUTE)
+ {
+ int chbit = srcRoute.channel;
+ Route dstRoute(t, chbit);
+ int mdidx = srcRoute.midiPort;
+ int chmask = 0;
+ ciRoute iir = rl->begin();
+ for (; iir != rl->end(); ++iir)
+ {
+ if(iir->type == Route::MIDI_PORT_ROUTE && iir->midiPort == mdidx) // Is there already a route to this port?
+ {
+ chmask = iir->channel; // Grab the channel mask.
+ break;
+ }
+ }
+
+ if ((chmask & chbit) == chbit) // Is the channel's bit(s) set?
+ {
+ //printf("routingPopupMenuActivated: removing src route ch:%d dst route ch:%d\n", srcRoute.channel, dstRoute.channel);
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ }
+ else
+ {
+ //printf("routingPopupMenuActivated: adding src route ch:%d dst route ch:%d\n", srcRoute.channel, dstRoute.channel);
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ return;
+ }
+
+ Route dstRoute(t, srcRoute.channel, srcRoute.channels);
+ dstRoute.remoteChannel = srcRoute.remoteChannel;
+
+ ciRoute irl = rl->begin();
+ for (; irl != rl->end(); ++irl) {
+ if (*irl == srcRoute)
+ break;
+ }
+ if (irl != rl->end()) {
+ // disconnect
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ }
+ else {
+ // connect
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+ }
+
+
+ }
+ //else
+ //{
+ //}
+}
+
+void RoutePopupMenu::prepare()
+{
+ _pup->disconnect();
+ _pup->clear();
+
+ if(!_track)
+ return;
+
+ connect(_pup, SIGNAL(triggered(QAction*)), SLOT(popupActivated(QAction*)));
+
+ if(_track->isMidiTrack())
+ {
+ RouteList* rl = _isOutMenu ? _track->outRoutes() : _track->inRoutes();
+
+ int gid = 0;
+ QAction* act = 0;
+
+ if(_isOutMenu)
+ {
+ // Support Midi Port to Audio Input track routes.
+ int port = ((MidiTrack*)_track)->outPort();
+ if(port >= 0 && port < MIDI_PORTS)
+ {
+ MidiPort* mp = &midiPorts[port];
+
+ // Do not list synth devices! Requiring valid device is desirable,
+ // but could lead to 'hidden' routes unless we add more support
+ // such as removing the existing routes when user changes flags.
+ // So for now, just list all valid ports whether read or write.
+ if(mp->device() && !mp->device()->isSynti())
+ {
+ RouteList* mprl = mp->outRoutes();
+ int chbits = 1 << ((MidiTrack*)_track)->outChannel();
+ //MidiDevice* md = mp->device();
+ //if(!md)
+ // continue;
+
+ _pup->addSeparator();
+ _pup->addAction(new MenuTitleItem(tr("Soloing chain"), _pup));
+ PopupMenu* subp = new PopupMenu(_pup, true);
+ subp->setTitle(tr("Audio returns"));
+ _pup->addMenu(subp);
+
+ InputList* al = song->inputs();
+ for (ciAudioInput i = al->begin(); i != al->end(); ++i)
+ {
+ Track* t = *i;
+ QString s(t->name());
+ act = subp->addAction(s);
+ act->setCheckable(true);
+ Route r(t, chbits);
+ act->setData(qVariantFromValue(r));
+ for(ciRoute ir = mprl->begin(); ir != mprl->end(); ++ir)
+ {
+ if(ir->type == Route::TRACK_ROUTE && ir->track == t && (ir->channel & chbits))
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ ++gid;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Warn if no devices available. Add an item to open midi config.
+ int pi = 0;
+ for( ; pi < MIDI_PORTS; ++pi)
+ {
+ MidiDevice* md = midiPorts[pi].device();
+ if(md && !md->isSynti() && (md->rwFlags() & 2))
+ break;
+ }
+ if(pi == MIDI_PORTS)
+ {
+ act = _pup->addAction(tr("Warning: No midi input devices!"));
+ act->setCheckable(false);
+ act->setData(-1);
+ _pup->addSeparator();
+ }
+ act = _pup->addAction(QIcon(*settings_midiport_softsynthsIcon), tr("Open midi config..."));
+ act->setCheckable(false);
+ act->setData(gid);
+ _pup->addSeparator();
+ ++gid;
+
+ _pup->addAction(new MenuTitleItem("Midi input ports", _pup));
+
+ for(int i = 0; i < MIDI_PORTS; ++i)
+ {
+ // NOTE: Could possibly list all devices, bypassing ports, but no, let's stick with ports.
+ MidiPort* mp = &midiPorts[i];
+ MidiDevice* md = mp->device();
+ //if(!md)
+ // continue;
+
+ // Do not list synth devices!
+ if(md && md->isSynti())
+ continue;
+
+ if(md && !(md->rwFlags() & 2))
+ continue;
+
+ //printf("MusE::prepareRoutingPopupMenu adding submenu portnum:%d\n", i);
+
+ int chanmask = 0;
+ // To reduce number of routes required, from one per channel to just one containing a channel mask.
+ // Look for the first route to this midi port. There should always be only a single route for each midi port, now.
+ ciRoute ir = rl->begin();
+ for( ; ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
+ {
+ // We have a route to the midi port. Grab the channel mask.
+ chanmask = ir->channel;
+ break;
+ }
+ }
+ // List ports with no device, but with routes to this track, in the main popup.
+ if(!md && ir == rl->end())
+ continue;
+
+ PopupMenu* subp = new PopupMenu(_pup, true);
+ subp->setTitle(QString("%1:").arg(i+1) + (md ? md->name() : tr("<none>")));
+
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ act = subp->addAction(QString("Channel %1").arg(ch+1));
+ act->setCheckable(true);
+ int chbit = 1 << ch;
+ Route srcRoute(i, chbit); // In accordance with channel mask, use the bit position.
+ act->setData(qVariantFromValue(srcRoute));
+ if(chanmask & chbit) // Is the channel already set? Show item check mark.
+ act->setChecked(true);
+ ++gid;
+ }
+ //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
+ act = subp->addAction(tr("Toggle all"));
+ //act->setCheckable(true);
+ Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
+ act->setData(qVariantFromValue(togRoute));
+ ++gid;
+ _pup->addMenu(subp);
+ }
+
+ #if 0
+ // p4.0.17 List ports with no device and no in routes, in a separate popup.
+ PopupMenu* morep = new PopupMenu(pup, true);
+ morep->setTitle(tr("More..."));
+ for(int i = 0; i < MIDI_PORTS; ++i)
+ {
+ MidiPort* mp = &midiPorts[i];
+ if(mp->device())
+ continue;
+
+ PopupMenu* subp = new PopupMenu(morep, true);
+ subp->setTitle(QString("%1:").arg(i) + tr("<none>"));
+
+ // MusE-2: Check this - needed with QMenu? Help says no. No - verified, it actually causes double triggers!
+ //connect(subp, SIGNAL(triggered(QAction*)), pup, SIGNAL(triggered(QAction*)));
+ //connect(subp, SIGNAL(aboutToHide()), pup, SIGNAL(aboutToHide()));
+
+ iRoute ir = rl->begin();
+ for( ; ir != rl->end(); ++ir)
+ {
+ if(ir->type == Route::MIDI_PORT_ROUTE && ir->midiPort == i)
+ break;
+ }
+ if(ir != rl->end())
+ continue;
+
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ act = subp->addAction(QString("Channel %1").arg(ch+1));
+ act->setCheckable(true);
+ act->setData(gid);
+
+ int chbit = 1 << ch;
+ Route srcRoute(i, chbit); // In accordance with new channel mask, use the bit position.
+
+ gRoutingMenuMap.insert( pRouteMenuMap(gid, srcRoute) );
+
+ //if(chanmask & chbit) // Is the channel already set? Show item check mark.
+ // act->setChecked(true);
+
+ ++gid;
+ }
+ //gid = MIDI_PORTS * MIDI_CHANNELS + i; // Make sure each 'toggle' item gets a unique id.
+ act = subp->addAction(QString("Toggle all"));
+ //act->setCheckable(true);
+ act->setData(gid);
+ Route togRoute(i, (1 << MIDI_CHANNELS) - 1); // Set all channel bits.
+ gRoutingMenuMap.insert( pRouteMenuMap(gid, togRoute) );
+ ++gid;
+ morep->addMenu(subp);
+ }
+ pup->addMenu(morep);
+ #endif
+
+ }
+ return;
+ }
+ else
+ {
+ AudioTrack* t = (AudioTrack*)_track;
+ int channel = t->channels();
+ if(_isOutMenu)
+ {
+ RouteList* orl = t->outRoutes();
+
+ QAction* act = 0;
+ int gid = 0;
+ gid = 0;
+
+ switch(_track->type())
+ {
+ case Track::AUDIO_OUTPUT:
+ {
+ for(int i = 0; i < channel; ++i)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), i+1);
+ MenuTitleItem* titel = new MenuTitleItem(QString(buffer), _pup);
+ _pup->addAction(titel);
+
+ if(!checkAudioDevice())
+ {
+ _pup->clear();
+ return;
+ }
+ std::list<QString> ol = audioDevice->inputPorts();
+ for(std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip)
+ {
+ act = _pup->addAction(*ip);
+ act->setCheckable(true);
+
+ Route dst(*ip, true, i, Route::JACK_ROUTE);
+ act->setData(qVariantFromValue(dst));
+ ++gid;
+ for(ciRoute ir = orl->begin(); ir != orl->end(); ++ir)
+ {
+ if(*ir == dst)
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ }
+ if(i+1 != channel)
+ _pup->addSeparator();
+ }
+
+ //
+ // Display using separate menu for audio inputs:
+ //
+ _pup->addSeparator();
+ _pup->addAction(new MenuTitleItem(tr("Soloing chain"), _pup));
+ PopupMenu* subp = new PopupMenu(_pup, true);
+ subp->setTitle(tr("Audio returns"));
+ _pup->addMenu(subp);
+ gid = addInPorts(t, subp, gid, -1, -1, true);
+ //
+ // Display all in the same menu:
+ //
+ //_pup->addSeparator();
+ //MenuTitleItem* title = new MenuTitleItem(tr("Audio returns"), _pup);
+ //_pup->addAction(title);
+ //gid = addInPorts(t, _pup, gid, -1, -1, true);
+ }
+ break;
+ case Track::AUDIO_SOFTSYNTH:
+ gid = addMultiChannelPorts(t, _pup, gid, true);
+ break;
+
+ case Track::AUDIO_INPUT:
+ case Track::WAVE:
+ case Track::AUDIO_GROUP:
+ case Track::AUDIO_AUX:
+ gid = addWavePorts( t, _pup, gid, -1, -1, true);
+ gid = addOutPorts( t, _pup, gid, -1, -1, true);
+ gid = addGroupPorts( t, _pup, gid, -1, -1, true);
+ gid = nonSyntiTrackAddSyntis(t, _pup, gid, true);
+ break;
+ default:
+ _pup->clear();
+ return;
+ }
+ }
+ else
+ {
+ if(_track->type() == Track::AUDIO_AUX)
+ return;
+
+ RouteList* irl = t->inRoutes();
+
+ QAction* act = 0;
+ int gid = 0;
+ gid = 0;
+
+ switch(_track->type())
+ {
+ case Track::AUDIO_INPUT:
+ {
+ for(int i = 0; i < channel; ++i)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().constData(), i+1);
+ MenuTitleItem* titel = new MenuTitleItem(QString(buffer), _pup);
+ _pup->addAction(titel);
+
+ if(!checkAudioDevice())
+ {
+ _pup->clear();
+ return;
+ }
+ std::list<QString> ol = audioDevice->outputPorts();
+ for(std::list<QString>::iterator ip = ol.begin(); ip != ol.end(); ++ip)
+ {
+ act = _pup->addAction(*ip);
+ act->setCheckable(true);
+
+ Route dst(*ip, true, i, Route::JACK_ROUTE);
+ act->setData(qVariantFromValue(dst));
+ ++gid;
+ for(ciRoute ir = irl->begin(); ir != irl->end(); ++ir)
+ {
+ if(*ir == dst)
+ {
+ act->setChecked(true);
+ break;
+ }
+ }
+ }
+ if(i+1 != channel)
+ _pup->addSeparator();
+ }
+
+ //
+ // Display using separate menus for midi ports and audio outputs:
+ //
+ _pup->addSeparator();
+ _pup->addAction(new MenuTitleItem(tr("Soloing chain"), _pup));
+ PopupMenu* subp = new PopupMenu(_pup, true);
+ subp->setTitle(tr("Audio sends"));
+ _pup->addMenu(subp);
+ gid = addOutPorts(t, subp, gid, -1, -1, false);
+ subp = new PopupMenu(_pup, true);
+ subp->setTitle(tr("Midi port sends"));
+ _pup->addMenu(subp);
+ addMidiPorts(t, subp, gid, false);
+ //
+ // Display all in the same menu:
+ //
+ //_pup->addAction(new MenuTitleItem(tr("Audio sends"), _pup));
+ //gid = addOutPorts(t, _pup, gid, -1, -1, false);
+ //_pup->addSeparator();
+ //_pup->addAction(new MenuTitleItem(tr("Midi sends"), _pup));
+ //addMidiPorts(t, _pup, gid, false);
+ }
+ break;
+ case Track::AUDIO_OUTPUT:
+ gid = addWavePorts( t, _pup, gid, -1, -1, false);
+ gid = addInPorts( t, _pup, gid, -1, -1, false);
+ gid = addGroupPorts(t, _pup, gid, -1, -1, false);
+ gid = addAuxPorts( t, _pup, gid, -1, -1, false);
+ gid = nonSyntiTrackAddSyntis(t, _pup, gid, false);
+ break;
+ case Track::WAVE:
+ gid = addWavePorts( t, _pup, gid, -1, -1, false);
+ gid = addInPorts( t, _pup, gid, -1, -1, false);
+ gid = addGroupPorts(t, _pup, gid, -1, -1, false);
+ gid = addAuxPorts( t, _pup, gid, -1, -1, false);
+ gid = nonSyntiTrackAddSyntis(t, _pup, gid, false);
+ break;
+ case Track::AUDIO_GROUP:
+ gid = addWavePorts( t, _pup, gid, -1, -1, false);
+ gid = addInPorts( t, _pup, gid, -1, -1, false);
+ gid = addGroupPorts(t, _pup, gid, -1, -1, false);
+ gid = addAuxPorts( t, _pup, gid, -1, -1, false);
+ gid = nonSyntiTrackAddSyntis(t, _pup, gid, false);
+ break;
+
+ case Track::AUDIO_SOFTSYNTH:
+ gid = addMultiChannelPorts(t, _pup, gid, false);
+ break;
+ default:
+ _pup->clear();
+ return;
+ }
+ }
+ }
+}
+
+void RoutePopupMenu::exec(Track* track, bool isOutput)
+{
+ if(track)
+ {
+ _track = track;
+ _isOutMenu = isOutput;
+ }
+ prepare();
+ _pup->exec();
+}
+
+void RoutePopupMenu::exec(const QPoint& p, Track* track, bool isOutput)
+{
+ if(track)
+ {
+ _track = track;
+ _isOutMenu = isOutput;
+ }
+ prepare();
+ _pup->exec(p);
+}
+
+void RoutePopupMenu::popup(const QPoint& p, Track* track, bool isOutput)
+{
+ if(track)
+ {
+ _track = track;
+ _isOutMenu = isOutput;
+ }
+ prepare();
+ _pup->popup(p);
+}
+
diff --git a/muse2/muse/widgets/routepopup.h b/muse2/muse/widgets/routepopup.h
new file mode 100644
index 00000000..6772e8ca
--- /dev/null
+++ b/muse2/muse/widgets/routepopup.h
@@ -0,0 +1,73 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+//
+// RoutePopupMenu.h
+// (C) Copyright 2011 Tim E. Real (terminator356 A T sourceforge D O T net)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ROUTEPOPUPMENU_H__
+#define __ROUTEPOPUPMENU_H__
+
+#include <QObject>
+
+class Track;
+class AudioTrack;
+class PopupMenu;
+class QWidget;
+class QString;
+class QAction;
+class QPoint;
+
+class RoutePopupMenu : public QObject
+{
+ Q_OBJECT
+
+ PopupMenu* _pup;
+ Track* _track;
+ // Whether the route popup was shown by clicking the output routes button, or input routes button.
+ bool _isOutMenu;
+
+ void init();
+ void prepare();
+
+ int addMenuItem(AudioTrack* track, Track* route_track, PopupMenu* lb, int id, int channel,
+ int channels, bool isOutput);
+ int addAuxPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput);
+ int addInPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput);
+ int addOutPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput);
+ int addGroupPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput);
+ int addWavePorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput);
+ int addSyntiPorts(AudioTrack* t, PopupMenu* lb, int id, int channel, int channels, bool isOutput);
+ int addMultiChannelPorts(AudioTrack* t, PopupMenu* pup, int id, bool isOutput);
+ int nonSyntiTrackAddSyntis(AudioTrack* t, PopupMenu* lb, int id, bool isOutput);
+ int addMidiPorts(AudioTrack* t, PopupMenu* pup, int id, bool isOutput);
+
+ private slots:
+ void popupActivated(QAction*);
+ void songChanged(int);
+
+ public:
+ RoutePopupMenu(QWidget* parent = 0, Track* track = 0, bool isOutput = false);
+ RoutePopupMenu(const QString& title, QWidget* parent = 0, Track* track = 0, bool isOutput = false);
+ ~RoutePopupMenu();
+
+ void updateRouteMenus();
+ void exec(Track* track = 0, bool isOutput = false);
+ void exec(const QPoint& p, Track* track = 0, bool isOutput = false);
+ void popup(const QPoint& p, Track* track = 0, bool isOutput = false);
+};
+
+#endif
diff --git a/muse2/synti/deicsonze/deicsonzeplugin.cpp b/muse2/synti/deicsonze/deicsonzeplugin.cpp
index 36684f5f..54eee202 100644
--- a/muse2/synti/deicsonze/deicsonzeplugin.cpp
+++ b/muse2/synti/deicsonze/deicsonzeplugin.cpp
@@ -406,7 +406,7 @@ void DeicsOnzeGui::setChorusCheckBox(double v, int i) {
else printf("setChorusCheckBox Error : cannot send controller upper than 225\n");
}
-void DeicsOnzeGui::setReverbFloatEntry(double v, int i) {
+void DeicsOnzeGui::setReverbFloatEntry(double /*v*/, int /*i*/) {
if(_deicsOnze->_pluginIReverb) {
// FIXME FIXME Tim
@@ -420,7 +420,7 @@ void DeicsOnzeGui::setReverbFloatEntry(double v, int i) {
}
else printf("Warning : no DeicsOnze reverb loaded\n");
}
-void DeicsOnzeGui::setReverbSlider(double v, int i) {
+void DeicsOnzeGui::setReverbSlider(double /*v*/, int /*i*/) {
if(_deicsOnze->_pluginIReverb) {
// FIXME FIXME Tim
@@ -434,7 +434,7 @@ void DeicsOnzeGui::setReverbSlider(double v, int i) {
}
else printf("Warning : no DeicsOnze reverb loaded\n");
}
-void DeicsOnzeGui::setChorusFloatEntry(double v, int i) {
+void DeicsOnzeGui::setChorusFloatEntry(double /*v*/, int /*i*/) {
if(_deicsOnze->_pluginIReverb) {
// FIXME FIXME Tim
@@ -448,7 +448,7 @@ void DeicsOnzeGui::setChorusFloatEntry(double v, int i) {
}
else printf("Warning : no DeicsOnze chorus loaded\n");
}
-void DeicsOnzeGui::setChorusSlider(double v, int i) {
+void DeicsOnzeGui::setChorusSlider(double /*v*/, int /*i*/) {
if(_deicsOnze->_pluginIReverb) {
// FIXME FIXME Tim