diff options
| author | Florian Jung <flo@windfisch.org> | 2011-10-11 13:30:53 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-10-11 13:30:53 +0000 | 
| commit | 872bace8291a63849ce690100eec7042bf8e05b6 (patch) | |
| tree | 55030d6a8bb4733e8656c53e7f236cf6e0c14eb5 /muse2/muse | |
| parent | b3280635650c81a718c1b93a2a3436d7bb35bab8 (diff) | |
| parent | 12a05293d545375bfc68665f047bb5838ac212ef (diff) | |
merged with trunk
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/appearance.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/appearance.h | 6 | ||||
| -rw-r--r-- | muse2/muse/arranger/tlist.cpp | 128 | ||||
| -rw-r--r-- | muse2/muse/conf.cpp | 6 | ||||
| -rw-r--r-- | muse2/muse/gconfig.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/gconfig.h | 8 | ||||
| -rw-r--r-- | muse2/muse/midiedit/dlist.cpp | 71 | ||||
| -rw-r--r-- | muse2/muse/midiedit/drumedit.cpp | 4 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 20 | ||||
| -rw-r--r-- | muse2/muse/midiport.cpp | 61 | ||||
| -rw-r--r-- | muse2/muse/mixer/amixer.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/mixer/amixer.h | 9 | ||||
| -rw-r--r-- | muse2/muse/widgets/musewidgetsplug.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/widgets/routepopup.cpp | 4 | 
14 files changed, 206 insertions, 119 deletions
| diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index 6c3ee2e4..ab2f8872 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -123,7 +123,7 @@ Appearance::Appearance(Arranger* a, QWidget* parent)        setupUi(this);        arr    = a;        color  = 0; -      config = new GlobalConfigValues; +      config = new MusEGlobal::GlobalConfigValues;        lastSelectedColorItem = 0;        lastSelectedBgItem = 0; diff --git a/muse2/muse/appearance.h b/muse2/muse/appearance.h index d8ec3dc5..ecefeae0 100644 --- a/muse2/muse/appearance.h +++ b/muse2/muse/appearance.h @@ -28,10 +28,12 @@  class QColor;  class QDialog; +namespace MusEGlobal { +  class GlobalConfigValues; +}  namespace MusEGui {  class Arranger; -class GlobalConfigValues;  class MusE;  //--------------------------------------------------------- @@ -45,7 +47,7 @@ class Appearance : public QDialog, public Ui::AppearanceDialogBase {   private:        Arranger* arr;        QColor* color; -      GlobalConfigValues* config; +      MusEGlobal::GlobalConfigValues* config;        QButtonGroup* aPalette;        QTreeWidgetItem* user_bg;        QTreeWidgetItem* global_bg; diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index decd1a2e..1b2358f3 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -592,7 +592,7 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y)              case MusECore::Track::DRUM:              case MusECore::Track::NEW_DRUM:              case MusECore::Track::AUDIO_SOFTSYNTH:  -                  { +            {                    MusECore::MidiTrack* track = (MusECore::MidiTrack*)t;                    //QPopupMenu* p = MusECore::midiPortsPopup(0); @@ -608,72 +608,86 @@ void TList::portsPopupMenu(MusECore::Track* t, int x, int y)                    else                         port = track->outPort(); -                  QMenu* p = MusECore::midiPortsPopup(0, port); +                  QMenu* p = MusECore::midiPortsPopup(this, port);     // 0, port);                    QAction* act = p->exec(mapToGlobal(QPoint(x, y)), 0); -                  if (act) { -                        int n = act->data().toInt(); -                        // Changed by T356. -                        //track->setOutPort(n); -                        //MusEGlobal::audio->msgSetTrackOutPort(track, n); -                         -                        //MusEGlobal::song->update(); -                        if (t->type() == MusECore::Track::DRUM) { -                              bool change = QMessageBox::question(this, tr("Update drummap?"), -                                             tr("Do you want to use same port for all instruments in the drummap?"), -                                             tr("&Yes"), tr("&No"), QString::null, 0, 1); -                              MusEGlobal::audio->msgIdle(true); -                              if (!change)  -                              { -                                    // Delete all port controller events. -                                    //MusEGlobal::audio->msgChangeAllPortDrumCtrlEvents(false); -                                    MusEGlobal::song->changeAllPortDrumCtrlEvents(false); -                                    track->setOutPort(n); +                  if(!act)  +                  { +                    delete p; +                    break; +                  }   +                     +                  int n = act->data().toInt(); +                  delete p; -                                    for (int i=0; i<DRUM_MAPSIZE; i++) //Remap all drum instruments to this port -                                          MusEGlobal::drumMap[i].port = track->outPort(); -                                    // Add all port controller events. -                                    //MusEGlobal::audio->msgChangeAllPortDrumCtrlEvents(true); -                                    MusEGlobal::song->changeAllPortDrumCtrlEvents(true); -                              } -                              else -                              { -                                //MusEGlobal::audio->msgSetTrackOutPort(track, n); -                                track->setOutPortAndUpdate(n); -                              } -                              MusEGlobal::audio->msgIdle(false); -                              MusEGlobal::audio->msgUpdateSoloStates();                   // (p4.0.14)  p4.0.17 -                              MusEGlobal::song->update(); -                        } -                        else -                        if (t->type() == MusECore::Track::AUDIO_SOFTSYNTH)  +                  if(n < 0)              // Invalid item. +                    break; +                   +                  if(n >= MIDI_PORTS)    // Show port config dialog. +                  { +                    MusEGlobal::muse->configMidiPorts(); +                    break; +                  } + +                  // Changed by T356. +                  //track->setOutPort(n); +                  //MusEGlobal::audio->msgSetTrackOutPort(track, n); +                   +                  //MusEGlobal::song->update(); +                  if (t->type() == MusECore::Track::DRUM) { +                        bool change = QMessageBox::question(this, tr("Update drummap?"), +                                      tr("Do you want to use same port for all instruments in the drummap?"), +                                      tr("&Yes"), tr("&No"), QString::null, 0, 1); +                        MusEGlobal::audio->msgIdle(true); +                        if (!change)                           { -                          if(md != 0) -                          { -                            // Idling is already handled in msgSetMidiDevice. -                            //MusEGlobal::audio->msgIdle(true); -                             -                            // Compiler complains if simple cast from Track to MusECore::SynthI... -                            MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[n], (MusEGlobal::midiPorts[n].device() == md) ? 0 : md); -                            MusEGlobal::muse->changeConfig(true);     // save configuration file -                           -                            //MusEGlobal::audio->msgIdle(false); -                            MusEGlobal::song->update(); -                          } +                              // Delete all port controller events. +                              //MusEGlobal::audio->msgChangeAllPortDrumCtrlEvents(false); +                              MusEGlobal::song->changeAllPortDrumCtrlEvents(false); +                              track->setOutPort(n); +                   +                              for (int i=0; i<DRUM_MAPSIZE; i++) //Remap all drum instruments to this port +                                    MusEGlobal::drumMap[i].port = track->outPort(); +                              // Add all port controller events. +                              //MusEGlobal::audio->msgChangeAllPortDrumCtrlEvents(true); +                              MusEGlobal::song->changeAllPortDrumCtrlEvents(true);                          }                          else                          { -                          MusEGlobal::audio->msgIdle(true);                            //MusEGlobal::audio->msgSetTrackOutPort(track, n);                            track->setOutPortAndUpdate(n); -                          MusEGlobal::audio->msgIdle(false); -                          //MusEGlobal::song->update(); -                          MusEGlobal::audio->msgUpdateSoloStates();                   // (p4.0.14) p4.0.17 -                          MusEGlobal::song->update(SC_MIDI_TRACK_PROP);               //                          } -                      } -                  delete p; +                        MusEGlobal::audio->msgIdle(false); +                        MusEGlobal::audio->msgUpdateSoloStates();                   // (p4.0.14)  p4.0.17 +                        MusEGlobal::song->update();                    } -                  break; +                  else +                  if (t->type() == MusECore::Track::AUDIO_SOFTSYNTH)  +                  { +                    if(md != 0) +                    { +                      // Idling is already handled in msgSetMidiDevice. +                      //MusEGlobal::audio->msgIdle(true); +                       +                      // Compiler complains if simple cast from Track to MusECore::SynthI... +                      MusEGlobal::midiSeq->msgSetMidiDevice(&MusEGlobal::midiPorts[n], (MusEGlobal::midiPorts[n].device() == md) ? 0 : md); +                      MusEGlobal::muse->changeConfig(true);     // save configuration file +                     +                      //MusEGlobal::audio->msgIdle(false); +                      MusEGlobal::song->update(); +                    } +                  } +                  else +                  { +                    MusEGlobal::audio->msgIdle(true); +                    //MusEGlobal::audio->msgSetTrackOutPort(track, n); +                    track->setOutPortAndUpdate(n); +                    MusEGlobal::audio->msgIdle(false); +                    //MusEGlobal::song->update(); +                    MusEGlobal::audio->msgUpdateSoloStates();                   // (p4.0.14) p4.0.17 +                    MusEGlobal::song->update(SC_MIDI_TRACK_PROP);               // +                } +            } +            break;              case MusECore::Track::WAVE:              case MusECore::Track::AUDIO_OUTPUT: diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 8fd2de1d..26f96bf1 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -1649,6 +1649,10 @@ void MidiFileConfig::cancelClicked()        close();        } +} // namespace MusEGui + + +namespace MusEGlobal {  //---------------------------------------------------------  //   write @@ -1737,5 +1741,5 @@ void MixerConfig::read(MusECore::Xml& xml)        } -} // namespace MusEGui +} // namespace MusEGlobal diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp index df8742e8..a19d9ed8 100644 --- a/muse2/muse/gconfig.cpp +++ b/muse2/muse/gconfig.cpp @@ -25,7 +25,7 @@  namespace MusEGlobal { -MusEGui::GlobalConfigValues config = { +GlobalConfigValues config = {        190,                        // globalAlphaBlend            {          QColor(0xff, 0xff, 0xff),   // palette diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h index 85eecf60..24fd787a 100644 --- a/muse2/muse/gconfig.h +++ b/muse2/muse/gconfig.h @@ -45,7 +45,7 @@ enum newDrumRecordCondition_t  } -namespace MusEGui { +namespace MusEGlobal {  //---------------------------------------------------------  //   MixerConfig @@ -180,10 +180,10 @@ struct GlobalConfigValues {        MusECore::newDrumRecordCondition_t newDrumRecordCondition;        }; -} // namespace MusEGui -namespace MusEGlobal { -extern MusEGui::GlobalConfigValues config; + + +extern GlobalConfigValues config;  } // namespace MusEGlobal  #endif diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 1d8436b6..2d4561e0 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -29,6 +29,8 @@  #include <stdio.h> +#include "globals.h" +#include "app.h"  #include "audio.h"  #include "pitchedit.h"  #include "midiport.h" @@ -230,37 +232,52 @@ void DList::devicesPopupMenu(MusECore::DrumMap* t, int x, int y, bool changeAll)          return;        } -      QMenu* p = MusECore::midiPortsPopup(); +      QMenu* p = MusECore::midiPortsPopup(this, t->port);        QAction* act = p->exec(mapToGlobal(QPoint(x, y)), 0);        bool doemit = false; -      if (act) { -            int n = act->data().toInt(); -            if (!changeAll) -            { -                if(n != t->port) -                { -                  MusEGlobal::audio->msgIdle(true); -                  MusEGlobal::song->remapPortDrumCtrlEvents(getSelectedInstrument(), -1, -1, n); -                  MusEGlobal::audio->msgIdle(false); -                  t->port = n; -                  doemit = true; -                }   -            }       -            else { -                  MusEGlobal::audio->msgIdle(true); -                  // Delete all port controller events. -                  MusEGlobal::song->changeAllPortDrumCtrlEvents(false); -                   -                  for (int i = 0; i < ourDrumMapSize; i++) -                        ourDrumMap[i].port = n; -                  // Add all port controller events. -                  MusEGlobal::song->changeAllPortDrumCtrlEvents(true); +      if(!act) +      { +        delete p; +        return; +      }   +       +      int n = act->data().toInt(); +      delete p; + +      if(n < 0)              // Invalid item. +        return; +       +      if(n >= MIDI_PORTS)    // Show port config dialog. +      { +        MusEGlobal::muse->configMidiPorts(); +        return; +      } -                  MusEGlobal::audio->msgIdle(false); -                  doemit = true; -                  } +      if (!changeAll) +      { +          if(n != t->port) +          { +            MusEGlobal::audio->msgIdle(true); +            MusEGlobal::song->remapPortDrumCtrlEvents(getSelectedInstrument(), -1, -1, n); +            MusEGlobal::audio->msgIdle(false); +            t->port = n; +            doemit = true; +          }   +      }       +      else { +            MusEGlobal::audio->msgIdle(true); +            // Delete all port controller events. +            MusEGlobal::song->changeAllPortDrumCtrlEvents(false); +             +            for (int i = 0; i < ourDrumMapSize; i++) +                  ourDrumMap[i].port = n; +            // Add all port controller events. +            MusEGlobal::song->changeAllPortDrumCtrlEvents(true); +             +            MusEGlobal::audio->msgIdle(false); +            doemit = true;              } -      delete p; +        if(doemit)        {          int instr = getSelectedInstrument(); diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index 5c8f2c23..e7e517ff 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -104,7 +104,7 @@ void DrumEdit::setHeaderWhatsThis()        header->setWhatsThis(COL_NOTELENGTH, tr("note length"));        header->setWhatsThis(COL_NOTE, tr("this is the note which is played"));        header->setWhatsThis(COL_OUTCHANNEL, tr("output channel (hold ctl to affect all rows)")); -      header->setWhatsThis(COL_OUTPORT, tr("output port")); +      header->setWhatsThis(COL_OUTPORT, tr("output port (hold ctl to affect all rows)"));        header->setWhatsThis(COL_LEVEL1, tr("shift + control key: draw velocity level 1"));        header->setWhatsThis(COL_LEVEL2, tr("control key: draw velocity level 2"));        header->setWhatsThis(COL_LEVEL3, tr("shift key: draw velocity level 3")); @@ -126,7 +126,7 @@ void DrumEdit::setHeaderToolTips()        header->setToolTip(COL_NOTELENGTH, tr("note length"));        header->setToolTip(COL_NOTE, tr("this is the note which is played"));        header->setToolTip(COL_OUTCHANNEL, tr("output channel (ctl: affect all rows)")); -      header->setToolTip(COL_OUTPORT, tr("output port")); +      header->setToolTip(COL_OUTPORT, tr("output port (ctl: affect all rows)"));        header->setToolTip(COL_LEVEL1, tr("shift + control key: draw velocity level 1"));        header->setToolTip(COL_LEVEL2, tr("control key: draw velocity level 2"));        header->setToolTip(COL_LEVEL3, tr("shift key: draw velocity level 3")); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index a9eba278..2be4bf60 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4596,16 +4596,6 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo   * CURRENT TODO   *   o my record flag handling   *  - *   o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg  - *   o find and fix FINDMICHJETZT - *   o fix all segfaults and non-working stuff! - *        - creating, changing types to and from, erasing NEW_DRUM tracks - *        - move parts around - *        - playing them. mute? - *        - recording/echoing/steprec them - *        - load, save them - *   o fix valgrind problems - *    * > o drum editor: channel-stuff   *        o clearly state in the changelog: when having multiple drumeditors open,   *          the mute-column may not work, because another editor is overriding this. @@ -4617,6 +4607,16 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo   *        o offer some way to set maintained_automatically to true again   *        o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions   * + *   o in appearance.cpp: add the new stuff for drumTrackLabelBg and drumTrackBg  + *   o find and fix FINDMICHJETZT + *   o fix all segfaults and non-working stuff! + *        - creating, changing types to and from, erasing NEW_DRUM tracks + *        - move parts around + *        - playing them. mute? + *        - recording/echoing/steprec them + *        - load, save them + *   o fix valgrind problems + *    * IMPORTANT TODO   *   o allow steprec-insert-rest-note to be set to "off" / "unused"   *   o all places where i added doubleclick-edits: only react on left-click double clicks! diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp index a8a248cb..71a90fe7 100644 --- a/muse2/muse/midiport.cpp +++ b/muse2/muse/midiport.cpp @@ -37,6 +37,8 @@  #include "synth.h"  #include "app.h"  #include "song.h" +#include "menutitleitem.h" +#include "icons.h"  //#ifdef DSSI_SUPPORT  //#include "dssihost.h" @@ -316,20 +318,65 @@ int MidiPort::portno() const  //   midiPortsPopup  //--------------------------------------------------------- -//QPopupMenu* midiPortsPopup(QWidget* parent)  QMenu* midiPortsPopup(QWidget* parent, int checkPort)        {        QMenu* p = new QMenu(parent); +      QMenu* subp = 0; +      QAction *act = 0; +      QString name; + +      // Warn if no devices available. Add an item to open midi config.  +      int pi = 0; +      for( ; pi < MIDI_PORTS; ++pi) +      { +        MusECore::MidiDevice* md = MusEGlobal::midiPorts[pi].device(); +        //if(md && !md->isSynti() && (md->rwFlags() & 1)) +        //if(md && (md->rwFlags() & 1))    +        if(md && (md->rwFlags() & 1 || md->isSynti()) )   +          break; +      } +      if(pi == MIDI_PORTS) +      { +        act = p->addAction(p->tr("Warning: No output devices!")); +        act->setCheckable(false); +        act->setData(-1); +        p->addSeparator(); +      } +      act = p->addAction(QIcon(*MusEGui::settings_midiport_softsynthsIcon), p->tr("Open midi config...")); +      act->setCheckable(false); +      act->setData(MIDI_PORTS);   +      p->addSeparator(); +       +      p->addAction(new MusEGui::MenuTitleItem("Output port/device", p)); +        for (int i = 0; i < MIDI_PORTS; ++i) {              MidiPort* port = &MusEGlobal::midiPorts[i]; -            QString name;              name.sprintf("%d:%s", port->portno()+1, port->portname().toLatin1().constData()); -	    QAction *act = p->addAction(name); -	    act->setData(i); -             -            if(i == checkPort) -              act->setChecked(true); +            if(port->device() || (i == checkPort))    +            {   +              act = p->addAction(name); +              act->setData(i); +              act->setCheckable(true); +              act->setChecked(i == checkPort); +            }   + +            if(!port->device()) +            { +              if(!subp)                  // No submenu yet? Create it now. +              { +                subp = new QMenu(p); +                subp->setTitle(subp->tr("Empty ports")); +                //subp->addAction(new MusEGui::MenuTitleItem("Empty Ports", subp)); +              }   +              //act = subp->addAction(name);               // No need for all those "<None>" names.  +              act = subp->addAction(QString().setNum(i+1)); +              act->setData(i); +              act->setCheckable(true); +              act->setChecked(i == checkPort); +            }              }   +      if(subp) +        p->addMenu(subp);        return p;        } diff --git a/muse2/muse/mixer/amixer.cpp b/muse2/muse/mixer/amixer.cpp index 64ebda11..f9ede36c 100644 --- a/muse2/muse/mixer/amixer.cpp +++ b/muse2/muse/mixer/amixer.cpp @@ -158,7 +158,7 @@ bool ScrollArea::viewportEvent(QEvent* event)  //    inputs | synthis | tracks | groups | master  //--------------------------------------------------------- -AudioMixerApp::AudioMixerApp(QWidget* parent, MixerConfig* c) +AudioMixerApp::AudioMixerApp(QWidget* parent, MusEGlobal::MixerConfig* c)     : QMainWindow(parent)        {        cfg = c; diff --git a/muse2/muse/mixer/amixer.h b/muse2/muse/mixer/amixer.h index 1f29c693..e1c70ca3 100644 --- a/muse2/muse/mixer/amixer.h +++ b/muse2/muse/mixer/amixer.h @@ -46,6 +46,10 @@ class Meter;  class Track;  } +namespace MusEGlobal { +  struct MixerConfig; +} +  namespace MusEGui {  class ComboBox;  class DoubleLabel; @@ -53,7 +57,6 @@ class Knob;  class RouteDialog;  class Slider;  class Strip; -struct MixerConfig;  typedef std::list<Strip*> StripList;  //--------------------------------------------------------- @@ -82,7 +85,7 @@ class AudioMixerApp : public QMainWindow {        Q_OBJECT        //QString name; -      MixerConfig* cfg; +      MusEGlobal::MixerConfig* cfg;        StripList stripList;        QScrollArea* view;        QWidget* central; @@ -143,7 +146,7 @@ class AudioMixerApp : public QMainWindow {     public:        //AudioMixerApp(QWidget* parent); -      AudioMixerApp(QWidget* parent, MixerConfig* c); +      AudioMixerApp(QWidget* parent, MusEGlobal::MixerConfig* c);        //void write(Xml&, const char* name);        //void write(int level, Xml& xml, const char* name);        void write(int level, MusECore::Xml& xml); diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp index 64189147..27e6d523 100644 --- a/muse2/muse/widgets/musewidgetsplug.cpp +++ b/muse2/muse/widgets/musewidgetsplug.cpp @@ -53,7 +53,7 @@ static const char* valu[] = {        "C","C#","D","D#","E","F","F#","G","G#","A","A#","H"        }; -GlobalConfigValues config = { +MusEGlobal::GlobalConfigValues config = {        190,                        // globalAlphaBlend            {          QColor(0xff, 0xff, 0xff),   // palette diff --git a/muse2/muse/widgets/routepopup.cpp b/muse2/muse/widgets/routepopup.cpp index 799d9079..73d29c25 100644 --- a/muse2/muse/widgets/routepopup.cpp +++ b/muse2/muse/widgets/routepopup.cpp @@ -1069,7 +1069,7 @@ void RoutePopupMenu::prepare()        }        if(pi == MIDI_PORTS)        { -        act = _pup->addAction(tr("Warning: No midi input devices!")); +        act = _pup->addAction(tr("Warning: No input devices!"));          act->setCheckable(false);          act->setData(-1);          _pup->addSeparator(); @@ -1080,7 +1080,7 @@ void RoutePopupMenu::prepare()        _pup->addSeparator();        ++gid; -      _pup->addAction(new MenuTitleItem("Midi input ports", _pup));  +      _pup->addAction(new MenuTitleItem("Input port/device", _pup));         for(int i = 0; i < MIDI_PORTS; ++i)        { | 
