summaryrefslogtreecommitdiff
path: root/muse2/muse/confmport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/confmport.cpp')
-rw-r--r--muse2/muse/confmport.cpp897
1 files changed, 897 insertions, 0 deletions
diff --git a/muse2/muse/confmport.cpp b/muse2/muse/confmport.cpp
new file mode 100644
index 00000000..bea2e714
--- /dev/null
+++ b/muse2/muse/confmport.cpp
@@ -0,0 +1,897 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: confmport.cpp,v 1.9.2.10 2009/12/15 03:39:58 terminator356 Exp $
+//
+// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <list>
+#include <termios.h>
+#include <iostream>
+
+#include <q3listview.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <q3buttongroup.h>
+//Added by qt3to4:
+#include <QPixmap>
+#include <stdio.h>
+#include <q3popupmenu.h>
+#include <q3groupbox.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qsignalmapper.h>
+#include <qtooltip.h>
+#include <q3filedialog.h>
+#include <qtoolbutton.h>
+#include <qmessagebox.h>
+#include <qpoint.h>
+
+#include "confmport.h"
+#include "app.h"
+#include "icons.h"
+#include "globals.h"
+#include "transport.h"
+#include "arranger.h"
+#include "midiport.h"
+#include "mididev.h"
+#include "xml.h"
+#include "midisyncimpl.h"
+#include "midifilterimpl.h"
+#include "ctrlcombo.h"
+#include "minstrument.h"
+#include "synth.h"
+#include "audio.h"
+#include "midiseq.h"
+#include "driver/alsamidi.h"
+#include "driver/jackmidi.h"
+#include "audiodev.h"
+#include "menutitleitem.h"
+
+extern std::vector<Synth*> synthis;
+
+enum { DEVCOL_NO = 0, DEVCOL_GUI, DEVCOL_REC, DEVCOL_PLAY, DEVCOL_INSTR, DEVCOL_NAME,
+ //DEVCOL_STATE };
+ DEVCOL_ROUTES, DEVCOL_STATE };
+
+//---------------------------------------------------------
+// mdevViewItemRenamed
+//---------------------------------------------------------
+
+void MPConfig::mdevViewItemRenamed(Q3ListViewItem* item, int col, const QString& s)
+{
+ //printf("MPConfig::mdevViewItemRenamed col:%d txt:%s\n", col, s.latin1());
+ if(item == 0)
+ return;
+ switch(col)
+ {
+ case DEVCOL_NAME:
+ {
+ QString id = item->text(DEVCOL_NO);
+ int no = atoi(id.latin1()) - 1;
+ if(no < 0 || no >= MIDI_PORTS)
+ return;
+
+ MidiPort* port = &midiPorts[no];
+ MidiDevice* dev = port->device();
+ // Only Jack midi devices.
+ if(!dev || dev->deviceType() != MidiDevice::JACK_MIDI)
+ return;
+ if(dev->name() == s)
+ return;
+
+ if(midiDevices.find(s))
+ {
+ QMessageBox::critical(this,
+ tr("MusE: bad device name"),
+ tr("please choose a unique device name"),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+ songChanged(-1);
+ return;
+ }
+ dev->setName(s);
+ song->update();
+ }
+ break;
+ default:
+ printf("MPConfig::mdevViewItemRenamed unknown column clicked col:%d txt:%s\n", col, s.latin1());
+ break;
+ }
+}
+
+//---------------------------------------------------------
+// rbClicked
+//---------------------------------------------------------
+
+void MPConfig::rbClicked(Q3ListViewItem* item, const QPoint& cpt, int col)
+ {
+ if (item == 0)
+ return;
+ QString id = item->text(DEVCOL_NO);
+ int no = atoi(id.latin1()) - 1;
+ if (no < 0 || no >= MIDI_PORTS)
+ return;
+
+ int n;
+ MidiPort* port = &midiPorts[no];
+ MidiDevice* dev = port->device();
+ int rwFlags = dev ? dev->rwFlags() : 0;
+ int openFlags = dev ? dev->openFlags() : 0;
+ Q3ListView* listView = item->listView();
+ //printf("MPConfig::rbClicked cpt x:%d y:%d\n", cpt.x(), cpt.y());
+ //printf("MPConfig::rbClicked new cpt x:%d y:%d\n", cpt.x(), cpt.y());
+ //printf("MPConfig::rbClicked new mapped cpt x:%d y:%d\n", cpt.x(), cpt.y());
+ QPoint ppt = listView->itemRect(item).bottomLeft();
+ //printf("MPConfig::rbClicked ppt x:%d y:%d\n", ppt.x(), ppt.y());
+ ppt += QPoint(listView->header()->sectionPos(col), listView->header()->height());
+ //printf("MPConfig::rbClicked new ppt x:%d y:%d\n", ppt.x(), ppt.y());
+ ppt = listView->mapToGlobal(ppt);
+ //printf("MPConfig::rbClicked new mapped ppt x:%d y:%d\n", ppt.x(), ppt.y());
+
+ switch (col) {
+ case DEVCOL_GUI:
+ if (dev == 0)
+ //break;
+ return;
+ if (port->hasGui())
+ {
+ port->instrument()->showGui(!port->guiVisible());
+ item->setPixmap(DEVCOL_GUI, port->guiVisible() ? *dotIcon : *dothIcon);
+ }
+ //break;
+ return;
+
+ case DEVCOL_REC:
+ if (dev == 0 || !(rwFlags & 2))
+ //break;
+ return;
+ openFlags ^= 0x2;
+ dev->setOpenFlags(openFlags);
+ midiSeq->msgSetMidiDevice(port, dev); // reopen device
+ item->setPixmap(DEVCOL_REC, openFlags & 2 ? *dotIcon : *dothIcon);
+ //break;
+ return;
+
+ case DEVCOL_PLAY:
+ if (dev == 0 || !(rwFlags & 1))
+ //break;
+ return;
+ openFlags ^= 0x1;
+ dev->setOpenFlags(openFlags);
+ midiSeq->msgSetMidiDevice(port, dev); // reopen device
+ item->setPixmap(DEVCOL_PLAY, openFlags & 1 ? *dotIcon : *dothIcon);
+ //break;
+ return;
+
+ case DEVCOL_ROUTES:
+ {
+ if(!checkAudioDevice())
+ return;
+
+ if(audioDevice->deviceType() != AudioDevice::JACK_AUDIO) // p3.3.52 Only if Jack is running.
+ return;
+
+ if(!dev)
+ return;
+
+ // Only Jack midi devices.
+ //MidiJackDevice* mjd = dynamic_cast<MidiJackDevice*>(dev);
+ //if(!mjd)
+ if(dev->deviceType() != MidiDevice::JACK_MIDI)
+ return;
+
+ if(!dev->rwFlags() & 3)
+ return;
+
+ RouteList* rl = (dev->rwFlags() & 1) ? dev->outRoutes() : dev->inRoutes();
+
+ Q3PopupMenu* pup = 0;
+ int gid = 0;
+ std::list<QString> sl;
+
+ pup = new Q3PopupMenu(this);
+ pup->setCheckable(true);
+
+ _redisplay:
+ pup->clear();
+ gid = 0;
+
+ // Jack input ports if device is writable, and jack output ports if device is readable.
+ sl = (dev->rwFlags() & 1) ? audioDevice->inputPorts(true, _showAliases) : audioDevice->outputPorts(true, _showAliases);
+
+ //for (int i = 0; i < channel; ++i)
+ //{
+ //char buffer[128];
+ //snprintf(buffer, 128, "%s %d", tr("Channel").latin1(), i+1);
+ //MenuTitleItem* titel = new MenuTitleItem(QString(buffer));
+ //pup->insertItem(titel);
+
+ pup->insertItem(tr("Show first aliases"), gid);
+ pup->setItemChecked(gid, (_showAliases == 0));
+ ++gid;
+ pup->insertItem(tr("Show second aliases"), gid);
+ pup->setItemChecked(gid, (_showAliases == 1));
+ ++gid;
+ pup->insertSeparator();
+
+ for(std::list<QString>::iterator ip = sl.begin(); ip != sl.end(); ++ip)
+ {
+ //int id = pup->insertItem(*ip, gid);
+ pup->insertItem(*ip, gid);
+ //Route dst(*ip, true, i);
+ Route rt(*ip, (dev->rwFlags() & 1), -1, Route::JACK_ROUTE);
+ for(iRoute ir = rl->begin(); ir != rl->end(); ++ir)
+ {
+ if (*ir == rt)
+ {
+ //pup->setItemChecked(id, true);
+ pup->setItemChecked(gid, true);
+ break;
+ }
+ }
+ ++gid;
+ }
+ //if (i+1 != channel)
+ // pup->insertSeparator();
+ //}
+
+ n = pup->exec(ppt, 0);
+ if (n != -1)
+ {
+ if(n == 0) // Show first aliases
+ {
+ ///delete pup;
+ if(_showAliases == 0)
+ _showAliases = -1;
+ else
+ _showAliases = 0;
+ goto _redisplay; // Go back
+ }
+ else
+ if(n == 1) // Show second aliases
+ {
+ ///delete pup;
+ if(_showAliases == 1)
+ _showAliases = -1;
+ else
+ _showAliases = 1;
+ goto _redisplay; // Go back
+ }
+
+ QString s(pup->text(n));
+
+ if(dev->rwFlags() & 1) // Writable
+ {
+ Route srcRoute(dev, -1);
+ Route dstRoute(s, true, -1, Route::JACK_ROUTE);
+
+ iRoute iir = rl->begin();
+ for(; iir != rl->end(); ++iir)
+ {
+ if(*iir == dstRoute)
+ break;
+ }
+ if(iir != rl->end())
+ // disconnect
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ else
+ // connect
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+ else
+ if(dev->rwFlags() & 2) // Readable
+ {
+ Route srcRoute(s, false, -1, Route::JACK_ROUTE);
+ Route dstRoute(dev, -1);
+
+ iRoute iir = rl->begin();
+ for(; iir != rl->end(); ++iir)
+ {
+ if(*iir == srcRoute)
+ break;
+ }
+ if(iir != rl->end())
+ // disconnect
+ audio->msgRemoveRoute(srcRoute, dstRoute);
+ else
+ // connect
+ audio->msgAddRoute(srcRoute, dstRoute);
+ }
+
+ audio->msgUpdateSoloStates();
+ song->update(SC_ROUTE);
+
+ // p3.3.46
+ //delete pup;
+ // FIXME:
+ // Routes can't be re-read until the message sent from msgAddRoute1()
+ // has had time to be sent and actually affected the routes.
+ ///goto _redisplay; // Go back
+
+ }
+ delete pup;
+ //iR->setDown(false); // pup->exec() catches mouse release event
+
+ }
+ //break;
+ return;
+
+ case DEVCOL_NAME:
+ {
+ //printf("MPConfig::rbClicked DEVCOL_NAME\n");
+
+ // Did we click in the text area?
+ if((cpt.x() - ppt.x()) > buttondownIcon->width())
+ {
+ //printf("MPConfig::rbClicked starting item rename... enabled?:%d\n", item->renameEnabled(DEVCOL_NAME));
+ // Start the renaming of the cell...
+ if(item->renameEnabled(DEVCOL_NAME))
+ item->startRename(DEVCOL_NAME);
+
+ return;
+ }
+ else
+ // We clicked the 'down' button.
+ {
+ Q3PopupMenu* pup = new Q3PopupMenu(this);
+
+ pup->setCheckable(true);
+
+ pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" input"), 0);
+ pup->insertItem(tr("Create") + QT_TR_NOOP(" Jack") + tr(" output"), 1);
+
+ typedef std::map<std::string, int > asmap;
+ typedef std::map<std::string, int >::iterator imap;
+
+ asmap mapALSA;
+ asmap mapJACK;
+ asmap mapSYNTH;
+
+ int aix = 2;
+ int jix = 0x10000000;
+ int six = 0x20000000;
+ for(iMidiDevice i = midiDevices.begin(); i != midiDevices.end(); ++i)
+ {
+ //devALSA = dynamic_cast<MidiAlsaDevice*>(*i);
+ //if(devALSA)
+ if((*i)->deviceType() == MidiDevice::ALSA_MIDI)
+ {
+ //mapALSA.insert( std::pair<std::string, int> (std::string(devALSA->name().lower().latin1()), ii) );
+ mapALSA.insert( std::pair<std::string, int> (std::string((*i)->name().latin1()), aix) );
+ ++aix;
+ }
+ else
+ if((*i)->deviceType() == MidiDevice::JACK_MIDI)
+ {
+ //devJACK = dynamic_cast<MidiJackDevice*>(*i);
+ //if(devJACK)
+ //mapJACK.insert( std::pair<std::string, int> (std::string(devJACK->name().lower().latin1()), ii) );
+ mapJACK.insert( std::pair<std::string, int> (std::string((*i)->name().latin1()), jix) );
+ ++jix;
+ }
+ else
+ if((*i)->deviceType() == MidiDevice::SYNTH_MIDI)
+ {
+ mapSYNTH.insert( std::pair<std::string, int> (std::string((*i)->name().latin1()), six) );
+ ++six;
+ }
+ else
+ printf("MPConfig::rbClicked unknown midi device: %s\n", (*i)->name().latin1());
+ }
+
+ //int sz = midiDevices.size();
+ if(!mapALSA.empty())
+ {
+ pup->insertSeparator();
+ // pup->insertItem(new MenuTitleItem(QT_TR_NOOP("ALSA:"))); ddskrjo
+
+ for(imap i = mapALSA.begin(); i != mapALSA.end(); ++i)
+ {
+ int idx = i->second;
+ //if(idx > sz) // Sanity check
+ // continue;
+ QString s(i->first.c_str());
+ MidiDevice* md = midiDevices.find(s, MidiDevice::ALSA_MIDI);
+ if(md)
+ {
+ //if(!dynamic_cast<MidiAlsaDevice*>(md))
+ if(md->deviceType() != MidiDevice::ALSA_MIDI)
+ continue;
+
+ //pup->insertItem(QT_TR_NOOP(md->name()), idx + 3);
+ pup->insertItem(QT_TR_NOOP(md->name()), idx);
+
+ //for(int k = 0; k < MIDI_PORTS; ++k)
+ //{
+ //MidiDevice* dev = midiPorts[k].device();
+ //if(dev && s == dev->name())
+ if(md == dev)
+ {
+ //pup->setItemEnabled(idx + 3, false);
+ //pup->setItemChecked(idx + 3, true);
+ pup->setItemChecked(idx, true);
+ //break;
+ }
+ //}
+ }
+ }
+ }
+
+ if(!mapJACK.empty())
+ {
+ pup->insertSeparator();
+ //pup->insertItem(new MenuTitleItem(QT_TR_NOOP("JACK:"))); ddskrjo
+
+ for(imap i = mapJACK.begin(); i != mapJACK.end(); ++i)
+ {
+ int idx = i->second;
+ //if(idx > sz)
+ // continue;
+ QString s(i->first.c_str());
+ MidiDevice* md = midiDevices.find(s, MidiDevice::JACK_MIDI);
+ if(md)
+ {
+ //if(!dynamic_cast<MidiJackDevice*>(md))
+ if(md->deviceType() != MidiDevice::JACK_MIDI)
+ continue;
+
+ //pup->insertItem(QT_TR_NOOP(md->name()), idx + 3);
+ pup->insertItem(QT_TR_NOOP(md->name()), idx);
+
+ //for(int k = 0; k < MIDI_PORTS; ++k)
+ //{
+ //MidiDevice* dev = midiPorts[k].device();
+ //if(dev && s == dev->name())
+ if(md == dev)
+ {
+ //pup->setItemEnabled(idx + 3, false);
+ //pup->setItemChecked(idx + 3, true);
+ pup->setItemChecked(idx, true);
+ //break;
+ }
+ //}
+ }
+ }
+ }
+
+ if(!mapSYNTH.empty())
+ {
+ pup->insertSeparator();
+ //pup->insertItem(new MenuTitleItem(QT_TR_NOOP("SYNTH:"))); ddskrjo
+
+ for(imap i = mapSYNTH.begin(); i != mapSYNTH.end(); ++i)
+ {
+ int idx = i->second;
+ //if(idx > sz)
+ // continue;
+ QString s(i->first.c_str());
+ MidiDevice* md = midiDevices.find(s, MidiDevice::SYNTH_MIDI);
+ if(md)
+ {
+ //if(!dynamic_cast<MidiJackDevice*>(md))
+ if(md->deviceType() != MidiDevice::SYNTH_MIDI)
+ continue;
+
+ //pup->insertItem(QT_TR_NOOP(md->name()), idx + 3);
+ pup->insertItem(QT_TR_NOOP(md->name()), idx);
+
+ //for(int k = 0; k < MIDI_PORTS; ++k)
+ //{
+ //MidiDevice* dev = midiPorts[k].device();
+ //if(dev && s == dev->name())
+ if(md == dev)
+ {
+ //pup->setItemEnabled(idx + 3, false);
+ //pup->setItemChecked(idx + 3, true);
+ pup->setItemChecked(idx, true);
+ //break;
+ }
+ //}
+ }
+ }
+ }
+
+ n = pup->exec(ppt, 0);
+ if(n == -1)
+ {
+ delete pup;
+ //break;
+ return;
+ }
+
+ //printf("MPConfig::rbClicked n:%d\n", n);
+
+ MidiDevice* sdev = 0;
+ if(n < 2)
+ {
+ delete pup;
+ if(n == 0)
+ sdev = MidiJackDevice::createJackMidiDevice(QString(), 2); // 2: Readable.
+ else
+ if(n == 1)
+ sdev = MidiJackDevice::createJackMidiDevice(QString(), 1); // 1:Writable.
+ }
+ else
+ {
+ int typ = MidiDevice::ALSA_MIDI;
+ if(n >= 0x10000000)
+ typ = MidiDevice::JACK_MIDI;
+ if(n >= 0x20000000)
+ typ = MidiDevice::SYNTH_MIDI;
+
+ sdev = midiDevices.find(pup->text(n), typ);
+ delete pup;
+ // Is it the current device? Reset it to <none>.
+ if(sdev == dev)
+ sdev = 0;
+ }
+
+ midiSeq->msgSetMidiDevice(port, sdev);
+ muse->changeConfig(true); // save configuration file
+ song->update();
+ }
+ }
+ //break;
+ return;
+
+ case DEVCOL_INSTR:
+ {
+ if (dev && dev->isSynti())
+ //break;
+ return;
+ if (instrPopup == 0)
+ instrPopup = new Q3PopupMenu(this);
+ instrPopup->clear();
+ for (iMidiInstrument i = midiInstruments.begin(); i
+ != midiInstruments.end(); ++i)
+ {
+ // By T356.
+ // Do not list synths. Although it is possible to assign a synth
+ // as an instrument to a non-synth device, we should not allow this.
+ // (One reason is that the 'show gui' column is then enabled, which
+ // makes no sense for a non-synth device).
+ SynthI* si = dynamic_cast<SynthI*>(*i);
+ if(!si)
+ instrPopup->insertItem((*i)->iname());
+ }
+ n = instrPopup->exec(ppt, 0);
+ if (n == -1)
+ //break;
+ return;
+ QString s = instrPopup->text(n);
+ item->setText(DEVCOL_INSTR, s);
+ for (iMidiInstrument i = midiInstruments.begin(); i
+ != midiInstruments.end(); ++i) {
+ if ((*i)->iname() == s) {
+ port->setInstrument(*i);
+ break;
+ }
+ }
+ song->update();
+ }
+ //break;
+ return;
+ }
+ //songChanged(-1);
+ }
+
+//---------------------------------------------------------
+// MPHeaderTip::maybeTip
+//---------------------------------------------------------
+
+void MPHeaderTip::maybeTip(const QPoint &pos)
+ {
+#if 0 // ddskrjo
+ Q3Header* w = (Q3Header*)parentWidget();
+ int section = w->sectionAt(pos.x());
+ if (section == -1)
+ return;
+ QRect r(w->sectionPos(section), 0, w->sectionSize(section),
+ w->height());
+ QString p;
+ switch (section) {
+ case DEVCOL_NO: p = Q3Header::tr("Port Number"); break;
+ case DEVCOL_GUI: p = Q3Header::tr("Enable gui"); break;
+ case DEVCOL_REC: p = Q3Header::tr("Enable reading"); break;
+ case DEVCOL_PLAY: p = Q3Header::tr("Enable writing"); break;
+ case DEVCOL_INSTR: p = Q3Header::tr("Port instrument"); break;
+ case DEVCOL_NAME: p = Q3Header::tr("Midi device name. Click to edit (Jack)"); break;
+ case DEVCOL_ROUTES: p = Q3Header::tr("Jack midi ports"); break;
+ case DEVCOL_STATE: p = Q3Header::tr("Device state"); break;
+ default: return;
+ }
+ tip(r, p);
+#endif
+ }
+
+//---------------------------------------------------------
+// MPWhatsThis::text
+//---------------------------------------------------------
+
+QString MPWhatsThis::text(const QPoint& pos)
+ {
+ int n = header->cellAt(pos.x());
+ if (n == -1)
+ return QString::null;
+ switch (header->mapToLogical(n)) {
+ case DEVCOL_NO:
+ return Q3Header::tr("Port Number");
+ case DEVCOL_GUI:
+ return Q3Header::tr("Enable gui for device");
+ case DEVCOL_REC:
+ return Q3Header::tr("Enable reading from device");
+ case DEVCOL_PLAY:
+ return Q3Header::tr("Enable writing to device");
+ case DEVCOL_NAME:
+ return Q3Header::tr("Name of the midi device associated with"
+ " this port number. Click to edit Jack midi name.");
+ case DEVCOL_INSTR:
+ return Q3Header::tr("Instrument connected to port");
+ case DEVCOL_ROUTES:
+ return Q3Header::tr("Jack midi ports");
+ case DEVCOL_STATE:
+ return Q3Header::tr("State: result of opening the device");
+ default:
+ break;
+ }
+ return QString::null;
+ }
+
+//---------------------------------------------------------
+// MPConfig
+// Midi Port Config
+//---------------------------------------------------------
+
+MPConfig::MPConfig(QWidget* parent, char* name)
+ : SynthConfigBase(parent, name)
+ {
+ _mptooltip = 0;
+ popup = 0;
+ instrPopup = 0;
+ _showAliases = -1; // 0: Show first aliases, if available. Nah, stick with -1: none at first.
+
+ mdevView->setSorting(-1);
+ mdevView->setAllColumnsShowFocus(true);
+ mdevView->addColumn(tr("Port"));
+ mdevView->addColumn(tr("GUI"));
+ mdevView->addColumn(tr("I"));
+ mdevView->addColumn(tr("O"));
+ mdevView->addColumn(tr("Instrument"), 120);
+ mdevView->addColumn(tr("Device Name"), 120);
+ mdevView->addColumn(tr("Routing"), 80);
+ mdevView->addColumn(tr("State"));
+ mdevView->setFocusPolicy(Qt::NoFocus);
+
+ mdevView->setColumnAlignment(DEVCOL_NO, Qt::AlignHCenter);
+ mdevView->setColumnAlignment(DEVCOL_GUI, Qt::AlignCenter);
+ mdevView->setColumnAlignment(DEVCOL_REC, Qt::AlignCenter);
+ mdevView->setColumnAlignment(DEVCOL_PLAY, Qt::AlignCenter);
+ mdevView->header()->setResizeEnabled(false, DEVCOL_NO);
+ mdevView->header()->setResizeEnabled(false, DEVCOL_REC);
+ mdevView->header()->setResizeEnabled(false, DEVCOL_GUI);
+ mdevView->setResizeMode(Q3ListView::LastColumn);
+
+ instanceList->setColumnAlignment(1, Qt::AlignHCenter);
+
+ new MPWhatsThis(mdevView, mdevView->header());
+ _mptooltip = new MPHeaderTip(mdevView->header());
+
+ connect(mdevView, SIGNAL(pressed(Q3ListViewItem*,const QPoint&,int)),
+ this, SLOT(rbClicked(Q3ListViewItem*,const QPoint&,int)));
+ connect(mdevView, SIGNAL(itemRenamed(Q3ListViewItem*,int,const QString&)),
+ this, SLOT(mdevViewItemRenamed(Q3ListViewItem*,int,const QString&)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+
+ connect(synthList, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+ connect(instanceList, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+
+ connect(addInstance, SIGNAL(clicked()), SLOT(addInstanceClicked()));
+ connect(removeInstance, SIGNAL(clicked()), SLOT(removeInstanceClicked()));
+ songChanged(0);
+ }
+
+
+MPConfig::~MPConfig()
+{
+ delete _mptooltip;
+}
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void MPConfig::selectionChanged()
+ {
+ addInstance->setEnabled(synthList->selectedItem());
+ removeInstance->setEnabled(instanceList->selectedItem());
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MPConfig::songChanged(int flags)
+ {
+ // Is it simply a midi controller value adjustment? Forget it.
+ if(flags == SC_MIDI_CONTROLLER)
+ return;
+
+ // Get currently selected index...
+ int no = -1;
+ Q3ListViewItem* sitem = mdevView->selectedItem();
+ if(sitem)
+ {
+ QString id = sitem->text(DEVCOL_NO);
+ no = atoi(id.latin1()) - 1;
+ if(no < 0 || no >= MIDI_PORTS)
+ no = -1;
+ }
+
+ sitem = 0;
+ mdevView->clear();
+ for (int i = MIDI_PORTS-1; i >= 0; --i)
+ {
+ MidiPort* port = &midiPorts[i];
+ MidiDevice* dev = port->device();
+ QString s;
+ s.setNum(i+1);
+ Q3ListViewItem* item = new Q3ListViewItem(mdevView);
+ item->setText(DEVCOL_NO, s);
+ item->setText(DEVCOL_STATE, port->state());
+ if (port->instrument())
+ item->setText(DEVCOL_INSTR, port->instrument()->iname() );
+ else
+ item->setText(DEVCOL_INSTR, tr("<unknown>"));
+ if (dev) {
+ item->setText(DEVCOL_NAME, dev->name());
+ // Is it a Jack midi device? Allow renaming.
+ //if(dynamic_cast<MidiJackDevice*>(dev))
+ if(dev->deviceType() == MidiDevice::JACK_MIDI)
+ item->setRenameEnabled(DEVCOL_NAME, true);
+
+ if (dev->rwFlags() & 0x2)
+ item->setPixmap(DEVCOL_REC, dev->openFlags() & 2 ? *dotIcon : *dothIcon);
+ else
+ item->setPixmap(DEVCOL_REC, QPixmap());
+ if (dev->rwFlags() & 0x1)
+ item->setPixmap(DEVCOL_PLAY, dev->openFlags() & 1 ? *dotIcon : *dothIcon);
+ else
+ item->setPixmap(DEVCOL_PLAY, QPixmap());
+ }
+ else {
+ item->setText(DEVCOL_NAME, tr("<none>"));
+ item->setPixmap(DEVCOL_GUI, *dothIcon);
+ item->setPixmap(DEVCOL_REC, QPixmap());
+ item->setPixmap(DEVCOL_PLAY, QPixmap());
+ }
+ if (port->hasGui()) {
+ item->setPixmap(DEVCOL_GUI, port->guiVisible() ? *dotIcon : *dothIcon);
+ }
+ else {
+ item->setPixmap(DEVCOL_GUI, QPixmap());
+ }
+ if (!(dev && dev->isSynti()))
+ item->setPixmap(DEVCOL_INSTR, *buttondownIcon);
+ item->setPixmap(DEVCOL_NAME, *buttondownIcon);
+
+ //if(dev && dynamic_cast<MidiJackDevice*>(dev))
+ if(dev && dev->deviceType() == MidiDevice::JACK_MIDI)
+ {
+ item->setPixmap(DEVCOL_ROUTES, *buttondownIcon);
+ item->setText(DEVCOL_ROUTES, tr("routes"));
+ }
+
+ mdevView->insertItem(item);
+ if(i == no)
+ sitem = item;
+ }
+ if(sitem)
+ {
+ mdevView->setSelected(sitem, true);
+ mdevView->ensureItemVisible(sitem);
+ }
+
+ QString s;
+ synthList->clear();
+ for (std::vector<Synth*>::iterator i = synthis.begin();
+ i != synthis.end(); ++i) {
+ //s = (*i)->baseName();
+ //s = (*i)->name();
+
+ Q3ListViewItem* item = new Q3ListViewItem(synthList);
+ //item->setText(0, s);
+ item->setText(0, QString((*i)->baseName()));
+ s.setNum((*i)->instances());
+ item->setText(1, s);
+ //item->setText(2, QString((*i)->baseName()));
+ item->setText(2, QString((*i)->name()));
+
+ item->setText(3, QString((*i)->version()));
+ item->setText(4, QString((*i)->description()));
+ }
+ instanceList->clear();
+ SynthIList* sl = song->syntis();
+ for (iSynthI si = sl->begin(); si != sl->end(); ++si) {
+ Q3ListViewItem* iitem = new Q3ListViewItem(instanceList);
+ iitem->setText(0, (*si)->name());
+ if ((*si)->midiPort() == -1)
+ s = tr("<none>");
+ else
+ s.setNum((*si)->midiPort() + 1);
+ iitem->setText(1, s);
+ }
+ selectionChanged();
+ }
+
+//---------------------------------------------------------
+// addInstanceClicked
+//---------------------------------------------------------
+
+void MPConfig::addInstanceClicked()
+ {
+ Q3ListViewItem* item = synthList->selectedItem();
+ if (item == 0)
+ return;
+ //SynthI *si = song->createSynthI(item->text(2));
+ SynthI *si = song->createSynthI(item->text(0), item->text(2));
+ if(!si)
+ return;
+
+ // add instance last in midi device list
+ for (int i = 0; i < MIDI_PORTS; ++i) {
+ MidiPort* port = &midiPorts[i];
+ MidiDevice* dev = port->device();
+ if (dev==0) {
+ midiSeq->msgSetMidiDevice(port, si);
+ muse->changeConfig(true); // save configuration file
+ song->update();
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// removeInstanceClicked
+//---------------------------------------------------------
+
+void MPConfig::removeInstanceClicked()
+ {
+ Q3ListViewItem* item = instanceList->selectedItem();
+ if (item == 0)
+ return;
+ SynthIList* sl = song->syntis();
+ iSynthI ii;
+ for (ii = sl->begin(); ii != sl->end(); ++ii) {
+ if ((*ii)->iname() == item->text(0))
+ break;
+ }
+ if (ii == sl->end()) {
+ printf("synthesizerConfig::removeInstanceClicked(): synthi not found\n");
+ return;
+ }
+ audio->msgRemoveTrack(*ii);
+ }
+
+//---------------------------------------------------------
+// configMidiPorts
+//---------------------------------------------------------
+
+void MusE::configMidiPorts()
+ {
+ if (!midiPortConfig)
+ midiPortConfig = new MPConfig(0, (char*) "midiPortConfig");
+ if (midiPortConfig->isVisible()) {
+ midiPortConfig->raise();
+ midiPortConfig->setActiveWindow();
+ }
+ else
+ midiPortConfig->show();
+ }
+